123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994 |
- /********************************************************************************
- * File Name: TcpComm.c
- * Function Describe: 通过TCP与服务器通信(TCP通信协议)
- * Explain:
- * Writer:
- * Date:
- *******************************************************************************/
-
- #include "includes.h"
- //-------------------------------------------------------------------------------
- //==============================================================================
- //@Functions
- //@brief 将32位大小端数据格式转换
- //@param
- //@retval 转换后的数据
- //==============================================================================
- unsigned int BigLittle32Conv(unsigned int srcData)
- {
- SUTDL dl1, dl2;//用于大小端转换
- dl1.Data.ulData = srcData;
- dl2.Data.ucData.b1 = dl1.Data.ucData.b4;
- dl2.Data.ucData.b2 = dl1.Data.ucData.b3;
- dl2.Data.ucData.b3 = dl1.Data.ucData.b2;
- dl2.Data.ucData.b4 = dl1.Data.ucData.b1;
- return dl2.Data.ulData;
- }
- //==============================================================================
- //@Functions
- //@brief 将16位大小端数据格式转换
- //@param
- //@retval 转换后的数据
- //==============================================================================
- unsigned short BigLittle16Conv(unsigned short srcData)
- {
- SUTDS ds1, ds2;//用于大小端转换
- ds1.Data.usData = srcData;
- ds2.Data.ucData.b1 = ds1.Data.ucData.b2;
- ds2.Data.ucData.b2 = ds1.Data.ucData.b1;
- return ds2.Data.usData;
- }
- //==============================================================================
- //@Functions
- //@brief 从pStr中找到pSearch,返回pSearch后的第一个地址(若无para则返回0)。可配合 StrNumToInt() 使用
- //举例:pStr=" "WorkEnable":1,"PowerOnTimeAdj":[123,45,-78,90], "
- // 如果pSearch="TimeAdj":[" 返回"123,45,-78,90], "
- // 如果pSearch="Work":" 返回"Enable":1,"PowerOnTimeAdj":[123,45,-78,90], "
- // 如果pSearch="abcd":" 返回NULL
- //@param
- //@retval pSearch后的第一个地址
- //==============================================================================
- char* SearchFromStr(char *pStr,char *pSearch)
- {
- char *pResult;
- unsigned char searchLen;
- pResult = strstr(pStr, pSearch);
- if(pResult == NULL)
- {
- return NULL;
- }
- searchLen = strlen(pSearch);
- pResult += searchLen;
- return pResult;
- }
- //==============================================================================
- //@Functions
- //@brief 指定位置开始,到非数字字符结束的数字字符串转换成整形数值(数值范围-2147483648~2147483647)
- // "65535,a" --> 65535(十六进制0xFFFF),返回5
- // "-123" --> -123(十六进制0x85),返回4
- // " -123" --> -123(十六进制0x85),返回5
- // "123456789,kk"--> 123456789,返回9
- //@param 输入: *pStrNum 字符串数字开始的指针
- // 输出 *pNum 转换的值
- //@retval 转换的字符串中数字长度(含"-"号和空格),0失败
- //==============================================================================
- static unsigned char StrNumToInt(int *pNum, char *pStrNum)
- {
- char i, numLen = 0;
- char buf[11] = {0};
- for(i = 0; i < 10; i++)
- {
- if(pStrNum[i]>0x39 || pStrNum[i]<0x30)
- {
- if(pStrNum[i] != ' ' && pStrNum[i] != '-') break;
- }
- buf[i] = pStrNum[i];
- numLen = i + 1;
- }
- buf[i] = 0;
- *pNum = atoi(buf);
- return numLen;
- }
- //==============================================================================
- //@Functions
- //@brief 获取 指定位置开始,到"结束的 字符串内容,并返回实际长度,若无",则获取最大长度
- // 17010001" --> 17010001(ASCII),返回8
- //
- //@param 输入: *pStr 字符串开始的指针 maxLen
- // 输出 *pAsc 转换的值
- //@retval 转换的字符串长度
- //==============================================================================
- static unsigned char StrToAsc(char *pAsc, char *pStr, unsigned char maxLen)
- {
- char i, numLen = 0;
- for(i = 0; i < maxLen; i++)
- {
- if(pStr[i] == '\"') break;//到"结束
- pAsc[i] = pStr[i];
- numLen = i + 1;
- }
- pAsc[i] = 0;
- return numLen;
- }
- //==============================================================================
- //GetIntVFromJson
- //从json串中根据字段名field提取其int类型的值拷贝到value中
- //返回:
- //0 获取失败, 找不到同名字段对应的值
- //>0 获取成功,并返回其值,存放在value中
- //<0 获取失败,值类型错误
- //==============================================================================
- int GetIntVFromJson(char *pJson,char *pField,int *pValue)
- {
- char *pStrData;
- int number;
- int fieldlen = strlen(pField);
- if(fieldlen < 1)return 0;
- pStrData = SearchFromStr(pJson, pField);
- if(*pStrData == '\"' && *(pStrData+1) == ':')
- {
- pStrData += 2;
- }
- else
- {
- return 0;
- }
- if(StrNumToInt(&number, pStrData))
- {
- *pValue = number;
- return 1;
- }
- else
- {
- return -1;
- }
- }
- /**************************************************************************
- GetShortVFromJson
- 从json串中根据字段名field提取其short类型的值拷贝到value中
- 返回:
- 0 获取失败, 找不到同名字段对应的值
- >0 获取成功,并返回其值,存放在value中
- <0 获取失败,值类型错误
- **************************************************************************/
- int GetShortVFromJson(char *json,char *field,short *value)
- {
- int r,v;
- r=GetIntVFromJson(json,field,&v);
- if(r>0){
- if(v<-32768 || v>32767)return -1;
- *value=v;
- return 0;
- }
- return r;
- }
- /**************************************************************************
- GetUShortVFromJson
- 从json串中根据字段名field提取其unsigned short类型的值拷贝到value中
- 返回:
- 0 获取失败, 找不到同名字段对应的值
- >0 获取成功,并返回其值,存放在value中
- <0 获取失败,值类型错误
- **************************************************************************/
- int GetUShortVFromJson(char *json,char *field,unsigned short *value)
- {
- int r,v;
- r=GetIntVFromJson(json,field,&v);
- if(r>0){
- if(v<0 || v>65535)return -1;
- *value=v;
- return 0;
- }
- return r;
- }
- /**************************************************************************
- GetUCharVFromJson
- 从json串中根据字段名field提取其unsigned char类型的值拷贝到value中
- 返回:
- 0 获取失败, 找不到同名字段对应的值
- >0 获取成功,并返回其值,存放在value中
- <0 获取失败,值类型错误
- **************************************************************************/
- int GetUCharVFromJson(char *json,char *field,unsigned char *value)
- {
- int r,v;
- r=GetIntVFromJson(json,field,&v);
- if(r>0){
- if(v<0 || v>255)return -1;
- *value=v;
- return 0;
- }
- return r;
- }
- /**************************************************************************
- GetStrValueFromJson
- 从json串中根据字段名field提取其""内的字符串类型的值拷贝到value中,约定value的最大长度为valuelen
- 返回:
- 0 获取失败,找不到同名字段对应的值
- >0 获取成功并返回value的长度
- <0 获取失败 value存储空间不够或结构不完整。
- **************************************************************************/
- int GetStrValueFromJson(char *pJson,char *pField,char *pValue,unsigned char maxLen)
- {
- char *pStrData;
- unsigned char strLen;
-
- int fieldlen = strlen(pField);
- if(fieldlen < 1)return 0;
- pStrData = SearchFromStr(pJson, pField);
- if(*pStrData == '\"' && *(pStrData+1) == ':' && *(pStrData+2) == '\"')
- {
- pStrData += 3;
- }
- else
- {
- return 0;
- }
- strLen = StrToAsc(pValue, pStrData, maxLen);
- if(strLen == maxLen && pValue[maxLen] != '\"')//
- {
- return -1;
- }
- else
- {
- return strLen;
- }
- }
- /**************************************************************************
- GetAUShortVFromJson
- 从json串中根据字段名field提取其unsigned short类型的值拷贝到value中
- 返回:
- 0 获取失败, 找不到同名字段对应的值
- >0 获取成功,并返回其值,存放在value中
- <0 获取失败,值类型错误
- **************************************************************************/
- int GetAAAAUShortVFromJson(char *pJson,char *pField,unsigned short value[],int num)
- {
- char *pStrData;
- int i, v;
- int fieldlen = strlen(pField);
- if(fieldlen < 1)return 0;
- pStrData = SearchFromStr(pJson, pField);
- if(*pStrData == '\"' && *(pStrData+1) == ':' && *(pStrData+2) == '[')
- {
- pStrData += 3;
- }
- else
- {
- return 0;
- }
- for(i = 0; i < num; i++)
- {
- if(StrNumToInt(&v, pStrData))
- {
- if(v<0 || v>65535)return -1;
- value[i] = v;
- }
- else
- {
- return -1;
- }
- //查找[]内下一个",",获取其后地址
- if(i < (num - 1))
- {
- pStrData = SearchFromStr(pStrData, ",");
- }
- }
- return 1;
- }
- //==============================================================================
- //@Functions
- //@brief
- // 登录信息转为JSON格式字符串
- //{
- //"imsi":"460030785666759",
- //"iccid":"8986031640020231458P",
- //"authType": 1,
- //"dtuVender":"xxxx",
- //"dtuId":xxxx,
- //"productKey": "xxxx",
- //"sn":"08e7a3ae-f8f3-4414-a312",
- //"md5": "9E107D9D372BB6826BD81D3542A419D6"
- //}
- //说明:
- //Imsi:卡imsi号,
- //Iccid:卡iccid号,
- //authType:接入方式。1:设备直连;2:DTU登陆;(待扩展)
- //dtuVender:DTU厂商编码,
- //dtuId:dtu编码,
- //productKey:产品(平台定义,固定10字节,数字和小写字母混合)
- //sn:设备编码
- //备注:
- //当authType是1(设备登陆)时, dtuVender, dtuId, productKey, sn都有效,dtuVender和dtuId选传,productKey,sn必传。
- //当authType是2(DTU登陆)时,dtuVender, dtuId字段必传,productKey和sn字段无效,可以不传。
- //
- //@param 输入:tcpLogin 登录信息,输出:*pJson
- //@retval 返回JSON有效长度
- //MD5:所发数据域中所有数值(不算数据名称)+DTU时间的10进制格式,全部ASCII形式 计算
- //==============================================================================
- static unsigned short LoginToJson(char *pJson, tcpMsgDatLogin_t tcpLogin)
- {
- char buf[12] = {0};
- char md5Buf[200] = {0};
- char i;
- MD5_CTX mdContext = {0};
- //------生成MD5-----------------------
- strcat(md5Buf, tcpLogin.imsi);
- strcat(md5Buf, tcpLogin.iccid);
- sprintf(buf,"%d", tcpLogin.authType);
- strcat(md5Buf, buf);
- strcat(md5Buf, tcpLogin.dtuVender);
- strcat(md5Buf, tcpLogin.dtuId);
- strcat(md5Buf, tcpLogin.productKey);
- strcat(md5Buf, tcpLogin.sn);
- sprintf(buf,"%d", tcpSendMsgCtrl.utc);
- strcat(md5Buf, buf);
-
- MD5Init(&mdContext);
- MD5Update(&mdContext, md5Buf, strlen(md5Buf));
- MD5Final(&mdContext);
- for(i = 0; i < 16; i++)
- {
- sprintf(&tcpLogin.md5[2*i],"%02x", mdContext.digest[i]);
- }
-
- //------生成JSON----------------------
- strcat(pJson, "{\"imsi\":\"");
- strcat(pJson, tcpLogin.imsi);
-
- strcat(pJson, "\",\"iccid\":\"");
- strcat(pJson, tcpLogin.iccid);
- strcat(pJson, "\",\"authType\":");
- sprintf(buf,"%d", tcpLogin.authType);
- strcat(pJson, buf);
-
- strcat(pJson, ",\"dtuVender\":\"");
- strcat(pJson, tcpLogin.dtuVender);
- strcat(pJson, "\",\"dtuId\":\"");
- strcat(pJson, tcpLogin.dtuId);
-
- strcat(pJson, "\",\"productKey\":\"");
- strcat(pJson, tcpLogin.productKey);
-
- strcat(pJson, "\",\"sn\":\"");
- strcat(pJson, tcpLogin.sn);
-
- strcat(pJson, "\",\"md5\":\"");
- strcat(pJson, tcpLogin.md5);
- strcat(pJson, "\"}");//
- return strlen(pJson);
- }
- //==============================================================================
- //@Functions
- //@brief
- //UPLOAD 报文数据
- //{
- // "sn": "123456789",
- // "attrs":
- // {
- // "Country":1,
- // "Province":1,
- // "District":1,
- // "Shipowner":1,
- // "ShipNumber":"XX01",
- // "Address":28,
- // "Type":1,
- // "Status":1,
- // "AntiTheft":[0,0,0,0,0],
- // "Reserve":[0,0,0,0]
- // }
- //}
- //数据说明:
- //sn:设备编号
- //Country:国家: 中国 1
- //Province:省份: 广东:1 (广东:1、广西:2、福建:3、海南:4、山东:5、浙江:6、辽宁:7、江苏:8、上海:9、天津:10、河北:11)
- //District:地区 (具体待定,DTU只透传)
- //Shipowner:船东(渔政船:1、渔业公司:2、个人船东:3)
- //ShipNumber:渔船号码。13位数
- //Address:地址码
- //Type:类型码: 感温:1;感烟:2;手报:3;输入模块:4;输出模块:5;声光报警器:6;地址接口模块:7
- //Status:状态码: 正常:1报警:2故障:3启动:4
- //AntiTheft:防盗预留
- //Reserve:预留
- //@param 输入:tcpUpload ,输出:*pJson
- //@retval 返回JSON有效长度
- //==============================================================================
- static unsigned short UploadToJson(char *pJson, tcpMsgDatUpload_t tcpUpload)
- {
- char buf[40] = {0};
- unsigned char i;
- strcat(pJson, "{\"sn\":\"");
- strcat(pJson, tcpUpload.sn);
-
- strcat(pJson, "\",\"attrs\":{\"Country\":");
- sprintf(buf,"%d", tcpUpload.country);
- strcat(pJson, buf);
-
- strcat(pJson, ",\"Province\":");
- sprintf(buf,"%d", tcpUpload.province);
- strcat(pJson, buf);
-
- strcat(pJson, ",\"District\":");
- sprintf(buf,"%d", tcpUpload.district);
- strcat(pJson, buf);
-
- strcat(pJson, ",\"Shipowner\":");
- sprintf(buf,"%d", tcpUpload.shipowner);
- strcat(pJson, buf);
-
- strcat(pJson, ",\"ShipNumber\":\"");
- for(i = 0; i < 13; i++)
- {
- sprintf(buf,"%d", tcpUpload.shipNumber[i]);
- strcat(pJson, buf);
- }
-
- strcat(pJson, "\",\"Address\":");
- sprintf(buf,"%d", tcpUpload.address);
- strcat(pJson, buf);
- strcat(pJson, ",\"Type\":");
- sprintf(buf,"%d", tcpUpload.type);
- strcat(pJson, buf);
-
- strcat(pJson, ",\"Status\":");
- sprintf(buf,"%d", tcpUpload.status);
- strcat(pJson, buf);
-
- strcat(pJson, ",\"AntiTheft\":");
- sprintf(buf,"[%d,%d,%d,%d,%d],", tcpUpload.antiTheft[0],tcpUpload.antiTheft[1],tcpUpload.antiTheft[2],tcpUpload.antiTheft[3],tcpUpload.antiTheft[4]);
- strcat(pJson, buf);
-
- strcat(pJson, "\"Reserve\":");
- sprintf(buf,"[%d,%d,%d,%d]", tcpUpload.reserve[0],tcpUpload.reserve[1],tcpUpload.reserve[2],tcpUpload.reserve[3]);
- strcat(pJson, buf);
-
- strcat(pJson, "}}");
-
- return strlen(pJson);
- }
- //==============================================================================
- //@Functions
- //@brief
- // 心跳报文内容转为JSON格式字符串
- //
- //@param 输入:tcpHeart ,输出:*pJson
- //@retval 返回JSON有效长度
- //==============================================================================
- static unsigned short HeartToJson(char *pJson, tcpMsgDatHeart_t tcpHeart)
- {
- strcat(pJson, "{\"sn\":\"");
- strcat(pJson, tcpHeart.sn);
- strcat(pJson, "\"}");
- return strlen(pJson);
- }
- //==============================================================================
- //@Functions
- //@brief
- // 将响应服务器 报文内容转为JSON格式字符串
- //
- //@param 输入:tcpAck ,输出:*pJson
- //@retval 返回JSON有效长度
- //==============================================================================
- static unsigned short AckToJson(char *pJson, tcpMsgDatAck_t tcpAck)
- {
- char buf[11] = {0};
- strcat(pJson, "{\"resultCode\":");
- sprintf(buf,"%d", tcpAck.resultCode);
- strcat(pJson, buf);
- strcat(pJson, "}");
- return strlen(pJson);
- }
- //==============================================================================
- //@Functions
- //@brief 按数据包格式将JSON格式ASCII码与帧控制,打包到pTcpBufBig中
- // 并添加CRC(大端格式)
- // tcpCtrl: 帧控制内容
- // *pJson JSON格式ASCII码
- // jsonLen JSON 有效长度
- // 格式 字长
- // |magic 1|len 4| ver 2| type 1| cmd 2| id 4| msgNum 4| utc 4|data[x]|crc16 2|
- //@param
- //@retval 返回包长
- //==============================================================================
- static unsigned short TcpMsgPack(tcpMsg_t *pTcpBufBig, tcpMsgCtrl_t tcpCtrl, char *pJson, unsigned short jsonLen)
- {
- unsigned int len;
- unsigned short crc16;
- memset(pTcpBufBig, 0, sizeof(tcpMsg_t));
- len = jsonLen + 24;//含CRC16,2字节
- if(len > TCP_SEND_BUF_LEN) return 0;
- pTcpBufBig->magic = TCP_MAGIC;
- pTcpBufBig->ctrl.len = BigLittle32Conv(len);
- pTcpBufBig->ctrl.ver = BigLittle16Conv(tcpCtrl.ver);
- pTcpBufBig->ctrl.type = tcpCtrl.type;
- pTcpBufBig->ctrl.cmd = BigLittle16Conv(tcpCtrl.cmd);
- pTcpBufBig->ctrl.id = BigLittle32Conv(tcpCtrl.id);//消息ID
- pTcpBufBig->ctrl.msgNum = BigLittle32Conv(tcpCtrl.msgNum);//消息流水号
- pTcpBufBig->ctrl.utc = BigLittle32Conv(tcpCtrl.utc);//UTC时间戳
- memcpy(pTcpBufBig->data, pJson, jsonLen);
- crc16 = crc_xmodem((unsigned char *)pTcpBufBig, len - 2);
- //crc16 在len长度的最后2字节
- *((unsigned char *)pTcpBufBig + len-2) = crc16>>8;//大端,低地址放高字节
- *((unsigned char *)pTcpBufBig + len-1) = crc16; //高地址放低字节
- return (unsigned short)len;
- }
- //==============================================================================
- //@Functions
- //@brief
- // 将登录信息打包,与 帧控制 合成传输帧格式,存放在pBuf中
- //
- //@param 输入:tcpLogin 登录信息, tcpCtrl 帧控制,输出:*pBuf 通信发送缓存
- //@retval 返回包长
- //==============================================================================
- unsigned short TcpPackLogin(unsigned char *pBuf, tcpMsgCtrl_t tcpCtrl, tcpMsgDatLogin_t tcpLogin)
- {
- char json[TCP_DATA_NUM_MAX] = {0};
- unsigned short jsonLen;
- jsonLen = LoginToJson(json, tcpLogin);//生成 Login JSON数据
- return TcpMsgPack((tcpMsg_t *)pBuf, tcpCtrl, json, jsonLen);
- }
- //==============================================================================
- //@Functions
- //@brief
- // 将上传报文内容打包,与 帧控制 合成传输帧格式,存放在pBuf中
- //
- //@param 输入:tcpUpload 待上传数据,tcpCtrl 帧控制,输出:*pBuf 通信发送缓存
- //@retval 返回包长
- //==============================================================================
- unsigned short TcpPackUpload(unsigned char *pBuf, tcpMsgCtrl_t tcpCtrl, tcpMsgDatUpload_t tcpUpload)
- {
- char json[TCP_DATA_NUM_MAX] = {0};
- unsigned short jsonLen;
- jsonLen = UploadToJson(json, tcpUpload);//生成 Upload JSON数据
- return TcpMsgPack((tcpMsg_t *)pBuf, tcpCtrl, json, jsonLen);
- }
- //==============================================================================
- //@Functions
- //@brief
- // 将 心跳 报文内容打包,与 帧控制 合成传输帧格式,存放在pBuf中
- //
- //@param 输入:tcpHeart 待上传数据,tcpCtrl 帧控制,输出:*pBuf 通信发送缓存
- //@retval 返回包长
- //==============================================================================
- unsigned short TcpPackHeart(unsigned char *pBuf, tcpMsgCtrl_t tcpCtrl, tcpMsgDatHeart_t tcpHeart)
- {
- char json[TCP_DATA_NUM_MAX] = {0};
- unsigned short jsonLen;
- jsonLen = HeartToJson(json, tcpHeart);//生成 Heart JSON数据
- return TcpMsgPack((tcpMsg_t *)pBuf, tcpCtrl, json, jsonLen);
- }
- //==============================================================================
- //@Functions
- //@brief
- // 将响应服务器报文内容打包,与 帧控制 合成传输帧格式,存放在pBuf中
- //
- //@param 输入:tcpAck ,tcpCtrl 帧控制,输出:*pBuf 通信发送缓存
- //@retval 返回包长
- //==============================================================================
- unsigned short TcpPackAck(unsigned char *pBuf, tcpMsgCtrl_t tcpCtrl, tcpMsgDatAck_t tcpAck)
- {
- char json[TCP_DATA_NUM_MAX] = {0};
- unsigned short jsonLen;
- jsonLen = AckToJson(json, tcpAck);//生成 tcpAck JSON数据
- return TcpMsgPack((tcpMsg_t *)pBuf, tcpCtrl, json, jsonLen);
- }
- //==============================================================================
- //@Functions
- //@brief
- // 将接收到TCP帧校验、解包,提取帧控制内容 和 JSON数据
- //
- //@param 输入:帧指针 *pBuf ,输出: 帧控制 *pTcpCtrl, Json内容指针的指针 *pJson
- //@retval 1---校验正确 0---校验错误
- //==============================================================================
- unsigned char TcpUnPackAndCheck(tcpMsgCtrl_t *pTcpCtrl, char **pJson, tcpMsg_t *pTcpMsgRecv)
- {
- unsigned short recvCrc, crc;
- if(pTcpMsgRecv->magic != TCP_MAGIC)
- {
- return 0;
- }
- pTcpCtrl->len = BigLittle32Conv(pTcpMsgRecv->ctrl.len);//获取长度整个包长度,大小端转换
- crc = crc_xmodem((unsigned char *)pTcpMsgRecv, pTcpCtrl->len - 2);
- recvCrc = *(unsigned short *)((unsigned char *)pTcpMsgRecv + pTcpCtrl->len - 2);
- recvCrc = BigLittle16Conv(recvCrc);
- if(crc != recvCrc)
- {
- return 0;
- }
- pTcpCtrl->ver = BigLittle16Conv(pTcpMsgRecv->ctrl.ver);
- pTcpCtrl->type = pTcpMsgRecv->ctrl.type;
- pTcpCtrl->cmd = BigLittle16Conv(pTcpMsgRecv->ctrl.cmd);
- pTcpCtrl->id = BigLittle32Conv(pTcpMsgRecv->ctrl.id);
- pTcpCtrl->msgNum = BigLittle32Conv(pTcpMsgRecv->ctrl.msgNum);
- pTcpCtrl->utc = BigLittle32Conv(pTcpMsgRecv->ctrl.utc);
- *pJson = pTcpMsgRecv->data;
- return 1;
- }
- //==============================================================================
- //@Functions
- //@brief
- // 将接收到的登录响应 data(JSON格式)内容解包至指定位置
- // 报文data(JSON格式): : {"resultCode":0}
- //@param 输入:data(JSON格式)起始地址 ,输出:*pTcpAck 登录响应内容
- //@retval 返回 0--解析失败 1--解析成功
- //==============================================================================
- unsigned char TcpJsonToAck(tcpMsgDatAck_t *pTcpAck, char *pJson)
- {
- char *pStrData;
- int number;
- if(pJson[0]!='{')return 0;//必须以"{"开头
- pStrData = SearchFromStr(pJson, "\"resultCode\":");
- if(pStrData == NULL)
- {
- return 0;
- }
- StrNumToInt(&number, pStrData);
- pTcpAck->resultCode = number;
- return 1;
- }
- //==============================================================================
- //@Functions
- //@brief
- // 将接收到的设置参数报文 data(JSON格式)内容解包至指定位置
- // 报文data(JSON格式):
- //{
- // "sn": "sn1234567891",
- // "attrs":
- // {
- // }
- //}
- //@param 输入:data(JSON格式)起始地址 ,输出:*pTcpDownload 服务器下发参数
- //@retval 返回 0--解析失败,数据非法 >0--解析成功 成功获取了一项或一项以上的值并修改了pTcpDownload
- //
- //==============================================================================
- unsigned char TcpJsonToDownload(tcpMsgDatDownload_t *pTcpDownload, char *pJson)
- {
- /*
- char *pStrData;
- int result = 0;
- if(pJson[0]!='{')return 0;//必须以"{"开头
- //查找"sn":"
- if(GetStrValueFromJson(pJson, "sn", pTcpDownload->sn, 16)) result++;
- //DtuNewVer
- if(GetUShortVFromJson(pJson, "DtuNewVer", (unsigned short *)&pTcpDownload->dtuNewVer)) result++;
- //OfflineTime
- if(GetUCharVFromJson(pJson, "OfflineTime", &pTcpDownload->offlineTime)) result++;
- //InTDSAdj
- if(GetShortVFromJson(pJson, "InTDSAdj", (short *)&pTcpDownload->inTDSAdj)) result++;
- //OutTDSAdj
- if(GetShortVFromJson(pJson, "OutTDSAdj", (short *)&pTcpDownload->outTDSAdj)) result++;
- //Speed1
- if(GetUShortVFromJson(pJson, "Speed1", (unsigned short *)&pTcpDownload->speed1)) result++;
- //Speed2
- if(GetUShortVFromJson(pJson, "Speed2", (unsigned short *)&pTcpDownload->speed2)) result++;
- //WorkMode
- if(GetUCharVFromJson(pJson, "WorkMode", &pTcpDownload->workMode)) result++;
- //PowerOnTimeReset
- if(GetAAAAUShortVFromJson(pJson, "PowerOnTimeReset", (unsigned short *)pTcpDownload->powerOnTimeReset, 4)) result++;
- // WaterflowReset
- if(GetAAAAUShortVFromJson(pJson, "WaterflowReset", (unsigned short *)pTcpDownload->waterflowReset, 4)) result++;
- //
- return result;
- */
- }
- /*
- unsigned char TcpJsonToDownload(tcpMsgDatDownload_t *pTcpDownload, char *pJson)
- {
- char *pStrData;
- char result = 0;
- int number;
- if(pJson[0]!='{')return 0;//必须以"{"开头
- //查找"sn":"
- pStrData = SearchFromStr(pJson, "\"sn\":\"");
- if(pStrData != NULL)
- {
- result++;
- StrToAsc(pTcpDownload->sn, pStrData, 16);
- }
- //DtuNewVer
- pStrData = SearchFromStr(pJson, "\"DtuNewVer\":");
- if(pStrData != NULL)
- {
- result++;
- StrNumToInt(&number, pStrData);
- pTcpDownload->dtuNewVer = number;
- }
- //OfflineTime
- pStrData = SearchFromStr(pJson, "\"OfflineTime\":");
- if(pStrData != NULL)
- {
- result++;
- StrNumToInt(&number, pStrData);
- pTcpDownload->offlineTime = number;
- }
- //InTDSAdj
- pStrData = SearchFromStr(pJson, "\"InTDSAdj\":");
- if(pStrData != NULL)
- {
- result++;
- StrNumToInt(&number, pStrData);
- pTcpDownload->inTDSAdj = number;
- }
- //OutTDSAdj
- pStrData = SearchFromStr(pJson, "\"OutTDSAdj\":");
- if(pStrData != NULL)
- {
- result++;
- StrNumToInt(&number, pStrData);
- pTcpDownload->outTDSAdj = number;
- }
- //Speed1
- pStrData = SearchFromStr(pJson, "\"Speed1\":");
- if(pStrData != NULL)
- {
- result++;
- StrNumToInt(&number, pStrData);
- pTcpDownload->speed1 = number;
- }
- //Speed2
- pStrData = SearchFromStr(pJson, "\"Speed2\":");
- if(pStrData != NULL)
- {
- result++;
- StrNumToInt(&number, pStrData);
- pTcpDownload->speed2 = number;
- }
- //WorkMode
- pStrData = SearchFromStr(pJson, "\"WorkMode\":");
- if(pStrData != NULL)
- {
- result++;
- StrNumToInt(&number, pStrData);
- pTcpDownload->workMode = number;
- }
- //PowerOnTimeReset
- pStrData = SearchFromStr(pJson, "\"PowerOnTimeReset\":[");
- if(pStrData != NULL)
- {
- result++;
- StrNumToInt(&number, pStrData);
- pTcpDownload->powerOnTimeReset[0] = number;
- //查找PowerOnTimeReset[]内第一个",",获取其后地址
- pStrData = SearchFromStr(pStrData, ",");
- if(pStrData != NULL)
- {
- StrNumToInt(&number, pStrData);
- pTcpDownload->powerOnTimeReset[1] = number;
- }
- //查找PowerOnTimeReset[]内第二个",",获取其后地址
- pStrData = SearchFromStr(pStrData, ",");
- if(pStrData != NULL)
- {
- StrNumToInt(&number, pStrData);
- pTcpDownload->powerOnTimeReset[2] = number;
- }
- //查找PowerOnTimeReset[]内第三个",",获取其后地址
- pStrData = SearchFromStr(pStrData, ",");
- if(pStrData != NULL)
- {
- StrNumToInt(&number, pStrData);
- pTcpDownload->powerOnTimeReset[3] = number;
- }
- }
- // WaterflowReset
- pStrData = SearchFromStr(pJson, "\"WaterflowReset\":[");
- if(pStrData != NULL)
- {
- result++;
- StrNumToInt(&number, pStrData);
- pTcpDownload->waterflowReset[0] = number;
- //查找PowerOnTimeReset[]内第一个",",获取其后地址
- pStrData = SearchFromStr(pStrData, ",");
- if(pStrData != NULL)
- {
- StrNumToInt(&number, pStrData);
- pTcpDownload->waterflowReset[1] = number;
- }
- //查找PowerOnTimeReset[]内第二个",",获取其后地址
- pStrData = SearchFromStr(pStrData, ",");
- if(pStrData != NULL)
- {
- StrNumToInt(&number, pStrData);
- pTcpDownload->waterflowReset[2] = number;
- }
- //查找PowerOnTimeReset[]内第三个",",获取其后地址
- pStrData = SearchFromStr(pStrData, ",");
- if(pStrData != NULL)
- {
- StrNumToInt(&number, pStrData);
- pTcpDownload->waterflowReset[3] = number;
- }
- }
- //
- if(result)
- {
- return 1;
- }
- else
- {
- return 0;
- }
- }
- */
- /*
- //==============================================================================
- //@Functions
- //@brief
- // 测试
- //
- //@param
- //@retval
- //==============================================================================
- unsigned char tcpSendMsgBigend[600];
- void TcpCommDebug1(void)
- {
- int length;
- tcpSendMsgCtrl.ver = 0x1234;
- tcpSendMsgCtrl.id = 0;
- tcpSendMsgCtrl.msgNum = 0x12345678;
- tcpSendMsgCtrl.utc = 0x12345678;
- tcpSendMsgCtrl.type = TCP_TYPE_REQ;
- tcpSendMsgCtrl.cmd = TCP_CMD_LOGIN;
-
- //发送注册数据
- tcpSendMsgCtrl.type = TCP_TYPE_REQ;
- tcpSendMsgCtrl.cmd = TCP_CMD_LOGIN;
- strcpy(tcpMsgDatLogin.deviceId, "2017041300001");
- strcpy(tcpMsgDatLogin.deviceType, "WP202");
- strcpy(tcpMsgDatLogin.iccid, "8986031640020231458P");
- strcpy(tcpMsgDatLogin.imsi, "460030785666759");
- strcpy(tcpMsgDatLogin.vendor, "Ratelan");
- length = TcpPackLogin((unsigned char *)&tcpSendMsgBigend, tcpSendMsgCtrl, tcpMsgDatLogin);
- //printf("%s",tcpSendMsgBigend);
- //Uart1Send((char *)&tcpSendMsgBigend,length);
-
- //发送上传数据
- tcpSendMsgCtrl.type = TCP_TYPE_REQ;
- tcpSendMsgCtrl.cmd = TCP_CMD_UPLOAD;
- tcpMsgDatUpload.alarm = 0x01;
- strcpy(tcpMsgDatUpload.sn, "sn1234567891");
- tcpMsgDatUpload.dtuVer = 0x1234;
- tcpMsgDatUpload.status = 0x02;
- tcpMsgDatUpload.inTDS = 0x1234;
- tcpMsgDatUpload.outTDS = 0x1234;
- tcpMsgDatUpload.waterYield = 0x1234;
- tcpMsgDatUpload.powerOnTime[0] = 0x1234;
- tcpMsgDatUpload.powerOnTime[1] = 0x1234;
- tcpMsgDatUpload.powerOnTime[2] = 0x1234;
- tcpMsgDatUpload.powerOnTime[3] = 0x1234;
- tcpMsgDatUpload.waterflow[0] = 0x1234;
- tcpMsgDatUpload.waterflow[1] = 0x1234;
- tcpMsgDatUpload.waterflow[2] = 0x1234;
- tcpMsgDatUpload.waterflow[3] = 0x1234;
- tcpMsgDatUpload.offlineTime = 0x02;
- tcpMsgDatUpload.inTDSAdj = 0x3412;
- tcpMsgDatUpload.outTDSAdj = 0x3412;
- tcpMsgDatUpload.speed1 = 0x3412;
- tcpMsgDatUpload.speed2 = 0x3412;
- tcpMsgDatUpload.workMode= 0x01;
- length = TcpPackUpload((unsigned char *)&tcpSendMsgBigend, tcpSendMsgCtrl, tcpMsgDatUpload);
- //printf("%s",tcpSendMsgBigend);
- //Uart1Send((char *)&tcpSendMsgBigend,length);
- //send((unsigned char *)&tcpSendMsgBigend, length);
- //心跳
- tcpSendMsgCtrl.type = TCP_TYPE_REQ;
- tcpSendMsgCtrl.cmd = TCP_CMD_HEART;
- strcpy(tcpMsgDatHeart.sn, "sn1234567891");
- length = TcpPackHeart((unsigned char *)&tcpSendMsgBigend, tcpSendMsgCtrl, tcpMsgDatHeart);
- //printf("%s",tcpSendMsgBigend);
- //send((unsigned char *)&tcpSendMsgBigend, length);
- //响应
- tcpSendMsgCtrl.type = TCP_TYPE_ACK;
- tcpSendMsgCtrl.cmd = TCP_CMD_DOWNLOAD;
-
- tcpMsgDatDownloadAck.resultCode = 0x00;
- length = TcpPackAck((unsigned char *)&tcpSendMsgBigend, tcpSendMsgCtrl, tcpMsgDatDownloadAck);
- //printf("%s",tcpSendMsgBigend);
- //send((unsigned char *)&tcpSendMsgBigend, length);
- }
- */
- /*
- unsigned char len1 = 0, len2 = 0;
- int num = 0;
- char Str1[] = "12345abc";
- char Str2[] = "123456a\"";
- char asc[33] = {0};
- char json[] = "{\"resultCode\":-12,\"NewVer\":-345}";
- char json2[] = "{\"resultCode\":12}";
- tcpMsgDatAck_t loginAck1 = {0};
- unsigned char resultCode1 = 0, resultCode2 = 0;
- //{
- // "sn": "sn1234567891",
- // "attrs":
- // {
- // "DtuNewVer":123,
- // "OfflineTime":12,
- // "InTDSAdj":345,
- // "OutTDSAdj":67,
- // "Speed1":12,
- // "Speed2":12,
- // "WorkMode":1,
- // "PowerOnTimeReset":[0,0,0,0],
- // "WaterflowReset":[0,0,0,0]
- // }
- //}
- char jsonDownload[] = "{\"sn\":\"sn1234567891\",\"attrs\":{\"DtuNewVer\":123,\"OfflineTime\":12,\"InTDSAdj\":345,\"OutTDSAdj\":-67,\"Speed1\":12,\"Speed2\":12,\"WorkMode\":1,\"PowerOnTimeReset\":[12,34,567,890],\"WaterflowReset\":[123,456,789,0]}";
- unsigned char recvReg[] = {0x98,0x00,0x00,0x00,0x51,0x00,0x01,0x01,0x00, 0x01, 0x12, 0x34, 0x56, 0x78, 0x12, 0x34, 0x56,
- 0x78, 0x59, 0x03 ,0xEC, 0x10 ,0x7B ,0x22 ,0x72 ,0x65 ,0x73 ,0x75 ,0x6C ,0x74 ,0x43 ,0x6F ,0x64 ,0x65 ,0x22, 0x3A, 0x33,0x2C, 0x22, 0x72 ,0x65 ,0x61,
- 0x73, 0x6F, 0x6E ,0x22 ,0x3A ,0x22, 0x53 ,0x69 ,0x67 ,0x6E ,0x61, 0x74 ,0x75 ,0x72 ,0x65 ,0x20 ,0x76 ,0x65 ,0x72, 0x69, 0x66, 0x69 ,0x63 ,0x61 ,0x74,
- 0x69 ,0x6F ,0x6E ,0x20, 0x66 ,0x61 ,0x69 ,0x6C ,0x65 ,0x64 ,0x22, 0x7D ,0x71 ,0x17};// {"resultCode":3,"reason":"Signature verification failed"}
- unsigned char check;
- char *jsonRecv;
- tcpMsgCtrl_t tcpRecvCtrl = {0};
- void TcpCommDebug2(void)
- {
- //test
- len1 = StrNumToInt(&num, Str1);
- len2 = StrToAsc(asc, Str2, 16);
- resultCode1 = TcpJsonToAck(&loginAck1, json);
- resultCode2 = TcpJsonToAck(&tcpMsgDatUploadAck, json2);
- TcpJsonToDownload(&tcpMsgDatDownload, jsonDownload);
- check = TcpUnPackAndCheck(&tcpRecvCtrl, &jsonRecv, (tcpMsg_t *)recvReg);
- }
- */
|