123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647 |
- /********************************************************************************
- * File Name: ModemTcpComm.c
- * Function Describe: 通过TCP与服务器通信(TCP通信协议)
- * Explain:
- * Writer:
- * Date:
- *******************************************************************************/
- #define THIS_FILE_ID 8
- /*******************************************************************************/
- #include "includes.h"
- //-------------------------------------------------------------------------------
- SUT_TCP_STATUS sutTcpStatus;
- SUT_LOGIN_ACK sutLoginAck={0,0,0,0,0,0,0,0,0};
- SUT_FOTA_PARA sutFotaPara;
- //UploadCode和UploadCodeAck 用于确保本地待上传的数据与服务器数据一致性
- //本地数据发生变化,需要上传时,将UploadCode加1并确保UploadCode!=UploadCodeAck
- //服务器收到后原值回传,本地收到服务器回复后覆盖UploadCodeAck
- //当检查到UploadCode!=UploadCodeAck时,将触发上传
- unsigned char g_ucUploadCode=0; //上传标志码,每次上传前先自动加1
- unsigned char g_ucUploadCodeAck=128;//上传标志码服务器回传码
- static void IapGetUpdateData(uint32_t offset,uint16_t len);
- static char IapCheckFileMD5_SPI_Flash(unsigned int dataAddr,unsigned int length,uint8_t *MD5);
- //==============================================================================
- //@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;
- }
- /********************************************************************************
- Packing
- 打包函数
- 按数据包格式将pdata的数据打包到pTcpBuf中
- 格式:
- |Head|Cmd|Length(2)| DATA(n)| Check |
- Length 是从DATA...到Check的数据长度(包含了Check)即Length=n+1
- 返回包长 包长应等于Length+4 也等于n+5
- *********************************************************************************/
- unsigned short TcpPacking(unsigned char *pBuf,unsigned char cmd,unsigned short datalen,unsigned char *pdata)
- {
- unsigned char i;
- unsigned char check=0;
- unsigned short len;
- if(datalen>(TCP_SEND_BUF_LEN-6))return 0;
- pBuf[0]=TCP_PACKET_HEAD;
- check=TCP_PACKET_HEAD;
- pBuf[1]=cmd;
- check^=cmd;
- len=datalen+1;
- pBuf[2]=(unsigned char)((len>>8)&0xff);
- check^=pBuf[2];
- pBuf[3]=(unsigned char)(len&0xff);
- check^=pBuf[3];
- for(i=0;i<datalen;i++){
- pBuf[4+i]=pdata[i];
- check^=pdata[i];
- }
- pBuf[datalen+4]=check;
- return len+4;
- }
- SUT_LOGIN sutLoginInfo;//size=56bytes
- /*********************************************************************************
- PackingReg
- 打包成注册信息包,存放在pBuf中
- //登陆服务器的数据结构
- *********************************************************************************/
- unsigned short TcpPackingReg(unsigned char *pBuf)
- {
- unsigned short len;
- SUTDS ds;
- SUTDL dl;
- unsigned char data[sizeof(SUT_LOGIN)];
- if(sizeof(SUT_LOGIN)>sizeof(data))return 0;
- if(sutProductPara.PSN==0 || 0==CheckAKey())return 0;//AKEY无效 不允许登陆
- sutLoginInfo.ASN=sutProductPara.PSN;
- sutLoginInfo.AKEY=sutProductPara.AKEY;
- memcpy(sutLoginInfo.CCID,sutModemStatus.CCID,20);
- memcpy(sutLoginInfo.Model,sutProductPara.ProductName,sizeof(sutLoginInfo.Model));
- sutLoginInfo.Ver=sutProductPara.SoftwareVer;
- sutLoginInfo.Rand=sutModemStatus.CSQ;
- memcpy(data,&sutLoginInfo,sizeof(SUT_LOGIN));
- ds.Data.usData=sutLoginInfo.Ver;
- data[8]=ds.Data.ucData.b2;
- data[9]=ds.Data.ucData.b1;
-
- dl.Data.ulData=sutLoginInfo.ASN;
- data[12]=dl.Data.ucData.b4;
- data[13]=dl.Data.ucData.b3;
- data[14]=dl.Data.ucData.b2;
- data[15]=dl.Data.ucData.b1;
-
- dl.Data.ulData=sutLoginInfo.AKEY;
- data[16]=dl.Data.ucData.b4;
- data[17]=dl.Data.ucData.b3;
- data[18]=dl.Data.ucData.b2;
- data[19]=dl.Data.ucData.b1;
-
- return TcpPacking(pBuf,CMD_LOGIN,sizeof(SUT_LOGIN),data);
- }
- /*********************************************************************************
- PackingSendTest
- 打包成SendTick信息包,存放在pBuf中
- *********************************************************************************/
- unsigned short TcpPackingSendTick(unsigned char *pBuf)
- {
- // unsigned char *pTemp;
- // unsigned short i,j,k;
- // unsigned char check=0;
- // unsigned short len;
- // //unsigned short datalen=sutTestData.TcLen+24;
- // if(datalen>(TCP_SEND_BUF_LEN-6))return 0;
- // j=0;
- // pBuf[j++]=TCP_PACKET_HEAD;
- // check=TCP_PACKET_HEAD;
- // pBuf[j++]=CMD_SEND_TEST;
- // len=datalen+1;
- // pBuf[j++]=(unsigned char)((len>>8)&0xff);
- // pBuf[j++]=(unsigned char)(len&0xff);
- // pBuf[j++]=sutTestData.NetMode;
- // pBuf[j++]=sutTestData.CSQ;
- // pBuf[j++]=(unsigned char )((sutTestData.GpsNum>>8)&0xff);
- // pBuf[j++]=(unsigned char)(sutTestData.GpsNum&0xff);
- // pBuf[j++]=(unsigned char )((sutTestData.BDNum>>8)&0xff);
- // pBuf[j++]=(unsigned char)(sutTestData.BDNum&0xff);
- //
- // pTemp=(unsigned char *)&sutTestData.Longitude;
- // for(i=8;i>0;i--){
- // pBuf[j++]=pTemp[i-1];
- // }
- // pTemp=(unsigned char *)&sutTestData.Latitude;
- // for(i=8;i>0;i--){
- // pBuf[j++]=pTemp[i-1];
- // }
- // pBuf[j++]=(unsigned char )((sutTestData.Speed>>8)&0xff);
- // pBuf[j++]=(unsigned char)(sutTestData.Speed&0xff);
- // pBuf[j++]=(unsigned char )((sutTestData.Aspect>>8)&0xff);
- // pBuf[j++]=(unsigned char)(sutTestData.Aspect&0xff);
- //
- //
- // for(i=0;i<sutTestData.TcLen;i++){
- // pBuf[i+j]=sutTestData.TcData[i];
- // }
- // j+=sutTestData.TcLen;
- //
- // //check
- // check=0;
- // for(i=0;i<j;i++){
- // check^=pBuf[i];
- // }
- // pBuf[j++]=check;
- // return j;
- }
- /*********************************************************************************
- PackingSendTest
- 打包成SendTest信息包,存放在pBuf中
- 入口参数:sutTestData
- 出口参数:pBuf
- 数据内容:
- TestCode,NetMode,CSQ ,GpsNum,BDNum, Longitude, Latitude, Speed, Aspect, DATA
- *********************************************************************************/
- unsigned short TcpPackingSendTest(unsigned char *pBuf)
- {
- // unsigned char *pTemp;
- // unsigned short i,j,k;
- // unsigned char check=0;
- // unsigned short len;
- // unsigned short datalen=25;//+sutTestData.TcLen;
- // if(datalen>(TCP_SEND_BUF_LEN-6))return 0;
- // j=0;
- // pBuf[j++]=TCP_PACKET_HEAD;
- // check=TCP_PACKET_HEAD;
- // pBuf[j++]=CMD_SEND_TEST;
- // len=datalen+1;
- // pBuf[j++]=(unsigned char)((len>>8)&0xff);
- // pBuf[j++]=(unsigned char)(len&0xff);
- // pBuf[j++]=g_ucUploadCode;
- // pBuf[j++]=sutTestData.NetMode;
- // pBuf[j++]=sutTestData.CSQ;
- // pBuf[j++]=sutTestData.GpsNum;
- // pBuf[j++]=sutTestData.BDNum;
- //
- //
- // pTemp=(unsigned char *)&sutTestData.Longitude;
- // for(i=8;i>0;i--){
- // pBuf[j++]=pTemp[i-1];
- // }
- // pTemp=(unsigned char *)&sutTestData.Latitude;
- // for(i=8;i>0;i--){
- // pBuf[j++]=pTemp[i-1];
- // }
- // pBuf[j++]=(unsigned char )((sutTestData.Speed>>8)&0xff);
- // pBuf[j++]=(unsigned char)(sutTestData.Speed&0xff);
- // pBuf[j++]=(unsigned char )((sutTestData.Aspect>>8)&0xff);
- // pBuf[j++]=(unsigned char)(sutTestData.Aspect&0xff);
- //
- //
- // for(i=0;i<sutTestData.TcLen;i++){
- // pBuf[i+j]=sutTestData.TcData[i];
- // }
- // j+=sutTestData.TcLen;
- //
- // //check
- // check=0;
- // for(i=0;i<j;i++){
- // check^=pBuf[i];
- // }
- // pBuf[j++]=check;
- // return j;
- }
- /*
- 收到服务器发来的TCP数据包
- |Head(1)|Cmd(1)|Len(2)|...|check(1)|
- */
- void TcpRecvData(unsigned char *pData,unsigned short DataLen)
- {
- char buf[50];
- unsigned char cmd;
- unsigned short Len;
- unsigned char check;
- int i;
- //trace recv data
- //Debugsend(pData,DataLen);
- //
-
- if(DataLen<5 || pData[0]!=0xAB){
- SlwTrace(DEBUG,"TcpRecvData error!\r\n");
- return;
- }
- Len=(((unsigned short)pData[2])<<8)+(unsigned short)pData[3];
- if(Len+4!=DataLen){
- SlwTrace(DEBUG,"TcpRecvData len error!\r\n");
- return;
- }
- check=0;
- for(i=0;i<(DataLen-1);i++){
- check^=pData[i];
- }
- if(check!=pData[DataLen-1]){
- SlwTrace(DEBUG,"TcpRecvData check error!\r\n");
- return;
- }
- //-----------
- cmd=pData[1];
- //snprintf(buf,sizeof(buf),"Recv cmd=%02X len=%d\r\n",cmd,DataLen);
- //SlwTrace(DEBUG,buf);
- switch(cmd){
- case CMD_LOGIN_ACK:
- //Head(1) Cmd(1) Len(2) NowTime(6) Interval(2) GNSSEnable(1) NetMode(1) NewVer(2) NewIP(4) NewPort(2) check(1)
- //Now Time=pData[4]~pData[[9]
- //Interval
- sutLoginAck.Interval=(unsigned short)pData[10];
- sutLoginAck.Interval<<=8;
- sutLoginAck.Interval+=(unsigned short)pData[11];
- if(sutLoginAck.Interval<10)sutLoginAck.Interval=10;
- sutLoginAck.GNSSEnable=pData[12];
- sutLoginAck.NetMode=pData[13];
- sutLoginAck.NewVer=(unsigned short)pData[14];
- sutLoginAck.NewVer<<=8;
- sutLoginAck.NewVer+=(unsigned short)pData[15];
- sutLoginAck.NewIP[0]=pData[16];
- sutLoginAck.NewIP[1]=pData[17];
- sutLoginAck.NewIP[2]=pData[18];
- sutLoginAck.NewIP[3]=pData[19];
- sutLoginAck.NewPort=(unsigned short)pData[20];
- sutLoginAck.NewPort<<=8;
- sutLoginAck.NewPort+=(unsigned short)pData[21];
- sprintf(buf,"I=%d GE=%d NM=%d NV=%d\r\n",\
- sutLoginAck.Interval,sutLoginAck.GNSSEnable,sutLoginAck.NetMode,sutLoginAck.NewVer);
- SlwTrace(DEBUG,buf);
- sprintf(buf,"NewH=%d.%d.%d.%d:%d\r\n",\
- sutLoginAck.NewIP[0],sutLoginAck.NewIP[1],sutLoginAck.NewIP[2],sutLoginAck.NewIP[3],sutLoginAck.NewPort);
- SlwTrace(DEBUG,buf);
- if(sutLoginAck.NewVer!=sutProductPara.SoftwareVer && sutLoginAck.NewVer!=0){
- sutTcpStatus.FoTa=OPENED;
- sutFotaPara.fotaStatus=FOTA_GET_FILEINFO;
- sutTcpStatus.ServerStatus=CLOSED;
- ModemCloseSocket(0);
- }else{
- sutTcpStatus.ServerStatus=OPENED;
- }
- break;
- case CMD_SEND_TEST_ACK:
- g_ucUploadCodeAck=pData[4];
- //sprintf(buf,"UploadCodeAck=%02X\r\n",g_ucUploadCodeAck);
- //SlwTrace(DEBUG,buf);
- break;
- case CMD_CONTROL:
- SlwTrace(DEBUG,"SCMD_SET_CTRL<<\r\n");
- break;
- case CMD_GET_FILE_INFO_ACK:
- SlwTrace(DEBUG,"CMD_GET_FILE_INFO_ACK<<\r\n");
- SUT_FILE_INFO *pFileInfo;
- unsigned short i,realDataLen,thisLen;
- SUTDS ds;
- SUTDL dl1;
- SUTDL dl2;
- char info[30];
- pFileInfo=(SUT_FILE_INFO *)&pData[4];
- snprintf(info,sizeof(info), "%s_V%d.bin", sutProductPara.ProductName,sutLoginAck.NewVer);
- if(0!=strcmp(pFileInfo->FileName, info))
- {//文件名和版本号不对,结束升级
- SlwTrace(DEBUG, "FNameErr\r\n");
- sutLoginAck.NewVer=0;//结束升级
- sutTcpStatus.ServerStatus=CLOSED;
- sutFotaPara.fotaStatus=FOTA_END;
- return;
- }
- dl1.Data.ulData=pFileInfo->FileLength;
- 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;
- sutFotaPara.fileLength=dl2.Data.ulData;
- sutFotaPara.encrypted=pFileInfo->encrypted;
- sutFotaPara.key=pFileInfo->key;
- memcpy(sutFotaPara.MD5,pFileInfo->MD5,16);
- if(sutFotaPara.fileLength==0)
- {//服务器没有文件,退出升级
- SlwTrace(DEBUG, "NoFileInServer");
- sutLoginAck.NewVer=0;//结束升级
- sutTcpStatus.ServerStatus=CLOSED;
- sutFotaPara.fotaStatus=FOTA_END;
-
- return;
- }
- sutFotaPara.lastOffset=-1;
- sutFotaPara.nextOffset=0;
- sutFotaPara.tcpCnt=0;
- sutFotaPara.fotaStatus=FOTA_GET_FILEDATA;
- sutTcpStatus.FoTa=OPENED;
- sutTcpStatus.ServerStatus=OPENED;
- break;
- case CMD_GET_FILE_DATA_ACK:
- SlwTrace(DEBUG,"CMD_GET_FILE_DATA_ACK<<\r\n");
- unsigned int thisOffset;
- //offset
- dl1.Data.ucData.b4=pData[4];
- dl1.Data.ucData.b3=pData[5];
- dl1.Data.ucData.b2=pData[6];
- dl1.Data.ucData.b1=pData[7];
- thisOffset=dl1.Data.ulData;
- //lenght
- ds.Data.ucData.b2=pData[8];
- ds.Data.ucData.b1=pData[9];
- thisLen=ds.Data.usData;
- //save
- SPI_Flash_Write(pData+10,APP_FILE_DATA_ADDR+thisOffset,thisLen);
- //done?
- if((thisOffset+thisLen) >= sutFotaPara.fileLength)
- {
- snprintf(info,sizeof(info), "\r\nHBD=%d\r\nLoad done\r\n",sutFotaPara.fileLength);
- SlwTrace(DEBUG, info);
- //校验
- if(0!=IapCheckFileMD5_SPI_Flash(APP_FILE_DATA_ADDR, sutFotaPara.fileLength, sutFotaPara.MD5))
- {//较验成功,准备跳转到IAP前准备
- memcpy(sutDeviceConfig.MD5, sutFotaPara.MD5,sizeof(sutDeviceConfig.MD5));
- sutDeviceConfig.AppExAddr=APP_FILE_DATA_ADDR;
- sutDeviceConfig.AppLen=sutFotaPara.fileLength;
- sutDeviceConfig.FoTaMark[0]='F';sutDeviceConfig.FoTaMark[1]='o';sutDeviceConfig.FoTaMark[2]='T';sutDeviceConfig.FoTaMark[3]='a';
- SaveDeviceConfigToFlash();
- SlwTrace(DEBUG, "GoingUpdate\r\n");
- //系统复位
- SystemReset();
- }else{
- SlwTrace(INF, "Md5Err");
- //重新升级
- sutFotaPara.fotaStatus=FOTA_GET_FILEINFO;
- sutTcpStatus.ServerStatus=CLOSED;
- }
- }else{
- sutFotaPara.tcpCnt=0;
- sutFotaPara.lastOffset=sutFotaPara.nextOffset;
- sutFotaPara.nextOffset=thisOffset+thisLen;
- snprintf(info,sizeof(info), "\r\nHBD=%d\r\n",sutFotaPara.lastOffset);
- SlwTrace(DEBUG, info);
- }
- break;
- case CMD_LOGIN_REJECT://鉴权失败,拒绝登陆
- sutTcpStatus.LoginWaitTime=(unsigned short)pData[4]&0xff;
- if(sutTcpStatus.LoginWaitTime==0)sutTcpStatus.LoginWaitTime=3600;//1小时
- else sutTcpStatus.LoginWaitTime*=60;
- break;
- }
- }
- /*******************************************************************
- 封包,获取新版本
- |Head|Cmd|length(2) | data... | Check|
- Head 包头,固定为0xAB
- Cmd 命令字
- length 后续的数据长度,包括到Check的长度 length=1+data.len
- Check 从Head开始按字节异或运算
- data:
- unsigned long PSN; //终端编号
- unsigned char FileName[20]; //文件名 如:RT101_V102.bin
- unsigned long offset; //请求数据在文件中的开始位置
- unsigned short len; //请求数据的长度,服务器返回的数据可能小于等于此长度
- *******************************************************************/
- unsigned short PacketGetFileData(unsigned char *buf,unsigned int offset,unsigned short len)
- {
- unsigned char checksum;
- unsigned short i,j;
- char FileName[21];
- SUTDL dl;
- SUTDS ds;
- j=0;
- memset(buf,0,35);
- buf[j++]=TCP_PACKET_HEAD;
- buf[j++]=CMD_GET_FILE_DATA;
- buf[j++]=0;
- buf[j++]=30+1;//数据18字节,1字节checksum
- //PSN
- dl.Data.ulData=sutProductPara.PSN; //因为协议要求大端模式传输,所以需要转一下
- buf[j++]=dl.Data.ucData.b4;
- buf[j++]=dl.Data.ucData.b3;
- buf[j++]=dl.Data.ucData.b2;
- buf[j++]=dl.Data.ucData.b1;
- //FileName
- snprintf(FileName,sizeof(FileName), "%s_V%d.bin", sutProductPara.ProductName,sutLoginAck.NewVer);
- for(i=0;i<20;i++){
- buf[j++]=FileName[i];
- }
- //offset
- dl.Data.ulData=offset; //因为协议要求大端模式传输,所以需要转一下
- buf[j++]=dl.Data.ucData.b4;
- buf[j++]=dl.Data.ucData.b3;
- buf[j++]=dl.Data.ucData.b2;
- buf[j++]=dl.Data.ucData.b1;
- //len
- ds.Data.usData=len;
- buf[j++]=ds.Data.ucData.b2;
- buf[j++]=ds.Data.ucData.b1;
- //校验
- checksum=0;
- for(i=0;i<j;i++){
- checksum=checksum^buf[i];
- }
- buf[j++]=checksum;
- return j;
- }
- /*
- */
- void FoTaGetFileData(void)
- {
- unsigned short subLen;
- unsigned char txbuf[35];
- subLen=PacketGetFileData(txbuf,sutFotaPara.nextOffset,1024);
- ModemSendToSocket(0,txbuf,subLen);
- }
- /////////////////////////////////////////////////////////////////
- /*******************************************************************
- 封包,获取新版本文件信息
- |Head|Cmd|length(2) | data... | Check|
- Head 包头,固定为0xAB
- Cmd 命令字
- length 后续的数据长度,包括到Check的长度 length=1+data.len
- Check 从Head开始按字节异或运算
- data:
- unsigned long PSN;//终端编号
- char FileName[20];//文件名,不够的在末尾补0
- 总长 24+5=29 bytes
- *******************************************************************/
- unsigned short PacketGetFileInfo(unsigned char *buf)
- {
- unsigned char checksum;
- unsigned short i,j,k;
- char FileName[21];
-
- SUTDL dl;
- SUTDS ds;
- j=0;
- memset(buf,0,29);
- buf[j++]=TCP_PACKET_HEAD;
- buf[j++]=CMD_GET_FILE_INFO;
- buf[j++]=0;
- buf[j++]=24+1;//数据24字节,1字节checksum
- //PSN
- dl.Data.ulData=sutProductPara.PSN; //因为协议要求大端模式传输,所以需要转一下
- buf[j++]=dl.Data.ucData.b4;
- buf[j++]=dl.Data.ucData.b3;
- buf[j++]=dl.Data.ucData.b2;
- buf[j++]=dl.Data.ucData.b1;
- //FileName
- snprintf(FileName,sizeof(FileName), "%s_V%d.bin", sutProductPara.ProductName,sutLoginAck.NewVer);
- for(i=0;i<20;i++){
- buf[j++]=FileName[i];
- }
- //校验
- checksum=0;
- for(i=0;i<j;i++){
- checksum=checksum^buf[i];
- }
- buf[j++]=checksum;
- return j;
- }
- static char IapCheckFileMD5_SPI_Flash(unsigned int dataAddr,unsigned int length,uint8_t *MD5)
- {
- MD5_CTX mdContext;
- unsigned char data[1024];
- unsigned long len,l;
- char tembuf[5];
- int i;
- MD5Init(&mdContext);
- len=0;
- while(len<length)
- {
- if((length-len)>1024)l=1024;
- else l=length-len;
- SPI_Flash_Read(data,dataAddr+len,l);
- MD5Update(&mdContext,data,l);
- len+=l;
- }
- MD5Final(&mdContext);
- //check
- for(i=0;i<16;i++){
- if(MD5[i]!=mdContext.digest[i])break;
- }
- if(i<16)return 0;
- else return 1;
- }
- void TcpCommInit(void)
- {
- memset(&sutTcpStatus,0,sizeof(SUT_TCP_STATUS));
- memset(&sutLoginAck,0,sizeof(SUT_LOGIN_ACK));
- memset(&sutFotaPara,0,sizeof(SUT_FOTA_PARA));
- }
- /*******************************************************************************/
|