925 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			925 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| #include <stdio.h>
 | ||
| #include "at_host.h"
 | ||
| #include "string.h"
 | ||
| #include "stdlib.h"
 | ||
| #include "rtthread.h"
 | ||
| #include "ble_demo.h"
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| //在同一个线程中调用则不需要加临界区
 | ||
| #if 1
 | ||
| 	#include "rthw.h"
 | ||
| 	#define IRQ_DISABLE()           rt_enter_critical()
 | ||
| 	#define IRQ_ENABLE()            rt_exit_critical()
 | ||
| #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_used<buff->buff_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---------------------------*/
 | ||
| 
 | ||
| 
 | ||
| static void ble_print_data(uint8_t *data,int len)
 | ||
| {
 | ||
|   for(int i=0;i<len;i++)
 | ||
|   {
 | ||
|     printf("%02X ",data[i]);
 | ||
|   }
 | ||
|   printf("\r\n");
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| /*--------------------------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);
 | ||
| 
 | ||
| 
 | ||
| static int ble_service_on(void *t);
 | ||
| static int ble_service_off(void);
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| //ble初始化
 | ||
| void ble_init(ble_struct *ble)
 | ||
| {
 | ||
|   if(ble==0) return;
 | ||
|   memset(ble,0,sizeof(ble_struct));
 | ||
| 	at_init();
 | ||
| 	ble->mode='i';
 | ||
| 	ble->linked=0;
 | ||
| 	for(int i=0;i<BLE_MAX_LINKED;i++)
 | ||
| 	{
 | ||
| 		device_init(&ble->device[i]);
 | ||
| 	}
 | ||
| 	at_clear_buff();
 | ||
|   ble->ret_event=rt_event_create("ble_ret", RT_IPC_FLAG_FIFO);
 | ||
|   ble->kno_event=rt_event_create("ble_kno", RT_IPC_FLAG_FIFO);
 | ||
|   rt_event_send(ble->kno_event,2);
 | ||
|   ble_service_on(ble);
 | ||
|   ble_reboot(ble);
 | ||
| }
 | ||
| 
 | ||
| //ble去初始化
 | ||
| void ble_deinit(ble_struct *ble)
 | ||
| {
 | ||
|   if(ble==0) return ;
 | ||
|   ble_reboot(ble);
 | ||
|   ble_service_off();
 | ||
|   at_deinit();
 | ||
|   if(ble->ret_event)
 | ||
|     rt_event_delete(ble->ret_event);
 | ||
|   if(ble->kno_event)
 | ||
|     rt_event_delete(ble->kno_event);
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| // 设置回调函数
 | ||
| int ble_set_callback_linked_change(ble_struct *ble,void (*linked_change)(uint16_t handle,uint16_t state))
 | ||
| {
 | ||
|   ble->linked_change=linked_change;
 | ||
|   return 1;
 | ||
| }
 | ||
| int ble_set_callback_recv_data(ble_struct *ble,void (*recv_data)(uint16_t handle,uint8_t *data,int len))
 | ||
| {
 | ||
|   ble->recv_data=recv_data;
 | ||
|   return 1;
 | ||
| }
 | ||
| int ble_set_callback_user_irq(ble_struct *ble,void (*user_irq)(uint8_t *data,int len))
 | ||
| {
 | ||
|   ble->user_irq=user_irq;
 | ||
|   return 1;
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| //处理通知消息
 | ||
| int ble_deal_notice(ble_struct *ble)
 | ||
| {
 | ||
|   if(ble==0) return 0;
 | ||
| 	int len=0;
 | ||
| 	uint8_t *data=ble->return_line;
 | ||
| 	len=at_get_return_line(data);
 | ||
| 	if(len==-1) {
 | ||
|         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)
 | ||
|   {
 | ||
|     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)
 | ||
| 		{
 | ||
| 			//收到新数据
 | ||
|       if(ble->recv_data==0)
 | ||
|         ble_save_data(ble,*(uint16_t *)par,par+2,par_size-2);
 | ||
|       else
 | ||
|         ble->recv_data(*(uint16_t *)par,par+2,par_size-2);
 | ||
| 		}
 | ||
|     else if(obj[0]==0xff)
 | ||
|     {
 | ||
|       // 用户中断
 | ||
|       if(ble->user_irq) ble->user_irq(par,par_size);
 | ||
|     }
 | ||
| 	}
 | ||
| 	return 1;
 | ||
| }
 | ||
| 
 | ||
| //添加通知消息
 | ||
| int ble_add_notice(ble_struct *ble,uint8_t *obj,int obj_size,uint8_t op,uint8_t *par,int par_size)
 | ||
| {
 | ||
|   notice_t *n=&ble->notice;
 | ||
|   if(ble->kno_event)
 | ||
|   {
 | ||
|     // 等待接收方查看通知
 | ||
|     rt_uint32_t ev;
 | ||
|     rt_event_recv(ble->kno_event,0xffffffff,RT_EVENT_FLAG_OR|RT_EVENT_FLAG_CLEAR,1000,&ev);
 | ||
|   }
 | ||
|   //ble_print_data(par,par_size);
 | ||
|   IRQ_DISABLE();
 | ||
|   memcpy(n->obj,obj,obj_size);
 | ||
|   memcpy(n->par,par,par_size);
 | ||
|   n->obj_size=obj_size;
 | ||
|   n->par_size=par_size;
 | ||
|   IRQ_ENABLE();
 | ||
|   if(ble->ret_event)
 | ||
|   {
 | ||
|     // 发送通知提醒接收方查看
 | ||
|     rt_event_send(ble->ret_event,1);
 | ||
|   }
 | ||
| 	return 1;
 | ||
| }
 | ||
| 
 | ||
| //获取通知消息,返回0失败
 | ||
| int ble_get_notice(ble_struct *ble,uint8_t *obj,int *obj_size,uint8_t *op,uint8_t *par,int *par_size)
 | ||
| {
 | ||
|   rt_uint32_t ev;
 | ||
|   if(ble->ret_event)
 | ||
|   {
 | ||
|     if(rt_event_recv(ble->ret_event,0xffffffff,RT_EVENT_FLAG_OR|RT_EVENT_FLAG_CLEAR,1000,&ev)==RT_EOK)
 | ||
|     {
 | ||
|       IRQ_DISABLE();
 | ||
|       notice_t *n=&ble->notice;
 | ||
|       if(obj) memcpy(obj,n->obj,n->obj_size);
 | ||
|       if(obj_size) *obj_size=n->obj_size;
 | ||
|       if(par) memcpy(par,n->par,n->par_size);
 | ||
|       if(par_size) *par_size=n->par_size;
 | ||
|       n->obj_size=0;
 | ||
|       n->par_size=0;
 | ||
|       IRQ_ENABLE();
 | ||
|       if(ble->kno_event)
 | ||
|       {
 | ||
|         // 通知已查看
 | ||
|         rt_event_send(ble->kno_event,1);
 | ||
|       }
 | ||
|       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;
 | ||
| 	}
 | ||
|   // 调用用户回调函数
 | ||
|   if(ble->linked_change) ble->linked_change(handle,state);
 | ||
|     
 | ||
| 	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)
 | ||
| 	{
 | ||
|     //printf("%s:recved %d\r\n",__func__,len);
 | ||
| 		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;i<BLE_MAX_LINKED;i++)
 | ||
| 	{
 | ||
| 		if(ble->device[i].conn_handle==handle)
 | ||
| 			return &ble->device[i];
 | ||
| 	}
 | ||
| 	return 0;
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| //返回指定索引的蓝牙设备
 | ||
| ble_device *ble_find_device_by_index(ble_struct *ble,int index)
 | ||
| {
 | ||
|     if(ble==0) return 0;
 | ||
| 	if(index<BLE_MAX_LINKED)
 | ||
| 	{
 | ||
| 		if(ble->device[index].conn_handle)
 | ||
| 			return &ble->device[index];
 | ||
| 	}
 | ||
| 	return 0;
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| //添加设备
 | ||
| int ble_add_device(ble_struct *ble,uint16_t handle)
 | ||
| {
 | ||
| 	if(handle==0) return 0;
 | ||
|   IRQ_DISABLE();
 | ||
| 	for(int i=0;i<BLE_MAX_LINKED;i++)
 | ||
| 	{
 | ||
| 		ble_device *device=&ble->device[i];
 | ||
| 		if(device->conn_handle==0)
 | ||
| 		{
 | ||
| 			memcpy(device->mac,ble->conn_mac,6);
 | ||
| 			device->conn_handle=handle;
 | ||
| 			device->linked=1;
 | ||
| 			ble->linked++;
 | ||
|       IRQ_ENABLE();
 | ||
| 			return 1;
 | ||
| 		}
 | ||
| 	}
 | ||
|   IRQ_ENABLE();
 | ||
| 	return 0;
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| //删除设备
 | ||
| int ble_sub_device(ble_struct *ble,uint16_t handle)
 | ||
| {
 | ||
| 	if(handle==0) return 0;
 | ||
|   IRQ_DISABLE();
 | ||
| 	for(int i=0;i<BLE_MAX_LINKED;i++)
 | ||
| 	{
 | ||
| 		ble_device *device=&ble->device[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--;
 | ||
|       IRQ_ENABLE();
 | ||
| 			return 1;
 | ||
| 		}
 | ||
| 	}
 | ||
|   IRQ_ENABLE();
 | ||
| 	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)
 | ||
| {
 | ||
|     if(ble==0) return 0;
 | ||
| 	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)
 | ||
| {
 | ||
|     if(ble==0) return 0;
 | ||
| 	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)
 | ||
| {
 | ||
|   int ret=0;
 | ||
| 
 | ||
|   ret=ble_get_notice(ble,0,0,0,buff,buff_size);
 | ||
|   return ret;
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| //设置设备名称
 | ||
| int ble_set_name(ble_struct *ble,char *name)
 | ||
| {
 | ||
|     if(ble==0) return 0;
 | ||
| 	uint8_t *data=ble->data_temp;
 | ||
| 	int size=0;
 | ||
| 	at_send_set_event(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])
 | ||
| {
 | ||
|     if(ble==0) return 0;
 | ||
| 	uint8_t *data=ble->data_temp;
 | ||
| 	int size=0;
 | ||
| 	at_send_get_event(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)
 | ||
| {
 | ||
|   if(ble==0) return 0;
 | ||
| 	uint8_t *data=ble->data_temp;
 | ||
| 	int size=0;
 | ||
| 	int time_out=100;
 | ||
| 	
 | ||
| 	do{
 | ||
| 		at_send_set_event(0x03,0,0);
 | ||
| 		rt_thread_delay(2);
 | ||
| 		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)
 | ||
| {
 | ||
|   if(ble==0) return 0;
 | ||
| 	uint8_t *data=ble->data_temp;
 | ||
| 	int size=0;
 | ||
| 	
 | ||
| 	data[0]=sub;data[1]=type;
 | ||
| 	memcpy(&data[2],uuid,type/8);
 | ||
| 	at_send_set_event(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)
 | ||
| {
 | ||
|   if(ble==0) return 0;
 | ||
| 	uint8_t *data=ble->data_temp;
 | ||
| 	int size=0;
 | ||
| 	at_send_set_event(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)
 | ||
| {
 | ||
|     if(ble==0) return 0;
 | ||
| 	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_event(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)
 | ||
| {
 | ||
|     if(ble==0) return 0;
 | ||
| 	uint8_t *data=ble->data_temp;
 | ||
| 	int size=0;
 | ||
| 	at_send_set_event(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)
 | ||
| {
 | ||
|     if(ble==0) return 0;
 | ||
| 	uint8_t *data=ble->data_temp;
 | ||
| 	int size=0;
 | ||
| 	at_send_set_event(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])
 | ||
| {
 | ||
|     if(ble==0) return 0;
 | ||
| 	uint8_t *data=ble->data_temp;
 | ||
| 	int size=0;
 | ||
| 	at_send_set_event(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])
 | ||
| {
 | ||
|     if(ble==0) return 0;
 | ||
| 	uint8_t *data=ble->data_temp;
 | ||
| 	int size=0;
 | ||
| 	at_send_set_event(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)
 | ||
| {
 | ||
|     if(ble==0) return 0;
 | ||
| 	uint8_t *data=ble->data_temp;
 | ||
| 	int size=0;
 | ||
| 	*mac_num=0;
 | ||
| 	at_send_set_event(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;
 | ||
| 	}
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| //发送用户设置数据
 | ||
| int ble_user_cmd_set(ble_struct *ble,uint8_t *tx,int tx_len)
 | ||
| {
 | ||
|   if(ble==0) return 0;
 | ||
| 	uint8_t *data=ble->data_temp;
 | ||
| 	int size=0;
 | ||
| 	at_send_set_event(0xff,tx,tx_len);
 | ||
| 	if(ble_get_cmd_return(ble,data,&size)==1)
 | ||
| 	{
 | ||
| 		if(size==1)
 | ||
| 			return 1;
 | ||
| 	}
 | ||
| 	return 0;
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| //发送用户获取数据,rx_len获取的数据长度,失败返回0
 | ||
| int ble_user_cmd_get(ble_struct *ble,uint8_t *tx,int tx_len,uint8_t *rx,int *rx_len)
 | ||
| {
 | ||
|   if(ble==0) return 0;
 | ||
| 	uint8_t *data=ble->data_temp;
 | ||
| 	int size=0;
 | ||
|   int recv_len=0;
 | ||
|   uint8_t obj;
 | ||
|   int obj_size;
 | ||
| 	at_send_get_event(0xff,tx,tx_len);
 | ||
|   while(1)
 | ||
|   {
 | ||
|     if(ble_get_notice(ble,&obj,&obj_size,0,data,&size)==1)
 | ||
|     {
 | ||
|       if(obj_size==0)
 | ||
|         return data[0];
 | ||
|       else
 | ||
|       {
 | ||
|         if(recv_len==0)
 | ||
|         {
 | ||
|           if(size>*rx_len) recv_len=*rx_len;
 | ||
|           else recv_len=size;
 | ||
|           memcpy(rx,data,recv_len);
 | ||
|           //ble_print_data(rx,recv_len);
 | ||
|           *rx_len=recv_len;
 | ||
|         }
 | ||
|       }
 | ||
|     }else break;
 | ||
|   }
 | ||
| 	return 0;
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| static int g_service_work;
 | ||
| static int g_service_done=1;
 | ||
| // ble 服务线程
 | ||
| static void ble_service_thread(void *t)
 | ||
| {
 | ||
|   ble_struct *ble=t;
 | ||
|   g_service_done=0;
 | ||
|   
 | ||
|   int ev;
 | ||
|   while(g_service_work)
 | ||
|   {
 | ||
|     ev=at_get_event();
 | ||
|     if(ev&CMDAT_EVENT_RECV)
 | ||
|     {
 | ||
|       ev&=~CMDAT_EVENT_RECV;
 | ||
|       while(ble_deal_notice(ble)==1);
 | ||
|     }
 | ||
|     if(ev&CMDAT_EVENT_USER)
 | ||
|     {
 | ||
|       ev&=~CMDAT_EVENT_USER;
 | ||
|       at_send_packet();
 | ||
|     }
 | ||
|     if(ev)
 | ||
|     {
 | ||
|       
 | ||
|     }
 | ||
|   }
 | ||
|   
 | ||
|   g_service_done=1;
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| static int ble_service_on(void *t)
 | ||
| {
 | ||
| 	rt_err_t result = RT_EOK;
 | ||
| 	rt_thread_t tid;
 | ||
| 
 | ||
|   // 保证线程没有被创建
 | ||
|   if(g_service_done)
 | ||
|   {
 | ||
|     g_service_work=1;
 | ||
|     tid = rt_thread_create("ble_service_thread", ble_service_thread, t, 2048, 11, 10);
 | ||
|     if (tid != NULL && result == RT_EOK)
 | ||
|       rt_thread_startup(tid);
 | ||
|     return 0;
 | ||
|   }
 | ||
|   else
 | ||
|   {
 | ||
|     return -1;
 | ||
|   }
 | ||
|   
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| static int ble_service_off(void)
 | ||
| {
 | ||
|   // 保证线程已经被创建
 | ||
|   if(g_service_work)
 | ||
|   {
 | ||
|     g_service_work=0;
 | ||
|     at_send_user_event(0x04);
 | ||
|     while(g_service_done==0)
 | ||
|     {
 | ||
|       rt_thread_delay(10);
 | ||
|     }
 | ||
|     return 0;
 | ||
|   }
 | ||
|   else
 | ||
|   {
 | ||
|     return -1;
 | ||
|   }
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 |