18#ifndef NIMBLE_CPP_ATTVALUE_H
19#define NIMBLE_CPP_ATTVALUE_H
25# ifndef NIMBLE_CPP_ARDUINO_STRING_AVAILABLE
26# define NIMBLE_CPP_ARDUINO_STRING_AVAILABLE (__has_include(<Arduino.h>))
29# if NIMBLE_CPP_ARDUINO_STRING_AVAILABLE
39# ifndef CONFIG_NIMBLE_CPP_ATT_VALUE_TIMESTAMP_ENABLED
40# define CONFIG_NIMBLE_CPP_ATT_VALUE_TIMESTAMP_ENABLED 0
43# ifndef BLE_ATT_ATTR_MAX_LEN
44# define BLE_ATT_ATTR_MAX_LEN 512
47# if !defined(CONFIG_NIMBLE_CPP_ATT_VALUE_INIT_LENGTH)
48# define CONFIG_NIMBLE_CPP_ATT_VALUE_INIT_LENGTH 20
49# elif CONFIG_NIMBLE_CPP_ATT_VALUE_INIT_LENGTH > BLE_ATT_ATTR_MAX_LEN
50# error CONFIG_NIMBLE_CPP_ATT_VALUE_INIT_LENGTH cannot be larger than 512 (BLE_ATT_ATTR_MAX_LEN)
51# elif CONFIG_NIMBLE_CPP_ATT_VALUE_INIT_LENGTH < 1
52# error CONFIG_NIMBLE_CPP_ATT_VALUE_INIT_LENGTH cannot be less than 1; Range = 1 : 512
56template <
typename T,
typename =
void,
typename =
void>
57struct Has_data_size : std::false_type {};
60struct Has_data_size<T, decltype(void(std::declval<T&>().data())), decltype(void(std::declval<T&>().size()))>
64template <
typename T,
typename =
void,
typename =
void>
65struct Has_c_str_length : std::false_type {};
68struct Has_c_str_length<T, decltype(void(std::declval<T&>().c_str())), decltype(void(std::declval<T&>().length()))>
72template <
typename T,
typename =
void>
73struct Has_value_type : std::false_type {};
76struct Has_value_type<T, decltype(void(sizeof(typename T::value_type)))>
86 uint8_t* m_attr_value{};
87 uint16_t m_attr_max_len{};
88 uint16_t m_attr_len{};
89 uint16_t m_capacity{};
90# if CONFIG_NIMBLE_CPP_ATT_VALUE_TIMESTAMP_ENABLED
101 NimBLEAttValue(uint16_t init_len = CONFIG_NIMBLE_CPP_ATT_VALUE_INIT_LENGTH, uint16_t max_len = BLE_ATT_ATTR_MAX_LEN);
109 NimBLEAttValue(
const uint8_t* value, uint16_t len, uint16_t max_len = BLE_ATT_ATTR_MAX_LEN);
117 :
NimBLEAttValue((uint8_t*)value, (uint16_t)strlen(value), max_len) {}
124 NimBLEAttValue(std::initializer_list<uint8_t> list, uint16_t max_len = BLE_ATT_ATTR_MAX_LEN)
140 NimBLEAttValue(
const std::vector<uint8_t> vec, uint16_t max_len = BLE_ATT_ATTR_MAX_LEN)
143# if NIMBLE_CPP_ARDUINO_STRING_AVAILABLE
149 NimBLEAttValue(
const String str, uint16_t max_len = BLE_ATT_ATTR_MAX_LEN)
163 uint16_t
max_size()
const {
return m_attr_max_len; }
169 uint16_t
length()
const {
return m_attr_len; }
172 uint16_t
size()
const {
return m_attr_len; }
175 const uint8_t*
data()
const {
return m_attr_value; }
178 const char*
c_str()
const {
return reinterpret_cast<const char*
>(m_attr_value); }
181 const uint8_t*
begin()
const {
return m_attr_value; }
184 const uint8_t*
end()
const {
return m_attr_value + m_attr_len; }
186# if CONFIG_NIMBLE_CPP_ATT_VALUE_TIMESTAMP_ENABLED
188 time_t getTimeStamp()
const {
return m_timestamp; }
191 void setTimeStamp() { m_timestamp = time(
nullptr); }
197 void setTimeStamp(time_t t) { m_timestamp = t; }
199 time_t getTimeStamp()
const {
return 0; }
200 void setTimeStamp() {}
201 void setTimeStamp(time_t t) {}
210 bool setValue(
const uint8_t* value, uint16_t len);
221 return setValue(
reinterpret_cast<const uint8_t*
>(s), len);
224 const NimBLEAttValue& getValue(time_t* timestamp =
nullptr)
const {
225 if (timestamp !=
nullptr) {
226# if CONFIG_NIMBLE_CPP_ATT_VALUE_TIMESTAMP_ENABLED
227 *timestamp = m_timestamp;
245# if __cplusplus < 201703L
251 template <
typename T>
255 typename std::enable_if<std::is_array<T>::value &&
256 std::is_same<typename std::remove_extent<T>::type,
char>::value,
260 return setValue(
reinterpret_cast<const uint8_t*
>(s), strnlen(s,
sizeof(T)));
269 template <
typename T>
273 typename std::enable_if<!std::is_pointer<T>::value && !Has_c_str_length<T>::value && !Has_data_size<T>::value &&
274 !(std::is_array<T>::value &&
275 std::is_same<typename std::remove_extent<T>::type,
char>::value),
279 return setValue(
reinterpret_cast<const uint8_t*
>(&v),
sizeof(T));
287 template <
typename T>
291 typename std::enable_if<Has_c_str_length<T>::value && !Has_data_size<T>::value,
bool>::type
294 return setValue(
reinterpret_cast<const uint8_t*
>(s.c_str()), s.length());
303 template <
typename T>
307 typename std::enable_if<Has_data_size<T>::value && Has_value_type<T>::value,
bool>::type
311 reinterpret_cast<const uint8_t*
>(v.data()),
312 v.size() *
sizeof(
typename T::value_type)
321 template <
typename T>
325 typename std::enable_if<Has_data_size<T>::value && !Has_value_type<T>::value,
bool>::type
328 return setValue(
reinterpret_cast<const uint8_t*
>(v.data()), v.size());
337 template <
typename T>
338 typename std::enable_if<!std::is_pointer<T>::value,
bool>::type
setValue(
const T& s) {
339 if constexpr (Has_data_size<T>::value) {
340 if constexpr (Has_value_type<T>::value) {
341 return setValue(
reinterpret_cast<const uint8_t*
>(s.data()), s.size() *
sizeof(
typename T::value_type));
343 return setValue(
reinterpret_cast<const uint8_t*
>(s.data()), s.size());
345 }
else if constexpr (Has_c_str_length<T>::value) {
346 return setValue(
reinterpret_cast<const uint8_t*
>(s.c_str()), s.length());
347 }
else if constexpr (std::is_array<T>::value &&
348 std::is_same<typename std::remove_extent<T>::type,
char>::value) {
349 return setValue(
reinterpret_cast<const uint8_t*
>(s), strnlen(s,
sizeof(s)));
351 return setValue(
reinterpret_cast<const uint8_t*
>(&s),
sizeof(s));
366 template <
typename T>
367 T
getValue(time_t* timestamp =
nullptr,
bool skipSizeCheck =
false)
const {
368 if (timestamp !=
nullptr) {
369# if CONFIG_NIMBLE_CPP_ATT_VALUE_TIMESTAMP_ENABLED
370 *timestamp = m_timestamp;
376 if (!skipSizeCheck &&
size() <
sizeof(T)) {
379 return *(
reinterpret_cast<const T*
>(m_attr_value));
388 operator std::vector<uint8_t>()
const {
return std::vector<uint8_t>(m_attr_value, m_attr_value + m_attr_len); }
391 operator std::string()
const {
return std::string(
reinterpret_cast<char*
>(m_attr_value), m_attr_len); }
394 operator const uint8_t*()
const {
return m_attr_value; }
401 setValue(
reinterpret_cast<const uint8_t*
>(&source[0]), source.size());
413 return (m_attr_len == source.
size()) ? memcmp(m_attr_value, source.
data(), m_attr_len) == 0 :
false;
419# if NIMBLE_CPP_ARDUINO_STRING_AVAILABLE
421 operator String()
const {
return String(
reinterpret_cast<char*
>(m_attr_value)); }
A specialized container class to hold BLE attribute values.
Definition NimBLEAttValue.h:85
NimBLEAttValue(const std::vector< uint8_t > vec, uint16_t max_len=BLE_ATT_ATTR_MAX_LEN)
Construct with an initial value from a std::vector<uint8_t>.
Definition NimBLEAttValue.h:140
~NimBLEAttValue()
Destructor.
Definition NimBLEAttValue.cpp:57
uint16_t length() const
Returns the current length of the value in bytes.
Definition NimBLEAttValue.h:169
NimBLEAttValue(const char *value, uint16_t max_len=BLE_ATT_ATTR_MAX_LEN)
Construct with an initial value from a const char string.
Definition NimBLEAttValue.h:116
uint16_t capacity() const
Returns the currently allocated capacity in bytes.
Definition NimBLEAttValue.h:166
const char * c_str() const
Returns a pointer to the internal buffer of the value as a const char*.
Definition NimBLEAttValue.h:178
NimBLEAttValue(const std::string str, uint16_t max_len=BLE_ATT_ATTR_MAX_LEN)
Construct with an initial value from a std::string.
Definition NimBLEAttValue.h:132
bool setValue(const uint8_t *value, uint16_t len)
Set the value from a buffer.
Definition NimBLEAttValue.cpp:106
NimBLEAttValue(std::initializer_list< uint8_t > list, uint16_t max_len=BLE_ATT_ATTR_MAX_LEN)
Construct with an initializer list.
Definition NimBLEAttValue.h:124
NimBLEAttValue & operator+=(const NimBLEAttValue &source)
Operator; Append another NimBLEAttValue.
Definition NimBLEAttValue.h:397
NimBLEAttValue(const NimBLEAttValue &source)
Copy constructor.
Definition NimBLEAttValue.h:154
NimBLEAttValue(NimBLEAttValue &&source)
Move constructor.
Definition NimBLEAttValue.h:157
const uint8_t * data() const
Returns a pointer to the internal buffer of the value.
Definition NimBLEAttValue.h:175
uint8_t operator[](int pos) const
Subscript operator.
Definition NimBLEAttValue.cpp:153
const uint8_t * end() const
Iterator end.
Definition NimBLEAttValue.h:184
bool setValue(const T &v)
Template to set value to the value of <type>val.
Definition NimBLEAttValue.h:278
NimBLEAttValue & append(const uint8_t *value, uint16_t len)
Append data to the value.
Definition NimBLEAttValue.cpp:114
uint16_t size() const
Returns the current size of the value in bytes.
Definition NimBLEAttValue.h:172
bool setValue(const char *s, uint16_t len=0)
Set value to the value of const char*.
Definition NimBLEAttValue.h:217
T getValue(time_t *timestamp=nullptr, bool skipSizeCheck=false) const
Template to return the value as a <type>.
Definition NimBLEAttValue.h:367
uint16_t max_size() const
Returns the max size in bytes.
Definition NimBLEAttValue.h:163
bool setValue(const T &s)
Template to set value to the value of a char array using strnlen.
Definition NimBLEAttValue.h:259
bool operator==(const NimBLEAttValue &source) const
Equality operator.
Definition NimBLEAttValue.h:412
NimBLEAttValue & operator=(const std::string &source)
Operator; Set the value from a std::string source.
Definition NimBLEAttValue.h:400
const uint8_t * begin() const
Iterator begin.
Definition NimBLEAttValue.h:181
bool operator!=(const NimBLEAttValue &source) const
Inequality operator.
Definition NimBLEAttValue.h:417