9 #ifndef MAIN_NIMBLEATTVALUE_H_
10 #define MAIN_NIMBLEATTVALUE_H_
12 #if defined(CONFIG_BT_ENABLED)
14 #ifdef NIMBLE_CPP_ARDUINO_STRING_AVAILABLE
18 #include "NimBLELog.h"
28 #ifndef CONFIG_NIMBLE_CPP_ATT_VALUE_TIMESTAMP_ENABLED
29 # define CONFIG_NIMBLE_CPP_ATT_VALUE_TIMESTAMP_ENABLED 0
32 #if CONFIG_NIMBLE_CPP_ATT_VALUE_TIMESTAMP_ENABLED
36 #if !defined(CONFIG_NIMBLE_CPP_ATT_VALUE_INIT_LENGTH)
37 # define CONFIG_NIMBLE_CPP_ATT_VALUE_INIT_LENGTH 20
38 #elif CONFIG_NIMBLE_CPP_ATT_VALUE_INIT_LENGTH > BLE_ATT_ATTR_MAX_LEN
39 # error CONFIG_NIMBLE_CPP_ATT_VALUE_INIT_LENGTH cannot be larger than 512 (BLE_ATT_ATTR_MAX_LEN)
40 #elif CONFIG_NIMBLE_CPP_ATT_VALUE_INIT_LENGTH < 1
41 # error CONFIG_NIMBLE_CPP_ATT_VALUE_INIT_LENGTH cannot be less than 1; Range = 1 : 512
46 template <
typename T,
typename =
void,
typename =
void>
47 struct Has_c_str_len : std::false_type {};
50 struct Has_c_str_len<T, decltype(void(std::declval<T &>().c_str())),
51 decltype(void(std::declval<T &>().length()))> : std::true_type {};
62 uint8_t* m_attr_value =
nullptr;
63 uint16_t m_attr_max_len = 0;
64 uint16_t m_attr_len = 0;
65 uint16_t m_capacity = 0;
66 #if CONFIG_NIMBLE_CPP_ATT_VALUE_TIMESTAMP_ENABLED
67 time_t m_timestamp = 0;
78 uint16_t max_len = BLE_ATT_ATTR_MAX_LEN);
87 uint16_t max_len = BLE_ATT_ATTR_MAX_LEN);
95 uint16_t max_len = BLE_ATT_ATTR_MAX_LEN)
104 :
NimBLEAttValue((uint8_t*)value, (uint16_t)strlen(value), max_len){}
119 NimBLEAttValue(
const std::vector<uint8_t> vec, uint16_t max_len = BLE_ATT_ATTR_MAX_LEN)
122 #ifdef NIMBLE_CPP_ARDUINO_STRING_AVAILABLE
128 NimBLEAttValue(
const String str, uint16_t max_len = BLE_ATT_ATTR_MAX_LEN)
142 uint16_t
max_size()
const {
return m_attr_max_len; }
148 uint16_t
length()
const {
return m_attr_len; }
151 uint16_t
size()
const {
return m_attr_len; }
154 const uint8_t*
data()
const {
return m_attr_value; }
157 const char*
c_str()
const {
return (
const char*)m_attr_value; }
160 const uint8_t*
begin()
const {
return m_attr_value; }
163 const uint8_t*
end()
const {
return m_attr_value + m_attr_len; }
165 #if CONFIG_NIMBLE_CPP_ATT_VALUE_TIMESTAMP_ENABLED
167 time_t getTimeStamp()
const {
return m_timestamp; }
170 void setTimeStamp() { m_timestamp = time(
nullptr); }
176 void setTimeStamp(time_t t) { m_timestamp = t; }
178 time_t getTimeStamp()
const {
return 0; }
179 void setTimeStamp() { }
180 void setTimeStamp(time_t t) { }
189 bool setValue(
const uint8_t *value, uint16_t len);
196 return setValue((uint8_t*)s, (uint16_t)strlen(s)); }
203 const uint8_t*
getValue(time_t *timestamp);
225 typename std::enable_if<!Has_c_str_len<T>::value,
bool>::type
228 return setValue((uint8_t*)&s,
sizeof(T));
240 typename std::enable_if<Has_c_str_len<T>::value,
bool>::type
243 return setValue((uint8_t*)s.c_str(), (uint16_t)s.length());
257 T
getValue(time_t *timestamp =
nullptr,
bool skipSizeCheck =
false) {
258 if(!skipSizeCheck &&
size() <
sizeof(T)) {
269 assert(pos < m_attr_len &&
"out of range");
return m_attr_value[pos]; }
272 operator std::vector<uint8_t>()
const {
273 return std::vector<uint8_t>(m_attr_value, m_attr_value + m_attr_len); }
276 operator std::string()
const {
277 return std::string((
char*)m_attr_value, m_attr_len); }
280 operator const uint8_t*()
const {
return m_attr_value; }
288 setValue((uint8_t*)source.data(), (uint16_t)source.size());
return *
this; }
298 return (m_attr_len == source.
size()) ?
299 memcmp(m_attr_value, source.
data(), m_attr_len) == 0 :
false; }
304 #ifdef NIMBLE_CPP_ARDUINO_STRING_AVAILABLE
306 operator String()
const {
return String((
char*)m_attr_value); }
313 m_attr_value = (uint8_t*)calloc(init_len + 1, 1);
314 assert(m_attr_value &&
"No Mem");
315 m_attr_max_len = std::min(BLE_ATT_ATTR_MAX_LEN, (
int)max_len);
317 m_capacity = init_len;
323 memcpy(m_attr_value, value, len);
324 m_attr_value[len] =
'\0';
329 if(m_attr_value !=
nullptr) {
335 if (
this != &source){
338 m_attr_value = source.m_attr_value;
339 m_attr_max_len = source.m_attr_max_len;
340 m_attr_len = source.m_attr_len;
341 m_capacity = source.m_capacity;
342 setTimeStamp(source.getTimeStamp());
343 source.m_attr_value =
nullptr;
349 if (
this != &source) {
355 inline void NimBLEAttValue::deepCopy(
const NimBLEAttValue & source) {
356 uint8_t* res = (uint8_t*)realloc( m_attr_value, source.m_capacity + 1);
357 assert(res &&
"deepCopy: realloc failed");
359 ble_npl_hw_enter_critical();
361 m_attr_max_len = source.m_attr_max_len;
362 m_attr_len = source.m_attr_len;
363 m_capacity = source.m_capacity;
364 setTimeStamp(source.getTimeStamp());
365 memcpy(m_attr_value, source.m_attr_value, m_attr_len + 1);
366 ble_npl_hw_exit_critical(0);
370 if(timestamp !=
nullptr) {
371 #if CONFIG_NIMBLE_CPP_ATT_VALUE_TIMESTAMP_ENABLED
372 *timestamp = m_timestamp;
381 if (len > m_attr_max_len) {
382 NIMBLE_LOGE(
"NimBLEAttValue",
"value exceeds max, len=%u, max=%u",
383 len, m_attr_max_len);
387 uint8_t *res = m_attr_value;
388 if (len > m_capacity) {
389 res = (uint8_t*)realloc(m_attr_value, (len + 1));
392 assert(res &&
"setValue: realloc failed");
394 #if CONFIG_NIMBLE_CPP_ATT_VALUE_TIMESTAMP_ENABLED
395 time_t t = time(
nullptr);
400 ble_npl_hw_enter_critical();
402 memcpy(m_attr_value, value, len);
403 m_attr_value[len] =
'\0';
406 ble_npl_hw_exit_critical(0);
415 if ((m_attr_len + len) > m_attr_max_len) {
416 NIMBLE_LOGE(
"NimBLEAttValue",
"val > max, len=%u, max=%u",
417 len, m_attr_max_len);
421 uint8_t* res = m_attr_value;
422 uint16_t new_len = m_attr_len + len;
423 if (new_len > m_capacity) {
424 res = (uint8_t*)realloc(m_attr_value, (new_len + 1));
425 m_capacity = new_len;
427 assert(res &&
"append: realloc failed");
429 #if CONFIG_NIMBLE_CPP_ATT_VALUE_TIMESTAMP_ENABLED
430 time_t t = time(
nullptr);
435 ble_npl_hw_enter_critical();
437 memcpy(m_attr_value + m_attr_len, value, len);
438 m_attr_len = new_len;
439 m_attr_value[m_attr_len] =
'\0';
441 ble_npl_hw_exit_critical(0);
A specialized container class to hold BLE attribute values.
Definition: NimBLEAttValue.h:61
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:119
~NimBLEAttValue()
Destructor.
Definition: NimBLEAttValue.h:328
NimBLEAttValue & operator+=(const NimBLEAttValue &source)
Operator; Append another NimBLEAttValue.
Definition: NimBLEAttValue.h:283
T getValue(time_t *timestamp=nullptr, bool skipSizeCheck=false)
Template to return the value as a <type>.
Definition: NimBLEAttValue.h:257
uint16_t length() const
Returns the current length of the value in bytes.
Definition: NimBLEAttValue.h:148
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:103
uint16_t capacity() const
Returns the currently allocated capacity in bytes.
Definition: NimBLEAttValue.h:145
const uint8_t * end() const
Iterator end.
Definition: NimBLEAttValue.h:163
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:111
bool setValue(const uint8_t *value, uint16_t len)
Set the value from a buffer.
Definition: NimBLEAttValue.h:380
const uint8_t * getValue(time_t *timestamp)
Get a pointer to the value buffer with timestamp.
Definition: NimBLEAttValue.h:369
const uint8_t * begin() const
Iterator begin.
Definition: NimBLEAttValue.h:160
NimBLEAttValue(std::initializer_list< uint8_t > list, uint16_t max_len=BLE_ATT_ATTR_MAX_LEN)
Construct with an initializer list.
Definition: NimBLEAttValue.h:94
NimBLEAttValue(const NimBLEAttValue &source)
Copy constructor.
Definition: NimBLEAttValue.h:133
NimBLEAttValue(NimBLEAttValue &&source)
Move constructor.
Definition: NimBLEAttValue.h:136
uint8_t operator[](int pos) const
Subscript operator.
Definition: NimBLEAttValue.h:268
bool operator==(const NimBLEAttValue &source)
Equality operator.
Definition: NimBLEAttValue.h:297
bool setValue(const char *s)
Set value to the value of const char*.
Definition: NimBLEAttValue.h:195
bool operator!=(const NimBLEAttValue &source)
Inequality operator.
Definition: NimBLEAttValue.h:302
const uint8_t * data() const
Returns a pointer to the internal buffer of the value.
Definition: NimBLEAttValue.h:154
NimBLEAttValue & operator=(const std::string &source)
Operator; Set the value from a std::string source.
Definition: NimBLEAttValue.h:287
NimBLEAttValue & append(const uint8_t *value, uint16_t len)
Append data to the value.
Definition: NimBLEAttValue.h:410
const char * c_str() const
Returns a pointer to the internal buffer of the value as a const char*.
Definition: NimBLEAttValue.h:157
NimBLEAttValue(uint16_t init_len=CONFIG_NIMBLE_CPP_ATT_VALUE_INIT_LENGTH, uint16_t max_len=BLE_ATT_ATTR_MAX_LEN)
Default constructor.
Definition: NimBLEAttValue.h:312
uint16_t size() const
Returns the current size of the value in bytes.
Definition: NimBLEAttValue.h:151
uint16_t max_size() const
Returns the max size in bytes.
Definition: NimBLEAttValue.h:142
bool setValue(const T &s)
Template to set value to the value of <type>val.
Definition: NimBLEAttValue.h:227
#define CONFIG_NIMBLE_CPP_ATT_VALUE_INIT_LENGTH
Uncomment to set the default allocation size (bytes) for each attribute if not specified when the con...
Definition: nimconfig.h:56