如何用C语言实现OpenAPI的用户登录请求和应答
下面的代码,仅给大家示例如何组包OpenAPI请求和解析OpenAPI应答。因代码是C++和C语言混合编写的,想用纯C代码实现的人,请参考改写。http协议的C语言实现,请大家自己去网上找参考代码,这里就不贴了。代码中的Json解析是C++实现,有想用CJson做解析的朋友,请自行改写。
OpenAPI的用户登录:
/* OpenAPI错误码返回信息 */typedef struct _errorInfo_st { int error; string errorMessage;} errorInfo_st;
/* 用户登录返回信息 */typedef struct _userLoginResult_st { errorInfo_st errorInfo; string uid; string token; long expireAt;} userLoginResult_st;
userLoginResult_st UserLogin(const char *appID, const char *userName, const char *password){ int responseCode = 0; int answerLen = 0; char *answer = NULL; char httpBody = { 0 }; char httpHeadCustom = { 0 }; userLoginResult_st userLoginResult = {};
if (!appID || !userName || !password || !appID || !userName || !password) { userLoginResult.errorInfo.error = ERROR_INVALID_PARAM; userLoginResult.errorInfo.errorMessage = "Invalid param(s)."; return userLoginResult; }
snprintf(httpHeadCustom, sizeof(httpHeadCustom), "Content-Type: application/json\r\n" "X-Gizwits-Application-Id: %s\r\n", appID); snprintf(httpBody, sizeof(httpBody), "{\"username\":\"%s\",\"password\":\"%s\"}", userName, password);
answer = http_request(GWifiConfig::sharedInstance()->GetOpenAPIDomain(), GWifiConfig::sharedInstance()->GetOpenAPIPort(), HTTP_TIMEOUT, HTTP_POST, "/app/login", httpHeadCustom, httpBody, &responseCode, &answerLen); if (answer) { Value jsonRoot = Value(nullValue); Reader jsonReader = Reader();
try { jsonReader.parse(answer, answer + answerLen, jsonRoot);
if('{' == answer && jsonRoot.isObject()) { userLoginResult.errorInfo.error = jsonRoot["error_code"].asInt(); userLoginResult.errorInfo.errorMessage = jsonRoot["error_message"].asString(); userLoginResult.uid = jsonRoot["uid"].asString(); userLoginResult.token = jsonRoot["token"].asString(); userLoginResult.expireAt = jsonRoot["expire_at"].asInt(); } } catch (exception e) { logMsgEx(LV_ERROR, __func__, "Cause parse exception - %s", e.what()); }
free(answer); } else { userLoginResult.errorInfo.error = ERROR_HTTP_FAIL; userLoginResult.errorInfo.errorMessage = "Http request failed: " + (errno ? string(strerror(errno)) : ""); logMsg(LV_WARN, "User %s login failed, responseCode:%d", userName, responseCode); }
//取到才uid跟token才视为成功 if (userLoginResult.uid.empty() || userLoginResult.token.empty()) { if (ERROR_NONE == userLoginResult.errorInfo.error) { userLoginResult.errorInfo.error = ERROR_HTTP_FAIL; userLoginResult.errorInfo.errorMessage = "Http response error format."; } logMsg(LV_ERROR, "User %s login failed, error:%d, errorMessage:%s", userName, userLoginResult.errorInfo.error, userLoginResult.errorInfo.errorMessage.c_str()); } else { logMsg(LV_WARN, "User %s login success, uid:%s, token:%s, expire_at:%ld", userName, userLoginResult.uid.c_str(), userLoginResult.token.c_str(), userLoginResult.expireAt); }
if (userLoginResult.errorInfo.errorMessage.length() && !userLoginResult.errorInfo.error) { userLoginResult.errorInfo.error = ERROR_GENERAL; }
return userLoginResult;}
OpenAPI的获取设备绑定列表:
/* 设备信息结构体 */
typedef struct _devDetailInfo_st {
errorInfo_st errorInfo;
string productKey; // 设备类型标识
string did; // 设备唯一识别码
string mac;// 设备mac地址
string passCode; // 设备验证码
string host; // m2m域名
string remark; // 设备昵称
int port; // m2m端口
int isOnline; // 设备是否在线
int isDisabled; //设备已注销
int type; // 设备类型,0:普通设备, 1:中控设备
} devDetailInfo_st;
/* 绑定设备列表返回结果 */
typedef struct _getBoundDevResult_st {
errorInfo_st errorInfo;
vector<devDetailInfo_st> devices;
} getBoundDevResult_st;
getBoundDevResult_st GetNumBoundDevicesFromIndex(const char *appID, const char *token, int num, int index, const char *showDisabled)
{
int responseCode = 0;
int answerLen = 0;
char *answer = NULL;
char httpDest = { 0 };
char httpHeadCustom = { 0 };
getBoundDevResult_st getBoundDevResult = {ERROR_INVALID_PARAM, "Invalid param(s)."};
if (!appID || !token || num <= 0|| index < 0) return getBoundDevResult;
snprintf(httpDest, sizeof(httpDest), "/app/bindings?show_disabled=%s&limit=%d&skip=%d",
showDisabled, num, index);
snprintf(httpHeadCustom, sizeof(httpHeadCustom),
"Content-Type: application/json\r\n"
"X-Gizwits-Application-Id: %s\r\n"
"X-Gizwits-User-token: %s\r\n", appID, token);
answer = http_request(GWifiConfig::sharedInstance()->GetOpenAPIDomain(), GWifiConfig::sharedInstance()->GetOpenAPIPort(), HTTP_TIMEOUT, HTTP_GET, httpDest, httpHeadCustom, NULL, &responseCode, &answerLen);
if (answer) {
Value jsonRoot = Value(nullValue);
Reader jsonReader = Reader();
try {
jsonReader.parse(answer, answer + answerLen, jsonRoot);
if('{' == answer && jsonRoot.isObject()) {
getBoundDevResult.errorInfo.error = jsonRoot["error_code"].asInt();
getBoundDevResult.errorInfo.errorMessage = jsonRoot["error_message"].asString();
Value jsonValue = jsonRoot["devices"];
if (jsonValue.isArray()) {
for (ValueIterator i = jsonValue.begin(); i != jsonValue.end(); ++i) {
devDetailInfo_st device = {};
device.productKey = (*i)["product_key"].asString();
device.did = (*i)["did"].asString();
device.mac = (*i)["mac"].asString();
device.passCode = (*i)["passcode"].asString();
device.host = (*i)["host"].asString();
device.port = (*i)["port"].asInt();
device.isOnline = (*i)["is_online"].asBool();
device.remark = (*i)["remark"].asString();
device.isDisabled = (*i)["is_disabled"].asBool();
if ((*i)["type"].isString()) {
if ((*i)["type"].asString() == string("center_control")) {
device.type = 1;
}
}
getBoundDevResult.devices.push_back(device);
}
getBoundDevResult.errorInfo.error = ERROR_NONE;
getBoundDevResult.errorInfo.errorMessage = string();
logMsg(LV_WARN, "Get %d devices from %s success", getBoundDevResult.devices.size(), GWifiConfig::sharedInstance()->GetOpenAPIDomain());
} else {
logMsg(LV_WARN, "Get devices from %s failed, can't find jsonKey(devices)", GWifiConfig::sharedInstance()->GetOpenAPIDomain());
}
} else {
logMsg(LV_WARN, "Get devices from %s failed, parse json error", GWifiConfig::sharedInstance()->GetOpenAPIDomain());
}
} catch (exception e) {
logMsgEx(LV_ERROR, __func__, "Cause parse exception - %s", e.what());
}
free(answer);
} else {
getBoundDevResult.errorInfo.error = ERROR_HTTP_FAIL;
getBoundDevResult.errorInfo.errorMessage = "Http request failed: " + (errno ? string(strerror(errno)) : "");
logMsg(LV_WARN, "Get devices from %s failed, responseCode:%d", GWifiConfig::sharedInstance()->GetOpenAPIDomain(), responseCode);
}
if (ERROR_INVALID_PARAM == getBoundDevResult.errorInfo.error) {
getBoundDevResult.errorInfo.error = ERROR_HTTP_FAIL;
getBoundDevResult.errorInfo.errorMessage = "Http response error format.";
}
if (getBoundDevResult.errorInfo.errorMessage.length() && !getBoundDevResult.errorInfo.error) {
getBoundDevResult.errorInfo.error = ERROR_GENERAL;
}
return getBoundDevResult;
} 一级棒! 这可真是所谓的开源啊!代码都贴出来了啊 非常棒,谢谢分型。
页:
[1]