当初始化完成、广播数据接收成功、扫描数据接收成功、连接成功、断开连接成功等事件发生时,会调用本函数。

我们可以在各个阶段完成时,进行下一阶段的操作。

例如:扫描到从机地址时,添加连接函数,则可实现“一发现从机地址即连接”。

所有会导致进入本回调函数的事件如下:

/** @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初始化完成之后被执行的:

  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++;
        // 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 );
				
/*BLE中的GAP和GATT GATT通俗理解为用于主从机之间的客户端和服务器端的数据交互,以Attribute Table来体现。 //*GATT层:是一个服务框架定义了对ATT应用的子程序。GATT指定了profile的结构。 //*在BLE中,由profile或者是服务所使用的所有类型的数据都称为characteristic。发生于两个设备间通过BLE连接进行交换的数据都需经过GATT子程
BLE协议栈Central 工程中与广播连接建立的事件         最近在改写BLE协议栈,需要实现实时发现周边从设备,并建立连接,获取RSSI的功能,没什么难度,但着实将各个事件好好看了一遍。曾经看到一位大神说相同的任务使用事件触发方式,不同的任务使用消息传递方式。冥冥之中突然来了感觉~        BLE进行广播和建立连接的事件主要实现是在simpleBLECentralEventC
首先要明确:连接参数是由主机端确定的,从机端可以发起更新连接参数的请求。主机端可以直接下发连接参数,而从机端则只能是发起更新请求并附带想要的连接参数范围。 在初始化中将想要的连接参数设置进osal( 在和iOS设备连接时需要注意一些规则,在前面有提到 ): GAPRole_SetParameter( GAPROLE_PARAM_UPDATE_ENABLE, sizeof( uint8 ), &
【1】主机、从机 代码主要区别。有无profile。 主机:无 profile 从机:有 profile (从机里包含了一个叫做profile的相关代码,这个profile决定了从机的功能。例如防丢器、血压仪、心率计等均是蓝牙组织规定的profile。) 【2】主机、从机 读写函数的区别 主机(Client客户端): GATT_WriteCharValue(?); 或者 GATT