Air protocol应用实战

Posted skdev

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Air protocol应用实战相关的知识,希望对你有一定的参考价值。

前言

https://github.com/Tuotaba/air_protocol

air_protocol提供一套应用于嵌入式设备的通讯协议协议涉及协议完整性的验证,长短数据的灵活调整,以及数据过滤等。适合设备的数据传输、文件传输等。

例1 收发数据

#include "air_protocol.h"
#include "fifo_buffer.h"
#include <stdio.h>
#include <stdlib.h>

#define MAX_BUFFER_LEN	256
static uint8_t pUartData[MAX_BUFFER_LEN];
static buffer_list_t UartBuf;

static uint8_t air_buffer[MAX_BUFFER_LEN];

void send_uart(uint8_t cmd,uint8_t *buf,uint16_t len)

	air_result_t result;
	air_ret_t ret;
	
	ret = air_alloc_pack(cmd,buf,len,&result);
	if(ret == AIR_FAIL)
		return;
	printf("send:\\n");
	air_show_log(result.pdata,result.len);		
	printf("\\n");
	buffer_append(&UartBuf,result.pdata,result.len);
	free(result.pdata);


void uart_data_parser(void)

	air_result_t result;
	air_ret_t ret;
	air_header_t air_header;
	uint8_t *pdata;
	int i,len;
	
	air_header.tag = AIR_TAG;
	i = buffer_find(&UartBuf,(uint8_t *)&air_header.tag,sizeof(air_header.tag));
	if(i >= 0)
	
		if(i>0)
			buffer_pop(&UartBuf,NULL,i);
		if(get_data_length(&UartBuf) > AIR_HEADER_LEN)
		
			pdata = (uint8_t *)&air_header;
			for(i=0;i<AIR_HEADER_LEN;i++)
				pdata[i] = buffer_get(&UartBuf,i);
			len = (AIR_HEADER_LEN+air_header.len+1);
			if(get_data_length(&UartBuf) >= len)
			
				buffer_pop(&UartBuf,air_buffer,len);
				ret = air_data_parser(air_buffer,len,&result);
				if(ret == AIR_SUCCESS)
				
					printf("recv:cmd = %02X,len =%d\\n",result.cmd,result.len);
					air_show_log(result.pdata,result.len);
					printf("\\n");
				
			
		
	


int main()
		
	int i,len;
	
	uint8_t data[] = 0xAA ,0xAA ,0xAA ,0xAA ,0xAA ,0xAA ,0xAA ,0xAA ,0xAA ,0xAA ,0xAA ,0xAA ,0xAA ,0xAA ,0xAA;
		
	buffer_init(&UartBuf,pUartData,MAX_BUFFER_LEN);

	send_uart(0x0A,data,sizeof(data));
	uart_data_parser();
	return 0;

一般数据的收发,数据完整性验证,结果:

send:

8D 7C 6B 5A 0A 00 0F 00 AA AA AA AA AA AA AA AA

AA AA AA AA AA AA AA DD

recv:cmd = 0A,len =15

AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA

例2 运动数据解析

#include "air_protocol.h"
#include "fifo_buffer.h"
#include <stdio.h>
#include <stdlib.h>

#define MAX_BUFFER_LEN	256
static uint8_t pUartData[MAX_BUFFER_LEN];
static buffer_list_t UartBuf;

static uint8_t air_buffer[MAX_BUFFER_LEN];

typedef struct
	
	uint32_t calories;
	uint32_t speed;
	uint32_t distance;
	uint32_t time;
_sport_data_t;

#define CMD_SPORT_DATA	0x10

void send_uart(uint8_t cmd,uint8_t *buf,uint16_t len)

	air_result_t result;
	air_ret_t ret;
	
	ret = air_alloc_pack(cmd,buf,len,&result);
	if(ret == AIR_FAIL)
		return;	
	buffer_append(&UartBuf,result.pdata,result.len);	
	free(result.pdata);


static void command_handler(uint8_t cmd,uint8_t *buf,uint16_t len)

	_sport_data_t *p_sport_data;
	
	switch(cmd)
	
		case CMD_SPORT_DATA:
			p_sport_data = (_sport_data_t *)buf;
			printf("calories : %d\\n",p_sport_data->calories);
			printf("speed : %d\\n",p_sport_data->speed);
			printf("distance : %d\\n",p_sport_data->distance);
			printf("time : %d\\n",p_sport_data->time);
		break;
		default:break;
	


void uart_data_parser(void)

	air_result_t result;
	air_ret_t ret;
	air_header_t air_header;
	uint8_t *pdata;
	int i,len;
	
	air_header.tag = AIR_TAG;
	i = buffer_find(&UartBuf,(uint8_t *)&air_header.tag,sizeof(air_header.tag));
	if(i >= 0)
	
		if(i>0)
			buffer_pop(&UartBuf,NULL,i);
		if(get_data_length(&UartBuf) > AIR_HEADER_LEN)
		
			pdata = (uint8_t *)&air_header;
			for(i=0;i<AIR_HEADER_LEN;i++)
				pdata[i] = buffer_get(&UartBuf,i);
			len = (AIR_HEADER_LEN+air_header.len+1);
			if(get_data_length(&UartBuf) >= len)
			
				buffer_pop(&UartBuf,air_buffer,len);
				ret = air_data_parser(air_buffer,len,&result);
				if(ret == AIR_SUCCESS)
				
					command_handler(result.cmd,result.pdata,result.len);
				
			
		
	


int main()
		
	int i,len;
	
	_sport_data_t data = 322,23,1000,30;	
	
	buffer_init(&UartBuf,pUartData,MAX_BUFFER_LEN);
	
	send_uart(CMD_SPORT_DATA,(uint8_t*)&data,sizeof(_sport_data_t));
	uart_data_parser();
	return 0;

收到对方发来的CMD_SPORT_DATA命令,附带_sport_data_t数据包,进行解析,解析出结果:

calories : 322

speed : 23

distance : 1000

time : 30

例3 文件传输

#include "air_protocol.h"
#include "fifo_buffer.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

#define MAX_BUFFER_LEN	512
static uint8_t pUartData[MAX_BUFFER_LEN];
static buffer_list_t UartBuf;

static uint8_t air_buffer[MAX_BUFFER_LEN];

typedef struct
	
	uint32_t addr;
	uint32_t len;
	uint8_t data[256];
_file_data_t;

#define CMD_FILE_BEGIN	0x10
#define CMD_FILE_DATA	0x11
#define CMD_FILE_END	0x12

void send_uart(uint8_t cmd,uint8_t *buf,uint16_t len)

	air_result_t result;
	air_ret_t ret;
	
	ret = air_alloc_pack(cmd,buf,len,&result);
	if(ret == AIR_FAIL)
		return;	
	buffer_append(&UartBuf,result.pdata,result.len);	
	free(result.pdata);


static void command_handler(uint8_t cmd,uint8_t *buf,uint16_t len)
	
	_file_data_t file_data;
	static uint32_t require_addr = 0;
	
	switch(cmd)
	
		case CMD_FILE_BEGIN:		
			require_addr = 0;
		break;
		case CMD_FILE_DATA:			
			memcpy(&file_data,buf,len);
			printf("%08X :\\n",file_data.addr);
			if(file_data.addr == require_addr)
				air_show_log(file_data.data,file_data.len);
				require_addr += file_data.len;
			
			else
				printf("please resend addr %08X\\n",require_addr);
			
		break;
		case CMD_FILE_END:
			printf("file is done\\n");
			break;
		default:break;
	


void uart_data_parser(void)

	air_result_t result;
	air_ret_t ret;
	air_header_t air_header;
	uint8_t *pdata;
	int i,len;
	
	air_header.tag = AIR_TAG;
	do
		i = buffer_find(&UartBuf,(uint8_t *)&air_header.tag,sizeof(air_header.tag));
		if(i >= 0)
		
			if(i>0)
				buffer_pop(&UartBuf,NULL,i);
			if(get_data_length(&UartBuf) > AIR_HEADER_LEN)
			
				pdata = (uint8_t *)&air_header;
				for(i=0;i<AIR_HEADER_LEN;i++)
					pdata[i] = buffer_get(&UartBuf,i);
				len = (AIR_HEADER_LEN+air_header.len+1);
				if(get_data_length(&UartBuf) >= len)
				
					buffer_pop(&UartBuf,air_buffer,len);
					ret = air_data_parser(air_buffer,len,&result);
					if(ret == AIR_SUCCESS)
					
						command_handler(result.cmd,result.pdata,result.len);
					
					continue;
				
						
		
		break;
	while(1);


int main()
		
	int len;
	FILE *fp = NULL;
	
	_file_data_t file_data;
	
	buffer_init(&UartBuf,pUartData,MAX_BUFFER_LEN);
	
	file_data.addr = 0;
		
	fp = fopen("./test.bin","r");
	if(fp == NULL)
	
		printf("not found test.bin\\n");
		return 0;
		
	send_uart(CMD_FILE_BEGIN,NULL,0);	
	while(1)		
		len = fread(file_data.data,1,256,fp);
		if(len <= 0)
			break;
		file_data.len = len;
		send_uart(CMD_FILE_DATA,(uint8_t*)&file_data,file_data.len+8);
		uart_data_parser();
		file_data.addr += len;
	
	send_uart(CMD_FILE_END,NULL,0);
	uart_data_parser();
	fclose(fp);
	return 0;

将test.bin读出,并进行传输,结果:

00000000 :

61 61 61 61 61 61 61 61 0A

file is done

如果文件足够大,会打印出更多的信息。

因为协议有对每帧数据进行完整性验证,所以不怕数据会出错,也不需要收全文件再进行检验。

以上是关于Air protocol应用实战的主要内容,如果未能解决你的问题,请参考以下文章

Air protocol应用实战

深度学习时间序列预测:LSTM算法构建时间序列单变量模型预测大气压( air pressure)+代码实战

Keras深度学习实战(29)——长短时记忆网络详解与实现

Keras深度学习实战(29)——长短时记忆网络详解与实现

Keras深度学习实战——使用长短时记忆网络构建情感分析模型

Web协议详解与抓包实战:HTTP1协议-如何管理跨代理服务器的长短连接?