mirror of
https://github.com/h2zero/esp-nimble-cpp.git
synced 2024-12-25 04:00:46 +01:00
[BREAKING] Refactor NimBLEAdvertised device.
* Construct the device with the parameters from the advertisement in the initialization list. * Removed no longer needed methods; setAddress, setAdvType, setRSSI, setSetId, setPrimaryPhy, setSecondaryPhy, setPeriodicInterval. * Removed `hasRSSI()` method, the RSSI is always reported so this is redundant. * Replace setPayload with new method; `update` which will update the device info when new advertisement data is received. * getPayload now returns `const std::vector<uint8_t>` instead of a pointer to internal memory. * Added `begin` and `end` read-only iterators for convienience and use in range loops. * Timestamp removed, if needed then the app should track the time in the callback. * Consolidate some functions to use getPayloadByType. * Add optional index parameter to getPayloadByType. * Change payload indexing to use 0 as the first item. * Code cleanup and apply const correctness.
This commit is contained in:
parent
6279817143
commit
c2ab790e1d
3 changed files with 353 additions and 497 deletions
File diff suppressed because it is too large
Load diff
|
@ -12,25 +12,25 @@
|
|||
* Author: kolban
|
||||
*/
|
||||
|
||||
#ifndef COMPONENTS_NIMBLEADVERTISEDDEVICE_H_
|
||||
#define COMPONENTS_NIMBLEADVERTISEDDEVICE_H_
|
||||
#ifndef NIMBLE_CPP_ADVERTISED_DEVICE_H_
|
||||
#define NIMBLE_CPP_ADVERTISED_DEVICE_H_
|
||||
|
||||
#include "nimconfig.h"
|
||||
#if defined(CONFIG_BT_ENABLED) && defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER)
|
||||
|
||||
#include "NimBLEAddress.h"
|
||||
#include "NimBLEScan.h"
|
||||
#include "NimBLEUUID.h"
|
||||
# include "NimBLEAddress.h"
|
||||
# include "NimBLEScan.h"
|
||||
# include "NimBLEUUID.h"
|
||||
|
||||
#if defined(CONFIG_NIMBLE_CPP_IDF)
|
||||
#include "host/ble_hs_adv.h"
|
||||
#else
|
||||
#include "nimble/nimble/host/include/host/ble_hs_adv.h"
|
||||
#endif
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <time.h>
|
||||
# if defined(CONFIG_NIMBLE_CPP_IDF)
|
||||
# include "host/ble_hs_adv.h"
|
||||
# include "host/ble_gap.h"
|
||||
# else
|
||||
# include "nimble/nimble/host/include/host/ble_hs_adv.h"
|
||||
# include "nimble/nimble/host/include/host/ble_gap.h"
|
||||
# endif
|
||||
|
||||
# include <vector>
|
||||
|
||||
class NimBLEScan;
|
||||
/**
|
||||
|
@ -40,20 +40,59 @@ class NimBLEScan;
|
|||
* class provides a model of a detected device.
|
||||
*/
|
||||
class NimBLEAdvertisedDevice {
|
||||
public:
|
||||
NimBLEAdvertisedDevice();
|
||||
public:
|
||||
NimBLEAdvertisedDevice() = default;
|
||||
|
||||
NimBLEAddress getAddress();
|
||||
uint8_t getAdvType();
|
||||
uint8_t getAdvFlags();
|
||||
uint16_t getAppearance();
|
||||
uint16_t getAdvInterval();
|
||||
uint16_t getMinInterval();
|
||||
uint16_t getMaxInterval();
|
||||
uint8_t getManufacturerDataCount();
|
||||
std::string getManufacturerData(uint8_t index = 0);
|
||||
std::string getURI();
|
||||
std::string getPayloadByType(uint16_t type);
|
||||
uint8_t getAdvType() const;
|
||||
uint8_t getAdvFlags() const;
|
||||
uint16_t getAppearance() const;
|
||||
uint16_t getAdvInterval() const;
|
||||
uint16_t getMinInterval() const;
|
||||
uint16_t getMaxInterval() const;
|
||||
uint8_t getManufacturerDataCount() const;
|
||||
const NimBLEAddress& getAddress() const;
|
||||
std::string getManufacturerData(uint8_t index = 0) const;
|
||||
std::string getURI() const;
|
||||
std::string getPayloadByType(uint16_t type, uint8_t index = 0) const;
|
||||
std::string getName() const;
|
||||
int8_t getRSSI() const;
|
||||
NimBLEScan* getScan() const;
|
||||
uint8_t getServiceDataCount() const;
|
||||
std::string getServiceData(uint8_t index = 0) const;
|
||||
std::string getServiceData(const NimBLEUUID& uuid) const;
|
||||
NimBLEUUID getServiceDataUUID(uint8_t index = 0) const;
|
||||
NimBLEUUID getServiceUUID(uint8_t index = 0) const;
|
||||
uint8_t getServiceUUIDCount() const;
|
||||
NimBLEAddress getTargetAddress(uint8_t index = 0) const;
|
||||
uint8_t getTargetAddressCount() const;
|
||||
int8_t getTXPower() const;
|
||||
uint8_t getAdvLength() const;
|
||||
uint8_t getAddressType() const;
|
||||
bool isAdvertisingService(const NimBLEUUID& uuid) const;
|
||||
bool haveAppearance() const;
|
||||
bool haveManufacturerData() const;
|
||||
bool haveName() const;
|
||||
bool haveServiceData() const;
|
||||
bool haveServiceUUID() const;
|
||||
bool haveTXPower() const;
|
||||
bool haveConnParams() const;
|
||||
bool haveAdvInterval() const;
|
||||
bool haveTargetAddress() const;
|
||||
bool haveURI() const;
|
||||
bool haveType(uint16_t type) const;
|
||||
std::string toString() const;
|
||||
bool isConnectable() const;
|
||||
bool isLegacyAdvertisement() const;
|
||||
# if CONFIG_BT_NIMBLE_EXT_ADV
|
||||
uint8_t getSetId() const;
|
||||
uint8_t getPrimaryPhy() const;
|
||||
uint8_t getSecondaryPhy() const;
|
||||
uint16_t getPeriodicInterval() const;
|
||||
# endif
|
||||
|
||||
const std::vector<uint8_t>& getPayload() const;
|
||||
const std::vector<uint8_t>::const_iterator begin() const;
|
||||
const std::vector<uint8_t>::const_iterator end() const;
|
||||
|
||||
/**
|
||||
* @brief A template to convert the service data to <type\>.
|
||||
|
@ -63,21 +102,14 @@ public:
|
|||
* less than <tt>sizeof(<type\>)</tt>.
|
||||
* @details <b>Use:</b> <tt>getManufacturerData<type>(skipSizeCheck);</tt>
|
||||
*/
|
||||
template<typename T>
|
||||
T getManufacturerData(bool skipSizeCheck = false) {
|
||||
template <typename T>
|
||||
T getManufacturerData(bool skipSizeCheck = false) const {
|
||||
std::string data = getManufacturerData();
|
||||
if(!skipSizeCheck && data.size() < sizeof(T)) return T();
|
||||
const char *pData = data.data();
|
||||
return *((T *)pData);
|
||||
if (!skipSizeCheck && data.size() < sizeof(T)) return T();
|
||||
const char* pData = data.data();
|
||||
return *((T*)pData);
|
||||
}
|
||||
|
||||
std::string getName();
|
||||
int getRSSI();
|
||||
NimBLEScan* getScan();
|
||||
uint8_t getServiceDataCount();
|
||||
std::string getServiceData(uint8_t index = 0);
|
||||
std::string getServiceData(const NimBLEUUID &uuid);
|
||||
|
||||
/**
|
||||
* @brief A template to convert the service data to <tt><type\></tt>.
|
||||
* @tparam T The type to convert the data to.
|
||||
|
@ -87,12 +119,12 @@ public:
|
|||
* less than <tt>sizeof(<type\>)</tt>.
|
||||
* @details <b>Use:</b> <tt>getServiceData<type>(skipSizeCheck);</tt>
|
||||
*/
|
||||
template<typename T>
|
||||
T getServiceData(uint8_t index = 0, bool skipSizeCheck = false) {
|
||||
template <typename T>
|
||||
T getServiceData(uint8_t index = 0, bool skipSizeCheck = false) const {
|
||||
std::string data = getServiceData(index);
|
||||
if(!skipSizeCheck && data.size() < sizeof(T)) return T();
|
||||
const char *pData = data.data();
|
||||
return *((T *)pData);
|
||||
if (!skipSizeCheck && data.size() < sizeof(T)) return T();
|
||||
const char* pData = data.data();
|
||||
return *((T*)pData);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -104,80 +136,38 @@ public:
|
|||
* less than <tt>sizeof(<type\>)</tt>.
|
||||
* @details <b>Use:</b> <tt>getServiceData<type>(skipSizeCheck);</tt>
|
||||
*/
|
||||
template<typename T>
|
||||
T getServiceData(const NimBLEUUID &uuid, bool skipSizeCheck = false) {
|
||||
template <typename T>
|
||||
T getServiceData(const NimBLEUUID& uuid, bool skipSizeCheck = false) const {
|
||||
std::string data = getServiceData(uuid);
|
||||
if(!skipSizeCheck && data.size() < sizeof(T)) return T();
|
||||
const char *pData = data.data();
|
||||
return *((T *)pData);
|
||||
if (!skipSizeCheck && data.size() < sizeof(T)) return T();
|
||||
const char* pData = data.data();
|
||||
return *((T*)pData);
|
||||
}
|
||||
|
||||
NimBLEUUID getServiceDataUUID(uint8_t index = 0);
|
||||
NimBLEUUID getServiceUUID(uint8_t index = 0);
|
||||
uint8_t getServiceUUIDCount();
|
||||
NimBLEAddress getTargetAddress(uint8_t index = 0);
|
||||
uint8_t getTargetAddressCount();
|
||||
int8_t getTXPower();
|
||||
uint8_t* getPayload();
|
||||
uint8_t getAdvLength();
|
||||
size_t getPayloadLength();
|
||||
uint8_t getAddressType();
|
||||
time_t getTimestamp();
|
||||
bool isAdvertisingService(const NimBLEUUID &uuid);
|
||||
bool haveAppearance();
|
||||
bool haveManufacturerData();
|
||||
bool haveName();
|
||||
bool haveRSSI();
|
||||
bool haveServiceData();
|
||||
bool haveServiceUUID();
|
||||
bool haveTXPower();
|
||||
bool haveConnParams();
|
||||
bool haveAdvInterval();
|
||||
bool haveTargetAddress();
|
||||
bool haveURI();
|
||||
bool haveType(uint16_t type);
|
||||
std::string toString();
|
||||
bool isConnectable();
|
||||
bool isLegacyAdvertisement();
|
||||
#if CONFIG_BT_NIMBLE_EXT_ADV
|
||||
uint8_t getSetId();
|
||||
uint8_t getPrimaryPhy();
|
||||
uint8_t getSecondaryPhy();
|
||||
uint16_t getPeriodicInterval();
|
||||
#endif
|
||||
|
||||
private:
|
||||
private:
|
||||
friend class NimBLEScan;
|
||||
|
||||
void setAddress(NimBLEAddress address);
|
||||
void setAdvType(uint8_t advType, bool isLegacyAdv);
|
||||
void setPayload(const uint8_t *payload, uint8_t length, bool append);
|
||||
void setRSSI(int rssi);
|
||||
#if CONFIG_BT_NIMBLE_EXT_ADV
|
||||
void setSetId(uint8_t sid) { m_sid = sid; }
|
||||
void setPrimaryPhy(uint8_t phy) { m_primPhy = phy; }
|
||||
void setSecondaryPhy(uint8_t phy) { m_secPhy = phy; }
|
||||
void setPeriodicInterval(uint16_t itvl) { m_periodicItvl = itvl; }
|
||||
#endif
|
||||
uint8_t findAdvField(uint8_t type, uint8_t index = 0, size_t * data_loc = nullptr);
|
||||
size_t findServiceData(uint8_t index, uint8_t* bytes);
|
||||
NimBLEAdvertisedDevice(const ble_gap_event* event, uint8_t eventType);
|
||||
void update(const ble_gap_event* event, uint8_t eventType);
|
||||
uint8_t findAdvField(uint8_t type, uint8_t index = 0, size_t* data_loc = nullptr) const;
|
||||
size_t findServiceData(uint8_t index, uint8_t* bytes) const;
|
||||
|
||||
NimBLEAddress m_address;
|
||||
uint8_t m_advType;
|
||||
int m_rssi;
|
||||
time_t m_timestamp;
|
||||
uint8_t m_callbackSent;
|
||||
uint8_t m_advLength;
|
||||
#if CONFIG_BT_NIMBLE_EXT_ADV
|
||||
bool m_isLegacyAdv;
|
||||
uint8_t m_sid;
|
||||
uint8_t m_primPhy;
|
||||
uint8_t m_secPhy;
|
||||
uint16_t m_periodicItvl;
|
||||
#endif
|
||||
NimBLEAddress m_address{};
|
||||
uint8_t m_advType{};
|
||||
int8_t m_rssi{};
|
||||
uint8_t m_callbackSent{};
|
||||
uint8_t m_advLength{};
|
||||
|
||||
std::vector<uint8_t> m_payload;
|
||||
# if CONFIG_BT_NIMBLE_EXT_ADV
|
||||
bool m_isLegacyAdv{};
|
||||
uint8_t m_sid{};
|
||||
uint8_t m_primPhy{};
|
||||
uint8_t m_secPhy{};
|
||||
uint16_t m_periodicItvl{};
|
||||
# endif
|
||||
|
||||
std::vector<uint8_t> m_payload;
|
||||
};
|
||||
|
||||
#endif /* CONFIG_BT_ENABLED && CONFIG_BT_NIMBLE_ROLE_OBSERVER */
|
||||
#endif /* COMPONENTS_NIMBLEADVERTISEDDEVICE_H_ */
|
||||
#endif /* NIMBLE_CPP_ADVERTISED_DEVICE_H_ */
|
||||
|
|
|
@ -111,29 +111,17 @@ int NimBLEScan::handleGapEvent(ble_gap_event* event, void* arg) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
advertisedDevice = new NimBLEAdvertisedDevice();
|
||||
advertisedDevice->setAddress(advertisedAddress);
|
||||
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
|
||||
advertisedDevice = new NimBLEAdvertisedDevice(event, event_type);
|
||||
pScan->m_scanResults.m_advertisedDevicesVector.push_back(advertisedDevice);
|
||||
NIMBLE_LOGI(LOG_TAG, "New advertiser: %s", advertisedAddress.toString().c_str());
|
||||
} else if (advertisedDevice != nullptr) {
|
||||
advertisedDevice->update(event, event_type);
|
||||
NIMBLE_LOGI(LOG_TAG, "Updated advertiser: %s", advertisedAddress.toString().c_str());
|
||||
} else {
|
||||
// Scan response from unknown device
|
||||
return 0;
|
||||
}
|
||||
|
||||
advertisedDevice->m_timestamp = time(nullptr);
|
||||
advertisedDevice->setRSSI(disc.rssi);
|
||||
advertisedDevice->setPayload(disc.data, disc.length_data, (isLegacyAdv &&
|
||||
event_type == BLE_HCI_ADV_RPT_EVTYPE_SCAN_RSP));
|
||||
|
||||
if (pScan->m_pScanCallbacks) {
|
||||
if (advertisedDevice->m_callbackSent == 0 || !pScan->m_scan_params.filter_duplicates) {
|
||||
advertisedDevice->m_callbackSent = 1;
|
||||
|
|
Loading…
Reference in a new issue