From 99ad62cdd45f7540aae0a39ac496f20c555758b0 Mon Sep 17 00:00:00 2001 From: h2zero Date: Fri, 29 May 2020 20:02:26 -0600 Subject: [PATCH] Add template casting to readValue and advertisement data (#52) The value returned by reading a remote characteristic or by getting a notification for it is kept in the class instance of the NimBLERemoteCharacteristic. This value can be accessed as a std::string type using the getValue() function. This adds templates to read the value in the type used by the peripheral. The same functionality is implemented for getting the manufacturer data or the service data of an advertised device. --- src/NimBLEAdvertisedDevice.h | 18 ++++++++++++++++++ src/NimBLEClient.cpp | 1 + src/NimBLERemoteCharacteristic.cpp | 13 +++++++++++-- src/NimBLERemoteCharacteristic.h | 26 ++++++++++++++++++++++---- 4 files changed, 52 insertions(+), 6 deletions(-) diff --git a/src/NimBLEAdvertisedDevice.h b/src/NimBLEAdvertisedDevice.h index f38a9b4..3380f4a 100644 --- a/src/NimBLEAdvertisedDevice.h +++ b/src/NimBLEAdvertisedDevice.h @@ -45,10 +45,28 @@ public: uint8_t getAdvType(); uint16_t getAppearance(); std::string getManufacturerData(); + + template + T getManufacturerData(bool skipSizeCheck = false) { + std::string data = getManufacturerData(); + if(!skipSizeCheck && data.size() < sizeof(T)) return T(); + const char *pData = data.data(); + return *((T *)pData); + } + std::string getName(); int getRSSI(); NimBLEScan* getScan(); std::string getServiceData(); + + template + T getServiceData(bool skipSizeCheck = false) { + std::string data = getServiceData(); + if(!skipSizeCheck && data.size() < sizeof(T)) return T(); + const char *pData = data.data(); + return *((T *)pData); + } + NimBLEUUID getServiceDataUUID(); NimBLEUUID getServiceUUID(); int8_t getTXPower(); diff --git a/src/NimBLEClient.cpp b/src/NimBLEClient.cpp index 1bcbeb6..9dcc43e 100644 --- a/src/NimBLEClient.cpp +++ b/src/NimBLEClient.cpp @@ -725,6 +725,7 @@ uint16_t NimBLEClient::getMTU() { (*characteristic)->m_timestamp = time(nullptr); (*characteristic)->m_semaphoreReadCharEvt.give(); } + if ((*characteristic)->m_notifyCallback != nullptr) { NIMBLE_LOGD(LOG_TAG, "Invoking callback for notification on characteristic %s", (*characteristic)->toString().c_str()); diff --git a/src/NimBLERemoteCharacteristic.cpp b/src/NimBLERemoteCharacteristic.cpp index e818b77..c879d71 100644 --- a/src/NimBLERemoteCharacteristic.cpp +++ b/src/NimBLERemoteCharacteristic.cpp @@ -384,7 +384,7 @@ uint8_t NimBLERemoteCharacteristic::readUInt8() { * @brief Read the value of the remote characteristic. * @return The value of the remote characteristic. */ -std::string NimBLERemoteCharacteristic::readValue() { +std::string NimBLERemoteCharacteristic::readValue(time_t *timestamp) { NIMBLE_LOGD(LOG_TAG, ">> readValue(): uuid: %s, handle: %d 0x%.2x", getUUID().toString().c_str(), getHandle(), getHandle()); @@ -437,7 +437,15 @@ std::string NimBLERemoteCharacteristic::readValue() { } while(rc != 0 && retryCount--); NIMBLE_LOGD(LOG_TAG, "<< readValue(): length: %d", m_value.length()); - return m_value; + + m_semaphoreReadCharEvt.take("returnValue"); + std::string value = m_value; + if(timestamp != nullptr) { + *timestamp = m_timestamp; + } + m_semaphoreReadCharEvt.give(); + + return value; } // readValue @@ -451,6 +459,7 @@ std::string NimBLERemoteCharacteristic::getValue(time_t *timestamp) { if(timestamp != nullptr) { *timestamp = m_timestamp; } + m_semaphoreReadCharEvt.give(); return value; } diff --git a/src/NimBLERemoteCharacteristic.h b/src/NimBLERemoteCharacteristic.h index c04e1f4..f6afa21 100644 --- a/src/NimBLERemoteCharacteristic.h +++ b/src/NimBLERemoteCharacteristic.h @@ -53,11 +53,29 @@ public: uint16_t getHandle(); uint16_t getDefHandle(); NimBLEUUID getUUID(); - std::string readValue(); - uint8_t readUInt8(); - uint16_t readUInt16(); - uint32_t readUInt32(); + std::string readValue(time_t *timestamp = nullptr); + + template + T readValue(time_t *timestamp = nullptr, bool skipSizeCheck = false) { + std::string value = readValue(timestamp); + if(!skipSizeCheck && value.size() < sizeof(T)) return T(); + const char *pData = value.data(); + return *((T *)pData); + } + + uint8_t readUInt8() __attribute__ ((deprecated)); + uint16_t readUInt16() __attribute__ ((deprecated)); + uint32_t readUInt32() __attribute__ ((deprecated)); std::string getValue(time_t *timestamp = nullptr); + + template + T getValue(time_t *timestamp = nullptr, bool skipSizeCheck = false) { + std::string value = getValue(timestamp); + if(!skipSizeCheck && value.size() < sizeof(T)) return T(); + const char *pData = value.data(); + return *((T *)pData); + } + bool registerForNotify(notify_callback _callback, bool notifications = true, bool response = true);