2020-03-30 01:44:20 +02:00
/*
* NimBLEScan . cpp
*
* Created : on Jan 24 2020
* Author H2zero
2020-05-14 06:03:56 +02:00
*
2020-03-30 01:44:20 +02:00
* Originally :
*
* BLEScan . cpp
*
* Created on : Jul 1 , 2017
* Author : kolban
*/
2020-05-14 06:03:56 +02:00
# include "nimconfig.h"
2021-09-07 05:14:43 +02:00
# if defined(CONFIG_BT_ENABLED) && defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER)
2020-05-14 06:03:56 +02:00
2020-03-30 01:44:20 +02:00
# include "NimBLEScan.h"
# include "NimBLEDevice.h"
# include "NimBLELog.h"
# include <string>
2022-01-15 04:45:24 +01:00
# include <climits>
2020-03-30 01:44:20 +02:00
static const char * LOG_TAG = " NimBLEScan " ;
/**
* @ brief Scan constuctor .
*/
NimBLEScan : : NimBLEScan ( ) {
m_scan_params . filter_policy = BLE_HCI_SCAN_FILT_NO_WL ;
m_scan_params . passive = 1 ; // If set, don’ t send scan requests to advertisers (i.e., don’ t request additional advertising data).
m_scan_params . itvl = 0 ; // This is defined as the time interval from when the Controller started its last LE scan until it begins the subsequent LE scan. (units=0.625 msec)
m_scan_params . window = 0 ; // The duration of the LE scan. LE_Scan_Window shall be less than or equal to LE_Scan_Interval (units=0.625 msec)
m_scan_params . limited = 0 ; // If set, only discover devices in limited discoverable mode.
2020-06-26 23:44:40 +02:00
m_scan_params . filter_duplicates = 0 ; // If set, the controller ignores all but the first advertisement from each device.
2020-03-30 01:44:20 +02:00
m_pAdvertisedDeviceCallbacks = nullptr ;
2021-01-11 05:54:32 +01:00
m_ignoreResults = false ;
2020-06-22 06:07:01 +02:00
m_pTaskData = nullptr ;
2021-01-13 04:42:19 +01:00
m_duration = BLE_HS_FOREVER ; // make sure this is non-zero in the event of a host reset
2021-01-31 02:27:06 +01:00
m_maxResults = 0xFF ;
2020-03-30 01:44:20 +02:00
}
2020-07-29 04:57:33 +02:00
/**
* @ brief Scan destructor , release any allocated resources .
*/
NimBLEScan : : ~ NimBLEScan ( ) {
clearResults ( ) ;
}
2020-03-30 01:44:20 +02:00
/**
* @ brief Handle GAP events related to scans .
* @ param [ in ] event The event type for this event .
* @ param [ in ] param Parameter data for this event .
*/
/*STATIC*/ int NimBLEScan : : handleGapEvent ( ble_gap_event * event , void * arg ) {
2022-04-10 18:21:45 +02:00
( void ) arg ;
NimBLEScan * pScan = NimBLEDevice : : getScan ( ) ;
2020-05-14 06:03:56 +02:00
2020-03-30 01:44:20 +02:00
switch ( event - > type ) {
2022-02-07 00:52:42 +01:00
case BLE_GAP_EVENT_EXT_DISC :
2020-03-30 01:44:20 +02:00
case BLE_GAP_EVENT_DISC : {
2021-01-11 05:54:32 +01:00
if ( pScan - > m_ignoreResults ) {
2021-01-31 02:06:29 +01:00
NIMBLE_LOGI ( LOG_TAG , " Scan op in progress - ignoring results " ) ;
2020-05-14 06:03:56 +02:00
return 0 ;
}
2022-04-10 18:21:45 +02:00
# if CONFIG_BT_NIMBLE_EXT_ADV
2022-02-07 00:52:42 +01:00
const auto & disc = event - > ext_disc ;
2022-04-10 18:21:45 +02:00
const bool isLegacyAdv = disc . props & BLE_HCI_ADV_LEGACY_MASK ;
const auto event_type = isLegacyAdv ? disc . legacy_event_type : disc . props ;
2022-02-07 00:52:42 +01:00
# else
const auto & disc = event - > disc ;
2022-04-10 18:21:45 +02:00
const bool isLegacyAdv = true ;
2022-02-07 00:52:42 +01:00
const auto event_type = disc . event_type ;
# endif
NimBLEAddress advertisedAddress ( disc . addr ) ;
2020-03-30 01:44:20 +02:00
// Examine our list of ignored addresses and stop processing if we don't want to see it or are already connected
if ( NimBLEDevice : : isIgnored ( advertisedAddress ) ) {
NIMBLE_LOGI ( LOG_TAG , " Ignoring device: address: %s " , advertisedAddress . toString ( ) . c_str ( ) ) ;
return 0 ;
}
2020-05-14 06:03:56 +02:00
NimBLEAdvertisedDevice * advertisedDevice = nullptr ;
2020-05-18 04:21:35 +02:00
// If we've seen this device before get a pointer to it from the vector
for ( auto & it : pScan - > m_scanResults . m_advertisedDevicesVector ) {
2022-04-10 18:21:45 +02:00
# if CONFIG_BT_NIMBLE_EXT_ADV
// Same address but different set ID should create a new advertised device.
if ( it - > getAddress ( ) = = advertisedAddress & & it - > getSetId ( ) = = disc . sid ) {
# else
if ( it - > getAddress ( ) = = advertisedAddress ) {
# endif
2020-05-18 04:21:35 +02:00
advertisedDevice = it ;
break ;
}
2020-03-30 01:44:20 +02:00
}
2020-05-18 04:21:35 +02:00
// If we haven't seen this device before; create a new instance and insert it in the vector.
2020-03-30 01:44:20 +02:00
// Otherwise just update the relevant parameters of the already known device.
2022-04-10 18:21:45 +02:00
if ( advertisedDevice = = nullptr & &
( ! isLegacyAdv | | event_type ! = BLE_HCI_ADV_RPT_EVTYPE_SCAN_RSP ) ) {
2021-01-31 02:27:06 +01:00
// Check if we have reach the scan results limit, ignore this one if so.
// We still need to store each device when maxResults is 0 to be able to append the scan results
2022-04-10 18:21:45 +02:00
if ( pScan - > m_maxResults > 0 & & pScan - > m_maxResults < 0xFF & &
( pScan - > m_scanResults . m_advertisedDevicesVector . size ( ) > = pScan - > m_maxResults ) ) {
2021-01-31 02:27:06 +01:00
return 0 ;
}
2022-04-10 18:21:45 +02:00
2020-03-30 01:44:20 +02:00
advertisedDevice = new NimBLEAdvertisedDevice ( ) ;
advertisedDevice - > setAddress ( advertisedAddress ) ;
2022-04-10 18:21:45 +02:00
advertisedDevice - > setAdvType ( event_type , isLegacyAdv ) ;
# if CONFIG_BT_NIMBLE_EXT_ADV
advertisedDevice - > setSetId ( disc . sid ) ;
advertisedDevice - > setPrimaryPhy ( disc . prim_phy ) ;
advertisedDevice - > setSecondaryPhy ( disc . sec_phy ) ;
advertisedDevice - > setPeriodicInterval ( disc . periodic_adv_itvl ) ;
# endif
2020-05-18 04:21:35 +02:00
pScan - > m_scanResults . m_advertisedDevicesVector . push_back ( advertisedDevice ) ;
2021-01-31 02:06:29 +01:00
NIMBLE_LOGI ( LOG_TAG , " New advertiser: %s " , advertisedAddress . toString ( ) . c_str ( ) ) ;
2022-04-10 18:21:45 +02:00
} else if ( advertisedDevice ! = nullptr ) {
2021-01-31 02:06:29 +01:00
NIMBLE_LOGI ( LOG_TAG , " Updated advertiser: %s " , advertisedAddress . toString ( ) . c_str ( ) ) ;
2021-01-31 02:27:06 +01:00
} else {
// Scan response from unknown device
return 0 ;
2020-03-30 01:44:20 +02:00
}
2021-01-31 02:06:29 +01:00
advertisedDevice - > m_timestamp = time ( nullptr ) ;
2022-02-07 00:52:42 +01:00
advertisedDevice - > setRSSI ( disc . rssi ) ;
2022-04-10 18:21:45 +02:00
advertisedDevice - > setPayload ( disc . data , disc . length_data , ( isLegacyAdv & &
event_type = = BLE_HCI_ADV_RPT_EVTYPE_SCAN_RSP ) ) ;
2020-03-30 01:44:20 +02:00
if ( pScan - > m_pAdvertisedDeviceCallbacks ) {
2021-01-31 02:27:06 +01:00
// If not active scanning or scan response is not available
2022-04-10 18:21:45 +02:00
// or extended advertisement scanning, report the result to the callback now.
if ( pScan - > m_scan_params . passive | | ! isLegacyAdv | |
2021-01-31 02:27:06 +01:00
( advertisedDevice - > getAdvType ( ) ! = BLE_HCI_ADV_TYPE_ADV_IND & &
advertisedDevice - > getAdvType ( ) ! = BLE_HCI_ADV_TYPE_ADV_SCAN_IND ) )
{
advertisedDevice - > m_callbackSent = true ;
pScan - > m_pAdvertisedDeviceCallbacks - > onResult ( advertisedDevice ) ;
// Otherwise, wait for the scan response so we can report the complete data.
2022-04-10 18:21:45 +02:00
} else if ( isLegacyAdv & & event_type = = BLE_HCI_ADV_RPT_EVTYPE_SCAN_RSP ) {
2021-01-31 02:27:06 +01:00
advertisedDevice - > m_callbackSent = true ;
pScan - > m_pAdvertisedDeviceCallbacks - > onResult ( advertisedDevice ) ;
}
2021-07-20 05:46:30 +02:00
// If not storing results and we have invoked the callback, delete the device.
2021-01-31 02:27:06 +01:00
if ( pScan - > m_maxResults = = 0 & & advertisedDevice - > m_callbackSent ) {
pScan - > erase ( advertisedAddress ) ;
2020-03-30 01:44:20 +02:00
}
}
return 0 ;
}
case BLE_GAP_EVENT_DISC_COMPLETE : {
NIMBLE_LOGD ( LOG_TAG , " discovery complete; reason=%d " ,
2021-01-31 02:06:29 +01:00
event - > disc_complete . reason ) ;
// If a device advertised with scan reponse available and it was not received
// the callback would not have been invoked, so do it here.
if ( pScan - > m_pAdvertisedDeviceCallbacks ) {
for ( auto & it : pScan - > m_scanResults . m_advertisedDevicesVector ) {
if ( ! it - > m_callbackSent ) {
pScan - > m_pAdvertisedDeviceCallbacks - > onResult ( it ) ;
}
}
}
2020-05-14 06:03:56 +02:00
2021-01-31 02:27:06 +01:00
if ( pScan - > m_maxResults = = 0 ) {
pScan - > clearResults ( ) ;
}
2020-03-30 01:44:20 +02:00
if ( pScan - > m_scanCompleteCB ! = nullptr ) {
pScan - > m_scanCompleteCB ( pScan - > m_scanResults ) ;
}
2020-05-14 06:03:56 +02:00
2020-06-22 06:07:01 +02:00
if ( pScan - > m_pTaskData ! = nullptr ) {
pScan - > m_pTaskData - > rc = event - > disc_complete . reason ;
xTaskNotifyGive ( pScan - > m_pTaskData - > task ) ;
}
2020-03-30 01:44:20 +02:00
return 0 ;
}
default :
return 0 ;
}
} // gapEventHandler
/**
* @ brief Should we perform an active or passive scan ?
2021-01-31 02:27:06 +01:00
* The default is a passive scan . An active scan means that we will request a scan response .
2020-03-30 01:44:20 +02:00
* @ param [ in ] active If true , we perform an active scan otherwise a passive scan .
*/
void NimBLEScan : : setActiveScan ( bool active ) {
2021-01-31 02:27:06 +01:00
m_scan_params . passive = ! active ;
2020-03-30 01:44:20 +02:00
} // setActiveScan
2020-07-02 01:26:44 +02:00
/**
* @ brief Set whether or not the BLE controller should only report results
* from devices it has not already seen .
2020-07-31 04:16:58 +02:00
* @ param [ in ] enabled If true , scanned devices will only be reported once .
2020-07-02 01:26:44 +02:00
* @ details The controller has a limited buffer and will start reporting
* dupicate devices once the limit is reached .
*/
2020-07-24 04:18:41 +02:00
void NimBLEScan : : setDuplicateFilter ( bool enabled ) {
m_scan_params . filter_duplicates = enabled ;
2020-07-02 01:26:44 +02:00
} // setDuplicateFilter
/**
* @ brief Set whether or not the BLE controller only report scan results
* from devices advertising in limited discovery mode , i . e . directed advertising .
2020-07-31 04:16:58 +02:00
* @ param [ in ] enabled If true , only limited discovery devices will be in scan results .
2020-07-02 01:26:44 +02:00
*/
2020-07-24 04:18:41 +02:00
void NimBLEScan : : setLimitedOnly ( bool enabled ) {
m_scan_params . limited = enabled ;
2020-07-02 01:26:44 +02:00
} // setLimited
/**
* @ brief Sets the scan filter policy .
* @ param [ in ] filter Can be one of :
2020-07-09 03:27:26 +02:00
* * BLE_HCI_SCAN_FILT_NO_WL ( 0 )
* Scanner processes all advertising packets ( white list not used ) except \ n
2020-07-02 01:26:44 +02:00
* directed , connectable advertising packets not sent to the scanner .
2020-07-09 03:27:26 +02:00
* * BLE_HCI_SCAN_FILT_USE_WL ( 1 )
* Scanner processes advertisements from white list only . A connectable , \ n
2020-07-02 01:26:44 +02:00
* directed advertisment is ignored unless it contains scanners address .
2020-07-09 03:27:26 +02:00
* * BLE_HCI_SCAN_FILT_NO_WL_INITA ( 2 )
* Scanner process all advertising packets ( white list not used ) . A \ n
2020-07-02 01:26:44 +02:00
* connectable , directed advertisement shall not be ignored if the InitA
* is a resolvable private address .
2020-07-09 03:27:26 +02:00
* * BLE_HCI_SCAN_FILT_USE_WL_INITA ( 3 )
* Scanner process advertisements from white list only . A connectable , \ n
2020-07-02 01:26:44 +02:00
* directed advertisement shall not be ignored if the InitA is a
* resolvable private address .
*/
void NimBLEScan : : setFilterPolicy ( uint8_t filter ) {
m_scan_params . filter_policy = filter ;
} // setFilterPolicy
2021-01-31 02:27:06 +01:00
/**
* @ brief Sets the max number of results to store .
* @ param [ in ] maxResults The number of results to limit storage to \ n
* 0 = = none ( callbacks only ) 0xFF = = unlimited , any other value is the limit .
*/
void NimBLEScan : : setMaxResults ( uint8_t maxResults ) {
m_maxResults = maxResults ;
}
2020-03-30 01:44:20 +02:00
/**
* @ brief Set the call backs to be invoked .
* @ param [ in ] pAdvertisedDeviceCallbacks Call backs to be invoked .
* @ param [ in ] wantDuplicates True if we wish to be called back with duplicates . Default is false .
*/
2020-07-02 01:26:44 +02:00
void NimBLEScan : : setAdvertisedDeviceCallbacks ( NimBLEAdvertisedDeviceCallbacks * pAdvertisedDeviceCallbacks ,
bool wantDuplicates ) {
2021-01-31 02:27:06 +01:00
setDuplicateFilter ( ! wantDuplicates ) ;
2020-03-30 01:44:20 +02:00
m_pAdvertisedDeviceCallbacks = pAdvertisedDeviceCallbacks ;
} // setAdvertisedDeviceCallbacks
/**
* @ brief Set the interval to scan .
2020-07-09 03:27:26 +02:00
* @ param [ in ] intervalMSecs The scan interval ( how often ) in milliseconds .
2020-03-30 01:44:20 +02:00
*/
void NimBLEScan : : setInterval ( uint16_t intervalMSecs ) {
m_scan_params . itvl = intervalMSecs / 0.625 ;
} // setInterval
/**
* @ brief Set the window to actively scan .
* @ param [ in ] windowMSecs How long to actively scan .
*/
void NimBLEScan : : setWindow ( uint16_t windowMSecs ) {
m_scan_params . window = windowMSecs / 0.625 ;
} // setWindow
2020-07-24 04:18:41 +02:00
/**
* @ brief Get the status of the scanner .
* @ return true if scanning or scan starting .
*/
bool NimBLEScan : : isScanning ( ) {
2021-01-11 05:54:32 +01:00
return ble_gap_disc_active ( ) ;
2020-07-24 04:18:41 +02:00
}
2020-03-30 01:44:20 +02:00
/**
* @ brief Start scanning .
* @ param [ in ] duration The duration in seconds for which to scan .
* @ param [ in ] scanCompleteCB A function to be called when scanning has completed .
2020-07-09 03:27:26 +02:00
* @ param [ in ] is_continue Set to true to save previous scan results , false to clear them .
2020-03-30 01:44:20 +02:00
* @ return True if scan started or false if there was an error .
*/
bool NimBLEScan : : start ( uint32_t duration , void ( * scanCompleteCB ) ( NimBLEScanResults ) , bool is_continue ) {
2022-01-15 20:43:17 +01:00
NIMBLE_LOGD ( LOG_TAG , " >> start: duration=% " PRIu32 , duration ) ;
2020-05-14 06:03:56 +02:00
2020-03-30 01:44:20 +02:00
// Save the callback to be invoked when the scan completes.
2020-05-14 06:03:56 +02:00
m_scanCompleteCB = scanCompleteCB ;
2020-03-30 01:44:20 +02:00
// Save the duration in the case that the host is reset so we can reuse it.
m_duration = duration ;
2020-05-14 06:03:56 +02:00
2020-03-30 01:44:20 +02:00
// If 0 duration specified then we assume a continuous scan is desired.
if ( duration = = 0 ) {
duration = BLE_HS_FOREVER ;
}
else {
2021-01-11 05:54:32 +01:00
// convert duration to milliseconds
duration = duration * 1000 ;
2020-03-30 01:44:20 +02:00
}
2020-05-14 06:03:56 +02:00
2021-01-11 05:54:32 +01:00
// Set the flag to ignore the results while we are deleting the vector
2020-03-30 01:44:20 +02:00
if ( ! is_continue ) {
2021-01-11 05:54:32 +01:00
m_ignoreResults = true ;
2020-03-30 01:44:20 +02:00
}
2020-05-14 06:03:56 +02:00
2022-04-10 18:21:45 +02:00
# if CONFIG_BT_NIMBLE_EXT_ADV
ble_gap_ext_disc_params scan_params ;
scan_params . passive = m_scan_params . passive ;
scan_params . itvl = m_scan_params . itvl ;
scan_params . window = m_scan_params . window ;
int rc = ble_gap_ext_disc ( NimBLEDevice : : m_own_addr_type ,
duration / 10 ,
0 ,
m_scan_params . filter_duplicates ,
m_scan_params . filter_policy ,
m_scan_params . limited ,
& scan_params ,
& scan_params ,
NimBLEScan : : handleGapEvent ,
NULL ) ;
2022-02-07 00:52:42 +01:00
# else
2022-04-10 18:21:45 +02:00
int rc = ble_gap_disc ( NimBLEDevice : : m_own_addr_type ,
duration ,
& m_scan_params ,
NimBLEScan : : handleGapEvent ,
NULL ) ;
2022-02-07 00:52:42 +01:00
# endif
2021-01-11 05:54:32 +01:00
switch ( rc ) {
case 0 :
if ( ! is_continue ) {
clearResults ( ) ;
}
break ;
case BLE_HS_EALREADY :
2021-04-01 04:24:57 +02:00
// Clear the cache if already scanning in case an advertiser was missed.
clearDuplicateCache ( ) ;
2021-01-11 05:54:32 +01:00
break ;
case BLE_HS_EBUSY :
NIMBLE_LOGE ( LOG_TAG , " Unable to scan - connection in progress. " ) ;
break ;
case BLE_HS_ETIMEOUT_HCI :
case BLE_HS_EOS :
case BLE_HS_ECONTROLLER :
case BLE_HS_ENOTSYNCED :
NIMBLE_LOGC ( LOG_TAG , " Unable to scan - Host Reset " ) ;
break ;
default :
NIMBLE_LOGE ( LOG_TAG , " Error initiating GAP discovery procedure; rc=%d, %s " ,
rc , NimBLEUtils : : returnCodeToString ( rc ) ) ;
break ;
2020-03-30 01:44:20 +02:00
}
2021-01-11 05:54:32 +01:00
m_ignoreResults = false ;
2020-03-30 01:44:20 +02:00
NIMBLE_LOGD ( LOG_TAG , " << start() " ) ;
2021-01-11 05:54:32 +01:00
2021-01-13 05:25:30 +01:00
if ( rc ! = 0 & & rc ! = BLE_HS_EALREADY ) {
2021-01-11 05:54:32 +01:00
return false ;
}
2020-03-30 01:44:20 +02:00
return true ;
} // start
/**
* @ brief Start scanning and block until scanning has been completed .
* @ param [ in ] duration The duration in seconds for which to scan .
2020-07-09 03:27:26 +02:00
* @ param [ in ] is_continue Set to true to save previous scan results , false to clear them .
* @ return The NimBLEScanResults .
2020-03-30 01:44:20 +02:00
*/
NimBLEScanResults NimBLEScan : : start ( uint32_t duration , bool is_continue ) {
2020-06-22 06:07:01 +02:00
if ( duration = = 0 ) {
NIMBLE_LOGW ( LOG_TAG , " Blocking scan called with duration = forever " ) ;
}
2022-01-10 03:04:41 +01:00
TaskHandle_t cur_task = xTaskGetCurrentTaskHandle ( ) ;
ble_task_data_t taskData = { nullptr , cur_task , 0 , nullptr } ;
2020-06-22 06:07:01 +02:00
m_pTaskData = & taskData ;
2020-03-30 01:44:20 +02:00
if ( start ( duration , nullptr , is_continue ) ) {
2022-01-10 03:04:41 +01:00
# ifdef ulTaskNotifyValueClear
// Clear the task notification value to ensure we block
ulTaskNotifyValueClear ( cur_task , ULONG_MAX ) ;
# endif
2020-06-22 06:07:01 +02:00
ulTaskNotifyTake ( pdTRUE , portMAX_DELAY ) ;
2020-03-30 01:44:20 +02:00
}
2020-06-22 06:07:01 +02:00
m_pTaskData = nullptr ;
2020-03-30 01:44:20 +02:00
return m_scanResults ;
} // start
/**
* @ brief Stop an in progress scan .
2020-07-09 03:27:26 +02:00
* @ return True if successful .
2020-03-30 01:44:20 +02:00
*/
2020-06-22 06:07:01 +02:00
bool NimBLEScan : : stop ( ) {
2020-03-30 01:44:20 +02:00
NIMBLE_LOGD ( LOG_TAG , " >> stop() " ) ;
2020-05-14 06:03:56 +02:00
2020-03-30 01:44:20 +02:00
int rc = ble_gap_disc_cancel ( ) ;
if ( rc ! = 0 & & rc ! = BLE_HS_EALREADY ) {
2021-01-31 02:06:29 +01:00
NIMBLE_LOGE ( LOG_TAG , " Failed to cancel scan; rc=%d " , rc ) ;
2020-06-22 06:07:01 +02:00
return false ;
2020-03-30 01:44:20 +02:00
}
2021-01-31 02:27:06 +01:00
if ( m_maxResults = = 0 ) {
clearResults ( ) ;
}
2020-07-13 04:35:10 +02:00
if ( rc ! = BLE_HS_EALREADY & & m_scanCompleteCB ! = nullptr ) {
2020-03-30 01:44:20 +02:00
m_scanCompleteCB ( m_scanResults ) ;
}
2020-05-14 06:03:56 +02:00
2020-06-22 06:07:01 +02:00
if ( m_pTaskData ! = nullptr ) {
xTaskNotifyGive ( m_pTaskData - > task ) ;
}
2020-05-14 06:03:56 +02:00
2020-03-30 01:44:20 +02:00
NIMBLE_LOGD ( LOG_TAG , " << stop() " ) ;
2020-06-22 06:07:01 +02:00
return true ;
2020-03-30 01:44:20 +02:00
} // stop
2021-04-01 04:24:57 +02:00
/**
* @ brief Clears the duplicate scan filter cache .
*/
void NimBLEScan : : clearDuplicateCache ( ) {
2021-07-20 05:46:30 +02:00
# ifdef CONFIG_IDF_TARGET_ESP32 // Not available for ESP32C3
2021-04-01 04:24:57 +02:00
esp_ble_scan_dupilcate_list_flush ( ) ;
2021-07-20 05:46:30 +02:00
# endif
2021-04-01 04:24:57 +02:00
}
2020-07-09 03:27:26 +02:00
/**
* @ brief Delete peer device from the scan results vector .
* @ param [ in ] address The address of the device to delete from the results .
* @ details After disconnecting , it may be required in the case we were connected to a device without a public address .
*/
2020-05-10 15:21:46 +02:00
void NimBLEScan : : erase ( const NimBLEAddress & address ) {
2021-01-31 02:06:29 +01:00
NIMBLE_LOGD ( LOG_TAG , " erase device: %s " , address . toString ( ) . c_str ( ) ) ;
2020-05-18 04:21:35 +02:00
2020-05-18 14:47:44 +02:00
for ( auto it = m_scanResults . m_advertisedDevicesVector . begin ( ) ; it ! = m_scanResults . m_advertisedDevicesVector . end ( ) ; + + it ) {
2020-05-18 04:21:35 +02:00
if ( ( * it ) - > getAddress ( ) = = address ) {
delete * it ;
m_scanResults . m_advertisedDevicesVector . erase ( it ) ;
break ;
}
}
2020-03-30 01:44:20 +02:00
}
/**
2021-01-13 04:42:19 +01:00
* @ brief Called when host reset , we set a flag to stop scanning until synced .
2020-03-30 01:44:20 +02:00
*/
void NimBLEScan : : onHostReset ( ) {
2021-01-13 04:42:19 +01:00
m_ignoreResults = true ;
2020-03-30 01:44:20 +02:00
}
2021-01-13 04:42:19 +01:00
/**
* @ brief If the host reset and re - synced this is called .
* If the application was scanning indefinitely with a callback , restart it .
*/
void NimBLEScan : : onHostSync ( ) {
m_ignoreResults = false ;
if ( m_duration = = 0 & & m_pAdvertisedDeviceCallbacks ! = nullptr ) {
start ( m_duration , m_scanCompleteCB ) ;
}
}
2020-03-30 01:44:20 +02:00
/**
* @ brief Get the results of the scan .
* @ return NimBLEScanResults object .
*/
NimBLEScanResults NimBLEScan : : getResults ( ) {
return m_scanResults ;
}
/**
* @ brief Clear the results of the scan .
*/
void NimBLEScan : : clearResults ( ) {
2020-05-18 04:21:35 +02:00
for ( auto & it : m_scanResults . m_advertisedDevicesVector ) {
delete it ;
2020-03-30 01:44:20 +02:00
}
2020-05-18 04:21:35 +02:00
m_scanResults . m_advertisedDevicesVector . clear ( ) ;
2021-04-01 04:24:57 +02:00
clearDuplicateCache ( ) ;
2020-03-30 01:44:20 +02:00
}
/**
* @ brief Dump the scan results to the log .
*/
void NimBLEScanResults : : dump ( ) {
NIMBLE_LOGD ( LOG_TAG , " >> Dump scan results: " ) ;
for ( int i = 0 ; i < getCount ( ) ; i + + ) {
NIMBLE_LOGI ( LOG_TAG , " - %s " , getDevice ( i ) . toString ( ) . c_str ( ) ) ;
}
} // dump
/**
2020-07-09 03:27:26 +02:00
* @ brief Get the count of devices found in the last scan .
2020-03-30 01:44:20 +02:00
* @ return The number of devices found in the last scan .
*/
int NimBLEScanResults : : getCount ( ) {
2020-05-18 04:21:35 +02:00
return m_advertisedDevicesVector . size ( ) ;
2020-03-30 01:44:20 +02:00
} // getCount
/**
* @ brief Return the specified device at the given index .
* The index should be between 0 and getCount ( ) - 1.
* @ param [ in ] i The index of the device .
* @ return The device at the specified index .
*/
NimBLEAdvertisedDevice NimBLEScanResults : : getDevice ( uint32_t i ) {
2020-05-18 04:21:35 +02:00
return * m_advertisedDevicesVector [ i ] ;
}
Add iterators to client remote attributes.
Add iterators for NimBLEScan: NimBLEadvertisedDevice, NimBLEClient: NimBLERemoteService, NimBLERemoteService: NimBLERemoteCharacteristic and NimBLERemoteCharacteristic: NimBLERemoteDescriptor
This is handy e.g. for showing every address of the advertised devices from a scan. To do so, first get a new scan and next:
```
for(auto pAdvertisedDevice: pBLEScan->getResults()) {
Serial.printf("Address is %s\n", std::string(pAdvertisedDevice->getAddress()).c_str());
}
```
Of course any other property of the advertised device can be shown (or looked up, if that is your use case)
Also this is handy e.g. for showing every UUID in a peripheral. To do so, first connect to a peripheral and next:
```
for(auto pService: *pClient) {
Serial.printf("Service UUID is %s\n", std::string(pService->getUUID()).c_str());
for(auto pCharacteristic: *pService) {
Serial.printf("Characteristic UUID is %s\n", std::string(pCharacteristic->getUUID()).c_str());
for(auto pDescriptor: *pCharacteristic) {
Serial.printf("Descriptor UUID is %s\n", std::string(pDescriptor->getUUID()).c_str());
}
}
}
```
Again of course any other property can be shown, or looked up.
2020-05-23 04:13:52 +02:00
/**
* @ brief Get iterator to the beginning of the vector of advertised device pointers .
* @ return An iterator to the beginning of the vector of advertised device pointers .
*/
std : : vector < NimBLEAdvertisedDevice * > : : iterator NimBLEScanResults : : begin ( ) {
return m_advertisedDevicesVector . begin ( ) ;
}
/**
* @ brief Get iterator to the end of the vector of advertised device pointers .
* @ return An iterator to the end of the vector of advertised device pointers .
*/
std : : vector < NimBLEAdvertisedDevice * > : : iterator NimBLEScanResults : : end ( ) {
return m_advertisedDevicesVector . end ( ) ;
}
2020-05-18 04:21:35 +02:00
/**
2020-07-09 03:27:26 +02:00
* @ brief Get a pointer to the specified device at the given address .
2020-05-18 04:21:35 +02:00
* If the address is not found a nullptr is returned .
* @ param [ in ] address The address of the device .
* @ return A pointer to the device at the specified address .
*/
NimBLEAdvertisedDevice * NimBLEScanResults : : getDevice ( const NimBLEAddress & address ) {
for ( size_t index = 0 ; index < m_advertisedDevicesVector . size ( ) ; index + + ) {
if ( m_advertisedDevicesVector [ index ] - > getAddress ( ) = = address ) {
return m_advertisedDevicesVector [ index ] ;
}
2020-03-30 01:44:20 +02:00
}
2020-05-18 04:21:35 +02:00
return nullptr ;
2020-03-30 01:44:20 +02:00
}
2021-09-07 05:14:43 +02:00
# endif /* CONFIG_BT_ENABLED && CONFIG_BT_NIMBLE_ROLE_OBSERVER */