#include "includes.h" /* 文件描述 1、主要处理终端与DTU之间的授权功能所需要的通讯逻辑 2、终端在正确下载完APP后,如果未进行授权,会自动跳到授权的任务中,直到授权成功 3、授权码产生算法存在于本设备及服务器中 4、终端启动后会读取MCU内存中的授权码,并与使用MCU ID进行加密码得出的授权码进行比对,不一样则未授权 */ #define UNIQUE_ID_BYTES 12 #define TAKE_PRINT_FLAG 0 #define RAND_STR_LEN 6 const unsigned char randStr[RAND_STR_LEN]={'s','z','5','0','2','8'}; const unsigned char srcAuth[16]={0x17,0x0d,0x55,0x9f,0xab,0xcc,0x1c,0x8f,0x30,0x0a,0x28,0xda,0x3c,0x91,0x11,0x6d}; const unsigned char FirmSrc[10]={0x50,0x28,0xaf,0x6d,0x08,0x9c,0x1b,0xe4,0x23,0x77}; uint32_t auth_seg_addr,iap_temp_addr,app_seg_addr; uint16_t this_dev_page_size,this_dev_flash_size; unsigned char SlaveNum; unsigned char Authed=0; //获取唯一ID接口 typedef enum{ STM32F0,STM32F1,STM32F2,STM32F3,STM32F4,STM32F7, STM32L0,STM32L1,STM32L4, STM32H7, STM_END }STM32_MCU_DEF; unsigned int mcustartAddr[STM_END]= { 0x1FFFF7AC,/*STM32F0*/ 0x1FFFF7E8,/*STM32F1*/ 0x1FFF7A10,/*STM32F2*/ 0x1FFFF7AC,/*STM32F3*/ 0x1FFF7A10,/*STM32F4*/ 0x1FF0F420,/*STM32F7*/ 0x1FF80050,/*STM32L0*/ 0x1FF80050,/*STM32L1*/ 0x1FFF7590,/*STM32L4*/ 0x1FF0F420 /*STM32H7*/ }; void GetSTM32_McuID(unsigned char *id,STM32_MCU_DEF type) { unsigned char i; if(id==NULL) return; for(i=0;i>8; //4-5 sendbuf[i++]=liushui; for(k=0;kSlaveNum=*dataPtr; //write new auth authInfo->authCode=codeData; //make lier data for(i=0;inoUseStart);i++){ authInfo->noUseStart[i]=*dataPtr++^data[6]; if(dataPtr>=&data[len]) dataPtr=data; } for(i=0;inoUseEnd);i++){ authInfo->noUseEnd[i]=*dataPtr++^data[4]; if(dataPtr>=&data[len]) dataPtr=data; } //WritePageData(auth_seg_addr,(unsigned char *)authInfo,sizeof(AUTH_INFO)); WritePageData(AUTH_PARA_ADDR,(unsigned char *)authInfo,sizeof(AUTH_INFO)); printf("newAuthInfo:%08x,targetcode:%08x\r\n",codeData,targetcode); if(codeData == targetcode){//当激活码与本地算的一致时 return 0; }else return 4;//当激活码与本地算的不一致时 } //根据MCU的FLASH容量大小判断出page大小,然后得到激活段与升级临时段的起始地址 void GetStartAddrByFlashSize(void) { #if 1 auth_seg_addr=0x8000000+124*1024; #else this_dev_flash_size=*(uint16_t *)(0x1FFFF7E0);//获取FLASH容量 if(this_dev_flash_size <= 128) this_dev_page_size=2048; else this_dev_page_size=2048; //取得激活码段起始地址 auth_seg_addr=APP_CONFIG_ADDR+this_dev_page_size; //取得临时段起始地址 iap_temp_addr=auth_seg_addr+this_dev_page_size; //取得APP应用起始地址 app_seg_addr=iap_temp_addr+this_dev_page_size; if(app_seg_addr % 2048) app_seg_addr += 1024;//跳转地址需要是页大小的倍数 //printf("addr:%08x,%08x,%08x\r\n",auth_seg_addr,iap_temp_addr,app_seg_addr); #endif } void reInitUart1(void) {//关闭IDLE中断,打开NE中断 USART_ITConfig(USART1, USART_IT_IDLE, DISABLE); USART_DMACmd(USART1,USART_DMAReq_Rx,DISABLE); USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); rx1_ct=0; g_usUart1RecvLen=0; } void authLink() { unsigned int i=0; AUTH_INFO authInfo; unsigned char id[UNIQUE_ID_BYTES]; //unsigned char id[UNIQUE_ID_BYTES]={1,2,3,4,5,6,7,8,9,1,1,2}; unsigned int encodeValue; unsigned char senddata[100]; unsigned int len; char ret; unsigned char j=0; unsigned char handshake=0; GetSTM32_McuID(id, STM32F1); #if(TAKE_PRINT_FLAG) printf("ID[%d]:",UNIQUE_ID_BYTES); for(i=0;i=3){ if(!handshake)j++; i=0; } if(j>3)break; IWDG_ReloadCounter();//喂狗 DelayMs(1000);//100 if(g_usUart1RecvLen==0) continue; ret=decodeAuthInfo(RxBuffer1,g_usUart1RecvLen,encodeValue,&authInfo); if(0==ret){ authSendCmd(PRO_AUTH_OK,id,UNIQUE_ID_BYTES); return; //break; }else if(4==ret){//鉴权码不正确 authSendCmd(PRO_AUTH_FAI,id,UNIQUE_ID_BYTES); }else if(5==ret){//握手成功 handshake=1; }else if(6==ret){ //请求基本数据 authSendCmd(PRO_AUTH_REQ,senddata,UNIQUE_ID_BYTES+16+16); } g_usUart1RecvLen=0; } while(1){ IWDG_ReloadCounter();//喂狗 DelayMs(100); printf("please try auth-------------------\r\n"); } } #define APP_UPDATE_COMPLETED 0x5c44f1d0 #define APP_UPDATE_DEFAULT 0xffffffff #define APP_UPDATE_NONE_COMPLETED 0x2487314d void takeNoteThatFlushAppCompleteOrNot(char status) { unsigned int flushStatus; unsigned int currentStatus; if(status==0) flushStatus=APP_UPDATE_NONE_COMPLETED;//未完成APP的更新 else flushStatus=APP_UPDATE_COMPLETED;//已完成APP的更新 ReadFlashData(iap_temp_addr, (unsigned char *)¤tStatus, 4); if(currentStatus == flushStatus) return; WritePageData(iap_temp_addr, (unsigned char *)&flushStatus, 4); } void checkLastAppUpdateCompleteOrNot(void) { unsigned int currentStatus; ReadFlashData(iap_temp_addr, (unsigned char *)¤tStatus, 4); if(currentStatus == APP_UPDATE_COMPLETED || currentStatus == APP_UPDATE_DEFAULT) return; currentStatus=0; while(1){ if(currentStatus==0) printf("Last update err, need retry!\r\n"); if(++currentStatus >= 2000*2000) currentStatus=0; } } //StrAsciiToHex /* 对长度为tagetlen的targetstring 进行加密 入参为randlen的随机串randstring */ void extCodeBuffer(unsigned char *randString, int randlen, unsigned char *targetString, int targetlen){ int i,j,k; unsigned char value; //先使用随机串依次对targetString进行异或 j=0; for(i=0;i=randlen) j=0; } //再对targetstring的奇数索引字节,与randstring的高低4位指向的srcAuth索引字节异或 j=0; for(i=0;i>4)&0x0F; value=srcAuth[k]; if(++j>=randlen) j=0; if(i%2) targetString[i] ^= value; } } unsigned char PocAuthDataPack(unsigned char *Packdata) { unsigned char id[UNIQUE_ID_BYTES]; unsigned char i=0; GetSTM32_McuID(id, STM32F1); strcpy(&Packdata[i], FACTORY_NAME); i=i+16; strcpy(&Packdata[i], MODE_NAME); i=i+16; Packdata[i]=UNIQUE_ID_BYTES; i=i+1; memcpy(&Packdata[i], id,UNIQUE_ID_BYTES); i=i+UNIQUE_ID_BYTES; return i; } //unsigned char AscToHex(unsigned char aHex) //{ // if((aHex>=0)&&(aHex<=9)) // aHex += 0x30; // else if((aHex>=10)&&(aHex<=15))//A-F // //aHex += 0x37; // aHex += 0x57; // else aHex = 0xff; // return aHex; //} static void AscStrToHexStrForgetZero(char *AscStr, char *HexStr,unsigned char len) { char *pAscStr=AscStr; unsigned char d,h,l; while(len){ d=(unsigned char)*pAscStr++; l=d&0x0f; h=d>>4; *HexStr++=AscToHex(h); *HexStr++=AscToHex(l); len--; } *HexStr=0; } void PocAuthProcess(char *msg) { unsigned char Ranbuf[20]; unsigned char SendDataBuf[120]; unsigned char DelDataBuf[120]; unsigned char i=0; unsigned char len; memset(DelDataBuf,0,sizeof(DelDataBuf)); memset(SendDataBuf,0,sizeof(SendDataBuf)); memset(Ranbuf,0,sizeof(Ranbuf)); printf(msg); //BEA6F8ECFFE4 -->0xBE 0XA6 StrAsciiToHex(msg,Ranbuf); memcpy(DelDataBuf,FirmSrc,sizeof(FirmSrc)); //MCU参数组包 len=sizeof(FirmSrc); extCodeBuffer(Ranbuf,strlen(Ranbuf)-1,DelDataBuf,len); // len=PocAuthDataPack(DelDataBuf); // extCodeBuffer(Ranbuf,strlen(Ranbuf)-1,DelDataBuf,len); //因为回车换行转成一个字节 AscStrToHexStrForgetZero(DelDataBuf,SendDataBuf,len); printf(SendDataBuf); memset(DelDataBuf,0,sizeof(DelDataBuf)); //AT+SAUTH snprintf(DelDataBuf,sizeof(DelDataBuf),"AT+SAUTH=%s\r\n",SendDataBuf); printf(DelDataBuf); ModemSendData(DelDataBuf,len*2+12); }