⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 modemgtm900.c

📁 华为GSM modem GTM900B的驱动代码
💻 C
📖 第 1 页 / 共 3 页
字号:
                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 + -