Skip to content

Commit

Permalink
Refactor NimBLEAttValue.
Browse files Browse the repository at this point in the history
* Add length parameter to `setValue()` templates, with defaults for backward compatibility.
* Changed `setValue(const char*)` to add an optional length parameter so that a NULL character can be included, defaults to strlen.
* Moved non-inline functions to `NimBLEAttValue.cpp` file.
* Corrected includes to permit compilation as a stand-alone utility.
* Removed repeated code in `setValue()` by using `append()` after clearing the value.
* General code cleanup.

# Conflicts:
#	CMakeLists.txt
  • Loading branch information
h2zero committed Jul 20, 2024
1 parent f7fd959 commit e81aead
Show file tree
Hide file tree
Showing 2 changed files with 272 additions and 266 deletions.
130 changes: 130 additions & 0 deletions src/NimBLEAttValue.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
/*
* NimBLEAttValue.cpp
*
* Created: on July 17, 2024
* Author H2zero
*
*/

#include "nimconfig.h"
#if defined(CONFIG_BT_ENABLED)

# if defined(CONFIG_NIMBLE_CPP_IDF)
# include "nimble/nimble_npl.h"
# else
# include "nimble/nimble/include/nimble/nimble_npl.h"
# endif

# include "NimBLEAttValue.h"

// Default constructor implementation.
NimBLEAttValue::NimBLEAttValue(uint16_t init_len, uint16_t max_len)
: m_attr_value{static_cast<uint8_t*>(calloc(init_len + 1, 1))},
m_attr_max_len{std::min<uint16_t>(BLE_ATT_ATTR_MAX_LEN, max_len)},
m_attr_len{},
m_capacity{init_len}
# if CONFIG_NIMBLE_CPP_ATT_VALUE_TIMESTAMP_ENABLED
,
m_timestamp{}
# endif
{
NIMBLE_CPP_DEBUG_ASSERT(m_attr_value);
}

// Value constructor implementation.
NimBLEAttValue::NimBLEAttValue(const uint8_t *value, uint16_t len, uint16_t max_len)
: NimBLEAttValue(len, max_len) {
memcpy(m_attr_value, value, len);
m_attr_value[len] = '\0';
m_attr_len = len;
}

// Destructor implementation.
NimBLEAttValue::~NimBLEAttValue() {
if (m_attr_value != nullptr) {
free(m_attr_value);
}
}

// Move assignment operator implementation.
NimBLEAttValue& NimBLEAttValue::operator=(NimBLEAttValue&& source) {
if (this != &source) {
free(m_attr_value);
m_attr_value = source.m_attr_value;
m_attr_max_len = source.m_attr_max_len;
m_attr_len = source.m_attr_len;
m_capacity = source.m_capacity;
setTimeStamp(source.getTimeStamp());
source.m_attr_value = nullptr;
}

return *this;
}

// Copy assignment implementation.
NimBLEAttValue& NimBLEAttValue::operator=(const NimBLEAttValue& source) {
if (this != &source) {
deepCopy(source);
}
return *this;
}

// Copy all the data from the source object to this object, including allocated space.
void NimBLEAttValue::deepCopy(const NimBLEAttValue& source) {
uint8_t* res = static_cast<uint8_t*>(realloc(m_attr_value, source.m_capacity + 1));
NIMBLE_CPP_DEBUG_ASSERT(res);

ble_npl_hw_enter_critical();
m_attr_value = res;
m_attr_max_len = source.m_attr_max_len;
m_attr_len = source.m_attr_len;
m_capacity = source.m_capacity;
setTimeStamp(source.getTimeStamp());
memcpy(m_attr_value, source.m_attr_value, m_attr_len + 1);
ble_npl_hw_exit_critical(0);
}

// Set the value of the attribute.
bool NimBLEAttValue::setValue(const uint8_t* value, uint16_t len) {
m_attr_len = 0; // Just set the value length to 0 and append instead of repeating code.
append(value, len);
return memcmp(m_attr_value, value, len) == 0 && m_attr_len == len;
}

// Append the new data, allocate as necessary.
NimBLEAttValue& NimBLEAttValue::append(const uint8_t* value, uint16_t len) {
if (len == 0) {
return *this;
}

if ((m_attr_len + len) > m_attr_max_len) {
NIMBLE_LOGE("NimBLEAttValue", "val > max, len=%u, max=%u", len, m_attr_max_len);
return *this;
}

uint8_t* res = m_attr_value;
uint16_t new_len = m_attr_len + len;
if (new_len > m_capacity) {
res = static_cast<uint8_t*>(realloc(m_attr_value, (new_len + 1)));
m_capacity = new_len;
}
NIMBLE_CPP_DEBUG_ASSERT(res);

# if CONFIG_NIMBLE_CPP_ATT_VALUE_TIMESTAMP_ENABLED
time_t t = time(nullptr);
# else
time_t t = 0;
# endif

ble_npl_hw_enter_critical();
memcpy(res + m_attr_len, value, len);
m_attr_value = res;
m_attr_len = new_len;
m_attr_value[m_attr_len] = '\0';
setTimeStamp(t);
ble_npl_hw_exit_critical(0);

return *this;
}

#endif // CONFIG_BT_ENABLED
Loading

0 comments on commit e81aead

Please sign in to comment.