Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 0 additions & 7 deletions Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -197,11 +197,4 @@ config NIMBLE_CPP_DEBUG_ASSERT_ENABLED
Enabling this option will add debug asserts to the NimBLE CPP library.
This will use approximately 1kB of flash memory.

config NIMBLE_CPP_FREERTOS_TASK_BLOCK_BIT
int "FreeRTOS task block bit."
default 31
help
Configure the bit to set in the task notification value when a task is blocked waiting for an event.
This should be set to a bit that is not used by other notifications in the system.

endmenu
15 changes: 13 additions & 2 deletions src/NimBLEAddress.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,19 @@ NimBLEAddress::NimBLEAddress(const std::string& addr, uint8_t type) {
} // NimBLEAddress

/**
* @brief Constructor for compatibility with bluedroid esp library using native ESP representation.
* @param [in] address A uint8_t[6] or esp_bd_addr_t containing the address.
* @brief Constructor accepting a 6-byte MSB-first BLE address (Bluedroid `esp_bd_addr_t` layout).
* @details The input bytes are stored internally in LSB-first wire
* order (NimBLE's `ble_addr_t.val` layout), so this constructor
* **reverses** the input. If you already have LSB-first wire bytes —
* e.g. straight out of a NimBLE callback's `ble_addr_t` — use the
* `NimBLEAddress(ble_addr_t)` constructor instead (it stores them
* as-is). If you have the address as a hex integer (e.g.
* `0xa4c1385def16` for `"a4:c1:38:5d:ef:16"`), use
* `NimBLEAddress(const uint64_t&, uint8_t)`.
* @param [in] address Six bytes in MSB-first order
* (`{0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff}` for
* `"aa:bb:cc:dd:ee:ff"`). Compatible with
* Bluedroid's `esp_bd_addr_t`.
* @param [in] type The type of the address should be one of:
* * BLE_ADDR_PUBLIC (0)
* * BLE_ADDR_RANDOM (1)
Expand Down
69 changes: 54 additions & 15 deletions src/NimBLEAttValue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,49 @@
#include "NimBLEAttValue.h"
#if CONFIG_BT_NIMBLE_ENABLED

# ifdef USING_NIMBLE_ARDUINO_HEADERS
# include "nimble/nimble/include/nimble/nimble_npl.h"
# else
# include "nimble/nimble_npl.h"
# endif

# include "NimBLEUtils.h"
# include "NimBLELog.h"

# if defined(__ARM_ARCH_6M__)
// Cortex-M0/M0+ has no LDREX/STREX, so GCC emits libcalls for 4 byte atomic read-modify-write
// operations that are not provided by libgcc. Implement them by briefly masking interrupts.
extern "C" {
unsigned int __atomic_fetch_add_4(volatile void* ptr, unsigned int val, int) {
volatile unsigned int* p = static_cast<volatile unsigned int*>(ptr);
unsigned int primask;
__asm volatile("mrs %0, primask\n\tcpsid i" : "=r"(primask)::"memory");
unsigned int old = *p;
*p = old + val;
__asm volatile("msr primask, %0" ::"r"(primask) : "memory");
return old;
}

unsigned int __atomic_fetch_sub_4(volatile void* ptr, unsigned int val, int) {
volatile unsigned int* p = static_cast<volatile unsigned int*>(ptr);
unsigned int primask;
__asm volatile("mrs %0, primask\n\tcpsid i" : "=r"(primask)::"memory");
unsigned int old = *p;
*p = old - val;
__asm volatile("msr primask, %0" ::"r"(primask) : "memory");
return old;
}

unsigned char __atomic_exchange_1(volatile void* ptr, unsigned char val, int) {
volatile unsigned char* p = static_cast<volatile unsigned char*>(ptr);
unsigned int primask;
__asm volatile("mrs %0, primask\n\tcpsid i" : "=r"(primask)::"memory");
unsigned char old = *p;
*p = val;
__asm volatile("msr primask, %0" ::"r"(primask) : "memory");
return old;
}
}
# endif

static const char* LOG_TAG = "NimBLEAttValue";
ble_npl_mutex NimBLEAttValue::Lock::m_mutex{};
std::atomic<bool> NimBLEAttValue::Lock::m_initialized{false};
std::atomic<int> NimBLEAttValue::Lock::m_activeCount{0};

// Default constructor implementation.
NimBLEAttValue::NimBLEAttValue(uint16_t init_len, uint16_t max_len)
Expand Down Expand Up @@ -64,6 +97,7 @@ NimBLEAttValue::~NimBLEAttValue() {
// Move assignment operator implementation.
NimBLEAttValue& NimBLEAttValue::operator=(NimBLEAttValue&& source) {
if (this != &source) {
Lock lock;
free(m_attr_value);
m_attr_value = source.m_attr_value;
m_attr_max_len = source.m_attr_max_len;
Expand All @@ -85,26 +119,27 @@ NimBLEAttValue& NimBLEAttValue::operator=(const NimBLEAttValue& source) {
}

// Copy all the data from the source object to this object, including allocated space.
void NimBLEAttValue::deepCopy(const NimBLEAttValue& source) {
bool NimBLEAttValue::deepCopy(const NimBLEAttValue& source) {
Lock lock;
uint8_t* res = static_cast<uint8_t*>(realloc(m_attr_value, source.m_capacity + 1));
NIMBLE_CPP_DEBUG_ASSERT(res);
if (res == nullptr) {
NIMBLE_LOGE(LOG_TAG, "Failed to realloc deepCopy");
return;
return false;
}

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);
return true;
}

// Set the value of the attribute.
bool NimBLEAttValue::setValue(const uint8_t* value, uint16_t len) {
Lock lock;
m_attr_len = 0; // Just set the value length to 0 and append instead of repeating code.
m_attr_value[0] = '\0'; // Set the first byte to 0 incase the len of the new value is 0.
append(value, len);
Expand All @@ -113,6 +148,7 @@ bool NimBLEAttValue::setValue(const uint8_t* value, uint16_t len) {

// Append the new data, allocate as necessary.
NimBLEAttValue& NimBLEAttValue::append(const uint8_t* value, uint16_t len) {
Lock lock;
if (len == 0) {
return *this;
}
Expand All @@ -124,34 +160,37 @@ NimBLEAttValue& NimBLEAttValue::append(const uint8_t* value, uint16_t len) {

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;
bool grow = new_len > m_capacity;
if (grow) {
res = static_cast<uint8_t*>(realloc(m_attr_value, (new_len + 1)));
}
NIMBLE_CPP_DEBUG_ASSERT(res);
if (res == nullptr) {
NIMBLE_LOGE(LOG_TAG, "Failed to realloc append");
return *this;
}

if (grow) {
m_capacity = new_len;
}

# if MYNEWT_VAL(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;
}

uint8_t NimBLEAttValue::operator[](int pos) const {
Lock lock;
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);
Expand Down
Loading
Loading