GPRS/3G

1、状态机机制的gprs拨号

像GPRS/3G模块之类的应用,需要连接,登陆,初始化等步骤完成后才能传输数据,而这些步骤又比较耗时。

所以用 状态机 + 超时 的机制来实现比较合理。

如下代码片段来描述数据透传 : 状态机 + 超时 这种机制(代码片段,仅用来描述一种思路)

以下程序是在没有操作系统调度机制下调试的,所以超时用的心跳,如果是linux下,有sleep更方便。

#include <stdio.h>
#include <string.h>
#include <stdlib.h> #define SERVER_IP "115.29.140.xxx"
#define SERVER_PORT "8082" #define BUFF_LEN 64
char aUart5RxBuffer[BUFF_LEN]; static int gprs_init_ok= ;
static int ppp_config_ok = ; void gprs_init(void)
{
if((strstr(aUart5RxBuffer, "command ready") == NULL)
/*||(strstr(aUart5RxBuffer, "+SIM READY") == NULL)*/)
{
gprs_init_ok = ;
}
else
{
gprs_init_ok = ;
} } void reset_gprs(void)
{
memset(aUart5RxBuffer, , BUFF_LEN);
gprs_init_ok= ;
ppp_config_ok = ;
//reset 3g module;
} void ppp_config(void)
{
static uint32_t ppp_config_step = ;
static uint32_t gprs_tick = ; switch (ppp_config_step)
{
case :
gprs_puts("AT+GTSET=\"LPMMODE\",0\r\n");
gprs_tick = msTicks;
ppp_config_step = ;
break;
case :
if((msTicks - gprs_tick) > )
{
if(strstr(aUart5RxBuffer, "OK") == NULL)
{
ppp_config_step = ;
}
else
{
ppp_config_step = ; }
memset(aUart5RxBuffer, , BUFF_LEN);
}
break; case :
gprs_puts("AT+CPIN?\r\n");
ppp_config_step = ;
gprs_tick = msTicks;
break;
case :
if((msTicks - gprs_tick) > )
{
if((strstr(aUart5RxBuffer, "OK") == NULL) || (strstr(aUart5RxBuffer, "+CPIN: READY") == NULL))
{
ppp_config_step = ;
}
else
{
ppp_config_step = ; }
memset(aUart5RxBuffer, , BUFF_LEN);
}
break; case :
gprs_puts("AT+CSQ\r\n");
ppp_config_step = ;
gprs_tick = msTicks;
break;
case :
if((msTicks - gprs_tick) > )
{
if(strstr(aUart5RxBuffer, "OK") == NULL)
{
ppp_config_step = ;
}
else
{
ppp_config_step = ;
}
memset(aUart5RxBuffer, , BUFF_LEN);
}
break; case :
gprs_puts("AT+CREG?\r\n");
ppp_config_step = ;
gprs_tick = msTicks;
break;
case :
if((msTicks - gprs_tick) > )
{
if(strstr(aUart5RxBuffer, "+CREG: 0,0") == NULL)
{
ppp_config_step = ;
}
else
{
ppp_config_step = ;
}
memset(aUart5RxBuffer, , BUFF_LEN);
}
break; case :
//gprs_puts("AT+MIPCALL=1,\"3GNET\"\r\n");
gprs_puts("AT+MIPCALL=1,\"xagfzqx.ydoa.snapn\"\r\n");
ppp_config_step = ;
gprs_tick = msTicks;
break;
case :
if((msTicks - gprs_tick) > )
{
if(strstr(aUart5RxBuffer, "+MIPCALL: 0") == NULL)
{
ppp_config_step = ;
ppp_config_ok = ;
}
else
{
ppp_config_step = ;
}
memset(aUart5RxBuffer, , BUFF_LEN);
}
break; default:
break;
} } void http_Send_test(char *data)
{
static unsigned char http_send_step = ;
static int send_err_cnt = ; switch (http_send_step)
{
case :
memset(data_tx_buf, , sizeof(data_tx_buf));
strcat(data_tx_buf, data);
gprs_puts("GET /app/pulse-wave/commit?");
gprs_puts("%s",data_tx_buf);
gprs_puts("\r\n"); http_send_step = ;
gprs_tick = msTicks; break; case : if((strstr(aUart5RxBuffer, "{\"msg\":\"commit pulse-wave data success.\",\"result\":true}") != NULL)
&&(strstr(aUart5RxBuffer, "+MIPSTAT: 1,1") != NULL)
&&((msTicks - gprs_tick) < ))
{ }
else
{
if(++send_err_cnt > ) {
reset_gprs();
send_err_cnt = ;
} }
     
     memset(aUart5RxBuffer, 0, BUFF_LEN);   
        http_send_step = ;              

        break;                                              

    default:
break; }
} void main(void)
{
while()
{
if(!gprs_init_ok) { gprs_init(); } if((gprs_init_ok)&&(!ppp_config_ok)) { ppp_config(); } if(ppp_config_ok) { http_Send_test("hello,world"); }
}
}

初始化成功了就可以传输数据了,数据发送和接收都跟串口一样。主要工作都在初始化 ,和异常修复机制的实现。因为网络传输每一步都可能会失败,而且外部因素太多,所以异常修复机制尤其重要。

2、用开源的ppp/pppoe指令拨号也一样

end

上一篇:asp.net DropDownList无刷新ajax二级联动实现详细过程


下一篇:asp.net DropDownList的AppendDataBoundItems属性