8 Star 8 Fork 2

wujehy / GeeJoanProtocol_C

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
README.md 5.37 KB
一键复制 编辑 原始数据 按行查看 历史
wujehy 提交于 2020-05-10 18:53 . update : README.md

GeeJoanProtocol_C

介绍

GeeJoan 协议包 的封装 , 可移植用于 嵌入式设备 等

API 文档 : http://api.geejoan.cn/

备份: http://api.iotgeek.top/

使用说明:

GeeJoanProtocol_C 是使用 C 语言封装的 GeeJoan 协议.

GeeJoan 协议 右两层包 : 网络包 + 业务包

客户端向服务端请求的是 : NetWorkPackageRequest

客户端会接收到相应的包:NetWorkPackageRespose

数据均通过GeeJoan 协议进行封装成 二进制数据的bytes 序列化

网络包的结构:

enum NetWorkPackageModel {
    UNDEFINE = 0;
    AuthMod = 1;
    IOTMod = 2;
}

//NetWorkPackageRequest
NetWorkPackageRequest{
    NetWorkPackageModel type_m ;
    int32 type_sub ;
    int64 taskid ;
    bytes body ;
    bytes pubilckey ;
}

//NetWorkPackageRespose
NetWorkPackageRespose {
    NetWorkPackageModel type_m;
    int32 type_sub;
    int64 taskid;
    int32 code;
    bytes body;
}

业务包 的 数据 封装在 body 里面 , 通过type_m , type_sub 判断具体数据包的类型:


/**
 * @brief Auth 模块的子类型是sub_type
 */
enum AUTH_MOD_TYPE
{
    AUTH_REGISTER = 1, ///< 注册
    AUTH_LOGIN = 2, ///< 登录
    AUTH_LOGOUT = 3, ///< 登出
    AUTH_CHANGE_PASSWORD = 5, ///<修改密码
};

/**
 * @brief IoT 模块的 子类型是
 */
enum IOT_MOD_TYPE
{
    IOT_UPLOAD_SENSOR_DATA = 1, ///< 数据上报
    IOT_FIND_SENSOR_DATA = 2, ///< 数据查询
    IOT_CONTROL_DEVICE = 3, ///< 控制设备
    IOT_CONTROL_ACK = 4, ///< 控制确认
    IOT_CONTROL_ACK_LISTERNER = 5, ///< 控制确认监听器
    IOT_CONTROL_LISTERNER = 6, ///< 控制监听器
    IOT_LOGIN_DEVICE = 7, ///< 登录设备
    IOT_HEART_BEAT = 8, ///< 心跳包
    IOT_FIND_GATEWAY = 9, ///< 查找网关
    IOT_CREATE_DEVICE = 10, ///< 创建设备
    IOT_FIND_DEVICE_TOKEN = 11, ///< 查询设备的Token
    IOT_GENERATE_DEVICE_TOKEN = 12, ///< 生成设备的Token
};

序列化API 格式:

*注: XXXX 代表对应的数据包的类型

  1. 序列化类的操作: serialzeXXXX
  2. 反序列化的操作:deserialzeXXXX
  3. 释放指针的操作:free_XXXX

示例: main.c

拼包(以登录为例 )

拼包有两步 , 业务包和网络包(上层可以使用者可以二次封装 )

业务包的封装

    char *loginBuffer = 0; // 储存序列化后的数据包
    const char* your_name = "testname";
    const char* your_password = "testpassword";
    int64_t currentTime = 1234567890123;
    
    //  & 才能修改为指针的buff
    int loginLen = serialzeLoginRequest(&loginBuffer , your_name ,  your_password , currentTime);

	// 如果序列化成功 , 那么 
    if (loginLen < 0 )
    {
        fprintf(stderr , "serial Login Request Error \r\n");
        return -1;
    } else
    {
        printf("serial Login Request Success \r\n");
    }

网络包则将body 填入 业务包的buffer

    // 网络请求包
    char* networkPackageBuffer = 0 ;
    long long taskid_ = 2 ; // 当前的任务 实际环境 自增
    int networkPackageLen = serialzeNetWorkPackageRequest(&networkPackageBuffer , ///< 输出的网络包
            NetWorkPackageModel_AuthMod , ///< 鉴权模块
            AUTH_LOGIN , ///< 登录子模块
            taskid_ , ///< 本地的 任务
            loginBuffer , ///< 登录的 业务包
            loginLen , ///<  登录的业务包长度
            NULL ,///< 公钥 , NULL 空
            0  ///< 长度约0
            );

    printf("Request : ");
    printBuff(networkPackageBuffer , networkPackageLen );

    printf("\r\n");

networkPackageBuffer 和 networkPackageLen 通过 socket 直接发出即可被炸服务器解析.

*注:解析参见 : https://gitee.com/wujehy/GeeJoanServerCpp

解包(以登录为例)

networkPackString 是 序列化的网络包, 同时进行hex 后的字符串

HexString2Char 是将Hex 字符串 反序列化成 bytes 的工具方法

 // 测试 的网络包
    const char *networkPackString = "080110021802221F0A08746573746E616D65120C7465737470617373776F726418CB89EC8FF723";
    // 获取源包 即 networkPackageBuffer
    void *decodePackage = 0;
    int decodeLen = HexString2Char(&decodePackage , networkPackString , strlen(networkPackString));
    if(decodeLen < 0 )
    {
        fprintf(stderr , "decode NetworkPackage Error \r\n");
        return -1;
    }

解包网络包:

实际情况直接 , decodePackage , decodeLen 由socket 读取的扎buffer 和站len 代替

   // 网络包
    NetWorkPackageRequest *requestRecv = 0 ;
    ERRORCODE retCode = deserialzeNetWorkPackageRequest( &requestRecv , (void*)decodePackage  , decodeLen);


  

然后通过类型 解析出具体的数据包

 if (requestRecv->type_sub == AUTH_LOGIN)
    {
        LoginRequest *loginRequest = 0 ;

        if(deserialzeLoginRequest(&loginRequest , requestRecv->body.data , requestRecv->body.len) == ERROR_FAIL)
        {
            fprintf(stderr , "deserialzeLoginRequest Error \r\n");
            return -1;
        }
        //
        printf("Name  : %s \r\n", loginRequest->username);
        printf("Passwd: %s \r\n", loginRequest->password);
        printf("time  : %lld \r\n", loginRequest->timestamp);

        // 释放了业务包
        free_LoginRequest(loginRequest);
    }

最后需要释放 网络包的内存防止泄漏

    // 释放网络包
    free_NetWorkPackageRequest(requestRecv);

API文档生成

$ doxygen ./doxygen.cfg 
C
1
https://gitee.com/wujehy/GeeJoanProtocol_C.git
git@gitee.com:wujehy/GeeJoanProtocol_C.git
wujehy
GeeJoanProtocol_C
GeeJoanProtocol_C
master

搜索帮助