#include "stdint.h" #include #include "at_host.h" #include "string.h" #include "stdlib.h" #include "ble_demo.h" //在同一个线程中调用则不需要加临界区 #if 0 # include "rthw.h" # define IRQ_DISABLE() rt_base_t irq_stat=rt_hw_interrupt_disable( ) # define IRQ_ENABLE() rt_hw_interrupt_enable (irq_stat) #else # define IRQ_DISABLE() # define IRQ_ENABLE() #endif /*------------------------buff相关操作函数---------------------------*/ //清空buff static int buff_clear(ble_buff *buff); //初始化buff static void buff_init(ble_buff *buff) { buff->buff_len=BLE_BUFF_LEN; buff_clear(buff); } //写入一个字节 static int buff_save_byte(ble_buff *buff,uint8_t data) { IRQ_DISABLE(); if (buff->buff_usedbuff_len) { buff->buff[buff->save_ptr]=data; buff->buff_used++; buff->save_ptr++; if (buff->save_ptr>=buff->buff_len) buff->save_ptr=0; IRQ_ENABLE(); return 1; } IRQ_ENABLE(); return 0; } //读取一个字节 static int buff_read_byte(ble_buff *buff,uint8_t *data) { IRQ_DISABLE(); if (buff->buff_used) { *data=buff->buff[buff->read_ptr]; buff->buff_used--; buff->read_ptr++; if (buff->read_ptr>=buff->buff_len) buff->read_ptr=0; IRQ_ENABLE(); return 1; } IRQ_ENABLE(); return 0; } //查找buff中是否有指定字符 static int buff_find_char(ble_buff *buff,uint8_t data) { int ptr=buff->read_ptr; int len=buff->buff_used; while(len--) { if(data==buff->buff[ptr]) return 1; ptr++; if (ptr>=buff->buff_len) ptr=0; } return 0; } //清空buff static int buff_clear(ble_buff *buff) { IRQ_DISABLE(); buff->buff_used=0; buff->read_ptr=0; buff->save_ptr=0; IRQ_ENABLE(); return 0; } /*------------------------buff相关操作函数End---------------------------*/ /*------------------------device相关操作函数---------------------------*/ //初始化蓝牙设备 int device_init(ble_device *device) { device->conn_handle=0; device->linked=0; memset(device->mac,0,6); buff_init(&device->buff_recv); return 1; } //设置此设备的mac地址 int device_set_mac(ble_device *device,uint8_t mac[6]) { memcpy(device->mac,mac,6); return 1; } //设置此设备的conn_handle int device_set_handle(ble_device *device,uint16_t handle) { device->conn_handle=handle; return 1; } //把数据存入设备缓冲 int device_save_buff(ble_device *device,uint8_t *buff,int size) { int ret=0; while(size--) { if (buff_save_byte(&device->buff_recv,buff[ret])==0) return ret; ret++; } return ret; } //读取设备缓冲,直到遇到界定符 int device_read_buff(ble_device *device,uint8_t *buff,int buff_size,uint8_t end_par) { if(buff_find_char(&device->buff_recv,end_par)==0) return 0; int ret=0; uint8_t t=0; while(1) { if(buff_read_byte(&device->buff_recv,&t)==0) return ret; if(buff_size) { buff[ret]=t; buff_size--; ret++; } if(t==end_par) return ret; } } //读取设备缓冲,指定长度 int device_read_buff_by_len(ble_device *device,uint8_t *buff,int read_len) { int ret=0; uint8_t t=0; while(1) { if(buff_read_byte(&device->buff_recv,&t)==0) return ret; if(read_len) { buff[ret]=t; read_len--; ret++; } else return ret; } } /*------------------------device相关操作函数End---------------------------*/ /*--------------------------ble相关操作函数----------------------------*/ //添加通知消息 int ble_add_notice(ble_struct *ble,uint8_t *obj,int obj_size,uint8_t op,uint8_t *par,int par_size); //连接事务改变 int ble_linked_change(ble_struct *ble,uint16_t handle,uint16_t state); //收到数据 int ble_save_data(ble_struct *ble,uint16_t handle,uint8_t *data,int len); //返回指定句柄的设备 ble_device *ble_find_device(ble_struct *ble,uint16_t handle); //添加设备 int ble_add_device(ble_struct *ble,uint16_t handle); //删除设备 int ble_sub_device(ble_struct *ble,uint16_t handle); //ble初始化 void ble_init(ble_struct *ble) { at_init(); ble->mode='i'; ble->linked=0; ble->notice_used=0; for(int i=0;idevice[i]); } at_clear_buff(); } //处理通知消息 int ble_deal_notice(ble_struct *ble) { int len=0; // uint8_t *data=malloc(100); uint8_t data[100]={0}; len=at_get_return_line(data); if(len==-1) {free(data);return 0;} uint8_t *par=0; int par_size=0; uint8_t *obj=0; int obj_size=0; uint8_t op=0; if(at_decode_line(data,len,&obj,&obj_size,&op,&par,&par_size)==-1) {free(data);return 0;} if(op==CMDAT_CMD_RET) { //命令返回消息,存储到通知缓冲区 ble_add_notice(ble,obj,obj_size,op,par,par_size); } else if(op==CMDAT_CMD_ACT) { //通知消息,进一步区分 if(obj[0]==0x01) { //连接事务改变 ble_linked_change(ble,*(uint16_t *)par,*(uint16_t *)(par+2)); } else if(obj[0]==0x02) { //收到新数据 ble_save_data(ble,*(uint16_t *)par,par+2,par_size-2); } } // free(data); return 1; } //添加通知消息 int ble_add_notice(ble_struct *ble,uint8_t *obj,int obj_size,uint8_t op,uint8_t *par,int par_size) { uint8_t *notice=0; if(ble->notice_usednotice[ble->notice_used]; ble->notice_used++; } else { //通知缓冲区已满,舍弃掉最久远的 notice=ble->notice[ble->notice_used-1]; for(int i=0;inotice_used-1;i++) { memcpy(ble->notice[i],ble->notice[i+1],BLE_NOTICE_LEN); } } notice[0]=obj_size; memcpy(¬ice[1],obj,obj_size); notice=¬ice[1+obj_size]; notice[0]=op; notice++; notice[0]=par_size; memcpy(¬ice[1],par,par_size); return 1; } //获取通知消息 int ble_get_notice(ble_struct *ble,uint8_t *obj,int *obj_size,uint8_t *op,uint8_t *par,int *par_size) { if(ble->notice_used) { uint8_t *notice=ble->notice[0]; if(obj) memcpy(obj,¬ice[1],notice[0]); if(obj_size) *obj_size=notice[0]; if(op) *op=notice[1+notice[0]]; if(par) memcpy(par,¬ice[1+notice[0]+1+1],notice[1+notice[0]+1]); if(par_size) *par_size=notice[1+notice[0]+1]; for(int i=0;inotice_used-1;i++) { memcpy(ble->notice[i],ble->notice[i+1],BLE_NOTICE_LEN); } ble->notice_used--; return 1; } return 0; } //连接事务改变 int ble_linked_change(ble_struct *ble,uint16_t handle,uint16_t state) { if(state==1) { //添加连接设备 ble_add_device(ble,handle); } else if(state==0) { //删除连接设备 ble_sub_device(ble,handle); } else { return 0; } return 1; } //收到数据 int ble_save_data(ble_struct *ble,uint16_t handle,uint8_t *data,int len) { ble_device *device=ble_find_device(ble,handle); if(device) { return device_save_buff(device,data,len); } return 0; } //返回指定句柄的设备 ble_device *ble_find_device(ble_struct *ble,uint16_t handle) { if(handle==0) return 0; for(int i=0;idevice[i].conn_handle==handle) return &ble->device[i]; } return 0; } //返回指定索引的蓝牙设备 ble_device *ble_find_device_by_index(ble_struct *ble,int index) { if(indexdevice[index].conn_handle) return &ble->device[index]; } return 0; } //添加设备 int ble_add_device(ble_struct *ble,uint16_t handle) { if(handle==0) return 0; for(int i=0;idevice[i]; if(device->conn_handle==0) { memcpy(device->mac,ble->conn_mac,6); device->conn_handle=handle; device->linked=1; ble->linked++; return 1; } } return 0; } //删除设备 int ble_sub_device(ble_struct *ble,uint16_t handle) { if(handle==0) return 0; for(int i=0;idevice[i]; if(device->conn_handle==handle) { device->conn_handle=0; device->linked=0; memset(device->mac,0,6); buff_clear(&device->buff_recv); ble->linked--; return 1; } } return 0; } //读取数据直到出现界定符 int ble_get_recv_data_by_end(ble_struct *ble,uint16_t handle,uint8_t *buff,int buff_size,uint8_t end_par) { ble_device *device=ble_find_device(ble,handle); if (device) { return device_read_buff(device,buff,buff_size,end_par); } return 0; } //读取指定长度的数据 int ble_get_recv_data(ble_struct *ble,uint16_t handle,uint8_t *buff,int read_len) { ble_device *device=ble_find_device(ble,handle); if (device) { return device_read_buff_by_len(device,buff,read_len); } return 0; } //获取命令返回 int ble_get_cmd_return(ble_struct *ble,uint8_t *buff,int *buff_size) { // rt_thread_delay(20); do{ ble_deal_notice(ble); } while(ble_get_notice(ble,0,0,0,buff,buff_size)==0); return 1; } //设置设备名称 int ble_set_name(ble_struct *ble,char *name) { uint8_t *data=ble->data_temp; int size=0; at_send_set(0x01,name,strlen(name)); if(ble_get_cmd_return(ble,data,&size)==1) { if(data[0]==1) return 1; } return 0; } //获取设备mac地址 int ble_get_mac(ble_struct *ble,uint8_t mac[6]) { uint8_t *data=ble->data_temp; int size=0; at_send_get(0x02,0,0); if(ble_get_cmd_return(ble,data,&size)==1) { if(size==6) { memcpy(mac,data,6); return 1; } } return 0; } //重启 int ble_reboot(ble_struct *ble) { uint8_t *data=ble->data_temp; int size=0; int time_out=100; do{ at_send_set(0x03,0,0); rt_thread_delay(2); ble_deal_notice(ble); ble_get_notice(ble,0,0,0,data,&size); if((size==1)&&(data[0]==1)) { rt_thread_delay(100); at_clear_buff(); return 1; } } while(time_out--); return 0; } //设置uuid int ble_set_uuid(ble_struct *ble,uint8_t sub,uint8_t type,uint8_t *uuid) { uint8_t *data=ble->data_temp; int size=0; data[0]=sub;data[1]=type; memcpy(&data[2],uuid,type/8); at_send_set(0x05,data,2+type/8); if(ble_get_cmd_return(ble,data,&size)==1) { if(data[0]==1) return 1; } return 0; } //打开/关闭数据传输 int ble_set_data_transport(ble_struct *ble,uint8_t power) { uint8_t *data=ble->data_temp; int size=0; at_send_set(0x06,&power,1); if(ble_get_cmd_return(ble,data,&size)==1) { if(data[0]==1) return 1; } return 0; } //发送数据 int ble_send_data(ble_struct *ble,uint16_t handle,uint8_t *buff,int len) { uint8_t *data=ble->data_temp; int size=0; int pack_len=0; while(len) { data[0]=handle; data[1]=handle>>8; if(len>20) pack_len=20; else pack_len=len; memcpy(&data[2],buff,pack_len); at_send_set(0x07,data,pack_len+2); if(ble_get_cmd_return(ble,data,&size)==1) { if(data[0]==1) { if (len==0) return 1; } else { return 0; } } else return 0; len-=pack_len; buff+=pack_len; } return 0; } //设置为从机模式 int ble_set_slave(ble_struct *ble) { uint8_t *data=ble->data_temp; int size=0; at_send_set(0x10,0,0); if(ble_get_cmd_return(ble,data,&size)==1) { if(data[0]==1) { ble->mode='s'; return 1; } } return 0; } //设置为主机模式 int ble_set_host(ble_struct *ble) { uint8_t *data=ble->data_temp; int size=0; at_send_set(0x20,0,0); if(ble_get_cmd_return(ble,data,&size)==1) { if(data[0]==1) { ble->mode='h'; return 1; } } return 0; } //连接指定的从机 int ble_connect_by_mac(ble_struct *ble,uint8_t mac[6]) { uint8_t *data=ble->data_temp; int size=0; at_send_set(0x21,mac,6); if(ble_get_cmd_return(ble,data,&size)==1) { if(data[0]==1) { memcpy(ble->conn_mac,mac,6); return 1; } } return 0; } //断开指定的从机 int ble_discon_by_mac(ble_struct *ble,uint8_t mac[6]) { uint8_t *data=ble->data_temp; int size=0; at_send_set(0x22,mac,6); if(ble_get_cmd_return(ble,data,&size)==1) { if(data[0]==1) return 1; } return 0; } //扫描 int ble_scan(ble_struct *ble,ble_mac_name mac[32],int *mac_num) { uint8_t *data=ble->data_temp; int size=0; *mac_num=0; at_send_set(0x23,0,0); rt_thread_delay(3500); while(1) { if(ble_get_cmd_return(ble,data,&size)==1) { if(size==1) { if(data[0]==1) return 1; else return 0; } else if(size>=7) { memcpy(mac[*mac_num].mac,data,6); mac[*mac_num].rssi=data[6]; if(size>7) { int len=size-7; memcpy(mac[*mac_num].name,data+7,len); mac[*mac_num].name[len]=0; } else mac[*mac_num].name[0]=0; (*mac_num)++; } } else return 0; } }