如何用BlueZ MGMT接口实现Ble Slave

一,关于MGMT接口

1,为什么有MGMT接口

In short, it’s a new interface for user space Bluetooth components (like bluetoothd) to talk to the kernel and it aims to replace the existing raw HCI sockets.

关于这部分信息可以访问:http://www.bluez.org/the-management-interface/
同样,bluez的获取方式如下:

git clone https://git.buildroot.net/buildroot
git clone git://git.buildroot.net/buildroot
2,为什么要用MGMT接口

对于我们嵌入式软件开发而言,大致可以归纳为一下几点:

1,很重要的一点,占用资源少。(实测Dbus环境动态库接近2M,bin接近1M,还是strip之后的。对于flash很小的设备而言内存占用压力很大,而用MGMT加起来不到1M)
2,便于纠错,直接和kernel通信的接口,避免过多的进程间交互,导致问题出来,不需要花大量时间纠错。(也是避免了内核与用户空间没有冲突的风险)
3,剩下的优点不提了,对于我当前简单实现ble slave,单点连接设备而言,用的比较少。
// 感兴趣可以看一下,来自官方blog
Command queues and synchronization
Since the kernel is now responsible for all HCI traffic there’s no risk of conflicts between kernel and userspace.Blocking operations
With the management interface there are simple asynchronous messages that are used to power on and off adapters: blocking problem solved.Unnecessary HCI event processing
No raw HCI sockets means no promisc flag on the kernel side. So extra processing of these packets isn’t needed anymore.Distributed security policy and logic
With the management interface only user interaction (PIN code/pass key requests, etc) and link key storage is handled on the user space side. User space will feed the kernel with all stored link keys, including the key types, upon adapter initialization. After that the kernel is responsible for handling link key requests.An additional benefit with having an abstracted interface for security is that it can be used for the Security Manager Protocol (SMP) that’s part of the Bluetooth Low Energy (LE) specification. SMP has a similar user interaction model as SSP so the same messages between user space and the kernel can be reused.As long as SMP is implemented on the kernel side there’d be a big problem with dealing with it from user space using the existing kernel interface since unlike SSP, SMP uses L2CAP and not HCI for messaging.Lack of early-tracing capability
The management interface will offer a special type of tracing socket which can be used to get the HCI traffic of all connected adapters. This will allow a userspace process to catch all traffic to and from an adapter from the first moment that it is plugged in.

二,如何用MGMT实现ble slave。

1,大致思路以及需要熟悉的接口文件。(本来不想跟网上一样多BB的,上来写代码的,但是一想,这个“渔”对于写代码还是很重要的。)
思路如下:
[1]  如何实现开关蓝牙.
[2]  如何实现广播,包含广播包和响应包的设定,以及广播参数设定等等。
[3]  如何实现GATT连接.
[4]  如何实现服务注册,即收发数据.
[5]  如何实现状态通知,包含连接成功,断开成功,timeout,terminate等等.
[6]  如何实现更新连接参数,连接间隔设定等等。需要指出,以上几点可归纳为如何两个文件以及kernel中node的设定等等。
[1][2]      -->bluez-5.5x\tools\btmgmt.c[3][4][5]   -->bluez-5.5x\tools\btgatt-server.c[6]         -->部分可从btmgmt.c中获取,剩下部分可参考如下:
// 仅供参考:
cat /sys/kernel/debug/bluetooth/hci0/
adv_channel_map                conn_latency                   dut_mode                       identity_resolving_keys        quirk_strict_duplicate_filter  ssp_debug_mode                 white_list_size
adv_max_interval               conn_max_interval              features                       idle_timeout                   random_address                 static_address
adv_min_interval               conn_min_interval              force_static_address           inquiry_cache                  remote_oob                     supervision_timeout
auto_accept_delay              dev_class                      hardware_error                 link_keys                      rpa_timeout                    use_debug_keys
blacklist                      device_id                      hci_revision                   long_term_keys                 sc_only_mode                   uuids
conn_info_max_age              device_list                    hci_version                    manufacturer                   sniff_max_interval             voice_setting
conn_info_min_age              discov_interleaved_timeout     identity                       quirk_simultaneous_discovery   sniff_min_interval             white_list
2,接口文件解释
[1] 如何实现开关蓝牙.

[2] 如何实现广播,包含广播包和响应包的设定,以及广播参数设定等等。


// node可以修改部分参数

[3] 如何实现GATT连接.
[4] 如何实现服务注册,即收发数据.

BlueZ提供了两份实例关于ble master以及ble slave。
其中ble slave对应上btgatt-server.c; ble master对应上btgatt-client.c

A.设定设备类型

B.设定GATT参数以及characteristic,同时注册回调

[5] 如何实现状态通知,包含连接成功,断开成功,timeout,terminate等等.
A,在设定状态等等之前,我们需要监听所有信息。

B,状态上报

[6] 如何实现更新连接参数,连接间隔设定等等。

关于更新连接参数以及连接间隔等操作,需要操作node,对应裸板实现时,需要把bluetooth的node引出,对其写操作
这部分不详述

三,如何用代码和MGMT接口实现ble slave。

1,在实现之前,我们需要理解使用socketpair实现双向通讯。实现线程间通信。


示例代码如下(以Btmgmt为例):

// 初始化如下:
void* mgmt_ble_init(MGMT_CBS *cbs)
{int sockets[2];int result;int bufferSize = SOCKET_BUFFER_SIZE;result = socketpair(AF_UNIX, SOCK_SEQPACKET, 0, sockets);if (-1 == result) {printf("socketpair error!\n");return NULL;}struct timeval mgmt_timeout;memset(&mgmt_timeout, 0x0, sizeof(mgmt_timeout));mgmt_timeout.tv_sec  = 10;mgmt_timeout.tv_usec = 0;if(setsockopt(sockets[0], SOL_SOCKET, SO_SNDTIMEO, (void *)&mgmt_timeout, sizeof(mgmt_timeout)) == -1) {printf("setsockopt: unable to set SO_RCVTIMEO");goto failed2;}if(setsockopt(sockets[1], SOL_SOCKET, SO_SNDTIMEO, (void *)&mgmt_timeout, sizeof(mgmt_timeout)) == -1) {printf("setsockopt: unable to set SO_RCVTIMEO");goto failed2;}setsockopt(sockets[0], SOL_SOCKET, SO_SNDBUF, &bufferSize, sizeof(bufferSize));setsockopt(sockets[0], SOL_SOCKET, SO_RCVBUF, &bufferSize, sizeof(bufferSize));setsockopt(sockets[1], SOL_SOCKET, SO_SNDBUF, &bufferSize, sizeof(bufferSize));setsockopt(sockets[1], SOL_SOCKET, SO_RCVBUF, &bufferSize, sizeof(bufferSize));struct mgmt_ble_com *hdl = NULL;hdl = (struct mgmt_ble_com*)malloc(sizeof(struct mgmt_ble_com));if (hdl == NULL) {printf("malloc failed\n");goto failed2;}hdl->msock[0] = sockets[0];hdl->msock[1] = sockets[1];memcpy(&hdl->cbs, cbs, sizeof(MGMT_CBS));pthread_attr_t attr;pthread_attr_init(&attr);pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);pthread_attr_setstacksize(&attr, 1024 * 1024);pthread_t mgmt_ble_thread = 0;if (pthread_create(&mgmt_ble_thread, &attr, mgmt_ble_process, hdl) != 0) {printf("cannot create mgmt server thread!\n");goto failed1;}pthread_t mgmt_rsp_thread = 0;if (pthread_create(&mgmt_rsp_thread, &attr, mgmt_ble_rsp, hdl) != 0) {printf("cannot create mgmt client thread!\n");goto failed1;}pthread_attr_destroy(&attr);return hdl;failed1:pthread_attr_destroy(&attr);free(hdl);failed2:printf("closing socket(%d), socket(%d)\n", sockets[0], sockets[1]);close(sockets[0]);close(sockets[1]);return NULL;
}// 双向缓冲buffer如下:
void *mgmt_ble_rsp(void *arg)
{unsigned char buf[BUFFER_SIZE] = {0};struct mgmt_ble_com *phdl = arg;int ret = -1;fd_set rdfds;struct timeval timeout;prctl(PR_SET_NAME, "mgmg-handle rsp");while(1) {FD_ZERO(&rdfds);FD_SET(phdl->msock[0], &rdfds);timeout.tv_sec  = 3;timeout.tv_usec = 0;if (phdl->m_num == 0) {(phdl->m_num)++;}ret = select(phdl->msock[0] + 1, &rdfds, NULL, NULL, &timeout);if (ret == 0) {//printf("select timeout\n");continue;} else if (ret < 0) {printf("select error, need to do something...\n");break;}if (FD_ISSET(phdl->msock[0], &rdfds)) {ret = read(phdl->msock[0], buf, BUFFER_SIZE);if (ret < 0) {printf("recv error...\n");break;}  else if(ret == 0) {printf("read zero\n");break;}buf[ret] = '\0';if (mgmt_ble_resp_data(phdl, buf, ret)) {printf("exit mgmt thread\n");break;}}}close(phdl->msock[0]);close(phdl->msock[1]);free(phdl);return NULL;
}
2,操作蓝牙开关以及广播。
// 通过写操作,对端接收信息并处理事件
int ble_mgmt_power(int index,void *bt_hdl, int onoff)
{struct mgmt_ble_com *hdl = bt_hdl;if (hdl == NULL) {printf("bt handle is null\n");return -1;}char *cmd = onoff?"power on":"power off";if (write(hdl->msock[0], cmd, strlen(cmd)) <= 0) {printf("(%d) send failed: %d %s\n",hdl->msock[0], errno, strerror(errno));return -1;}return 0;
}// 发送广播信息
int ble_mgmt_adv(int index,void *bt_hdl, tuya_ble_mgmt_adv_data_t *adv, tuya_ble_mgmt_rsp_data_t *rsp)
{struct mgmt_ble_com *hdl = bt_hdl;char cmd[256] = {0};if (hdl == NULL) {printf("bt handle is null\n");return -1;}if((adv->data == NULL)||(adv->len == 0)||(rsp->data == NULL)||(rsp->len == 0)) {return -2;}else {snprintf(cmd, sizeof(cmd), "add-adv -c -d %.*s -s %.*s %.*d", adv->len * 2,adv->str,rsp->len * 2,rsp->str,1,instance_id);}if (write(hdl->msock[0], cmd, strlen(cmd)) <= 0) {printf("(%d) send failed: %d %s\n",hdl->msock[0], errno, strerror(errno));return -3;}return 0;
}
3,如何写操作。
A, 对于btgatt-server初始化部分如上述相同方式。我们直接贴上如何操作写数据
// 写数据
int ble_gatt_set_value(void *bt_hdl, unsigned char *data, int len)
{ struct mgmt_ble_com *hdl = bt_hdl;char cmd[512] = {0};int i, size;int j = 0;if (hdl == NULL) {printf("bt handle is null\n");return -1;}if(hdl->common_handle == 0) {printf("error handle id for this notify");return -1;}snprintf(cmd, sizeof(cmd), "notify 0x%04x ", hdl->common_handle);size = strlen(cmd);for (i = 0; i < len; i++) {snprintf(cmd+size+j, sizeof(cmd), "%02x ", data[i]);j=j+3;}if (ble_gatt_send_cmd(hdl, cmd) < 0)return -1;return 0;
}
4,实现效果.
A,先跑起来

B,实现透传

C, 对应上手机端

【BlueZ5】 如何用MGMT接口实现ble slave相关推荐

  1. MGMT接口采集服务器IMM日志

    X3850 x5 PC server上有system MGMT口,可用普通网线连接普通台式机网口, 默认IP 192.168.70.125,用户名/密码:USERID/PASSW0RD(注意passw ...

  2. netlink怎么读_如何用netlink接口读取内核路由表

    展开全部 获取内核路由62616964757a686964616fe58685e5aeb931333335343937表以及操作内核路由表有几种方法:读proc 或者用ioctl(sock_fd, S ...

  3. 如何用API接口获取拼多多商品详情?

    API (Application Programming Interface) :应用程序编程接口 今天给大家带来获取拼多多商品详情的方法: 一.注册账号 API网站注册后最重要的个人数据是请求key ...

  4. 如何用CTP接口开发自己的交易系统?(二)

    本文开始先说说CTP给开发者提供了什么.CTP提供给开发者的文件一共有4个头文件 ThostFtdcTraderApi.h,ThostFtdcMdApi.h, ThostFtdcUserApiStru ...

  5. 如何用API接口获得淘宝商品详情数据

    首先了解下API的定义 1.API是什么? API应用程序接口(API:application programming interface),是一组定义.程序及协议的集合,通过API接口实现计算机软件 ...

  6. 如何用VGA接口乳法?

    1.什么是VGA接口 1.1.VGA接口介绍 VGA,英文全称"Video Graphics Array",译为视频图形阵列,是一种使用模拟信号进行视频传输的标准协议,由 IBM ...

  7. 【BlueZ】【蓝牙】跨平台实现Ble MasterSlaveMesh 之Linux篇-1

    一,前述 1,上一篇讲述了如何通过Windows实现蓝牙应用,该方式可适用于Windows/Linux/Macos等场景.[https://blog.csdn.net/u014028690/artic ...

  8. 如何抓包分析BLE 空口报文(GAP + GATT + LESC procedure)?

    文章目录 一.如何抓取BLE 空口报文? 二.BLE 通信报文是如何交互的? 2.1 GAP Discovery and Connection establishment procedures 2.2 ...

  9. Android的BLE广播数据包介绍和解析---BLE--Android系列, 蓝牙技术BLE

    目录 一.引言 二.广播的类型 三.广播数据格式 四.广播数据解析 五.总结 一.引言 理解和分析这个数据包结构(这里面也涉及广播间隔时间的设置,设备广播数据间隔设置长了,会影响设备被发现的效率:设置 ...

  10. 轻松易懂arduino低功耗BLE蓝牙通信

    今天我们介绍蓝牙通信的另一种方式--BLE(Bluetooth Low Energy,蓝牙低功耗).         什么是BLE         在<无线通信3:HC05/HC06经典蓝牙BT ...

最新文章

  1. WhatsApp与Gmail用户数均突破10亿大关
  2. Py之demjson:Python库之demjson的简介、安装、使用方法详细攻略
  3. tensorflow 加载bert_用NodeJS/TensorFlowJS调用BERT实现文本分类
  4. 子空间:群论的角度解释无监督深度学习
  5. MVC与三层架构区别
  6. html表情选择器,原生JS写的emoji表情选择器
  7. python调用.a静态库_Python 调用 C
  8. mysql 主从_搭建mysql主从并编写监控主从状态脚本
  9. bootstrap轮播图 原点变为方块_Brother兄弟机床原点设定方法
  10. [转] css3变形属性transform
  11. MySql 中的 int(11) 到底代表什么意思?
  12. 30 岁成 AI 顶尖科学家,这位阿里副总裁厉害了
  13. Linux装gcc经过
  14. paip.截屏功能流程说明
  15. 群辉做无盘服务器,累了,最后的福利:NAS做家用无盘近完美资源包
  16. 水逆期自我救赎:MacBook pro进水
  17. 关于T检验的各种问题
  18. T3677 道生一——dfs
  19. Linux下使用Intel_WiFi_Link_5100AGN 破解无线加密
  20. iOS获取高德地图实现持续定位功能

热门文章

  1. Enchanted —— Taylor Swift
  2. 联想g400从u盘启动计算机,【联想G40怎么从U盘启动】联想g40怎么设置u启动_联想g40从u盘启动...
  3. 混凝土塔吊浇筑怎么计算机械费,秒懂塔吊和施工电梯费用的摊销成本测算~
  4. java gui 做闹钟,用JAVA怎样编写一个可以在eclipse中运行的闹钟程序?
  5. C语言知识点--define的替换列表为空是怎么回事?
  6. 用python编译linux内核,戴子轩/RK3399上编译linux-kernel
  7. 详细介绍 Yolov5 转 ONNX模型 + 使用ONNX Runtime 的 Python 部署(包含官方文档的介绍)
  8. HTML、css、js 特殊字符(空格符号)
  9. 现代公司制度的法理学基础 (贾登勋 王勇)
  10. 本地电脑没有虚拟机网卡vm8