Use templates for attribute values.

* Add timestamps for NimBLECharacteristic.
This commit is contained in:
h2zero 2020-07-01 17:32:41 -06:00
parent 745f9c00ed
commit 8d2821a429
7 changed files with 50 additions and 88 deletions

View file

@ -51,6 +51,7 @@ NimBLECharacteristic::NimBLECharacteristic(const NimBLEUUID &uuid, uint16_t prop
m_value = ""; m_value = "";
m_valMux = portMUX_INITIALIZER_UNLOCKED; m_valMux = portMUX_INITIALIZER_UNLOCKED;
m_pTaskData = nullptr; m_pTaskData = nullptr;
m_timestamp = 0;
} // NimBLECharacteristic } // NimBLECharacteristic
/** /**
@ -163,9 +164,12 @@ NimBLEUUID NimBLECharacteristic::getUUID() {
* @brief Retrieve the current value of the characteristic. * @brief Retrieve the current value of the characteristic.
* @return A pointer to storage containing the current characteristic value. * @return A pointer to storage containing the current characteristic value.
*/ */
std::string NimBLECharacteristic::getValue() { std::string NimBLECharacteristic::getValue(time_t *timestamp) {
portENTER_CRITICAL(&m_valMux); portENTER_CRITICAL(&m_valMux);
std::string retVal = m_value; std::string retVal = m_value;
if(timestamp != nullptr) {
*timestamp = m_timestamp;
}
portEXIT_CRITICAL(&m_valMux); portEXIT_CRITICAL(&m_valMux);
return retVal; return retVal;
@ -461,6 +465,7 @@ void NimBLECharacteristic::setValue(const uint8_t* data, size_t length) {
portENTER_CRITICAL(&m_valMux); portENTER_CRITICAL(&m_valMux);
m_value = std::string((char*)data, length); m_value = std::string((char*)data, length);
m_timestamp = time(nullptr);
portEXIT_CRITICAL(&m_valMux); portEXIT_CRITICAL(&m_valMux);
NIMBLE_LOGD(LOG_TAG, "<< setValue"); NIMBLE_LOGD(LOG_TAG, "<< setValue");
@ -478,45 +483,6 @@ void NimBLECharacteristic::setValue(const std::string &value) {
setValue((uint8_t*)(value.data()), value.length()); setValue((uint8_t*)(value.data()), value.length());
} // setValue } // setValue
void NimBLECharacteristic::setValue(uint8_t data8) {
setValue(&data8, 1);
} // setValue
void NimBLECharacteristic::setValue(uint16_t& data16) {
uint8_t temp[2];
temp[0] = data16;
temp[1] = data16 >> 8;
setValue(temp, 2);
} // setValue
void NimBLECharacteristic::setValue(uint32_t& data32) {
uint8_t temp[4];
temp[0] = data32;
temp[1] = data32 >> 8;
temp[2] = data32 >> 16;
temp[3] = data32 >> 24;
setValue(temp, 4);
} // setValue
void NimBLECharacteristic::setValue(int& data32) {
uint8_t temp[4];
temp[0] = data32;
temp[1] = data32 >> 8;
temp[2] = data32 >> 16;
temp[3] = data32 >> 24;
setValue(temp, 4);
} // setValue
void NimBLECharacteristic::setValue(float& data32) {
float temp = data32;
setValue((uint8_t*)&temp, 4);
} // setValue
void NimBLECharacteristic::setValue(double& data64) {
double temp = data64;
setValue((uint8_t*)&temp, 8);
} // setValue
/** /**
* @brief Return a string representation of the characteristic. * @brief Return a string representation of the characteristic.

View file

@ -73,19 +73,28 @@ public:
NimBLEDescriptor* getDescriptorByUUID(const char* uuid); NimBLEDescriptor* getDescriptorByUUID(const char* uuid);
NimBLEDescriptor* getDescriptorByUUID(const NimBLEUUID &uuid); NimBLEDescriptor* getDescriptorByUUID(const NimBLEUUID &uuid);
NimBLEUUID getUUID(); NimBLEUUID getUUID();
std::string getValue(); std::string getValue(time_t *timestamp = nullptr);
template<typename T>
T getValue(time_t *timestamp = nullptr, bool skipSizeCheck = false) {
std::string value = getValue();
if(!skipSizeCheck && value.size() < sizeof(T)) return T();
const char *pData = value.data();
return *((T *)pData);
}
size_t getDataLength(); size_t getDataLength();
void indicate(); void indicate();
void notify(bool is_notification = true); void notify(bool is_notification = true);
void setCallbacks(NimBLECharacteristicCallbacks* pCallbacks); void setCallbacks(NimBLECharacteristicCallbacks* pCallbacks);
void setValue(const uint8_t* data, size_t size); void setValue(const uint8_t* data, size_t size);
void setValue(const std::string &value); void setValue(const std::string &value);
void setValue(uint8_t data8);
void setValue(uint16_t& data16); template<typename T>
void setValue(uint32_t& data32); void setValue(const T &s) {
void setValue(int& data32); setValue((uint8_t*)&s, sizeof(T));
void setValue(float& data32); }
void setValue(double& data64);
std::string toString(); std::string toString();
uint16_t getHandle(); uint16_t getHandle();
@ -122,6 +131,7 @@ private:
std::vector<NimBLEDescriptor*> m_dscVec; std::vector<NimBLEDescriptor*> m_dscVec;
ble_task_data_t *m_pTaskData; ble_task_data_t *m_pTaskData;
portMUX_TYPE m_valMux; portMUX_TYPE m_valMux;
time_t m_timestamp;
}; // NimBLECharacteristic }; // NimBLECharacteristic

View file

@ -52,6 +52,11 @@ public:
void setValue(const std::string &value); void setValue(const std::string &value);
std::string toString(); std::string toString();
template<typename T>
void setValue(const T &s) {
setValue((uint8_t*)&s, sizeof(T));
}
private: private:
friend class NimBLECharacteristic; friend class NimBLECharacteristic;
friend class NimBLEService; friend class NimBLEService;

View file

@ -357,11 +357,7 @@ std::string NimBLERemoteCharacteristic::getValue(time_t *timestamp) {
* @return The unsigned 16 bit value. * @return The unsigned 16 bit value.
*/ */
uint16_t NimBLERemoteCharacteristic::readUInt16() { uint16_t NimBLERemoteCharacteristic::readUInt16() {
std::string value = readValue(); return readValue<uint16_t>();
if (value.length() >= 2) {
return *(uint16_t*)(value.data());
}
return 0;
} // readUInt16 } // readUInt16
@ -370,11 +366,7 @@ uint16_t NimBLERemoteCharacteristic::readUInt16() {
* @return the unsigned 32 bit value. * @return the unsigned 32 bit value.
*/ */
uint32_t NimBLERemoteCharacteristic::readUInt32() { uint32_t NimBLERemoteCharacteristic::readUInt32() {
std::string value = readValue(); return readValue<uint32_t>();
if (value.length() >= 4) {
return *(uint32_t*)(value.data());
}
return 0;
} // readUInt32 } // readUInt32
@ -383,14 +375,19 @@ uint32_t NimBLERemoteCharacteristic::readUInt32() {
* @return The value as a byte * @return The value as a byte
*/ */
uint8_t NimBLERemoteCharacteristic::readUInt8() { uint8_t NimBLERemoteCharacteristic::readUInt8() {
std::string value = readValue(); return readValue<uint8_t>();
if (value.length() >= 1) {
return (uint8_t)value[0];
}
return 0;
} // readUInt8 } // readUInt8
/**
* @brief Read a float value.
* @return the float value.
*/
float NimBLERemoteCharacteristic::readFloat() {
return readValue<float>();
} // readFloat
/** /**
* @brief Read the value of the remote characteristic. * @brief Read the value of the remote characteristic.
* @return The value of the remote characteristic. * @return The value of the remote characteristic.
@ -646,19 +643,6 @@ bool NimBLERemoteCharacteristic::writeValue(const std::string &newValue, bool re
} // writeValue } // writeValue
/**
* @brief Write the new value for the characteristic.
*
* This is a convenience function. Many BLE characteristics are a single byte of data.
* @param [in] newValue The new byte value to write.
* @param [in] response Whether we require a response from the write.
* @return false if not connected or cant perform write for some reason.
*/
bool NimBLERemoteCharacteristic::writeValue(uint8_t newValue, bool response) {
return writeValue(&newValue, 1, response);
} // writeValue
/** /**
* @brief Write the new value for the characteristic from a data buffer. * @brief Write the new value for the characteristic from a data buffer.
* @param [in] data A pointer to a data buffer. * @param [in] data A pointer to a data buffer.

View file

@ -74,6 +74,7 @@ public:
uint8_t readUInt8() __attribute__ ((deprecated("Use template readValue<uint8_t>()"))); uint8_t readUInt8() __attribute__ ((deprecated("Use template readValue<uint8_t>()")));
uint16_t readUInt16() __attribute__ ((deprecated("Use template readValue<uint16_t>()"))); uint16_t readUInt16() __attribute__ ((deprecated("Use template readValue<uint16_t>()")));
uint32_t readUInt32() __attribute__ ((deprecated("Use template readValue<uint32_t>()"))); uint32_t readUInt32() __attribute__ ((deprecated("Use template readValue<uint32_t>()")));
float readFloat() __attribute__ ((deprecated("Use template readValue<float>()")));
std::string getValue(time_t *timestamp = nullptr); std::string getValue(time_t *timestamp = nullptr);
template<typename T> template<typename T>
@ -97,8 +98,11 @@ public:
bool response = false); bool response = false);
bool writeValue(const std::string &newValue, bool writeValue(const std::string &newValue,
bool response = false); bool response = false);
bool writeValue(uint8_t newValue, template<typename T>
bool response = false); bool writeValue(const T &s, bool response = false) {
return writeValue((uint8_t*)&s, sizeof(T), response);
}
std::string toString(); std::string toString();
NimBLERemoteService* getRemoteService(); NimBLERemoteService* getRemoteService();

View file

@ -328,15 +328,5 @@ bool NimBLERemoteDescriptor::writeValue(const std::string &newValue, bool respon
} // writeValue } // writeValue
/**
* @brief Write a byte value to the Descriptor.
* @param [in] The single byte to write.
* @param [in] True if we expect a response.
*/
bool NimBLERemoteDescriptor::writeValue(uint8_t newValue, bool response) {
return writeValue(&newValue, 1, response);
} // writeValue
#endif // #if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL) #endif // #if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL)
#endif /* CONFIG_BT_ENABLED */ #endif /* CONFIG_BT_ENABLED */

View file

@ -47,7 +47,10 @@ public:
std::string toString(void); std::string toString(void);
bool writeValue(const uint8_t* data, size_t length, bool response = false); bool writeValue(const uint8_t* data, size_t length, bool response = false);
bool writeValue(const std::string &newValue, bool response = false); bool writeValue(const std::string &newValue, bool response = false);
bool writeValue(uint8_t newValue, bool response = false); template<typename T>
bool writeValue(const T &s, bool response = false) {
return writeValue((uint8_t*)&s, sizeof(T), response);
}
private: private:
friend class NimBLERemoteCharacteristic; friend class NimBLERemoteCharacteristic;