#include "string.h" #include "gprs.h" #include "rtc.h" #include "sleep.h" #include "API-Platform.h" #include "sleep.h" #include "TEA.h" #include "NB-IOT.h" #include "gsdk_sdk.h" #include <math.h> #include "flash.h" #include "AiderProtocol.h" #include "gsdk_ril.h" #include "gsdk_ril_cmds.h" #include "gsdk_api.h" #include "gsdk_sdk.h" #include <stdio.h> #include <stdlib.h> extern struct Config_RegPara ConfigData; //定义的下发配置参数,HEX格式,方便在系统进入休眠模式之前写入BKP寄存器 extern struct DeviceSet DeviceConfig; //液位计配置信息结构体 extern struct DataFrame dataFrame; extern uint8_t SIMCard_Type; extern struct BusinessData businessData; uint8_t Flash_Write_Flag[9]; // 自定义的tolower函数。 int _tolower(int c) { if (c>='A' && c<='Z') return c+32; else return c; } /******************************************************************************* * Function Name : int string_to_hex(char* h,char s[]) * Description : string×a?ˉ3éhex£?2¢·μ??hex×a?ˉêyá? ?°a320?±-->0xa3,0x20 * Input : None * Output : None * Return : None *******************************************************************************/ int string_to_hex(char* h,char s[]) { int i ,j; for (i=0,j=0; (s[i] >= '0' && s[i] <= '9') || (s[i] >= 'a' && s[i] <= 'z') || (s[i] >='A' && s[i] <= 'Z'); ++i) { if (_tolower(s[i]) > '9') { h[j] = 16 * h[j] + (10 + _tolower(s[i]) - 'a'); } else { h[j] = 16 * h[j] + (_tolower(s[i]) - '0'); } if(i%2==1) { j++; } } return j; } /******************************************************************************* * Function Name : XX * Description : XX * Input : None * Output : None * Return : None *******************************************************************************/ unsigned char ReverseBitOrder08( unsigned char iSrc ) { unsigned char index; unsigned char iDst; iDst = iSrc & 0X01; for( index = 0X00; index < 0X07; index++ ) { iDst <<= 0X01; iSrc >>= 0X01; iDst |= ( iSrc & 0X01 ); } return iDst; } /******************************************************************************* * Function Name : XX * Description : XX * Input : None * Output : None * Return : None *******************************************************************************/ unsigned short ReverseBitOrder16( unsigned short iSrc ) { unsigned char index; unsigned short iDst; iDst = iSrc & 0X01; for( index = 0X00; index < 0X0F; index++ ) { iDst <<= 0X01; iSrc >>= 0X01; iDst |= ( iSrc & 0X01 ); } return iDst; } /******************************************************************************* * Function Name : unsigned short CRC16( unsigned char * pMsg, unsigned short iSize ) * Description : f(X)=X^16 + X^15 + X^2 + X^0£?POLYNOMIALS = 0X8005 * Input : None * Output : None * Return : None *******************************************************************************/ unsigned short CRC16( unsigned char * pMsg, unsigned short iSize ) { unsigned char index; unsigned short iCRC; // The default value iCRC = 0XFFFF; while ( iSize-- ) { iCRC ^= ( ( ( unsigned short ) ReverseBitOrder08( *pMsg ) ) << 0X08 ); for ( index = 0X00; index < 0X08; index++ ) { if ( iCRC & 0X8000 ) { iCRC = ( iCRC << 1 ) ^ 0X8005; } else { iCRC <<= 1; } } pMsg++; } return ReverseBitOrder16( iCRC ); } /***********函数功能:在特定序列中发现一个指定的序列****************/ /***********如果找到,则返回目标序列在源序列中的首地址**************/ char* Find_SpecialString(char* Source, char* Object, short Length_Source, short Length_Object) { char* Ptemp1 = Source; char* Ptemp2 = Object; short i=0,j=0; short count=0; if((Length_Source < 0)||(Length_Object < 0)) { return NULL; } if(Length_Source < Length_Object) { return NULL; } else if(Length_Source == Length_Object) { if((Length_Source==0)&&(Length_Object==0)) { return NULL; } else { for(i=0; i<Length_Source; i++) { if(Ptemp1[i] != Ptemp2[i]) return NULL; } return Ptemp1; } } else { if(Length_Object == 0) { return NULL; } else { count = Length_Source - Length_Object + 1; for(i=0; i<count; i++) { for(j=0; j<Length_Object; j++) { if(Ptemp1[i+j] != Ptemp2[j]) break; } if(j==Length_Object) { return &Ptemp1[i]; } } return NULL; } } } /******************************************************************************* * Function Name : 协议数据分析 * Description : XX * Input : None * Output : None * Return : None *******************************************************************************/ void Treaty_Data_Analysis(uint8_t* pTreatyBuff, uint16_t* pFlag) { uint8_t DataLen =0; //Tag序列或者OID序列的长度 uint16_t PduType =0; uint16_t FramStatus =0; //发送数据接收状态 uint8_t i=0,j=0; uint8_t* pChar =NULL; uint32_t* pOid =NULL; uint8_t Tag_Lenth = 0; uint8_t k = 0; uint8_t Dot_Counter = 0; //分隔符计数器 dataFrame.Tag_Count = 0; uint8_t ServerPort[6]; //服务器端口 struct CommandFrame ParaRequest; PduType = pTreatyBuff[13]*256 + pTreatyBuff[14]; //结算接收数据PDU编码 *pFlag =PduType; switch(PduType) { case 0x019C: //Get Request { #if DEBUG_TEST printf("\r\nReceive Get Request Command from Server.\r\n"); //测试使用 #endif ////////////////////////////////////////// DataLen =pTreatyBuff[2]*256 +pTreatyBuff[3]-12; //接收到的OID序列的总长度 ParaRequest.OID_Count =DataLen/4; //接收到的OID序列数量 if((ParaRequest.OID_Count >0)&&(ParaRequest.OID_Count <=20)) //限定OID长度,防止内存溢出 { pOid = (uint32_t*)&pTreatyBuff[16]; j =ParaRequest.OID_Count; for(i=0; i<ParaRequest.OID_Count; i++) { ParaRequest.OID_List[i] =(CommandType)*pOid; //OID高低字节顺序有待确认 ParaRequest.OID_List[i] =ntohl( ParaRequest.OID_List[i] ); //网络序转换为机器序,即将数据的低字节放在低地址 // if(ParaRequest.OID_List[i]==DATA_REQUEST) GetRequestFlag=1; printf("\r\n--Cycle--%4x----.\r\n", ParaRequest.OID_List[i]); //测试使用 j--; if(j==0) { break; } pOid++; } } else { #if DEBUG_TEST printf("\r\nReceive Command OID not correct.\r\n"); //测试使用 #endif } break; } case 0x039C: //Trap Response { #if DEBUG_TEST printf("\r\nReceive Trap Response Command from Server.\r\n"); //测试使用 #endif DataLen =pTreatyBuff[2]*256 +pTreatyBuff[3]-12; //接收到的Tag序列的总长度 if(DataLen >6) //至少存在一个合法的配置参数 { pOid = (uint32_t*)(pTreatyBuff+16); i=0; while( DataLen >6 ) { // printf("\r\n--Cycle--%4x----.\r\n",ntohl(*pOid)); //测试使用 pChar = (uint8_t*)pOid; switch(ntohl(*pOid)) { case SYSTERM_TIME: //系统时间 { DeviceConfig.Time_Year =*(pChar+6); DeviceConfig.Time_Mon =*(pChar+7); DeviceConfig.Time_Mday =*(pChar+8); DeviceConfig.Time_Hour =*(pChar+9); DeviceConfig.Time_Min =*(pChar+10); DeviceConfig.Time_Sec =*(pChar+11); printf("\r\n-年-月-日-时-分-秒:-%d--%d--%d--%d--%d--%d--.\r\n",DeviceConfig.Time_Year,DeviceConfig.Time_Mon,DeviceConfig.Time_Mday, DeviceConfig.Time_Hour,DeviceConfig.Time_Min, DeviceConfig.Time_Sec ); //测试使用 if((DeviceConfig.Time_Mon<=12)&&(DeviceConfig.Time_Mday<=31)&&(DeviceConfig.Time_Hour<=23)&&(DeviceConfig.Time_Min<=60)&&(DeviceConfig.Time_Sec<=60)) //参数合法性判定 { // RTC_Timing(2); //通过服务器下发参数进行RTC时钟校准 } ParaRequest.OID_List[i] =SYSTERM_TIME; pOid =(uint32_t*)(pChar+12); //指针后移1个Tag DataLen = DataLen-12; i++; //合法OID计数器 dataFrame.Tag_Count++; break; } case FRAM_STATE: { FramStatus= pChar[6]*256+pChar[7]; //获取上位机数据接收状态 ParaRequest.OID_List[i] =FRAM_STATE; pOid =(uint32_t*)(pChar+8); //指针后移1个Tag DataLen = DataLen-8; i++; //合法OID计数器 dataFrame.Tag_Count++; printf("\r\nServer Receive Trap Response Status:0x%.4x\r\n",FramStatus); //测试使用 break; } case DEF_NR: //重传次数 { DeviceConfig.RetryNum = *(pChar + 6); if(DeviceConfig.RetryNum >= 1) //参数合法性判定 { Flash_Write_Flag[0] = 1; // Module_Flash_Write(RetryNum_ADDR - FLASH_TEST_BASE, &(DeviceConfig.RetryNum), 1); } else //当配置参数不合法时,使用默认参数,同时不更新Flash数据 { DeviceConfig.RetryNum = 1; //为了反馈真实情况不发送默认参数 } printf("\r\n-Retry Num-%x---.\r\n", DeviceConfig.RetryNum); //测试使用 pOid = (uint32_t*)(pChar + 7); //指针后移1个Tag DataLen = DataLen - 7; i++; //合法OID计数器 dataFrame.Tag_Count++; break; } case CLT1_STIME1: //一时区采集时间 { DeviceConfig.CollectTime = pChar[6] * 256 + pChar[7]; printf("\r\n-CollectTime:-%2x---.\r\n", DeviceConfig.CollectTime ); //测试使用 if(DeviceConfig.CollectTime <= 1440) //参数合法性判定 { Flash_Write_Flag[1] = 1; // Module_Flash_Write( CollectTime_ADDR - FLASH_TEST_BASE, (uint8_t*) & (DeviceConfig.CollectTime), 2); } pOid = (uint32_t*)(pChar + 8); //指针后移1个Tag DataLen = DataLen - 8; i++; //合法OID计数器 dataFrame.Tag_Count++; break; } case CLT1_ITRL1: //一时区采集间隔 { DeviceConfig.CollectPeriod = pChar[6] * 256 + pChar[7]; printf("\r\n-CollectPeriod:-%2x---.\r\n", DeviceConfig.CollectPeriod ); //测试使用 if(DeviceConfig.CollectPeriod <= 1440) //参数合法性判定 { Flash_Write_Flag[2] = 1; // Module_Flash_Write(CollectPeriod_ADDR - FLASH_TEST_BASE, (uint8_t*) & (DeviceConfig.CollectPeriod), 2); } pOid = (uint32_t*)(pChar + 8); //指针后移1个Tag DataLen = DataLen - 8; i++; //合法OID计数器 dataFrame.Tag_Count++; break; } case CLT1_CNT1: //一时区采集次数 { DeviceConfig.CollectNum = pChar[6] * 256 + pChar[7]; printf("\r\n-CollectNum:-%2x---.\r\n", DeviceConfig.CollectNum ); //测试使用 if(DeviceConfig.CollectNum <= 1440) //参数合法性判定 { Flash_Write_Flag[3] = 1; // Module_Flash_Write(CollectNum_ADDR - FLASH_TEST_BASE, (uint8_t*) & (DeviceConfig.CollectNum), 2); } pOid = (uint32_t*)(pChar + 8); //指针后移1个Tag DataLen = DataLen - 8; i++; //合法OID计数器 dataFrame.Tag_Count++; break; } case UPLOAD_CYCLE: //上报周期 { DeviceConfig.UploadCycle = pChar[6] * 256 + pChar[7]; if(DeviceConfig.UploadCycle <= 1440) //参数合法性判定 { Flash_Write_Flag[4] = 1; // Module_Flash_Write(UploadCycle_ADDR - FLASH_TEST_BASE, (uint8_t*) & (DeviceConfig.UploadCycle), 2); } printf("\r\n-UploadCycle:-%2x---.\r\n", DeviceConfig.UploadCycle ); //测试使用 pOid = (uint32_t*)(pChar + 8); //指针后移1个Tag DataLen = DataLen - 8; i++; //合法OID计数器 dataFrame.Tag_Count++; break; } case MOUNT_HEIGHT: //低浓度报警阈值 { for(k = 0; k < 4; k++) //调用函数已经做了防溢出处理,strlen(pSetPara)<=15 { DeviceConfig.MountHeight.Data_Hex[k] = pChar[k+6]; } if(DeviceConfig.MountHeight.Data_Float <= 100) //参数合法性判定 { Flash_Write_Flag[5] = 1; // Module_Flash_Write(MountHeight_ADDR - FLASH_TEST_BASE, DeviceConfig.MountHeight.Data_Hex, 4); } printf("\r\n-MountHeight:-%f---.\r\n", DeviceConfig.MountHeight.Data_Float); //测试使用 pOid = (uint32_t*)(pChar + 10); //指针后移1个Tag DataLen = DataLen - 10; i++; //合法OID计数器 dataFrame.Tag_Count++; break; } case ALARM_VALUE: //高浓度报警阈值 { for(k = 0; k < 4; k++) //调用函数已经做了防溢出处理,strlen(pSetPara)<=15 { DeviceConfig.AlarmValue.Data_Hex[k] = pChar[k+6]; } if(DeviceConfig.AlarmValue.Data_Float <= 100) //参数合法性判定 { Flash_Write_Flag[6] = 1; // Module_Flash_Write(AlarmValue_ADDR - FLASH_TEST_BASE, DeviceConfig.AlarmValue.Data_Hex, 4); } printf("\r\n-AlarmValue:-%f---.\r\n", DeviceConfig.AlarmValue.Data_Float); //测试使用 pOid = (uint32_t*)(pChar + 10); //指针后移1个Tag DataLen = DataLen - 10; i++; //合法OID计数器 dataFrame.Tag_Count++; break; } case BSS_IP: //网络服务IP地址(主IP) { Tag_Lenth = *(pChar + 5); if((Tag_Lenth > 6) && (Tag_Lenth < 16)) { for(k = 0; k < Tag_Lenth; k++) //调用函数已经做了防溢出处理,strlen(pSetPara)<=15 { if((pChar[6 + k] >= '0') && (pChar[6 + k] <= '9')) { DeviceConfig.ServerIP[k] = pChar[6 + k]; } else if((pChar[6 + k] == '.') && (pChar[6 + k - 1] != '.')) //分隔符统计 { Dot_Counter++; DeviceConfig.ServerIP[k] = pChar[6 + k]; } else { break; } } if(Dot_Counter == 3) { DeviceConfig.ServerIP[k] = '\0'; Flash_Write_Flag[7] = 1; // Module_Flash_Write(ServerIP_ADDR - FLASH_TEST_BASE, (uint8_t*) & (DeviceConfig.ServerIP), k); printf("\r\n接收合法IP\r\n "); } else { printf("\r\n接收非法IP\r\n "); } printf("\r\n-主IP号:-%s---.\r\n", DeviceConfig.ServerIP ); //测试使用 pOid = (uint32_t*)(pChar + 6 + Tag_Lenth); //指针后移1个Tag DataLen = DataLen - 6 - Tag_Lenth; i++; //合法OID计数器 dataFrame.Tag_Count++; } else { #if DEBUG_TEST printf("\r\n 新IP格式不正确!\r\n"); //测试使用 #endif pOid = (uint32_t*)(pChar + 1); //指针后移一个字节,查询后续有无合法OID DataLen = DataLen - 1; //指针后移一个字节,查询后续有无合法OID } break; } case BSS_PORT: //网络服务端口号 { DeviceConfig.ServerPort = pChar[6] * 256 + pChar[7]; printf("\r\n-ServerPort:-%d---.\r\n", DeviceConfig.ServerPort ); //测试使用 if(DeviceConfig.ServerPort < 65535) //参数合法性判定 { Flash_Write_Flag[8] = 1; // Module_Flash_Write(CollectNum_ADDR - FLASH_TEST_BASE, (uint8_t*) & (DeviceConfig.CollectNum), 2); } pOid = (uint32_t*)(pChar + 8); //指针后移1个Tag DataLen = DataLen - 8; i++; //合法OID计数器 dataFrame.Tag_Count++; break; } { Tag_Lenth = *(pChar + 5); if((Tag_Lenth > 0) && (Tag_Lenth < 6)) { for(k = 0; k < Tag_Lenth; k++) //调用函数已经做了防溢出处理,strlen(pSetPara)<=15 { if((pChar[6 + k] >= '0') && (pChar[6 + k] <= '9')) { ServerPort[k] = pChar[6 + k]; } else { break; } } if(k == Tag_Lenth) { ServerPort[k] = '\0'; Flash_Write_Flag[8] = 1; DeviceConfig.ServerPort = atoi((char*)ServerPort); printf("\r\n接收合法端口号\r\n "); pOid = (uint32_t*)(pChar + 6 + Tag_Lenth); //指针后移1个Tag DataLen = DataLen - 6 - Tag_Lenth; i++; //合法OID计数器 dataFrame.Tag_Count++; } else { printf("\r\n接收非法端口号\r\n "); pOid = (uint32_t*)(pChar + 1); //指针后移一个字节,查询后续有无合法OID DataLen = DataLen - 1; //指针后移一个字节,查询后续有无合法OID } printf("\r\n-主端口号:-%s---.\r\n", ServerPort); //测试使用 break; } else { #if DEBUG_TEST printf("\r\n 新PORT范围不正确!\r\n"); //测试使用 #endif pOid = (uint32_t*)(pChar + 1); //指针后移一个字节,查询后续有无合法OID DataLen = DataLen - 1; //指针后移一个字节,查询后续有无合法OID } break; } default: { #if DEBUG_TEST printf("\r\nWarning!!Tag OID not recognition!\r\n"); //测试使用 #endif pOid =(uint32_t*)(pChar+1); //指针后移一个字节,查询后续有无合法OID DataLen = DataLen-1; //指针后移一个字节,查询后续有无合法OID break; } } } } else { #if DEBUG_TEST printf("\r\nWarning!!Receive Trap Response Data Not Rrecognition!\r\n"); //测试使用 #endif } break; } case 0x099C: //Startup Response { #if DEBUG_TEST printf("\r\nReceive Startup Response Command from Server.\r\n"); //测试使用 #endif DataLen =pTreatyBuff[2]*256 +pTreatyBuff[3]-12; //接收到的Tag序列的总长度 if(DataLen >6) //至少存在一个合法的配置参数 { pOid = (uint32_t*)(pTreatyBuff+16); i=0; while( DataLen >6 ) { // printf("\r\n--Cycle--%4x----.\r\n",ntohl(*pOid)); //测试使用 pChar = (uint8_t*)pOid; switch(ntohl(*pOid)) { case SYSTERM_TIME: //系统时间 { DeviceConfig.Time_Year =*(pChar+6); DeviceConfig.Time_Mon =*(pChar+7); DeviceConfig.Time_Mday =*(pChar+8); DeviceConfig.Time_Hour =*(pChar+9); DeviceConfig.Time_Min =*(pChar+10); DeviceConfig.Time_Sec =*(pChar+11); printf("\r\n-年-月-日-时-分-秒:-%d--%d--%d--%d--%d--%d--.\r\n",DeviceConfig.Time_Year,DeviceConfig.Time_Mon,DeviceConfig.Time_Mday, DeviceConfig.Time_Hour,DeviceConfig.Time_Min, DeviceConfig.Time_Sec ); //测试使用 if((DeviceConfig.Time_Mon<=12)&&(DeviceConfig.Time_Mday<=31)&&(DeviceConfig.Time_Hour<=23)&&(DeviceConfig.Time_Min<=60)&&(DeviceConfig.Time_Sec<=60)) //参数合法性判定 { // RTC_Timing(2); //通过服务器下发参数进行RTC时钟校准 } ParaRequest.OID_List[i] =SYSTERM_TIME; pOid =(uint32_t*)(pChar+12); //指针后移1个Tag DataLen = DataLen-12; i++; //合法OID计数器 break; } case FRAM_STATE: { FramStatus= pChar[6]*256+pChar[7]; //获取上位机数据接收状态 ParaRequest.OID_List[i] =FRAM_STATE; pOid =(uint32_t*)(pChar+8); //指针后移1个Tag DataLen = DataLen-8; i++; //合法OID计数器 printf("\r\nServer Receive Startup Response Status:0x%.4x\r\n",FramStatus); //测试使用 break; } default: { #if DEBUG_TEST printf("\r\nWarning!!Tag OID not recognition!\r\n"); //测试使用 #endif pOid =(uint32_t*)(pChar+1); //指针后移一个字节,查询后续有无合法OID DataLen = DataLen-1; //指针后移一个字节,查询后续有无合法OID break; } } } } else { #if DEBUG_TEST printf("\r\nWarning!!Receive Startup Response Data Not Rrecognition!\r\n"); //测试使用 #endif } break; } default: { #if DEBUG_TEST printf("\r\nWarning!!PDU Type not recognition!\r\n"); //测试使用 #endif break; } } } int my_strlen(char *str) { // assert(str != NULL); if (*str == '\0') { return 0; } else { return (1 + my_strlen(++str)); } } /******************************************************************************* * Function Name : XX * Description : 433模块接收数据解析(第一层) * Input : None * Output : None * Return : None *******************************************************************************/ uint16_t Receive_Data_Analysis(char* recev_buff) { uint16_t ReceiveFlag = 0; //接收数据正确性标志变量 char* pRecevBuff = NULL; char RecevFromCollector[2] = {0xA3, 0x20}; //接收数据集中器数据标志序列,如果软件版本号有改动,后续软件需要做相应修改 uint8_t PayloadLen = 0; uint8_t CrcSize = 0; uint16_t CrcVerify = 0x0000; uint16_t CrcRecev = 0x0000; uint8_t j = 0; char TempBuffer[RECEIVEBUFF_SIZE]; uint8_t count = 0; printf("\r\n接收数据解析!!\r\n"); if(SIMCard_Type == 1) /* 电信平台将字符转成hex格式 */ { pRecevBuff = Find_SpecialString(recev_buff, "A320", 1024, 4); //检查模块入网状态 if(pRecevBuff != NULL) { string_to_hex(TempBuffer, pRecevBuff); PayloadLen = TempBuffer[2] * 256 + TempBuffer[3] + 6 - 16 - 2; //Tag-list数据长度 if((PayloadLen % 8) != 0) { PayloadLen += (8 - (PayloadLen % 8)); } PayloadLen += 18;//整条报文数据长度 printf("\r\n T PayloadLen:%d \r\n", PayloadLen); //测试使用 } } else { pRecevBuff = Find_SpecialString(recev_buff, RecevFromCollector, 1024, strlen(RecevFromCollector)); if(pRecevBuff != NULL) { PayloadLen = pRecevBuff[2] * 256 + pRecevBuff[3] + 6 - 16 - 2; //Tag-list数据长度 if((PayloadLen % 8) != 0) { PayloadLen += (8 - (PayloadLen % 8)); } PayloadLen += 18;//整条报文数据长度 printf("\r\n MU PayloadLen:%d \r\n", PayloadLen); //测试使用 for(j = 0; j < PayloadLen; j++) { TempBuffer[j] = pRecevBuff[j]; } } } if((pRecevBuff != NULL) && (pRecevBuff < recev_buff + (1024 - 1 - 3))) //防止指针越界 { CrcSize = PayloadLen - 2; //计算校验数据长度,不包括CRC字段 CrcVerify = CRC16((uint8_t*)TempBuffer, CrcSize); CrcRecev = TempBuffer[CrcSize] * 256 + TempBuffer[CrcSize + 1]; //上位机CRC高字节在前低字节在后,与上位机保持一致 if(CrcRecev == CrcVerify) { printf("\r\nReceive data right!!\r\n"); //测试使用 Tea_Decrypt((uint8_t*)(TempBuffer + 16), PayloadLen - 16 - 2); Treaty_Data_Analysis((uint8_t*)TempBuffer, &ReceiveFlag); //解析接收数据 } else { printf("\r\nReceive data not correct!!\r\n"); //测试使用 } while (1) { if (count > 10) { break; } vTaskDelay(500 / portTICK_PERIOD_MS); count++; } // vTaskDelay(500); pRecevBuff = NULL; } else { pRecevBuff = NULL; printf("\r\nReceive data invalid!\rConsult Finish!\r\n"); //测试使用 } printf("\r\n接收数据解析完成!!\r\n");//调试使用 return ReceiveFlag; }