?? modemgtm900.c
字號:
else
i = 1;
}
pt1 ++;
}
else
break;
}
if (err != OS_TIMEOUT)
{
Ascii2ToHex(&ptrTemp->pktCmd.version,ptrTemp->pBuf,24);
if(ptrTemp->pktCmd.cmdId == 0x61)
{
memcpy(ptrTemp->pBuf,&ptrTemp->pBuf[24],30);
Ascii2ToHex(&ptrTemp->pBuf[30],&ptrTemp->pBuf[54],6);
i = (i - 30) / 2 - 2 + 30; //長度不包括CRC
}
else
{
Ascii2ToHex(ptrTemp->pBuf,&ptrTemp->pBuf[24],i - 24);
i = i / 2 - 2; //長度不包括CRC
}
crc.chr[0] = ptrTemp->pBuf[ptrTemp->pktCmd.dataLen];
crc.chr[1] = ptrTemp->pBuf[ptrTemp->pktCmd.dataLen+1];
j = calculateCRC(&ptrTemp->pktCmd.version,i);
if(crc.wrd[0] == j) //如果CRC正確且協議類型為APA層,則向NP層發送消息
{
ptrTemp->Info.bufLen = i;
ptrTemp->Info.comType = COM_DATA;
ptrTemp->Info.srcPort = PKT_PORT_MODEM;
OSQPost(QueuePcktApNpa, ptrTemp);
#ifdef DEBUG_MODEM
printf("\r\nreceive corret sms %s, line %u\n",__FILE__, __LINE__ );
#endif
return;
}
}
FreePcktBuf(ptrTemp);
}
/*******************************************************************************
* 連接GPRS
*
* Description: 連接成功獲得本地IP地址
*
*
*
* Arguments : pCntIpAddr: 指向服務器IP地址的指針
* CntIpPort: 服務器的IP端口
* Returns : 成功:1;失敗:0
*******************************************************************************/
INT8U OpenGprs(INT8U* pCntIpAddr, INT16U CntIpPort)
{
INT8U i,err;
char strtemp[40];
sprintf(strtemp, "%s\"%d.%d.%d.%d\",%d\r",ST_AT_IPOPEN,*pCntIpAddr,*(pCntIpAddr+1),
*(pCntIpAddr+2),*(pCntIpAddr+3),CntIpPort); //按格式輸出到字符串
modemState = MODEM_INVALID;
for(i=0;i<5;i++)
{
EXTUARTWriteA((INT8U *)ST_AT_CGDCONT,strlen((const char *)ST_AT_CGDCONT)); //定義PDP 上下文
printf("send AT command: %s \n", ST_AT_CGDCONT);
OSSemPend(ResetSem, OS_TICKS_PER_SEC * 20, &err);
if(err == OS_TIMEOUT)
{
continue;
}
EXTUARTWriteA((INT8U *)ST_AT_ETCPIP,strlen((const char *)ST_AT_ETCPIP)); //進入tcpip功能
printf("send AT command: %s \n", ST_AT_ETCPIP);
OSSemPend(ResetSem, OS_TICKS_PER_SEC * 20, &err);
if(err == OS_TIMEOUT)
{
continue;
}
err = strlen((const char *)strtemp);
EXTUARTWriteA((INT8U *)strtemp,strlen((const char *)strtemp)); //連接服務器
printf("send AT command: %s \n",strtemp);
OSSemPend(ResetSem, OS_TICKS_PER_SEC * 20, &err);
if(err == OS_TIMEOUT)
{
continue;
}
break;
}
if(i<5) //GPRS連接成功,modem同時在GPRS和SMS模式下
{
modemState = MODEM_GPRS|MODEM_SMS;
return 1;
}
else //不成功,modem狀態恢復到SMS模式
{
#ifdef DEBUG_MODEM
printf("\r\n GPRS not connected: %s, line %u\n",__FILE__, __LINE__ );
#endif
modemState = MODEM_SMS;
return 0;
}
}
/*******************************************************************************
* Description: gprs數據接收
*
* Arguments : none
*
* Returns : none
*
* Note : 只負責接收數據,把數據交給app程序去解析執行。這里只是個驅動。
*******************************************************************************/
void GprsRcvPro(void)
{
INT8U ch,i;
int len;
char ATCmd[10];
char datalen[5];
char *ptr;
X_PACKET *ptrTemp = NULL;
char dataBuf[GPRSBUF_LEN];
memset(datalen,0x00,5);
memset(dataBuf,NULL,GPRSBUF_LEN);
for(i = 0; i < GPRSBUF_LEN - 1; i ++)
{
ch = EXTUARTGetchTmA(OS_TICKS_PER_SEC/10,(INT8U *)&dataBuf[i]);
if(ch == OS_TIMEOUT)
{
break;
}
if(dataBuf[i] == 0x0D)
{
break;
}
}
//查找冒號: %和:之間的字符是命令類型
ptr = strchr(dataBuf,':');
memset(ATCmd,NULL,10);
len = ptr - dataBuf;
if(len<=10 && len >0)
strncpy(ATCmd,dataBuf,len);
else
{
#ifdef DEBUG_MODEM
printf("no : found %s, line %u\n",__FILE__, __LINE__ );
#endif
return;
}
if(strstr(ATCmd, "IPDATA")) //接收到GPRS的TCPIP數據
{
ptrTemp = GetPcktBuf(); //申請內存
while(ptrTemp == NULL)
{
OSTimeDly(OS_TICKS_PER_SEC/200);//延時5ms
ptrTemp = GetPcktBuf();
#ifdef DEBUG_MODEM
printf("\r\n when receive gprs,no packet %s, line %u\n",__FILE__, __LINE__ );
#endif
}
ptr++; //指向數據長度
for(i=0; i<4; i++) //數據長度最多4位數
{
datalen[i] = *ptr;
ptr++;
if((*ptr < 0x30) || (*ptr > 0x39)) //非數字退出
break;
}
len = atoi(datalen); //取數據長度
ptr = strchr(dataBuf,'"'); //找第一個引號
printf("received gprs data: %s\n",dataBuf);
if(ptr != NULL) //把接收到的數據發送給app程序
{
ptr++; //指向數據段
Ascii2ToHex(ptrTemp->pBuf,(INT8U*)ptr,len*2);
ptrTemp->Info.comType = COM_GPRS;
ptrTemp->Info.srcPort = PKT_PORT_MODEM;
OSQPost(QueuePcktRawDataIn, ptrTemp);
}
else
{
FreePcktBuf(ptrTemp);
#ifdef DEBUG_MODEM
printf("no content in received gprs data %s, line %u\n",__FILE__, __LINE__ );
#endif
}
}
else if(strstr(ATCmd, "IPSEND")) //IP發送成功
printf("gprs send OK");
else if(strstr(ATCmd, "IPCLOSE")) //TCPIP鏈路關閉
{
printf("gprs tcpip closed");
}
else
{
#ifdef DEBUG_MODEM
printf("illegal command received:%s, line %u\n",__FILE__, __LINE__ );
#endif
}
}
/*******************************************************************************
* Description: GPRS數據發送函數
*
* Arguments : ptr, 指向發送數據首地址;
* : len,需發送數據的長度
* Returns : 1,發送成功
* 2,發送失敗
* Note : 發送一包的數據長度不能超過512字節
*******************************************************************************/
INT8U WriteGprs( INT8U *ptr, INT16U len)
{
INT8U reSentCnt=3; //最多重發3次
INT8U err;
INT8U sendBuf[512];
while(reSentCnt > 0)
{
hexTo2Ascii(sendBuf,ptr,len);
OSSemPend(EXTUARTSemShareA,0,&err);
EXTUARTWriteA((INT8U *)ST_AT_IPSEND,strlen((const char *)ST_AT_IPSEND));
EXTUARTPutchA('"');
EXTUARTWriteA(sendBuf,len*2);
EXTUARTPutchA('"');
EXTUARTPutchA('\r');
OSSemPost(EXTUARTSemShareA);
//等待執行的結果
if(err != OS_TIMEOUT)
{
return 1; //成功,跳出
}
else
{
reSentCnt--;
}
}
return 2;
}
/*******************************************************************************
* Description: gprs或sms接收
*
* Arguments : none
*
* Returns : none
*
* Note : modem可以同時工作在sms和gprs狀態下。調用該函數時,表明modem已經
工作在sms或gprs模式下,因此接收到%符號時可以認為是接收到gprs數據
*******************************************************************************/
void SmsGprsRcv(void)
{
INT8U ch,err;
err = EXTUARTGetchTmA(OS_TICKS_PER_SEC/2,&ch);
if(err == OS_TIMEOUT)
return;
else if(ch == '>') //發送短信成功的回應
{
OSSemPost(SMSSnd1);
return;
}
else if(ch == '%') //接收到gprs數據
GprsRcvPro();
else if((ch == '+') || ( ch == 'Q')) //接收到sms數據
ATCmdRcvPro(ch);
else //可能是ERROR,需處理
return;
}
/*******************************************************************************
** 函數名稱: TaskEXTUARTARcv
** 功能描述: 擴展串口A接收任務,用于和modem的通訊
** 輸 入: *pdata
** 輸 出: 無
** MSR_Uart_A的第7位是modem的DCD腳狀態 1表示數據鏈路已連接 0表示短信方式
** 全局變量:
** 調用模塊:
*******************************************************************************/
static void TaskEXTUARTARcv(void *pdata)
{
INT8U ch,err;
INT32U i;
char ack[] = "OK";
char connect[] = "CONNECT";
PS_X_PACKET ptrTemp = NULL;
pdata = pdata;
for(;;)
{
i = (MSR_Uart_A & 0x80);
if(((MSR_Uart_A & 0x80) != 0x00) && (modemState & MODEM_SMS) && ((modemState & MODEM_GPRS) != MODEM_GPRS))
{
modemState = MODEM_DATA;
#ifdef DEBUG_MODEM
printf("\r\nModem sms to data %s, line %u\n",__FILE__, __LINE__ );
#endif
}
else if(((MSR_Uart_A & 0x80) == 0x00))
{
if(modemState & MODEM_DATA)
{
DataFlag = 0;
modemState = MODEM_SMS | MODEM_GPRS;
#ifdef DEBUG_MODEM
printf("\r\nModem data to sms %s, line %u\n",__FILE__, __LINE__ );
#endif
}
}
if(modemState & (MODEM_GPRS | MODEM_SMS)) //SMS或GPRS狀態下
{
SmsGprsRcv();
if(DataFlag != 0) //避免由于在數傳沒有接通前,掛斷來電,造成不能查詢信源信息
{
if(ConnectTimeOut < OSTimeGet())
{
DataFlag = 0;
}
}
}
else if(modemState == MODEM_DATA)
{
ModemDataRcvPRO();
}
else
{
err = EXTUARTGetchTmA(OS_TICKS_PER_SEC*5 ,&ch);
if(err == OS_TIMEOUT)
continue;
ptrTemp = GetPcktBuf();
while(ptrTemp == NULL)
{
OSTimeDly(OS_TICKS_PER_SEC/200);//延時5ms
ptrTemp = GetPcktBuf();
}
memset(ptrTemp->pBuf,0x00,MAX_BUFLEN);
ptrTemp->pBuf[0] = ch;
for(i = 1; i < MAX_BUFLEN - 1; i ++)
{
ch = EXTUARTGetchTmA(OS_TICKS_PER_SEC / 2,&ptrTemp->pBuf[i]);
if(ch != OS_TIMEOUT)
{
if(ptrTemp->pBuf[i] == 0x0D)
{
ptrTemp->Info.bufLen = i + 1;
break;
}
}
else
{
break;
}
}
#ifdef DEBUG_MODEM
printf("received AT ack: %s \n",ptrTemp->pBuf);
#endif
if((ch != OS_TIMEOUT) && (strstr((char*)ptrTemp->pBuf,connect)))
{
OSSemPost(ResetSem);
printf("tcp ip OK: %s, line %u\n",__FILE__, __LINE__ );
}
else if((ch != OS_TIMEOUT) && (strstr((char*)ptrTemp->pBuf,ack) ||(ptrTemp->pBuf[i - 1] == 0x30))) //收到的最后一個字符是0
{
OSSemPost(ResetSem);
}
FreePcktBuf(ptrTemp);
OSTimeDly(OS_TICKS_PER_SEC/200);
}
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -