-
nrf51822蓝牙学习笔记之GAP(通用属性配置文件)解读(二)
2016-11-20 14:56:13BLE的应用本质就是用来传输数据,而数据的传输最终利用就是属性条目中的属性值。... 因为服务器中的数据库本质上都是一条条属性条目,但是每个属性条目都具有自己的意义,像是前面说的用来声明一个服务的属性条目,就称BLE的应用本质就是用来传输数据,而数据的传输最终利用就是属性条目中的属性值。通常我们所说的创建一个特性值,创建一个通道,本质上都是说的是属性条目中的这个属性值,因为数据的最底层传输传输就是通过这个属性值来进行。 即特性值指的是整个属性条目,它包括句柄,UUID,和属性值。 因为服务器中的数据库本质上都是一条条属性条目,但是每个属性条目都具有自己的意义,像是前面说的用来声明一个服务的属性条目,就称为服务声明。 那么这里说的本质上用来传输数据的属性值也是属于某个属性条目的。所以就称该属性条目整体为特性值,其句柄和UUID都是用来标示该属性条目,而其属性值就是用来真实传输的。
首先,进行服务声明,每个服务的属性列表的第一条数据(定义服务的uuid 0x2800),目的就是为了说明这个服务的UUID。
其次,就是创建一个特性值(定义特征值uuid 0x2803),我们利用的是其中的属性值来作为传输数据,这个”传输通道”有读,写,notify等性质, 以及相关的描述符等。然而一条属性条目肯定无法包含那么多信息。也就需要几条相关的属性条目来解释。 所以 围绕这个 特性值 相关的一组属性 就称为 特性, 特性有几条属性条目组成。 包括 特性声明属性条目,该属性条目描述 “传输通道”(特性值条目中的属性值)的读写以及notify等性质。 特性值属性条目,该条目就是用来最终传输的,利用其属性值传输。 特性描述符属性条目,包含该特性的附加信息和配置。
由上图讲解:一共定义了四个服务:1 2 3 4 ,
服务一:设备名服务 带一个特性。
服务二:什么也没做。
服务三: 电池电量服务 带一个特性。
服务四:温度服务 带有两个特性4-1,4-2。
-
蓝牙BLE GATT完全分析和运用
2016-02-26 20:34:10本文结合BLE的服务发现协议标准和DA14580平台、CC2541平台的应用实践来深入分析GATT,让大家能够自如地构建一个BLE的属性数据库。网上几乎没有类似这样对底层协议结构进行分析的文章,做蓝牙开发的童鞋要好好收藏。很多人都做过蓝牙开发,很多人也能够通过仿照GATT例程的方式添加一个属性服务,但是很多人都未必能够清晰地理解BLE的属性profile,也很容易被属性Attribute和特性characteristic所混淆。本文结合BLE的服务发现协议标准和DA14580平台、CC2541平台的应用实践来深入分析GATT,让大家能够自如地构建一个BLE的属性数据库。
更多蓝牙设备开发的经验原创总结敬请关注微信公众号:嵌入式企鹅圈。
一、 BLE GATT(Generic Attribute Profile)规范
1. GATT定义
GATT是低功耗蓝牙属性应用规范,应用于主机和从设备之间的数据传输。其与GAP并列为BLE两大profile。
Attribute是属性的意思。何为属性?在各蓝牙单芯片平台的SDK实际使用中,属性是指一条带有标签的、可以被寻址的数据。在蓝牙实际的规范中,寻址即用handle句柄来表示。每个属性都对应一个唯一的handle。
2. 对属性协议需求的思考
蓝牙是无线通信,BLE利用属性协议进行传输,其如此重要,如果我们不理解其需求,那么我们也很难从真正去理解其规范。尽管在实际的蓝牙单芯片SDK中很容易通过模仿的方法进行应用,但是如果想深入地理解其为什么要设计呢?
1)连接的参数是一个设备的固有参数,一般会作为一个服务来提供,如GAP服务;而假设这个设备是一个温度采集器,那么这个温度采集明显跟设备的参数不属于一类,因此可以再作为一个服务。所以属性协议应该支持多个服务。如何来区分这些不同的服务?这即对应蓝牙标准规范规定的UUID。我们可以认为不同的UUID对应不同的确定的服务。
2)连接的参数可以有多个,如Connection Interval、Slave Latency等等,我们如何区分这是一个服务,又如何区分服务包含了这些特性参数。我们可以认为一个服务包含了多个特性(参数)。在蓝牙标准里面,同样是用不同的UUID来区分服务类型、特性类型等等。
3)对于每个特性characteristic,要让对方获取这个特性,就必须要分别告诉对方这个特性的长度是多少,值是多少,而不能只给数值。除此之外,特性还可能有描述值(说明特性名称或者作用等)、特性单位等(国际单位,如米是公里/每小时还是米/秒)。后面这两个是非必选的。
4)属性还应该有一个访问控制,如可读可写还是读写、或者是通知notify/indicate等等,这是数据通信必须具有的权限控制,不管是服务还是特性,它都具有访问控制属性。
3. 属性和属性类型
属性由属性句柄、属性类型、属性值组成。如下图:
1) 属性句柄在实际的运用中可以认为是属性在属性数组中的下标。我们都知道在实际的编程中,下标并不需要专门存储,而只是通过元素的结构体来进行索引即可。因此可以认为属性句柄是一个无形的东西,它只能被所在的设备程序所认识,而不能用于无线传输。
2) 属性类型是真实存在的,其和属性值都会被实际存储。属性类型是由蓝牙标准组织所规范,其一般通过128位的UUID来表征一个具体的属性。由于BLE的GATT可以认为是蓝牙标准规范的精简版,所以BLE被允许只传输前面2字节(16位)的UUID,所有的BLE的UUID的基数都是一样的,如下,只有前面两字节不同。
利用2字节(16位)也可以定义65536种属性了。事实上,蓝牙标准组织对这些UUID进行了分类。如下:
属性类型即是0x2800~0x28ff,在实际的应用中,属性类型主要包括:我们主要使用服务和特性定义两种,其他两个很少用到。
3) 蓝牙标准不仅通过UUID来进行属性分类,而且还用UUID来确定各种具体的服务和特性。所以我们会看到UUID可能会出现在属性的属性类型和属性值两个地方。
4) 蓝牙标准组织规定两个ATT_DECL_PRIMARY_SERVICE服务之间的特性都隶属于第一个服务。这样可以理解在蓝牙服务发现协议中先通过UUID找到目标服务,然后通过ATT_DECL_PRIMARY_SERVICE这个属性类型找到下一个服务,接着即可以在这两个服务中进行特性的遍历,遍历的结果即是目标服务的所有特性。
4. 属性值
属性值的长度可以最长到512字节,但对于某些属性,其长度是固定的。对于蓝牙标准里面规定的UUID所对应的属性(包括服务、特性定义、特性值、特性描述等等),服务、特性定义的长度是确定的,而特性值则是不固定长度的。
所以,对于不同的属性,其属性值是不一样的。也即对于以上五类(通用服务、单位、属性类型、特性描述和区分特性类型)等属性,其属性值的规范是不一样,具体到不同的特性类型,其属性值也是不同的。
1)通用服务类通过唯一的UUID(0x1800~0x26ff)来标识一种明确的服务。好比,0x180f代表电池电量服务。
2)计量单位类通过唯一的UUID来标识一种单位。
3)区分属性类型类通过唯一的UUID来标识该属性是首要服务定义、次要服务、包含服务还是特性定义等。其好比程序中的变量的类型,是整型、字节型、还是确定的结构体。
4)特性描述类除了描述特性的名称、作用之外,还有一个非常重要的配置作用。例如如果提供的特性服务需要主动告知对方,那么对方就必须在连接时进行订阅配置。这样在该特性的数据值发生变更时能够主动地进行notify或者indicate。
5)区分特性类型用于用户定义不同的特性,用于区分该设备里面所有的特性。
5. 特性
把特性理解为一个程序中的一个变量是最好理解的。变量有变量类型和值,变量类型有int整型、字节型等等(其实就是变量的存储长度),值即具体的数值。相应地,而特性则有值和存储值的长度的概念。如同变量的声明和定义,特性characteristic也有声明和定义(赋值)的概念。
一般地,在蓝牙标准里面,特性一般包括三个要素:声明、数值和描述。前两者都是必须的。作为通信交互,一个特性必须要告诉对方声明(存储长度和访问控制)、定义(具体赋值)。在某些特性(如notify或者indicate)里面,特性还需要告知对方附加的配置属性(提供订阅等)。
特性声明必须作为服务属性之后的第一条属性,而数值必须紧随其后。
1) 特性声明
性质为一个8位字段,指示访问控制权限,包括读、写、notify或者indicate等。对于特性声明而言,其一般是只读的(这里只针对声明这条属性本身,而不是针对对应的特性数值)。数值句柄即用于直接寻址接下来的特性数值。其对于通信的对方是很有好处的,因为对方只需要记录该句柄即可在后续的访问中直接寻址,否则每次通信都要遍历。在实际的编程应用中,我们往往在初始化时填入0,代表由底层逻辑来自动更新该handle。而属性UUID和接下来的特性数值属性的区分特性类型值是一致的。
2)特性数值
特性数值也是一个属性,其属性类型填入特性声明的属性UUID。属性值要填入特性数值的访问权限、长度和数值。
3)特性描述
其可以是字符串表示的特性名称,或者是notify/indicate要求的配置等等。
二、对属性协议重要的理解原则
1)无论是服务还是特性,它们都是一条条属性;特性的各个要素也是一条条属性。只不过,不同的服务是独立的;而一个服务如果有多个特性,那么不同的特性也是独立的;一个特性包含的多条属性则是关联的。
2)对于蓝牙通信来说,其都是通过一个个不同的UUID来标识区分不同的服务,区分不同的特性,甚至服务/特性之间的类别。
3)对于各个蓝牙单芯片SDK平台,其上层应用对于属性协议的支持并不一致,它们只需要保证底层的蓝牙数据格式一致即可。
三、属性协议范例说明
例如一个电池服务包括一个特性(电池电量),那么其至少包括以下属性:首要服务定义(电池服务)、当前电量的特性定义(定义值长度)、当前电量的特性值。如果希望电池电量在低于某个水平时主动告知对方,那么这个电量特性值不仅应该是可读的,还应该是能够notify的。由于有主动告知,因此该特性还需要包括配置要素,用于对方来订阅。
1.对于电池服务这个属性,其属性类型是ATT_DECL_PRIMARY_SERVICE(0x2800),属性值是访问可读和蓝牙标准组织规定的0x180f(位于0x1800到0x26ff之间);
2.电池当前电量的特性定义这个属性,其属性类型是ATT_DECL_CHARACTERISTIC(0x2803),属性值是可读、特性值句柄和特性值的UUID(0x2A19)。
3.对于当前电量的特性值这个属性,其属性类型是0x2A19(0x2A00~0x7fff之间,区分特性类型),其用于区分多种不同的特性(如一个温度采集器可能要采集多个温度,这里就要用户通过不同的UUID来区分不同的特性了),属性值即访问控制(可读/indicate)、长度(1字节)、数值。
4.配置属性,用于notify的订阅配置。其属性类型是0x2902,属性值是可读/可写(要能写入订阅方的handle)、长度(2个字节)、handle值。
根据以上分析,我们来重构这个蓝牙的数据底层数据库。
四、DA14580平台SDK属性结构定义
1.单个属性定义
对于不同的属性,其length长度由value的类型来决定。例如服务的属性值对应的结构就是uint16_t;而特性声明的属性值对应的结构就是:
2.电池电量服务定义
五、CC254X平台SDK属性结构定义
1.单个属性定义
同样的,属性值pValue的数据结构由其对应的UUID来决定。例如服务属性的pValue对应的结构是gattAttrType_t(包括长度2和具体的服务UUID)。而特性声明的pValue对应的结构是一个字节的访问权限控制。特性数值的pValue对应的结构则是直接的变量定义,其可能是一个字节或者是字节数组,其长度由底层通过判断数组来决定。
2.电池电量服务定义
六、参考文献
1. BLE标准core_V4.0,英文规格书
2. 低功耗蓝牙开发权威指南,蓝牙标准起草人撰写,中译本。
如需要这两本电子书请关注微信公众号:嵌入式企鹅圈 之后发消息获取。
做蓝牙开发的童鞋们记得点赞啊,网上几乎没有类似这样对底层协议结构进行分析的文章,最多就是写写属性、服务、特性之类的定义,看了过眼就忘。这篇文章应该可以好好收藏,不记得的时候就翻出来看看:-)
更多嵌入式Linux和物联网原创技术总结敬请关注微信公众号:嵌入式企鹅圈
-
-
Android保存数据到系统数据库中:Settings.System
2021-01-03 21:29:03有时候我们一些设置属性要保存到本地,防止软件卸载后配置属性消失。 比如我今天就有个修改手机蓝牙名称显示的功能,但是只需要修改一次,并且进行标记,并保存这个标识,如果程序卸载,重新安装也不需要再修改,... -
android settings--简述获取部分系统属性
2013-12-13 18:45:07在android中,许多的系统属性都在settings应用当中进行设置的,比如wifi、蓝牙状态,当前本机语言,屏幕亮度等等一些相关的系统属性值。这些数据主要是存储在数据库中,对应的URI为:content://settings/system和...在android中,许多的系统属性都在settings应用当中进行设置的,比如wifi、蓝牙状态,当前本机语言,屏幕亮度等等一些相关的系统属性值。这些数据主要是存储在数据库中,对应的URI为:content://settings/system和content://settings/secure,这两个是主要的,目前也只是涉及到这两个数据库表的使用。
接下来,就了解下settings应用中是如何对系统属性进行设置的。
当需要获得当前wifi状态的值,调用已封装的方法如下:
Settings.Secure.getInt(getContentResolver() , Settings.Secure.WIFI_ON);
修改wifi状态只需要调用对应的setInt方法就可以实现。
当需要获得当前时间日期自动获取,调用如下:
Settings.System.getInt(getContentResolver() , "auto_time");
修改也是调用对应的setInt方法。
注意:这里修改settings的系统属性值需要有相关的权限。如修改wifi状态需要有android.permission.WRITE_SETTINGS权限,权限问题只要参考sdk下的描述就可以。
其实在settings应用中所获取或者修改属性都是调用了framework中android.provider.settings的Settings类对应的方法,也就是说真正有跟数据库打交道的是在provider中,这里也体现了ContentProvider的用途。
就大体说下android.provider.settings.Settings这个类吧。Settings里面创建了包含System和Secure在内的几个内部类,每个内部类都对应了一张数据库表,也就是继承自BaseColumns类,System和Secure类分别对应着system和secure数据库表。
对于上面通过getInt获得的字段,其实是在初始获得数据库数值的时候,首先是有getString方法将数据库数据保留,然后在integer.parseInt将数据转换成int类型。这就是settings读取和保留数据的基本原理。
转自 http://suking3.iteye.com/blog/875431
-
低功耗蓝牙学习笔记-GATT
2020-03-04 14:46:40在上一章节我们知道属性的组成。在实际的应用中,程序中存放的就是由多个上图属性组成的一个数据库。声明:如果是ble初学者,看到这么多层协议可能感到头晕,已经记不清各层之间是如何衔接的。其实在主机端开发者能接触到的只有HCI层、L2CAP层、属性协议层(ATT)。GATT不属于协议,它是很据ATT层实现的访问规范。每次想到这就忍不住高歌一曲《洋葱》:你就这样一层一层的剥开我的心~,最后真正的数据就剩那么点!
在上一章节我们了解了属性的概念。在实际的应用中,有这么一个数据库,它是由很多条属性组成。这个数据库是一个独立的profile,一个profile可以由至少一个或多个Server 组成。而 一个Server 的由0 或多个引用服务《Include》和至少一个特性《Characteristic》 组成。如下图:
一个特性包括
特性声明
特性值声明
特性描述符
知道你们又开始晕了!来来来~大家跟我一起动动手。
推荐一个BLE的APP工具,它简直就是学习BLE的利器。让我们来使用手机配置一个带电池服务的BLE服务器。
nRF Connect走起~
服务定义的开始为服务声明,结束于下一个服务声明或者句柄达到 0xFFFF。所有的包含定义将紧跟服务声明并在特性定义之前, 所有的特定定义将紧跟在最后一个包含定义,当没有包含定义时,特性定义紧跟在服务声明之后。
属性类型分组
在 GATT Profile 中将属性类型分为 3 组:首要服务Primary Service次要服务 Secondary Service特性Characteristic一个组开始于一个声明, 服务分组结束于下一个服务声明特性分组结束于下一个特性的声明或者是下一个服务的声明也就是服务声明对服务进行分组,特性声明对特性进行分组。服务是一种或多种特性的组合;特性则是由一种或多种属性组成。特性Characteristic特性包含 3 个基本的要素:特性声明声明的属性的值的声明
特性描述符表 3-9 是截取的表 3-5 中心率计的第一个特性分组 ,它刚好是一个最小的特性。GATT规程
对于 GATT 规程定义了如何用 ATT 协议发现和使用服务、特性与描述符的标准方法。
GATT 规程有 3 中基本规程:发现规程、客户端发起规程和服务器发起规程
发现服务和特性
有 3 种方法发现服务:发现所有首要服务、按服务 UUID 发现首要服务、查找包含服务。
在服务发现以后,便可以发现每个服务的特性。要取得完整的特性,需要发现特性和特性描述符
ATT 协议与 GATT 映射表
-
adroid setting获取部分系统属性
2012-06-12 23:25:06在android中,许多的系统属性都在settings应用当中进行设置的,比如wifi、蓝牙状态,当前本机语言,屏幕亮度等等一些相关的系统属性值。这些数据主要是存储在数据库中,对应的URI为:content://settings/system和... -
mybatis解决属性名和字段名不一致的问题
2021-02-20 22:12:39属性名称和数据库中的字段名称不一致,查询出来的结果为null Java中的实体类设计: public class User { private int id; //id private String name; //姓名 private String password; //密 -
一个难倒三线城市所有开发人员,主要在数据库方面的项目,就等给各位大侠发路费了
2018-07-23 07:02:28同时要求当向某一个区块增加一个新的数据时不能与其所有相邻的区块内的已有的数据出现某一特定属性的共同特征;用这个方法来进行系统“容错、纠错”,保证即便真的出现了错误,也能正确的还原输出正确信息。如图1所... -
Android 开发权限注册
2017-11-09 12:57:29蓝牙 使用蓝牙 android.permission.BLUETOOTH:允许程序连接配对过的蓝牙设备 蓝牙管理 android.permission.BLUETOOTH...android.permission.ACCESS_CHECKIN_PROPERTIES ,读取或写入登记check-in数据库属性表的权限 -
Android Settings.System的使用
2016-01-25 19:47:15在Android中,如果你要打开或关闭数据连接,WiFi,飞行模式,蓝牙,你需要对数据库中这些开关的值进行修改,这时,你会使用到Settings.System,在settings数据库中这些属性值以键值对的形式存储,通过其get和put方法... -
安卓从应用,修改设置开关和内部底层的方法
2015-11-12 14:58:35系统属性都在settings应用当中进行设置的,比如wifi、蓝牙状态,当前本机语言,屏幕亮度等等一些相关的系统属性值。这些数据主要是存储在数据库中,对应的URI为: content://settings/system和content://... -
智能手环产品分析(资料来源网上,自己总结)
2014-02-23 23:01:332. APP辅助功能:饮食(拍照、条形码、饮食数据库,给出饮食的营养信息指导用户调整饮食)、心情分析、健康数据分析(指导用户行为对健康的影响)。 3. 物理属性:防水、防汗、亲肤、震动、呼吸灯、LED灯组。 4. ... -
Android开发权威指南.(人民邮电.李宁).pdf
2016-06-01 12:41:24从技术实现上,讲解了6大完整综合案例及源代码分析,分别是新浪微博客户端、蓝牙聊天、全键盘输入法、月球登陆(游戏)、贪吃蛇(游戏)、笑脸连连看(游戏)。 本书注重对实际动手能力的指导,在遵循技术研发知识体系... -
Android开发权威指南(第一版扫描版).李宁.pdf
2014-03-29 18:38:54从技术实现上,讲解了6大完整综合案例及源代码分析,分别是新浪微博客户端、蓝牙聊天、全键盘输入法、月球登陆(游戏)、贪吃蛇(游戏)、笑脸连连看(游戏)。 《Android开发权威指南》注重对实际动手能力的指导,在遵循... -
android开发秘籍--pdf
2013-06-18 21:56:074.3.1 秘诀32:设置和更改文本属性 4.3.2 秘诀33:提供文本输入 4.3.3 秘诀34:创建表单 4.4 其他控件:从按钮到拖动条 4.4.1 秘诀35:在表格布局中使用图像按钮 4.4.2 秘诀36:使用复选框和开关... -
tengge py for s60编程教程
2012-07-17 21:34:585.5蓝牙的开启与关闭 5.6mbm图片的解压 5.7lambda函数的使用 5.8运行字符串中的程序 5.9对象与字符串的转换 6.0逻辑运算符 6.1定时程序的设计 6.2文本的查找替换和分割 6.3打包三版py软件的方法 6.4附加目录的创建... -
Android4高级编程
2014-08-03 19:41:271.5.2 使用Wi-Fi、蓝牙技术和NFC进行数据传输 1.5.3 地图、地理编码和基于位置的服务 1.5.4 后台服务 1.5.5 使用SQLite数据库进行数据存储和检索 1.5.6 共享数据和应用程序间通信 1.5.7 使用Widget和Live ... -
工程硕士学位论文 基于Android+HTML5的移动Web项目高效开发探究
2017-02-28 21:22:19Sqlite 一款轻型的数据库,是遵守ACID的关系型数据库管理系统,它包含在一个相对小的C库中 W3C 万维网联盟,创建于1994年,是Web技术领域最具权威和影响力的国际中立性技术标准机构。主要的工作是发展 Web 规范,... -
Android高级编程--详细书签版
2013-02-06 17:37:5210.5.4 访问手机的属性和状态 339 10.5.5 控制电话 340 10.6 使用蓝牙 341 10.6.1 蓝牙服务介绍 341 10.6.2 控制本地蓝牙设备 341 10.6.3 发现并配对蓝牙设备 342 10.6.4 管理蓝牙连接 343 10.6.5 使用蓝牙... -
8、Assets目录数据库相关 9、设置Badge数字角标 10、状态栏相关 11、Base64相关 12、Bitmap相关 13、选择适配器 14、数据验证相关 15、类操作相关 16、清除缓存/文件相关工具类 17、剪贴板相关工具类 18、关闭操作流...
-
android开发资料大全
2013-04-07 15:51:23android自带的示例程序 BluetoothChat 变蓝牙串口助手(内含DIY蓝牙遥控车附源码实例教程) Android高手过招 FAQ 网友收集的android开发书籍(可下载哦) 东软集团内部文件《android编程指南》 从零开始Android... -
《Android应用开发揭秘》源码
2012-02-24 23:18:306.5 Android数据库编程 6.5.1 SQLite简介 6.5.2 SQLite编程详解 6.5.3 SQLiteOpenHelper应用 6.6 数据共享(ContentProviders) 6.7 小结 第7 章多媒体开发 7.1 多媒体开发详解 7.1.1 Open Core ... -
Android应用开发揭秘--详细书签版
2012-12-12 13:27:466.5 Android数据库编程 165 6.5.1 SQLite简介 166 6.5.2 SQLite编程详解 166 6.5.3 SQLiteOpenHelper应用 172 6.6 数据共享(Content Providers) 177 6.7 小结 187 第7章 多媒体开发 188 7.1 多媒体开发...
-
维吾尔文笔迹鉴别预处理及边缘提取方法研究
-
Java多线程-源码
-
样板:Wordpress网站的样板-源码
-
设计模式:服务器编程语言中无法实现的设计模式-源码
-
python简易计算器
-
很棒的自行车出租-源码
-
基于python的dango框架购物商城毕业设计毕设源代码使用教程
-
Java生成随机码效率对比
-
2021-03-01
-
gitk.exe
-
购物排序-源码
-
【解决方案】民爆器材仓库视频监控要解决哪些难题?EasyNVR远程视频监控突发险情的必要性
-
【Python-随到随学】FLask第二周
-
chrome-dino-autobot-源码
-
计算当天、本周、本月、本季、今年的起止日期
-
牛牛量化策略交易
-
MySQL 数据库权限管理(用户高级管理和精确访问控制)
-
基于HTK的维吾尔语连续音素识别技术研究
-
css粘性定位position:sticky
-
web无插件直播点播系统EasyDSS获取指定时间录像m3u8播放地址兼容iOS平台吗?