mirror of
https://github.com/h2zero/esp-nimble-cpp.git
synced 2024-11-24 06:00:55 +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,8 +12,9 @@
|
||||||
* Author: kolban
|
* Author: kolban
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef COMPONENTS_NIMBLEADVERTISEDDEVICE_H_
|
#ifndef NIMBLE_CPP_ADVERTISED_DEVICE_H_
|
||||||
#define COMPONENTS_NIMBLEADVERTISEDDEVICE_H_
|
#define NIMBLE_CPP_ADVERTISED_DEVICE_H_
|
||||||
|
|
||||||
#include "nimconfig.h"
|
#include "nimconfig.h"
|
||||||
#if defined(CONFIG_BT_ENABLED) && defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER)
|
#if defined(CONFIG_BT_ENABLED) && defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER)
|
||||||
|
|
||||||
|
@ -23,14 +24,13 @@
|
||||||
|
|
||||||
# if defined(CONFIG_NIMBLE_CPP_IDF)
|
# if defined(CONFIG_NIMBLE_CPP_IDF)
|
||||||
# include "host/ble_hs_adv.h"
|
# include "host/ble_hs_adv.h"
|
||||||
|
# include "host/ble_gap.h"
|
||||||
# else
|
# else
|
||||||
# include "nimble/nimble/host/include/host/ble_hs_adv.h"
|
# include "nimble/nimble/host/include/host/ble_hs_adv.h"
|
||||||
|
# include "nimble/nimble/host/include/host/ble_gap.h"
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
#include <map>
|
|
||||||
# include <vector>
|
# include <vector>
|
||||||
#include <time.h>
|
|
||||||
|
|
||||||
|
|
||||||
class NimBLEScan;
|
class NimBLEScan;
|
||||||
/**
|
/**
|
||||||
|
@ -41,19 +41,58 @@ class NimBLEScan;
|
||||||
*/
|
*/
|
||||||
class NimBLEAdvertisedDevice {
|
class NimBLEAdvertisedDevice {
|
||||||
public:
|
public:
|
||||||
NimBLEAdvertisedDevice();
|
NimBLEAdvertisedDevice() = default;
|
||||||
|
|
||||||
NimBLEAddress getAddress();
|
uint8_t getAdvType() const;
|
||||||
uint8_t getAdvType();
|
uint8_t getAdvFlags() const;
|
||||||
uint8_t getAdvFlags();
|
uint16_t getAppearance() const;
|
||||||
uint16_t getAppearance();
|
uint16_t getAdvInterval() const;
|
||||||
uint16_t getAdvInterval();
|
uint16_t getMinInterval() const;
|
||||||
uint16_t getMinInterval();
|
uint16_t getMaxInterval() const;
|
||||||
uint16_t getMaxInterval();
|
uint8_t getManufacturerDataCount() const;
|
||||||
uint8_t getManufacturerDataCount();
|
const NimBLEAddress& getAddress() const;
|
||||||
std::string getManufacturerData(uint8_t index = 0);
|
std::string getManufacturerData(uint8_t index = 0) const;
|
||||||
std::string getURI();
|
std::string getURI() const;
|
||||||
std::string getPayloadByType(uint16_t type);
|
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\>.
|
* @brief A template to convert the service data to <type\>.
|
||||||
|
@ -64,20 +103,13 @@ public:
|
||||||
* @details <b>Use:</b> <tt>getManufacturerData<type>(skipSizeCheck);</tt>
|
* @details <b>Use:</b> <tt>getManufacturerData<type>(skipSizeCheck);</tt>
|
||||||
*/
|
*/
|
||||||
template <typename T>
|
template <typename T>
|
||||||
T getManufacturerData(bool skipSizeCheck = false) {
|
T getManufacturerData(bool skipSizeCheck = false) const {
|
||||||
std::string data = getManufacturerData();
|
std::string data = getManufacturerData();
|
||||||
if (!skipSizeCheck && data.size() < sizeof(T)) return T();
|
if (!skipSizeCheck && data.size() < sizeof(T)) return T();
|
||||||
const char* pData = data.data();
|
const char* pData = data.data();
|
||||||
return *((T*)pData);
|
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>.
|
* @brief A template to convert the service data to <tt><type\></tt>.
|
||||||
* @tparam T The type to convert the data to.
|
* @tparam T The type to convert the data to.
|
||||||
|
@ -88,7 +120,7 @@ public:
|
||||||
* @details <b>Use:</b> <tt>getServiceData<type>(skipSizeCheck);</tt>
|
* @details <b>Use:</b> <tt>getServiceData<type>(skipSizeCheck);</tt>
|
||||||
*/
|
*/
|
||||||
template <typename T>
|
template <typename T>
|
||||||
T getServiceData(uint8_t index = 0, bool skipSizeCheck = false) {
|
T getServiceData(uint8_t index = 0, bool skipSizeCheck = false) const {
|
||||||
std::string data = getServiceData(index);
|
std::string data = getServiceData(index);
|
||||||
if (!skipSizeCheck && data.size() < sizeof(T)) return T();
|
if (!skipSizeCheck && data.size() < sizeof(T)) return T();
|
||||||
const char* pData = data.data();
|
const char* pData = data.data();
|
||||||
|
@ -105,79 +137,37 @@ public:
|
||||||
* @details <b>Use:</b> <tt>getServiceData<type>(skipSizeCheck);</tt>
|
* @details <b>Use:</b> <tt>getServiceData<type>(skipSizeCheck);</tt>
|
||||||
*/
|
*/
|
||||||
template <typename T>
|
template <typename T>
|
||||||
T getServiceData(const NimBLEUUID &uuid, bool skipSizeCheck = false) {
|
T getServiceData(const NimBLEUUID& uuid, bool skipSizeCheck = false) const {
|
||||||
std::string data = getServiceData(uuid);
|
std::string data = getServiceData(uuid);
|
||||||
if (!skipSizeCheck && data.size() < sizeof(T)) return T();
|
if (!skipSizeCheck && data.size() < sizeof(T)) return T();
|
||||||
const char* pData = data.data();
|
const char* pData = data.data();
|
||||||
return *((T*)pData);
|
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;
|
friend class NimBLEScan;
|
||||||
|
|
||||||
void setAddress(NimBLEAddress address);
|
NimBLEAdvertisedDevice(const ble_gap_event* event, uint8_t eventType);
|
||||||
void setAdvType(uint8_t advType, bool isLegacyAdv);
|
void update(const ble_gap_event* event, uint8_t eventType);
|
||||||
void setPayload(const uint8_t *payload, uint8_t length, bool append);
|
uint8_t findAdvField(uint8_t type, uint8_t index = 0, size_t* data_loc = nullptr) const;
|
||||||
void setRSSI(int rssi);
|
size_t findServiceData(uint8_t index, uint8_t* bytes) const;
|
||||||
#if CONFIG_BT_NIMBLE_EXT_ADV
|
|
||||||
void setSetId(uint8_t sid) { m_sid = sid; }
|
NimBLEAddress m_address{};
|
||||||
void setPrimaryPhy(uint8_t phy) { m_primPhy = phy; }
|
uint8_t m_advType{};
|
||||||
void setSecondaryPhy(uint8_t phy) { m_secPhy = phy; }
|
int8_t m_rssi{};
|
||||||
void setPeriodicInterval(uint16_t itvl) { m_periodicItvl = itvl; }
|
uint8_t m_callbackSent{};
|
||||||
#endif
|
uint8_t m_advLength{};
|
||||||
uint8_t findAdvField(uint8_t type, uint8_t index = 0, size_t * data_loc = nullptr);
|
|
||||||
size_t findServiceData(uint8_t index, uint8_t* bytes);
|
|
||||||
|
|
||||||
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
|
# if CONFIG_BT_NIMBLE_EXT_ADV
|
||||||
bool m_isLegacyAdv;
|
bool m_isLegacyAdv{};
|
||||||
uint8_t m_sid;
|
uint8_t m_sid{};
|
||||||
uint8_t m_primPhy;
|
uint8_t m_primPhy{};
|
||||||
uint8_t m_secPhy;
|
uint8_t m_secPhy{};
|
||||||
uint16_t m_periodicItvl;
|
uint16_t m_periodicItvl{};
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
std::vector<uint8_t> m_payload;
|
std::vector<uint8_t> m_payload;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* CONFIG_BT_ENABLED && CONFIG_BT_NIMBLE_ROLE_OBSERVER */
|
#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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
advertisedDevice = new NimBLEAdvertisedDevice();
|
advertisedDevice = new NimBLEAdvertisedDevice(event, event_type);
|
||||||
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
|
|
||||||
pScan->m_scanResults.m_advertisedDevicesVector.push_back(advertisedDevice);
|
pScan->m_scanResults.m_advertisedDevicesVector.push_back(advertisedDevice);
|
||||||
NIMBLE_LOGI(LOG_TAG, "New advertiser: %s", advertisedAddress.toString().c_str());
|
NIMBLE_LOGI(LOG_TAG, "New advertiser: %s", advertisedAddress.toString().c_str());
|
||||||
} else if (advertisedDevice != nullptr) {
|
} else if (advertisedDevice != nullptr) {
|
||||||
|
advertisedDevice->update(event, event_type);
|
||||||
NIMBLE_LOGI(LOG_TAG, "Updated advertiser: %s", advertisedAddress.toString().c_str());
|
NIMBLE_LOGI(LOG_TAG, "Updated advertiser: %s", advertisedAddress.toString().c_str());
|
||||||
} else {
|
} else {
|
||||||
// Scan response from unknown device
|
// Scan response from unknown device
|
||||||
return 0;
|
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 (pScan->m_pScanCallbacks) {
|
||||||
if (advertisedDevice->m_callbackSent == 0 || !pScan->m_scan_params.filter_duplicates) {
|
if (advertisedDevice->m_callbackSent == 0 || !pScan->m_scan_params.filter_duplicates) {
|
||||||
advertisedDevice->m_callbackSent = 1;
|
advertisedDevice->m_callbackSent = 1;
|
||||||
|
|
Loading…
Reference in a new issue