From b290ca9077483d15a29ecc4efff47962697ae4dc Mon Sep 17 00:00:00 2001 From: h2zero Date: Sat, 6 Feb 2021 13:27:12 -0700 Subject: [PATCH] [NimBLEAdvertisementData] Add setServices methods for multiple UUID's Adds: - setPartialServices16 - setPartialServices32 - setCompleteServices16 - setCompleteServices32 Each takes an input parameter of std::vector to allow for advertising multiple services with a simple interface. --- src/NimBLEAdvertising.cpp | 170 ++++++++++++++++++++++---------------- src/NimBLEAdvertising.h | 6 ++ 2 files changed, 103 insertions(+), 73 deletions(-) diff --git a/src/NimBLEAdvertising.cpp b/src/NimBLEAdvertising.cpp index a104804..e74d3e7 100644 --- a/src/NimBLEAdvertising.cpp +++ b/src/NimBLEAdvertising.cpp @@ -646,6 +646,7 @@ int NimBLEAdvertising::handleGapEvent(struct ble_gap_event *event, void *arg) { */ void NimBLEAdvertisementData::addData(const std::string &data) { if ((m_payload.length() + data.length()) > BLE_HS_ADV_MAX_SZ) { + NIMBLE_LOGE(LOG_TAG, "Advertisement data length exceded"); return; } m_payload.append(data); @@ -657,11 +658,8 @@ void NimBLEAdvertisementData::addData(const std::string &data) { * @param [in] data The data to be added to the payload. * @param [in] length The size of data to be added to the payload. */ -void NimBLEAdvertisementData::addData(char * data, size_t length){ - if ((m_payload.length() + length) > BLE_HS_ADV_MAX_SZ) { - return; - } - m_payload.append(data,length); +void NimBLEAdvertisementData::addData(char * data, size_t length) { + addData(std::string(data, length)); } // addData @@ -680,43 +678,6 @@ void NimBLEAdvertisementData::setAppearance(uint16_t appearance) { } // setAppearance -/** - * @brief Set the complete services to advertise. - * @param [in] uuid The UUID of the service. - */ -void NimBLEAdvertisementData::setCompleteServices(const NimBLEUUID &uuid) { - char cdata[2]; - switch (uuid.bitSize()) { - case 16: { - // [Len] [0x02] [LL] [HH] - cdata[0] = 3; - cdata[1] = BLE_HS_ADV_TYPE_COMP_UUIDS16; // 0x03 - addData(std::string(cdata, 2) + std::string((char*) &uuid.getNative()->u16.value, 2)); - break; - } - - case 32: { - // [Len] [0x04] [LL] [LL] [HH] [HH] - cdata[0] = 5; - cdata[1] = BLE_HS_ADV_TYPE_COMP_UUIDS32; // 0x05 - addData(std::string(cdata, 2) + std::string((char*) &uuid.getNative()->u32.value, 4)); - break; - } - - case 128: { - // [Len] [0x04] [0] [1] ... [15] - cdata[0] = 17; - cdata[1] = BLE_HS_ADV_TYPE_COMP_UUIDS128; // 0x07 - addData(std::string(cdata, 2) + std::string((char*) uuid.getNative()->u128.value, 16)); - break; - } - - default: - return; - } -} // setCompleteServices - - /** * @brief Set the advertisement flags. * @param [in] flag The flags to be set in the advertisement. @@ -738,12 +699,10 @@ void NimBLEAdvertisementData::setFlags(uint8_t flag) { * @param [in] data The manufacturer data to advertise. */ void NimBLEAdvertisementData::setManufacturerData(const std::string &data) { - NIMBLE_LOGD("NimBLEAdvertisementData", ">> setManufacturerData"); char cdata[2]; cdata[0] = data.length() + 1; cdata[1] = BLE_HS_ADV_TYPE_MFG_DATA ; // 0xff addData(std::string(cdata, 2) + data); - NIMBLE_LOGD("NimBLEAdvertisementData", "<< setManufacturerData"); } // setManufacturerData @@ -752,50 +711,117 @@ void NimBLEAdvertisementData::setManufacturerData(const std::string &data) { * @param [in] name The name to advertise. */ void NimBLEAdvertisementData::setName(const std::string &name) { - NIMBLE_LOGD("NimBLEAdvertisementData", ">> setName: %s", name.c_str()); char cdata[2]; cdata[0] = name.length() + 1; cdata[1] = BLE_HS_ADV_TYPE_COMP_NAME; // 0x09 addData(std::string(cdata, 2) + name); - NIMBLE_LOGD("NimBLEAdvertisementData", "<< setName"); } // setName /** - * @brief Set the partial services to advertise. - * @param [in] uuid The single service to advertise. + * @brief Set a single service to advertise as a complete list of services. + * @param [in] uuid The service to advertise. + */ +void NimBLEAdvertisementData::setCompleteServices(const NimBLEUUID &uuid) { + setServices(true, uuid.bitSize(), {uuid}); +} // setCompleteServices + + +/** + * @brief Set the complete list of 16 bit services to advertise. + * @param [in] v_uuid A vector of 16 bit UUID's to advertise. + */ +void NimBLEAdvertisementData::setCompleteServices16(const std::vector& v_uuid) { + setServices(true, 16, v_uuid); +} + + +/** + * @brief Set the complete list of 32 bit services to advertise. + * @param [in] v_uuid A vector of 32 bit UUID's to advertise. + */ +void NimBLEAdvertisementData::setCompleteServices32(const std::vector& v_uuid) { + setServices(true, 32, v_uuid); +} + + +/** + * @brief Set a single service to advertise as a partial list of services. + * @param [in] uuid The service to advertise. */ void NimBLEAdvertisementData::setPartialServices(const NimBLEUUID &uuid) { + setServices(false, uuid.bitSize(), {uuid}); +} // setPartialServices + + +/** + * @brief Set the partial list of services to advertise. + * @param [in] v_uuid A vector of 16 bit UUID's to advertise. + */ +void NimBLEAdvertisementData::setPartialServices16(const std::vector& v_uuid) { + setServices(false, 16, v_uuid); +} + + +/** + * @brief Set the partial list of services to advertise. + * @param [in] v_uuid A vector of 32 bit UUID's to advertise. + */ +void NimBLEAdvertisementData::setPartialServices32(const std::vector& v_uuid) { + setServices(false, 32, v_uuid); +} + + +/** + * @brief Utility function to create the list of service UUID's from a vector. + * @param [in] complete If true the vector is the complete set of services. + * @param [in] size The bit size of the UUID's in the vector. (16, 32, or 128). + * @param [in] v_uuid The vector of service UUID's to advertise. + */ +void NimBLEAdvertisementData::setServices(const bool complete, const uint8_t size, + const std::vector &v_uuid) +{ char cdata[2]; - switch (uuid.bitSize()) { - case 16: { - // [Len] [0x02] [LL] [HH] - cdata[0] = 3; - cdata[1] = BLE_HS_ADV_TYPE_INCOMP_UUIDS16; // 0x02 - addData(std::string(cdata, 2) + std::string((char *) &uuid.getNative()->u16.value, 2)); + cdata[0] = (size / 8) * v_uuid.size() + 1; + switch(size) { + case 16: + cdata[1] = complete ? BLE_HS_ADV_TYPE_COMP_UUIDS16 : BLE_HS_ADV_TYPE_INCOMP_UUIDS16; break; - } - - case 32: { - // [Len] [0x04] [LL] [LL] [HH] [HH] - cdata[0] = 5; - cdata[1] = BLE_HS_ADV_TYPE_INCOMP_UUIDS32; // 0x04 - addData(std::string(cdata, 2) + std::string((char *) &uuid.getNative()->u32.value, 4)); + case 32: + cdata[1] = complete ? BLE_HS_ADV_TYPE_COMP_UUIDS32 : BLE_HS_ADV_TYPE_INCOMP_UUIDS32; break; - } - - case 128: { - // [Len] [0x04] [0] [1] ... [15] - cdata[0] = 17; - cdata[1] = BLE_HS_ADV_TYPE_INCOMP_UUIDS128; // 0x06 - addData(std::string(cdata, 2) + std::string((char *) &uuid.getNative()->u128.value, 16)); + case 128: + cdata[1] = complete ? BLE_HS_ADV_TYPE_COMP_UUIDS128 : BLE_HS_ADV_TYPE_INCOMP_UUIDS128; break; - } - default: return; } -} // setPartialServices + + std::string uuids; + + for(auto &it : v_uuid){ + if(it.bitSize() != size) { + NIMBLE_LOGE(LOG_TAG, "Service UUID(%d) invalid", size); + return; + } else { + switch(size) { + case 16: + uuids += std::string((char*)&it.getNative()->u16.value, 2); + break; + case 32: + uuids += std::string((char*)&it.getNative()->u32.value, 4); + break; + case 128: + uuids += std::string((char*)&it.getNative()->u128.value, 16); + break; + default: + return; + } + } + } + + addData(std::string(cdata, 2) + uuids); +} /** @@ -841,12 +867,10 @@ void NimBLEAdvertisementData::setServiceData(const NimBLEUUID &uuid, const std:: * @param [in] name The short name of the device. */ void NimBLEAdvertisementData::setShortName(const std::string &name) { - NIMBLE_LOGD("NimBLEAdvertisementData", ">> setShortName: %s", name.c_str()); char cdata[2]; cdata[0] = name.length() + 1; cdata[1] = BLE_HS_ADV_TYPE_INCOMP_NAME; // 0x08 addData(std::string(cdata, 2) + name); - NIMBLE_LOGD("NimBLEAdvertisementData", "<< setShortName"); } // setShortName diff --git a/src/NimBLEAdvertising.h b/src/NimBLEAdvertising.h index 0d97ecb..82b096f 100644 --- a/src/NimBLEAdvertising.h +++ b/src/NimBLEAdvertising.h @@ -50,10 +50,14 @@ class NimBLEAdvertisementData { public: void setAppearance(uint16_t appearance); void setCompleteServices(const NimBLEUUID &uuid); + void setCompleteServices16(const std::vector &v_uuid); + void setCompleteServices32(const std::vector &v_uuid); void setFlags(uint8_t); void setManufacturerData(const std::string &data); void setName(const std::string &name); void setPartialServices(const NimBLEUUID &uuid); + void setPartialServices16(const std::vector &v_uuid); + void setPartialServices32(const std::vector &v_uuid); void setServiceData(const NimBLEUUID &uuid, const std::string &data); void setShortName(const std::string &name); void addData(const std::string &data); // Add data to the payload. @@ -62,6 +66,8 @@ public: private: friend class NimBLEAdvertising; + void setServices(const bool complete, const uint8_t size, + const std::vector &v_uuid); std::string m_payload; // The payload of the advertisement. }; // NimBLEAdvertisementData