本帖最后由 冒汗的心情 于 2016-4-15 11:36 编辑
CC2541的事件回调函数解析
一、简介 这里主要介绍CC2541的SimpleBLECentral工程的事件回调函数simpleBLECentralEventCB,对事件回调函数的详细解析,从中深入理解他的作用和使用方法。协议栈版本:BLE-CC254x-1.3.2,编译软件:IAR 8.20.2
二、simpleBLECentralEventCB函数中的作用 当初始化完成、广播数据接收成功、扫描数据接收成功、连接成功、断开连接成功等事件发生时,会调用本函数。 我们可以在各个阶段完成时,进行下一阶段的操作。 例如:扫描到从机地址时,添加连接函数,则可实现“一发现从机地址即连接”。 所有会导致进入本回调函数的事件如下: /** @defgroup GAP_MSG_EVENT_DEFINES GAP Message IDs
* @{
*/
#define GAP_DEVICE_INIT_DONE_EVENT 0x00 //!< Sent when the Device Initialization is complete. This event is sent as an OSAL message defined as gapDeviceInitDoneEvent_t.
#define GAP_DEVICE_DISCOVERY_EVENT 0x01 //!< Sent when the Device Discovery Process is complete. This event is sent as an OSAL message defined as gapDevDiscEvent_t.
#define GAP_ADV_DATA_UPDATE_DONE_EVENT 0x02 //!< Sent when the Advertising Data or SCAN_RSP Data has been updated. This event is sent as an OSAL message defined as gapAdvDataUpdateEvent_t.
#define GAP_MAKE_DISCOVERABLE_DONE_EVENT 0x03 //!< Sent when the Make Discoverable Request is complete. This event is sent as an OSAL message defined as gapMakeDiscoverableRspEvent_t.
#define GAP_END_DISCOVERABLE_DONE_EVENT 0x04 //!< Sent when the Advertising has ended. This event is sent as an OSAL message defined as gapEndDiscoverableRspEvent_t.
#define GAP_LINK_ESTABLISHED_EVENT 0x05 //!< Sent when the Establish Link Request is complete. This event is sent as an OSAL message defined as gapEstLinkReqEvent_t.
#define GAP_LINK_TERMINATED_EVENT 0x06 //!< Sent when a connection was terminated. This event is sent as an OSAL message defined as gapTerminateLinkEvent_t.
#define GAP_LINK_PARAM_UPDATE_EVENT 0x07 //!< Sent when an Update Parameters Event is received. This event is sent as an OSAL message defined as gapLinkUpdateEvent_t.
#define GAP_RANDOM_ADDR_CHANGED_EVENT 0x08 //!< Sent when a random address was changed. This event is sent as an OSAL message defined as gapRandomAddrEvent_t.
#define GAP_SIGNATURE_UPDATED_EVENT 0x09 //!< Sent when the device's signature counter is updated. This event is sent as an OSAL message defined as gapSignUpdateEvent_t.
#define GAP_AUTHENTICATION_COMPLETE_EVENT 0x0A //!< Sent when the Authentication (pairing) process is complete. This event is sent as an OSAL message defined as gapAuthCompleteEvent_t.
#define GAP_PASSKEY_NEEDED_EVENT 0x0B //!< Sent when a Passkey is needed. This is part of the pairing process. This event is sent as an OSAL message defined as gapPasskeyNeededEvent_t.
#define GAP_SLAVE_REQUESTED_SECURITY_EVENT 0x0C //!< Sent when a Slave Security Request is received. This event is sent as an OSAL message defined as gapSlaveSecurityReqEvent_t.
#define GAP_DEVICE_INFO_EVENT 0x0D //!< Sent during the Device Discovery Process when a device is discovered. This event is sent as an OSAL message defined as gapDeviceInfoEvent_t.
#define GAP_BOND_COMPLETE_EVENT 0x0E //!< Sent when the bonding(bound) process is complete. This event is sent as an OSAL message defined as gapBondCompleteEvent_t.
#define GAP_PAIRING_REQ_EVENT 0x0F //!< Sent when an unexpected Pairing Request is received. This event is sent as an OSAL message defined as gapPairingReqEvent_t.
/** @} End GAP_MSG_EVENT_DEFINES */
四、解析代码实际上SimpleBLECentral工程中并没有列出上述的所有情况,仅对6个事件进行了处理。
1、GAP_DEVICE_INIT_DONE_EVENT(初始化完成事件) case GAP_DEVICE_INIT_DONE_EVENT:
{
LCD_WRITE_STRING( "BLE Central", HAL_LCD_LINE_1 );
LCD_WRITE_STRING( bdAddr2Str( pEvent->initDone.devAddr ), HAL_LCD_LINE_2 );
}
break;
它是在GAPCentralRole_StartDevice初始化完成之后被执行的:
[cpp] view plain copy
if ( events & START_DEVICE_EVT )
{
// Start the Device
VOID GAPCentralRole_StartDevice( (gapCentralRoleCB_t *) &simpleBLERoleCB );
// Register with bond manager after starting device
GAPBondMgr_Register( (gapBondCBs_t *) &simpleBLEBondCB );
return ( events ^ START_DEVICE_EVT );
}
2、GAP_DEVICE_INFO_EVENT(设备信息事件)
在发现设备过程中,如果有设备被发现,就会执行该事件。 注意,进到该事件时,主机已经获得了某个从机的UUID和MAC地址,而且一个设备会先后进两次本事件,一次是广播数据、一次是扫描应答数据。 举个例子, 有个从机地址的UUID是0xFFF0、MAC地址是0xB4994C621B09。 当主机进到GAP_DEVICE_INFO_EVENT事件时,已经获取到了0xFFF0(广播数据中)和0xB4994C621B09(广播数据和扫描应答数据中都没有发现,应该是在底层的交互数据中)。第一次进GAP_DEVICE_INFO_EVENT事件时pEvent->deviceInfo.pEvtData指向的是广播数据,第二次进GAP_DEVICE_INFO_EVENT事件时pEvent->deviceInfo.pEvtData指向的是扫描应答数据。
来看看simpleBLEFindSvcUuid函数是怎么实现的: static bool simpleBLEFindSvcUuid( uint16 uuid, uint8 *pData, uint8 dataLen )
{
uint8 adLen;
uint8 adType;
uint8 *pEnd;
pEnd = pData + dataLen - 1;
// While end of data not reached
while ( pData < pEnd )
{
// Get length of next AD item
adLen = *pData++;
if ( adLen > 0 )
{
adType = *pData;
// If AD type is for 16-bit service UUID
if ( adType == GAP_ADTYPE_16BIT_MORE || adType == GAP_ADTYPE_16BIT_COMPLETE )
{
pData++;
adLen--;
// For each UUID in list
while ( adLen >= 2 && pData < pEnd )
{
// Check for match
if ( pData[0] == LO_UINT16(uuid) && pData[1] == HI_UINT16(uuid) )
{
// Match found
return TRUE;
}
// Go to next
pData += 2;
adLen -= 2;
}
// Handle possible erroneous extra byte in UUID list
if ( adLen == 1 )
{
pData++;
}
}
else
{
// Go to next item
pData += adLen;
}
}
}
// Match not found
return FALSE;
}
上面这段代码实现过程:先接收“数据长度”,判断“数据长度”后面一个字节的“数据类型”,如果是GAP_ADTYPE_16BIT_MORE或GAP_ADTYPE_16BIT_COMPLETE则说明该数据段是UUID,则保存下来。
对比看看下图的广播数据就比较清楚了。
再看看simpleBLEAddDeviceInfo是如何添加MAC地址到列表的。
3、GAP_DEVICE_DISCOVERY_EVENT(发现设备完成事件)
注意: GAP_DEVICE_INFO_EVENT事件是发现设备过程中,发现一个设备即进一次事件。 GAP_DEVICE_DISCOVERY_EVENT事件则是发现结束后产生的事件。
4、GAP_LINK_ESTABLISHED_EVENT(连接结束事件)
5、GAP_LINK_TERMINATED_EVENT(断开完成事件)
6、GAP_LINK_PARAM_UPDATE_EVENT(参数更新) case GAP_LINK_PARAM_UPDATE_EVENT:
{
LCD_WRITE_STRING( "Param Update", HAL_LCD_LINE_1 );
}
break;
GAP_LINK_PARAM_UPDATE_EVENT事件是在GAPCentralRole_UpdateLink被调用后而执行的: if ( keys & HAL_KEY_RIGHT )
{
// Connection update
if ( simpleBLEState == BLE_STATE_CONNECTED )
{
GAPCentralRole_UpdateLink( simpleBLEConnHandle,
DEFAULT_UPDATE_MIN_CONN_INTERVAL,
DEFAULT_UPDATE_MAX_CONN_INTERVAL,
DEFAULT_UPDATE_SLAVE_LATENCY,
DEFAULT_UPDATE_CONN_TIMEOUT );
}
}
|