/* * Copyright 2020-2024 Ryan Powell and * esp-nimble-cpp, NimBLE-Arduino contributors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef NIMBLE_CPP_SCAN_H_ #define NIMBLE_CPP_SCAN_H_ #include "nimconfig.h" #if defined(CONFIG_BT_ENABLED) && defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER) # include "NimBLEAdvertisedDevice.h" # include "NimBLEUtils.h" # if defined(CONFIG_NIMBLE_CPP_IDF) # include "host/ble_gap.h" # else # include "nimble/nimble/host/include/host/ble_gap.h" # endif # include class NimBLEDevice; class NimBLEScan; class NimBLEAdvertisedDevice; class NimBLEScanCallbacks; class NimBLEAddress; /** * @brief A class that contains and operates on the results of a BLE scan. * @details When a scan completes, we have a set of found devices. Each device is described * by a NimBLEAdvertisedDevice object. The number of items in the set is given by * getCount(). We can retrieve a device by calling getDevice() passing in the * index (starting at 0) of the desired device. */ class NimBLEScanResults { public: void dump() const; int getCount() const; const NimBLEAdvertisedDevice* getDevice(uint32_t idx) const; const NimBLEAdvertisedDevice* getDevice(const NimBLEAddress& address) const; std::vector::const_iterator begin() const; std::vector::const_iterator end() const; private: friend NimBLEScan; std::vector m_deviceVec; }; /** * @brief Perform and manage %BLE scans. * * Scanning is associated with a %BLE client that is attempting to locate BLE servers. */ class NimBLEScan { public: bool start(uint32_t duration, bool isContinue = false, bool restart = true); bool isScanning(); void setScanCallbacks(NimBLEScanCallbacks* pScanCallbacks, bool wantDuplicates = false); void setActiveScan(bool active); void setInterval(uint16_t intervalMs); void setWindow(uint16_t windowMs); void setDuplicateFilter(uint8_t enabled); void setLimitedOnly(bool enabled); void setFilterPolicy(uint8_t filter); bool stop(); void clearResults(); NimBLEScanResults getResults(); NimBLEScanResults getResults(uint32_t duration, bool is_continue = false); void setMaxResults(uint8_t maxResults); void erase(const NimBLEAddress& address); void erase(const NimBLEAdvertisedDevice* device); # if CONFIG_BT_NIMBLE_EXT_ADV enum Phy { SCAN_1M = 0x01, SCAN_CODED = 0x02, SCAN_ALL = 0x03 }; void setPhy(Phy phyMask); void setPeriod(uint32_t periodMs); # endif private: friend class NimBLEDevice; NimBLEScan(); ~NimBLEScan(); static int handleGapEvent(ble_gap_event* event, void* arg); void onHostSync(); NimBLEScanCallbacks* m_pScanCallbacks; ble_gap_disc_params m_scanParams; NimBLEScanResults m_scanResults; NimBLETaskData* m_pTaskData; uint8_t m_maxResults; # if CONFIG_BT_NIMBLE_EXT_ADV uint8_t m_phy{SCAN_ALL}; uint16_t m_period{0}; # endif }; /** * @brief A callback handler for callbacks associated device scanning. */ class NimBLEScanCallbacks { public: virtual ~NimBLEScanCallbacks() {} /** * @brief Called when a new device is discovered, before the scan result is received (if applicable). * @param [in] advertisedDevice The device which was discovered. */ virtual void onDiscovered(const NimBLEAdvertisedDevice* advertisedDevice); /** * @brief Called when a new scan result is complete, including scan response data (if applicable). * @param [in] advertisedDevice The device for which the complete result is available. */ virtual void onResult(const NimBLEAdvertisedDevice* advertisedDevice); /** * @brief Called when a scan operation ends. * @param [in] scanResults The results of the scan that ended. * @param [in] reason The reason code for why the scan ended. */ virtual void onScanEnd(const NimBLEScanResults& scanResults, int reason); }; #endif // CONFIG_BT_ENABLED CONFIG_BT_NIMBLE_ROLE_OBSERVER #endif // NIMBLE_CPP_SCAN_H_