本帖最后由 sinanjj 于 2012-6-8 10:24 编辑
void wait_gsm(void* param)
{
if(oa_sim_network_is_valid()) { 这个api是检测gsm网络ready的,可以看到,不ready继续检测,ready了 执行wait_gprs 去。思路从名字都看得出来。
oa_timer_start(OA_APP_SCHEDULER_ID, wait_gprs, NULL, 1000);
} else {
oa_timer_start(OA_APP_SCHEDULER_ID, wait_gsm, NULL, 1000);
}
}
void wait_gprs(void* param)
{
oa_soc_apn_info_struct apn_info_cmnet = {"cmnet","",""};
oa_gprs_set_apn_req(&apn_info_cmnet, apn_handler);
oa_gprs_attach_req(gprs_handler); 这些是手机上网必须设置的。估计用gprs上过网的人都熟吧。(什么?你不知道?打开手机找找设置)
if(gprs_ok) { 这个是从回调函数里设置的值,回调函数是 gprs_handler.
oa_sockaddr_struct soc_addr = { OA_SOCK_DGRAM, 14, "173.255.226.41", 2001 };
socket_id = oa_soc_create(OA_SOCK_DGRAM, 0);
oa_soc_notify_ind_register(udp_data); //register socket network notify event callback function
oa_soc_connect(socket_id, OA_IP_ADDRESS, &soc_addr); 这里创建链接,使用的udp,不是tcp哈,在网络不稳定的情况下尽量使用udp,因为底层可以自己优化(当然你用raw socket写tcp状态机当我没说)
oa_uart_set_read_delay(OA_UART2, 48); //set the time interval between uart data, for received data frame by frame,one frame max length is 300 bytes
oa_memset(ack_seq, '\x01', 256);ack_seq是一个数组,为什么用数组呢?因为数据包的延时ack机制,就是每一个发出的数据包都有一个序列号,这个序列号是1个byte的,作用就是区分ack,相当于tcp里的序列号,每个ack到达与否对应于这个数组中的值。(确实比较难解释。。。)
oa_uart_register_callback(OA_UART2, uart_handler); //register UART1 received data callback function
oa_uart_write (OA_UART2,"\r\nstart\r\n",9); 标识gprs开始
oa_timer_start(OA_APP_SCHEDULER_ID, ack_check, NULL, 10000); 这个daemon是不断的检测ack的情况,一旦检测到5个包没有ack就自动重启模块。
} else {
oa_timer_start(OA_APP_SCHEDULER_ID, wait_gprs, NULL, 1000);
}
}
然后重要的部分就是ack,心跳了,我这里使用了每3s一次的采集参数作为心跳,ack。
服务器程序需要满足ack需求,即:每个ack的值都是包头的第一个值,即是序列号。
void uart_handler (void * param, oa_uint32 len)
{
if (len>=512) return;
pkt_len = len +3;
oa_memset(pkt, '\x00', 515);
oa_memcpy((void *)&pkt[3], param, len);
seq ++;
pkt[0] = seq; pkt[1] = 0x00; pkt[2] = 0x01; // | 1byte seq | 2 byte ID | uart data |
oa_soc_send(socket_id, pkt, pkt_len);
*(ack_seq+seq) = 0;
}
重点在于 pkt[0] = seq; pkt[1] = 0x00; pkt[2] = 0x01; // | 1byte seq | 2 byte ID | uart data |
0001是id号,大家可以不管,seq是序列号,保证ack的。 |