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

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

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值