Refactor NimBLEAdvertisementData/NimBLEExtAdvertising

* NimBLEUtils added method to get UUID type from size.
* NimBLEUUID added method to get location within payload.
* NimBLEUUID added method as wrapper for NimBLEUtils::getType().
This commit is contained in:
thekurtovic 2024-12-21 18:05:13 -05:00
parent 015217c764
commit 1d504bf6ff
6 changed files with 83 additions and 127 deletions

View file

@ -146,19 +146,9 @@ bool NimBLEAdvertisementData::setPreferredParams(uint16_t minInterval, uint16_t
* @param [in] serviceUUID The UUID of the service to expose.
*/
bool NimBLEAdvertisementData::addServiceUUID(const NimBLEUUID& serviceUUID) {
uint8_t bytes = serviceUUID.bitSize() / 8;
int type;
switch (bytes) {
case 2:
type = BLE_HS_ADV_TYPE_COMP_UUIDS16;
break;
case 4:
type = BLE_HS_ADV_TYPE_COMP_UUIDS32;
break;
case 16:
type = BLE_HS_ADV_TYPE_COMP_UUIDS128;
break;
default:
uint8_t bytes = serviceUUID.bitSize() >> 3;
uint8_t type = serviceUUID.getType();
if (type == 0) {
return false;
}
@ -201,19 +191,9 @@ bool NimBLEAdvertisementData::addServiceUUID(const char* serviceUUID) {
* @return True if successful or uuid not found, false if uuid error or data could not be reset.
*/
bool NimBLEAdvertisementData::removeServiceUUID(const NimBLEUUID& serviceUUID) {
uint8_t bytes = serviceUUID.bitSize() / 8;
int type;
switch (bytes) {
case 2:
type = BLE_HS_ADV_TYPE_COMP_UUIDS16;
break;
case 4:
type = BLE_HS_ADV_TYPE_COMP_UUIDS32;
break;
case 16:
type = BLE_HS_ADV_TYPE_COMP_UUIDS128;
break;
default:
uint8_t bytes = serviceUUID.bitSize() >> 3;
uint8_t type = serviceUUID.getType();
if (type == 0) {
return false;
}
@ -222,14 +202,7 @@ bool NimBLEAdvertisementData::removeServiceUUID(const NimBLEUUID& serviceUUID) {
return true;
}
int uuidLoc = -1;
for (size_t i = dataLoc + 2; i < m_payload.size(); i += bytes) {
if (memcmp(&m_payload[i], serviceUUID.getValue(), bytes) == 0) {
uuidLoc = i;
break;
}
}
int uuidLoc = serviceUUID.getLoc(dataLoc, m_payload);
if (uuidLoc == -1) {
return true;
}
@ -409,7 +382,7 @@ bool NimBLEAdvertisementData::setPartialServices32(const std::vector<NimBLEUUID>
* @details The number of services will be truncated if the total length exceeds 31 bytes.
*/
bool NimBLEAdvertisementData::setServices(bool complete, uint8_t size, const std::vector<NimBLEUUID>& uuids) {
uint8_t bytes = size / 8;
uint8_t bytes = size >> 3;
uint8_t length = 2; // start with 2 for length + type bytes
uint8_t data[31];
@ -429,18 +402,8 @@ bool NimBLEAdvertisementData::setServices(bool complete, uint8_t size, const std
}
data[0] = length - 1; // don't count the length byte as part of the AD length
switch (size) {
case 16:
data[1] = (complete ? BLE_HS_ADV_TYPE_COMP_UUIDS16 : BLE_HS_ADV_TYPE_INCOMP_UUIDS16);
break;
case 32:
data[1] = (complete ? BLE_HS_ADV_TYPE_COMP_UUIDS32 : BLE_HS_ADV_TYPE_INCOMP_UUIDS32);
break;
case 128:
data[1] = (complete ? BLE_HS_ADV_TYPE_COMP_UUIDS128 : BLE_HS_ADV_TYPE_INCOMP_UUIDS128);
break;
default:
data[1] = NimBLEUtils::getUUIDType(size, complete);
if (data[1] == 0) {
return false;
}
@ -456,25 +419,15 @@ bool NimBLEAdvertisementData::setServices(bool complete, uint8_t size, const std
* @return True if successful, false if data length is too long or could not be set.
*/
bool NimBLEAdvertisementData::setServiceData(const NimBLEUUID& uuid, const uint8_t* data, size_t length) {
uint8_t uuidBytes = uuid.bitSize() / 8;
uint8_t uuidBytes = uuid.bitSize() >> 3;
uint8_t sDataLen = 2 + uuidBytes + length;
if (sDataLen > 31) {
NIMBLE_LOGE(LOG_TAG, "Service Data too long");
return false;
}
uint8_t type;
switch (uuidBytes) {
case 2:
type = BLE_HS_ADV_TYPE_SVC_DATA_UUID16;
break;
case 4:
type = BLE_HS_ADV_TYPE_SVC_DATA_UUID32;
break;
case 16:
type = BLE_HS_ADV_TYPE_SVC_DATA_UUID128;
break;
default:
uint8_t type = uuid.getType();
if (type == 0) {
return false;
}

View file

@ -688,19 +688,9 @@ bool NimBLEExtAdvertisement::setName(const std::string& name, bool isComplete) {
* @param [in] serviceUUID The UUID of the service to expose.
*/
bool NimBLEExtAdvertisement::addServiceUUID(const NimBLEUUID& serviceUUID) {
uint8_t bytes = serviceUUID.bitSize() / 8;
int type;
switch (bytes) {
case 2:
type = BLE_HS_ADV_TYPE_COMP_UUIDS16;
break;
case 4:
type = BLE_HS_ADV_TYPE_COMP_UUIDS32;
break;
case 16:
type = BLE_HS_ADV_TYPE_COMP_UUIDS128;
break;
default:
uint8_t bytes = serviceUUID.bitSize() >> 3;
uint8_t type = serviceUUID.getType();
if (type == 0) {
return false;
}
@ -743,19 +733,9 @@ bool NimBLEExtAdvertisement::addServiceUUID(const char* serviceUUID) {
* @return True if successful or uuid not found, false if uuid error or data could not be reset.
*/
bool NimBLEExtAdvertisement::removeServiceUUID(const NimBLEUUID& serviceUUID) {
uint8_t bytes = serviceUUID.bitSize() / 8;
int type;
switch (bytes) {
case 2:
type = BLE_HS_ADV_TYPE_COMP_UUIDS16;
break;
case 4:
type = BLE_HS_ADV_TYPE_COMP_UUIDS32;
break;
case 16:
type = BLE_HS_ADV_TYPE_COMP_UUIDS128;
break;
default:
uint8_t bytes = serviceUUID.bitSize() >> 3;
uint8_t type = serviceUUID.getType();
if (type == 0) {
return false;
}
@ -764,14 +744,7 @@ bool NimBLEExtAdvertisement::removeServiceUUID(const NimBLEUUID& serviceUUID) {
return true;
}
int uuidLoc = -1;
for (size_t i = dataLoc + 2; i < m_payload.size(); i += bytes) {
if (memcmp(&m_payload[i], serviceUUID.getValue(), bytes) == 0) {
uuidLoc = i;
break;
}
}
int uuidLoc = serviceUUID.getLoc(dataLoc, m_payload);
if (uuidLoc == -1) {
return true;
}
@ -866,18 +839,8 @@ bool NimBLEExtAdvertisement::setServices(bool complete, uint8_t size, const std:
uint8_t header[2];
uint8_t uuidBytes = size / 8;
header[0] = uuidBytes * uuids.size() + 1;
switch (size) {
case 16:
header[1] = complete ? BLE_HS_ADV_TYPE_COMP_UUIDS16 : BLE_HS_ADV_TYPE_INCOMP_UUIDS16;
break;
case 32:
header[1] = complete ? BLE_HS_ADV_TYPE_COMP_UUIDS32 : BLE_HS_ADV_TYPE_INCOMP_UUIDS32;
break;
case 128:
header[1] = complete ? BLE_HS_ADV_TYPE_COMP_UUIDS128 : BLE_HS_ADV_TYPE_INCOMP_UUIDS128;
break;
default:
header[1] = NimBLEUtils::getUUIDType(size, complete);
if (header[1] == 0) {
return false;
}
@ -913,25 +876,15 @@ bool NimBLEExtAdvertisement::setServices(bool complete, uint8_t size, const std:
* @return True if successful, false if data length is too long or could not be set.
*/
bool NimBLEExtAdvertisement::setServiceData(const NimBLEUUID& uuid, const uint8_t* data, size_t length) {
uint8_t uuidBytes = uuid.bitSize() / 8;
uint8_t uuidBytes = uuid.bitSize() >> 3;
uint8_t sDataLen = 2 + uuidBytes + length;
if (m_payload.size() + sDataLen > CONFIG_BT_NIMBLE_MAX_EXT_ADV_DATA_LEN) {
return false;
}
uint8_t type;
switch (uuidBytes) {
case 2:
type = BLE_HS_ADV_TYPE_SVC_DATA_UUID16;
break;
case 4:
type = BLE_HS_ADV_TYPE_SVC_DATA_UUID32;
break;
case 16:
type = BLE_HS_ADV_TYPE_SVC_DATA_UUID128;
break;
default:
uint8_t type = uuid.getType();
if (type == 0) {
return false;
}

View file

@ -172,6 +172,32 @@ const ble_uuid_t* NimBLEUUID::getBase() const {
return &this->m_uuid.u;
} // getBase
/**
* @brief Get the UUID type based on size in bits.
* @return BLE_HS_ADV_TYPE_COMP_UUIDS16/32/128 or BLE_HS_ADV_TYPE_INCOMP_UUIDS16/32/128
* for valid input size, else 0.
*/
uint8_t NimBLEUUID::getType() const {
return NimBLEUtils::getUUIDType(bitSize(), true);
} // getType
/**
* @brief Get the location of the UUID within a payload.
* @param [in] dataLoc The data location.
* @param [in] payload The payload to search through.
* @return >= 0 if found, else -1.
*/
int NimBLEUUID::getLoc(int dataLoc, const std::vector<uint8_t> payload) const {
uint8_t bytes = bitSize() >> 3;
const size_t size = payload.size();
for (size_t i = dataLoc + 2; i < size; i += bytes) {
if (memcmp(&payload[i], getValue(), bytes) == 0) {
return i;
}
}
return -1;
} // getLoc
/**
* @brief Compare a UUID against this UUID.
*

View file

@ -34,6 +34,7 @@
# include <string>
# include <cstring>
# include <vector>
/**
* @brief A model of a %BLE UUID.
@ -55,6 +56,8 @@ class NimBLEUUID {
uint8_t bitSize() const;
const uint8_t* getValue() const;
const ble_uuid_t* getBase() const;
uint8_t getType() const;
int getLoc(int dataLoc, const std::vector<uint8_t> payload) const;
bool equals(const NimBLEUUID& uuid) const;
std::string toString() const;
static NimBLEUUID fromString(const std::string& uuid);

View file

@ -572,4 +572,24 @@ NimBLEAddress NimBLEUtils::generateAddr(bool nrpa) {
return NimBLEAddress{addr};
} // generateAddr
/**
* @brief Get the UUID type based on size.
* @param [in] size The size of the UUID in bits.
* @param [in] complete False if the UUID is truncated, else True.
* @return BLE_HS_ADV_TYPE_COMP_UUIDS16/32/128 or BLE_HS_ADV_TYPE_INCOMP_UUIDS16/32/128
* for valid input size, else 0.
*/
uint8_t NimBLEUtils::getUUIDType(uint8_t size, bool complete) {
switch (size) {
case 16:
return complete ? BLE_HS_ADV_TYPE_COMP_UUIDS16 : BLE_HS_ADV_TYPE_INCOMP_UUIDS16;
case 32:
return complete ? BLE_HS_ADV_TYPE_COMP_UUIDS32 : BLE_HS_ADV_TYPE_INCOMP_UUIDS32;
case 128:
return complete ? BLE_HS_ADV_TYPE_COMP_UUIDS128 : BLE_HS_ADV_TYPE_INCOMP_UUIDS128;
default:
return 0;
}
} // getUUIDType
#endif // CONFIG_BT_ENABLED

View file

@ -53,6 +53,7 @@ class NimBLEUtils {
static NimBLEAddress generateAddr(bool nrpa);
static bool taskWait(const NimBLETaskData& taskData, uint32_t timeout);
static void taskRelease(const NimBLETaskData& taskData, int rc = 0);
static uint8_t getUUIDType(uint8_t size, bool complete = true);
};
#endif // CONFIG_BT_ENABLED