Skip to content

Commit

Permalink
Refactor NimBLEAdvertisementData/NimBLEExtAdvertising
Browse files Browse the repository at this point in the history
* NimBLEUtils added method to get UUID type from size.
* NimBLEUtils added method to get service data UUID type from size.
* NimBLEUUID added method to get location within payload.
* NimBLEUUID added method as wrapper for NimBLEUtils::getType().
  • Loading branch information
thekurtovic committed Dec 27, 2024
1 parent 015217c commit c853340
Show file tree
Hide file tree
Showing 6 changed files with 102 additions and 127 deletions.
81 changes: 17 additions & 64 deletions src/NimBLEAdvertisementData.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -146,20 +146,10 @@ 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:
return false;
uint8_t bytes = serviceUUID.bitSize() >> 3;
uint8_t type = serviceUUID.getType();
if (type == 0) {
return false;
}

int dataLoc = getDataLocation(type);
Expand Down Expand Up @@ -201,35 +191,18 @@ 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:
return false;
uint8_t bytes = serviceUUID.bitSize() >> 3;
uint8_t type = serviceUUID.getType();
if (type == 0) {
return false;
}

int dataLoc = getDataLocation(type);
if (dataLoc == -1) {
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;
}
Expand Down Expand Up @@ -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];

Expand All @@ -429,19 +402,9 @@ 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:
return false;
data[1] = NimBLEUtils::getUUIDType(size, complete);
if (data[1] == 0) {
return false;
}

return addData(data, length);
Expand All @@ -456,26 +419,16 @@ 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:
return false;
uint8_t type = NimBLEUtils::getServiceType(uuidBytes);
if (type == 0) {
return false;
}

if (length == 0) {
Expand Down
79 changes: 16 additions & 63 deletions src/NimBLEExtAdvertising.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -688,20 +688,10 @@ 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:
return false;
uint8_t bytes = serviceUUID.bitSize() >> 3;
uint8_t type = serviceUUID.getType();
if (type == 0) {
return false;
}

int dataLoc = getDataLocation(type);
Expand Down Expand Up @@ -743,35 +733,18 @@ 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:
return false;
uint8_t bytes = serviceUUID.bitSize() >> 3;
uint8_t type = serviceUUID.getType();
if (type == 0) {
return false;
}

int dataLoc = getDataLocation(type);
if (dataLoc == -1) {
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;
}
Expand Down Expand Up @@ -866,19 +839,9 @@ 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:
return false;
header[1] = NimBLEUtils::getUUIDType(size, complete);
if (header[1] == 0) {
return false;
}

if (addData(header, 2)) {
Expand Down Expand Up @@ -913,26 +876,16 @@ 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:
return false;
uint8_t type = NimBLEUtils::getServiceType(uuidBytes);
if (type == 0) {
return false;
}

if (length == 0) {
Expand Down
26 changes: 26 additions & 0 deletions src/NimBLEUUID.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
Expand Down
3 changes: 3 additions & 0 deletions src/NimBLEUUID.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@

# include <string>
# include <cstring>
# include <vector>

/**
* @brief A model of a %BLE UUID.
Expand All @@ -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);
Expand Down
38 changes: 38 additions & 0 deletions src/NimBLEUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -572,4 +572,42 @@ 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

/**
* @brief Get the service data UUID type based on size.
* @param [in] size The size of the UUID in bytes.
* @return BLE_HS_ADV_TYPE_SVC_DATA_UUID16/32/128 for valid input size, else 0.
*/
uint8_t NimBLEUtils::getServiceType(uint8_t size) {
switch (size) {
case 2:
return BLE_HS_ADV_TYPE_SVC_DATA_UUID16;
case 4:
return BLE_HS_ADV_TYPE_SVC_DATA_UUID32;
case 16:
return BLE_HS_ADV_TYPE_SVC_DATA_UUID128;
default:
return 0;
}
} // getServiceType

#endif // CONFIG_BT_ENABLED
2 changes: 2 additions & 0 deletions src/NimBLEUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ 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);
static uint8_t getServiceType(uint8_t size);
};

#endif // CONFIG_BT_ENABLED
Expand Down

0 comments on commit c853340

Please sign in to comment.