mirror of
https://github.com/h2zero/esp-nimble-cpp.git
synced 2024-11-22 13:10:55 +01:00
Add support for getting multiple services data from advertisments. (#20)
* Add support for getting multiple services data from advertisments. * Adds new methods for getting advertised service data and UUIDS. - getServiceData(index), gets the service data by index value. - getServiceData(NimBLEUUID), gets the service data by UUID. - getServiceDataCount(), gets the number of services with data advertised. * Templates added for getServiceData(index) and getServiceData(NimBLEUUID) to be able to specify the data type returned by these methods Example: getServiceData<uint32_t>(NimBLEUUID("ABCD"); * Also added: - getServiceUUID(index), gets the advertised service UUID by index value. - getServiceUUIDCount(), gets the number of advertised services.
This commit is contained in:
parent
f1a13d5949
commit
b2df8384b3
3 changed files with 201 additions and 180 deletions
|
@ -17,6 +17,7 @@
|
||||||
#include "nimconfig.h"
|
#include "nimconfig.h"
|
||||||
#if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER)
|
#if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER)
|
||||||
|
|
||||||
|
#include "NimBLEDevice.h"
|
||||||
#include "NimBLEAdvertisedDevice.h"
|
#include "NimBLEAdvertisedDevice.h"
|
||||||
#include "NimBLEUtils.h"
|
#include "NimBLEUtils.h"
|
||||||
#include "NimBLELog.h"
|
#include "NimBLELog.h"
|
||||||
|
@ -30,15 +31,11 @@ static const char* LOG_TAG = "NimBLEAdvertisedDevice";
|
||||||
NimBLEAdvertisedDevice::NimBLEAdvertisedDevice() {
|
NimBLEAdvertisedDevice::NimBLEAdvertisedDevice() {
|
||||||
m_advType = 0;
|
m_advType = 0;
|
||||||
m_appearance = 0;
|
m_appearance = 0;
|
||||||
m_deviceType = 0;
|
|
||||||
m_manufacturerData = "";
|
m_manufacturerData = "";
|
||||||
m_name = "";
|
m_name = "";
|
||||||
m_rssi = -9999;
|
m_rssi = -9999;
|
||||||
m_serviceData = "";
|
|
||||||
m_txPower = 0;
|
m_txPower = 0;
|
||||||
m_payloadLength = 0;
|
m_payloadLength = 0;
|
||||||
m_pScan = nullptr;
|
|
||||||
m_payloadLength = 0;
|
|
||||||
m_payload = nullptr;
|
m_payload = nullptr;
|
||||||
|
|
||||||
m_haveAppearance = false;
|
m_haveAppearance = false;
|
||||||
|
@ -121,36 +118,74 @@ int NimBLEAdvertisedDevice::getRSSI() {
|
||||||
* @return The scan object.
|
* @return The scan object.
|
||||||
*/
|
*/
|
||||||
NimBLEScan* NimBLEAdvertisedDevice::getScan() {
|
NimBLEScan* NimBLEAdvertisedDevice::getScan() {
|
||||||
return m_pScan;
|
return NimBLEDevice::getScan();
|
||||||
} // getScan
|
} // getScan
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the service data.
|
* @brief Get the service data.
|
||||||
* @return The ServiceData of the advertised device.
|
* @param [in] index The vector index of the service data requested.
|
||||||
|
* @return The advertised service data or empty string if no data.
|
||||||
*/
|
*/
|
||||||
std::string NimBLEAdvertisedDevice::getServiceData() {
|
std::string NimBLEAdvertisedDevice::getServiceData(uint8_t index) {
|
||||||
return m_serviceData;
|
if(index > m_serviceDataVec.size()) {
|
||||||
|
NIMBLE_LOGW(LOG_TAG, "getServiceData: index out of range");
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return m_serviceDataVec[index].second;
|
||||||
|
} //getServiceData
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the service data.
|
||||||
|
* @param [in] uuid The uuid of the service data requested.
|
||||||
|
* @return The advertised service data or empty string if no data.
|
||||||
|
*/
|
||||||
|
std::string NimBLEAdvertisedDevice::getServiceData(const NimBLEUUID &uuid) const {
|
||||||
|
for(auto &it : m_serviceDataVec) {
|
||||||
|
if(it.first == uuid) {
|
||||||
|
return it.second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
NIMBLE_LOGW(LOG_TAG, "getServiceData: uuid not found");
|
||||||
|
return "";
|
||||||
} //getServiceData
|
} //getServiceData
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the advertised service UUID.
|
* @brief Get the advertised service UUID.
|
||||||
* @return The advertise service UUID.
|
* @param [in] index The vector index of the service data UUID requested.
|
||||||
|
* @return The advertised service UUID or an empty UUID if not found.
|
||||||
*/
|
*/
|
||||||
|
NimBLEUUID NimBLEAdvertisedDevice::getServiceDataUUID(uint8_t index) {
|
||||||
NimBLEUUID NimBLEAdvertisedDevice::getServiceDataUUID() {
|
if(!haveServiceData() || index > m_serviceDataVec.size()) {
|
||||||
return m_serviceDataUUID;
|
NIMBLE_LOGW(LOG_TAG, "getServiceDataUUID: index out of range");
|
||||||
|
return NimBLEUUID("");
|
||||||
|
}
|
||||||
|
return m_serviceDataVec[index].first;
|
||||||
} // getServiceDataUUID
|
} // getServiceDataUUID
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the Service UUID.
|
* @brief Get the count of advertised service data UUIDS
|
||||||
* @return The Service UUID of the advertised device.
|
* @return The number of service data UUIDS in the vector.
|
||||||
*/
|
*/
|
||||||
|
size_t NimBLEAdvertisedDevice::getServiceDataCount() {
|
||||||
|
return m_serviceDataVec.size();
|
||||||
|
} // getServiceDataCount
|
||||||
|
|
||||||
NimBLEUUID NimBLEAdvertisedDevice::getServiceUUID() { //TODO Remove it eventually, is no longer useful
|
|
||||||
return m_serviceUUIDs[0];
|
/**
|
||||||
|
* @brief Get the Service UUID.
|
||||||
|
* @param [in] index The vector index of the service UUID requested.
|
||||||
|
* @return The Service UUID of the advertised service, or an empty UUID if not found.
|
||||||
|
*/
|
||||||
|
NimBLEUUID NimBLEAdvertisedDevice::getServiceUUID(uint8_t index) {
|
||||||
|
if(!haveServiceUUID() || index > m_serviceUUIDs.size()) {
|
||||||
|
NIMBLE_LOGW(LOG_TAG, "getServiceUUID: index out of range");
|
||||||
|
return NimBLEUUID("");
|
||||||
|
}
|
||||||
|
return m_serviceUUIDs[index];
|
||||||
} // getServiceUUID
|
} // getServiceUUID
|
||||||
|
|
||||||
|
|
||||||
|
@ -158,9 +193,8 @@ NimBLEUUID NimBLEAdvertisedDevice::getServiceUUID() { //TODO Remove it eventual
|
||||||
* @brief Check advertised services for existance of the required UUID
|
* @brief Check advertised services for existance of the required UUID
|
||||||
* @return Return true if service is advertised
|
* @return Return true if service is advertised
|
||||||
*/
|
*/
|
||||||
bool NimBLEAdvertisedDevice::isAdvertisingService(const NimBLEUUID &uuid){
|
bool NimBLEAdvertisedDevice::isAdvertisingService(const NimBLEUUID &uuid) const {
|
||||||
for (int i = 0; i < m_serviceUUIDs.size(); i++) {
|
for (int i = 0; i < m_serviceUUIDs.size(); i++) {
|
||||||
NIMBLE_LOGI(LOG_TAG, "Comparing UUIDS: %s %s", m_serviceUUIDs[i].toString().c_str(), uuid.toString().c_str());
|
|
||||||
if (m_serviceUUIDs[i].equals(uuid)) return true;
|
if (m_serviceUUIDs[i].equals(uuid)) return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -251,121 +285,126 @@ bool NimBLEAdvertisedDevice::haveTXPower() {
|
||||||
*
|
*
|
||||||
* https://www.bluetooth.com/specifications/assigned-numbers/generic-access-profile
|
* https://www.bluetooth.com/specifications/assigned-numbers/generic-access-profile
|
||||||
*/
|
*/
|
||||||
void NimBLEAdvertisedDevice::parseAdvertisement(ble_hs_adv_fields *fields) {
|
void NimBLEAdvertisedDevice::parseAdvertisement(uint8_t* payload, uint8_t length) {
|
||||||
//char s[BLE_HS_ADV_MAX_SZ];
|
struct ble_hs_adv_fields fields;
|
||||||
uint8_t *u8p;
|
int rc = ble_hs_adv_parse_fields(&fields, payload, length);
|
||||||
uint8_t length;
|
if (rc != 0) {
|
||||||
int i;
|
NIMBLE_LOGE(LOG_TAG, "Gap Event Parse ERROR.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (fields->uuids16 != NULL) {
|
m_payload = payload;
|
||||||
for (i = 0; i < fields->num_uuids16; i++) {
|
m_payloadLength = length;
|
||||||
setServiceUUID(NimBLEUUID(fields->uuids16[i].value));
|
|
||||||
|
#if CONFIG_LOG_DEFAULT_LEVEL > 3 || (ARDUINO_ARCH_ESP32 && CORE_DEBUG_LEVEL >= 4)
|
||||||
|
char* pHex = NimBLEUtils::buildHexData(nullptr, m_payload, m_payloadLength);
|
||||||
|
NIMBLE_LOGD(LOG_TAG,"payload: %s", pHex);
|
||||||
|
free(pHex);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (fields.uuids16 != NULL) {
|
||||||
|
for (int i = 0; i < fields.num_uuids16; i++) {
|
||||||
|
setServiceUUID(NimBLEUUID(fields.uuids16[i].value));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fields->uuids32 != NULL) {
|
if (fields.uuids32 != NULL) {
|
||||||
for (i = 0; i < fields->num_uuids32; i++) {
|
for (int i = 0; i < fields.num_uuids32; i++) {
|
||||||
setServiceUUID(NimBLEUUID(fields->uuids32[i].value));
|
setServiceUUID(NimBLEUUID(fields.uuids32[i].value));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fields->uuids128 != NULL) {
|
if (fields.uuids128 != NULL) {
|
||||||
for (i = 0; i < fields->num_uuids128; i++) {
|
for (int i = 0; i < fields.num_uuids128; i++) {
|
||||||
setServiceUUID(NimBLEUUID(&fields->uuids128[i]));
|
setServiceUUID(NimBLEUUID(&fields.uuids128[i]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fields->name != NULL) {
|
if (fields.name != NULL) {
|
||||||
setName(std::string(reinterpret_cast<char*>(fields->name), fields->name_len));
|
setName(std::string(reinterpret_cast<char*>(fields.name), fields.name_len));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fields->tx_pwr_lvl_is_present) {
|
if (fields.tx_pwr_lvl_is_present) {
|
||||||
setTXPower(fields->tx_pwr_lvl);
|
setTXPower(fields.tx_pwr_lvl);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fields->svc_data_uuid16 != NULL) {
|
if (fields.svc_data_uuid16 != NULL ||
|
||||||
|
fields.svc_data_uuid32 != NULL ||
|
||||||
|
fields.svc_data_uuid128 != NULL)
|
||||||
|
{
|
||||||
|
ble_hs_adv_field *field;
|
||||||
|
uint8_t *data = payload;
|
||||||
|
while(length > 1) {
|
||||||
|
field = (ble_hs_adv_field*)data;
|
||||||
|
|
||||||
u8p = fields->svc_data_uuid16;
|
if(field->length > length) {
|
||||||
length = fields->svc_data_uuid16_len;
|
break;
|
||||||
|
|
||||||
if (length < 2) {
|
|
||||||
NIMBLE_LOGE(LOG_TAG,"Length too small for ESP_BLE_AD_TYPE_SERVICE_DATA");
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
uint16_t uuid = *(uint16_t*)u8p;
|
|
||||||
setServiceDataUUID(NimBLEUUID(uuid));
|
|
||||||
if (length > 2) {
|
|
||||||
setServiceData(std::string(reinterpret_cast<char*>(u8p + 2), length - 2));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fields->svc_data_uuid32 != NULL) {
|
if(field->type == BLE_HS_ADV_TYPE_SVC_DATA_UUID16) {
|
||||||
|
if(field->length > 2) {
|
||||||
u8p = fields->svc_data_uuid16;
|
uint16_t uuid;
|
||||||
length = fields->svc_data_uuid16_len;
|
memcpy(&uuid, field->value, 2);
|
||||||
|
setServiceData(NimBLEUUID(uuid), std::string(reinterpret_cast<char*>(field->value + 2), field->length - 3));
|
||||||
if (length < 4) {
|
|
||||||
NIMBLE_LOGE(LOG_TAG,"Length too small for ESP_BLE_AD_TYPE_32SERVICE_DATA");
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t uuid = *(uint32_t*) u8p;
|
|
||||||
setServiceDataUUID(NimBLEUUID(uuid));
|
|
||||||
if (length > 4) {
|
|
||||||
setServiceData(std::string(reinterpret_cast<char*>(u8p + 4), length - 4));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fields->svc_data_uuid128 != NULL) {
|
if(field->type == BLE_HS_ADV_TYPE_SVC_DATA_UUID32) {
|
||||||
|
if(field->length > 4) {
|
||||||
u8p = fields->svc_data_uuid16;
|
uint32_t uuid;
|
||||||
length = fields->svc_data_uuid16_len;
|
memcpy(&uuid, field->value, 4);
|
||||||
|
setServiceData(NimBLEUUID(uuid), std::string(reinterpret_cast<char*>(field->value + 4), field->length - 5));
|
||||||
if (length < 16) {
|
|
||||||
NIMBLE_LOGE(LOG_TAG,"Length too small for ESP_BLE_AD_TYPE_128SERVICE_DATA");
|
|
||||||
}
|
|
||||||
|
|
||||||
setServiceDataUUID(NimBLEUUID(u8p, (size_t)16, false));
|
|
||||||
if (length > 16) {
|
|
||||||
setServiceData(std::string(reinterpret_cast<char*>(u8p + 16), length - 16));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fields->appearance_is_present) {
|
if(field->type == BLE_HS_ADV_TYPE_SVC_DATA_UUID128) {
|
||||||
NIMBLE_LOGD(LOG_TAG, " appearance=0x%04x", fields->appearance);
|
if(field->length > 16) {
|
||||||
setAppearance(fields->appearance);
|
NimBLEUUID uuid(field->value, (size_t)16, false);
|
||||||
|
setServiceData(uuid, std::string(reinterpret_cast<char*>(field->value + 16), field->length - 17));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
length -= 1 + field->length;
|
||||||
|
data += 1 + field->length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fields.appearance_is_present) {
|
||||||
|
setAppearance(fields.appearance);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fields.mfg_data != NULL) {
|
||||||
|
setManufacturerData(std::string(reinterpret_cast<char*>(fields.mfg_data), fields.mfg_data_len));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: create storage and fucntions for these parameters
|
/* TODO: create storage and fucntions for these parameters
|
||||||
if (fields->public_tgt_addr != NULL) {
|
if (fields.public_tgt_addr != NULL) {
|
||||||
NIMBLE_LOGD(LOG_TAG, " public_tgt_addr=");
|
NIMBLE_LOGD(LOG_TAG, " public_tgt_addr=");
|
||||||
u8p = fields->public_tgt_addr;
|
u8p = fields.public_tgt_addr;
|
||||||
for (i = 0; i < fields->num_public_tgt_addrs; i++) {
|
for (i = 0; i < fields.num_public_tgt_addrs; i++) {
|
||||||
NIMBLE_LOGD(LOG_TAG, "public_tgt_addr=%s ", addr_str(u8p));
|
NIMBLE_LOGD(LOG_TAG, "public_tgt_addr=%s ", addr_str(u8p));
|
||||||
u8p += BLE_HS_ADV_PUBLIC_TGT_ADDR_ENTRY_LEN;
|
u8p += BLE_HS_ADV_PUBLIC_TGT_ADDR_ENTRY_LEN;
|
||||||
}
|
}
|
||||||
NIMBLE_LOGD(LOG_TAG, "\n");
|
NIMBLE_LOGD(LOG_TAG, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fields->slave_itvl_range != NULL) {
|
if (fields.slave_itvl_range != NULL) {
|
||||||
NIMBLE_LOGD(LOG_TAG, " slave_itvl_range=");
|
NIMBLE_LOGD(LOG_TAG, " slave_itvl_range=");
|
||||||
print_bytes(fields->slave_itvl_range, BLE_HS_ADV_SLAVE_ITVL_RANGE_LEN);
|
print_bytes(fields.slave_itvl_range, BLE_HS_ADV_SLAVE_ITVL_RANGE_LEN);
|
||||||
NIMBLE_LOGD(LOG_TAG, "\n");
|
NIMBLE_LOGD(LOG_TAG, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fields->adv_itvl_is_present) {
|
if (fields.adv_itvl_is_present) {
|
||||||
NIMBLE_LOGD(LOG_TAG, " adv_itvl=0x%04x\n", fields->adv_itvl);
|
NIMBLE_LOGD(LOG_TAG, " adv_itvl=0x%04x\n", fields.adv_itvl);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fields->uri != NULL) {
|
if (fields.uri != NULL) {
|
||||||
NIMBLE_LOGD(LOG_TAG, " uri=");
|
NIMBLE_LOGD(LOG_TAG, " uri=");
|
||||||
print_bytes(fields->uri, fields->uri_len);
|
print_bytes(fields.uri, fields.uri_len);
|
||||||
NIMBLE_LOGD(LOG_TAG, "\n");
|
NIMBLE_LOGD(LOG_TAG, "\n");
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
if (fields->mfg_data != NULL) {
|
|
||||||
setManufacturerData(std::string(reinterpret_cast<char*>(fields->mfg_data), fields->mfg_data_len));
|
|
||||||
}
|
|
||||||
} //parseAdvertisement
|
} //parseAdvertisement
|
||||||
|
|
||||||
|
|
||||||
|
@ -394,7 +433,6 @@ void NimBLEAdvertisedDevice::setAdvType(uint8_t advType) {
|
||||||
void NimBLEAdvertisedDevice::setAppearance(uint16_t appearance) {
|
void NimBLEAdvertisedDevice::setAppearance(uint16_t appearance) {
|
||||||
m_appearance = appearance;
|
m_appearance = appearance;
|
||||||
m_haveAppearance = true;
|
m_haveAppearance = true;
|
||||||
NIMBLE_LOGD(LOG_TAG,"- appearance: %d", m_appearance);
|
|
||||||
} // setAppearance
|
} // setAppearance
|
||||||
|
|
||||||
|
|
||||||
|
@ -405,10 +443,6 @@ void NimBLEAdvertisedDevice::setAppearance(uint16_t appearance) {
|
||||||
void NimBLEAdvertisedDevice::setManufacturerData(std::string manufacturerData) {
|
void NimBLEAdvertisedDevice::setManufacturerData(std::string manufacturerData) {
|
||||||
m_manufacturerData = manufacturerData;
|
m_manufacturerData = manufacturerData;
|
||||||
m_haveManufacturerData = true;
|
m_haveManufacturerData = true;
|
||||||
|
|
||||||
char* pHex = NimBLEUtils::buildHexData(nullptr, (uint8_t*) m_manufacturerData.data(), (uint8_t) m_manufacturerData.length());
|
|
||||||
NIMBLE_LOGD(LOG_TAG,"- manufacturer data: %s", pHex);
|
|
||||||
free(pHex);
|
|
||||||
} // setManufacturerData
|
} // setManufacturerData
|
||||||
|
|
||||||
|
|
||||||
|
@ -419,7 +453,6 @@ void NimBLEAdvertisedDevice::setManufacturerData(std::string manufacturerData) {
|
||||||
void NimBLEAdvertisedDevice::setName(std::string name) {
|
void NimBLEAdvertisedDevice::setName(std::string name) {
|
||||||
m_name = name;
|
m_name = name;
|
||||||
m_haveName = true;
|
m_haveName = true;
|
||||||
NIMBLE_LOGD(LOG_TAG,"- setName(): name: %s", m_name.c_str());
|
|
||||||
} // setName
|
} // setName
|
||||||
|
|
||||||
|
|
||||||
|
@ -430,19 +463,9 @@ void NimBLEAdvertisedDevice::setName(std::string name) {
|
||||||
void NimBLEAdvertisedDevice::setRSSI(int rssi) {
|
void NimBLEAdvertisedDevice::setRSSI(int rssi) {
|
||||||
m_rssi = rssi;
|
m_rssi = rssi;
|
||||||
m_haveRSSI = true;
|
m_haveRSSI = true;
|
||||||
NIMBLE_LOGD(LOG_TAG,"- setRSSI(): rssi: %d", m_rssi);
|
|
||||||
} // setRSSI
|
} // setRSSI
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Set the Scan that created this advertised device.
|
|
||||||
* @param [in] pScan The Scan that created this advertised device.
|
|
||||||
*/
|
|
||||||
void NimBLEAdvertisedDevice::setScan(NimBLEScan* pScan) {
|
|
||||||
m_pScan = pScan;
|
|
||||||
} // setScan
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set the Service UUID for this device.
|
* @brief Set the Service UUID for this device.
|
||||||
* @param [in] serviceUUID The discovered serviceUUID
|
* @param [in] serviceUUID The discovered serviceUUID
|
||||||
|
@ -466,30 +489,26 @@ void NimBLEAdvertisedDevice::setServiceUUID(NimBLEUUID serviceUUID) {
|
||||||
}
|
}
|
||||||
m_serviceUUIDs.push_back(serviceUUID);
|
m_serviceUUIDs.push_back(serviceUUID);
|
||||||
m_haveServiceUUID = true;
|
m_haveServiceUUID = true;
|
||||||
NIMBLE_LOGD(LOG_TAG,"- addServiceUUID(): serviceUUID: %s", serviceUUID.toString().c_str());
|
|
||||||
} // setServiceUUID
|
} // setServiceUUID
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set the ServiceData value.
|
* @brief Set the ServiceData value.
|
||||||
* @param [in] data ServiceData value.
|
* @param [in] uuid The UUID that the service data belongs to.
|
||||||
|
* @param [in] data The service data.
|
||||||
*/
|
*/
|
||||||
void NimBLEAdvertisedDevice::setServiceData(std::string serviceData) {
|
void NimBLEAdvertisedDevice::setServiceData(NimBLEUUID uuid, std::string data) {
|
||||||
m_haveServiceData = true; // Set the flag that indicates we have service data.
|
m_haveServiceData = true;
|
||||||
m_serviceData = serviceData; // Save the service data that we received.
|
for(auto &it : m_serviceDataVec) {
|
||||||
|
if(it.first == uuid) {
|
||||||
|
it.second = data;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_serviceDataVec.push_back({uuid, data});
|
||||||
} //setServiceData
|
} //setServiceData
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Set the ServiceDataUUID value.
|
|
||||||
* @param [in] data ServiceDataUUID value.
|
|
||||||
*/
|
|
||||||
void NimBLEAdvertisedDevice::setServiceDataUUID(NimBLEUUID uuid) {
|
|
||||||
m_haveServiceData = true; // Set the flag that indicates we have service data.
|
|
||||||
m_serviceDataUUID = uuid;
|
|
||||||
} // setServiceDataUUID
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set the power level for this device.
|
* @brief Set the power level for this device.
|
||||||
* @param [in] txPower The discovered power level.
|
* @param [in] txPower The discovered power level.
|
||||||
|
@ -497,7 +516,6 @@ void NimBLEAdvertisedDevice::setServiceDataUUID(NimBLEUUID uuid) {
|
||||||
void NimBLEAdvertisedDevice::setTXPower(int8_t txPower) {
|
void NimBLEAdvertisedDevice::setTXPower(int8_t txPower) {
|
||||||
m_txPower = txPower;
|
m_txPower = txPower;
|
||||||
m_haveTXPower = true;
|
m_haveTXPower = true;
|
||||||
NIMBLE_LOGD(LOG_TAG,"- txPower: %d", m_txPower);
|
|
||||||
} // setTXPower
|
} // setTXPower
|
||||||
|
|
||||||
|
|
||||||
|
@ -533,7 +551,15 @@ std::string NimBLEAdvertisedDevice::toString() {
|
||||||
res += val;
|
res += val;
|
||||||
}
|
}
|
||||||
|
|
||||||
res += ", advType: " + std::string(NimBLEUtils::advTypeToString(m_advType));
|
if(haveServiceData()) {
|
||||||
|
size_t count = getServiceDataCount();
|
||||||
|
res += "\nService Data:";
|
||||||
|
for(size_t i = 0; i < count; i++) {
|
||||||
|
res += "\nUUID: " + std::string(getServiceDataUUID(i));
|
||||||
|
res += ", Data: " + getServiceData(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
res += "\nadvType: " + std::string(NimBLEUtils::advTypeToString(m_advType));
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
|
@ -593,16 +619,6 @@ size_t NimBLEAdvertisedDevice::getPayloadLength() {
|
||||||
} // getPayloadLength
|
} // getPayloadLength
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Set the advertisment payload data.
|
|
||||||
* @param [in] payload A pointer to the device payload data.
|
|
||||||
* @param [in] length The length of the payload data in bytes.
|
|
||||||
*/
|
|
||||||
void NimBLEAdvertisedDevice::setAdvertisementResult(uint8_t* payload, uint8_t length){
|
|
||||||
m_payload = payload;
|
|
||||||
m_payloadLength = length;
|
|
||||||
} // setAdvertisementResult
|
|
||||||
|
|
||||||
#endif // #if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL)
|
#endif // #if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL)
|
||||||
#endif /* CONFIG_BT_ENABLED */
|
#endif /* CONFIG_BT_ENABLED */
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,7 @@ public:
|
||||||
uint16_t getAppearance();
|
uint16_t getAppearance();
|
||||||
std::string getManufacturerData();
|
std::string getManufacturerData();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief A template to convert the service data to <type\>.
|
* @brief A template to convert the service data to <type\>.
|
||||||
* @tparam T The type to convert the data to.
|
* @tparam T The type to convert the data to.
|
||||||
* @param [in] skipSizeCheck If true it will skip checking if the data size is less than <tt>sizeof(<type\>)</tt>.
|
* @param [in] skipSizeCheck If true it will skip checking if the data size is less than <tt>sizeof(<type\>)</tt>.
|
||||||
|
@ -65,26 +65,47 @@ public:
|
||||||
std::string getName();
|
std::string getName();
|
||||||
int getRSSI();
|
int getRSSI();
|
||||||
NimBLEScan* getScan();
|
NimBLEScan* getScan();
|
||||||
std::string getServiceData();
|
size_t getServiceDataCount();
|
||||||
|
std::string getServiceData(uint8_t index = 0);
|
||||||
|
std::string getServiceData(const NimBLEUUID &uuid) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @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.
|
||||||
|
* @param [in] index The vector index of the service data requested.
|
||||||
* @param [in] skipSizeCheck If true it will skip checking if the data size is less than <tt>sizeof(<type\>)</tt>.
|
* @param [in] skipSizeCheck If true it will skip checking if the data size is less than <tt>sizeof(<type\>)</tt>.
|
||||||
* @return The data converted to <type\> or NULL if skipSizeCheck is false and the data is
|
* @return The data converted to <type\> or NULL if skipSizeCheck is false and the data is
|
||||||
* less than <tt>sizeof(<type\>)</tt>.
|
* less than <tt>sizeof(<type\>)</tt>.
|
||||||
* @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(bool skipSizeCheck = false) {
|
T getServiceData(uint8_t index = 0, bool skipSizeCheck = false) {
|
||||||
std::string data = getServiceData();
|
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();
|
||||||
return *((T *)pData);
|
return *((T *)pData);
|
||||||
}
|
}
|
||||||
|
|
||||||
NimBLEUUID getServiceDataUUID();
|
/**
|
||||||
NimBLEUUID getServiceUUID();
|
* @brief A template to convert the service data to <tt><type\></tt>.
|
||||||
|
* @tparam T The type to convert the data to.
|
||||||
|
* @param [in] uuid The uuid of the service data requested.
|
||||||
|
* @param [in] skipSizeCheck If true it will skip checking if the data size is less than <tt>sizeof(<type\>)</tt>.
|
||||||
|
* @return The data converted to <type\> or NULL if skipSizeCheck is false and the data is
|
||||||
|
* 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) {
|
||||||
|
std::string data = getServiceData(uuid);
|
||||||
|
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);
|
||||||
|
size_t getServiceUUIDCount();
|
||||||
int8_t getTXPower();
|
int8_t getTXPower();
|
||||||
uint8_t* getPayload();
|
uint8_t* getPayload();
|
||||||
size_t getPayloadLength();
|
size_t getPayloadLength();
|
||||||
|
@ -93,7 +114,7 @@ public:
|
||||||
void setAddressType(uint8_t type);
|
void setAddressType(uint8_t type);
|
||||||
|
|
||||||
|
|
||||||
bool isAdvertisingService(const NimBLEUUID &uuid);
|
bool isAdvertisingService(const NimBLEUUID &uuid) const;
|
||||||
bool haveAppearance();
|
bool haveAppearance();
|
||||||
bool haveManufacturerData();
|
bool haveManufacturerData();
|
||||||
bool haveName();
|
bool haveName();
|
||||||
|
@ -107,17 +128,14 @@ public:
|
||||||
private:
|
private:
|
||||||
friend class NimBLEScan;
|
friend class NimBLEScan;
|
||||||
|
|
||||||
void parseAdvertisement(ble_hs_adv_fields *fields);
|
void parseAdvertisement(uint8_t* payload, uint8_t length);
|
||||||
void setAddress(NimBLEAddress address);
|
void setAddress(NimBLEAddress address);
|
||||||
void setAdvType(uint8_t advType);
|
void setAdvType(uint8_t advType);
|
||||||
void setAdvertisementResult(uint8_t* payload, uint8_t length);
|
|
||||||
void setAppearance(uint16_t appearance);
|
void setAppearance(uint16_t appearance);
|
||||||
void setManufacturerData(std::string manufacturerData);
|
void setManufacturerData(std::string manufacturerData);
|
||||||
void setName(std::string name);
|
void setName(std::string name);
|
||||||
void setRSSI(int rssi);
|
void setRSSI(int rssi);
|
||||||
void setScan(NimBLEScan* pScan);
|
void setServiceData(NimBLEUUID serviceUUID, std::string data);
|
||||||
void setServiceData(std::string data);
|
|
||||||
void setServiceDataUUID(NimBLEUUID uuid);
|
|
||||||
void setServiceUUID(const char* serviceUUID);
|
void setServiceUUID(const char* serviceUUID);
|
||||||
void setServiceUUID(NimBLEUUID serviceUUID);
|
void setServiceUUID(NimBLEUUID serviceUUID);
|
||||||
void setTXPower(int8_t txPower);
|
void setTXPower(int8_t txPower);
|
||||||
|
@ -134,14 +152,10 @@ private:
|
||||||
NimBLEAddress m_address = NimBLEAddress("");
|
NimBLEAddress m_address = NimBLEAddress("");
|
||||||
uint8_t m_advType;
|
uint8_t m_advType;
|
||||||
uint16_t m_appearance;
|
uint16_t m_appearance;
|
||||||
int m_deviceType;
|
|
||||||
std::string m_manufacturerData;
|
std::string m_manufacturerData;
|
||||||
std::string m_name;
|
std::string m_name;
|
||||||
NimBLEScan* m_pScan;
|
|
||||||
int m_rssi;
|
int m_rssi;
|
||||||
int8_t m_txPower;
|
int8_t m_txPower;
|
||||||
std::string m_serviceData;
|
|
||||||
NimBLEUUID m_serviceDataUUID;
|
|
||||||
uint8_t* m_payload;
|
uint8_t* m_payload;
|
||||||
size_t m_payloadLength;
|
size_t m_payloadLength;
|
||||||
uint8_t m_addressType;
|
uint8_t m_addressType;
|
||||||
|
@ -149,6 +163,7 @@ private:
|
||||||
bool m_callbackSent;
|
bool m_callbackSent;
|
||||||
|
|
||||||
std::vector<NimBLEUUID> m_serviceUUIDs;
|
std::vector<NimBLEUUID> m_serviceUUIDs;
|
||||||
|
std::vector<std::pair<NimBLEUUID, std::string>>m_serviceDataVec;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -167,7 +182,6 @@ public:
|
||||||
* As we are scanning, we will find new devices. When found, this call back is invoked with a reference to the
|
* As we are scanning, we will find new devices. When found, this call back is invoked with a reference to the
|
||||||
* device that was found. During any individual scan, a device will only be detected one time.
|
* device that was found. During any individual scan, a device will only be detected one time.
|
||||||
*/
|
*/
|
||||||
//virtual void onResult(NimBLEAdvertisedDevice advertisedDevice) = 0;
|
|
||||||
virtual void onResult(NimBLEAdvertisedDevice* advertisedDevice) = 0;
|
virtual void onResult(NimBLEAdvertisedDevice* advertisedDevice) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -52,8 +52,6 @@ NimBLEScan::NimBLEScan() {
|
||||||
/*STATIC*/int NimBLEScan::handleGapEvent(ble_gap_event* event, void* arg) {
|
/*STATIC*/int NimBLEScan::handleGapEvent(ble_gap_event* event, void* arg) {
|
||||||
|
|
||||||
NimBLEScan* pScan = (NimBLEScan*)arg;
|
NimBLEScan* pScan = (NimBLEScan*)arg;
|
||||||
struct ble_hs_adv_fields fields;
|
|
||||||
int rc = 0;
|
|
||||||
|
|
||||||
switch(event->type) {
|
switch(event->type) {
|
||||||
|
|
||||||
|
@ -63,13 +61,6 @@ NimBLEScan::NimBLEScan() {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = ble_hs_adv_parse_fields(&fields, event->disc.data,
|
|
||||||
event->disc.length_data);
|
|
||||||
if (rc != 0) {
|
|
||||||
NIMBLE_LOGE(LOG_TAG, "Gap Event Parse ERROR.");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
NimBLEAddress advertisedAddress(event->disc.addr);
|
NimBLEAddress advertisedAddress(event->disc.addr);
|
||||||
|
|
||||||
// Examine our list of ignored addresses and stop processing if we don't want to see it or are already connected
|
// Examine our list of ignored addresses and stop processing if we don't want to see it or are already connected
|
||||||
|
@ -102,9 +93,9 @@ NimBLEScan::NimBLEScan() {
|
||||||
NIMBLE_LOGI(LOG_TAG, "UPDATING PREVIOUSLY FOUND DEVICE: %s", advertisedAddress.toString().c_str());
|
NIMBLE_LOGI(LOG_TAG, "UPDATING PREVIOUSLY FOUND DEVICE: %s", advertisedAddress.toString().c_str());
|
||||||
}
|
}
|
||||||
advertisedDevice->setRSSI(event->disc.rssi);
|
advertisedDevice->setRSSI(event->disc.rssi);
|
||||||
advertisedDevice->parseAdvertisement(&fields);
|
if(event->disc.length_data > 0) {
|
||||||
advertisedDevice->setScan(pScan);
|
advertisedDevice->parseAdvertisement(event->disc.data, event->disc.length_data);
|
||||||
advertisedDevice->setAdvertisementResult(event->disc.data, event->disc.length_data);
|
}
|
||||||
advertisedDevice->m_timestamp = time(nullptr);
|
advertisedDevice->m_timestamp = time(nullptr);
|
||||||
|
|
||||||
if (pScan->m_pAdvertisedDeviceCallbacks) {
|
if (pScan->m_pAdvertisedDeviceCallbacks) {
|
||||||
|
|
Loading…
Reference in a new issue