热度 20
2015-9-21 16:02
2683 次阅读|
0 个评论
蓝牙 BLE4.0 协议的 GAP 层规定了 BLE4.0 的四种角色——广播者( Broadcaster )、观测者( Observer )、主机( Central )和外设( Peripheral )。 TI CC2541 的协议栈( v1.4.0 )里有个例程 SimpleBLEBroadcaster ,是用来实现一个蓝牙广播者。苹果比较火的 iBeacons 就是一个广播者。 广播者就是只通过广播的形式发送信息,不与其他蓝牙设备配对、连接。信息的内容可以是位置信息,可以是温湿度或其他自定义的信息。 广播事件分为四种类型: • a connectable undirected event ——可连接非定向类型 • a connectable directed event ——可连接定向类型 • a non-connectable undirected event ——不可连接非定向类型 • a scannable undirected event ——可扫描非定向类型 在 CC2541 协议栈中是如此定义的: /** @defgroup GAP_ADVERTISEMENT_REPORT_TYPE_DEFINES GAP Advertising Report Event Types * for eventType field in gapDevRec_t and gapDeviceInfoEvent_t * @{ */ #define GAP_ADRPT_ADV_IND 0x00 //! Connectable undirected advertisement #define GAP_ADRPT_ADV_DIRECT_IND 0x01 //! Connectable directed advertisement #define GAP_ADRPT_ADV_SCAN_IND 0x02 //! Scannable undirected advertisement #define GAP_ADRPT_ADV_NONCONN_IND 0x03//! Non-Connectable undirected advertisement #define GAP_ADRPT_SCAN_RSP 0x04//! Scan Response 当然它还定义了扫描的响应事件( Scan response )。 上述四种类型的区别在: 主要是针对主机或者说其他设备的扫描和连接请求的回应不同。 蓝牙 BLE4.0 规范的 Vol.6 Part B Section 4.4.2.3~4.4.2.6 对上述四种广播类型有详细的表述,这里只来研究 GAP_ADRPT_ADV_SCAN_IND 类型,因为 CC2541 的 SimpleBLEBroacaster 例程是定义成的可扫描类型。如上图所示,只响应扫描请求不响应连接请求。 广播相关的参数有: 1 ) Advertising Interval 广播间隔( Advertising_Interval_Min Advertising_Interval_Max ) 所有非定向广播,两个广播事件的广播间隔( T_advEvent )为: T_advEvent = advInterval + advDelay advInterval 必须是 0.625ms 的整数倍,且 20ms ≤ advInterval ≤ 10.24s ,对于可扫描非定向广播类型和不可连接非定向广播类型, advInterval 要大于等于 100ms ( 160 个 0.625ms );对于可连接非定向广播类型,该值最小可以到 20ms. 而式中的 advDelay 值是一个 0~10ms 之间的伪随机数。 Advertising_Interval_Min Advertising_Interval_Max 两个参数用来调整广播间隔 Advertising Interval ,通常分别设置上下限,也可以设置为同一个值,值应为 0.625ms 的倍数。在 CC2541 的协议栈中是设置为了同一值。 #define DEFAULT_ADVERTISING_INTERVAL 160 uint16 advInt = DEFAULT_ADVERTISING_INTERVAL; GAP_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 ); 2 ) Advertising_Type 广播类型 就是前面所讲的四种广播类型,不再赘述。 3 ) Own_Address_Type 自身地址类型 指的是广播者本身的地址类型。 0 表示使用公共设备地址,就是在 IEEE 注册的地址,即全球唯一的 MAC ; 1 表示使用随机地址。默认状态下是 0 ,即公共地址。 另外,还有 Direct_Address_Type 、 Direct_Address 等参数,情况跟 Own_Address_Type 类似。 4 ) Advertising_Channel_Map 广播信道设置 广播信道在信道 37~39 中选择。 5 ) Advertising_Filter_Policy 广播过滤策略 主要是针对扫描的请求的。 6 ) Advertising Data 和 Scan Reponse Data 广播数据和扫描应答数据 这两种数据包的结构是一样的。 都是最长 31 个字节。不同的是,广播数据是在广播的时候主动发送的数据;扫描应答数据是在收到扫描请求的时候响应的数据。 这两个参数在例程中的设置如下: static uint8 scanRspData = { // Flags; this sets the device to use limited discoverable // mode (advertises for 30 seconds at a time) instead of general // discoverable mode (advertises indefinitely) 0x02, // length of this data GAP_ADTYPE_FLAGS, GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED, // three-byte broadcast of the data "1 2 3" 0x04, // length of this data including the data type byte GAP_ADTYPE_MANUFACTURER_SPECIFIC, // manufacturer specific advertisement data type 1, 2, 3 }; 在 scanRspData[] 数组的最后面有一个发射功率设置的参数,这里设置为 0dbm. 在 Hci.h 文件中声明了这样的函数接口 extern hciStatus_t HCI_EXT_SetTxPowerCmd( uint8 txPower ); 对发射功率的设置,有 4 个等级: LL_EXT_TX_POWER_MINUS_23_DBM, LL_EXT_TX_POWER_MINUS_6_DBM, LL_EXT_TX_POWER_0_DBM, LL_EXT_TX_POWER_4_DBM 分别是 4dbm 、 0dbm 、 -6dbm 和 -23dbm ,如果要修改,可以调用这个 HCI 函数来设置。 上述参数在 CC2541 的 SimpleBLEBroadcaster 例程里面是这样设置的: uint8 advType = GAP_ADTYPE_ADV_SCAN_IND; // use scannable unidirected advertisements GAPRole_SetParameter( GAPROLE_ADVERT_ENABLED, sizeof( uint8 ), initial_advertising_enable ); GAPRole_SetParameter( GAPROLE_ADVERT_OFF_TIME, sizeof( uint16 ), gapRole_AdvertOffTime ); GAPRole_SetParameter( GAPROLE_SCAN_RSP_DATA, sizeof ( scanRspData ), scanRspData ); GAPRole_SetParameter( GAPROLE_ADVERT_DATA, sizeof( advertData ), advertData ); GAPRole_SetParameter( GAPROLE_ADV_EVENT_TYPE, sizeof( uint8 ), advType ); 这个 SimpleBLEBroadcaster 例程在 DeviceMonitor 中竟然扫描不到其 MAC ,目前原因未知,可能跟 DeviceMonitor 软件有关。 通过 Sniffer 抓包,可以抓到: