diff --git a/src/NimBLEAdvertisementData.cpp b/src/NimBLEAdvertisementData.cpp index b0f28ff..e9662c5 100644 --- a/src/NimBLEAdvertisementData.cpp +++ b/src/NimBLEAdvertisementData.cpp @@ -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); @@ -201,20 +191,10 @@ 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); @@ -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 * @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& 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,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); @@ -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 = uuid.getType(); + if (type == 0) { + return false; } if (length == 0) { diff --git a/src/NimBLEExtAdvertising.cpp b/src/NimBLEExtAdvertising.cpp index aa016cc..d954118 100644 --- a/src/NimBLEExtAdvertising.cpp +++ b/src/NimBLEExtAdvertising.cpp @@ -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); @@ -743,20 +733,10 @@ 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); @@ -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,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)) { @@ -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 = uuid.getType(); + if (type == 0) { + return false; } if (length == 0) { diff --git a/src/NimBLEUUID.cpp b/src/NimBLEUUID.cpp index c947648..0e10d33 100644 --- a/src/NimBLEUUID.cpp +++ b/src/NimBLEUUID.cpp @@ -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 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. * diff --git a/src/NimBLEUUID.h b/src/NimBLEUUID.h index 32f625c..efaf739 100644 --- a/src/NimBLEUUID.h +++ b/src/NimBLEUUID.h @@ -34,6 +34,7 @@ # include # include +# include /** * @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 payload) const; bool equals(const NimBLEUUID& uuid) const; std::string toString() const; static NimBLEUUID fromString(const std::string& uuid); diff --git a/src/NimBLEUtils.cpp b/src/NimBLEUtils.cpp index f447ff0..7276271 100644 --- a/src/NimBLEUtils.cpp +++ b/src/NimBLEUtils.cpp @@ -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 diff --git a/src/NimBLEUtils.h b/src/NimBLEUtils.h index e56f568..a9b8020 100644 --- a/src/NimBLEUtils.h +++ b/src/NimBLEUtils.h @@ -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