/******************************************************************************** * 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); } */