HID初始化
广播包数据解析


1、第一个0x02是长度 ,后面跟着类型和数据 长度是类型加数据的和
2、前面的4条是广播数据包,后面的3条扫描数据包
看程序里是这样的
// Advertising data
static uint8 advData[] =
{// flags0x02, // length of this dataGAP_ADTYPE_FLAGS, //0x01GAP_ADTYPE_FLAGS_LIMITED | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED, //0x05// appearance0x03, // length of this dataGAP_ADTYPE_APPEARANCE, //0x19LO_UINT16(GAP_APPEARE_HID_GAMEPAD), //0x03HI_UINT16(GAP_APPEARE_HID_GAMEPAD), //0xc4// service UUIDs0x03, // length of this dataGAP_ADTYPE_16BIT_COMPLETE, //0x03LO_UINT16(HID_SERV_UUID), //0x18HI_UINT16(HID_SERV_UUID), //0x120x04,GAP_ADTYPE_OOB_CLASS_OF_DEVICE, //0xd0x04,0x05,0x00,};// GAP Profile - Name attribute for SCAN RSP data
static uint8 scanData[] =
{// appearance0x03, // length of this dataGAP_ADTYPE_APPEARANCE, //0x19LO_UINT16(GAP_APPEARE_HID_GAMEPAD), //0x03HI_UINT16(GAP_APPEARE_HID_GAMEPAD), //0xc4// service UUIDs0x03, // length of this dataGAP_ADTYPE_16BIT_COMPLETE, //0x03LO_UINT16(HID_SERV_UUID), //0x18HI_UINT16(HID_SERV_UUID), //0x120x0D, // length of this data GAP_ADTYPE_LOCAL_NAME_COMPLETE, // AD Type = Complete local name //0x09'H', //0x'I','D',' ','K','e','y','b','o','a','r','d'
};
在GATT中实现HID要求的服务和特性。

0x1812是HID Service的UUID,必须要使用该UUID实现服务。
0x2A4A是HID Information 的特性UUID,主要功能是展示HID的信息,其值为4个字节,前两个字节是HID版本,一般填入0x01,0x01,表示版本号为1.1。第三个字节是Country Code,一般填入0x00。第四个字节是HID Flags,一般填入0x02,表示Normally Connectable。
0x2A4B是Report Map的特性UUID,主要功能是描述HID设备与HID主机数据交互的方式,即二者之间所发送的数据每一位的含义。
0x2A4C是Control Point的特性UUID,该特性一定要可Write ,HID主机通过该特性告知HID设备主机的状态,比如电脑休眠后会告知蓝牙键盘也进入低功耗模式。
0x2A4D是HID设备与HID主机之间交互数据(Report)的特性UUID。对于键盘设备,当某个按键按下时,HID设备发送数据到HID主机;当开关CapsLock,NumsLook和ScrollLook功能时,HID主机将相关指示灯的状态发送给HID键盘。所以键盘设备需要两个UUID为0x2A4D的特性,一个用于发送数据,另一个用于接收数据(使用UUID为0x2908的描述来区分)。而对于鼠标,游戏手柄这种只发送数据给电脑的设备,只需要定义一个0x2A4D的特性用来发送数据就可以了(当然定义两个也不会出错)。
0x2A4E是协议模式的特性UUID,对于键盘和鼠标这两种设备,可能也会在电脑BIOS阶段使用,此阶段的计算机没有进入系统,难以支持复杂的设备。所以键盘鼠标就有两种模式,分别是Report模式和Boot模式,系统启动前使用的是Boot模式,HID设备与HID主机之间使用固定的数据格式进行交互。系统启动完成后,HID主机会通过该特性发数据给HID设备,通知HID设备切换成Report模式,在Report模式下,数据格式由 Report Map 决定。
该特性的数据值为0x00表示Boot模式,0x01表示Report模式。
在Boot模式下,Keyboard Input 的特性UUID是0x2A22,Output 的特性UUID是0x2A32;Mous Input 的特性UUID是0x2A33。
(作者:我是鹏老师 https://www.bilibili.com/read/cv15067064 出处:bilibili)
void HidKbd_Init( uint8 task_id )
{hidKbdTaskId = task_id;LOG("%s\n",__FUNCTION__);// Setup the GAPVOID GAP_SetParamValue( TGAP_CONN_PAUSE_PERIPHERAL, DEFAULT_CONN_PAUSE_PERIPHERAL );// calibration time for 2 connection event, will advance the next conn event receive window// SLAVE_CONN_DELAY for sync catch, SLAVE_CONN_DELAY_BEFORE_SYNC for sync not catch// pGlobal_config[SLAVE_CONN_DELAY] = 500;//0;//1500;//0;//3000;//0; ---> update 11-20// pGlobal_config[SLAVE_CONN_DELAY_BEFORE_SYNC] = 1100; //800-1100// Setup the GAP Peripheral Role Profile{uint8 initial_advertising_enable = TRUE; //开启广播// By setting this to zero, the device will go into the waiting state after// being discoverable for 30.72 second, and will not being advertising again// until the enabler is set back to TRUEuint16 gapRole_AdvertOffTime = 0;uint8 enable_update_request = DEFAULT_ENABLE_UPDATE_REQUEST; // 是否自动更新uint16 desired_min_interval = DEFAULT_DESIRED_MIN_CONN_INTERVAL; //最小的连接间隔时间uint16 desired_max_interval = DEFAULT_DESIRED_MAX_CONN_INTERVAL; // 最大连接间隔时间uint16 desired_slave_latency = DEFAULT_DESIRED_SLAVE_LATENCY; // 从设备延迟使用uint16 desired_conn_timeout = DEFAULT_DESIRED_CONN_TIMEOUT; //超时时间参数设置 5s// Set the GAP Role ParametersGAPRole_SetParameter( GAPROLE_ADVERT_ENABLED, sizeof( uint8 ), &initial_advertising_enable ); //是否开启广播GAPRole_SetParameter( GAPROLE_ADVERT_OFF_TIME, sizeof( uint16 ), &gapRole_AdvertOffTime ); //GAPRole_SetParameter( GAPROLE_ADVERT_DATA, sizeof( advData ), advData ); //GAPRole_SetParameter( GAPROLE_SCAN_RSP_DATA, sizeof ( scanData ), scanData ); //GAPRole_SetParameter( GAPROLE_PARAM_UPDATE_ENABLE, sizeof( uint8 ), &enable_update_request ); //GAPRole_SetParameter( GAPROLE_MIN_CONN_INTERVAL, sizeof( uint16 ), &desired_min_interval ); //GAPRole_SetParameter( GAPROLE_MAX_CONN_INTERVAL, sizeof( uint16 ), &desired_max_interval ); //GAPRole_SetParameter( GAPROLE_SLAVE_LATENCY, sizeof( uint16 ), &desired_slave_latency ); //GAPRole_SetParameter( GAPROLE_TIMEOUT_MULTIPLIER, sizeof( uint16 ), &desired_conn_timeout ); //}uint8 appearence_data[2];appearence_data[0]=LO_UINT16(GAP_APPEARE_HID_GAMEPAD);//GAP_APPEARE_HID_KEYBOARDappearence_data[1]=HI_UINT16(GAP_APPEARE_HID_GAMEPAD);//GAP_APPEARE_HID_KEYBOARDGGS_SetParameter( GGS_APPEARANCE_ATT, 2, (void*) appearence_data );// Set the GAP CharacteristicsGGS_SetParameter( GGS_DEVICE_NAME_ATT, GAP_DEVICE_NAME_LEN, (void*) attDeviceName );// Setup the GAP Bond Manager{uint32 passkey = DEFAULT_PASSCODE;uint8 pairMode = DEFAULT_PAIRING_MODE;uint8 mitm = DEFAULT_MITM_MODE;uint8 ioCap = DEFAULT_IO_CAPABILITIES;uint8 bonding = DEFAULT_BONDING_MODE;GAPBondMgr_SetParameter( GAPBOND_DEFAULT_PASSCODE, sizeof( uint32 ), &passkey );GAPBondMgr_SetParameter( GAPBOND_PAIRING_MODE, sizeof( uint8 ), &pairMode );GAPBondMgr_SetParameter( GAPBOND_MITM_PROTECTION, sizeof( uint8 ), &mitm );GAPBondMgr_SetParameter( GAPBOND_IO_CAPABILITIES, sizeof( uint8 ), &ioCap );GAPBondMgr_SetParameter( GAPBOND_BONDING_ENABLED, sizeof( uint8 ), &bonding );}{// Use the same interval for general and limited advertising.// Note that only general advertising will occur based on the above configurationuint16_t advInt = 80;//160GAP_SetParamValue(TGAP_LIM_DISC_ADV_INT_MIN, advInt);GAP_SetParamValue(TGAP_LIM_DISC_ADV_INT_MAX, advInt);GAP_SetParamValue(TGAP_GEN_DISC_ADV_INT_MIN, advInt);GAP_SetParamValue(TGAP_GEN_DISC_ADV_INT_MAX, advInt);}// Set up HID keyboard serviceHidKbd_AddService();// Register for HID Dev callbackHidDev_Register(&hidKbdCfg, &hidKbdHidCBs);ATT_SetMTUSizeMax(23);llInitFeatureSet2MPHY(FALSE);llInitFeatureSetDLE(FALSE);ota_app_AddService();// HCI_PPLUS_ExtendTRXCmd(1);// hal_gpio_pin_init(P14,IE);// hal_gpio_pull_set(P14,STRONG_PULL_UP);// hal_gpioin_register(P14,P14_POS_Callback,P14_NEG_Callback);// Setup a delayed profile startuposal_set_event( hidKbdTaskId, START_DEVICE_EVT );
}
GAPROLE_ADVERT_OFF_TIME :
广播关闭时间,默认是30s 如果要使用有限可发现模式,该值需要设置为0,不然的话关闭广播后过段时间就又会打开广播了。
Generic Access Profile (GAP)
GAP 一共有四种角色:
Broadcaster ,Observer,Peripheral ,Central
Connection Interval (主从设备连接间隔) 最小7.5ms 最大4.0s
Slave Latency (从设备延迟): 忽略主设备的应答 继续处于睡眠状态
Supervision Timeout (检测时间超时) : 最大可连接时间。
有效连接时间:
Effective Connection Interval = (Connection Interval) * ( 1 + (Slave Latency) ) ;
从设备可以通过Connection Parameter Update Request去要求主设备改变连接的设置,同时对于主设备的应答采取接受或者拒绝。解决函数在L2CAP层中。
改变的连接设置包括四种:
1 minimum connection interval
2 maximum connection Interval
3 slave latency
4 timeout
GAP层还负责连接状态时主从设备的安全信息的初始化。
GAP Central Role Profile
两个主要的设置函数:
GAPCentralRole_GetParameter 与 GAPCentralRole_SetParameter
GAP central role profile 使用的是回调函数功能区通知事件的发生。使用GAPCentralRole_StartDevice进行初始化设置,且只能被声明一次。
gapCentralRolesCBs_t : 结构体中包涵了两个函数指针,
eventCB:当设备发现或者连接建立或者暂停事件发生的时候会调用此回调函数。
rssiCB:回调当前的RSSI.
在例程中 simpleBLECentralEventCB和 RSSI 回调函数是 simpleBLECentralRssiCB;
Generic Attribute Profile (GATT)
两个角色:
GATT Client :在GATT服务端读/ 写数据
GATT Server : 数据被GATT 客户端读写
GATT层所提供的服务:
Mandatory GAP Service :包涵设备和接入信息(设备名,设备识别码等),以库的形式在协议栈中。
Mandatory GATT Service :(自我理解是本协议层的相关服务信息)以库的形式提供。
SimpleGATTProfile Service: 配置文件。( 在simpleGATTProfile.c 和simpleGATTProfile.h中).
特征值(characteristic):是包涵任务属性和配置的类似接口的值。
特征值有以下属性:
1 handle(句柄):服务属性的地址。
2 Type:UUID;
3 Permissions(许可):是否允许从设备得到特征信息。
GATT提供的子服务(部分):
Read Characteristic Value
Read Using Characteristic UUID
Read Multiple Characteristic Values
Read Characteristic Descriptor
Discover Characteristic by UUID
Write Characteristic Value
Write Characteristic Descriptor
Characteristic Value Notification
四个特殊的特征值:
GATT_PRIMARY_SERVICE_UUID:由服务端提供的特征值。自我理解是此项服务的ID
GATT_CHARACTER_UUID: 紧随特征值后面的声明值。自我理解是特征值在GATT层的另一种表达。
GATT_CLIENT_CHAR_CFG_UUID:允许GATT client使能通知功能的特征值。
GATT_CHAR_USER_DESC_UUID : 用ASCII 来表示的特征值。
GATT层API主要功能:
1 从GATT层服务器注册或者撤销服务属性以及回调。
2 加入或删除GATT服务。
GAP层API 相关参数:
GAPROLE_PARAM_UPDATE_ENABLE 使能或失能自动连接功能。
GAPROLE_MIN_CONN_INTERVAL 最小连接时间间隔
GAPROLE_MAX_CONN_INTERVAL 最大连接时间间隔
GAPROLE_SLAVE_LATENCY 从设备延时( 默认 0)
GAPROLE_TIMEOUT_MULTIPLIER 最大连接等待时间
GAPROLE_ADVERT_ENABLED 使能或使能广播功能
GAPROLE_ADVERT_DATA 改变其值可以限制发现的模式
GAPROLE_SCAN_RSP_DATA 设备名称
GAPROLE_ADVERT_OFF_TIME 未建立连接时,启动第二次连接的间隔
GAP层的API应该使用回调函数来通知应用程序发生了事件,并使用 GAPRole_StartDevice(外面没找到到,估计在库里)进行初始化设置。
gapRolesCBs_t:结构体有两个非常重要的内部指针:
pfnStateChange :得到当前的链接状态
pfnRssiRead: 得到当前的RSSI(信号强度)
在例程中, peripheralStateNotificationCB是返回当前状态的回调函数,但是无法得到信号强度 ,因为指针被指向了NULL.
同时,在 peripheral profile 中包涵了一个自动连接参数:
GAPROLE_PARAM_UPDATE_ENABLE(在SimpleBLEPeripheral_Init中进行初始化)
如果它的值是TRUE 则在连接的状态下从设备就可以向主设备发送连接参数,去更新当钱的连接状态。
Simple GATT Profile (是用来储存和处理与GATT 服务器的数据文件)
SimpleProfile_AddService 初始化程序将属性加入到属性列表里。 在GATT serive中注册和读写回调函数
SimpleProfile_SetParameter 设置GATT层参数函数
SimpleProfile_GetParameter 得到GATT层参数函数
SimpleProfile_RegisterAppCBs 应用程序注册的一个回调函数 目的是在GATT client一个服务中可以写一个新值给特征值。
利用simpleProfileCBs_t结构体中的函数指针指向一个回调函数来实现此操作。
simpleProfile_ReadAttrCB 当GATT client 在profile中想读取属性值时,调用次函数。
simpleProfile_WriteAttrCB 当GATTclient 在profile中想写新的特征值时,调用此函数。
simpleProfile_HandleConnStatusCB 当连接状态发生变化时,回调函数将会受到此函数的信息,如果一个连接暂停,它会改变所有特征值配置值。通常这个函数用来查看特
征值配置,读写值,或者处理一个特征值的通知。
The simple GATT profile 中有5个特征值:
SIMPLEPROFILE_CHAR1:读写
SIMPLEPROFILE_CHAR2:读
SIMPLEPROFILE_CHAR3:写
SIMPLEPROFILE_CHAR4:给client一个通知
SIMPLEPROFILE_CHAR5:当连接时可以写5个字节的数据给client
为了能接收到GATT serive 发来的通知(notification),GATT client 必须打开通知功能
方法:GATT_CLIENT_CFG_NOTIFY写入0x0001 {每当设置新值使用SimpleProfile_SetParameter}
两个single-device 的project说明在TI CC254x Bluetooth Low Energy Software Developer’s Guide中有说明。
2.1 安全特性
安全特性取决于设备的认证需求,可选的安全特性如下:
| 安全特性 | MITM保护 | 所属配对方法 |
|---|---|---|
| LE Secure Connections pairing | Yes | LE安全连接配对 |
| Authenticated MITM protection | Yes | 传统配对 |
| Unauthenticated no MITM protection | No | 传统配对 |
| No security requirements | No | 传统配对 |
MITM(Man in the Middle)指中间人攻击,假如第三方设备攻破了BLE连接,A设备发送的消息被C设备接收,C设备再转发给B设备,A与B设备相互以为建立了连接,而实际上所有的数据通信都经过了C设备转发。
前两种安全特性可以实现MITM保护,后两种则无法防护MITM攻击。
四种安全等级从上至下安全性依次降低。
安全特性信息会持久保存在设备的安全数据库中。
GAPBOND_PAIRING_MODE
配对模式,配置成等待主机的配对请求GAPBOND_PAIRING_MODE_WAIT_FOR_REQ
/** @defgroup GAPBOND_PAIRING_MODE_DEFINES GAP Bond Manager Pairing Modes@{
*/
#define GAPBOND_PAIRING_MODE_NO_PAIRING 0x00 //!< Pairing is not allowed
#define GAPBOND_PAIRING_MODE_WAIT_FOR_REQ 0x01 //!< Wait for a pairing request or slave security request
#define GAPBOND_PAIRING_MODE_INITIATE 0x02 //!< Don't wait, initiate a pairing request or slave security request
GAPBOND_MITM_PROTECTION
设置中间人保护是否使能.如果使能了,配对请求将鉴定连接在从和主之间.profile默认的值为FALSE,即使应用设置它为TRUE在初始化的时候. 打开密钥保护的配对算法
GAPBOND_IO_CAPABILITIES
告诉绑定管理器设备的输入和输出的能力.为了判断设备是否有显示屏或者输入键盘这个参数是需要的.然而,默认的值为GAPBOND_IO_CAP_DISPLAY_ONLY,表明设备有一个显示屏但没有键盘.即使设备没有物理意义上的显示器,一个展示的钥匙(在用户指导中)被认为是一个显示器.默认的万能钥匙是一个六位数字字符串”000000”
GAPBOND_BONDING_ENABLED
可以通过GAPBOND_BONDING_ENABLED参数对任何类型的配对启用或禁用绑定,并在配对过程完成后进行绑定 。
参考文章:CC2640R2F BLE5.0 蓝牙协议栈GAP Bond管理和LE安全连接 - 灰信网(软件开发博客聚合)
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
