2020-03-29 17:44:20 -06:00
/*
* NimBLEScan.cpp
*
* Created: on Jan 24 2020
* Author H2zero
2020-05-13 22:03:56 -06:00
*
2020-03-29 17:44:20 -06:00
* Originally:
*
* BLEScan.cpp
*
* Created on: Jul 1, 2017
* Author: kolban
*/
2020-05-13 22:03:56 -06:00
#include "nimconfig.h"
2021-09-06 21:14:43 -06:00
#if defined(CONFIG_BT_ENABLED) && defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER)
2020-05-13 22:03:56 -06:00
2020-03-29 17:44:20 -06:00
#include "NimBLEScan.h"
#include "NimBLEDevice.h"
#include "NimBLELog.h"
#include <string>
2022-01-14 20:45:24 -07:00
#include <climits>
2020-03-29 17:44:20 -06: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.
2022-06-04 14:24:30 -06:00
m_scan_params . filter_duplicates = 1 ; // If set, the controller ignores all but the first advertisement from each device.
2022-08-27 13:13:27 -06:00
m_pScanCallbacks = nullptr ;
2021-01-10 21:54:32 -07:00
m_ignoreResults = false ;
2020-06-21 22:07:01 -06:00
m_pTaskData = nullptr ;
2021-01-12 20:42:19 -07:00
m_duration = BLE_HS_FOREVER ; // make sure this is non-zero in the event of a host reset
2021-01-30 18:27:06 -07:00
m_maxResults = 0xFF ;
2020-03-29 17:44:20 -06:00
}
2020-07-28 20:57:33 -06:00
/**
* @brief Scan destructor, release any allocated resources.
*/
NimBLEScan ::~ NimBLEScan () {
clearResults ();
}
2020-03-29 17:44:20 -06: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.
*/
2022-08-27 13:13:27 -06:00
/*STATIC*/
int NimBLEScan :: handleGapEvent ( ble_gap_event * event , void * arg ) {
2022-04-10 10:21:45 -06:00
( void ) arg ;
NimBLEScan * pScan = NimBLEDevice :: getScan ();
2020-05-13 22:03:56 -06:00
2020-03-29 17:44:20 -06:00
switch ( event -> type ) {
2022-02-06 16:52:42 -07:00
case BLE_GAP_EVENT_EXT_DISC :
2020-03-29 17:44:20 -06:00
case BLE_GAP_EVENT_DISC : {
2021-01-10 21:54:32 -07:00
if ( pScan -> m_ignoreResults ) {
2021-01-30 18:06:29 -07:00
NIMBLE_LOGI ( LOG_TAG , "Scan op in progress - ignoring results" );
2020-05-13 22:03:56 -06:00
return 0 ;
}
2022-04-10 10:21:45 -06:00
#if CONFIG_BT_NIMBLE_EXT_ADV
2022-02-06 16:52:42 -07:00
const auto & disc = event -> ext_disc ;
2022-04-10 10:21:45 -06:00
const bool isLegacyAdv = disc . props & BLE_HCI_ADV_LEGACY_MASK ;
const auto event_type = isLegacyAdv ? disc . legacy_event_type : disc . props ;
2022-02-06 16:52:42 -07:00
#else
const auto & disc = event -> disc ;
2022-04-10 10:21:45 -06:00
const bool isLegacyAdv = true ;
2022-02-06 16:52:42 -07:00
const auto event_type = disc . event_type ;
#endif
NimBLEAddress advertisedAddress ( disc . addr );
2020-03-29 17:44:20 -06: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-13 22:03:56 -06:00
NimBLEAdvertisedDevice * advertisedDevice = nullptr ;
2020-05-17 20:21:35 -06: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 10:21:45 -06: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-17 20:21:35 -06:00
advertisedDevice = it ;
break ;
}
2020-03-29 17:44:20 -06:00
}
2020-05-17 20:21:35 -06:00
// If we haven't seen this device before; create a new instance and insert it in the vector.
2020-03-29 17:44:20 -06:00
// Otherwise just update the relevant parameters of the already known device.
2022-04-10 10:21:45 -06:00
if ( advertisedDevice == nullptr &&
( ! isLegacyAdv || event_type != BLE_HCI_ADV_RPT_EVTYPE_SCAN_RSP )) {
2021-01-30 18:27:06 -07: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 10:21:45 -06:00
if ( pScan -> m_maxResults > 0 && pScan -> m_maxResults < 0xFF &&
( pScan -> m_scanResults . m_advertisedDevicesVector . size () >= pScan -> m_maxResults )) {
2021-01-30 18:27:06 -07:00
return 0 ;
}
2022-04-10 10:21:45 -06:00
2024-07-17 19:52:01 -06:00
advertisedDevice = new NimBLEAdvertisedDevice ( event , event_type );
2020-05-17 20:21:35 -06:00
pScan -> m_scanResults . m_advertisedDevicesVector . push_back ( advertisedDevice );
2021-01-30 18:06:29 -07:00
NIMBLE_LOGI ( LOG_TAG , "New advertiser: %s" , advertisedAddress . toString (). c_str ());
2022-04-10 10:21:45 -06:00
} else if ( advertisedDevice != nullptr ) {
2024-07-17 19:52:01 -06:00
advertisedDevice -> update ( event , event_type );
2021-01-30 18:06:29 -07:00
NIMBLE_LOGI ( LOG_TAG , "Updated advertiser: %s" , advertisedAddress . toString (). c_str ());
2021-01-30 18:27:06 -07:00
} else {
// Scan response from unknown device
return 0 ;
2020-07-28 20:09:54 -06:00
}
2021-01-30 18:06:29 -07:00
2022-08-27 13:13:27 -06:00
if ( pScan -> m_pScanCallbacks ) {
2023-04-06 15:56:53 -06:00
if ( advertisedDevice -> m_callbackSent == 0 || ! pScan -> m_scan_params . filter_duplicates ) {
advertisedDevice -> m_callbackSent = 1 ;
pScan -> m_pScanCallbacks -> onDiscovered ( advertisedDevice );
}
if ( pScan -> m_scan_params . filter_duplicates && advertisedDevice -> m_callbackSent >= 2 ) {
2022-06-04 14:24:30 -06:00
return 0 ;
}
2021-01-30 18:27:06 -07:00
// If not active scanning or scan response is not available
2022-04-10 10:21:45 -06:00
// or extended advertisement scanning, report the result to the callback now.
if ( pScan -> m_scan_params . passive || ! isLegacyAdv ||
2021-01-30 18:27:06 -07:00
( advertisedDevice -> getAdvType () != BLE_HCI_ADV_TYPE_ADV_IND &&
advertisedDevice -> getAdvType () != BLE_HCI_ADV_TYPE_ADV_SCAN_IND ))
{
2023-04-06 15:56:53 -06:00
advertisedDevice -> m_callbackSent = 2 ;
2022-08-27 13:13:27 -06:00
pScan -> m_pScanCallbacks -> onResult ( advertisedDevice );
2020-07-01 17:26:44 -06:00
2021-01-30 18:27:06 -07:00
// Otherwise, wait for the scan response so we can report the complete data.
2022-04-10 10:21:45 -06:00
} else if ( isLegacyAdv && event_type == BLE_HCI_ADV_RPT_EVTYPE_SCAN_RSP ) {
2023-04-06 15:56:53 -06:00
advertisedDevice -> m_callbackSent = 2 ;
2022-08-27 13:13:27 -06:00
pScan -> m_pScanCallbacks -> onResult ( advertisedDevice );
2021-01-30 18:27:06 -07:00
}
2021-07-19 21:46:30 -06:00
// If not storing results and we have invoked the callback, delete the device.
2023-04-06 15:56:53 -06:00
if ( pScan -> m_maxResults == 0 && advertisedDevice -> m_callbackSent >= 2 ) {
2021-01-30 18:27:06 -07:00
pScan -> erase ( advertisedAddress );
2020-03-29 17:44:20 -06:00
}
}
return 0 ;
}
case BLE_GAP_EVENT_DISC_COMPLETE : {
NIMBLE_LOGD ( LOG_TAG , "discovery complete; reason=%d" ,
2021-01-30 18:06:29 -07:00
event -> disc_complete . reason );
2021-01-30 18:27:06 -07:00
if ( pScan -> m_maxResults == 0 ) {
pScan -> clearResults ();
}
2022-08-27 13:13:27 -06:00
if ( pScan -> m_pScanCallbacks != nullptr ) {
pScan -> m_pScanCallbacks -> onScanEnd ( pScan -> m_scanResults );
2020-03-29 17:44:20 -06:00
}
2020-05-13 22:03:56 -06:00
2020-06-21 22:07:01 -06:00
if ( pScan -> m_pTaskData != nullptr ) {
pScan -> m_pTaskData -> rc = event -> disc_complete . reason ;
xTaskNotifyGive ( pScan -> m_pTaskData -> task );
}
2020-03-29 17:44:20 -06:00
return 0 ;
}
default :
return 0 ;
}
} // gapEventHandler
/**
* @brief Should we perform an active or passive scan?
2021-01-30 18:27:06 -07:00
* The default is a passive scan. An active scan means that we will request a scan response.
2020-03-29 17:44:20 -06:00
* @param [in] active If true, we perform an active scan otherwise a passive scan.
*/
void NimBLEScan :: setActiveScan ( bool active ) {
2021-01-30 18:27:06 -07:00
m_scan_params . passive = ! active ;
2020-03-29 17:44:20 -06:00
} // setActiveScan
2020-07-01 17:26:44 -06:00
/**
* @brief Set whether or not the BLE controller should only report results
* from devices it has not already seen.
2020-07-30 20:16:58 -06:00
* @param [in] enabled If true, scanned devices will only be reported once.
2020-07-01 17:26:44 -06:00
* @details The controller has a limited buffer and will start reporting
2022-07-31 11:00:12 -06:00
* duplicate devices once the limit is reached.
2020-07-01 17:26:44 -06:00
*/
2020-07-23 20:18:41 -06:00
void NimBLEScan :: setDuplicateFilter ( bool enabled ) {
m_scan_params . filter_duplicates = enabled ;
2020-07-01 17:26:44 -06: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-30 20:16:58 -06:00
* @param [in] enabled If true, only limited discovery devices will be in scan results.
2020-07-01 17:26:44 -06:00
*/
2020-07-23 20:18:41 -06:00
void NimBLEScan :: setLimitedOnly ( bool enabled ) {
m_scan_params . limited = enabled ;
2020-07-01 17:26:44 -06:00
} // setLimited
/**
* @brief Sets the scan filter policy.
* @param [in] filter Can be one of:
2020-07-08 19:27:26 -06:00
* * BLE_HCI_SCAN_FILT_NO_WL (0)
* Scanner processes all advertising packets (white list not used) except\n
2020-07-01 17:26:44 -06:00
* directed, connectable advertising packets not sent to the scanner.
2020-07-08 19:27:26 -06:00
* * BLE_HCI_SCAN_FILT_USE_WL (1)
* Scanner processes advertisements from white list only. A connectable,\n
2022-07-31 11:00:12 -06:00
* directed advertisement is ignored unless it contains scanners address.
2020-07-08 19:27:26 -06:00
* * BLE_HCI_SCAN_FILT_NO_WL_INITA (2)
* Scanner process all advertising packets (white list not used). A\n
2020-07-01 17:26:44 -06:00
* connectable, directed advertisement shall not be ignored if the InitA
* is a resolvable private address.
2020-07-08 19:27:26 -06:00
* * BLE_HCI_SCAN_FILT_USE_WL_INITA (3)
* Scanner process advertisements from white list only. A connectable,\n
2020-07-01 17:26:44 -06: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-30 18:27:06 -07: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-29 17:44:20 -06:00
/**
* @brief Set the call backs to be invoked.
2022-08-27 13:13:27 -06:00
* @param [in] pScanCallbacks Call backs to be invoked.
2020-03-29 17:44:20 -06:00
* @param [in] wantDuplicates True if we wish to be called back with duplicates. Default is false.
*/
2022-08-27 13:13:27 -06:00
void NimBLEScan :: setScanCallbacks ( NimBLEScanCallbacks * pScanCallbacks , bool wantDuplicates ) {
2021-01-30 18:27:06 -07:00
setDuplicateFilter ( ! wantDuplicates );
2022-08-27 13:13:27 -06:00
m_pScanCallbacks = pScanCallbacks ;
} // setScanCallbacks
2020-03-29 17:44:20 -06:00
/**
* @brief Set the interval to scan.
2020-07-08 19:27:26 -06:00
* @param [in] intervalMSecs The scan interval (how often) in milliseconds.
2020-03-29 17:44:20 -06: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-23 20:18:41 -06:00
/**
* @brief Get the status of the scanner.
* @return true if scanning or scan starting.
*/
bool NimBLEScan :: isScanning () {
2021-01-10 21:54:32 -07:00
return ble_gap_disc_active ();
2020-07-23 20:18:41 -06:00
}
2020-03-29 17:44:20 -06:00
/**
* @brief Start scanning.
2024-10-31 16:09:05 -07:00
* @param [in] duration The duration in milliseconds for which to scan. 0 == scan forever.
2020-07-08 19:27:26 -06:00
* @param [in] is_continue Set to true to save previous scan results, false to clear them.
2020-03-29 17:44:20 -06:00
* @return True if scan started or false if there was an error.
*/
2022-08-27 13:13:27 -06:00
bool NimBLEScan :: start ( uint32_t duration , bool is_continue ) {
2022-01-15 12:43:17 -07:00
NIMBLE_LOGD ( LOG_TAG , ">> start: duration=%" PRIu32 , duration );
2020-05-13 22:03:56 -06:00
2020-03-29 17:44:20 -06:00
// Save the duration in the case that the host is reset so we can reuse it.
m_duration = duration ;
2020-05-13 22:03:56 -06:00
2020-03-29 17:44:20 -06:00
// If 0 duration specified then we assume a continuous scan is desired.
if ( duration == 0 ){
duration = BLE_HS_FOREVER ;
}
2020-05-13 22:03:56 -06:00
2021-01-10 21:54:32 -07:00
// Set the flag to ignore the results while we are deleting the vector
2020-03-29 17:44:20 -06:00
if ( ! is_continue ) {
2021-01-10 21:54:32 -07:00
m_ignoreResults = true ;
2020-03-29 17:44:20 -06:00
}
2020-05-13 22:03:56 -06:00
2022-04-10 10:21:45 -06: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 ;
2024-09-29 15:59:42 -06:00
int rc = ble_gap_ext_disc ( NimBLEDevice :: m_ownAddrType ,
2022-04-10 10:21:45 -06:00
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-06 16:52:42 -07:00
#else
2024-09-29 15:59:42 -06:00
int rc = ble_gap_disc ( NimBLEDevice :: m_ownAddrType ,
2022-04-10 10:21:45 -06:00
duration ,
& m_scan_params ,
NimBLEScan :: handleGapEvent ,
NULL );
2022-02-06 16:52:42 -07:00
#endif
2021-01-10 21:54:32 -07:00
switch ( rc ) {
case 0 :
if ( ! is_continue ) {
clearResults ();
}
break ;
case BLE_HS_EALREADY :
2021-03-31 20:24:57 -06:00
// Clear the cache if already scanning in case an advertiser was missed.
clearDuplicateCache ();
2021-01-10 21:54:32 -07: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 :
2024-07-04 10:56:30 -06:00
NIMBLE_LOGE ( LOG_TAG , "Unable to scan - Host Reset" );
2021-01-10 21:54:32 -07:00
break ;
default :
NIMBLE_LOGE ( LOG_TAG , "Error initiating GAP discovery procedure; rc=%d, %s" ,
rc , NimBLEUtils :: returnCodeToString ( rc ));
break ;
}
m_ignoreResults = false ;
NIMBLE_LOGD ( LOG_TAG , "<< start()" );
2021-01-12 21:25:30 -07:00
if ( rc != 0 && rc != BLE_HS_EALREADY ) {
2020-03-29 17:44:20 -06:00
return false ;
}
return true ;
} // start
/**
* @brief Stop an in progress scan.
2020-07-08 19:27:26 -06:00
* @return True if successful.
2020-03-29 17:44:20 -06:00
*/
2020-06-21 22:07:01 -06:00
bool NimBLEScan :: stop () {
2020-03-29 17:44:20 -06:00
NIMBLE_LOGD ( LOG_TAG , ">> stop()" );
2020-05-13 22:03:56 -06:00
2020-03-29 17:44:20 -06:00
int rc = ble_gap_disc_cancel ();
if ( rc != 0 && rc != BLE_HS_EALREADY ) {
2021-01-30 18:06:29 -07:00
NIMBLE_LOGE ( LOG_TAG , "Failed to cancel scan; rc=%d" , rc );
2020-06-21 22:07:01 -06:00
return false ;
2020-03-29 17:44:20 -06:00
}
2021-01-30 18:27:06 -07:00
if ( m_maxResults == 0 ) {
clearResults ();
}
2022-08-27 13:13:27 -06:00
if ( rc != BLE_HS_EALREADY && m_pScanCallbacks != nullptr ) {
m_pScanCallbacks -> onScanEnd ( m_scanResults );
2020-03-29 17:44:20 -06:00
}
2020-05-13 22:03:56 -06:00
2020-06-21 22:07:01 -06:00
if ( m_pTaskData != nullptr ) {
xTaskNotifyGive ( m_pTaskData -> task );
}
2020-05-13 22:03:56 -06:00
2020-03-29 17:44:20 -06:00
NIMBLE_LOGD ( LOG_TAG , "<< stop()" );
2020-06-21 22:07:01 -06:00
return true ;
2020-03-29 17:44:20 -06:00
} // stop
2021-03-31 20:24:57 -06:00
/**
* @brief Clears the duplicate scan filter cache.
*/
void NimBLEScan :: clearDuplicateCache () {
2021-07-19 21:46:30 -06:00
#ifdef CONFIG_IDF_TARGET_ESP32 // Not available for ESP32C3
2021-03-31 20:24:57 -06:00
esp_ble_scan_dupilcate_list_flush ();
2021-07-19 21:46:30 -06:00
#endif
2021-03-31 20:24:57 -06:00
}
2020-07-08 19:27:26 -06: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 07:21:46 -06:00
void NimBLEScan :: erase ( const NimBLEAddress & address ) {
2021-01-30 18:06:29 -07:00
NIMBLE_LOGD ( LOG_TAG , "erase device: %s" , address . toString (). c_str ());
2020-05-17 20:21:35 -06:00
2020-05-18 06:47:44 -06:00
for ( auto it = m_scanResults . m_advertisedDevicesVector . begin (); it != m_scanResults . m_advertisedDevicesVector . end (); ++ it ) {
2020-05-17 20:21:35 -06:00
if (( * it ) -> getAddress () == address ) {
delete * it ;
m_scanResults . m_advertisedDevicesVector . erase ( it );
break ;
}
}
2020-03-29 17:44:20 -06:00
}
/**
2021-01-12 20:42:19 -07:00
* @brief Called when host reset, we set a flag to stop scanning until synced.
2020-03-29 17:44:20 -06:00
*/
void NimBLEScan :: onHostReset () {
2021-01-12 20:42:19 -07:00
m_ignoreResults = true ;
2020-03-29 17:44:20 -06:00
}
2021-01-12 20:42:19 -07: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 ;
2022-08-27 13:13:27 -06:00
if ( m_duration == 0 && m_pScanCallbacks != nullptr ) {
start ( 0 , false );
2021-01-12 20:42:19 -07:00
}
}
2022-08-27 13:13:27 -06:00
/**
* @brief Start scanning and block until scanning has been completed.
2024-02-29 21:34:53 -03:00
* @param [in] duration The duration in milliseconds for which to scan.
2022-08-27 13:13:27 -06:00
* @param [in] is_continue Set to true to save previous scan results, false to clear them.
* @return The scan results.
*/
NimBLEScanResults NimBLEScan :: getResults ( uint32_t duration , bool is_continue ) {
if ( duration == 0 ) {
NIMBLE_LOGW ( LOG_TAG , "Blocking scan called with duration = forever" );
}
TaskHandle_t cur_task = xTaskGetCurrentTaskHandle ();
2024-11-02 19:00:07 -06:00
BleTaskData taskData = { nullptr , cur_task , 0 , nullptr };
2022-08-27 13:13:27 -06:00
m_pTaskData = & taskData ;
if ( start ( duration , is_continue )) {
#ifdef ulTaskNotifyValueClear
// Clear the task notification value to ensure we block
ulTaskNotifyValueClear ( cur_task , ULONG_MAX );
#endif
ulTaskNotifyTake ( pdTRUE , portMAX_DELAY );
}
m_pTaskData = nullptr ;
return m_scanResults ;
} // getResults
2020-03-29 17:44:20 -06: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-17 20:21:35 -06:00
for ( auto & it : m_scanResults . m_advertisedDevicesVector ) {
delete it ;
2020-03-29 17:44:20 -06:00
}
2020-05-17 20:21:35 -06:00
m_scanResults . m_advertisedDevicesVector . clear ();
2021-03-31 20:24:57 -06:00
clearDuplicateCache ();
2020-03-29 17:44:20 -06: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-08 19:27:26 -06:00
* @brief Get the count of devices found in the last scan.
2020-03-29 17:44:20 -06:00
* @return The number of devices found in the last scan.
*/
int NimBLEScanResults :: getCount () {
2020-05-17 20:21:35 -06:00
return m_advertisedDevicesVector . size ();
2020-03-29 17:44:20 -06: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-17 20:21:35 -06:00
return * m_advertisedDevicesVector [ i ];
}
2020-05-22 20:13:52 -06: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-17 20:21:35 -06:00
/**
2020-07-08 19:27:26 -06:00
* @brief Get a pointer to the specified device at the given address.
2020-05-17 20:21:35 -06: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-29 17:44:20 -06:00
}
2020-05-17 20:21:35 -06:00
return nullptr ;
2020-03-29 17:44:20 -06:00
}
2021-09-06 21:14:43 -06:00
#endif /* CONFIG_BT_ENABLED && CONFIG_BT_NIMBLE_ROLE_OBSERVER */