TcpComm.c 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994
  1. /********************************************************************************
  2. * File Name: TcpComm.c
  3. * Function Describe: 通过TCP与服务器通信(TCP通信协议)
  4. * Explain:
  5. * Writer:
  6. * Date:
  7. *******************************************************************************/
  8. #include "includes.h"
  9. //-------------------------------------------------------------------------------
  10. //==============================================================================
  11. //@Functions
  12. //@brief 将32位大小端数据格式转换
  13. //@param
  14. //@retval 转换后的数据
  15. //==============================================================================
  16. unsigned int BigLittle32Conv(unsigned int srcData)
  17. {
  18. SUTDL dl1, dl2;//用于大小端转换
  19. dl1.Data.ulData = srcData;
  20. dl2.Data.ucData.b1 = dl1.Data.ucData.b4;
  21. dl2.Data.ucData.b2 = dl1.Data.ucData.b3;
  22. dl2.Data.ucData.b3 = dl1.Data.ucData.b2;
  23. dl2.Data.ucData.b4 = dl1.Data.ucData.b1;
  24. return dl2.Data.ulData;
  25. }
  26. //==============================================================================
  27. //@Functions
  28. //@brief 将16位大小端数据格式转换
  29. //@param
  30. //@retval 转换后的数据
  31. //==============================================================================
  32. unsigned short BigLittle16Conv(unsigned short srcData)
  33. {
  34. SUTDS ds1, ds2;//用于大小端转换
  35. ds1.Data.usData = srcData;
  36. ds2.Data.ucData.b1 = ds1.Data.ucData.b2;
  37. ds2.Data.ucData.b2 = ds1.Data.ucData.b1;
  38. return ds2.Data.usData;
  39. }
  40. //==============================================================================
  41. //@Functions
  42. //@brief 从pStr中找到pSearch,返回pSearch后的第一个地址(若无para则返回0)。可配合 StrNumToInt() 使用
  43. //举例:pStr=" "WorkEnable":1,"PowerOnTimeAdj":[123,45,-78,90], "
  44. // 如果pSearch="TimeAdj":[" 返回"123,45,-78,90], "
  45. // 如果pSearch="Work":" 返回"Enable":1,"PowerOnTimeAdj":[123,45,-78,90], "
  46. // 如果pSearch="abcd":" 返回NULL
  47. //@param
  48. //@retval pSearch后的第一个地址
  49. //==============================================================================
  50. char* SearchFromStr(char *pStr,char *pSearch)
  51. {
  52. char *pResult;
  53. unsigned char searchLen;
  54. pResult = strstr(pStr, pSearch);
  55. if(pResult == NULL)
  56. {
  57. return NULL;
  58. }
  59. searchLen = strlen(pSearch);
  60. pResult += searchLen;
  61. return pResult;
  62. }
  63. //==============================================================================
  64. //@Functions
  65. //@brief 指定位置开始,到非数字字符结束的数字字符串转换成整形数值(数值范围-2147483648~2147483647)
  66. // "65535,a" --> 65535(十六进制0xFFFF),返回5
  67. // "-123" --> -123(十六进制0x85),返回4
  68. // " -123" --> -123(十六进制0x85),返回5
  69. // "123456789,kk"--> 123456789,返回9
  70. //@param 输入: *pStrNum 字符串数字开始的指针
  71. // 输出 *pNum 转换的值
  72. //@retval 转换的字符串中数字长度(含"-"号和空格),0失败
  73. //==============================================================================
  74. static unsigned char StrNumToInt(int *pNum, char *pStrNum)
  75. {
  76. char i, numLen = 0;
  77. char buf[11] = {0};
  78. for(i = 0; i < 10; i++)
  79. {
  80. if(pStrNum[i]>0x39 || pStrNum[i]<0x30)
  81. {
  82. if(pStrNum[i] != ' ' && pStrNum[i] != '-') break;
  83. }
  84. buf[i] = pStrNum[i];
  85. numLen = i + 1;
  86. }
  87. buf[i] = 0;
  88. *pNum = atoi(buf);
  89. return numLen;
  90. }
  91. //==============================================================================
  92. //@Functions
  93. //@brief 获取 指定位置开始,到"结束的 字符串内容,并返回实际长度,若无",则获取最大长度
  94. // 17010001" --> 17010001(ASCII),返回8
  95. //
  96. //@param 输入: *pStr 字符串开始的指针 maxLen
  97. // 输出 *pAsc 转换的值
  98. //@retval 转换的字符串长度
  99. //==============================================================================
  100. static unsigned char StrToAsc(char *pAsc, char *pStr, unsigned char maxLen)
  101. {
  102. char i, numLen = 0;
  103. for(i = 0; i < maxLen; i++)
  104. {
  105. if(pStr[i] == '\"') break;//到"结束
  106. pAsc[i] = pStr[i];
  107. numLen = i + 1;
  108. }
  109. pAsc[i] = 0;
  110. return numLen;
  111. }
  112. //==============================================================================
  113. //GetIntVFromJson
  114. //从json串中根据字段名field提取其int类型的值拷贝到value中
  115. //返回:
  116. //0 获取失败, 找不到同名字段对应的值
  117. //>0 获取成功,并返回其值,存放在value中
  118. //<0 获取失败,值类型错误
  119. //==============================================================================
  120. int GetIntVFromJson(char *pJson,char *pField,int *pValue)
  121. {
  122. char *pStrData;
  123. int number;
  124. int fieldlen = strlen(pField);
  125. if(fieldlen < 1)return 0;
  126. pStrData = SearchFromStr(pJson, pField);
  127. if(*pStrData == '\"' && *(pStrData+1) == ':')
  128. {
  129. pStrData += 2;
  130. }
  131. else
  132. {
  133. return 0;
  134. }
  135. if(StrNumToInt(&number, pStrData))
  136. {
  137. *pValue = number;
  138. return 1;
  139. }
  140. else
  141. {
  142. return -1;
  143. }
  144. }
  145. /**************************************************************************
  146. GetShortVFromJson
  147. 从json串中根据字段名field提取其short类型的值拷贝到value中
  148. 返回:
  149. 0 获取失败, 找不到同名字段对应的值
  150. >0 获取成功,并返回其值,存放在value中
  151. <0 获取失败,值类型错误
  152. **************************************************************************/
  153. int GetShortVFromJson(char *json,char *field,short *value)
  154. {
  155. int r,v;
  156. r=GetIntVFromJson(json,field,&v);
  157. if(r>0){
  158. if(v<-32768 || v>32767)return -1;
  159. *value=v;
  160. return 0;
  161. }
  162. return r;
  163. }
  164. /**************************************************************************
  165. GetUShortVFromJson
  166. 从json串中根据字段名field提取其unsigned short类型的值拷贝到value中
  167. 返回:
  168. 0 获取失败, 找不到同名字段对应的值
  169. >0 获取成功,并返回其值,存放在value中
  170. <0 获取失败,值类型错误
  171. **************************************************************************/
  172. int GetUShortVFromJson(char *json,char *field,unsigned short *value)
  173. {
  174. int r,v;
  175. r=GetIntVFromJson(json,field,&v);
  176. if(r>0){
  177. if(v<0 || v>65535)return -1;
  178. *value=v;
  179. return 0;
  180. }
  181. return r;
  182. }
  183. /**************************************************************************
  184. GetUCharVFromJson
  185. 从json串中根据字段名field提取其unsigned char类型的值拷贝到value中
  186. 返回:
  187. 0 获取失败, 找不到同名字段对应的值
  188. >0 获取成功,并返回其值,存放在value中
  189. <0 获取失败,值类型错误
  190. **************************************************************************/
  191. int GetUCharVFromJson(char *json,char *field,unsigned char *value)
  192. {
  193. int r,v;
  194. r=GetIntVFromJson(json,field,&v);
  195. if(r>0){
  196. if(v<0 || v>255)return -1;
  197. *value=v;
  198. return 0;
  199. }
  200. return r;
  201. }
  202. /**************************************************************************
  203. GetStrValueFromJson
  204. 从json串中根据字段名field提取其""内的字符串类型的值拷贝到value中,约定value的最大长度为valuelen
  205. 返回:
  206. 0 获取失败,找不到同名字段对应的值
  207. >0 获取成功并返回value的长度
  208. <0 获取失败 value存储空间不够或结构不完整。
  209. **************************************************************************/
  210. int GetStrValueFromJson(char *pJson,char *pField,char *pValue,unsigned char maxLen)
  211. {
  212. char *pStrData;
  213. unsigned char strLen;
  214. int fieldlen = strlen(pField);
  215. if(fieldlen < 1)return 0;
  216. pStrData = SearchFromStr(pJson, pField);
  217. if(*pStrData == '\"' && *(pStrData+1) == ':' && *(pStrData+2) == '\"')
  218. {
  219. pStrData += 3;
  220. }
  221. else
  222. {
  223. return 0;
  224. }
  225. strLen = StrToAsc(pValue, pStrData, maxLen);
  226. if(strLen == maxLen && pValue[maxLen] != '\"')//
  227. {
  228. return -1;
  229. }
  230. else
  231. {
  232. return strLen;
  233. }
  234. }
  235. /**************************************************************************
  236. GetAUShortVFromJson
  237. 从json串中根据字段名field提取其unsigned short类型的值拷贝到value中
  238. 返回:
  239. 0 获取失败, 找不到同名字段对应的值
  240. >0 获取成功,并返回其值,存放在value中
  241. <0 获取失败,值类型错误
  242. **************************************************************************/
  243. int GetAAAAUShortVFromJson(char *pJson,char *pField,unsigned short value[],int num)
  244. {
  245. char *pStrData;
  246. int i, v;
  247. int fieldlen = strlen(pField);
  248. if(fieldlen < 1)return 0;
  249. pStrData = SearchFromStr(pJson, pField);
  250. if(*pStrData == '\"' && *(pStrData+1) == ':' && *(pStrData+2) == '[')
  251. {
  252. pStrData += 3;
  253. }
  254. else
  255. {
  256. return 0;
  257. }
  258. for(i = 0; i < num; i++)
  259. {
  260. if(StrNumToInt(&v, pStrData))
  261. {
  262. if(v<0 || v>65535)return -1;
  263. value[i] = v;
  264. }
  265. else
  266. {
  267. return -1;
  268. }
  269. //查找[]内下一个",",获取其后地址
  270. if(i < (num - 1))
  271. {
  272. pStrData = SearchFromStr(pStrData, ",");
  273. }
  274. }
  275. return 1;
  276. }
  277. //==============================================================================
  278. //@Functions
  279. //@brief
  280. // 登录信息转为JSON格式字符串
  281. //{
  282. //"imsi":"460030785666759",
  283. //"iccid":"8986031640020231458P",
  284. //"authType": 1,
  285. //"dtuVender":"xxxx",
  286. //"dtuId":xxxx,
  287. //"productKey": "xxxx",
  288. //"sn":"08e7a3ae-f8f3-4414-a312",
  289. //"md5": "9E107D9D372BB6826BD81D3542A419D6"
  290. //}
  291. //说明:
  292. //Imsi:卡imsi号,
  293. //Iccid:卡iccid号,
  294. //authType:接入方式。1:设备直连;2:DTU登陆;(待扩展)
  295. //dtuVender:DTU厂商编码,
  296. //dtuId:dtu编码,
  297. //productKey:产品(平台定义,固定10字节,数字和小写字母混合)
  298. //sn:设备编码
  299. //备注:
  300. //当authType是1(设备登陆)时, dtuVender, dtuId, productKey, sn都有效,dtuVender和dtuId选传,productKey,sn必传。
  301. //当authType是2(DTU登陆)时,dtuVender, dtuId字段必传,productKey和sn字段无效,可以不传。
  302. //
  303. //@param 输入:tcpLogin 登录信息,输出:*pJson
  304. //@retval 返回JSON有效长度
  305. //MD5:所发数据域中所有数值(不算数据名称)+DTU时间的10进制格式,全部ASCII形式 计算
  306. //==============================================================================
  307. static unsigned short LoginToJson(char *pJson, tcpMsgDatLogin_t tcpLogin)
  308. {
  309. char buf[12] = {0};
  310. char md5Buf[200] = {0};
  311. char i;
  312. MD5_CTX mdContext = {0};
  313. //------生成MD5-----------------------
  314. strcat(md5Buf, tcpLogin.imsi);
  315. strcat(md5Buf, tcpLogin.iccid);
  316. sprintf(buf,"%d", tcpLogin.authType);
  317. strcat(md5Buf, buf);
  318. strcat(md5Buf, tcpLogin.dtuVender);
  319. strcat(md5Buf, tcpLogin.dtuId);
  320. strcat(md5Buf, tcpLogin.productKey);
  321. strcat(md5Buf, tcpLogin.sn);
  322. sprintf(buf,"%d", tcpSendMsgCtrl.utc);
  323. strcat(md5Buf, buf);
  324. MD5Init(&mdContext);
  325. MD5Update(&mdContext, md5Buf, strlen(md5Buf));
  326. MD5Final(&mdContext);
  327. for(i = 0; i < 16; i++)
  328. {
  329. sprintf(&tcpLogin.md5[2*i],"%02x", mdContext.digest[i]);
  330. }
  331. //------生成JSON----------------------
  332. strcat(pJson, "{\"imsi\":\"");
  333. strcat(pJson, tcpLogin.imsi);
  334. strcat(pJson, "\",\"iccid\":\"");
  335. strcat(pJson, tcpLogin.iccid);
  336. strcat(pJson, "\",\"authType\":");
  337. sprintf(buf,"%d", tcpLogin.authType);
  338. strcat(pJson, buf);
  339. strcat(pJson, ",\"dtuVender\":\"");
  340. strcat(pJson, tcpLogin.dtuVender);
  341. strcat(pJson, "\",\"dtuId\":\"");
  342. strcat(pJson, tcpLogin.dtuId);
  343. strcat(pJson, "\",\"productKey\":\"");
  344. strcat(pJson, tcpLogin.productKey);
  345. strcat(pJson, "\",\"sn\":\"");
  346. strcat(pJson, tcpLogin.sn);
  347. strcat(pJson, "\",\"md5\":\"");
  348. strcat(pJson, tcpLogin.md5);
  349. strcat(pJson, "\"}");//
  350. return strlen(pJson);
  351. }
  352. //==============================================================================
  353. //@Functions
  354. //@brief
  355. //UPLOAD 报文数据
  356. //{
  357. // "sn": "123456789",
  358. // "attrs":
  359. // {
  360. // "Country":1,
  361. // "Province":1,
  362. // "District":1,
  363. // "Shipowner":1,
  364. // "ShipNumber":"XX01",
  365. // "Address":28,
  366. // "Type":1,
  367. // "Status":1,
  368. // "AntiTheft":[0,0,0,0,0],
  369. // "Reserve":[0,0,0,0]
  370. // }
  371. //}
  372. //数据说明:
  373. //sn:设备编号
  374. //Country:国家: 中国 1
  375. //Province:省份: 广东:1 (广东:1、广西:2、福建:3、海南:4、山东:5、浙江:6、辽宁:7、江苏:8、上海:9、天津:10、河北:11)
  376. //District:地区 (具体待定,DTU只透传)
  377. //Shipowner:船东(渔政船:1、渔业公司:2、个人船东:3)
  378. //ShipNumber:渔船号码。13位数
  379. //Address:地址码
  380. //Type:类型码: 感温:1;感烟:2;手报:3;输入模块:4;输出模块:5;声光报警器:6;地址接口模块:7
  381. //Status:状态码: 正常:1报警:2故障:3启动:4
  382. //AntiTheft:防盗预留
  383. //Reserve:预留
  384. //@param 输入:tcpUpload ,输出:*pJson
  385. //@retval 返回JSON有效长度
  386. //==============================================================================
  387. static unsigned short UploadToJson(char *pJson, tcpMsgDatUpload_t tcpUpload)
  388. {
  389. char buf[40] = {0};
  390. unsigned char i;
  391. strcat(pJson, "{\"sn\":\"");
  392. strcat(pJson, tcpUpload.sn);
  393. strcat(pJson, "\",\"attrs\":{\"Country\":");
  394. sprintf(buf,"%d", tcpUpload.country);
  395. strcat(pJson, buf);
  396. strcat(pJson, ",\"Province\":");
  397. sprintf(buf,"%d", tcpUpload.province);
  398. strcat(pJson, buf);
  399. strcat(pJson, ",\"District\":");
  400. sprintf(buf,"%d", tcpUpload.district);
  401. strcat(pJson, buf);
  402. strcat(pJson, ",\"Shipowner\":");
  403. sprintf(buf,"%d", tcpUpload.shipowner);
  404. strcat(pJson, buf);
  405. strcat(pJson, ",\"ShipNumber\":\"");
  406. for(i = 0; i < 13; i++)
  407. {
  408. sprintf(buf,"%d", tcpUpload.shipNumber[i]);
  409. strcat(pJson, buf);
  410. }
  411. strcat(pJson, "\",\"Address\":");
  412. sprintf(buf,"%d", tcpUpload.address);
  413. strcat(pJson, buf);
  414. strcat(pJson, ",\"Type\":");
  415. sprintf(buf,"%d", tcpUpload.type);
  416. strcat(pJson, buf);
  417. strcat(pJson, ",\"Status\":");
  418. sprintf(buf,"%d", tcpUpload.status);
  419. strcat(pJson, buf);
  420. strcat(pJson, ",\"AntiTheft\":");
  421. sprintf(buf,"[%d,%d,%d,%d,%d],", tcpUpload.antiTheft[0],tcpUpload.antiTheft[1],tcpUpload.antiTheft[2],tcpUpload.antiTheft[3],tcpUpload.antiTheft[4]);
  422. strcat(pJson, buf);
  423. strcat(pJson, "\"Reserve\":");
  424. sprintf(buf,"[%d,%d,%d,%d]", tcpUpload.reserve[0],tcpUpload.reserve[1],tcpUpload.reserve[2],tcpUpload.reserve[3]);
  425. strcat(pJson, buf);
  426. strcat(pJson, "}}");
  427. return strlen(pJson);
  428. }
  429. //==============================================================================
  430. //@Functions
  431. //@brief
  432. // 心跳报文内容转为JSON格式字符串
  433. //
  434. //@param 输入:tcpHeart ,输出:*pJson
  435. //@retval 返回JSON有效长度
  436. //==============================================================================
  437. static unsigned short HeartToJson(char *pJson, tcpMsgDatHeart_t tcpHeart)
  438. {
  439. strcat(pJson, "{\"sn\":\"");
  440. strcat(pJson, tcpHeart.sn);
  441. strcat(pJson, "\"}");
  442. return strlen(pJson);
  443. }
  444. //==============================================================================
  445. //@Functions
  446. //@brief
  447. // 将响应服务器 报文内容转为JSON格式字符串
  448. //
  449. //@param 输入:tcpAck ,输出:*pJson
  450. //@retval 返回JSON有效长度
  451. //==============================================================================
  452. static unsigned short AckToJson(char *pJson, tcpMsgDatAck_t tcpAck)
  453. {
  454. char buf[11] = {0};
  455. strcat(pJson, "{\"resultCode\":");
  456. sprintf(buf,"%d", tcpAck.resultCode);
  457. strcat(pJson, buf);
  458. strcat(pJson, "}");
  459. return strlen(pJson);
  460. }
  461. //==============================================================================
  462. //@Functions
  463. //@brief 按数据包格式将JSON格式ASCII码与帧控制,打包到pTcpBufBig中
  464. // 并添加CRC(大端格式)
  465. // tcpCtrl: 帧控制内容
  466. // *pJson JSON格式ASCII码
  467. // jsonLen JSON 有效长度
  468. // 格式 字长
  469. // |magic 1|len 4| ver 2| type 1| cmd 2| id 4| msgNum 4| utc 4|data[x]|crc16 2|
  470. //@param
  471. //@retval 返回包长
  472. //==============================================================================
  473. static unsigned short TcpMsgPack(tcpMsg_t *pTcpBufBig, tcpMsgCtrl_t tcpCtrl, char *pJson, unsigned short jsonLen)
  474. {
  475. unsigned int len;
  476. unsigned short crc16;
  477. memset(pTcpBufBig, 0, sizeof(tcpMsg_t));
  478. len = jsonLen + 24;//含CRC16,2字节
  479. if(len > TCP_SEND_BUF_LEN) return 0;
  480. pTcpBufBig->magic = TCP_MAGIC;
  481. pTcpBufBig->ctrl.len = BigLittle32Conv(len);
  482. pTcpBufBig->ctrl.ver = BigLittle16Conv(tcpCtrl.ver);
  483. pTcpBufBig->ctrl.type = tcpCtrl.type;
  484. pTcpBufBig->ctrl.cmd = BigLittle16Conv(tcpCtrl.cmd);
  485. pTcpBufBig->ctrl.id = BigLittle32Conv(tcpCtrl.id);//消息ID
  486. pTcpBufBig->ctrl.msgNum = BigLittle32Conv(tcpCtrl.msgNum);//消息流水号
  487. pTcpBufBig->ctrl.utc = BigLittle32Conv(tcpCtrl.utc);//UTC时间戳
  488. memcpy(pTcpBufBig->data, pJson, jsonLen);
  489. crc16 = crc_xmodem((unsigned char *)pTcpBufBig, len - 2);
  490. //crc16 在len长度的最后2字节
  491. *((unsigned char *)pTcpBufBig + len-2) = crc16>>8;//大端,低地址放高字节
  492. *((unsigned char *)pTcpBufBig + len-1) = crc16; //高地址放低字节
  493. return (unsigned short)len;
  494. }
  495. //==============================================================================
  496. //@Functions
  497. //@brief
  498. // 将登录信息打包,与 帧控制 合成传输帧格式,存放在pBuf中
  499. //
  500. //@param 输入:tcpLogin 登录信息, tcpCtrl 帧控制,输出:*pBuf 通信发送缓存
  501. //@retval 返回包长
  502. //==============================================================================
  503. unsigned short TcpPackLogin(unsigned char *pBuf, tcpMsgCtrl_t tcpCtrl, tcpMsgDatLogin_t tcpLogin)
  504. {
  505. char json[TCP_DATA_NUM_MAX] = {0};
  506. unsigned short jsonLen;
  507. jsonLen = LoginToJson(json, tcpLogin);//生成 Login JSON数据
  508. return TcpMsgPack((tcpMsg_t *)pBuf, tcpCtrl, json, jsonLen);
  509. }
  510. //==============================================================================
  511. //@Functions
  512. //@brief
  513. // 将上传报文内容打包,与 帧控制 合成传输帧格式,存放在pBuf中
  514. //
  515. //@param 输入:tcpUpload 待上传数据,tcpCtrl 帧控制,输出:*pBuf 通信发送缓存
  516. //@retval 返回包长
  517. //==============================================================================
  518. unsigned short TcpPackUpload(unsigned char *pBuf, tcpMsgCtrl_t tcpCtrl, tcpMsgDatUpload_t tcpUpload)
  519. {
  520. char json[TCP_DATA_NUM_MAX] = {0};
  521. unsigned short jsonLen;
  522. jsonLen = UploadToJson(json, tcpUpload);//生成 Upload JSON数据
  523. return TcpMsgPack((tcpMsg_t *)pBuf, tcpCtrl, json, jsonLen);
  524. }
  525. //==============================================================================
  526. //@Functions
  527. //@brief
  528. // 将 心跳 报文内容打包,与 帧控制 合成传输帧格式,存放在pBuf中
  529. //
  530. //@param 输入:tcpHeart 待上传数据,tcpCtrl 帧控制,输出:*pBuf 通信发送缓存
  531. //@retval 返回包长
  532. //==============================================================================
  533. unsigned short TcpPackHeart(unsigned char *pBuf, tcpMsgCtrl_t tcpCtrl, tcpMsgDatHeart_t tcpHeart)
  534. {
  535. char json[TCP_DATA_NUM_MAX] = {0};
  536. unsigned short jsonLen;
  537. jsonLen = HeartToJson(json, tcpHeart);//生成 Heart JSON数据
  538. return TcpMsgPack((tcpMsg_t *)pBuf, tcpCtrl, json, jsonLen);
  539. }
  540. //==============================================================================
  541. //@Functions
  542. //@brief
  543. // 将响应服务器报文内容打包,与 帧控制 合成传输帧格式,存放在pBuf中
  544. //
  545. //@param 输入:tcpAck ,tcpCtrl 帧控制,输出:*pBuf 通信发送缓存
  546. //@retval 返回包长
  547. //==============================================================================
  548. unsigned short TcpPackAck(unsigned char *pBuf, tcpMsgCtrl_t tcpCtrl, tcpMsgDatAck_t tcpAck)
  549. {
  550. char json[TCP_DATA_NUM_MAX] = {0};
  551. unsigned short jsonLen;
  552. jsonLen = AckToJson(json, tcpAck);//生成 tcpAck JSON数据
  553. return TcpMsgPack((tcpMsg_t *)pBuf, tcpCtrl, json, jsonLen);
  554. }
  555. //==============================================================================
  556. //@Functions
  557. //@brief
  558. // 将接收到TCP帧校验、解包,提取帧控制内容 和 JSON数据
  559. //
  560. //@param 输入:帧指针 *pBuf ,输出: 帧控制 *pTcpCtrl, Json内容指针的指针 *pJson
  561. //@retval 1---校验正确 0---校验错误
  562. //==============================================================================
  563. unsigned char TcpUnPackAndCheck(tcpMsgCtrl_t *pTcpCtrl, char **pJson, tcpMsg_t *pTcpMsgRecv)
  564. {
  565. unsigned short recvCrc, crc;
  566. if(pTcpMsgRecv->magic != TCP_MAGIC)
  567. {
  568. return 0;
  569. }
  570. pTcpCtrl->len = BigLittle32Conv(pTcpMsgRecv->ctrl.len);//获取长度整个包长度,大小端转换
  571. crc = crc_xmodem((unsigned char *)pTcpMsgRecv, pTcpCtrl->len - 2);
  572. recvCrc = *(unsigned short *)((unsigned char *)pTcpMsgRecv + pTcpCtrl->len - 2);
  573. recvCrc = BigLittle16Conv(recvCrc);
  574. if(crc != recvCrc)
  575. {
  576. return 0;
  577. }
  578. pTcpCtrl->ver = BigLittle16Conv(pTcpMsgRecv->ctrl.ver);
  579. pTcpCtrl->type = pTcpMsgRecv->ctrl.type;
  580. pTcpCtrl->cmd = BigLittle16Conv(pTcpMsgRecv->ctrl.cmd);
  581. pTcpCtrl->id = BigLittle32Conv(pTcpMsgRecv->ctrl.id);
  582. pTcpCtrl->msgNum = BigLittle32Conv(pTcpMsgRecv->ctrl.msgNum);
  583. pTcpCtrl->utc = BigLittle32Conv(pTcpMsgRecv->ctrl.utc);
  584. *pJson = pTcpMsgRecv->data;
  585. return 1;
  586. }
  587. //==============================================================================
  588. //@Functions
  589. //@brief
  590. // 将接收到的登录响应 data(JSON格式)内容解包至指定位置
  591. // 报文data(JSON格式): : {"resultCode":0}
  592. //@param 输入:data(JSON格式)起始地址 ,输出:*pTcpAck 登录响应内容
  593. //@retval 返回 0--解析失败 1--解析成功
  594. //==============================================================================
  595. unsigned char TcpJsonToAck(tcpMsgDatAck_t *pTcpAck, char *pJson)
  596. {
  597. char *pStrData;
  598. int number;
  599. if(pJson[0]!='{')return 0;//必须以"{"开头
  600. pStrData = SearchFromStr(pJson, "\"resultCode\":");
  601. if(pStrData == NULL)
  602. {
  603. return 0;
  604. }
  605. StrNumToInt(&number, pStrData);
  606. pTcpAck->resultCode = number;
  607. return 1;
  608. }
  609. //==============================================================================
  610. //@Functions
  611. //@brief
  612. // 将接收到的设置参数报文 data(JSON格式)内容解包至指定位置
  613. // 报文data(JSON格式):
  614. //{
  615. // "sn": "sn1234567891",
  616. // "attrs":
  617. // {
  618. // }
  619. //}
  620. //@param 输入:data(JSON格式)起始地址 ,输出:*pTcpDownload 服务器下发参数
  621. //@retval 返回 0--解析失败,数据非法 >0--解析成功 成功获取了一项或一项以上的值并修改了pTcpDownload
  622. //
  623. //==============================================================================
  624. unsigned char TcpJsonToDownload(tcpMsgDatDownload_t *pTcpDownload, char *pJson)
  625. {
  626. /*
  627. char *pStrData;
  628. int result = 0;
  629. if(pJson[0]!='{')return 0;//必须以"{"开头
  630. //查找"sn":"
  631. if(GetStrValueFromJson(pJson, "sn", pTcpDownload->sn, 16)) result++;
  632. //DtuNewVer
  633. if(GetUShortVFromJson(pJson, "DtuNewVer", (unsigned short *)&pTcpDownload->dtuNewVer)) result++;
  634. //OfflineTime
  635. if(GetUCharVFromJson(pJson, "OfflineTime", &pTcpDownload->offlineTime)) result++;
  636. //InTDSAdj
  637. if(GetShortVFromJson(pJson, "InTDSAdj", (short *)&pTcpDownload->inTDSAdj)) result++;
  638. //OutTDSAdj
  639. if(GetShortVFromJson(pJson, "OutTDSAdj", (short *)&pTcpDownload->outTDSAdj)) result++;
  640. //Speed1
  641. if(GetUShortVFromJson(pJson, "Speed1", (unsigned short *)&pTcpDownload->speed1)) result++;
  642. //Speed2
  643. if(GetUShortVFromJson(pJson, "Speed2", (unsigned short *)&pTcpDownload->speed2)) result++;
  644. //WorkMode
  645. if(GetUCharVFromJson(pJson, "WorkMode", &pTcpDownload->workMode)) result++;
  646. //PowerOnTimeReset
  647. if(GetAAAAUShortVFromJson(pJson, "PowerOnTimeReset", (unsigned short *)pTcpDownload->powerOnTimeReset, 4)) result++;
  648. // WaterflowReset
  649. if(GetAAAAUShortVFromJson(pJson, "WaterflowReset", (unsigned short *)pTcpDownload->waterflowReset, 4)) result++;
  650. //
  651. return result;
  652. */
  653. }
  654. /*
  655. unsigned char TcpJsonToDownload(tcpMsgDatDownload_t *pTcpDownload, char *pJson)
  656. {
  657. char *pStrData;
  658. char result = 0;
  659. int number;
  660. if(pJson[0]!='{')return 0;//必须以"{"开头
  661. //查找"sn":"
  662. pStrData = SearchFromStr(pJson, "\"sn\":\"");
  663. if(pStrData != NULL)
  664. {
  665. result++;
  666. StrToAsc(pTcpDownload->sn, pStrData, 16);
  667. }
  668. //DtuNewVer
  669. pStrData = SearchFromStr(pJson, "\"DtuNewVer\":");
  670. if(pStrData != NULL)
  671. {
  672. result++;
  673. StrNumToInt(&number, pStrData);
  674. pTcpDownload->dtuNewVer = number;
  675. }
  676. //OfflineTime
  677. pStrData = SearchFromStr(pJson, "\"OfflineTime\":");
  678. if(pStrData != NULL)
  679. {
  680. result++;
  681. StrNumToInt(&number, pStrData);
  682. pTcpDownload->offlineTime = number;
  683. }
  684. //InTDSAdj
  685. pStrData = SearchFromStr(pJson, "\"InTDSAdj\":");
  686. if(pStrData != NULL)
  687. {
  688. result++;
  689. StrNumToInt(&number, pStrData);
  690. pTcpDownload->inTDSAdj = number;
  691. }
  692. //OutTDSAdj
  693. pStrData = SearchFromStr(pJson, "\"OutTDSAdj\":");
  694. if(pStrData != NULL)
  695. {
  696. result++;
  697. StrNumToInt(&number, pStrData);
  698. pTcpDownload->outTDSAdj = number;
  699. }
  700. //Speed1
  701. pStrData = SearchFromStr(pJson, "\"Speed1\":");
  702. if(pStrData != NULL)
  703. {
  704. result++;
  705. StrNumToInt(&number, pStrData);
  706. pTcpDownload->speed1 = number;
  707. }
  708. //Speed2
  709. pStrData = SearchFromStr(pJson, "\"Speed2\":");
  710. if(pStrData != NULL)
  711. {
  712. result++;
  713. StrNumToInt(&number, pStrData);
  714. pTcpDownload->speed2 = number;
  715. }
  716. //WorkMode
  717. pStrData = SearchFromStr(pJson, "\"WorkMode\":");
  718. if(pStrData != NULL)
  719. {
  720. result++;
  721. StrNumToInt(&number, pStrData);
  722. pTcpDownload->workMode = number;
  723. }
  724. //PowerOnTimeReset
  725. pStrData = SearchFromStr(pJson, "\"PowerOnTimeReset\":[");
  726. if(pStrData != NULL)
  727. {
  728. result++;
  729. StrNumToInt(&number, pStrData);
  730. pTcpDownload->powerOnTimeReset[0] = number;
  731. //查找PowerOnTimeReset[]内第一个",",获取其后地址
  732. pStrData = SearchFromStr(pStrData, ",");
  733. if(pStrData != NULL)
  734. {
  735. StrNumToInt(&number, pStrData);
  736. pTcpDownload->powerOnTimeReset[1] = number;
  737. }
  738. //查找PowerOnTimeReset[]内第二个",",获取其后地址
  739. pStrData = SearchFromStr(pStrData, ",");
  740. if(pStrData != NULL)
  741. {
  742. StrNumToInt(&number, pStrData);
  743. pTcpDownload->powerOnTimeReset[2] = number;
  744. }
  745. //查找PowerOnTimeReset[]内第三个",",获取其后地址
  746. pStrData = SearchFromStr(pStrData, ",");
  747. if(pStrData != NULL)
  748. {
  749. StrNumToInt(&number, pStrData);
  750. pTcpDownload->powerOnTimeReset[3] = number;
  751. }
  752. }
  753. // WaterflowReset
  754. pStrData = SearchFromStr(pJson, "\"WaterflowReset\":[");
  755. if(pStrData != NULL)
  756. {
  757. result++;
  758. StrNumToInt(&number, pStrData);
  759. pTcpDownload->waterflowReset[0] = number;
  760. //查找PowerOnTimeReset[]内第一个",",获取其后地址
  761. pStrData = SearchFromStr(pStrData, ",");
  762. if(pStrData != NULL)
  763. {
  764. StrNumToInt(&number, pStrData);
  765. pTcpDownload->waterflowReset[1] = number;
  766. }
  767. //查找PowerOnTimeReset[]内第二个",",获取其后地址
  768. pStrData = SearchFromStr(pStrData, ",");
  769. if(pStrData != NULL)
  770. {
  771. StrNumToInt(&number, pStrData);
  772. pTcpDownload->waterflowReset[2] = number;
  773. }
  774. //查找PowerOnTimeReset[]内第三个",",获取其后地址
  775. pStrData = SearchFromStr(pStrData, ",");
  776. if(pStrData != NULL)
  777. {
  778. StrNumToInt(&number, pStrData);
  779. pTcpDownload->waterflowReset[3] = number;
  780. }
  781. }
  782. //
  783. if(result)
  784. {
  785. return 1;
  786. }
  787. else
  788. {
  789. return 0;
  790. }
  791. }
  792. */
  793. /*
  794. //==============================================================================
  795. //@Functions
  796. //@brief
  797. // 测试
  798. //
  799. //@param
  800. //@retval
  801. //==============================================================================
  802. unsigned char tcpSendMsgBigend[600];
  803. void TcpCommDebug1(void)
  804. {
  805. int length;
  806. tcpSendMsgCtrl.ver = 0x1234;
  807. tcpSendMsgCtrl.id = 0;
  808. tcpSendMsgCtrl.msgNum = 0x12345678;
  809. tcpSendMsgCtrl.utc = 0x12345678;
  810. tcpSendMsgCtrl.type = TCP_TYPE_REQ;
  811. tcpSendMsgCtrl.cmd = TCP_CMD_LOGIN;
  812. //发送注册数据
  813. tcpSendMsgCtrl.type = TCP_TYPE_REQ;
  814. tcpSendMsgCtrl.cmd = TCP_CMD_LOGIN;
  815. strcpy(tcpMsgDatLogin.deviceId, "2017041300001");
  816. strcpy(tcpMsgDatLogin.deviceType, "WP202");
  817. strcpy(tcpMsgDatLogin.iccid, "8986031640020231458P");
  818. strcpy(tcpMsgDatLogin.imsi, "460030785666759");
  819. strcpy(tcpMsgDatLogin.vendor, "Ratelan");
  820. length = TcpPackLogin((unsigned char *)&tcpSendMsgBigend, tcpSendMsgCtrl, tcpMsgDatLogin);
  821. //printf("%s",tcpSendMsgBigend);
  822. //Uart1Send((char *)&tcpSendMsgBigend,length);
  823. //发送上传数据
  824. tcpSendMsgCtrl.type = TCP_TYPE_REQ;
  825. tcpSendMsgCtrl.cmd = TCP_CMD_UPLOAD;
  826. tcpMsgDatUpload.alarm = 0x01;
  827. strcpy(tcpMsgDatUpload.sn, "sn1234567891");
  828. tcpMsgDatUpload.dtuVer = 0x1234;
  829. tcpMsgDatUpload.status = 0x02;
  830. tcpMsgDatUpload.inTDS = 0x1234;
  831. tcpMsgDatUpload.outTDS = 0x1234;
  832. tcpMsgDatUpload.waterYield = 0x1234;
  833. tcpMsgDatUpload.powerOnTime[0] = 0x1234;
  834. tcpMsgDatUpload.powerOnTime[1] = 0x1234;
  835. tcpMsgDatUpload.powerOnTime[2] = 0x1234;
  836. tcpMsgDatUpload.powerOnTime[3] = 0x1234;
  837. tcpMsgDatUpload.waterflow[0] = 0x1234;
  838. tcpMsgDatUpload.waterflow[1] = 0x1234;
  839. tcpMsgDatUpload.waterflow[2] = 0x1234;
  840. tcpMsgDatUpload.waterflow[3] = 0x1234;
  841. tcpMsgDatUpload.offlineTime = 0x02;
  842. tcpMsgDatUpload.inTDSAdj = 0x3412;
  843. tcpMsgDatUpload.outTDSAdj = 0x3412;
  844. tcpMsgDatUpload.speed1 = 0x3412;
  845. tcpMsgDatUpload.speed2 = 0x3412;
  846. tcpMsgDatUpload.workMode= 0x01;
  847. length = TcpPackUpload((unsigned char *)&tcpSendMsgBigend, tcpSendMsgCtrl, tcpMsgDatUpload);
  848. //printf("%s",tcpSendMsgBigend);
  849. //Uart1Send((char *)&tcpSendMsgBigend,length);
  850. //send((unsigned char *)&tcpSendMsgBigend, length);
  851. //心跳
  852. tcpSendMsgCtrl.type = TCP_TYPE_REQ;
  853. tcpSendMsgCtrl.cmd = TCP_CMD_HEART;
  854. strcpy(tcpMsgDatHeart.sn, "sn1234567891");
  855. length = TcpPackHeart((unsigned char *)&tcpSendMsgBigend, tcpSendMsgCtrl, tcpMsgDatHeart);
  856. //printf("%s",tcpSendMsgBigend);
  857. //send((unsigned char *)&tcpSendMsgBigend, length);
  858. //响应
  859. tcpSendMsgCtrl.type = TCP_TYPE_ACK;
  860. tcpSendMsgCtrl.cmd = TCP_CMD_DOWNLOAD;
  861. tcpMsgDatDownloadAck.resultCode = 0x00;
  862. length = TcpPackAck((unsigned char *)&tcpSendMsgBigend, tcpSendMsgCtrl, tcpMsgDatDownloadAck);
  863. //printf("%s",tcpSendMsgBigend);
  864. //send((unsigned char *)&tcpSendMsgBigend, length);
  865. }
  866. */
  867. /*
  868. unsigned char len1 = 0, len2 = 0;
  869. int num = 0;
  870. char Str1[] = "12345abc";
  871. char Str2[] = "123456a\"";
  872. char asc[33] = {0};
  873. char json[] = "{\"resultCode\":-12,\"NewVer\":-345}";
  874. char json2[] = "{\"resultCode\":12}";
  875. tcpMsgDatAck_t loginAck1 = {0};
  876. unsigned char resultCode1 = 0, resultCode2 = 0;
  877. //{
  878. // "sn": "sn1234567891",
  879. // "attrs":
  880. // {
  881. // "DtuNewVer":123,
  882. // "OfflineTime":12,
  883. // "InTDSAdj":345,
  884. // "OutTDSAdj":67,
  885. // "Speed1":12,
  886. // "Speed2":12,
  887. // "WorkMode":1,
  888. // "PowerOnTimeReset":[0,0,0,0],
  889. // "WaterflowReset":[0,0,0,0]
  890. // }
  891. //}
  892. 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]}";
  893. unsigned char recvReg[] = {0x98,0x00,0x00,0x00,0x51,0x00,0x01,0x01,0x00, 0x01, 0x12, 0x34, 0x56, 0x78, 0x12, 0x34, 0x56,
  894. 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,
  895. 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,
  896. 0x69 ,0x6F ,0x6E ,0x20, 0x66 ,0x61 ,0x69 ,0x6C ,0x65 ,0x64 ,0x22, 0x7D ,0x71 ,0x17};// {"resultCode":3,"reason":"Signature verification failed"}
  897. unsigned char check;
  898. char *jsonRecv;
  899. tcpMsgCtrl_t tcpRecvCtrl = {0};
  900. void TcpCommDebug2(void)
  901. {
  902. //test
  903. len1 = StrNumToInt(&num, Str1);
  904. len2 = StrToAsc(asc, Str2, 16);
  905. resultCode1 = TcpJsonToAck(&loginAck1, json);
  906. resultCode2 = TcpJsonToAck(&tcpMsgDatUploadAck, json2);
  907. TcpJsonToDownload(&tcpMsgDatDownload, jsonDownload);
  908. check = TcpUnPackAndCheck(&tcpRecvCtrl, &jsonRecv, (tcpMsg_t *)recvReg);
  909. }
  910. */