主机会运行SCAN来搜寻广播中的设备
运行函数:
GAPCentralRole_StartDiscovery( DEFAULT_DISCOVERY_MODE,
DEFAULT_DISCOVERY_ACTIVE_SCAN,
DEFAULT_DISCOVERY_WHITE_LIST );
1 /** 2 * @brief Start a device discovery scan. 3 * 4 * Public function defined in central.h. 5 */ 6 bStatus_t GAPCentralRole_StartDiscovery( uint8 mode, uint8 activeScan, uint8 whiteList ) 7 { 8 gapDevDiscReq_t params; 9 10 params.taskID = gapCentralRoleTaskId; 11 params.mode = mode; 12 params.activeScan = activeScan; 13 params.whiteList = whiteList; 14 15 return GAP_DeviceDiscoveryRequest( ¶ms ); 16 }
最终使用的是API:GAP_DeviceDiscoveryRequest
来看几个参数:DEFAULT_DISCOVERY_MODE
// Discovey mode (limited, general, all)
#define DEFAULT_DISCOVERY_MODE DEVDISC_MODE_ALL
#define DEVDISC_MODE_NONDISCOVERABLE 0x00 //!< No discoverable setting
#define DEVDISC_MODE_GENERAL 0x01 //!< General Discoverable devices
#define DEVDISC_MODE_LIMITED 0x02 //!< Limited Discoverable devices
#define DEVDISC_MODE_ALL 0x03 //!< Not filtered
// TRUE to use active scan
#define DEFAULT_DISCOVERY_ACTIVE_SCAN TRUE
// TRUE to use white list during discovery
#define DEFAULT_DISCOVERY_WHITE_LIST FALSE
//TRUE to only allow advertisements from devices in the white list.
初始化函数中有些设置:
// Setup Central Profile
{
uint8 scanRes = DEFAULT_MAX_SCAN_RES;
GAPCentralRole_SetParameter ( GAPCENTRALROLE_MAX_SCAN_RES, sizeof( uint8 ), &scanRes );
}
// Maximum number of scan responses
#define DEFAULT_MAX_SCAN_RES 8
最大的支持扫描到的器件数,为8
GAP_SetParamValue( TGAP_GEN_DISC_SCAN, DEFAULT_SCAN_DURATION );
GAP_SetParamValue( TGAP_LIM_DISC_SCAN, DEFAULT_SCAN_DURATION );
// Scan duration in ms
#define DEFAULT_SCAN_DURATION 4000
#define TGAP_GEN_DISC_SCAN 2 //!< Minimum time to perform scanning, when performing General Discovery proc (mSec)
#define TGAP_LIM_DISC_SCAN 3 //!< Minimum time to perform scanning, when performing Limited Discovery proc (mSec)
主机的发现过程,有两个事件:GAP_DEVICE_INFO_EVENT,GAP_DEVICE_DISCOVERY_EVENT
#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.
发现当中每发现一个device就触发一次
#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.
发现结束时候调用
1 case GAP_DEVICE_INFO_EVENT: 2 { 3 // if filtering device discovery results based on service UUID 4 if ( DEFAULT_DEV_DISC_BY_SVC_UUID == TRUE ) 5 { 6 if ( simpleBLEFindSvcUuid( SIMPLEPROFILE_SERV_UUID, 7 pEvent->deviceInfo.pEvtData, 8 pEvent->deviceInfo.dataLen ) ) 9 { 10 simpleBLEAddDeviceInfo( pEvent->deviceInfo.addr, pEvent->deviceInfo.addrType ); 11 } 12 } 13 } 14 break;
每次发现会调用两个函数:simpleBLEFindSvcUuid,确定发现的设备SvcUUid是否匹配,匹配的话调用simpleBLEAddDeviceInfo将其地址加入列表
1 /********************************************************************* 2 * @fn simpleBLEFindSvcUuid 3 * 4 * @brief Find a given UUID in an advertiser's service UUID list. 5 * 6 * @return TRUE if service UUID found 7 */ 8 static bool simpleBLEFindSvcUuid( uint16 uuid, uint8 *pData, uint8 dataLen ) 9 { 10 uint8 adLen; 11 uint8 adType; 12 uint8 *pEnd; 13 14 pEnd = pData + dataLen - 1; 15 16 // While end of data not reached 17 while ( pData < pEnd ) 18 { 19 // Get length of next AD item 20 adLen = *pData++; 21 if ( adLen > 0 ) 22 { 23 adType = *pData; 24 25 // If AD type is for 16-bit service UUID 26 if ( adType == GAP_ADTYPE_16BIT_MORE || adType == GAP_ADTYPE_16BIT_COMPLETE ) 27 { 28 pData++; 29 adLen--; 30 31 // For each UUID in list 32 while ( adLen >= 2 && pData < pEnd ) 33 { 34 // Check for match 35 if ( pData[0] == LO_UINT16(uuid) && pData[1] == HI_UINT16(uuid) ) 36 { 37 // Match found 38 return TRUE; 39 } 40 41 // Go to next 42 pData += 2; 43 adLen -= 2; 44 } 45 46 // Handle possible erroneous extra byte in UUID list 47 if ( adLen == 1 ) 48 { 49 pData++; 50 } 51 } 52 else 53 { 54 // Go to next item 55 pData += adLen; 56 } 57 } 58 } 59 60 // Match not found 61 return FALSE; 62 }
这个函数利用广播数据格式来判断,先找到类型字节,判断类型是否是uuid,是的话判断内容,不是的话调到下一段内容,把广播格式再粘一次
1 / GAP - Advertisement data (max size = 31 bytes, though this is 2 // best kept short to conserve power while advertisting) 3 static uint8 advertData[] = 4 { 5 // Flags; this sets the device to use limited discoverable 6 // mode (advertises for 30 seconds at a time) instead of general 7 // discoverable mode (advertises indefinitely) 8 0x02, // length of this data 9 GAP_ADTYPE_FLAGS, 10 DEFAULT_DISCOVERABLE_MODE | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED, 11 12 // service UUID, to notify central devices what services are included 13 // in this peripheral 14 0x03, // length of this data 15 GAP_ADTYPE_16BIT_MORE, // some of the UUID's, but not all 16 LO_UINT16( SIMPLEPROFILE_SERV_UUID ), 17 HI_UINT16( SIMPLEPROFILE_SERV_UUID ), 18 19 };
如果是的话加入数组当中,也将扫描到的设备数+1
1 /********************************************************************* 2 * @fn simpleBLEAddDeviceInfo 3 * 4 * @brief Add a device to the device discovery result list 5 * 6 * @return none 7 */ 8 static void simpleBLEAddDeviceInfo( uint8 *pAddr, uint8 addrType ) 9 { 10 uint8 i; 11 12 // If result count not at max 13 if ( simpleBLEScanRes < DEFAULT_MAX_SCAN_RES ) 14 { 15 // Check if device is already in scan results 16 for ( i = 0; i < simpleBLEScanRes; i++ ) 17 { 18 if ( osal_memcmp( pAddr, simpleBLEDevList[i].addr , B_ADDR_LEN ) ) 19 { 20 return; 21 } 22 } 23 24 // Add addr to scan result list 25 osal_memcpy( simpleBLEDevList[simpleBLEScanRes].addr, pAddr, B_ADDR_LEN ); 26 simpleBLEDevList[simpleBLEScanRes].addrType = addrType; 27 28 // Increment scan result count 29 simpleBLEScanRes++; 30 } 31 }
发现结束后会将数组转移做些存储然后指示用户下一步
1 case GAP_DEVICE_DISCOVERY_EVENT: 2 { 3 // discovery complete 4 simpleBLEScanning = FALSE; 5 6 // if not filtering device discovery results based on service UUID 7 if ( DEFAULT_DEV_DISC_BY_SVC_UUID == FALSE ) 8 { 9 // Copy results 10 simpleBLEScanRes = pEvent->discCmpl.numDevs; 11 osal_memcpy( simpleBLEDevList, pEvent->discCmpl.pDevList, 12 (sizeof( gapDevRec_t ) * pEvent->discCmpl.numDevs) ); 13 } 14 15 LCD_WRITE_STRING_VALUE( "Devices Found", simpleBLEScanRes, 16 10, HAL_LCD_LINE_1 ); 17 if ( simpleBLEScanRes > 0 ) 18 { 19 LCD_WRITE_STRING( "<- To Select", HAL_LCD_LINE_2 ); 20 } 21 22 // initialize scan index to last device 23 simpleBLEScanIdx = simpleBLEScanRes; 24 25 } 26 break;
key里面有个更新显示,对于收到的device比较多的时候:
1 if ( keys & HAL_KEY_LEFT ) 2 { 3 // Display discovery results 4 if ( !simpleBLEScanning && simpleBLEScanRes > 0 ) 5 { 6 // Increment index of current result (with wraparound) 7 simpleBLEScanIdx++; 8 if ( simpleBLEScanIdx >= simpleBLEScanRes ) 9 { 10 simpleBLEScanIdx = 0; 11 } 12 13 LCD_WRITE_STRING_VALUE( "Device", simpleBLEScanIdx + 1, 14 10, HAL_LCD_LINE_1 ); 15 LCD_WRITE_STRING( bdAddr2Str( simpleBLEDevList[simpleBLEScanIdx].addr ), 16 HAL_LCD_LINE_2 ); 17 } 18 }