www.pudn.com > TC35I.zip > TC35I.C
#include "hardware.h" #include "uart.h" #include "protocol.h" #include "system.h" #includeUART0_RECV xdata g_UART0RBuf; UART0_SEND xdata g_UART0SBuf; UINT8 xdata *g_pSendUART0Buf; UINT8 xdata g_Modem_S_Delay; //猫发过来的数据堆栈空间 Modem_Buffer xdata g_ModemSP[Modem_SP]; UINT8 xdata g_ModemWaitRecvEndTime; UINT8 xdata g_ModemCurrentSPIndex; DEL_MSG_SP xdata g_ModemDelMsgSP[Modem_SP]; RECE_DATA xdata g_UART0_Rcv_Bak[MODEM_RCV_BAK_MAX]; UINT8 xdata g_Eeprom_Data [ALL_EEPROM_DATA] ; //所有与中心相关的有用数据空间 SAVE_EEPROM xdata g_SaveData; BOOL g_Modem_Init_Ok; BOOL g_Modem_PowerOn; BOOL g_Modem_SendSMS; UINT8 g_Modem_InitIndex; UINT8 xdata g_Modem_WaitSendSMSTime; UINT8 xdata g_RS485Flag; //是主机,还是从机, extern UINT16 xdata g_AlarmPacketSN; extern UINT8 g_UARTStatus; extern UINT8 g_ModemAT_Index; //呼叫MODEM的次序 extern ALARM_THREAD xdata g_AlarmThread[10]; extern ALARM_ITEM xdata g_AlarmStatusChangeFlag,g_AlarmItem; code char *AT_SMS_INIT [ ] = { "AT\r\n", "ATE0\r\n", "AT+CMGF=1\r\n", "AT&W\r\n", "AT+CSMS=1\r\n", "AT&W\r\n", "AT+CNMI=2,1,0,0,1\r\n", "AT&W\r\n", //"AT+CSCA=", "AT+CMGD=1\r\n", "\0", }; code char *AT_MODEM_INIT [] = { "AT\r\n", "ATE0\r\n", "ATQ1\r\n", "ATH0\r\n", "ATS0=2\r\n", "\0", }; void UART0_IRQ(void) interrupt 4 { UINT8 UARTDat; static bit NeedCheckFirstCharFlag = 0; if(TI) { TI=0; if(g_UART0SBuf.Send_Num) { SBUF=*g_pSendUART0Buf; g_pSendUART0Buf++; g_UART0SBuf.Send_Num--; } else g_UART0SBuf.Send_Busy=0; } if(RI) { RI=0; UARTDat=SBUF; #if 0 if(!g_UART0RBuf.TimeOut) { //需要过滤数据,本地数据以'X'开头,猫的数据以'+'开头 if(!((UARTDat==0x7E)||(UARTDat=='+'))) return; g_UART0RBuf.Recv_Num=0; } g_UART0RBuf.Recv_Buf[g_UART0RBuf.Recv_Num++]=UARTDat; g_UART0RBuf.TimeOut=MODEM_DELAY; #else //如果是猫过来的数据就先压在猫栈里面 //如果是本地过来的数据就直接防在待处理的缓冲区中 if(g_UARTStatus == ON_MODEM) { if(NeedCheckFirstCharFlag) { if(UARTDat == '+') g_ModemWaitRecvEndTime = 0; } if(!g_ModemWaitRecvEndTime) { if(UARTDat != '+') return; NeedCheckFirstCharFlag = 0; //过滤好数据后开始寻找猫栈空间 for(g_ModemCurrentSPIndex = 0; g_ModemCurrentSPIndex< Modem_SP; g_ModemCurrentSPIndex++) { if(g_ModemSP[g_ModemCurrentSPIndex].Length == 0) break; } if(g_ModemCurrentSPIndex == Modem_SP) return; //找不到空间了 } //将数据填充进去 g_ModemSP[g_ModemCurrentSPIndex].Buffer[g_ModemSP[g_ModemCurrentSPIndex].Length] = UARTDat; g_ModemSP[g_ModemCurrentSPIndex].Length++; g_ModemWaitRecvEndTime = MODEM_DELAY; //如果近来的数据有回车,换行,那么就要为开始存放在下一个栈区 //但是需要注意除非下一个字符是'+',否则继续 if(UARTDat == 0x0A) NeedCheckFirstCharFlag = 1; } #endif } } void UART0_SendStrInit(UINT8 *SendBuf,UINT8 SendLength,BOOL CopyBufDataFlag) { g_UART0SBuf.Send_Num=SendLength; if(CopyBufDataFlag) Memcopy(g_UART0SBuf.Send_Buf, SendBuf, SendLength); g_pSendUART0Buf=g_UART0SBuf.Send_Buf; g_UART0SBuf.Send_Busy=1; TI=1; while(g_UART0SBuf.Send_Busy); } //----------------------------提取‘litter’字符区内的数据--------------------------- unsigned char Get_The_String ( unsigned char *des , unsigned char *buf , unsigned char litter ) { UINT8 i; while(*buf&&(*buf!=litter)) //查找第1个字符 buf++; if(!*buf) return 0; buf++; //跳过这个字符 i=0; while(*buf&&(*buf!=litter)) //开始拷贝特征字符之间的数据 { *des++=*buf++; i++; } if(*buf!=litter) i=0; //如果没有结尾符,照样判断是出错,防呆处理 return i; //返回拷贝数据的长度 } //------------------------------获取电话号码----------------------------------------- unsigned char Get_The_Phone ( unsigned char *des , unsigned char *src ) { #if 0 unsigned char i ; i = Get_The_String ( src , src , '\"' ) ; //find the " " if(!(i) ) return 0 ; Memcopy ( des , " " , 15 ) ; //清数据区 if ( i <= 15 ) Memcopy( des , src , i ) ; //保存号码 else Memcopy( des , src+i-15 , 15 ); //如果号码超长,则保存最后15位 return ( i ) ; //返回号码长度(可能包含'+86'等),0为未找到 #else unsigned char i; //首先查找第1个\" while(*src && (*src!='\"')) src++; if(!*src) return 0; src++; //Memcopy ( des , " " , 20 ) ; //清数据区 //开始copy电话号码,最大到20位 i=0; while(*src && (*src!='\"')) { *des++=*src++; i++; if(i==20) break; } return i; #endif } //------------------------------查找字符,并返回该字符的位置--------------- //注意传入的字符串最后必须以0结尾 //如果没有该字符返回0 unsigned char Find_The_Str(unsigned char *src,unsigned char litter) { UINT8 i=1; while(*src&&(*src!=litter)) { src++; i++; } if(*src) return i; else return 0; } //下面是处理猫的堆栈 void Deal_Modem_SP(void) { UINT8 i; //需要在猫上面 if(g_UARTStatus != ON_MODEM) return; //猫没有初始化OK也不能做 if(!g_Modem_Init_Ok) return; //怕已经COPY一个队列数据,但是还没有来的及处理,所以要等待 if(g_UART0RBuf.Recv_Num) return; //看堆栈是不是正在被后台处理 if(g_ModemWaitRecvEndTime) return; //寻找堆栈中有用的数据 for(i = 0; i < Modem_SP; i++) { if(g_ModemSP[i].Length) break; } if(i == Modem_SP) return; //没有发现有用的数据 #if 0 //测试使用 UART0_SendStrInit(g_ModemSP[i].Buffer, g_ModemSP[i].Length, 1); g_ModemSP[i].Length = 0; return; #endif //COPY数据到待处理的缓冲区中 Memcopy(g_UART0RBuf.Recv_Buf, g_ModemSP[i].Buffer, g_ModemSP[i].Length); //COPY数据长度 g_UART0RBuf.Recv_Num = g_ModemSP[i].Length; //删掉相应的空间 g_ModemSP[i].Length = 0; //debug使用================================= #if 0 Lcd_ShowStrings(Line2, 1, " SP----->Buff ", 16); #endif //========================================== } //下面是删除猫栈中的信息 void Del_Modem_MSG_SP(void) { UINT8 ModemBufWIndex; //需要在猫上面 if(g_UARTStatus != ON_MODEM) return; //需要在主机上才行 if(g_RS485Flag == RS485_SLAVE) return; //看堆栈是不是正在被后台处理 if(g_ModemWaitRecvEndTime) return; //如果还有短信需要发送,就要等待 if(g_UART0_Rcv_Bak[MODEM_RCV_BAK_MAX-1].Processed) return; //看有没有在等待猫输出 if(g_Modem_WaitSendSMSTime) return; //还要看缓冲区中有没有需要被处理的数据 for(ModemBufWIndex = 0; ModemBufWIndex < (MODEM_RCV_BAK_MAX-1); ModemBufWIndex++) //最后一个要拿来做发送处理的缓冲区 if(g_UART0_Rcv_Bak[ModemBufWIndex].Processed) return; //还要等待没有任何操作猫的空闲时间 if(g_UART0SBuf.Send_Delay) return; //恭喜现在可以删除短信了 //首先寻找删除栈中有效的数据 for(ModemBufWIndex = 0; ModemBufWIndex < Modem_SP; ModemBufWIndex++) if(g_ModemDelMsgSP[ModemBufWIndex].Length) break; if(ModemBufWIndex == Modem_SP) return; //短信已经被删除完了 UART0_SendStrInit(g_ModemDelMsgSP[ModemBufWIndex].Buffer, g_ModemDelMsgSP[ModemBufWIndex].Length, 1); g_UART0SBuf.Send_Delay = 250; //等待删除时间为2.5秒 //清掉当前这个数据栈 g_ModemDelMsgSP[ModemBufWIndex].Length = 0; } //下面是处理接收RS232或猫过来的数据 void Serial_Receive_Event(void) { UINT8 xdata TempPhoneNum[20]; UINT8 xdata TempPhoneCnt; UINT8 xdata TempSerialBuf[256]; UINT8 xdata TempSerialBufCnt; UINT8 xdata ModemBufWIndex; UINT16 xdata RecvDataLength; //暂时先考虑成>256个数据 UINT8 xdata MsgPositionData[15]; UINT8 xdata MsgPositionDataLength; RECE_DATA xdata *pWReceDat; UINT8 xdata *pS; UINT8 xdata *pD; UINT16 xdata CRCData; UINT8 xdata SpecChr_Position; if(g_UART0RBuf.Recv_Num) //串口缓冲区中有一包正常的数据 { g_UART0RBuf.Recv_Buf[g_UART0RBuf.Recv_Num]=0; //填充最后一个数据 RecvDataLength = g_UART0RBuf.Recv_Num; g_UART0RBuf.Recv_Num=0; //表示此串口缓冲区数据已被处理 //debug使用==================================== #if 0 Lcd_ShowStrings(Line2, 1, g_UART0RBuf.Recv_Buf, 16); #endif //============================================= //先寻找空的接入层缓冲区 ModemBufWIndex=0; while( ModemBufWIndex<(MODEM_RCV_BAK_MAX-1)) //最后一个要拿来做发送处理的缓冲区 { if(g_UART0_Rcv_Bak[ModemBufWIndex].Processed==0) break; ModemBufWIndex++; } if( ModemBufWIndex==(MODEM_RCV_BAK_MAX-1)) //已经没有数据空间了 return; pWReceDat = &g_UART0_Rcv_Bak[ModemBufWIndex]; //首先将电话号码的长度清0 //因为在RS232和IP+UDP上,电话号码是没有的 pWReceDat->PhoneNum = 0; //注意处理RS232采用A协议,需要做转义处理,无须字节拆分 //处理猫过来的数据采用B协议,需要字节拆分,无需转义处理 //处理网卡通信采用C协议,数据是透明的 if(g_UARTStatus == ON_PC) goto DealRS232_A_Protocol; else if(g_UARTStatus == ON_MODEM) goto DealModem_B_Protocol; else goto DealEthernet_C_Protocol; DealRS232_A_Protocol: //下面是对本地串口过来的数据进行处理 //处理方式:先做转义处理,再计算CRC //最后将协议包数据从新转移到代处理的缓冲区中 //debug 使用============================== #if 0 Lcd_ShowStrings(Line2, 1, &g_UART0RBuf.Recv_Buf[0], 16); #endif //======================================= //先判断是否为正常的数据包其始数据 if(g_UART0RBuf.Recv_Buf[0] != 0x7E) return; //转义处理 //先除去头尾2个字节 RecvDataLength -= 2; pS = &g_UART0RBuf.Recv_Buf[1]; pD = &g_UART0RBuf.Recv_Buf[0]; CRCData = 0; while(RecvDataLength) { if(*pS == 0x5E) { pS++; RecvDataLength--; if(*pS == 0x5D) *pD = 0x5E; else if(*pS == 0x7D) *pD = 0x7E; } else *pD = *pS; pD++; pS++; CRCData++; RecvDataLength--; } RecvDataLength = CRCData; pWReceDat->DataSource = DataSource_RS232; goto Deal_CRC; DealModem_B_Protocol: //下面是对猫过来的数据(短信)进行处理 //处理方式:先进行合并处理,再计算CRC //最后将协议包数据从新转移到代处理的缓冲区中 //先看是不是短信猫发出的特殊回应,针对读,删除短信功能 if(g_UART0RBuf.Recv_Buf[0] == '+') { if(MemCmpr(&g_UART0RBuf.Recv_Buf[1], "CMTI", 4)==0) //提示有短信到 { //寻找',' SpecChr_Position=Find_The_Str(g_UART0RBuf.Recv_Buf, ','); //寻找结束符号 MsgPositionDataLength = Find_The_Str(g_UART0RBuf.Recv_Buf, 0x0A)-SpecChr_Position; //COPY短信存储位置到缓冲区中, 目的是等一下好删除这条短信 Memcopy(MsgPositionData, "AT+CMGD=", 8); Memcopy(&MsgPositionData[8], &g_UART0RBuf.Recv_Buf[SpecChr_Position], MsgPositionDataLength); //在删除短信的堆栈中寻找空间 //临时用电话号码长度来做中间变量 for(TempPhoneCnt = 0; TempPhoneCnt < Modem_SP; TempPhoneCnt++) if(g_ModemDelMsgSP[TempPhoneCnt].Length == 0) { Memcopy(g_ModemDelMsgSP[TempPhoneCnt].Buffer, MsgPositionData, 8 + MsgPositionDataLength); g_ModemDelMsgSP[TempPhoneCnt].Length = 8 + MsgPositionDataLength; break; } //发送读短信的命令 //等待1秒后再去读短信 g_UART0SBuf.Send_Delay=100; while(g_UART0SBuf.Send_Delay); //先等待串口没有操作,怕万一这时有短信提醒 while(g_ModemWaitRecvEndTime); UART0_SendStrInit("AT+CMGR=", 8, 1); UART0_SendStrInit(&g_UART0RBuf.Recv_Buf[SpecChr_Position], MsgPositionDataLength, 1); //等待1秒种去读短信内容,目的是不让其他的操作猫 g_UART0SBuf.Send_Delay=100; //目前先设10秒去等待看还会不回收到下一条短信 //目的就是避开发送短信时又在接收短信 //因为在发射又接收的时候,发射会失败 g_Modem_WaitSendSMSTime = 4 * 10; return; } else if(MemCmpr(&g_UART0RBuf.Recv_Buf[1], "CMGR", 4)==0) { //寻找',' SpecChr_Position=Find_The_Str(g_UART0RBuf.Recv_Buf, ','); //先将存短信号码的内存清空 for(TempPhoneCnt=0; TempPhoneCnt<20; TempPhoneCnt++) TempPhoneNum[TempPhoneCnt] = 0x00; TempPhoneCnt=Get_The_Phone(TempPhoneNum, &g_UART0RBuf.Recv_Buf[SpecChr_Position]); //取电话号码 } else if(MemCmpr(&g_UART0RBuf.Recv_Buf[1], "CMGS", 4)==0) { g_Modem_SendSMS=OK; return; } else return; } else return; //debug 使用===================================== #if 0 Lcd_ClearLine(Line2); Lcd_ShowStrings(Line2, 1, TempPhoneNum, TempPhoneCnt); #endif //============================================== TempSerialBufCnt=Get_The_String(TempSerialBuf, g_UART0RBuf.Recv_Buf, 0x21); //取协议数据 //debug使用====================================== #if 0 Lcd_ClearLine(Line2); Lcd_ShowStrings(Line2, 1, TempSerialBuf, 16); #endif //=============================================== //判断数据包是否正常 if(TempSerialBufCnt == 0) return; //先保存电话号码 Memcopy(pWReceDat->RecePhone, TempPhoneNum, 20); pWReceDat->PhoneNum = TempPhoneCnt; //数据合并处理,并放入到接收缓冲区中 RecvDataLength = Data_Combin(g_UART0RBuf.Recv_Buf, TempSerialBuf, TempSerialBufCnt); pWReceDat->DataSource = DataSource_SMS; goto Deal_CRC; DealEthernet_C_Protocol: //下面是对网卡(IP+UDP)过来的数据进行处理 //处理方式:把数据当成透明的 pWReceDat->DataSource = DataSource_UDP; goto SaveData2Buffer; Deal_CRC: //从新修正数据长度,先除掉CRC 2字节 RecvDataLength -= 2; //goto SaveData2Buffer; //debug使用 //计算CRC CRCData = CRC16_Get(&g_UART0RBuf.Recv_Buf, (UINT8)RecvDataLength); //CRC校验 if((((UINT8*)&CRCData)[0] != g_UART0RBuf.Recv_Buf[RecvDataLength+1]) || (((UINT8*)&CRCData)[1] != g_UART0RBuf.Recv_Buf[RecvDataLength])) return; SaveData2Buffer: //将数据保存到待处理的备份缓冲区中 //注意数据包格式:协议类型承载协议类型PDU Memcopy(pWReceDat->ReceData, g_UART0RBuf.Recv_Buf, RecvDataLength); pWReceDat->DataNum = RecvDataLength; //debug使用==================================== #if 0 SpecChr_Position = pWReceDat->DataNum / 10 + 0x30; Lcd_ShowStrings(Line2, 1, &SpecChr_Position, 1); SpecChr_Position = pWReceDat->DataNum % 10 + 0x30; Lcd_ShowStrings(Line2, 2, &SpecChr_Position, 1); #endif //============================================= //做好标记,表示有正常待处理的数据 pWReceDat->Processed = 0x01; } } void Deal_Rcv_BakBuf(void) { UINT8 xdata ModemBufRIndex; UINT8 xdata i; NET_PROTOCOL xdata *pRNP; NET_PROTOCOL xdata *pWNP; RECE_DATA xdata *pSrc; RECE_DATA xdata *pDes; MONITOR_INFO xdata *pRObject; MONITOR_INFO xdata *pWObject; UINT8 xdata MAP_PDU_Length; UINT8 xdata RSumObjectDataLength; UINT8 xdata WSumObjectDataLength; UINT8 xdata *pWOC; UINT8 xdata *pROC; UINT16 xdata OID; //先判断需要被发送的缓冲区中是否为空 if(g_UART0_Rcv_Bak[MODEM_RCV_BAK_MAX-1].Processed) //回应的数据缓冲区还没有被处理 return; //寻找待处理的备份缓冲区中是否有待处理的数据 ModemBufRIndex=0; while(ModemBufRIndex<(MODEM_RCV_BAK_MAX-1)) { if(g_UART0_Rcv_Bak[ModemBufRIndex].Processed==0x00) ModemBufRIndex++; else break; } if(ModemBufRIndex==(MODEM_RCV_BAK_MAX-1)) //数据缓冲区没有需要处理的新包数据 return; //debug使用======================================== #if 0 MAP_PDU_Length = ModemBufRIndex / 10 + 0x30; Lcd_ShowStrings(Line2, 1, &MAP_PDU_Length, 1); MAP_PDU_Length = ModemBufRIndex % 10 + 0x30; Lcd_ShowStrings(Line2, 2, &MAP_PDU_Length, 1); #endif //================================================= pSrc = &g_UART0_Rcv_Bak[ModemBufRIndex]; pDes = &g_UART0_Rcv_Bak[MODEM_RCV_BAK_MAX-1]; //标记已经被处理 pSrc->Processed = 0x00; //如果有电话号码,直接COPY电话号码数据 if(pSrc->PhoneNum) { pDes->PhoneNum = pSrc->PhoneNum; Memcopy(pDes->RecePhone, pSrc->RecePhone, pSrc->PhoneNum); } else pDes->PhoneNum = 0; //debug使用========================================= #if 0 Lcd_ClearLine(Line2); Lcd_ShowStrings(Line2, 1, pDes->RecePhone, pDes->PhoneNum); #endif //================================================== //指向数据体 //先COPY协议类型 承载协议类型 pDes->ReceData[0] = pSrc->ReceData[0]; pDes->ReceData[1] = pSrc->ReceData[1]; pRNP = (NET_PROTOCOL*)&g_UART0_Rcv_Bak[ModemBufRIndex].ReceData[2]; pWNP = (NET_PROTOCOL*)&g_UART0_Rcv_Bak[MODEM_RCV_BAK_MAX-1].ReceData[2]; //将通信方式COPY过去 pDes->DataSource = pSrc->DataSource; //首先将站点编号和通信包标志号返回 Memcopy((UINT8*)pWNP, (UINT8*)pRNP, 7); //更新回应的NP曾交互标志 pWNP->CommFlag = 0x00; //应用协议标志 pWNP->APID = 0x01; //将命令COPY过去 pWNP->MAP.CommandFlag = pRNP->MAP.CommandFlag; //将应答标志设为OK pWNP->MAP.ACKFlag = 0x00; //通信安全性鉴权处理 //处理方式:放弃 #if 0 //首先检查站点信息 if(MemCmpr(pRNP->RepeaterMainNum, &g_Eeprom_Data[OFF_DEVICE_MAIN_NUM], 5)) { //站点信息安全检查失败,放弃处理该包数据 return; } #endif //这个系统很特殊,因为没有近端配置, //所以在远程就不对电话号码安全行检查了, #if 0 if(pSrc->DataSource == DataSource_SMS) { for(i = 0; i < 20; i++) TempPhoneNum[i] = 0x20; Memcopy(TempPhoneNum, pDes->RecePhone, pDes->PhoneNum); //其次检查电话号码是否和DB中的一样 if(MemCmpr(TempPhoneNum, &g_Eeprom_Data[OFF_PHONE1], 20) == 0) goto StartDealCommand; if(MemCmpr(TempPhoneNum, &g_Eeprom_Data[OFF_PHONE2], 20) == 0) goto StartDealCommand; if(MemCmpr(TempPhoneNum, &g_Eeprom_Data[OFF_PHONE3], 20) == 0) goto StartDealCommand; if(MemCmpr(TempPhoneNum, &g_Eeprom_Data[OFF_PHONE4], 20) == 0) goto StartDealCommand; if(MemCmpr(TempPhoneNum, &g_Eeprom_Data[OFF_PHONE5], 20) == 0) goto StartDealCommand; return; } #endif //StartDealCommand: //这里先区分是否为OMC发过来的告警上报确认包 if(pRNP->MAP.CommandFlag == Param_Alarm) { //需要处理看是哪些上报的告警信息已经得到确认 //如果是告诉从机的,那么要转发给从机,从机收到后不用回传信息给主机 //让主机采用超时的方式退出 //开始查找报警通信包栈 for(i=0; i CommPacketSN[1]) && (((UINT8*)&g_AlarmThread[i].PacketSN)[1] == pRNP->CommPacketSN[0])) break; } if(i == (Alarm_BackUp_Max - 1)) g_AlarmThread[i].PacketSN = 0x0000; else if(i != Alarm_BackUp_Max) { while(i < (Alarm_BackUp_Max - 1)) { g_AlarmThread[i].PacketSN = 0x0000; if(g_AlarmThread[i+1].PacketSN) Memcopy((UINT8*)&g_AlarmThread[i], (UINT8*)&g_AlarmThread[i+1], sizeof(ALARM_THREAD)); else break; i++; } } return; } //先将缓冲区中数据长度给初始值 pDes->DataNum =1 + 1 + NP_TotalCommandHeadLength; //先计算MAP 的PDU 长度 MAP_PDU_Length = pSrc->DataNum - NP_TotalCommandHeadLength -1 -1; RSumObjectDataLength = 0; WSumObjectDataLength = 0; //debug使用======================================= #if 0 ModemBufRIndex = MAP_PDU_Length / 100 + 0x30; Lcd_ShowStrings(Line2, 1, &ModemBufRIndex, 1); ModemBufRIndex = MAP_PDU_Length /10 % 10 + 0x30; Lcd_ShowStrings(Line2, 2, &ModemBufRIndex, 1); ModemBufRIndex = MAP_PDU_Length % 10 + 0x30; Lcd_ShowStrings(Line2, 3, &ModemBufRIndex, 1); #else #if 0 #if 0 ModemBufRIndex = pSrc->ReceData[36] / 100 + 0x30; Lcd_ShowStrings(Line2, 1, &ModemBufRIndex, 1); ModemBufRIndex = pSrc->ReceData[36] / 10 % 10 + 0x30; Lcd_ShowStrings(Line2, 2, &ModemBufRIndex, 1); ModemBufRIndex = pSrc->ReceData[36] % 10 + 0x30; Lcd_ShowStrings(Line2, 3, &ModemBufRIndex, 1); #else //首先指向监控对象长度位置 pRObject = &pRNP->MAP.Object + 23; ModemBufRIndex = pRObject->OL / 100 + 0x30; Lcd_ShowStrings(Line2, 1, &ModemBufRIndex, 1); ModemBufRIndex = pRObject->OL / 10 % 10 + 0x30; Lcd_ShowStrings(Line2, 2, &ModemBufRIndex, 1); ModemBufRIndex = pRObject->OL % 10 + 0x30; Lcd_ShowStrings(Line2, 3, &ModemBufRIndex, 1); #endif #endif #endif //================================================ //循环命令处理 while(MAP_PDU_Length) { //首先指向监控对象长度位置 #if 0 pRObject = &pRNP->MAP.Object + RSumObjectDataLength; pWObjec = &pWNP->MAP.Object + WSumObjectDataLength; #else pRObject = (MONITOR_INFO*)&pSrc->ReceData[1 + 1 + NP_TotalCommandHeadLength + RSumObjectDataLength]; pWObject= (MONITOR_INFO*)&pDes->ReceData[1 + 1 + NP_TotalCommandHeadLength + WSumObjectDataLength]; #endif //更新长度,为指向下一个监控对象做准备 RSumObjectDataLength += pRObject->OL; //更新已处理了的数据缓冲区长度 //加入防呆处理,怕万一数据长度有错就麻烦了 if(MAP_PDU_Length >= pRObject->OL) MAP_PDU_Length -= pRObject->OL; else MAP_PDU_Length = 0; //debug使用======================================= #if 0 ModemBufRIndex = pRObject->OL / 10 + 0x30; Lcd_ShowStrings(Line2, 1, &ModemBufRIndex, 1); ModemBufRIndex = pRObject->OL % 10 + 0x30; Lcd_ShowStrings(Line2, 2, &ModemBufRIndex, 1); #endif //================================================ //取出命令 ((UINT8*)&OID)[0] = pRObject->OID[1]; ((UINT8*)&OID)[1] = pRObject->OID[0]; //debug使用======================================= #if 0 ModemBufRIndex = OID / 10000 + 0x30; Lcd_ShowStrings(Line2, 1, &ModemBufRIndex, 1); ModemBufRIndex = OID /1000 % 10 + 0x30; Lcd_ShowStrings(Line2, 2, &ModemBufRIndex, 1); ModemBufRIndex = OID / 100 %10 + 0x30; Lcd_ShowStrings(Line2, 3, &ModemBufRIndex, 1); ModemBufRIndex = OID /10 % 10 + 0x30; Lcd_ShowStrings(Line2, 4, &ModemBufRIndex, 1); ModemBufRIndex = OID % 10 + 0x30; Lcd_ShowStrings(Line2, 5, &ModemBufRIndex, 1); #endif //================================================ //先将命令写回到缓冲区中 pWObject->OID[0] = pRObject->OID[0]; pWObject->OID[1] = pRObject->OID[1]; //先将长度写回到缓冲区中 //这里有可能是上位机发过来的信息是错的,暂时没有做防呆处理 pWObject->OL = pRObject->OL; //更新写回缓冲区的数据长度 WSumObjectDataLength +=pWObject->OL; pDes->DataNum +=pWObject->OL; //为方便读写数据,定义新的指针指向监控内容的首地址 pWOC = &pWObject->OC; pROC = &pRObject->OC; if(OID < 0x00FF) { //这里需要做出错处理 //命令:0x0000 ~ 0x00FF只能读取,不可设置 if(pRNP->MAP.CommandFlag == Param_Set) { Memcopy(pWOC, pROC, pRObject->OL); //回复命令错误 pWNP->MAP.ACKFlag = 0x02; } else { switch(OID) { case OID_R_DEVICE_CODE: *pWOC = g_Eeprom_Data[OFF_DEVICE_COMMPANY_CODE]; break; case OID_R_DEVICE_TYPE: *pWOC = g_Eeprom_Data[OFF_DEVICE_TYPE]; break; case OID_R_DEVICE_INFO: Memcopy(pWOC, &g_Eeprom_Data[OFF_DEVICE_INFO], 20); break; case OID_R_DEVICE_PRODUCT_SN: Memcopy(pWOC, &g_Eeprom_Data[OFF_DEVICE_MAKE_SN], 20); break; case OID_R_DEVICE_TOTAL_CHANNEL: *pWOC = g_Eeprom_Data[OFF_DEVICE_TOTAL_CHANNEL]; break; case OID_R_LONGITUDE: Memcopy(pWOC, &g_Eeprom_Data[OFF_LONGITUDE], 20); break; case OID_R_LATITUDE: Memcopy(pWOC, &g_Eeprom_Data[OFF_LATITUDE], 20); break; case OID_R_DEVICE_MONITOR_ITEM: *pWOC++ = 1; //通知远程查3次 *pWOC++ = 1; //这是第1次 *pWOC++ = 0x02; *pWOC++ = 0x00; *pWOC++ = 0x04; *pWOC++ = 0x00; *pWOC++ = 0x05; *pWOC++ = 0x00; *pWOC++ = 0x09; *pWOC++ = 0x00; *pWOC++ = 0x01; *pWOC++ = 0x01; *pWOC++ = 0x02; *pWOC++ = 0x01; *pWOC++ = 0x11; *pWOC++ = 0x01; *pWOC++ = 0x20; *pWOC++ = 0x01; *pWOC++ = 0x40; *pWOC++ = 0x01; *pWOC++ = 0x50; *pWOC++ = 0x01; *pWOC++ = 0x01; *pWOC++ = 0x02; *pWOC++ = 0x04; *pWOC++ = 0x02; *pWOC++ = 0x01; *pWOC++ = 0x03; *pWOC++ = 0x04; *pWOC++ = 0x03; pWObject->OL = 33; pDes->DataNum += 28; break; default: Memcopy(pWOC, pROC, pRObject->OL); pWObject->OID[1] += 0x10; break; } } } else if((OID > 0x0100) && (OID < 0x01FF)) { //这里是可以设置,也可以读取 //如果是设置,需要将设置的内容原封不动地返回给监控中心 if(pRNP->MAP.CommandFlag == Param_Set) Memcopy(pWOC, pROC, pRObject->OL); switch(OID) { case OID_RW_DEVICE_MAIN_NUM: if(pRNP->MAP.CommandFlag == Param_Inquiry) //查询 Memcopy(pWOC, &g_Eeprom_Data[OFF_DEVICE_MAIN_NUM], 4); else { //设置 Memcopy(&g_Eeprom_Data[OFF_DEVICE_MAIN_NUM], pROC, 4); //注意这里需要更新NP层的站点信息 Memcopy(pWNP->RepeaterMainNum, pROC, 4); //保存数据到EEPROM中 g_SaveData.StartAddress = OFF_DEVICE_MAIN_NUM; g_SaveData.SaveNum = 4; g_SaveData.SaveFlag = 1; } break; case OID_RW_DEVICE_SUB_NUM: if(pRNP->MAP.CommandFlag == Param_Inquiry) *pWOC = g_Eeprom_Data[OFF_DEVICE_SUB_NUM]; else { g_Eeprom_Data[OFF_DEVICE_SUB_NUM] = *pROC; //更新NP层站点信息 pWNP->RepeaterSubNum = *pROC; //保存数据到EEPROM中 g_SaveData.StartAddress = OFF_DEVICE_SUB_NUM; g_SaveData.SaveNum = 1; g_SaveData.SaveFlag = 1; } break; case OID_RW_SMS_CENTER_NUM: if(pRNP->MAP.CommandFlag == Param_Inquiry) Memcopy(pWOC, &g_Eeprom_Data[OFF_SMS_CENTER_NUM], 20); else { Memcopy(&g_Eeprom_Data[OFF_SMS_CENTER_NUM], pROC, 20); //保存数据到EEPROM中 g_SaveData.StartAddress = OFF_SMS_CENTER_NUM; g_SaveData.SaveNum = 20; g_SaveData.SaveFlag = 1; } break; case OID_RW_PHONE1: case OID_RW_PHONE2: case OID_RW_PHONE3: case OID_RW_PHONE4: case OID_RW_PHONE5: if(pRNP->MAP.CommandFlag == Param_Inquiry) Memcopy(pWOC, &g_Eeprom_Data[OFF_PHONE1 + (OID - OID_RW_PHONE1)*20], 20); else { Memcopy(&g_Eeprom_Data[OFF_PHONE1 + (OID - OID_RW_PHONE1)*20], pROC, 20); //保存数据到EEPROM中 g_SaveData.StartAddress = OFF_PHONE1 + (OID - OID_RW_PHONE1)*20; g_SaveData.SaveNum = 20; g_SaveData.SaveFlag = 1; } break; case OID_RW_ALARM_PHONE: if(pRNP->MAP.CommandFlag == Param_Inquiry) Memcopy(pWOC, &g_Eeprom_Data[OFF_ALARM_PHONE], 20); else { Memcopy(&g_Eeprom_Data[OFF_ALARM_PHONE], pROC, 20); //保存数据到EEPROM中 g_SaveData.StartAddress = OFF_ALARM_PHONE; g_SaveData.SaveNum = 20; g_SaveData.SaveFlag = 1; } break; case OID_RW_OMC_IP: if(pRNP->MAP.CommandFlag == Param_Inquiry) Memcopy(pWOC, &g_Eeprom_Data[OFF_OMC_IP], 4); else { Memcopy(&g_Eeprom_Data[OFF_OMC_IP], pROC, 4); //保存数据到EEPROM中 g_SaveData.StartAddress = OFF_OMC_IP; g_SaveData.SaveNum = 4; g_SaveData.SaveFlag = 1; } break; case OID_RW_COMM_MODE: if(pRNP->MAP.CommandFlag == Param_Inquiry) *pWOC = g_Eeprom_Data[OFF_COMM_MODE]; else { g_Eeprom_Data[OFF_COMM_MODE] = *pROC; //保存数据到EEPROM中 g_SaveData.StartAddress = OFF_COMM_MODE; g_SaveData.SaveNum = 1; g_SaveData.SaveFlag = 1; } break; case OID_RW_ALARM_TYPE: if(pRNP->MAP.CommandFlag == Param_Inquiry) *pWOC = g_Eeprom_Data[OFF_ALARM_TYPE]; else { g_Eeprom_Data[OFF_ALARM_TYPE] = *pROC; //保存数据到EEPROM中 g_SaveData.StartAddress = OFF_ALARM_TYPE; g_SaveData.SaveNum = 1; g_SaveData.SaveFlag = 1; } break; case OID_RW_DATE_TIME: if(pRNP->MAP.CommandFlag == Param_Inquiry) Memcopy(pWOC, &g_Eeprom_Data[OFF_DATE_TIME], 7); else { Memcopy(&g_Eeprom_Data[OFF_DATE_TIME], pROC, 7); //保存数据到EEPROM中 g_SaveData.StartAddress = OFF_DATE_TIME; g_SaveData.SaveNum = 7; g_SaveData.SaveFlag = 1; } break; default: Memcopy(pWOC, pROC, pRObject->OL); //回复命令错误 pWObject->OID[1] += 0x10; break; } } else if((OID > 0x0200) && (OID < 0x0215)) { //看是设置还是查询 if(pRNP->MAP.CommandFlag == Param_Inquiry) { //查询 *pWOC = g_Eeprom_Data[OFF_POWER_LOSE_ALARM_ENABLE + OID - 0x0201]; } else if(pRNP->MAP.CommandFlag == Param_Set) { //设置,需要将设置的内容原封不动地返回给监控中心 Memcopy(pWOC, pROC, pRObject->OL); //设置 g_Eeprom_Data[OFF_POWER_LOSE_ALARM_ENABLE + OID - 0x0201] = *pROC; //需要置上标志,上层存储 //保存数据到EEPROM中 g_SaveData.StartAddress = OFF_POWER_LOSE_ALARM_ENABLE + OID - 0x0201; g_SaveData.SaveNum = 1; g_SaveData.SaveFlag = 1; } } else if((OID >= 0x0220) && (OID < 0x0228)) { //看是设置还是查询 if(pRNP->MAP.CommandFlag == Param_Inquiry) { //查询 *pWOC = g_Eeprom_Data[OFF_EXTERNAL_ALARM_ENABLE1 + OID - 0x0220]; } else if(pRNP->MAP.CommandFlag == Param_Set) { //设置,需要将设置的内容原封不动地返回给监控中心 Memcopy(pWOC, pROC, pRObject->OL); //设置 g_Eeprom_Data[OFF_EXTERNAL_ALARM_ENABLE1 + OID - 0x0220] = *pROC; //需要置上标志,上层存储 //保存数据到EEPROM中 g_SaveData.StartAddress = OFF_EXTERNAL_ALARM_ENABLE1 + OID - 0x0220; g_SaveData.SaveNum = 1; g_SaveData.SaveFlag = 1; } } else if((OID > 0x0300) && (OID < 0x0315)) { //这里是只能读取,不可设置 if(pRNP->MAP.CommandFlag == Param_Inquiry) { if(g_AlarmItem.TotalItem & ((UINT32)1 << (OID - 0x0301))) *pWOC = 0x01; else *pWOC = 0x00; } else { //命令错误 Memcopy(pWOC, pROC, pRObject->OL); //回复命令错误 pWNP->MAP.ACKFlag = 0x02; } } else if((OID >= 0x0320) && (OID < 0x0328)) { //这里是只能读取,不可设置 if(pRNP->MAP.CommandFlag == Param_Inquiry) { if(((UINT8*)&g_AlarmItem.TotalItem)[3] & ((UINT8)1 << (OID - 0x0320))) *pWOC = 0x01; else *pWOC = 0x00; } else { //命令错误 Memcopy(pWOC, pROC, pRObject->OL); //回复命令错误 pWNP->MAP.ACKFlag = 0x02; } } else if((OID > 0x0400) && (OID < 0x04FF)) { //这里是可以设置,也可以读取 //如果是设置,需要将设置的内容原封不动地返回给监控中心 if(pRNP->MAP.CommandFlag == Param_Set) Memcopy(pWOC, pROC, pRObject->OL); if((OID >= 0x0410) && (OID <= 0x041F)) { if(pRNP->MAP.CommandFlag == Param_Inquiry) Memcopy(pWOC, &g_Eeprom_Data[OFF_CHANNEL + (OID - 0x0410)*2], 2); else { Memcopy(&g_Eeprom_Data[OFF_CHANNEL + (OID - 0x0410)*2], pROC, 2); //保存数据到EEPROM中 g_SaveData.StartAddress = OFF_CHANNEL + (OID - 0x0410)*2; g_SaveData.SaveNum = 2; g_SaveData.SaveFlag = 1; } } else if((OID >= 0x0420) && (OID <= 0x042F)) { if(pRNP->MAP.CommandFlag == Param_Inquiry) Memcopy(pWOC, &g_Eeprom_Data[OFF_MF_CHANNEL + (OID - 0x0420)*2], 2); else { Memcopy(&g_Eeprom_Data[OFF_MF_CHANNEL + (OID - 0x0420)*2], pROC, 2); //保存数据到EEPROM中 g_SaveData.StartAddress = OFF_MF_CHANNEL + (OID - 0x0420)*2; g_SaveData.SaveNum = 2; g_SaveData.SaveFlag = 1; } } else if((OID >= 0x0460) && (OID <= 0x0465)) { if(pRNP->MAP.CommandFlag == Param_Inquiry) *pWOC = g_Eeprom_Data[OFF_RF_SWITCH_STATUS + (OID - 0x0460)] & 0x01; else { g_Eeprom_Data[OFF_RF_SWITCH_STATUS + (OID - 0x0460)] = *pROC; //保存数据到EEPROM中 g_SaveData.StartAddress = OFF_RF_SWITCH_STATUS + (OID - 0x0460); g_SaveData.SaveNum = 1; g_SaveData.SaveFlag = 1; } } else { switch(OID) { case OID_RW_RF_ONOFF_STATUS: if(pRNP->MAP.CommandFlag == Param_Inquiry) *pWOC = g_Eeprom_Data[OFF_RF_ONOFF_STATUS] & 0x01; else { g_Eeprom_Data[OFF_RF_ONOFF_STATUS] = *pROC; //保存数据到EEPROM中 g_SaveData.StartAddress = OFF_RF_ONOFF_STATUS; g_SaveData.SaveNum = 1; g_SaveData.SaveFlag = 1; } break; case OID_RW_UP_SIDER_BAND_CHANNEL: if(pRNP->MAP.CommandFlag == Param_Inquiry) { *pWOC++ = g_Eeprom_Data[OFF_UP_SIDER_BAND_CHANNEL]; *pWOC = g_Eeprom_Data[OFF_UP_SIDER_BAND_CHANNEL+1]; } else { g_Eeprom_Data[OFF_UP_SIDER_BAND_CHANNEL] = *pROC++; g_Eeprom_Data[OFF_UP_SIDER_BAND_CHANNEL+1] = *pROC; //保存数据到EEPROM中 g_SaveData.StartAddress = OFF_UP_SIDER_BAND_CHANNEL; g_SaveData.SaveNum = 2; g_SaveData.SaveFlag = 1; } break; case OID_RW_DN_SIDER_BAND_CHANNEL: if(pRNP->MAP.CommandFlag == Param_Inquiry) { *pWOC++ = g_Eeprom_Data[OFF_DN_SIDER_BAND_CHANNEL]; *pWOC = g_Eeprom_Data[OFF_DN_SIDER_BAND_CHANNEL+1]; } else { g_Eeprom_Data[OFF_DN_SIDER_BAND_CHANNEL] = *pROC++; g_Eeprom_Data[OFF_DN_SIDER_BAND_CHANNEL+1] = *pROC; //保存数据到EEPROM中 g_SaveData.StartAddress = OFF_DN_SIDER_BAND_CHANNEL; g_SaveData.SaveNum = 2; g_SaveData.SaveFlag = 1; } break; case OID_RW_UL_ATTEN: if(pRNP->MAP.CommandFlag == Param_Inquiry) *pWOC = g_Eeprom_Data[OFF_UL_ATTEN]; else { g_Eeprom_Data[OFF_UL_ATTEN] = *pROC; //保存数据到EEPROM中 g_SaveData.StartAddress = OFF_UL_ATTEN; g_SaveData.SaveNum = 1; g_SaveData.SaveFlag = 1; } break; case OID_RW_DL_ATTEN: if(pRNP->MAP.CommandFlag == Param_Inquiry) *pWOC = g_Eeprom_Data[OFF_DL_ATTEN]; else { g_Eeprom_Data[OFF_DL_ATTEN] = *pROC; //保存数据到EEPROM中 g_SaveData.StartAddress = OFF_DL_ATTEN; g_SaveData.SaveNum = 1; g_SaveData.SaveFlag = 1; } break; case OID_RW_DL_STANDWAVE_LIMIT: if(pRNP->MAP.CommandFlag == Param_Inquiry) *pWOC = g_Eeprom_Data[OFF_DL_STANDWAVE_LIMIT]; else { g_Eeprom_Data[OFF_DL_STANDWAVE_LIMIT] = *pROC; //保存数据到EEPROM中 g_SaveData.StartAddress = OFF_DL_STANDWAVE_LIMIT; g_SaveData.SaveNum = 1; g_SaveData.SaveFlag = 1; } break; case OID_RW_OVER_TEMPRATURE_LIMIT: if(pRNP->MAP.CommandFlag == Param_Inquiry) *pWOC = g_Eeprom_Data[OFF_OVER_TEMPRATURE_LIMIT]; else { g_Eeprom_Data[OFF_OVER_TEMPRATURE_LIMIT] = *pROC; //保存数据到EEPROM中 g_SaveData.StartAddress = OFF_OVER_TEMPRATURE_LIMIT; g_SaveData.SaveNum = 1; g_SaveData.SaveFlag = 1; } break; case OID_RW_SINGAL_INFO: if(pRNP->MAP.CommandFlag == Param_Inquiry) { *pWOC++ = g_Eeprom_Data[OFF_SINGAL_INFO]; *pWOC = g_Eeprom_Data[OFF_SINGAL_INFO+1]; } else { g_Eeprom_Data[OFF_SINGAL_INFO] = *pROC++; g_Eeprom_Data[OFF_SINGAL_INFO+1] = *pROC; //保存数据到EEPROM中 g_SaveData.StartAddress = OFF_SINGAL_INFO; g_SaveData.SaveNum = 2; g_SaveData.SaveFlag = 1; } break; case OID_RW_DL_RFIN_DOWN_LIMIT: if(pRNP->MAP.CommandFlag == Param_Inquiry) *pWOC = g_Eeprom_Data[OFF_DL_RFIN_DOWN_LIMIT]; else { g_Eeprom_Data[OFF_DL_RFIN_DOWN_LIMIT] = *pROC; //保存数据到EEPROM中 g_SaveData.StartAddress = OFF_DL_RFIN_DOWN_LIMIT; g_SaveData.SaveNum = 1; g_SaveData.SaveFlag = 1; } break; case OID_RW_DL_RFIN_OVER_LIMIT: if(pRNP->MAP.CommandFlag == Param_Inquiry) *pWOC = g_Eeprom_Data[OFF_DL_RFIN_OVER_LIMIT]; else { g_Eeprom_Data[OFF_DL_RFIN_OVER_LIMIT] = *pROC; //保存数据到EEPROM中 g_SaveData.StartAddress = OFF_DL_RFIN_OVER_LIMIT; g_SaveData.SaveNum = 1; g_SaveData.SaveFlag = 1; } break; case OID_RW_DL_RFOUT_DOWN_LIMIT: if(pRNP->MAP.CommandFlag == Param_Inquiry) *pWOC = g_Eeprom_Data[OFF_DL_RFOUT_DOWN_LIMIT]; else { g_Eeprom_Data[OFF_DL_RFOUT_DOWN_LIMIT] = *pROC; //保存数据到EEPROM中 g_SaveData.StartAddress = OFF_DL_RFOUT_DOWN_LIMIT; g_SaveData.SaveNum = 1; g_SaveData.SaveFlag = 1; } break; case OID_RW_DL_RFOUT_OVER_LIMIT: if(pRNP->MAP.CommandFlag == Param_Inquiry) *pWOC = g_Eeprom_Data[OFF_DL_RFOUT_OVER_LIMIT]; else { g_Eeprom_Data[OFF_DL_RFOUT_OVER_LIMIT] = *pROC; //保存数据到EEPROM中 g_SaveData.StartAddress = OFF_DL_RFOUT_OVER_LIMIT; g_SaveData.SaveNum = 1; g_SaveData.SaveFlag = 1; } break; default: //回复监控标号无法识别 Memcopy(pWOC, pROC, pRObject->OL); pWObject->OID[1] += 0x10; break; } } } else { //回复监控标号无法识别 Memcopy(pWOC, pROC, pRObject->OL); pWObject->OID[1] += 0x10; } //将需要保存的数据写入相应的EEPROM地址中 Eeprom_SaveData(); } pDes->Processed=1; //回应缓冲区等待打包发送 } void Serial_Send_Event(void) { RECE_DATA xdata *pSrc; UINT16 xdata CRC; UART0_SEND xdata *pDes; UINT8 xdata *pS; UINT8 xdata *pD; UINT8 xdata Temp8BitData; //首先看待发送的缓冲区中是否有数据包 if(g_UART0_Rcv_Bak[MODEM_RCV_BAK_MAX-1].Processed == 0x00) return; //先等待猫初始化完成 if(!g_Modem_Init_Ok&&(g_UARTStatus==ON_MODEM)) //等待MODEM初始化OK return; pSrc = &g_UART0_Rcv_Bak[MODEM_RCV_BAK_MAX-1]; pDes = &g_UART0SBuf; //下面按照通信方式分别将MAP层转换到NP层再转入到接入层发送 if(pSrc->DataSource == DataSource_RS232) goto Deal_DataSource_RS232; if(pSrc->DataSource == DataSource_SMS) goto Deal_DataSource_SMS; if(pSrc->DataSource == DataSource_RS485) goto Deal_DataSource_RS485; if(pSrc->DataSource == DataSource_UDP) goto Deal_DataSource_UDP; Deal_DataSource_RS232: //RS232间隔发送数据包的时间为100ms,先等待是否有这么长的间隔时间 if(pDes->Send_Delay) return; //先计算CRC CRC = CRC16_Get(pSrc->ReceData, pSrc->DataNum); //将CRC数据追加到缓冲区尾部 pSrc->ReceData[pSrc->DataNum++] = ((UINT8*)&CRC)[1]; pSrc->ReceData[pSrc->DataNum++] = ((UINT8*)&CRC)[0]; //先将发送缓冲区的数据长度清0 pDes->Send_Num = 0; //放入起始标记 pDes->Send_Buf[0] = 0x7E; pDes->Send_Num = 1; //现在开始做转义处理 //为方便将定义新的指针指向需要处理的数据其始位置 pS = pSrc->ReceData; pD = &pDes->Send_Buf[1]; while(pSrc->DataNum) { switch(*pS) { case 0x5E: *pD++ = 0x5E; *pD++ = 0x5D; pDes->Send_Num += 2; break; case 0x7E: *pD++ = 0x5E; *pD++ = 0x7D; pDes->Send_Num += 2; break; default: *pD++ = *pS; pDes->Send_Num++; break; } pS++; pSrc->DataNum--; } //加入结束标记 *pD = 0x7E; pDes->Send_Num++; //开始将接入层数据发送出去 UART0_SendStrInit(pDes->Send_Buf, pDes->Send_Num, 0); g_UART0SBuf.Send_Delay = RS232_DELAY; //标记缓冲区已经被处理 pSrc->Processed = 0x00; return; Deal_DataSource_SMS: //这里开始发送短信 //先校验电话号码,看是否正确? if(pSrc->PhoneNum == 0) { pSrc->Processed = 0; return; } switch(g_ModemAT_Index) { case 0: //先看有没有在等待接收短信的时间 if(g_Modem_WaitSendSMSTime) break; //先看延迟的时间是否完成 if(pDes->Send_Delay) break; //先发送AT命令头AT+CMGS="电话号码" pDes->Send_Num = 0; Memcopy(pDes->Send_Buf, "AT+CMGS=", 8); pDes->Send_Num = 8; pDes->Send_Buf[pDes->Send_Num++] = '\"'; Memcopy(&pDes->Send_Buf[pDes->Send_Num], pSrc->RecePhone, pSrc->PhoneNum); pDes->Send_Num += pSrc->PhoneNum; pDes->Send_Buf[pDes->Send_Num++] = '\"'; pDes->Send_Buf[pDes->Send_Num++] = '\r'; UART0_SendStrInit(pDes->Send_Buf, pDes->Send_Num, 0); g_ModemAT_Index++; pDes->Send_Delay = 150; //等待1s,等猫反应> break; case 1: //先等待给猫的命令时间延迟完成 if(pDes->Send_Delay) break; //开始整理数据 //先计算CRC CRC = CRC16_Get(pSrc->ReceData, pSrc->DataNum); //将CRC数据追加到缓冲区尾部 pSrc->ReceData[pSrc->DataNum++] = ((UINT8*)&CRC)[1]; pSrc->ReceData[pSrc->DataNum++] = ((UINT8*)&CRC)[0]; //放入起始标记 pDes->Send_Buf[0] = 0x21; pDes->Send_Num = 1; //现在开始做字节拆分处理 //为方便处理数据将定义新的指针指向需要处理的数据其始位置 pS = pSrc->ReceData; pD = &pDes->Send_Buf[1]; while(pSrc->DataNum) { Temp8BitData = *pS >> 4; if((Temp8BitData >= 0) && (Temp8BitData <= 9)) *pD = 0x30 + Temp8BitData; else *pD = 0x37 + Temp8BitData; pD++; Temp8BitData = *pS & 0x0F; if((Temp8BitData >= 0) && (Temp8BitData <= 9)) *pD = 0x30 + Temp8BitData; else *pD = 0x37 + Temp8BitData; pD++; pDes->Send_Num += 2; pS++; pSrc->DataNum--; } //加入结束标记 *pD++ = 0x21; pDes->Send_Num++; //加入结束字符0x1A *pD = 0x1A; pDes->Send_Num++; //开始发送 UART0_SendStrInit(pDes->Send_Buf, pDes->Send_Num, 0); g_ModemAT_Index++; pDes->Send_Delay = 2000; //等待10秒 g_Modem_SendSMS = NG; break; case 2: //等待了MODEM的应答 if(g_Modem_SendSMS == OK) pDes->Send_Delay = 0; if(pDes->Send_Delay) break; g_ModemAT_Index=0; //表示所有数据已发送完成 //标记缓冲区已经被处理 pSrc->Processed = 0x00; break; } return; Deal_DataSource_RS485: //从这里开始发送RS485数据 //注意发送数据协议: "phone"+接入层C协议包数据+CRC校验值 //因为没有RS485,所以就不用处理了 return; Deal_DataSource_UDP: //从这里开始发送IP+UDP的数据,数据无须做任何处理 UART0_SendStrInit(pSrc->ReceData, pSrc->DataNum, 1); pDes->Send_Delay = 10; //标记缓冲区已经被处理 pSrc->Processed = 0x00; } //=================================================================================== //-----------------------------远程通信模块初试化------------------------------------ void Modem_Init ( void ) { if (g_UARTStatus==ON_PC) return ; //近端配置(PC) if ( g_Modem_Init_Ok ) return ; //初试化成功就不在进行处理 if ( g_Modem_S_Delay ) return ; //初试化等待时间 if(!g_Modem_PowerOn) { g_Modem_PowerOn=1; Modem_IGT=1; //关闭触发猫的电源 g_Modem_InitIndex=0; g_Modem_S_Delay = 4 * 15; //延迟30秒后去初始化猫 return; } if ( g_UART0SBuf.Send_Delay) return ; //初试化等待时间 switch ( g_Eeprom_Data[ OFF_COMM_MODE] ) { case MODEM_SMS: if ( *AT_SMS_INIT[g_Modem_InitIndex] ) { //初试化未完成 UART0_SendStrInit ( AT_SMS_INIT[g_Modem_InitIndex] , strlen ( AT_SMS_INIT[g_Modem_InitIndex] ) ,1) ; #if 0 if(g_Modem_InitIndex==8) { pD = &g_Eeprom_Data[OFF_SMS_CENTER_NUM]; while(*pD != 0x20) { UART0_SendStrInit(pD, 1, 1); pD++; } UART0_SendStrInit("\r\n", 2, 1); } #endif g_Modem_InitIndex++; g_UART0SBuf.Send_Delay = 200; //每隔2秒设置一次 } else { g_Modem_Init_Ok = 1 ; g_Modem_InitIndex=0; } break ; case MODEM_CSD: if ( *AT_MODEM_INIT[g_Modem_InitIndex] ) { UART0_SendStrInit ( AT_MODEM_INIT[g_Modem_InitIndex] , strlen ( AT_MODEM_INIT[g_Modem_InitIndex] ) ,1) ; g_Modem_InitIndex++; g_UART0SBuf.Send_Delay = 100 ; //每隔1秒设置一次 } else { g_Modem_Init_Ok = 1 ; g_Modem_InitIndex=0; } break ; default : g_Modem_Init_Ok = 1 ; g_Modem_InitIndex=0; break ; } }