2024-07-17 23:35:13 +02:00
|
|
|
/*
|
2024-12-13 03:21:03 +01:00
|
|
|
* Copyright 2020-2024 Ryan Powell <ryan@nable-embedded.io> and
|
|
|
|
* esp-nimble-cpp, NimBLE-Arduino contributors.
|
2024-07-17 23:35:13 +02:00
|
|
|
*
|
2024-12-13 03:21:03 +01:00
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
2024-07-17 23:35:13 +02:00
|
|
|
*
|
2024-12-13 03:21:03 +01:00
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License.
|
2024-07-17 23:35:13 +02:00
|
|
|
*/
|
|
|
|
|
|
|
|
#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"
|
2025-01-03 19:49:29 +01:00
|
|
|
# include "NimBLELog.h"
|
|
|
|
|
|
|
|
static const char* LOG_TAG = "NimBLEAttValue";
|
2024-07-17 23:35:13 +02:00
|
|
|
|
|
|
|
// 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);
|
2025-01-03 19:49:29 +01:00
|
|
|
if (m_attr_value == nullptr) {
|
|
|
|
NIMBLE_LOGE(LOG_TAG, "Failed to calloc ctx");
|
|
|
|
}
|
2024-07-17 23:35:13 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Value constructor implementation.
|
2024-12-13 03:21:03 +01:00
|
|
|
NimBLEAttValue::NimBLEAttValue(const uint8_t* value, uint16_t len, uint16_t max_len) : NimBLEAttValue(len, max_len) {
|
2025-01-03 19:49:29 +01:00
|
|
|
if (m_attr_value != nullptr) {
|
|
|
|
memcpy(m_attr_value, value, len);
|
|
|
|
m_attr_len = len;
|
|
|
|
}
|
2024-07-17 23:35:13 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// 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);
|
2025-01-03 19:49:29 +01:00
|
|
|
if (res == nullptr) {
|
|
|
|
NIMBLE_LOGE(LOG_TAG, "Failed to realloc deepCopy");
|
|
|
|
return;
|
|
|
|
}
|
2024-07-17 23:35:13 +02:00
|
|
|
|
|
|
|
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) {
|
2025-01-03 19:49:29 +01:00
|
|
|
NIMBLE_LOGE(LOG_TAG, "val > max, len=%u, max=%u", len, m_attr_max_len);
|
2024-07-17 23:35:13 +02:00
|
|
|
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);
|
2025-01-03 19:49:29 +01:00
|
|
|
if (res == nullptr) {
|
|
|
|
NIMBLE_LOGE(LOG_TAG, "Failed to realloc append");
|
|
|
|
return *this;
|
|
|
|
}
|
2024-07-17 23:35:13 +02:00
|
|
|
|
|
|
|
# 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;
|
|
|
|
}
|
|
|
|
|
2025-01-03 19:49:29 +01:00
|
|
|
uint8_t NimBLEAttValue::operator[](int pos) const {
|
|
|
|
NIMBLE_CPP_DEBUG_ASSERT(pos < m_attr_len);
|
|
|
|
if (pos >= m_attr_len) {
|
|
|
|
NIMBLE_LOGE(LOG_TAG, "pos >= len, pos=%u, len=%u", pos, m_attr_len);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return m_attr_value[pos];
|
|
|
|
}
|
|
|
|
|
2024-07-17 23:35:13 +02:00
|
|
|
#endif // CONFIG_BT_ENABLED
|