网站logo图标,seo网站关键词优化费用,计算机作业网页设计代码,广东网站建设效果蓝牙协议栈学习笔记
蓝牙简介
蓝牙工作在全球通用的 2.4GHz ISM#xff08;即工业、科学、医学#xff09;频段#xff0c;使用 IEEE802.11 协议
蓝牙 4.0 是迄今为止第一个蓝牙综合协议规范#xff0c;将三种规格集成在一起。其中最重要的变化就是 BLE#xff08;Blue…蓝牙协议栈学习笔记
蓝牙简介
蓝牙工作在全球通用的 2.4GHz ISM即工业、科学、医学频段使用 IEEE802.11 协议
蓝牙 4.0 是迄今为止第一个蓝牙综合协议规范将三种规格集成在一起。其中最重要的变化就是 BLEBluetooth Low Energy低功耗功能提出了低功耗蓝牙、传统蓝牙和高速蓝牙三种模式 ”高速蓝牙“主攻数据交换与传输“传统蓝牙”则以信息沟通、设备连接为重点”低功耗蓝牙“以不需占用太多带宽的设备连接为主功耗较老版本降低了 90%。
蓝牙 4.0 的芯片模式分为 Single mode 与 Dual mode。 Single mode 只能与蓝牙 4.0 互相传输无法向下与 3.0/2.1/2.0 版本兼容 Dual mode 可以向下兼容 3.0/2.1/2.0 版本。 前者应用于使用纽扣电池的传感器设备例如对功耗要求较高的心率检测器和温度计后者应用于传统蓝牙设备同时兼顾低功耗的需求。 此外蓝牙 4.0 还把蓝牙的传输距离提升到 100 米以上低功耗模式条件下。拥有更快的响应速度最短可在 3 毫秒内完成连接设置并开始传输数据。更安全的技术使用AES-128 CCM 加密算法进行数据包加密和认证。
蓝牙 5.0 在低功耗模式下具备更快更远的传输能力传输速率是蓝牙 4.2 的两倍速度上限为 2Mbps有效传输距离是蓝牙 4.2 的四倍理论上可达 300 米数据包容量是蓝牙 4.2 的八倍。 支持室内定位导航功能结合 WiFi 可以实现精度小于 1 米的室内定位。 针对 IoT 物联网进行底层优化力求以更低的功耗和更高的性能为智能家居服务。
随着蓝牙 5 技术的出现和蓝牙 mesh 技术的成熟大大降低了设备之间的长距离、多设备通讯门槛为未来的 IoT 带来了更大的想象空间。
HCI蓝牙架构
BT Controller此部分指的是蓝牙芯片包括 BR/EDR 芯片蓝牙 2.1 芯片AMP 芯片蓝牙 3.0 芯片LE 芯片蓝牙 4.0 芯片后续我们把 4.0 以下统称为传统蓝牙4.0 以上称为低功耗蓝牙芯片层面会有 2 种模式包括 单模蓝牙芯片单一传统蓝牙芯片单一低功耗蓝牙芯片 双模蓝牙芯片同时支持传统蓝牙跟低功耗蓝牙的芯片 BT Host蓝牙协议栈 HW 层这里就是蓝牙芯片层包含以下几个部分
RFRADIO射频层本地蓝牙数据通过射频发送给远端设备并且通过射频接收来自远端蓝牙设备的数据BBBASEBAND基带层进行射频信号与数字或语音信号的相互转化实现基带协议和其它的底层连接规程。LMPLINK MANAGER PROTOCOL链路管理层负责管理蓝牙设备之间的通信实现链路的建立、验证、链路配置等操作HCIHOST CONTROLLER INTERFACE主机控制器接口层HCI 层在芯片以及协议栈都有芯片层面的 HCI 负责把协议栈的数据做处理转换为芯片内部动作并且接收到远端的数据通过 HCI 上报给协议栈。BLE PHYBLE 的物理层BLE LLBLE 的链路层
TRANSPORT 层此部分在硬件接口UART/USB/SDIO实现 HOST 跟 CONTROLLER 的交互此部分会分为以下几个协议在后续章节会对 transport 协议做详细的说明
H2USB 的 transportH4: UART 的 transportH5: UART 的 transportBCSP: UART 的 transportSDIO的 transport 其中2,3,4的主要差别在于H4需要BT CHIP UART_TX/UART_RX/UART_CTS/UART_RTS/VCC/GND接到 MCU而 H5,BCSP 只需要 BT CHIP 的 UART_TX/UART_RX/VCC/GND 接到 MCU 就可以通信。
HOST 层此部分就是蓝牙协议栈是我们本书的重点
HCIHOST CONTROLLER INTERFACE主机控制层接口主要负责透过 transport把协议栈的数据发送给蓝牙芯片并且接受来自蓝牙芯片的数据
core 文档 HCI 的架构如下 2. L2CAPLogical Link Control and Adaptation Protocol逻辑链路控制与适配协议将ACL数据分组交换为便于高层应用的数据分组格式并提供协议复用和服务质量交换等功能。 通过协议多路复用、分段重组操作和组概念,向高层提供面向连接的和无连接的数据服务,L2CAP还屏蔽了低层传输协议中的很多特性使得高层协议应用开发人员可以不必了解基层协议而进行开发。架构如下: 3. SDPSERVICE DISCOVERY PROTOCOL服务发现协议服务发现协议(SDP)为应用程序提供了一种方法来发现哪些服务可用并确定这些可用服务的特征 4. RFCOMMSerialPortEmulation串口仿真协议上层协议蓝牙电话蓝牙透传SPP等协议都是直接走的RFCOMM 5. OBEX对象交换协议蓝牙电话本蓝牙短信文件传输等协议都是走的OBEX 6. HFPHands-Free蓝牙免提协议 一共分为两个角色AG跟HF蓝牙耳机跟手机连接那么手机的角色就是AG蓝牙耳机的角色是HF 7. HSP蓝牙耳机协议最开始的蓝牙耳机协议。算是一个简化版的HFP。 8. SPPSERIAL PORT PROFILE蓝牙串口协议架构如下 9. IAP苹果的特有协议分为IAP1/IAP2一般做Carplay或者iPod功能的人肯定接触过这块 10. PBAPPhone Book Access蓝牙电话本访问协议,架构如下 11. MAPMESSAGE ACCESS PROFILE蓝牙短信访问协议架构如下 12. OPPOBJECT PUSH PROFILE对象推送协议架构如下 13. AVCTPAUDIO/VIDEO CONTROL TRANSPORT PROTOCOL音视频控制传输协议是AVRCP的底层架构如下 14. AVDTPAUDIO/VIDEODISTRIBUTIONTRANSPORTPROTOCOL音视频分布传输协议是A2DP的底层架构如下 15. HIDHUMAN INTERFACE DEVICE人机接口协议架构如下 16. A2DPAdvanced AudioDistribution: 蓝牙音乐协议架构如下 17. AVRCPAUDIO/VIDEO REMOTE CONTROL PROFILE蓝牙音乐控制协议 18. ATT蓝牙 BLE 属性协议 ATTAttribute Protocol用于发现、读、写对端设备的协议(针对 BLE 设备),ATT允许设备作为服务端提供拥有关联值的属性集 让作为客户端的设备来发现、读、写这些属性同时服务端能主动通知客户端。 说到属性协议我们就不得不提属性是什么在 ATT 中属性分为 3 个内容 1属性类型(attribute type)用 UUID 的形式来表现 2属性句柄(attribute handle)用于标识一个属性 3属性权限(permissions), 控制是否该 Attribute 可读、可写、属性值是否通过加密链路发送 ATT 分为两个角色Server/Client
GATT蓝牙BLE通用属性协议 GATT(Generic Attribute Profile)描述了一种使用ATT的服务框架该框架定义了服务(Server)和服务属性(characteristic)的过程(Procedure)及格式。 Procedure定义了characteristic的发现、读、写、通知(Notifing)、指示(Indicating)及配置characteristic的广播。 GATT可以被Application或其他Profile使用其协议栈如下图 SM: 蓝牙BLE安全管理协议
蓝牙debug方式
一般蓝牙有几种方式可以debug 1直接分析debuglog就是打印log这是最简单粗暴的方式一般程序调试都是用这种方式这种方式对于逻辑错误执行流程有很大的帮助但是对于不懂协议栈的人来说直接打印有的时候很难定位蓝牙具体问题 2Btsnoop调试蓝牙协议栈这种通过软件来根据特定的格式来写一个文件来看蓝牙整个的交互流程在后续章节有介绍 3直接录制HCI log跟2的区别在于2是通过软件来生成文件而这种方式是通过特定的工具软件来采集蓝牙芯片端跟协议栈的收发数据打开效果类似于btsnoop但是更加有参考意义常用的hci log工具有frontline,ellisys都是很贵另外这个是有使用场景或者需求在的 假设你的MCU没有FileSystem或者Flash不足以保存足够大的btsnoop那替代btsnoop的方式推荐使用HCIHWsniffer,另外一种场景是上层确定调用uart 收发接口是正常的但是到了芯片这端就是不响应或者controller给你一个错误的应答为了防止跟驱动扯皮HCI HW sniffer也有应用场景在的 4录制airlog也就是空中包来抓本地芯片跟远端芯片的蓝牙交互流程也是用特定的工具跟软件来查看常用的同样是ellisys,frontline传统蓝牙的一般都比较贵但是低功耗的蓝牙有更多的选择而且价格相对于便宜很多淘宝有100RMB的。 5抓芯片log,比如TI有TI logger,csr有spi接口来抓取相应的芯片log 总结下:以上5种方式各有各的好处也各有各的弊端针对具体问题采用不同的debug方式
transport类型介绍
H4
H4 是 UART 传输中最简的一个 Transport只是在 HCI raw data 的前面加一个 type 就行如下 HCI 一共有五种 HCI data: 1HCI COMMAND:由蓝牙协议栈发送给芯片的命令HOST-CONTROLLER 2HCI EVENT:由蓝牙芯片上报给蓝牙协议栈的事件HOST-CONTROLLER 3HCI ACL:蓝牙协议栈跟蓝牙芯片双向交互的普通数据HOST-CONTROLLER 4HCI SCO:蓝牙芯片跟蓝牙协议栈双向交互的通话/语音识别数据HOST-CONTROLLER 5HCI ISO这部分是在 core5.2 才添加:BLE audioHOST-CONTROLLER
仅在HCI原始数据之前添加了一个字节表示type
主机控制器接口层
HCI流控
蓝牙协议栈到蓝牙芯片的流控
从 host 到 Controller 的数据流控分为两种Packet-based Data Flow Control和 Data-Block-Based Data Flow Control。通过 HCI_Write_Flow_Control_Mode 命令来切换Packet-based data flow control 对于 BR/EDR和LE 芯片来说是默认的Data-Block-Based Data Flow Control对于AMP controller来说是默认的
协议栈给芯片发送read buffer size command芯片回复read buffer size event 在初始化的时候我们读到的 acl buffer size 是 10所以我们发送了一个 acl 数据此部分变为 9.
蓝牙协议栈收到蓝牙芯片回送的 Num of complete packet event 后协议栈更新 acl buffer size 数量。
蓝牙芯片到蓝牙协议栈的流控
一般不常用可以分别控制ACL和SCO的流控开关通过Set Controller To Host Flow Control command 命令控制初始化的时候通过 Host Buffer Size command 由蓝牙协议栈发送给芯片 acl,sco packet num以及 length协议栈收到 acl 后发送给芯片 Host Number Of Completed Packets command断开后芯片自己维护重新计数
传统蓝牙command/event/acl/sco/iso命令格式
除非特别声明否则所有的数据都采用小端模式。
蓝牙command格式
HCI 命令包用于从协议栈发送给芯片的命令。HCI 命令包的格式如下图所示
Opcode
每个命令被分配一个2字节的而操作码分为两个字段操作码组字段OGF操作码命令字段OCFOGF占用高6bit位置OCF占用低10bit位置。代码实现
OGF分为以下8组
Link Control commands, the OGF is defined as 0x01. 此组 Command 集合是用于连接控制的比如搜索啦连接啦等等Link Policy commands, the OGF is defined as 0x02 此组 Command 集合是用于连接策略的比如进入 Sniffer mode/角色切换等HCI Control and Baseband commands, the OGF is defined as 0x03 此组 Command 集合是用于控制本地 Controller 跟基带的比如复位设置连接 超时等Informational Parameters commands, the OGF is defined as 0x04 此组 Command 集合是设置或者获取信息参数的比如读取蓝牙地址Status parameters commands, the OGF is defined as 0x05 此组 Command 集合是状态参数的比如读取信号强度等Testing commands, the OGF is defined as 0x06 此组 Command 集合是测试命令比如让设备进度 DUTDevice under Test模式的LE Controller commands, the OGF code is defined as 0x08 此组 Command 集合是 BLE 的 commandvendor-specific debug commandsthe OGF code is defined as 0x3F 此部分是 vendor 定义的也就是芯片厂商为了扩展 core 文档的 HCI command 定义
OCF 众多在每个 OGF 下都有一堆的 OCF 定义后面详细介绍
Parameter Total Length1字节后续参数的长度
Parameter:每个 command 的 para
我们在组合封包的时候代码如下 蓝牙event格式
HCI event 是蓝牙芯片发送给协议栈的事件。HCI 事件包的格式如下图所示每个字段的定义如下所示
Event code:唯一 event 编码在后续的小节会介绍
Parameter Total Length:后续参数的长度
Parameter:event 参数
Event header 结构体代码如下 以 HCI_Command_Complete 格式为例: 是reset命令的回复event raw data 分析 0x04-》是H4 transport的开头type 0x0E - command complete event code 0x04 - para len也就是后面参数的长度 0x01 - num HCI command pacekets允许从host发往ctrler的命令数量一般都是1 0x03 0x0c - HCI reset command opcode 0x00 - status success
蓝牙acl格式
HCI acl 用于从协议栈跟蓝牙芯片双向交互上层协议的数据。HCI acl 的格式如 下图所示每个字段的定义如下所示
Handle一个半字节连接句柄用于蓝牙连接后跟remote交互acl数据用
PB flag2位此部分就是用于上层数据L2CAP是否是分隔数据具体 bit 的定义如下不理解意思是首包数据或中间数据或者结尾数据 BC flag此部分定义是否为广播 Data total length:后续 payload 的长度
蓝牙sco格式
HCI sco 用于从协议栈跟蓝牙芯片双向交互音频数据主要用于传统蓝牙。HCI sco 的格式如下图所示每个字段的定义如下所示
Connection_Handle一个半字节连接句柄用于之后交互soc数据
Packet_Status_Flag2位:此部分协议栈发送给芯片的设置为 0x00芯片发送给协议栈的如下图 Data_Total_LengthSCO数据长度
蓝牙ISO格式
此部分是从 core5.2 开始增加主要是蓝牙协议栈跟蓝牙芯片交互同步数据主要用来传输 BLE Audio 的数据 HCI iso 的格式如下图所示每个字段的定义如下所示
实际应用介绍部分command/event
搜索command以及产生的event
整个流程如下 1首先协议栈给蓝牙芯片发送搜索 command 2芯片收到搜索命令上报协议栈一个 command status 的 event 3然后芯片上报协议栈搜索结果 4最终芯片上报协议栈搜索完成 HCI_Inquiry命令
参数 LAP分为通用搜索访问代码GIAC和受限搜索访问代码LIAC Unlimited inquiry 可以搜索到处于limited inquiry scan 跟 unlimited inquiry scan 状态的设备。 limited inquiry 只能搜索到处于limited inquiry scan 状态的设备。
Inquiry_Length Num_Responses 后两个参数决定停止搜索的时间
HCI_Command_Status事件
异步指令才会触发该事件 参数status 0x00表示该命令正常处理中其他表示命令存在问题 Num_HCI_Command_Packets:控制器允许主机发送的命令数量 Command_Opcode:表示该事件是主机下发的哪个命令的响应
HCI_Inquiry_Result事件
一般是每搜到一个设备就会上报一个该事件 参数Num_Responses搜索到设备的个数 BD_ADDR搜到的蓝牙地址 Page_Scan_Repetition_Modepage scan 重复模式 Reserved保留参数 Class_of_Device设备类型 Clock_Offset时钟偏移 注意此部分普通的搜索不会上来 remote bluetooth name需要额外去调用 Remote Name Request command 去请求当然 EIR 除外后续我们会说明 EIR。
如下是带有 remote bluetooth name的EIR事件应该是需要先发送Write Extended Inquiry Response命令配置
HCI_Inquiry_Complete事件
达到搜索完成的条件之后会触发该事件 参数status0x00表示成功完成了搜索其他表示出错
取消搜索command以及产生的event
流程是先发送取消搜索的命令然后收到命令完成的事件
HCI_Inquiry_Cancel命令
无参数
HCI_Command_Complete事件
一般的同步命令完成都会触发该事件上报 参数 Num_HCI_Command_Packets控制器允许主机发送的命令数量 Command_Opcode该事件对应的命令Opcode Return_Parameters根据对应的具体命令确定返回的参数
hci connection command 以及产生的 event
流程如下
总结步骤1蓝牙协议栈向芯片发送连接的 command 2蓝牙芯片上报蓝牙协议栈 command status with create connection opcode 3蓝牙芯片上报蓝牙协议栈 connect complete
HCI_Create_Connection命令
异步命令 参数 BD_ADDR要连接的remote设备的蓝牙地址 Packet_Type支持的数据封包类型 Page_Scan_Repetition_Modepage scan 重复模式 Reserved保留 Clock_Offset时钟偏移 Allow_Role_Switch是否允许角色转换 HCI_Connection_Complete事件
参数 status00代表连接成功 Connection_Handle连接句柄 BD_ADDR连接的蓝牙地址 Link_Type连接的类型SCO或者ACL Encryption_Enabled是否允许加密
hci 接受连线请求 command 以及产生的 event 步骤整理如下 1收到芯片上报给协议栈 connect request 的事件 2协议栈发送给芯片接受连接请求的 command 3收到 command status with accept connection req 的 opcode 4收到 connect complete 的 event
HCI_Connection_Request事件
参数 BD_ADDR:蓝牙地址 Class_of_Device: 对方的 cod设备类型可穿戴设备智能手机等等 Link_Type:连线类型SCOACLeSCO
HCI_Accept_Connection_Request命令
参数BD_ADDR蓝牙地址 Role当前连接的角色00作为master会产生一个role switch行为01作为slave
传统蓝牙初始化介绍
每个协议栈使用顺序的会有所不同并没有一个固定的顺序一定要哪条指令先发 举例如下
发送 HCI Reset 以及接收回应发送Vendor command我司自己定义的host和controller之间的vendor comman发送 Read Buffer Size command接收到 command complete with command opcode发送 Read BT address command接收到 command complete with command opcode.发送 Write code command接收到 command complete with comand opcode.发送 Change Local Name command接收到 command complete with comand opcode.发送 Write page timeout command接收到 command complete with comand opcode.发送 Write set Event Mask command接收到 command complete with comand opcode.发送 Write Write Simple Pairing command接收到 command complete with comand发送 Write Scan Enable command接收到 command complete with comand opcode.
Core手册查询方法 command和event位于Vol 4Part E,第7章1846~2632页之间 另外LE和传统BT的command有部分不同
我司流程
HCI_Vendor_Command 0x01HCI ResetHCI Read Local Version InformationHCI Read Buffer SizeHCI Read BDADDRHCI Write Class of Device (Pager)HCI Write Page Timeout (Timeout5 s)HCI Write Local Name (Local Name“XS09 Ultra-B80”)HCI Write Simple Pairing Mode (ModeEnabled)SSP配对方式HCI Write Inquiry Mode (ModeExtended)HCI Write Scan Enable (EnableBoth)inquiry scan影响其他设备搜索本设备page scan影响其他设备跟本设备建立连接但关闭并不影响本设备搜索和连接其他设备HCI Write Extended Inquiry Response
蓝牙PINCODE配对方式
步骤
收到HCI_PIN_Code_Request事件发送HCI_PIN_Code_Request_Reply命令带上了PIN_Code长度和PIN_Code内容
蓝牙SSP配对方式
1接受到 IO Capability Response event(0x32) 2接受到 IO Capability Request event0x31 3发送 IO Capability Request Reply commandOGF0x01 OCF0x2B并接收到 command complete with opcode 4接收到 User Confirmation Request event0x33 5发送 User Confirmation Request Reply commandOGF0x01 OCF0x2C并接收到 command complete with opcode 6接收到 Simple Pairing Complete event0x36 应该是需要先建立一个HCI连接才能进行SSP配对
HCI_IO_Capability_Response事件
参数 BD_ADDR蓝牙地址 IO_CapabilityIO能力log中为DisplayYesNo OOB_Data_Present:是否需要 OOB datalog中为None Authentication_Requirements:是否需要 authlog中为MITM Protection Not Required, No Bonding
IO能力意思如下 DisplayOnly 只是需要显示随机数字就好了 DisplayYesNo 让 user 来决定是否要配对或者不配对 KeyBoardonly 让用户通过键盘来输入配对码 NoInputNoOutput 啥也不需要显示。
HCI_IO_Capability_Request事件
参数 BD_ADDR蓝牙地址
HCI_IO_Capability_Request_Reply命令
BD_ADDR蓝牙地址 IO_Capability:IO 能力log中为No Input/Output OOB_Data_Present:是否需要 OOB datalog中为None Authentication_Requirements:是否需要 authlog中为MITM Protection Not Required, General Bonding
HCI_User_Confirmation_Request事件
参数 BD_ADDR蓝牙地址 Numeric_Value随机数十进制0-99999916进制0-0x000F423F)
HCI_User_Confirmation_Request_Reply命令
参数 BD_ADDR蓝牙地址
HCI_Simple_Pairing_Complete事件
参数 status同上00表示成功 BD_ADDR蓝牙地址
EIR注册以及extern inquiry扫描对方的EIR
搜索分为三种类型 标准/RSSI/EIR 区别在于 标准搜索只会附带以下信息 RSSI就是在此基础上附带RSSI那么 EIR(EXTENDED INQUIRY RESPONSE)就是在这些基础上会附带额外的一些信息比如 remote name对方支持的 UUID 等前提是对方注册了 EIR,TX power 等
EIR格式说明 EIR 信息不管是否有效数据是多少 byte最终都要 240byte EIR Data Structure 的格式为1Byte lengthnByte type(一般是 1byte)len-n byte EIR raw data EIR具体信息在文档 CSS_V9/V10 中
要让其他设备可以搜到本设备的EIR信息需要先进行写入 HCI_Write_Extended_Inquity_response命令用于写入相关信息local nameuuid表示支持哪些profile
要获取其他设备的EIR信息需要先设置inquiry模式为extended模式再搜索
HCI_Write_Inquiry_Mode命令
参数 Inquiry_mode标准,rssi,extended
Extended inquiry使用注意点
Extern inquiry 的结果会反复上来有重复需要协议栈过滤 可以看到同样的蓝牙地址同样的蓝牙名称但是 RSSI 不同在同一次搜索中 会上来几次Extern inquiry 的搜索可能有的时候不带 EIR 数据 可以看到同样的蓝牙地址有的时候并没有上来 EIR 的 dataExtern inquiry 跟标准的搜索前面的格式稍有区别可以看到 cod 的偏移是相差一个 byte 的
逻辑链路控制和适配协议L2CAP
一些概念
L2CAP channel在两个设备之间的逻辑通道通过CID区分 SDU, L2CAP跟上层通信使用的数据包服务数据单元 PDUL2CAP跟下层通信使用的数据包协议数据单元 L2CAP有基础模式增强重传模式流模式重传模式流控模式 基础模式主要用Basic information frameB-frame它是PDU的开头包含长度和CID Control frameC-frame它是包含L2CAP信令信息的PDU,仅用在信令通道上 segmentation和reassemblySDU的拆包组包主要用于非基础模式 fragmentation和recombinationPDU的拆包组包他们可能会用在所有模式下
• Basic L2CAP Mode(equivalent to L2CAP specification in Bluetooth v1.1) 默认模式在未选择其他模式的情况下用此模式。 • Flow Control Mode此模式下不会进行重传但是丢失的数据能够被检测到并报告丢失。 • Retransmission Mode此模式确保数据包都能成功的传输给对端设备。 • Enhanced Retransmission Mode此模式和重传模式类似加入了 Poll-bit 等提高恢复效率。 • Streaming Mode此模式是为了真实的实时传输数据包被编号但是不需要 ACK 确认。设定一个超时定时器一旦定时器超时就将超时数据冲掉。 • LE Credit Based Flow Control Mode被用于 LE 设备通讯。 • Enhanced Credit BasedFlow Control Mode
低功耗蓝牙host介绍
主机控制器接口层HCI
低功耗蓝牙HCI Command命令说明
低功耗蓝牙HCI Event事件说明
LE Meta event
Event Code0x3E 这个事件封装了所有LE controller的特有事件其参数的第一个字节就是子事件代码。
初始化过程
HCI_Vendor_Command 0x01HCI ResetHCI Read Local Version InformationHCI Read Buffer SizeHCI Read BDADDRHCI Write Class of Device (Pager)HCI Write Page Timeout (Timeout5 s)HCI Write Local Name (Local Name“XS09 Ultra-B80”)HCI Set Event Mask (Enabled62)HCI Write Simple Pairing Mode (ModeEnabled)SSP配对方式HCI Write Inquiry Mode (ModeExtended)HCI Write Scan Enable (EnableBoth)HCI Write Extended Inquiry ResponseHCI Write LE Host Supported (LEEnabled, SimultaneousDisabled)HCI LE Set Event Mask (Events56)HCI LE Set Random Address (AddressC9:D1:09:85:3D:6D (Static))HCI LE Read Buffer Size › Data251, Packets4HCI LE Read Local Supported Features › Encr, ParReq, ExtRej, FeatEx, Ping, CIS, BISHCI LE Set Advertising Parameters (Min480 ms, Max640 ms, TypeConnectable, OwnPublic, DirectPublic, Address00:00:00:00:00:00, Channels37 | 38 | 39, FilterScan Any, Request Any)HCI LE Set Advertising Data (Data7 bytes)HCI LE Set Advertise Enable (AdvertisingEnabled)
LE_SCAN LE_Scan_Type:分主动扫描跟被动扫描 区别主要有几个 ① 被动扫描仅仅接受广播包不会发起扫描请求 ② 主动扫描接受广播包后悔发送扫描请求给处于广播态的设备来获取额外的广播数据 一般被动扫描用于确定从机不会发送扫描响应只会发送 31byte 的广播数据 而主动扫描用于不确定从机是否有额外的数据所以要额外发起扫描请求来接受更多的广播的数据 注意主动扫描的扫描请求以及扫描响应也是广播封包
BLE 搜索广播 command 以及 event 步骤 1发送设置事件掩码的 command(set event mask)以及收到commnd complete event 步骤 2发送设置支持 BLE 的 command(write le host support)收到command complete event 步骤 3发送设置 BLE scan 参数的 command(LE set scan param) 步骤 4发送 BLE 搜索使能的 command(LE set scan enable) 步骤 5收到步骤 34的 command complete 步骤 6解析 BLE 广播 event 的数据包 步骤 7发送结束搜索的 command(LE set scan enable)以及收到commnd complete event
属性协议ATT
ATT概念
ATTAttribute Protocol用于发现、读、写对端设备属性的协议(针对 BLE设备)ATT 分为两个角色Server/ClientATT 允许设备作为服务端提供拥有关联值的属性集让作为客户端的设备来发现、读、写这些属性同时服务端能主动通知客户端。
ATT 有固定的 L2CAP CID也就是 0x0004
ATT部分术语
属性类型Attribute type
通过 UUID(universally unique identifier)来标识UUID 一般分为16bit/32bit/128bit 的 UUID在 ATT 协议中32bit 的 UUID 必须转换为 128bit的 UUID 另外16bit的UUID是通过加一个128 bit的base uuid来转换为128bit的UUIDbase UUID 为00000000-0000-1000-8000-00805F9B34FB只所以本来 128bit的 UUID大部分却采用 16 bit 来发送数据主要是为了提搞传输速率以及减少交互次数
属性句柄Attribute handle
采用 16bit 的值用于标识一个属性范围是 0x0000~0xffff0x0000 是保留数值0xffff 是最大数值所以我们一般不用
属性句柄组Attribute handle grouping
Grouping 是一由高层协议定义的一组属性他们位于其他属性组之前客户可以请求第一个和最后一个与属性组关联的 Handle
属性值Attribute value
属性值是自定义的字段可以是任何类型的数据长度可以是固定的也可以是可变的可变的情况下在一个request、response、notification、indication中只能有一个attribute value固定的情况下长度在attribute type中定义好了这时可以传送多个attribute value
属性权限Attribute permission
Attribute permissions是access permissions、encryption permissions、authentication permissions和authorization permissions的组合。 1access permissions用来表示attribute是否允许client进行读写取值包括Readable、Writeable、Readable and writable 2encryption permissions用来表示是否加密取值包括Encryption required、No encryption required 3authentication permissions用来表示当client访问attribute value时是否需要一个已认证的物理链路同样也表示当server向client发送notification和indication时是否需要一个已认证的物理链路取值包括Authentication Required、No Authentication Required 4authorization permissions用来表示当client访问attribute value时是否需要授权取值包括Authorization Required、No Authorization Required
控制点属性Control-point attributes
不可读,但是可写,可通知(Notified)和可指示(Indicated)的属性被称为Control-Point Attribute 高层协议可使用该属性来使能设备特定过程比如设备上一个给定过程的命令或指示已经完成.
协议方法Protocol methods
ATT 使用 Protocol Methods 来发现、读、写、通知、指示属性方法可分为如 下几种 Request/Response/Command/Notification/Indication/Confirmation
命令(Commands)是 ATT client 发送给 server 端的命令数据并且不要求回复response,以 CMD 结尾. 请求(Requests)是 ATT client 发送给 server 端的请求数据要求 server 回复response,以 REQ 结尾. 响应(Reponses)是 ATT server 为响应 client 请求回复的 response 数据以RSP 结尾. 通知(Notifications)是 ATT server 发送给 client 的通知数据并且不要求回复 confirmation以 NRF 结尾. 指示(Indications)是 ATT server 发送给 client 的指示数据要求 client 发送confirmation 数据以 IND 结尾. 确认(Confirmations)是 ATT client 为了回复 server 发送的 indications,发送的 indications 数据以 CFM 结尾 ATT bearers
就是用来传输 ATT PDU 的 L2CAP 通道
交互MTUExchanging MTU size
ATT_MTU 定义了 Client 和 Server 之间数据包的最大值其默认值由高层协议来定义,Client 和 Server 可通过 Exchange MTU Request and Response PDUs 来交换最大数据包然后均使用交换值中的最小值进行通信同时作为 Server 和Client 的设备应该使用相同的 Client Rx MTU 和 Server Rx MTU,每个 ATT BearerL2CAP等下层协议均有其 ATT_MTU当一个设备拥有多个 ATT Bearer 时不同 ATT Bearer 的 ATT_MTU可能不同
长属性值Long attribute value
1一个数据包最大可以发送的attribute长度是ATT_MTU-1个字节至少Attribute Opcode要占一个字节如果attribute value的长度大于ATT_MTU-1个字节则称为Long Attribute 2read长度大于ATT_MTU-1个字节Attribute需要使用read blob request使用read request可能读取到前面的ATT_MTU-1个字节 3write长度大于ATT_MTU-3个字节Attribute使用prepare write request和execute write request使用write request可能写入前面的ATT_MTU-3个字节 4在ATT协议中无法确定一个attribute的长度是否可以大于ATT_MTU-3在上层协议中将声明给定属性的最大长度可以大于(ATT_MTU-3)字节 5attribute value最大长度是512个字节
原子操作Atomic operations
Server 应该将 Client 的每个请求或命令视为不受影像的原子操作,如果一个链路由于某种原因断开高层协议应当对属性值得修改负责Long Attribute 不能被单一的原子操作读、写
ATT PDUProtocol Data Unit介绍
PDU类型
对应六种协议方法
PDU格式
整个 ATT PDU 包含 3 个部分 1Attribute Opcode 2Attribyte Parameters 3Authentication Signature
Attribute Opcode:ATT PDU 的操作码 Attribyte ParametersATT PDU 的参数每个opcode有自己的参数 Authentication Signature Flag 取值如下
0: PDU 不包含 Authentication Signature, X 为 11: PDU 包含 Authentication Signature(12 octets), X 为 13 当 Attribute PDU 包含 Authentication Signature 时则该 PDU 应该通过加密链路传输 Command Flag 取值如下1: PDU 为一个 Command 注意: 只有 Write Command 可能包含一个 Authentication Signature ATT 是一种 Sequential Protocol这意味着在执行下一个动作前应该得到相应的回应ATT 将 Request-Response 和 Indication-Confirmation Pair 看作一个单一的事务(Transaction)
PDU具体介绍
Error Response
Error Response 用来声明一个给定的请求无法完成并给出原因 备注ATT_WRITE_CMD 不需要回复这个 PDU 参数 Attribute Opcode:操作码在上一小节中有讲此处 ATT_ERROR_RSP PDU(0x01) Request Opcode In Error:是回复哪个请求 Opcode Attribute Handle In Error:发生错误的句柄 Error Code错误码可以查表
MTU exchange
Client 使用 MTU Exchange Request 来告知对方所支持的最大接收 MTU size,同时请求 Server 回应 Server 所支持的最大接收 MTU size. 在低功耗蓝牙连接中属性协议默认的 MTU 为 23 字节。一般客户端如果不发起这个请求的它的默认值就是 23当双方交换的值不同时用较小的那个作为最终使用的值。
Find information
Find information 包括两组 request/response ATT_FIND_INFORMATION_REQ 对应 ATT_FIND_INFORMATION_RSP ATT_FIND_BY_TYPE_VALUE_REQ 对应 ATT_FIND_BY_TYPE_VALUE_RSP
ATT_FIND_INFORMATION_REQ/ATT_FIND_INFORMATION_RSP
查找信息请求和回复用来查找一系列属性的句柄和类型信息。这是唯一一个能让客户端发现任意属性类型的消息。
查找信息请求包含有两个句柄起始句柄和结束句柄。它们定义了该请求用到的属性句柄范围。为了找到所有数值的属性该请求的起始句柄将是 0x0001结束句柄设为 0xFFFF。但是回复的信息中因为长度限制并不能包含所有的属性所以需要再次请求只是将起始句柄改为查找到的最大句柄的后一个句柄开始。
查找信息的响应格式包括format和information Data format代表UUID的类型是16bit还是128bit的 information Data是两字节的Handle标识属性还有两字节或16字节的UUID标识属性类型的
ATT_FIND_BY_TYPE_VALUE_REQ/ATT_FIND_BY_TYPE_VALUE_RSP
按类型值查找请求和回复可以根据给定的类型与数值查找相应的属性。该请求包含有两个句柄 起始句柄和结束句柄规定查找范围。对于这一范围类的所有属性如果和请求中所指定的类型和数值一样那么这个属性就要在响应中返回
Reading attribute
Ready attributes 包括 6 组 request/reponse ATT_READ_BY_TYPE_REQ/ATT_READ_BY_TYPE_RSP ATT_READ_REQ/ATT_READ_RSP ATT_READ_BLOB_REQ/ATT_READ_BLOB_RSP ATT_READ_MULTIPLE_REQ/ATT_READ_MULTIPLE_RSP ATT_READ_BY_GROUP_TYPE_REQ/ATT_READ_BY_GROUP_TYPE_RSP ATT_READ_MULTIPLE_VARIABLE_REQ/ATT_READ_MULTIPLE_VARIABLE_RSP
ATT_READ_BY_TYPE_REQ/ATT_READ_BY_TYPE_RSP
这个命令能在句柄范围内读取某个属性值。当客户端仅知道属性的类型而非句柄时可以使用该请求。请求包含有起始、结束句柄和需要读取的属性的类型。响应将给出符合的句柄和数值。这个请求用于搜索被包含的服务并通过特性类型来发现服务中的所有的特性。它也被用来读取已知类型的特性值
ATT_READ_REQ/ATT_READ_RSP
读取请求是属性协议总最简单的请求。该请求包含一个句柄响应将返回该句柄对应的属性值。只有在客户端已知属性句柄的情况下才能使用该请求读取属性值。
ATT_READ_BLOB_REQ/ATT_READ_BLOB_RSP
有时属性值太长无法装入一个读取响应须使用大对象读取请求来获取剩余字节。大对象读取请求不光包含属性句柄还包含属性值的这个数据中的偏移量。 其响应将从属性偏移量开始包含尽可能多的属性值。在获得了属性值的前 22 (ATT_MTU-1)节后假如客户端还想获取后续的属性值则使用大对象读取请求。下一条响应将返回第 23 个字节到 44 个字节如此继续直到客户端读取到完整的属性值。该请求用于读取长特征值与长特征描述符。
ATT_READ_MULTIPLE_REQ/ATT_READ_MULTIPLE_RSP
用来在一个操作中读取多个属性值。该请求包含一个或多个属性句柄响应则按顺序返回相应的属性值。然而因为响应中的数值之间没有界限因此在请求中除了最后一个属性允许可变的长度其他属性必须为定长的属性值。也就是说如果客户端用一个多重读取请求来读取三个属性前两个属性的长度必须固定最后一个属性的长度则可以变化。如果客户端请求读取的属性值的长度超过了响应数据包所能承载的最大长度那么无法放入响应数据包的数值将被丢弃。
ATT_READ_BY_GROUP_TYPE_REQ/ATT_READ_BY_GROUP_TYPE_RSP
它和按类型读取请求类似也包含有一个句柄范围读取时将其视为一个属性的类型来处理只不过属性的类型必须为分组属性。其响应包含所读取的属性句柄、属性分组中最后一个属性以及属性的数值。这意味着如果分组类型是首要服务它将返回所有首要服务声明的属性句柄、该首要服务中最后一个属性以及首要服务声明的数值。因此可以仅凭单个请求来发现设备上的所有首要服务、与之关联的属性句柄的范围以及这些服务的类型。如同其他返回对个句柄-数值对的响应如果返回的值长度可变那么只有长度相同的属性值将在第一个响应中被返回。因此客户端必须再次发起请求更新起始句柄来发现想要获取的下一个属性
Writing attributes
Write attributes 包括 1 组 request/response两组 command
ATT_WRITE_REQ/ATT_WRITE_RSP
这个是写特定的 handle 的属性值
ATT_WRITE_CMD
写入命令类似于读取请求区别是写入命令没有响应。写入命令包含要写入的属性的句柄和要写入的数值。当无需响应时可以使用写入命令。
ATT_SIGNED_WRITE_CMD
签名写命令和写命令类似只是前者包含认证签名。通过这样的机制发送端可以向服务器发送写入命令时认证自己而无需加密通信连接。签名写命令适用于以下两种场合 1发起加密将显著增加数据连接的延迟 2发起加密将显著增加简短且无需加密的数据的送达成本 认证签名由签名计数器和消息认证码构成。签名计数器对设备间发送的每一条消息赋予不同的值不论消息发送的间隙连接中断与否。使用签名计数器可以抵御消息重放攻击因此假如签名写入命令的签名计数器值和先前的值相同该命令会被忽略。消息认证码长度为 64 位该码位于句柄、数值和签名计数器之后。注意服务器需要为每一个客户端保存其最后使用的签名计数器。
Queued writes
长属性的写入需要分为两步先准备写再执行写 准备写ATT_PREPARE_WRITE_REQ 和ATT_PREPARE_WRITE_RSP 准备写过程是客户端将长属性分段传输给了服务器服务器先放入缓存队列之中传完之后再执行写 执行写ATT_EXECUTE_WRITE_REQ 和ATT_EXECUTE_WRITE_RSP 执行写过程就是将之前收到的属性值写入真正的属性中
Server initiated
Server initiated 包括 1 组 indication/confirms,两组 notification ATT_HANDLE_VALUE_NTF ATT_HANDLE_VALUE_IND/ATT_HANDLE_VALUE_CFM ATT_MULTIPLE_HANDLE_VALUE_NTF
ATT_HANDLE_VALUE_NTF
当服务器想要向客户端发送快速的属性状态更新时可以发送一条句柄值通知。这个是服务器能够发给客户端的两种消息中的一种并且是不要求响应的那种。
ATT_HANDLE_VALUE_IND/ATT_HANDLE_VALUE_CFM
句柄值指示类似于句柄值通知。它有着相同的属性句柄字段和数值不同的是客户端收到指示以后应回复。服务器一次只能发送一条指示并且只有收到确认响应后才能发起下一条指示。 句柄值确认不含任何数据主要用于流控。因为具备了确认机制指示被视为可靠传输。一旦服务器收到确认信息它便能确定客户端收到了该信息。
ATT_MULTIPLE_HANDLE_VALUE_NTF
可以发送两个或者两个以上的 notification
通用属性协议GATT
GATT概念
GATT(Generic Attribute Profile)描述了一种使用 ATT 的服务框架 该框架定义了服务(Server)和服务属性(characteristic)的过程(Procedure)及格式 。Procedure 定义了 characteristic 的发现、读、写、通知(Notifing)、指示(Indicating)及配置 characteristic 的广播。 GATT 可以被 Application 或其他 Profile 使用其协议栈如下图
PC 就是做 GATT client 用来读取温度计的数据,温度计 Sensor 做 GATT server 用来把温度数据发送送出去
GATT层级
GATT 指定了数据交互的结构(Structure)这个结构体定义了一些基本元素如Service、Characteristic 这些元素存在于 Attribute 中层级结构如下 GATT 中最上层是 ProfileProfile 由一个或多个服务(Service)组成 服务是由 Characteristics 组成或是其他服务的引用(Include)Characteristic 包含一个值(Value)可能包含该 Value 的相关信息
服务service
一个service是被service definition定义的service definition可能包含其他services的引用、必须的characteristics和可选的characteristics
有两种类型的 service 1Primary Service : 拥有基本功能的服务,可被其他服务包含,可以通过Primary Service Discovery 过程来发现 2Secondary Service : 仅用来被 Primary/Other Secondary Service、高层协议引用的服务.
service definition肯定包含一个service declaration可能包含include definitions 和characteristic definitions发现下一个service declaration或者Attribute Handle达到最大值则表示service definition结束了
特性Characteristic
Characteristic 由 Characteristic Definition 定义包含一个特征声明Characteristic declaration、特征值声明(Characteristic Value declaration)和可选的特征的描述声明(characteristic descriptor declarations)
特性声明Characteristic declaration
特性声明Characteristic declaration特性声明本身的 UUID 值是 0x2803特性声明中需要声明的特性是在属性值中的属性值包含有 3 个字段 特性性质、属性句柄和属性类型且仅为只读。如下
特征值声明Characteristic Value declaration
Characteristic Value declaration包含characteristic的valueCharacteristic Value declaration紧跟在characteristic declaration之后一个characteristic definitions都有一个Characteristic Value declaration具体组成如下图所示
特征的描述声明characteristic descriptor declaration
Characteristic descriptors主要包含一些Characteristic Value的相关信息.Characteristic descriptors位于Characteristic Value declaration之后多个Characteristic descriptors之间没有顺序要求。
客户端特性配置描述符Client Characteristic Configuration
支持通知或者指示的特性必须使用客户端配置描述符。它的声明格式如图所示。 该描述符是一个 2byte 的数值分别用于设置通知与指示但是不允许同时设置。
服务器特性配置描述符Server Characteristic Configuration
使设备广播该特性所属服务的相关数据格式如下
特性表示格式描述符Characteristic Presentation Format
Characteristic Presentation Format declaration定义Characteristic Value的格式如果在characteristic definition中有超过1个Characteristic Presentation Format declarations存在那么肯定要有一个Characteristic Aggregate Format declaration存在
特定聚合格式描述符Characteristic Aggregate Format
有些特性值远比单一的数据复杂得多。譬如用标准的符号来表示地球上的某个位置通常包含经度和纬度值二者组合在一起便构成一个“坐标值”。为了构造类似的复杂的特性值特性聚合格式描述符允许引用多个表示格式描述符来解释组合值的每个字段
GATT特性
GATT 一共定义了 11 个特性如下 There are 11 features defined in the GATT Profile:
Server ConfigurationPrimary Service DiscoveryRelationship DiscoveryCharacteristic DiscoveryCharacteristic Descriptor DiscoveryReading a Characteristic ValueWriting a Characteristic ValueNotification of a Characteristic ValueIndication of a Characteristic Value 10.Reading a Characteristic Descriptor 11.Writing a Characteristic Descriptor
Server Configuration
这个功能是client用来设置ATT的MTU当client的ATT_MTU大于default ATT_MTU时client就会调用Exchange MTU程序配置ATT_MTU这个程序只有在连接过程中执行一次虽然Spec中规定只能使用一次但是NRF connect中可以无限测试。 (client和server都会取Client Rx MTU和Server Rx MTU中最小的值作为ATT_MTU
Primary Service Discovery
Client使用这个功能搜索server上的primary services这个功能分为两个子程序Discover All Primary Services和Discover Primary Services by Service UUID
Discover All Primary Services Discover Primary Service by Service UUID
举例 1Client使用ATT的Find By Type Value Request设置Attribute Type为«Primary Service»Starting Handle0x0001Ending Handle0xFFFFAttribute Value设置为UUID1 2server回复Find By Type Value ResponseHandles Information List为0x0200,0x0214最后一个元素的Group End Handle0x0214不是0xFFFF所以没有结束。 3client继续ATT的Find By Type Value Request设置Attribute Type为«Primary Service»Starting Handle1 0x02140x0215Ending Handle0xFFFFAttribute Value设置为UUID1 4server回复Error ResponseError Code为«Attribute Not Found»搜索结束
Relationship Discovery 举例 1Client使用Read By Type RequestAttribute Type为«Include»Starting Handle为包含这个«Include»的Service的starting handle即0x0200Ending Handle为包含个«Include»的Service的最后一个handle即0x0214 2server回复Read By Type ResponseLength0x08Attribute Data List为0x0201,0x0500,0x518,«UUID1»其中0x08表示Attribute Data List中每个元素的长度0x0201表示include declaration的handle0x0500,0x518分别表示被包含的那个service的service declaration、End Group Handle«UUID1»即被包含的service的16bit的UUID。0x0201!0x0214所以没有结束。 3client继续发送ATT的Read By Type Request设置Attribute Type为«Include»Starting Handle1 0x02010x0202Ending Handle0x0214 4server回复Read By Type ResponseLength0x06Attribute Data List为0x0202,0x0550,0x568其中0x06表示Attribute Data List中每个元素的长度0x0202表示include declaration的handle0x0550,0x558分别表示被包含的那个service的service declaration、End Group Handle没有被包含的那个service的UUID所以被包含的那个service的UUID应该是128bit的需要使用Read Request去获取 5Client使用Read RequestAttribute Handle参数设置为0x550 6Server回复Read Response参数Attribute Value就是被包含的那个service的128bit的UUID 7client继续发送ATT的Read By Type Request设置Attribute Type为«Include»Starting Handle1 0x02020x0203Ending Handle0x0214 8server回复Error ResponseError Code为«Attribute Not Found»搜索结束
Characteristic Discovery
Discover All Characteristics of a Service
举例 1Client使用Read By Type RequestAttribute Type为«Characteristic»Starting Handle为包含个«Characteristic»的Service的starting handle即0x0200Ending Handle为包含这个«Characteristic»的Service的最后一个handle即0x0214 2server回复Read By Type ResponseLength0x07Attribute Data List为0x0203,0x02,0x0204, «UUID1»,0x0210,0x02,0x212,«UUID2»其中0x07表 示Attribute Data List中每个元素的长度0x0203,0x02,0x204, «UUID1»是第一个Attribute Handle和Attribute Value对Attribute Handle0x0203Characteristic Properties0x02Characteristic Value Handle0x0204Characteristic UUID «UUID1»0x0210,0x02,0x212,«UUID2»是第二个Attribute Handle和Attribute Value对0x0210!0x0214所以没有结束。 3client继续发送ATT的Read By Type Request设置Attribute Type为«Characteristic»Starting Handle1 0x02100x0211Ending Handle0x0214 4server回复Error ResponseError Code为«Attribute Not Found»搜索结束
物理通道被细分为时间单位称为事件。数据以包的形式在LE设备之间传输这些包位于这些事件中。事件类型包括:Advertising事件、Extended Advertising事件、Periodic Advertising事件、Connection事件和Isochronous事件(分为BIS、BIG、CIS和CIG事件)。
Descriptor学习
characteristic Extended properties
这个描述符每个characteristic只能有一个 在characteristic properties中extended properties位是1那么这个描述符应该存在 只读无需认证无需授权
value
reliable write 只占1bit 允许这个characteristic的value进行可靠写 可靠写过程举例如下 writable Auxiliaries 只占1bit 允许写这个characteristic 的 characteristic user Descriptor
characteristic user Descriptor
这个描述符每个characteristic只能有一个 这个就是用户描述这个characteristic的描述符value就是UTF-8的字符串
client characteristic configuration
这个描述符每个characteristic只能有一个 这个描述符的配置应在跨连接的绑定设备中保持持久掉电保存。客户端特征配置描述符值应在每次与非绑定设备连接时设置为默认值。 每个客户端都有自己的客户端特征配置实例。读取客户端特征配置仅显示该客户端的配置写入仅影响该客户端的配置。服务器可能需要进行身份验证和授权才能写入配置描述符。 属性值长度应为两个八位字节并应设置为特征描述符值。
value
notification占1位如果这位为1这个characteristic value变化了通知订阅了这个值的客户端 Indication占1位如果这位为1这个characteristic value变化了指示订阅了这个值的客户端
server characteristic configuration
这个描述符每个characteristic只能有一个 这个描述符对所有客户端有效 实际上就是确定这个characteristic value是否要被广播