ModemTcpComm.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647
  1. /********************************************************************************
  2. * File Name: ModemTcpComm.c
  3. * Function Describe: 通过TCP与服务器通信(TCP通信协议)
  4. * Explain:
  5. * Writer:
  6. * Date:
  7. *******************************************************************************/
  8. #define THIS_FILE_ID 8
  9. /*******************************************************************************/
  10. #include "includes.h"
  11. //-------------------------------------------------------------------------------
  12. SUT_TCP_STATUS sutTcpStatus;
  13. SUT_LOGIN_ACK sutLoginAck={0,0,0,0,0,0,0,0,0};
  14. SUT_FOTA_PARA sutFotaPara;
  15. //UploadCode和UploadCodeAck 用于确保本地待上传的数据与服务器数据一致性
  16. //本地数据发生变化,需要上传时,将UploadCode加1并确保UploadCode!=UploadCodeAck
  17. //服务器收到后原值回传,本地收到服务器回复后覆盖UploadCodeAck
  18. //当检查到UploadCode!=UploadCodeAck时,将触发上传
  19. unsigned char g_ucUploadCode=0; //上传标志码,每次上传前先自动加1
  20. unsigned char g_ucUploadCodeAck=128;//上传标志码服务器回传码
  21. static void IapGetUpdateData(uint32_t offset,uint16_t len);
  22. static char IapCheckFileMD5_SPI_Flash(unsigned int dataAddr,unsigned int length,uint8_t *MD5);
  23. //==============================================================================
  24. //@Functions
  25. //@brief 将32位大小端数据格式转换
  26. //@param
  27. //@retval 转换后的数据
  28. //==============================================================================
  29. unsigned int BigLittle32Conv(unsigned int srcData)
  30. {
  31. SUTDL dl1, dl2;//用于大小端转换
  32. dl1.Data.ulData = srcData;
  33. dl2.Data.ucData.b1 = dl1.Data.ucData.b4;
  34. dl2.Data.ucData.b2 = dl1.Data.ucData.b3;
  35. dl2.Data.ucData.b3 = dl1.Data.ucData.b2;
  36. dl2.Data.ucData.b4 = dl1.Data.ucData.b1;
  37. return dl2.Data.ulData;
  38. }
  39. //==============================================================================
  40. //@Functions
  41. //@brief 将16位大小端数据格式转换
  42. //@param
  43. //@retval 转换后的数据
  44. //==============================================================================
  45. unsigned short BigLittle16Conv(unsigned short srcData)
  46. {
  47. SUTDS ds1, ds2;//用于大小端转换
  48. ds1.Data.usData = srcData;
  49. ds2.Data.ucData.b1 = ds1.Data.ucData.b2;
  50. ds2.Data.ucData.b2 = ds1.Data.ucData.b1;
  51. return ds2.Data.usData;
  52. }
  53. //==============================================================================
  54. //@Functions
  55. //@brief 从pStr中找到pSearch,返回pSearch后的第一个地址(若无para则返回0)。可配合 StrNumToInt() 使用
  56. //举例:pStr=" "WorkEnable":1,"PowerOnTimeAdj":[123,45,-78,90], "
  57. // 如果pSearch="TimeAdj":[" 返回"123,45,-78,90], "
  58. // 如果pSearch="Work":" 返回"Enable":1,"PowerOnTimeAdj":[123,45,-78,90], "
  59. // 如果pSearch="abcd":" 返回NULL
  60. //@param
  61. //@retval pSearch后的第一个地址
  62. //==============================================================================
  63. char* SearchFromStr(char *pStr,char *pSearch)
  64. {
  65. char *pResult;
  66. unsigned char searchLen;
  67. pResult = strstr(pStr, pSearch);
  68. if(pResult == NULL)
  69. {
  70. return NULL;
  71. }
  72. searchLen = strlen(pSearch);
  73. pResult += searchLen;
  74. return pResult;
  75. }
  76. //==============================================================================
  77. //@Functions
  78. //@brief 指定位置开始,到非数字字符结束的数字字符串转换成整形数值(数值范围-2147483648~2147483647)
  79. // "65535,a" --> 65535(十六进制0xFFFF),返回5
  80. // "-123" --> -123(十六进制0x85),返回4
  81. // " -123" --> -123(十六进制0x85),返回5
  82. // "123456789,kk"--> 123456789,返回9
  83. //@param 输入: *pStrNum 字符串数字开始的指针
  84. // 输出 *pNum 转换的值
  85. //@retval 转换的字符串中数字长度(含"-"号和空格),0失败
  86. //==============================================================================
  87. static unsigned char StrNumToInt(int *pNum, char *pStrNum)
  88. {
  89. char i, numLen = 0;
  90. char buf[11] = {0};
  91. for(i = 0; i < 10; i++)
  92. {
  93. if(pStrNum[i]>0x39 || pStrNum[i]<0x30)
  94. {
  95. if(pStrNum[i] != ' ' && pStrNum[i] != '-') break;
  96. }
  97. buf[i] = pStrNum[i];
  98. numLen = i + 1;
  99. }
  100. buf[i] = 0;
  101. *pNum = atoi(buf);
  102. return numLen;
  103. }
  104. //==============================================================================
  105. //@Functions
  106. //@brief 获取 指定位置开始,到"结束的 字符串内容,并返回实际长度,若无",则获取最大长度
  107. // 17010001" --> 17010001(ASCII),返回8
  108. //
  109. //@param 输入: *pStr 字符串开始的指针 maxLen
  110. // 输出 *pAsc 转换的值
  111. //@retval 转换的字符串长度
  112. //==============================================================================
  113. static unsigned char StrToAsc(char *pAsc, char *pStr, unsigned char maxLen)
  114. {
  115. char i, numLen = 0;
  116. for(i = 0; i < maxLen; i++)
  117. {
  118. if(pStr[i] == '\"') break;//到"结束
  119. pAsc[i] = pStr[i];
  120. numLen = i + 1;
  121. }
  122. pAsc[i] = 0;
  123. return numLen;
  124. }
  125. /********************************************************************************
  126. Packing
  127. 打包函数
  128. 按数据包格式将pdata的数据打包到pTcpBuf中
  129. 格式:
  130. |Head|Cmd|Length(2)| DATA(n)| Check |
  131. Length 是从DATA...到Check的数据长度(包含了Check)即Length=n+1
  132. 返回包长 包长应等于Length+4 也等于n+5
  133. *********************************************************************************/
  134. unsigned short TcpPacking(unsigned char *pBuf,unsigned char cmd,unsigned short datalen,unsigned char *pdata)
  135. {
  136. unsigned char i;
  137. unsigned char check=0;
  138. unsigned short len;
  139. if(datalen>(TCP_SEND_BUF_LEN-6))return 0;
  140. pBuf[0]=TCP_PACKET_HEAD;
  141. check=TCP_PACKET_HEAD;
  142. pBuf[1]=cmd;
  143. check^=cmd;
  144. len=datalen+1;
  145. pBuf[2]=(unsigned char)((len>>8)&0xff);
  146. check^=pBuf[2];
  147. pBuf[3]=(unsigned char)(len&0xff);
  148. check^=pBuf[3];
  149. for(i=0;i<datalen;i++){
  150. pBuf[4+i]=pdata[i];
  151. check^=pdata[i];
  152. }
  153. pBuf[datalen+4]=check;
  154. return len+4;
  155. }
  156. SUT_LOGIN sutLoginInfo;//size=56bytes
  157. /*********************************************************************************
  158. PackingReg
  159. 打包成注册信息包,存放在pBuf中
  160. //登陆服务器的数据结构
  161. *********************************************************************************/
  162. unsigned short TcpPackingReg(unsigned char *pBuf)
  163. {
  164. unsigned short len;
  165. SUTDS ds;
  166. SUTDL dl;
  167. unsigned char data[sizeof(SUT_LOGIN)];
  168. if(sizeof(SUT_LOGIN)>sizeof(data))return 0;
  169. if(sutProductPara.PSN==0 || 0==CheckAKey())return 0;//AKEY无效 不允许登陆
  170. sutLoginInfo.ASN=sutProductPara.PSN;
  171. sutLoginInfo.AKEY=sutProductPara.AKEY;
  172. memcpy(sutLoginInfo.CCID,sutModemStatus.CCID,20);
  173. memcpy(sutLoginInfo.Model,sutProductPara.ProductName,sizeof(sutLoginInfo.Model));
  174. sutLoginInfo.Ver=sutProductPara.SoftwareVer;
  175. sutLoginInfo.Rand=sutModemStatus.CSQ;
  176. memcpy(data,&sutLoginInfo,sizeof(SUT_LOGIN));
  177. ds.Data.usData=sutLoginInfo.Ver;
  178. data[8]=ds.Data.ucData.b2;
  179. data[9]=ds.Data.ucData.b1;
  180. dl.Data.ulData=sutLoginInfo.ASN;
  181. data[12]=dl.Data.ucData.b4;
  182. data[13]=dl.Data.ucData.b3;
  183. data[14]=dl.Data.ucData.b2;
  184. data[15]=dl.Data.ucData.b1;
  185. dl.Data.ulData=sutLoginInfo.AKEY;
  186. data[16]=dl.Data.ucData.b4;
  187. data[17]=dl.Data.ucData.b3;
  188. data[18]=dl.Data.ucData.b2;
  189. data[19]=dl.Data.ucData.b1;
  190. return TcpPacking(pBuf,CMD_LOGIN,sizeof(SUT_LOGIN),data);
  191. }
  192. /*********************************************************************************
  193. PackingSendTest
  194. 打包成SendTick信息包,存放在pBuf中
  195. *********************************************************************************/
  196. unsigned short TcpPackingSendTick(unsigned char *pBuf)
  197. {
  198. // unsigned char *pTemp;
  199. // unsigned short i,j,k;
  200. // unsigned char check=0;
  201. // unsigned short len;
  202. // //unsigned short datalen=sutTestData.TcLen+24;
  203. // if(datalen>(TCP_SEND_BUF_LEN-6))return 0;
  204. // j=0;
  205. // pBuf[j++]=TCP_PACKET_HEAD;
  206. // check=TCP_PACKET_HEAD;
  207. // pBuf[j++]=CMD_SEND_TEST;
  208. // len=datalen+1;
  209. // pBuf[j++]=(unsigned char)((len>>8)&0xff);
  210. // pBuf[j++]=(unsigned char)(len&0xff);
  211. // pBuf[j++]=sutTestData.NetMode;
  212. // pBuf[j++]=sutTestData.CSQ;
  213. // pBuf[j++]=(unsigned char )((sutTestData.GpsNum>>8)&0xff);
  214. // pBuf[j++]=(unsigned char)(sutTestData.GpsNum&0xff);
  215. // pBuf[j++]=(unsigned char )((sutTestData.BDNum>>8)&0xff);
  216. // pBuf[j++]=(unsigned char)(sutTestData.BDNum&0xff);
  217. //
  218. // pTemp=(unsigned char *)&sutTestData.Longitude;
  219. // for(i=8;i>0;i--){
  220. // pBuf[j++]=pTemp[i-1];
  221. // }
  222. // pTemp=(unsigned char *)&sutTestData.Latitude;
  223. // for(i=8;i>0;i--){
  224. // pBuf[j++]=pTemp[i-1];
  225. // }
  226. // pBuf[j++]=(unsigned char )((sutTestData.Speed>>8)&0xff);
  227. // pBuf[j++]=(unsigned char)(sutTestData.Speed&0xff);
  228. // pBuf[j++]=(unsigned char )((sutTestData.Aspect>>8)&0xff);
  229. // pBuf[j++]=(unsigned char)(sutTestData.Aspect&0xff);
  230. //
  231. //
  232. // for(i=0;i<sutTestData.TcLen;i++){
  233. // pBuf[i+j]=sutTestData.TcData[i];
  234. // }
  235. // j+=sutTestData.TcLen;
  236. //
  237. // //check
  238. // check=0;
  239. // for(i=0;i<j;i++){
  240. // check^=pBuf[i];
  241. // }
  242. // pBuf[j++]=check;
  243. // return j;
  244. }
  245. /*********************************************************************************
  246. PackingSendTest
  247. 打包成SendTest信息包,存放在pBuf中
  248. 入口参数:sutTestData
  249. 出口参数:pBuf
  250. 数据内容:
  251. TestCode,NetMode,CSQ ,GpsNum,BDNum, Longitude, Latitude, Speed, Aspect, DATA
  252. *********************************************************************************/
  253. unsigned short TcpPackingSendTest(unsigned char *pBuf)
  254. {
  255. // unsigned char *pTemp;
  256. // unsigned short i,j,k;
  257. // unsigned char check=0;
  258. // unsigned short len;
  259. // unsigned short datalen=25;//+sutTestData.TcLen;
  260. // if(datalen>(TCP_SEND_BUF_LEN-6))return 0;
  261. // j=0;
  262. // pBuf[j++]=TCP_PACKET_HEAD;
  263. // check=TCP_PACKET_HEAD;
  264. // pBuf[j++]=CMD_SEND_TEST;
  265. // len=datalen+1;
  266. // pBuf[j++]=(unsigned char)((len>>8)&0xff);
  267. // pBuf[j++]=(unsigned char)(len&0xff);
  268. // pBuf[j++]=g_ucUploadCode;
  269. // pBuf[j++]=sutTestData.NetMode;
  270. // pBuf[j++]=sutTestData.CSQ;
  271. // pBuf[j++]=sutTestData.GpsNum;
  272. // pBuf[j++]=sutTestData.BDNum;
  273. //
  274. //
  275. // pTemp=(unsigned char *)&sutTestData.Longitude;
  276. // for(i=8;i>0;i--){
  277. // pBuf[j++]=pTemp[i-1];
  278. // }
  279. // pTemp=(unsigned char *)&sutTestData.Latitude;
  280. // for(i=8;i>0;i--){
  281. // pBuf[j++]=pTemp[i-1];
  282. // }
  283. // pBuf[j++]=(unsigned char )((sutTestData.Speed>>8)&0xff);
  284. // pBuf[j++]=(unsigned char)(sutTestData.Speed&0xff);
  285. // pBuf[j++]=(unsigned char )((sutTestData.Aspect>>8)&0xff);
  286. // pBuf[j++]=(unsigned char)(sutTestData.Aspect&0xff);
  287. //
  288. //
  289. // for(i=0;i<sutTestData.TcLen;i++){
  290. // pBuf[i+j]=sutTestData.TcData[i];
  291. // }
  292. // j+=sutTestData.TcLen;
  293. //
  294. // //check
  295. // check=0;
  296. // for(i=0;i<j;i++){
  297. // check^=pBuf[i];
  298. // }
  299. // pBuf[j++]=check;
  300. // return j;
  301. }
  302. /*
  303. 收到服务器发来的TCP数据包
  304. |Head(1)|Cmd(1)|Len(2)|...|check(1)|
  305. */
  306. void TcpRecvData(unsigned char *pData,unsigned short DataLen)
  307. {
  308. char buf[50];
  309. unsigned char cmd;
  310. unsigned short Len;
  311. unsigned char check;
  312. int i;
  313. //trace recv data
  314. //Debugsend(pData,DataLen);
  315. //
  316. if(DataLen<5 || pData[0]!=0xAB){
  317. SlwTrace(DEBUG,"TcpRecvData error!\r\n");
  318. return;
  319. }
  320. Len=(((unsigned short)pData[2])<<8)+(unsigned short)pData[3];
  321. if(Len+4!=DataLen){
  322. SlwTrace(DEBUG,"TcpRecvData len error!\r\n");
  323. return;
  324. }
  325. check=0;
  326. for(i=0;i<(DataLen-1);i++){
  327. check^=pData[i];
  328. }
  329. if(check!=pData[DataLen-1]){
  330. SlwTrace(DEBUG,"TcpRecvData check error!\r\n");
  331. return;
  332. }
  333. //-----------
  334. cmd=pData[1];
  335. //snprintf(buf,sizeof(buf),"Recv cmd=%02X len=%d\r\n",cmd,DataLen);
  336. //SlwTrace(DEBUG,buf);
  337. switch(cmd){
  338. case CMD_LOGIN_ACK:
  339. //Head(1) Cmd(1) Len(2) NowTime(6) Interval(2) GNSSEnable(1) NetMode(1) NewVer(2) NewIP(4) NewPort(2) check(1)
  340. //Now Time=pData[4]~pData[[9]
  341. //Interval
  342. sutLoginAck.Interval=(unsigned short)pData[10];
  343. sutLoginAck.Interval<<=8;
  344. sutLoginAck.Interval+=(unsigned short)pData[11];
  345. if(sutLoginAck.Interval<10)sutLoginAck.Interval=10;
  346. sutLoginAck.GNSSEnable=pData[12];
  347. sutLoginAck.NetMode=pData[13];
  348. sutLoginAck.NewVer=(unsigned short)pData[14];
  349. sutLoginAck.NewVer<<=8;
  350. sutLoginAck.NewVer+=(unsigned short)pData[15];
  351. sutLoginAck.NewIP[0]=pData[16];
  352. sutLoginAck.NewIP[1]=pData[17];
  353. sutLoginAck.NewIP[2]=pData[18];
  354. sutLoginAck.NewIP[3]=pData[19];
  355. sutLoginAck.NewPort=(unsigned short)pData[20];
  356. sutLoginAck.NewPort<<=8;
  357. sutLoginAck.NewPort+=(unsigned short)pData[21];
  358. sprintf(buf,"I=%d GE=%d NM=%d NV=%d\r\n",\
  359. sutLoginAck.Interval,sutLoginAck.GNSSEnable,sutLoginAck.NetMode,sutLoginAck.NewVer);
  360. SlwTrace(DEBUG,buf);
  361. sprintf(buf,"NewH=%d.%d.%d.%d:%d\r\n",\
  362. sutLoginAck.NewIP[0],sutLoginAck.NewIP[1],sutLoginAck.NewIP[2],sutLoginAck.NewIP[3],sutLoginAck.NewPort);
  363. SlwTrace(DEBUG,buf);
  364. if(sutLoginAck.NewVer!=sutProductPara.SoftwareVer && sutLoginAck.NewVer!=0){
  365. sutTcpStatus.FoTa=OPENED;
  366. sutFotaPara.fotaStatus=FOTA_GET_FILEINFO;
  367. sutTcpStatus.ServerStatus=CLOSED;
  368. ModemCloseSocket(0);
  369. }else{
  370. sutTcpStatus.ServerStatus=OPENED;
  371. }
  372. break;
  373. case CMD_SEND_TEST_ACK:
  374. g_ucUploadCodeAck=pData[4];
  375. //sprintf(buf,"UploadCodeAck=%02X\r\n",g_ucUploadCodeAck);
  376. //SlwTrace(DEBUG,buf);
  377. break;
  378. case CMD_CONTROL:
  379. SlwTrace(DEBUG,"SCMD_SET_CTRL<<\r\n");
  380. break;
  381. case CMD_GET_FILE_INFO_ACK:
  382. SlwTrace(DEBUG,"CMD_GET_FILE_INFO_ACK<<\r\n");
  383. SUT_FILE_INFO *pFileInfo;
  384. unsigned short i,realDataLen,thisLen;
  385. SUTDS ds;
  386. SUTDL dl1;
  387. SUTDL dl2;
  388. char info[30];
  389. pFileInfo=(SUT_FILE_INFO *)&pData[4];
  390. snprintf(info,sizeof(info), "%s_V%d.bin", sutProductPara.ProductName,sutLoginAck.NewVer);
  391. if(0!=strcmp(pFileInfo->FileName, info))
  392. {//文件名和版本号不对,结束升级
  393. SlwTrace(DEBUG, "FNameErr\r\n");
  394. sutLoginAck.NewVer=0;//结束升级
  395. sutTcpStatus.ServerStatus=CLOSED;
  396. sutFotaPara.fotaStatus=FOTA_END;
  397. return;
  398. }
  399. dl1.Data.ulData=pFileInfo->FileLength;
  400. dl2.Data.ucData.b1=dl1.Data.ucData.b4;
  401. dl2.Data.ucData.b2=dl1.Data.ucData.b3;
  402. dl2.Data.ucData.b3=dl1.Data.ucData.b2;
  403. dl2.Data.ucData.b4=dl1.Data.ucData.b1;
  404. sutFotaPara.fileLength=dl2.Data.ulData;
  405. sutFotaPara.encrypted=pFileInfo->encrypted;
  406. sutFotaPara.key=pFileInfo->key;
  407. memcpy(sutFotaPara.MD5,pFileInfo->MD5,16);
  408. if(sutFotaPara.fileLength==0)
  409. {//服务器没有文件,退出升级
  410. SlwTrace(DEBUG, "NoFileInServer");
  411. sutLoginAck.NewVer=0;//结束升级
  412. sutTcpStatus.ServerStatus=CLOSED;
  413. sutFotaPara.fotaStatus=FOTA_END;
  414. return;
  415. }
  416. sutFotaPara.lastOffset=-1;
  417. sutFotaPara.nextOffset=0;
  418. sutFotaPara.tcpCnt=0;
  419. sutFotaPara.fotaStatus=FOTA_GET_FILEDATA;
  420. sutTcpStatus.FoTa=OPENED;
  421. sutTcpStatus.ServerStatus=OPENED;
  422. break;
  423. case CMD_GET_FILE_DATA_ACK:
  424. SlwTrace(DEBUG,"CMD_GET_FILE_DATA_ACK<<\r\n");
  425. unsigned int thisOffset;
  426. //offset
  427. dl1.Data.ucData.b4=pData[4];
  428. dl1.Data.ucData.b3=pData[5];
  429. dl1.Data.ucData.b2=pData[6];
  430. dl1.Data.ucData.b1=pData[7];
  431. thisOffset=dl1.Data.ulData;
  432. //lenght
  433. ds.Data.ucData.b2=pData[8];
  434. ds.Data.ucData.b1=pData[9];
  435. thisLen=ds.Data.usData;
  436. //save
  437. SPI_Flash_Write(pData+10,APP_FILE_DATA_ADDR+thisOffset,thisLen);
  438. //done?
  439. if((thisOffset+thisLen) >= sutFotaPara.fileLength)
  440. {
  441. snprintf(info,sizeof(info), "\r\nHBD=%d\r\nLoad done\r\n",sutFotaPara.fileLength);
  442. SlwTrace(DEBUG, info);
  443. //校验
  444. if(0!=IapCheckFileMD5_SPI_Flash(APP_FILE_DATA_ADDR, sutFotaPara.fileLength, sutFotaPara.MD5))
  445. {//较验成功,准备跳转到IAP前准备
  446. memcpy(sutDeviceConfig.MD5, sutFotaPara.MD5,sizeof(sutDeviceConfig.MD5));
  447. sutDeviceConfig.AppExAddr=APP_FILE_DATA_ADDR;
  448. sutDeviceConfig.AppLen=sutFotaPara.fileLength;
  449. sutDeviceConfig.FoTaMark[0]='F';sutDeviceConfig.FoTaMark[1]='o';sutDeviceConfig.FoTaMark[2]='T';sutDeviceConfig.FoTaMark[3]='a';
  450. SaveDeviceConfigToFlash();
  451. SlwTrace(DEBUG, "GoingUpdate\r\n");
  452. //系统复位
  453. SystemReset();
  454. }else{
  455. SlwTrace(INF, "Md5Err");
  456. //重新升级
  457. sutFotaPara.fotaStatus=FOTA_GET_FILEINFO;
  458. sutTcpStatus.ServerStatus=CLOSED;
  459. }
  460. }else{
  461. sutFotaPara.tcpCnt=0;
  462. sutFotaPara.lastOffset=sutFotaPara.nextOffset;
  463. sutFotaPara.nextOffset=thisOffset+thisLen;
  464. snprintf(info,sizeof(info), "\r\nHBD=%d\r\n",sutFotaPara.lastOffset);
  465. SlwTrace(DEBUG, info);
  466. }
  467. break;
  468. case CMD_LOGIN_REJECT://鉴权失败,拒绝登陆
  469. sutTcpStatus.LoginWaitTime=(unsigned short)pData[4]&0xff;
  470. if(sutTcpStatus.LoginWaitTime==0)sutTcpStatus.LoginWaitTime=3600;//1小时
  471. else sutTcpStatus.LoginWaitTime*=60;
  472. break;
  473. }
  474. }
  475. /*******************************************************************
  476. 封包,获取新版本
  477. |Head|Cmd|length(2) | data... | Check|
  478. Head 包头,固定为0xAB
  479. Cmd 命令字
  480. length 后续的数据长度,包括到Check的长度 length=1+data.len
  481. Check 从Head开始按字节异或运算
  482. data:
  483. unsigned long PSN; //终端编号
  484. unsigned char FileName[20]; //文件名 如:RT101_V102.bin
  485. unsigned long offset; //请求数据在文件中的开始位置
  486. unsigned short len; //请求数据的长度,服务器返回的数据可能小于等于此长度
  487. *******************************************************************/
  488. unsigned short PacketGetFileData(unsigned char *buf,unsigned int offset,unsigned short len)
  489. {
  490. unsigned char checksum;
  491. unsigned short i,j;
  492. char FileName[21];
  493. SUTDL dl;
  494. SUTDS ds;
  495. j=0;
  496. memset(buf,0,35);
  497. buf[j++]=TCP_PACKET_HEAD;
  498. buf[j++]=CMD_GET_FILE_DATA;
  499. buf[j++]=0;
  500. buf[j++]=30+1;//数据18字节,1字节checksum
  501. //PSN
  502. dl.Data.ulData=sutProductPara.PSN; //因为协议要求大端模式传输,所以需要转一下
  503. buf[j++]=dl.Data.ucData.b4;
  504. buf[j++]=dl.Data.ucData.b3;
  505. buf[j++]=dl.Data.ucData.b2;
  506. buf[j++]=dl.Data.ucData.b1;
  507. //FileName
  508. snprintf(FileName,sizeof(FileName), "%s_V%d.bin", sutProductPara.ProductName,sutLoginAck.NewVer);
  509. for(i=0;i<20;i++){
  510. buf[j++]=FileName[i];
  511. }
  512. //offset
  513. dl.Data.ulData=offset; //因为协议要求大端模式传输,所以需要转一下
  514. buf[j++]=dl.Data.ucData.b4;
  515. buf[j++]=dl.Data.ucData.b3;
  516. buf[j++]=dl.Data.ucData.b2;
  517. buf[j++]=dl.Data.ucData.b1;
  518. //len
  519. ds.Data.usData=len;
  520. buf[j++]=ds.Data.ucData.b2;
  521. buf[j++]=ds.Data.ucData.b1;
  522. //校验
  523. checksum=0;
  524. for(i=0;i<j;i++){
  525. checksum=checksum^buf[i];
  526. }
  527. buf[j++]=checksum;
  528. return j;
  529. }
  530. /*
  531. */
  532. void FoTaGetFileData(void)
  533. {
  534. unsigned short subLen;
  535. unsigned char txbuf[35];
  536. subLen=PacketGetFileData(txbuf,sutFotaPara.nextOffset,1024);
  537. ModemSendToSocket(0,txbuf,subLen);
  538. }
  539. /////////////////////////////////////////////////////////////////
  540. /*******************************************************************
  541. 封包,获取新版本文件信息
  542. |Head|Cmd|length(2) | data... | Check|
  543. Head 包头,固定为0xAB
  544. Cmd 命令字
  545. length 后续的数据长度,包括到Check的长度 length=1+data.len
  546. Check 从Head开始按字节异或运算
  547. data:
  548. unsigned long PSN;//终端编号
  549. char FileName[20];//文件名,不够的在末尾补0
  550. 总长 24+5=29 bytes
  551. *******************************************************************/
  552. unsigned short PacketGetFileInfo(unsigned char *buf)
  553. {
  554. unsigned char checksum;
  555. unsigned short i,j,k;
  556. char FileName[21];
  557. SUTDL dl;
  558. SUTDS ds;
  559. j=0;
  560. memset(buf,0,29);
  561. buf[j++]=TCP_PACKET_HEAD;
  562. buf[j++]=CMD_GET_FILE_INFO;
  563. buf[j++]=0;
  564. buf[j++]=24+1;//数据24字节,1字节checksum
  565. //PSN
  566. dl.Data.ulData=sutProductPara.PSN; //因为协议要求大端模式传输,所以需要转一下
  567. buf[j++]=dl.Data.ucData.b4;
  568. buf[j++]=dl.Data.ucData.b3;
  569. buf[j++]=dl.Data.ucData.b2;
  570. buf[j++]=dl.Data.ucData.b1;
  571. //FileName
  572. snprintf(FileName,sizeof(FileName), "%s_V%d.bin", sutProductPara.ProductName,sutLoginAck.NewVer);
  573. for(i=0;i<20;i++){
  574. buf[j++]=FileName[i];
  575. }
  576. //校验
  577. checksum=0;
  578. for(i=0;i<j;i++){
  579. checksum=checksum^buf[i];
  580. }
  581. buf[j++]=checksum;
  582. return j;
  583. }
  584. static char IapCheckFileMD5_SPI_Flash(unsigned int dataAddr,unsigned int length,uint8_t *MD5)
  585. {
  586. MD5_CTX mdContext;
  587. unsigned char data[1024];
  588. unsigned long len,l;
  589. char tembuf[5];
  590. int i;
  591. MD5Init(&mdContext);
  592. len=0;
  593. while(len<length)
  594. {
  595. if((length-len)>1024)l=1024;
  596. else l=length-len;
  597. SPI_Flash_Read(data,dataAddr+len,l);
  598. MD5Update(&mdContext,data,l);
  599. len+=l;
  600. }
  601. MD5Final(&mdContext);
  602. //check
  603. for(i=0;i<16;i++){
  604. if(MD5[i]!=mdContext.digest[i])break;
  605. }
  606. if(i<16)return 0;
  607. else return 1;
  608. }
  609. void TcpCommInit(void)
  610. {
  611. memset(&sutTcpStatus,0,sizeof(SUT_TCP_STATUS));
  612. memset(&sutLoginAck,0,sizeof(SUT_LOGIN_ACK));
  613. memset(&sutFotaPara,0,sizeof(SUT_FOTA_PARA));
  614. }
  615. /*******************************************************************************/