408 lines
5.9 KiB
C
408 lines
5.9 KiB
C
#include "usart2.h"
|
||
#include "at_host.h"
|
||
#include "string.h"
|
||
#include "rtthread.h"
|
||
#include "stdlib.h"
|
||
|
||
typedef struct{
|
||
void *data;
|
||
int size;
|
||
int type;// 0:set;1,get
|
||
int cmd;
|
||
}send_pkt_def;
|
||
|
||
|
||
static uint8_t g_send_buff[CMD_AT_MAXLEN]={0};
|
||
static rt_event_t g_recv_event;
|
||
static send_pkt_def g_pkt;
|
||
|
||
static int at_puts_data(uint8_t *data,int len)
|
||
{
|
||
for (int i=0;i<len;i++)
|
||
{
|
||
usart2_put_byte(data[i]);
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
|
||
static int at_get_byte(uint8_t *data)
|
||
{
|
||
return usart2_get_byte(data);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
//计算命令帧长度
|
||
static int cmdlen(uint8_t *cmd)
|
||
{
|
||
int len=0;
|
||
while(*cmd!=0xfc)
|
||
{
|
||
len++;
|
||
if (CMD_AT_MAXLEN<len)
|
||
return -1;
|
||
cmd++;
|
||
}
|
||
return len;
|
||
}
|
||
|
||
//去转义,输出转义之后的数据长度
|
||
static int unescaped(uint8_t *dat,int len)
|
||
{
|
||
uint8_t *src=dat;
|
||
uint8_t *dsc=dat;
|
||
while(len>0)
|
||
{
|
||
if (*src<0xf0)
|
||
{
|
||
*dsc=*src;
|
||
dsc++;
|
||
src++;
|
||
len--;
|
||
}
|
||
else
|
||
{
|
||
*dsc=src[0]+src[1];
|
||
dsc++;
|
||
src+=2;
|
||
len-=2;
|
||
}
|
||
}
|
||
return dsc-dat;
|
||
}
|
||
|
||
//转义,输出转义后的数据长度
|
||
static int escaped(uint8_t *src,uint8_t *dsc,int src_len)
|
||
{
|
||
uint8_t *dsc_t=dsc;
|
||
while(src_len--)
|
||
{
|
||
if (*src<0xf0)
|
||
{
|
||
*dsc=*src;
|
||
dsc++;
|
||
src++;
|
||
}
|
||
else
|
||
{
|
||
*dsc=0xf0;
|
||
dsc++;
|
||
*dsc=*src-0xf0;
|
||
dsc++;
|
||
src++;
|
||
}
|
||
}
|
||
return dsc-dsc_t;
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/**
|
||
* 找到指定字符的索引
|
||
*
|
||
*/
|
||
static int find_char_index (uint8_t *str,char ch,int len)
|
||
{
|
||
// int len=strlen(str);
|
||
for (int i=0;i<len;i++)
|
||
{
|
||
if (str[i]==ch)
|
||
return i;
|
||
}
|
||
return -1;
|
||
}
|
||
|
||
|
||
static void cb_recv_data(uint8_t d)
|
||
{
|
||
if((d==CMDAT_CMD_END)&&(g_recv_event!=0))
|
||
{
|
||
rt_event_send(g_recv_event,CMDAT_EVENT_RECV);
|
||
}
|
||
}
|
||
|
||
|
||
|
||
//初始化
|
||
int at_init(void)
|
||
{
|
||
if(g_recv_event==0)
|
||
{
|
||
g_recv_event=rt_event_create("at_event", RT_IPC_FLAG_FIFO);
|
||
usart2_init();
|
||
usart2_set_cbcall(cb_recv_data);
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
//去初始化
|
||
int at_deinit(void)
|
||
{
|
||
if(g_recv_event)
|
||
{
|
||
usart2_deinit();
|
||
usart2_set_cbcall(0);
|
||
rt_event_delete(g_recv_event);
|
||
g_recv_event=0;
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
|
||
//清除缓冲区
|
||
int at_clear_buff(void)
|
||
{
|
||
usart2_clear();
|
||
return 0;
|
||
}
|
||
|
||
|
||
|
||
//设置
|
||
static int at_send_set(uint8_t cmd,void *par, int size)
|
||
{
|
||
int len=0;
|
||
g_send_buff[0]=CMDAT_CMD_START;
|
||
len=escaped(&cmd,&g_send_buff[1],1);
|
||
g_send_buff[len+1]=CMDAT_CMD_SET;
|
||
if ((par==0)||size==0)
|
||
{
|
||
g_send_buff[len+2]=CMDAT_CMD_END;
|
||
at_puts_data(g_send_buff,len+2+1);
|
||
}
|
||
else
|
||
{
|
||
int par_len=0;
|
||
par_len=escaped(par,&g_send_buff[len+2],size);
|
||
g_send_buff[len+2+par_len]=CMDAT_CMD_END;
|
||
at_puts_data(g_send_buff,len+2+par_len+1);
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
|
||
//查询
|
||
static int at_send_get(uint8_t cmd,void *par, int size)
|
||
{
|
||
int len=0;
|
||
g_send_buff[0]=CMDAT_CMD_START;
|
||
len=escaped(&cmd,&g_send_buff[1],1);
|
||
g_send_buff[len+1]=CMDAT_CMD_GET;
|
||
if ((par==0)||size==0)
|
||
{
|
||
g_send_buff[len+2]=CMDAT_CMD_END;
|
||
at_puts_data(g_send_buff,len+2+1);
|
||
}
|
||
else
|
||
{
|
||
int par_len=0;
|
||
par_len=escaped(par,&g_send_buff[len+2],size);
|
||
g_send_buff[len+2+par_len]=CMDAT_CMD_END;
|
||
at_puts_data(g_send_buff,len+2+par_len+1);
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
//获取一个数据帧
|
||
int at_get_return_line(uint8_t *buff)
|
||
{
|
||
uint8_t t=0;
|
||
int len=0;
|
||
int act=0;
|
||
while(at_get_byte(&t)==0)
|
||
{
|
||
if(t==CMDAT_CMD_START) act=1;
|
||
if(act)
|
||
{
|
||
buff[len]=t;
|
||
len++;
|
||
}
|
||
if (t==CMDAT_CMD_END)
|
||
{
|
||
break;
|
||
}
|
||
}
|
||
if(t==CMDAT_CMD_END)
|
||
{
|
||
return len;
|
||
}
|
||
else
|
||
{
|
||
return -1;
|
||
}
|
||
}
|
||
|
||
|
||
//解析数据帧
|
||
int at_decode_line(uint8_t *buff,int buff_len,uint8_t **obj,int *obj_size,uint8_t *op,uint8_t **par,int *par_size)
|
||
{
|
||
if(buff[0]!=CMDAT_CMD_START)
|
||
return -1;
|
||
if(buff[buff_len-1]!=CMDAT_CMD_END)
|
||
return -1;
|
||
|
||
int in=-1;
|
||
in=find_char_index(buff+1,CMDAT_CMD_RET,buff_len-1);
|
||
if(in!=-1)
|
||
{
|
||
if(op) *op=CMDAT_CMD_RET;
|
||
if(obj_size) *obj_size=unescaped(buff+1,in);
|
||
if(obj) *obj=buff+1;
|
||
if(par_size) *par_size=unescaped(buff+1+in+1,buff_len-3-in);
|
||
if(par) *par=buff+1+in+1;
|
||
return 0;
|
||
}
|
||
in=find_char_index(buff+1,CMDAT_CMD_ACT,buff_len-1);
|
||
if(in!=-1)
|
||
{
|
||
if(op) *op=CMDAT_CMD_ACT;
|
||
if(obj_size) *obj_size=unescaped(buff+1,in);
|
||
if(obj) *obj=buff+1;
|
||
if(par_size) *par_size=unescaped(buff+1+in+1,buff_len-3-in);
|
||
if(par) *par=buff+1+in+1;
|
||
return 0;
|
||
}
|
||
return -1;
|
||
}
|
||
|
||
|
||
|
||
//字符转化为16进制
|
||
static uint8_t at_char_to_hex(char par)
|
||
{
|
||
uint8_t ret=0xff;
|
||
if (par>='0'&&par<='9')
|
||
{
|
||
ret=par-'0';
|
||
}
|
||
if (par>='A'&&par<='F')
|
||
{
|
||
ret=par-'A'+10;
|
||
}
|
||
if (par>='a'&&par<='f')
|
||
{
|
||
ret=par-'a'+10;
|
||
}
|
||
return ret;
|
||
}
|
||
|
||
|
||
//把字符串转化为hex,低字节在前
|
||
int at_string_to_hex(char *str,void *hex)
|
||
{
|
||
char *str_s=str;
|
||
uint8_t *data=hex;
|
||
int index=0;
|
||
uint8_t tmp=0;
|
||
while (*str_s)
|
||
{
|
||
tmp=at_char_to_hex(*str_s);
|
||
if(tmp!=0xff)
|
||
{
|
||
data[index>>1]|=tmp<<((index&1)?0:4);
|
||
index++;
|
||
}
|
||
str_s++;
|
||
}
|
||
return index;
|
||
}
|
||
|
||
|
||
// 发送设置命令事件
|
||
int at_send_set_event(uint8_t cmd,void *par, int size)
|
||
{
|
||
if(g_recv_event)
|
||
{
|
||
if(g_pkt.data) free(g_pkt.data);
|
||
g_pkt.data=malloc(size);
|
||
memcpy(g_pkt.data,par,size);
|
||
g_pkt.size=size;
|
||
g_pkt.type=0;
|
||
g_pkt.cmd=cmd;
|
||
rt_event_send(g_recv_event,CMDAT_EVENT_USER);
|
||
return 0;
|
||
}
|
||
else
|
||
{
|
||
return -1;
|
||
}
|
||
}
|
||
|
||
// 发送获取命令事件
|
||
int at_send_get_event(uint8_t cmd,void *par, int size)
|
||
{
|
||
if(g_recv_event)
|
||
{
|
||
if(g_pkt.data) free(g_pkt.data);
|
||
g_pkt.data=malloc(size);
|
||
memcpy(g_pkt.data,par,size);
|
||
g_pkt.size=size;
|
||
g_pkt.type=1;
|
||
g_pkt.cmd=cmd;
|
||
rt_event_send(g_recv_event,CMDAT_EVENT_USER);
|
||
return 0;
|
||
}
|
||
else
|
||
{
|
||
return -1;
|
||
}
|
||
}
|
||
|
||
// 发送数据包
|
||
int at_send_packet(void)
|
||
{
|
||
if(g_pkt.data||g_pkt.cmd)
|
||
{
|
||
if(g_pkt.type==0)
|
||
{
|
||
return at_send_set(g_pkt.cmd,g_pkt.data,g_pkt.size);
|
||
}
|
||
else if(g_pkt.type==1)
|
||
{
|
||
return at_send_get(g_pkt.cmd,g_pkt.data,g_pkt.size);
|
||
}
|
||
}
|
||
return -1;
|
||
}
|
||
|
||
|
||
// 获取事件
|
||
int at_get_event(void)
|
||
{
|
||
rt_uint32_t ev;
|
||
if(g_recv_event)
|
||
{
|
||
if(rt_event_recv(g_recv_event,0xffffffff,RT_EVENT_FLAG_OR|RT_EVENT_FLAG_CLEAR,RT_WAITING_FOREVER,&ev)==RT_EOK)
|
||
return ev;
|
||
else
|
||
return 0;
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
|
||
// 发送用户事件
|
||
int at_send_user_event(uint32_t ev)
|
||
{
|
||
if(g_recv_event)
|
||
{
|
||
rt_event_send(g_recv_event,ev);
|
||
return 0;
|
||
}
|
||
else
|
||
return -1;
|
||
}
|
||
|
||
|