csr867x入门之gatt使用(五)
简述
目前的adk中只有电池,心率等几个固定的gatt服务,所以如果要实现自定义的数据收发,需要再自定义一个gatt服务
使能BLE/GATT功能
首先要在config中使能gatt,如下图所示:
添加gatt服务及属性
csr adk通过gatt_custom_server_db.dbi文件,然后利用工具生成对应的gatt服务数据表,在将该服务添加一个gatt服务列表中。通常来说嵌入式设备都是作为服务器(外设设备)存在,向客户端(中心设备)提供数据,.dbi文件如下:
primary_service {uuid : UUID_CUSTOM_SERVICE,name : "CUSTOM_FIRST_SERVICE",characteristic {uuid : UUID_CUSTOM_CHARA_WRITE,name : "WRITE",flags : [ FLAG_IRQ ],properties : [ write_cmd ],size_value : 0x14},characteristic {uuid : UUID_CUSTOM_CHARA_READ,name : "READ",flags : [ FLAG_IRQ ],properties : [ notify ],size_value : 0x14,client_config{name : "CUSTOM_CCC",flags : [ FLAG_IRQ , FLAG_DYNLEN ]}},characteristic {uuid : UUID_CUSTOM_CHARA_FLOW_CTL,name : "FLOW_CTL",flags : [ FLAG_IRQ ],properties : [ notify ],value : 0x0}
},
.dbi文件在编译中会转成相应的.c与.h文件,具体可以参考battery与heartrate对应的dbi文件。上面的dbi中,我定义了一个custom 服务,服务中包含三个character,第一个用于从手机读取,第二个用于向手机发送数据,第三个是流控。
Gatt数据发送
因为我们使用的数据发送的模型是notify,所以数据的发送需要调用一下接口GattNotificationRequest()。需要注意的是cid(channel id)参数,在这里我选择的是第一个gatt连接的cid,theSink.rundata->ble.gatt[0].cid,当有多个连接时,需要注意参数选择;还有handle参数,一定要与我们custom服务中相应的handle的UUID匹配
下面是我通过串口工具发送的指令到开发板,指令解析之后,将我要发送的数据通过蓝牙发送出去
void handleGattSendData(Task t, const struct GattSendData *send_data)
{uint16 index = 0;uint16 custom_cid = theSink.rundata->ble.gatt[index].cid;if(stateManagerGetState() > deviceConnDiscoverable){GattNotificationRequest(sinkGetBleTask(), custom_cid, HANDLE_READ, send_data->data.length, send_data->data.data);UartSendStr("OK\r\n");}else{UartSendStr("ERROR\r\n");}
}
Gatt数据接收
当底层收到数据之后,会发送给sinkGattManagerMsgHandler()进行消息处理,我们的server的消息将会包含在GATT_MANAGER_SERVER_ACCESS_IND中,原始的adk没有关于这块的数据处理,这里我参加了一个接口去打印gatt的数据
static gatt_status_t custom_gatt_data_handle(void *msg)
{uint16 flags,handle;gatt_status_t status = gatt_status_success;GATT_MANAGER_SERVER_ACCESS_IND_T *pMsg = (GATT_MANAGER_SERVER_ACCESS_IND_T *)msg;flags = pMsg->flags;handle = pMsg->handle;if (flags == (ATT_ACCESS_PERMISSION | ATT_ACCESS_WRITE_COMPLETE | ATT_ACCESS_WRITE)) {if (handle == HANDLE_WRITE) {UartSendStr("+GATTDATA:");UartSendData(pMsg->value, pMsg->size_value);UartSendStr("\r\n");} else if (handle == HANDLE_CUSTOM_CCC) {} else{status = gatt_status_write_not_permitted;}} else if (flags == (ATT_ACCESS_PERMISSION | ATT_ACCESS_READ)) {}return status;
}
Ble广播数据添加
如果想要在广播数据中包含自定义的服务的uuid等信息,需要在这里添加ble的服务数据
static void updateServicesAdData(uint8* ad_data_ptr, uint16 *counter_ptr , uint16 num_services)
{if (num_services){BLE_AD_INFO(("Custom Service"));ad_data_ptr[*counter_ptr] = (0x00 & 0xFF);(*counter_ptr)++;ad_data_ptr[*counter_ptr] = (0xFF >> 8);(*counter_ptr)++;num_services--;}
}
上面我只贴出了部分代码,详细源码及相关的工具资料等,请到我的博客<csr867x入门笔记(序)>最下面的网盘链接或者github链接中下载。
csr867x入门之gatt使用(五)相关推荐
- csr867x入门笔记(序)
本专栏的主要内容是csr867x的入门使用,主要包括环境搭建及体验,串口调试,at指令协议添加,各个蓝牙协议的使用等,最终这些例程会加入到adk里面,adk主要是基于4.1版本. 我也会把相关的资料放 ...
- 【OpenCV入门指南】第五篇轮廓检测 下
上一篇<[OpenCV入门指南]第五篇轮廓检测上>介绍了cvFindContours函数和cvDrawContours函数,并作了一个简单的使用示范.本篇将展示一个实例,让大家对轮廓检测有 ...
- VUE—从入门到飞起(五)
目录 路由 路由基本使用 路由规则中定义参数 路由嵌套 命名视图实现经典布局 VUE-从入门到飞起(一) VUE-从入门到飞起(二) VUE-从入门到飞起(三) VUE-从入门到飞起(四) VUE-从 ...
- GPU 编程入门到精通(五)之 GPU 程序优化进阶
版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[+] 博主由于工作当中的需要,开始学习 GPU 上面的编程,主要涉及到的是基于 GPU 的深度学习方面的知识,鉴于之前没有接触过 GP ...
- 《假如编程是魔法之零基础看得懂的Python入门教程 》——(五)我的魔法竟然有了一丝逻辑
学习目标 了解魔法世界中的结构表现--缩进 了解魔法世界的逻辑判断--if 了解魔法世界的多次逻辑判断--ifelse嵌套 了解魔法世界中的逻辑运算--且 and 与或 or 推荐 1.<备受好 ...
- html5游戏制作入门系列教程(五)
我们继续这一系列文章,使用HTML5的canvas组件进行游戏开发.今天,这是相当完整的游戏例子 – 它会回顾经典的旧电脑游戏 – 坦克大战.我会教你使用阵列地图并教你如何检测活动对象(坦克)与环境( ...
- Python编程从入门到实践第五章部分习题
Python编程从入门到实践第五章部分习题 5-8 5-9` names = ['admin','zhang','li','zhao','song'] for name in names:if nam ...
- csr867x入门之按键配置(九)
目录 简介 配置按键触发条件 io口配置 将按键事件对应到用户事件 触发逻辑电平反转 简介 Csr支持通过ADKConfigTool.exe配置按键,给实际的开发提供了很大的方便! 打开配置工具,连接 ...
- csr867x入门之iis使用(八)
目录 Csr iis接口简介 用configuration tool设置iis模式 程序运行中的iis与analog切换 Csr iis接口简介 其iis有四根线:采样率(帧时钟).位时钟.数据输出, ...
最新文章
- 通俗理解tf.name_scope()、tf.variable_scope()
- 模板特化,全特化,偏特化,全部特化,部分特化的含义
- Understanding SOAP
- 把二元查找树转变成排序的双向链表(树)
- Hmac - Java加密与安全
- 同时运行两个PHP吗,PHP-避免由两个工作人员同时运行后台作业
- 如何使用LVM逻辑卷
- Python各类图像库的图片读写方式总结
- 文本生成系列之transformer结构扩展(二)
- 彼得林奇:赚钱密码(1990年一次演讲)
- @EnableWebMvc引发的swagger-ui.html的灾难
- MikroTik RouterOS U盘安装工具netinstall的使用
- Excel 做统计学分析
- Java开发一年经验北京薪资,全网首发!
- android9原生体验,原生安卓必备软件 优化类原生ROM体验
- 高德地图红绿灯读秒是怎么实现的?(一)
- 【转】Linux 虚拟内存
- Qt大屏电子看板系统源码基础版
- c# 计算圆锥的体积_用C#如何编写程序计算球,圆柱和圆锥的表面积和体积? 用C#编写方法并通过方法...
- 2019年记录:java小白级程序员工作一年以来的经历,遇到的坎坷以及当时的心态
热门文章
- 虚拟化技术之docker技术详解
- 使用iPhone来提醒自己-日历和提醒事项
- 【Java版oj】逆波兰表达式求值
- php手术要休息多久,囊肿切除后需要休息多久
- 手把手教你如何远程连接云服务器(图文教程)?
- 鸡蛋的吃法及营养价值
- 记录java.util.Collections.unmodifiableList()使用
- JVM-对象什么时候进入老年代(实战篇)
- AttributeError: module 'easygui' has no attribute 'msgbox'错误
- 全志v3s学习笔记(8)——TF卡分区及烧录