第一次总结:整体框架
tcp部份:
1、初始化WiFi连接路由器
wifi.begin();
bool b = wifi.Initialize(STA, SSID, PASSWORD);连接局域网
if(!b)
{
DebugSerial.println("Init error");
}
delay(8000); //make sure the module can have enough time to get an IP address
String ipstring = wifi.showIP();
DebugSerial.println(ipstring); //show the ip address of module
delay(5000);
wifi.confMux(1);
delay(100);
if(wifi.confServer(1,8080))
DebugSerial.println("Server is set up");
2、终端登录
if(AT+ CIPSTATUS?)
{
pro_avtice_TeConnect(); //终端登录函数
}
if(gprs_upl_mnginfo_ptr()->flags.upl_timesynch == FALSE) //时间同步
{
gprs_pro_ack_TimeSynch();
3、tcp连接并向服务器发送数据
void pro_avtice_TeConnect(void){
gprs_pro_cmd_t local_com; //结构体
memset((u8*)&local_com,0,sizeof(gprs_pro_cmd_t));
local_com.pro_data = malloc(128);
local_com.command_id = 0x0002;//终端登录
local_com.seq_num = 0x0001; //暂定
local_com.dev_id = 0x30313233343536;//{0x30,0x31,0x32,0x33,0x34,0x35,0x36};
local_com.pro_data = 0x324235....;
local_com.len = 74;
protocol_datapack(&local_com);
}
4.接受数据:
rece_data函数接受的数据类型为int型需用String tempstr函数转化为string型,最后由pro_protocol_analysis函数根据通信协议分析数据内容
void rec_data(){接受数据
int rece_data = wifi.ReceiveMessage(buf);
String tempstr = String(rece_data);
if (strcmp(rece_data, "@@") == 0)对比字符串是否一样
{
data = pro_protocol_analysis((u8*)&rece_data,tempstr.length)
}
}
函数总结:
1.打包程序:将GPRS数据根据通信协议进行打包发送到服务器端,event.size函数内的 17 为通信协议中GPRS数据包排除校验的数据长度。
其中:
消息头:固定两个字符“@@”, HEX 表示为 40h 40h;
消息长度:Word 数据类型,从消息流水号到校验字段前所有字节的总和;
消息流水号:Word 数据类型,标识本数据包的流水号;
设备 ID:7 字节 ID,第 1 个字节为 ASCII,表示传感器类型,第 2-7 字节为 BCD 码,高字节在前,低字节在后,如:
传感器设备 ID: M121501010001,即 0x4D,0x12,0x15,0x01,0x01,0x00,0x01;
功能 ID:Word 数据类型,标识本数据包的功能;
void protocol_datapack(gprs_pro_cmd_t *com){
/
mab_event_t event;
u8 *com_para;
u16 crc16;
//event:
event.size = (17 +com->len); 17为排除校验
event.buff = malloc(event.size);
if(NULL == event.buff)
{
printf("Pro package can't malloc!\r\n");
return;
}
com_para = event.buff; //
//head: 消息头
com_para[0] = 0x40;
com_para[1] = 0x40;
com_para += 2;
//len:消息长度
crc16 = com->len +GPRS_PRO_SEQ_LEN +GPRS_PRO_DEV_ID_LEN +GPRS_PRO_CMD_LEN;
memcpy(com_para, (u8*)&crc16, 2);
buff_overturn(com_para,2); //待定处理
com_para += 2;
//seq: 消息流水号
memcpy(com_para, (u8*)&com->seq_num, 2);
com_para += 2;
//id:
memcpy(com_para, com->dev_id, GPRS_PRO_DEVICE_ID);
com_para += GPRS_PRO_DEVICE_ID;
//cmd: 功能id
memcpy(com_para, (u8*)&com->command_id, 2);
buff_overturn(com_para,2);
com_para += 2;
//Data info: 数据段
if(com->len)
{
memcpy(com_para, com->pro_data, com->len);
com_para += com->len;
}
//verify: 校验
crc16 = verify_crc16(event.buff, event.size -GPRS_PRO_VRFY_LEN); //校验函数待定
memcpy(com_para, (u8*)&crc16, 2);
buff_overturn(com_para,2);
//send:
wifi.Send(event.buff,event.size); //待定处理
free(event.buff,event.size);
}
**2.解析函数:**帮助arduino理解服务器端发送的数据
void pro_protocol_analysis(u8 *data_buff, u16 data_len){
gprs_pro_cmd_t pro_com;
u8 *com_para;
u16 crc16,calc_crc;
u8 device_id[GPRS_PRO_DEVICE_ID+1];
com_para = data_buff;
while(data_len >= GPRS_PRO_BASE_LEN)
{
//head info:
if((com_para[0] != 0x40) ||(com_para[1] != 0x40))
{
data_len --;
com_para ++;
continue;
}
//len:0x404000144883
pro_com.len = (u16)(com_para[2] <<8) +com_para[3];
if((pro_com.len < 12)||((pro_com.len+GPRS_PRO_LENGTH_LEN+GPRS_PRO_VRFY_LEN) > data_len))
{
printf("Pro anly len err!len=%d,data_len=%d\r\n",pro_com.len,data_len);
data_len --;
com_para ++;
continue;
}
//verify:
crc16 = (u16)(com_para[pro_com.len+4] << 8) + com_para[pro_com.len+5]; //CRC
calc_crc = verify_crc16(com_para,4+pro_com.len);
if(crc16 != calc_crc)
{
printf("Pro anly verify err!calc_crc=%04x\r\n",calc_crc);
data_len --;
com_para ++;
continue;
}
data_len -= 4;
com_para += 4;
//seq:
memcpy((u8*)&pro_com.seq_num, com_para, 2);
data_len -= 2;
com_para += 2;
//id:
memcpy(pro_com.dev_id, com_para, GPRS_PRO_DEVICE_ID);
data_len -= GPRS_PRO_DEVICE_ID;
com_para += GPRS_PRO_DEVICE_ID;
//cmd id:
pro_com.command_id = (u16)((com_para[0] << 8) + com_para[1]);
data_len -= 2;
com_para += 2;
//data:
pro_com.len -= (GPRS_PRO_SEQ_LEN+GPRS_PRO_DEV_ID_LEN+GPRS_PRO_CMD_LEN);
pro_com.pro_data = com_para;
data_len -= pro_com.len;
com_para += pro_com.len;
//handler:
gprs_pro_menue_handler(&pro_com);
}
}
**3.终端登陆函数:**其中心跳函数防止于服务器端连接中断
void pro_avtice_TeConnect(void){
gprs_pro_cmd_t local_com; //结构体
memset((u8*)&local_com,0,sizeof(gprs_pro_cmd_t));
local_com.pro_data = malloc(128);
local_com.command_id = 0x0002;//终端登录
local_com.seq_num = 0x0001; //暂定
local_com.dev_id = 0x30313233343536;//{0x30,0x31,0x32,0x33,0x34,0x35,0x36};
local_com.pro_data = 0x324235....;
local_com.len = 74;
protocol_datapack(&local_com);
}
void gprs_pro_active_PingReq(void) //心跳
{
gprs_pro_cmd_t local_com;
memset((u8*)&local_com,0,sizeof(gprs_pro_cmd_t));
local_com.command_id = 0x0003;
local_com.seq_num = 0x0001;
local_com.dev_id = 0x30313233343536;
gprs_pro_datapack(&local_com);
}
void gprs_pro_active_TimeSynch(void) // 时间同步
{
gprs_pro_cmd_t local_com;
memset((u8*)&local_com,0,sizeof(gprs_pro_cmd_t));
local_com.command_id = 0x0004;
local_com.seq_num = 0x0001;
local_com.dev_id = 0x30313233343536;
gprs_pro_datapack_package(&local_com);
//sys_mng_info_ptr()->clksych_SEQ = local_com.seq_num;
}