蓝牙笔记
2017-01-04 14:53
197 查看
一、蓝牙4.0BLE简介
1.1 什么是蓝牙4.0BLE
蓝牙低功耗技术(Bluetooth Low energy),拥有超低运行功耗和待机功耗。1.2 蓝牙4.0BLE特点
高可靠性低成本。低功耗
快速启动,瞬间连接
传输距离提高
高安全性
1.3 蓝牙4.0BLE协议简介
蓝牙4.0BLE中定义了GAP(generic access profile)和GATT(generic attribute)两个基本配置文件。GAP:负责设备访问模式和进程,包括设备发现、建立连接、终止连接、初始化安全特性和设备配置。
GATT:用于已连接的蓝牙设备之间的数据通信。
二、蓝牙4.0BLE协议栈
2.1 什么是蓝牙4.0BLE协议栈
协议栈是协议的具体实现形式,通俗的可以理解为用代码实现的函数库,以便于开发人员的调用。不同厂商提供的协议栈是有区别的。蓝牙4.0BLE协议栈就是将各个层定义的协议都集合在一起,以函数的形式实现并提供一些应用层API供用户调用。
2.2 蓝牙4.0BLE协议栈的构成
TI的蓝牙4.0BLE协议栈包含两部分:主机和控制器。协议栈的实现方式采用分层思想。
控制器:物理层、链路层、主控制接口层。
主机:逻辑链路控制及自适应协议层、安全管理层、属性协议层、通用访问配置文件层、通用属性配置文件层。
物理层:1Mbps自适应跳频的GFSK射频
链路层:用于控制设备的射频状态
主机控制接口层:为知己和控制器之间提供标准通信接口,可以是软件API或硬件接口,如UART、SPI、USB
逻辑链路控制及自适应协议层:为上层提供数据封装服务
安全管理层:定义了配对和密钥分配方式,并为协议栈其他层与另一个设备之间的安全连接和数据交换提供服务
属性协议层:允许设备向另一个设备展示一块特定的数据,称之为“属性”。在ATT环境中,展示“属性的”设备称为服务器,与之配对的设备称为客户端
通用属性配置文件层:定义了使用ATT的服务框架,规定了配置文件的结构。在BLE中,所有被profile或服务用的到数据块都成为“特性”,两个建立连接的设备之间的所有数据通信都是通过GATT子程序处理
2.3 通用访问配置文件(GAP)
GAP层总是作为下面四种角色之一:广播者:不可连接的广告设备
观测者:扫描广播,但不发起建立连接
外部设备:可连接的广告设备
集中器:扫描广告设备并发起连接,在单链路层或多链路层作为主机。目前,BLE协议栈支持一个集中器连接三个外设。
2.3.1在典型的BLE中,设备发现的全过程:
从机(外部设备)发送广告数据(包含设备地址、设备名称)主机(集中器)收到广告数据后,发送扫描请求
从机(外部设备)发送扫描回应,让主机知道该设备为可连接设备
此时,集中器可以向外部设备发起建立连接的请求,连接请求包括下面的一些连接参数:
连接间隔:在两个BLE设备的连接中使用跳频机制,两个设备使用特定的信道收发数据,然后过一段时间后再使用新的信道(链路层处理信道切换),两设备在信道切换后收发数据称之为连接事件。即使没有应用数据的收发,两设备仍然会通过交换链路层数据来维持连接。连接间隔就是两个连接事件之间的时间间隔,连接间隔以1.25为单位,连接间俩的值为6(7.5ms)~3200(4s)。
不同的应用可能要求不同的时间间隔。长的时间间隔的优势是显著地节省功耗,因为设备可以在连接事件之间有较长时间的休眠,坏处是当设各有应用数据需要发送时,必须要等到下一个连接事件;短的时间间隔的优势是两设备连接频发,可以更快地收发数据,坏处是设备因连接事件的到来而被濒繁地唤醒,会有较多功耗。
从机延迟:这个参数的设置可以使从机(外部设备)跳过若干连接事件,这给了外设更多的灵活度,如果它没有数据发送时,可以选择跳过连接事件继续休眠,以节省功耗。
管理超时:这是两个成功连接事件之间的最大允许间隔。如果超过了这个时间而没有成功的连接事件,设备被认为是丢失连接,返回到未连接状态。这个值的单位是10ms,管理超时的范围是10(100ms)~3200 (32s)。另外,超时值必须大于有效的连接间隔[有效的连接间隔=连接间隔*(1+从机延迟)]。
注意:外设可以通过向集中器发送“连接参数更新请求”来改变连接设置,这个请求由协议栈的L2CAP层处理。这个请求包含4个参数:最小连接间隔、最大连接间隔、从机延迟、超时。这些值代表了外设所要求的连接参数。当集中器收到请求后,可以选择接受或拒绝这些新的参数。
代码片段
//广播间隔,数值越大功耗越低,但是广播的包的时间间隔就太长(units of 625us, 160=100ms) #define DEFAULT_ADVERTISING_INTERVAL 50 //连接间隔与数据发送量有关, 连接间隔越短, 单位时间内就能发送越多的数据(units of 1.25ms, 80=100ms) #define DEFAULT_DESIRED_MIN_CONN_INTERVAL 6 //连接间隔与数据发送量有关, 连接间隔越短, 单位时间内就能发送越多的数据(units of 1.25ms, 800=1000ms) #define DEFAULT_DESIRED_MAX_CONN_INTERVAL 6 //各种原因断开连接后,超时并重新广播的时间:100 = 1s (units of 10ms, 1000=10s) #define DEFAULT_DESIRED_CONN_TIMEOUT 300 // GAP - SCAN RSP data (max size = 31 bytes) static uint8 scanRspData[] = { // complete name 0x14, // length of this data GAP_ADTYPE_LOCAL_NAME_COMPLETE, 0x53, // 'S' 0x69, // 'i' 0x6d, // 'm' 0x70, // 'p' 0x6c, // 'l' 0x65, // 'e' 0x42, // 'B' 0x4c, // 'L' 0x45, // 'E' 0x50, // 'P' 0x65, // 'e' 0x72, // 'r' 0x69, // 'i' 0x70, // 'p' 0x68, // 'h' 0x65, // 'e' 0x72, // 'r' 0x61, // 'a' 0x6c, // 'l' // connection interval range 0x05, // length of this data GAP_ADTYPE_SLAVE_CONN_INTERVAL_RANGE, LO_UINT16( DEFAULT_DESIRED_MIN_CONN_INTERVAL ), // 100ms HI_UINT16( DEFAULT_DESIRED_MIN_CONN_INTERVAL ), LO_UINT16( DEFAULT_DESIRED_MAX_CONN_INTERVAL ), // 1s HI_UINT16( DEFAULT_DESIRED_MAX_CONN_INTERVAL ), // Tx power level 0x02, // length of this data GAP_ADTYPE_POWER_LEVEL, 0 // 0dBm }; /////////////////////////////////// void SimpleBLEPeripheral_Init( uint8 task_id ) { ........ GAPRole_SetParameter( GAPROLE_SCAN_RSP_DATA, sizeof ( scanRspData ), scanRspData ); ........
2.3.2终止连接
连接可以被主机或从机以任何原因自动终止。当一方发起终止连接时,另一方必须响应,然后两个设备才能退出连接状态。2.3.3安全特征初始化
只有在已认证的连接中,特定的数据才能被读写。一旦建立连接,两个设备进行配对,当配对完成后,形成加密链接的密钥。在外设应用中,外设请求集中器提供密钥来完成配对工作,密钥可以是一个固定值或随机值,当集中器设备发送正确的密钥后,两设备交换安全密钥并加密认证链接。安全机制中,有一绑定特性允许两个已连接过的设备之间建立长期的安全密钥信息,可以让两设备重新连接时快速的完成加密认证,不用每次都执行完整的配对过程。
2.4 通用属性配置文件(GATT)
两个设备应用数据的通信是通过协议栈的GATT层实现。从GATT角度来看,当两个设备建立连接后,他们处手下面两种角色之一:GATT服务器—它是为GATT客户端提供数据服务的设备
GATT客户端—它是从GATT服务器读写应用数据的设备
需要特别注意的是,GATT角色中的客户端和服务器的概念与链路层的主机和从机概念完全独立,与GAP角色中的外设和集中器概念也是完全独立的。主机既可以是GATT客户端也可以是GATT服务器;从机既可以是GATT客户端也可以是GATT服务器。
一个GATT服务器中可包含一个或多个GATT服务,GATT服务是完成特定功能的一系列数据的集合。在示例土程SimpieBLEPeripheral应用中,有三个GATE服务。
2.4.1GATT服务
强制的GAP服务:这一服务包含了设备和访问信息。例如,设备名、设备供应商和产品标识。它是协议栈的一部分,是BLE规范对每一个BLE设备的强制要求。这部分源代码并没有提供,而是编译到协议找库文件中了强制的GATT服务:这一服务包含了GATT服务器的信息,是协议栈的一部分,是BLE规范对每一个BLE设备的要求。这部分源代码编译到协议栈库文件中了
“特性”(Characteristies)是服务用到的值,以及其内容和配置信息。GATT定义了在BLE连接中发现、读取和写入属性的子过程。GATT服务器上的特性值,及其内容和配置信息(称为描述符)存储于属性表中。属性表是一个数据库,包含了称为属性的小块数据,除了值本身,每个属性都包含下列属性:
句柄:属性在表中的地址,每个属性有唯一的句柄
类型:表示数据代表的事务,通常是蓝牙技术联盟规定或由用户自定义的UUID(Universally Unique Identifier)
权限:规定GATT客户端设备对属性的访问权限,包括是否能访问和怎样访问。
2.4.2服务器与客户端通讯的子过程
读特性值:客户端设备请求读取句柄处的特性值,服务器将此值回应给客户端(假定属性有读权限)。使用特性的UUID读:客户端请求读基于一个特定类型的所有特性值,服务器将所有与指定类型匹配的特性的句柄和值回应给客户端(假定属性有读权限)。
读多个特性值:客户端一次请求中读取几个句柄的特性值,服务器将这些特性值回应给客户端(假设属性有读权限)。客户端需要知道如何解析这些不同特性值的数据。
读特性描述符:客户端请求读特定句柄处的特性描述符,服务器将特性描述符的值回应给客户端设备(假定属性有读权限)。
使用UUID发现特性:客户端通过发送“特性”的类型UUID来请求发现这个“特性”的句柄。服务器将这个“特性”的声明回应给客户端设各,其中包括特性值的句柄以及“特性”的权限。
写特性值:客户端设各请求向服务器特定的句柄处写入特性值,服务器将数据是否写入成功的信息反馈给客户端。
写特性描述符:客户端设备请求向服务器特定的句柄处写入特性描述符,服务器将特性描述符是否写入成功的信息反馈给客户端。
特性值通知:服务器将一个特性值通知给客户端。客户端设备不需要向服务器请求这个数据,当客户端收到这个数据时,也不需要回应服务器。但需要注意的是,要想使能服务器通知,首先要配置好特性,profile中定义了什么时候服务器应该发送这个数据。
2.4.2服务发现
当集中器设备作为客户端,需要读取外设中提供的数据服务是,需要首先进行服务发现。客户端进行GATT服务发现时,需要给出要发现的服务的UUID,只有服务UUID配对,才能获得GATT数据服务。在建立连接回调函数中使用OSAL定时器设置了一个定时事件,即为GATT服务发现事件。定时时间到达后,调用事件处理函数来处理这个时间。三、示例工程
3.1节点设备示例工程
应用程序初始化分为两个阶段:1. 第一阶段:调用’SimpleBLEPeripheral_Init’函数,该函数设置了GAP任务配置文件参数、GAP特性、GAP绑定管理参数、GATT配置文件参数
void SimpleBLEPeripheral_Init( uint8 task_id ) { .............. osal_set_event( simpleBLEPeripheral_TaskID, SBP_START_DEVICE_EVT ); }
第二阶段:用SimpleBLEPeripheral_ProcessEvent()事件函数来处理。
uint16 SimpleBLEPeripheral_ProcessEvent( uint8 task_id, uint16 events ) { VOID task_id; if ( events & SYS_EVENT_MSG )// 系统事件 { uint8 *pMsg; if ( (pMsg = osal_msg_receive( simpleBLEPeripheral_TaskID )) != NULL ) { simpleBLEPeripheral_ProcessOSALMsg( (osal_event_hdr_t *)pMsg ); VOID osal_msg_deallocate( pMsg ); } return (events ^ SYS_EVENT_MSG); } if ( events & SBP_START_DEVICE_EVT ) { // Start the Device VOID GAPRole_StartDevice( &simpleBLEPeripheral_PeripheralCBs ); VOID GAPBondMgr_Register( &simpleBLEPeripheral_BondMgrCBs ); osal_start_timerEx( simpleBLEPeripheral_TaskID, SBP_PERIODIC_EVT, SBP_PERIODIC_EVT_PERIOD ); return ( events ^ SBP_START_DEVICE_EVT ); } .............. return 0; }
初始化完成后,设备处于可发现状态,未指定广告接收者。此时,集中器设备可以通过扫描来发现这个设备。如果集中器设备向这个外设发送连接请求,则外设接受请求并作为从机进入连接状态。外设发送广告并处于可发现状态时,有两种模式:
受限的发现模式
外设在发送广告时,如果没收到集中器设备发来的建立连接的请求,则只保持30S的可发现状态,然后 转为不可被发现的待机状态。
不受限的发现模式
外设在没有收到集中器设备的连接请求时,一直发送广告,处于可被发现的状态。
//受限的可发现模式 #define DEFAULT_DISCOVERABLE_MODE GAP_ADTYPE_FLAGS_LIMITED //不受限的可发现模式 #define DEFAULT_DISCOVERABLE_MODE GAP_ADTYPE_FLAGS_GENERAL
3.2集中器示例工程
应用初始化分为两个阶段:第一阶段:调用’SimpleBLECentral_Init’函数,该函数设置了GAP任务配置文件参数、GAP特性、GAP绑定管理参数、初始化GATT配置文件参数,在属性服务器中设置标准的GAP和GATT服务。
第二阶段:调用SimpleBLECentral_ProcessEvent事件处理函数来处理第二阶段的初始化工作,这一阶段使用’GAP_CentralRole_StartDevice’函数来社会资应用的GAP功能,然后调用GAPBondMgr_Register函数来注册绑定管理。
simpleBLECentralRssiCB
GAP RSSI回调函数,用来显示最新的RSSI(接收的信号强度指示)值,为无线发送层的可选部分,用来判断链接质量,以及是否增大广播发送强度。
simpleBLECentralEventCB
GAP事件回调函数,是在设备初始化阶段注册的,GAP状态改变时调用,用来对GAP初始化、设备发现、设备连接、断开连接等事件进行处理。
simpleBLECentralPairStateCB
GAP绑定管理状态回调函数,用于显示配对和绑定操作的状态。
simpleBLECentralPasscodeCB
GAP绑定管理密钥回调函数,用来生成和显示一个密钥。
3.2.1服务发现
当集中器设备作为客户端,需要读取外设中提供的数据服务是,需要首先进行服务发现。客户端进行GATT服务发现时,需要给出要发现的服务的UUID,只有服务UUID配对,才能获得GATT数据服务。在建立连接回调函数中使用OSAL定时器设置了一个定时事件,即为GATT服务发现事件。定时时间到达后,调用事件处理函数来处理这个时间。if ( events & START_DISCOVERY_EVT ) { simpleBLECentralStartDiscovery( );//调用服务发现处理函数,进行GATT数据服务的发现 return ( events ^ START_DISCOVERY_EVT ); } ................... static void simpleBLECentralStartDiscovery( void ) { //指定GATT服务发现的UUID分为高8位和低8位 uint8 uuid[ATT_BT_UUID_SIZE] = { LO_UINT16(SIMPLEPROFILE_SERV_UUID),HI_UINT16(SIMPLEPROFILE_SERV_UUID) }; BLE_DEV *p = &(gDev[simpleBLEScanIdx]); //将服务的起始句柄、结束句柄以及“特性”句柄清零 p->simpleBLESvcStartHdl = p->simpleBLESvcEndHdl = 0; //将当前发现状态标志设为服务发现 p->simpleBLEDiscState = BLE_DISC_STATE_SVC; //通过指定的服务UUID发现基本服务,只发现UUID匹配的服务。这一函数处理上一次GATT过程的结果,并初始化下一步的发现操作。 GATT_DiscPrimaryServiceByUUID( p->simpleBLEConnHandle, uuid, ATT_BT_UUID_SIZE, simpleBLETaskId ); }
BLE链接相关技术分析