基于BlueZ5.44协议栈的RTL8723 BLE蓝牙连接(二)

来源:互联网 发布:淘宝肖像权投诉 编辑:程序博客网 时间:2024/06/16 13:01

一、打印数据现象分析:

二、应用层分析:gatttool.c

三、驱动层分析:Rtk_bt.c  Rtk_coex.c

四、蓝牙连接方法:

五、蓝牙电源的管理

六、交叉编译蓝牙BlueZ协议栈

七、问题分析

八、项目总结

 

从Bluez下移植蓝牙方面看,只关心两个地方,一个是bluez的工具集中的gatttool工具(使用uart接口的蓝牙需要hciattach),另一个是蓝牙驱动的移植。

一、打印数据现象分析:

1)BLE蓝牙设备连接不上:# ./gatttool59 -b 80:EA:CA:01:00:01 --char-write-req -a 0x0026 -n 0100  --listen----1-----------2-----------3-----rtk_btusb: hci0 evt 1------4-------rtk_btusb: btusb_notify : hci0 evt 1-gh---5-----------6-------opt_primary:0-characteristics_write_req---9-----------10-----------10----0-------12-----------13-------rtk_btusb: update_profile_connection: is_add=1, profile_index=1rtk_btusb: update_profile_connection: usb_coex_info.profile_bitmap = 2rtk_btusb: update_profile_connection: usb_coex_info.profile_refcount[0] = 0rtk_btusb: update_profile_connection: usb_coex_info.profile_refcount[1] = 1-gh---cb1-------rtk_btusb: update_profile_connection: usb_coex_info.profile_refcount[2] = 0----cb2-rtk_btusb: update_profile_connection: usb_coex_info.profile_refcount[3] = 0------rtk_btusb: update_profile_connection: usb_coex_info.profile_refcount[4] = 0rtk_btusb: update_profile_connection: usb_coex_info.profile_refcount[5] = 0----cb3-------rtk_btusb: update_profile_connection: usb_coex_info.profile_refcount[6] = 0rtk_btusb: update_profile_connection: usb_coex_info.profile_refcount[7] = 0rtk_btusb: rtk_notify_profileinfo_to_fw, BufferSize is 5rtk_btusb: rtk_notify_profileinfo_to_fw, NumberOfHandles is 1----cb4-------rtk_btusb: rtk_notify_profileinfo_to_fw, handle is 10rtk_btusb: rtk_notify_profileinfo_to_fw, profile_bitmap is 2rtk_btusb: rtk_notify_profileinfo_to_fw, profile_status is 0rtk_btusb: rtk_vendor_cmd_to_fw, opcode is 0xfc19rtk_btusb: update_hid_active_state: handle = 10, interval = 0x36----characteristrtk_btusb: in hci_cmd_task, coex_info.num_hci_cmd_packet is 1ics_write_req--grtk_btusb: send cmd to fw, opcode = 0xfc19attool--0---00000000000000buf=54----characteristrtk_btusb: rtk_notify_profileinfo_to_fw, BufferSize is 5ics_write_req--grtk_btusb: rtk_notify_profileinfo_to_fw, NumberOfHandles is 1attool--1----grtk_btusb: rtk_notify_profileinfo_to_fw, handle is 10h---listen_startrtk_btusb: rtk_notify_profileinfo_to_fw, profile_bitmap is 121--------gh---rtk_btusb: rtk_notify_profileinfo_to_fw, profile_status is 2listen_start2---rtk_btusb: rtk_vendor_cmd_to_fw, opcode is 0xfc19----hello enter/nrtk_btusb: in hci_cmd_task, coex_info.num_hci_cmd_packet is 0read: 54/nrtk_btusb: rtk_handle_le_meta_evt----char_write_req_cb--gattool--0---user space from kernelflag:0Characteristic value was written successfullyrtk_btusb: update_profile_connection: is_add=0, profile_index=1rtk_btusb: for test: --, usb_coex_info.profile_refcount[1] = 0rtk_btusb: update_profile_connection: usb_coex_info.profile_bitmap = 0rtk_btusb: update_profile_connection: usb_coex_info.profile_refcount[0] = 0rtk_btusb: update_profile_connection: usb_coex_info.profile_refcount[1] = 0rtk_btusb: update_profile_connection: usb_coex_info.profile_refcount[2] = 0rtk_btusb: update_profile_connection: usb_coex_info.profile_refcount[3] = 0rtk_btusb: update_profile_connection: usb_coex_info.profile_refcount[4] = 0rtk_btusb: update_profile_connection: usb_coex_info.profile_refcount[5] = 0rtk_btusb: update_profile_connection: usb_coex_info.profile_refcount[6] = 0rtk_btusb: update_profile_connection: usb_coex_info.profile_refcount[7] = 0rtk_btusb: rtk_notify_profileinfo_to_fw, BufferSize is 2rtk_btusb: rtk_notify_profileinfo_to_fw, NumberOfHandles is 0rtk_btusb: rtk_notify_profileinfo_to_fw, profile_status is 0rtk_btusb: rtk_vendor_cmd_to_fw, opcode is 0xfc19rtk_btusb: in hci_cmd_task, coex_info.num_hci_cmd_packet is 0rtk_btusb: command timeoutrtk_btusb: send cmd to fw, opcode = 0xfc19rtk_btusb: in hci_cmd_task, coex_info.num_hci_cmd_packet is 1rtk_btusb: send cmd to fw, opcode = 0xfc19rtk_btusb: hci0 evt 2rtk_btusb: btusb_notify : hci0 evt 22)BLE蓝牙设备已连接:# ./gatttool59 -b 80:EA:CA:01:00:01 --char-write-req -a 0x0026 -n 0100  --listen----1-----------2-----------3-----rtk_btusb: hci0 evt 1------4-------rtk_btusb: btusb_notify : hci0 evt 1-gh---5-----------6-------opt_primary:0-characteristics_write_req---9-----------10-----------10----0-------12-----------13-------rtk_btusb: update_profile_connection: is_add=1, profile_index=1rtk_btusb: update_profile_connection: usb_coex_info.profile_bitmap = 2rtk_btusb: update_profile_connection: usb_coex_info.profile_refcount[0] = 0rtk_btusb: update_profile_connection: usb_coex_info.profile_refcount[1] = 1-gh---cb1-------rtk_btusb: update_profile_connection: usb_coex_info.profile_refcount[2] = 0rtk_btusb: update_profile_connection: usb_coex_info.profile_refcount[3] = 0rtk_btusb: update_profile_connection: usb_coex_info.profile_refcount[4] = 0rtk_btusb: update_profile_connection: usb_coex_info.profile_refcount[5] = 0----cb2-------rtk_btusb: update_profile_connection: usb_coex_info.profile_refcount[6] = 0----cb3-------rtk_btusb: update_profile_connection: usb_coex_info.profile_refcount[7] = 0----cb4-------rtk_btusb: rtk_notify_profileinfo_to_fw, BufferSize is 5----charactertk_btusb: rtk_notify_profileinfo_to_fw, NumberOfHandles is 1ristics_write_rertk_btusb: rtk_notify_profileinfo_to_fw, handle is 10q--gattool--0---rtk_btusb: rtk_notify_profileinfo_to_fw, profile_bitmap is 2rtk_btusb: rtk_notify_profileinfo_to_fw, profile_status is 0rtk_btusb: rtk_vendor_cmd_to_fw, opcode is 0xfc19----characteristrtk_btusb: update_hid_active_state: handle = 10, interval = 0x36ics_write_req--grtk_btusb: in hci_cmd_task, coex_info.num_hci_cmd_packet is 1attool--1----grtk_btusb: send cmd to fw, opcode = 0xfc19h---listen_start00000000000000buf=541--------gh---rtk_btusb: rtk_notify_profileinfo_to_fw, BufferSize is 5listen_start2---rtk_btusb: rtk_notify_profileinfo_to_fw, NumberOfHandles is 1----rtk_btusb: rtk_notify_profileinfo_to_fw, handle is 10rtk_btusb: rtk_notify_profileinfo_to_fw, profile_bitmap is 12rtk_btusb: rtk_notify_profileinfo_to_fw, profile_status is 2rtk_btusb: rtk_vendor_cmd_to_fw, opcode is 0xfc19hello enter/nrtk_btusb: in hci_cmd_task, coex_info.num_hci_cmd_packet is 0read: 54/nrtk_btusb: rtk_handle_le_meta_evt----char_write_req_cb--gattool--0---user space from kernelflag:0Characteristic value was written successfullyrtk_btusb: update_hid_active_state: handle = 10, interval = 0xc00000000000000buf=12hello enter/nread: 12/nrtk_btusb: rtk_handle_le_connection_update_complete_evtrtk_btusb: rtk_handle_le_meta_evt-------events_handler---01---------events_handler---02--temp1=29, humi1=46update bt data:update TemperatureRegister set command_temperature = 29 , command_humidity = 46             where device_port = 'bluetooth';ij:1xy:1-------events_handler---0---------events_handler---01---------events_handler---02--ij:2xy:2-------events_handler---0---------events_handler---01---------events_handler---02--ij:3xy:3-------events_handler---0--^C# rtk_btusb: update_hid_active_state: handle = 10, interval = 0xc00000000000000buf=12hello enter/nread: 12/nrtk_btusb: rtk_handle_le_connection_update_complete_evtrtk_btusb: rtk_handle_le_meta_evtrtk_btusb: update_profile_connection: is_add=0, profile_index=1rtk_btusb: for test: --, usb_coex_info.profile_refcount[1] = 0rtk_btusb: update_profile_connection: usb_coex_info.profile_bitmap = 0rtk_btusb: update_profile_connection: usb_coex_info.profile_refcount[0] = 0rtk_btusb: update_profile_connection: usb_coex_info.profile_refcount[1] = 0rtk_btusb: update_profile_connection: usb_coex_info.profile_refcount[2] = 0rtk_btusb: update_profile_connection: usb_coex_info.profile_refcount[3] = 0rtk_btusb: update_profile_connection: usb_coex_info.profile_refcount[4] = 0rtk_btusb: update_profile_connection: usb_coex_info.profile_refcount[5] = 0rtk_btusb: update_profile_connection: usb_coex_info.profile_refcount[6] = 0rtk_btusb: update_profile_connection: usb_coex_info.profile_refcount[7] = 0rtk_btusb: rtk_notify_profileinfo_to_fw, BufferSize is 2rtk_btusb: rtk_notify_profileinfo_to_fw, NumberOfHandles is 0rtk_btusb: rtk_notify_profileinfo_to_fw, profile_status is 0rtk_btusb: rtk_vendor_cmd_to_fw, opcode is 0xfc19rtk_btusb: in hci_cmd_task, coex_info.num_hci_cmd_packet is 0rtk_btusb: command timeoutrtk_btusb: send cmd to fw, opcode = 0xfc19rtk_btusb: in hci_cmd_task, coex_info.num_hci_cmd_packet is 1rtk_btusb: send cmd to fw, opcode = 0xfc19rtk_btusb: hci0 evt 2rtk_btusb: btusb_notify : hci0 evt 2


二、应用层分析:gatttool.c

执行程序:./gatttool59 -b 80:EA:CA:01:00:01 --char-write-req -a 0x0026 -n0100  --listen

//读取notifications里的内容,监听读取notifications时需要向该handle写入一个1,在命令行中16进制的表示为0100,可以设置listen来开启监听否则每次只读一次

init||//获取命令行参数chan = gatt_connect(opt_src, opt_dst, opt_dst_type, opt_sec_level,opt_psm, opt_mtu, connect_cb, &gerr);||event_loop = g_main_loop_new(NULL, FALSE);||g_main_loop_run(event_loop);||static void connect_cb(GIOChannel *io, GError *err, gpointer user_data)>g_idle_add(listen_start, attrib);||static gboolean characteristics_write_req(gpointer user_data)// 调用命令行char-write-req>gatt_write_char(attrib, opt_handle, value, len, char_write_req_cb,NULL);||static gboolean listen_start(gpointer user_data)//监听读取数据>g_attrib_register(attrib, ATT_OP_HANDLE_IND,GATTRIB_ALL_HANDLES,events_handler, attrib, NULL);||static void char_write_req_cb(guint8 status, const guint8 *pdu, guint16 plen,gpointer user_data)>if (!dec_write_resp(pdu, plen) && !dec_exec_write_resp(pdu, plen)) 连接上*******Characteristic value was written successfully连接不上*****if (status != 0)Characteristic Write Request failed: Request attribute has encountered an unlikely error||//接受温湿度数据(判断是否断开连接)static void events_handler(const uint8_t *pdu, uint16_t len, gpointer user_data)

三、驱动层分析:Rtk_bt.c  Rtk_coex.c

3.1、Bluez下内核蓝牙框架

使用Bluez时,需要内核提供一系列的socket接口来操作蓝牙,内核中蓝牙的框架如图所示。蓝牙框架分成两部分:蓝牙socket部分及蓝牙驱动部分。蓝牙socket部分负责管理提供给bluez的socket,并包含L2cap层的功能;蓝牙驱动包含hci层协议及蓝牙硬件接口的管理。蓝牙socket部分与蓝牙驱动通过hci_core来连接。

这里写图片描述

3.2 、内核中的蓝牙

在Ubuntu系统下,Bluez的蓝牙驱动负责hci协议的处理、与蓝牙硬件交互数据、注册hci接口供蓝牙socket部分使用。

3.3、USB蓝牙驱动

不管是uart接口还是usb接口的蓝牙,都是通过hci_register_dev函数向hci_core层注册接口,sock通信,发送和接受skb网络包;

static int __init btusb_init(void)//初始化化returnusb_register(&btusb_driver); //注册设备驱动||static struct usb_device_id btusb_table[]//加载芯片设备参数||staticstruct usb_driver btusb_driver //填充file_operations结构体中操作函数.probe                = btusb_probe,||static intbtusb_probe(struct usb_interface *intf,const struct usb_device_id *id)err =hci_register_dev(hdev); //通过hci_register_dev函数向hci_core层注册接口||intbtusb_send_frame(struct hci_dev *hdev, struct sk_buff *skb)//发送数据数据包(帧)类型:1.HCI_ACLDATA_PKT:异步非连接,发送ACL数据包,给上层的L2CAP协议处理,放入connection的发送队列中,然后调度发送任务去发送。2. HCI_SCODATA_PKT:同步面向连接,发送SCO数据包,给上层的SCO协议处理放入connection的发送队列中,然后调度发送任务去发送。3. HCI_COMMAND_PKT:用于处理一些通信事件,比如连接建立,连接断开,认证和加密等事件,这些事件控制协议状态的改变。||static void btusb_notify(structhci_dev *hdev, unsigned int evt)//通过中断接受数据struct btusb_data *data =GET_DRV_DATA(hdev);//负责接收数据的任务,它从队列中取数据,然后根据数据的类型调用上层函数处理static voidbtusb_intr_complete(struct urb *urb)               ||static int btusb_probe(structusb_interface *intf,const struct usb_device_id *id)hdev->open= btusb_open;||static int btusb_open(struct hci_dev *hdev)||void rtk_usb_coex_open(struct hci_dev *hdev)//蓝牙匹配  INIT_DELAYED_WORK(&usb_coex_info.fw_work,(void *)rtk_parse_event_data);||static void rtk_parse_event_data(void)         u8*p = usb_coex_info.urb->transfer_buffer;         u8event_code = *p++;         switch(event_code)    caseHCI_EV_LE_META:       rtk_handle_le_meta_evt(p);||static void rtk_handle_le_meta_evt(u8* p)// 监听读取notifications时需要handle握手    u8sub_event = *p++;switch(sub_event)    case HCI_EV_LE_CONN_UPDATE_COMPLETE:       rtk_handle_le_connection_update_complete_evt(p);||static voidrtk_handle_le_connection_update_complete_evt(u8* p) //判断是否断开连接 status = *p++;STREAM_TO_UINT16(interval, p);update_hid_active_state(handle,interval);||static voidupdate_hid_active_state(uint16_t handle, uint16_t interval)//Profile是蓝牙设备间数据通信的无线接口规范,与硬件相关(判断向应用层传数据)         if(interval< 60) {                   if((phci_conn->profile_bitmap&(BIT(profile_hid_interval))) == 0) {                            need_update= 1;                            phci_conn->profile_bitmap|= BIT(profile_hid_interval);                             usb_coex_info.profile_refcount[profile_hid_interval]++;                            if(usb_coex_info.profile_refcount[profile_hid_interval]== 1)                                     usb_coex_info.profile_status|= BIT(profile_hid);                                                       RTKBT_DBG("update_hid_active_stateprofile_hid");                   }  ||//读取rtl8821cu_fw参数配置static int btusb_probe(struct usb_interface*intf, const struct usb_device_id *id)err = patch_add(intf);||int patch_add(struct usb_interface* intf)||patch_info* get_patch_entry(struct usb_device*udev)patch_entry = fw_patch_table;||static patch_info fw_patch_table[]||返回到btusb_probe函数进入hdev->open= btusb_open;||static int btusb_open(struct hci_dev *hdev)加载||int download_patch(struct usb_interface* intf)||int get_firmware(xchange_data* xdata)||int load_firmware(dev_data* dev_entry, uint8_t**buff)rtk_parse_config_file(config_file_buf,&config_len, vnd_local_bd_addr);rtk_get_patch_entry(epatch_buf,¤t_entry);ret_val= request_firmware(&fw, fw_name, &udev->dev);然后在hdev->open 的时候,在btusb_open中进行fw下载和参数配置的工作,这时蓝牙就可以正常工作了。下载的fw和配置文件通过内核的request_firmware函数获取,对于需要获取的文件,只需要提供文件名,该函数会自动搜索系统部分路径,其中就包含“/lib/firmware/,所以只要把fw及配置文件放到“/lib/firmware/”目录下即可。同时usb保证了传输的可靠性,所以也不需要h4、h5协议了(在初始化的时候,由hciattach使用串口,初始化完成后,把串口切换给hci使用,hci负责与串口交互蓝牙数据,中间还经过了h4/h5协议层,驱动层跟移植相关只有h4/h5协议,相同的id号通信)。

1、查找USB蓝牙设备两个PID、VID:


2、在驱动代码rtk_bt.c 的1952行遍历 fw_patch_table ,pid =0xc820  在1686行的蓝牙配置文
件:rtl8821cu_fw, rtl8821cu_config时,发现错误“get_patch_entry =NULL, can not find device pid in patch_table”;
原因在1928行出现pid!=patch_entry->prod_id,但是fw_patch_table表里是有0xc820的蓝牙配置文件:rtl8821cu_fw, rtl8821cu_config的。
通过命令“# grep 820 ./ -nr”发现rtk_8821btusb.ko找不到“820”信息:


3、rtk_bt.c 的1952行 fw_patch_table表里是有pid = 0xc820的蓝牙配置文件:rtl8821cu_fw,rtl8821cu_config,我们在lib/firmware换了海思提供的的rtl8821cu_fw文件,驱动可以加载insmod但是在读取的rtl8821cu_fw信息时出错:(如下图),所以可以确定6221E-UUC模块的rtl8821cu_fw文件信息不匹配,导致驱动读取错误,升级一下固件rtl8821cu_fw文件:


4、加载RTL8821驱动,正常log信息:


四、蓝牙连接方法:

            

 

连接成功

连接失败

内核

12

0

应用层

1

0

 


五、蓝牙电源的管理

通过LightBlue蓝牙调试工具:蓝牙是一直有电的并且开机时就打开,关闭蓝牙的时候把蓝牙断电。

 

六、交叉编译蓝牙BlueZ协议栈

参考博客:基于RTL8723 低功耗蓝牙协议栈BlueZ5.44 http://blog.csdn.net/u010872301/article/details/72511092

  

七、问题分析

问题1:反复连接:

一是应用层gatttool连接:“Characteristic Write Requestfailed”

characteristic特征值,ble主从机的通信均是通过characteristic来实现,可以理解为一个标签,通过这个标签可以获取或者写入想要的内容。低功耗蓝牙具有节能休眠机制,减少了电量的消耗,导致ble主从机连接超时status不稳定。不能实时向标签characteristic获取或者写入内容。(./gatttool68 -b80:EA:CA:01:00:01 --char-write-req -a0x0026-n0100  --listen)

查看设备特征值流程:

#./gatttool-b 80:EA:CA:01:00:56 –I

>connect  //连接低功耗设备

>characteristics  //查看设备特征值

handle:0x0015, char properties: 0x02, char valuehandle:0x0016, uuid:00002a26-0000-1000-8000-00805f9b34fb

 

二是驱动层连接:command timeout

连接超时command timeout,USB设备驱动接收不到urb结构体的通信信息,导致调用hci_recv_fragment接口提交数据到transfer_buffer为0,所以interval就被赋值为0;

staticvoid rtk_parse_event_data(void)

u8*p = usb_coex_info.urb->transfer_buffer;

||

rtk_usb_coexistence_infousb_coex_info;

||

staticvoid rtk_handle_le_connection_update_complete_evt(u8* p)

STREAM_TO_UINT16(interval, p);

 

问题2:第一次连接稳定后,异常断开出现连接断断续续的接受数据:(驱动层红色字体),

因为蓝牙驱动接收不到数据Interval =0,连接多次后出现Interval = 0xC接收一组或二组数据,Interval =0蓝牙断开,重复连接。

——————————————————————————

Characteristicvalue was written successfully

rtk_btusb:update_hid_active_state: handle = 10, interval = 0xc

-----------------update_hid_active_statebuf=12

rtk_btusb:--------rtk_handle_le_connection_update_complete_evt: handle = 10, interval =0xc

rtk_btusb:rtk_handle_le_connection_update_complete_evt

00000000000000buf=12

helloenter/nread: 12/n

rtk_btusb:-----rtk_handle_le_meta_evt

00000000000000flag_kernal=0

-------events_handler---01--

-------events_handler---02--

temp1=28,humi1=36

updatebt data:update TemperatureRegister set command_temperature = 28 ,command_humidity = 36             wheredevice_port = 'bluetooth';

ij:1

—————————————————————————

连接上后稳定接受数据;

解决方案:因为RTL 8723BU不支持低功耗4.1蓝牙设备数据接收温湿度数据,更换硬件RTL8821CU芯片。

因为函数(static void events_handler (const uint8_t *pdu, uint16_t len,gpointer user_data) )中接收数据不稳定,不在gatttool.c的接受温湿度数据

做写文件判断连接,所以只放在蓝牙驱动函数(static void rtk_handle_le_connection_update_complete_evt(u8* p))连接做判断,在断开后添加复位函数数据

intbtusb_resume(struct usb_interface *intf),再使用Kill -2 功能类似于Ctrl+ C 是程序在结束之前,能够保存相关数据,然后再退出。

#include #include //80:EA:CA:01:00:01int main(){FILE *inkernal;int flag_kernal = 0;char array[1];if ((inkernal = fopen("kernel_file","w+")) == NULL) {printf("canot find the test_txt file!\n");return;}while(1){system("./gatttool68 -b 80:EA:CA:01:00:01 --char-write-req -a 0x0026 -n 0100  --listen &");sleep(2);fscanf(inkernal,"%d",&flag_kernal);//printf("00000000000000flag_kernal=%d\n",flag_kernal);while(flag_kernal == 12){sleep(1);#if 0    sleep(10);    //system("./hciconfig hci0 down");system("rmmod /mnt/zxwork/ngb_w_nw3100/HiSTBLinuxV100R005C00SPC041/software/HiSTBLinuxV100R005C00SPC041/out/hi3798cv200/hi3798cv2dmo/kmod/rtk_8821btusb.ko");sleep(1);system("insmod /mnt/zxwork/ngb_w_nw3100/HiSTBLinuxV100R005C00SPC041/software/HiSTBLinuxV100R005C00SPC041/out/hi3798cv200/hi3798cv2dmo/kmod/rtk_8821btusb.ko");sleep(1);//system("./hciconfig hci0 up");system("./bluez_init");#endifflag_kernal = 0;fprintf(inkernal,"%d",flag_kernal);break;}system("kill -2 `ps -w | grep -v grep | grep gatttool68 | awk '{print $1}'`");sleep(1);//printf("8882 flag=%d\n",flag);}fclose(inkernal); return 0;}
 


在linux内核中读写文件:

我们注意到在vfs_read和vfs_write函数中,其参数buf指向的用户空间的内存地址,如果我们直接使用内核空间的指针,则会返回-EFALUT。所以我们需要使用

set_fs()和get_fs()宏来改变内核对内存地址检查并做变换。最后的参数loff_t * pos,pos所指向的值要初始化,表明从文件的什么地方开始读写。所以在内核空间对文件的读写流程为:

1)mm_segment_t fs =get_fs();

2)set_fs(KERNEL_DS);

3)vfs_write();

4)vfs_read();

5)set_fs(fs);


八、项目总结
1、硬件和软件开发环境平台、及开发版本型号
1)接受方蓝牙设备:
第一版本:RTL 8723BU
第二版本:RTL8821CU
2)发送方蓝牙设备:DA14580的MN581A蓝牙模块、SHT21(I2C总线)温室度数据
3)接受方蓝牙设备开发平台:海思Hi3798C V200
2、实现功能
1)扫描到低功耗蓝牙4.1设备后,连接,然后接受温湿度数据,保存到数据库。
2)蓝牙连接断开后,可以重新连接。
3、开发工具:蓝牙BlueZ协议栈的工具集gattttool工具和hcitool工具
4、功能需要改进的地方
1)蓝牙连接后,稳定接受温室度数据,但后台会继续连接,如果断开依然会重新连接,最初程序设计是在
while(flag_kernal == 12)中接受温湿度数据,断口后跳出循环,再重新连接。

2)持续接受温湿度数据占用USB蓝牙接口,导致gatttool重复连接时出现“connect: Device or resource busy (16)”。

3)连接时间平均3次*3s=9s/次,如果发送方蓝牙设备不断电,数据接受稳定。4)在交互模式下,connect连接,稍等片刻,双方达成参数一致后,即interval=12时,再向连接设备中写入数据char-write-cmd 0x0026 0100 ,此时数据接受稳定。这也是非交互模式下需要多连接几次的原因。
下载linux Realtek rtl8821CU驱动及固件:http://download.csdn.net/download/u010872301/10048600
参考博客基于BlueZ5.44协议栈的RTL8723 BLE蓝牙连接(一)http://blog.csdn.net/u010872301/article/details/72511092Ubuntu系统(bluez)蓝牙调试http://blog.csdn.net/zjli321/article/details/52122447