收藏官网首页
查看: 16019|回复: 4

如何用C语言实现OpenAPI的用户登录请求和应答

跳转到指定楼层
楼主
发表于 2015-4-23 11:49:47 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
注册成为机智云开发者,手机加虚拟设备快速开发
下面的代码,仅给大家示例如何组包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[MAX_BUF_LEN] = { 0 };
    char httpHeadCustom[MAX_BUF_LEN] = { 0 };
    userLoginResult_st userLoginResult = {};

    if (!appID || !userName || !password || !appID[0] || !userName[0] || !password[0]) {
        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[0] && 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;
}


沙发
 楼主| 发表于 2015-4-23 11:50:52 | 只看该作者
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[MAX_BUF_LEN] = { 0 };
    char httpHeadCustom[MAX_BUF_LEN] = { 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[0] && 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;
}

71

主题

169

帖子

1223

积分

金牌会员

Rank: 6Rank: 6

积分
1223
地板
发表于 2015-4-24 21:58:21 | 只看该作者
这可真是所谓的开源啊!代码都贴出来了啊

9

主题

66

帖子

235

积分

中级会员

Rank: 3Rank: 3

积分
235
5#
发表于 2015-6-11 09:21:41 | 只看该作者
免费使用STM32、APP自动代码生成工具
非常棒,谢谢分型。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

加入Q群 返回顶部

版权与免责声明 © 2006-2024 Gizwits IoT Technology Co., Ltd. ( 粤ICP备11090211号 )

快速回复 返回顶部 返回列表