Replace NimBLEAttValue asserts with user defineable action.

* Adds the NIMBLE_CPP_DEBUG_ASSERT macro that calls a weak function to allow user defined action, defaults to critical error message and aborts.
* Adds a config option to disable asserts using the NIMBLE_CPP_DEBUG_ASSERT macro.
This commit is contained in:
h2zero 2024-07-04 10:49:09 -06:00 committed by h2zero
parent 44977cdcce
commit d9f5794b57
4 changed files with 41 additions and 10 deletions

13
Kconfig
View file

@ -33,7 +33,7 @@ config NIMBLE_CPP_ENABLE_RETURN_CODE_TEXT
Enabling this option will display return code values as text Enabling this option will display return code values as text
messages in the debug log. This will use approximately 8kB messages in the debug log. This will use approximately 8kB
of flash memory. of flash memory.
config NIMBLE_CPP_ENABLE_GAP_EVENT_CODE_TEXT config NIMBLE_CPP_ENABLE_GAP_EVENT_CODE_TEXT
bool "Show NimBLE gap events as text in debug log." bool "Show NimBLE gap events as text in debug log."
default "n" default "n"
@ -47,7 +47,7 @@ config NIMBLE_CPP_ENABLE_ADVERTISEMENT_TYPE_TEXT
default "n" default "n"
help help
Enabling this option will display advertisment types recieved Enabling this option will display advertisment types recieved
while scanning as text messages in the debug log. while scanning as text messages in the debug log.
This will use approximately 250 bytes of flash memory. This will use approximately 250 bytes of flash memory.
config NIMBLE_CPP_ATT_VALUE_TIMESTAMP_ENABLED config NIMBLE_CPP_ATT_VALUE_TIMESTAMP_ENABLED
@ -68,5 +68,12 @@ config NIMBLE_CPP_ATT_VALUE_INIT_LENGTH
when the constructor is called. This is also the size used when a remote when the constructor is called. This is also the size used when a remote
characteristic or descriptor is constructed before a value is read/notifed. characteristic or descriptor is constructed before a value is read/notifed.
Increasing this will reduce reallocations but increase memory footprint. Increasing this will reduce reallocations but increase memory footprint.
config NIMBLE_CPP_DEBUG_ASSERT_ENABLED
bool "Enable debug asserts."
default "n"
help
Enabling this option will add debug asserts to the NimBLE CPP library.
This will use approximately 1kB of flash memory.
endmenu endmenu

View file

@ -42,7 +42,6 @@
# error CONFIG_NIMBLE_CPP_ATT_VALUE_INIT_LENGTH cannot be less than 1; Range = 1 : 512 # error CONFIG_NIMBLE_CPP_ATT_VALUE_INIT_LENGTH cannot be less than 1; Range = 1 : 512
#endif #endif
/* Used to determine if the type passed to a template has a c_str() and length() method. */ /* Used to determine if the type passed to a template has a c_str() and length() method. */
template <typename T, typename = void, typename = void> template <typename T, typename = void, typename = void>
struct Has_c_str_len : std::false_type {}; struct Has_c_str_len : std::false_type {};
@ -267,7 +266,8 @@ public:
/** @brief Subscript operator */ /** @brief Subscript operator */
uint8_t operator [](int pos) const { uint8_t operator [](int pos) const {
assert(pos < m_attr_len && "out of range"); return m_attr_value[pos]; } NIMBLE_CPP_DEBUG_ASSERT(pos < m_attr_len);
return m_attr_value[pos]; }
/** @brief Operator; Get the value as a std::vector<uint8_t>. */ /** @brief Operator; Get the value as a std::vector<uint8_t>. */
operator std::vector<uint8_t>() const { operator std::vector<uint8_t>() const {
@ -312,7 +312,7 @@ public:
inline NimBLEAttValue::NimBLEAttValue(uint16_t init_len, uint16_t max_len) { inline NimBLEAttValue::NimBLEAttValue(uint16_t init_len, uint16_t max_len) {
m_attr_value = (uint8_t*)calloc(init_len + 1, 1); m_attr_value = (uint8_t*)calloc(init_len + 1, 1);
assert(m_attr_value && "No Mem"); NIMBLE_CPP_DEBUG_ASSERT(m_attr_value);
m_attr_max_len = std::min(BLE_ATT_ATTR_MAX_LEN, (int)max_len); m_attr_max_len = std::min(BLE_ATT_ATTR_MAX_LEN, (int)max_len);
m_attr_len = 0; m_attr_len = 0;
m_capacity = init_len; m_capacity = init_len;
@ -355,7 +355,7 @@ inline NimBLEAttValue& NimBLEAttValue::operator =(const NimBLEAttValue & source)
inline void NimBLEAttValue::deepCopy(const NimBLEAttValue & source) { inline void NimBLEAttValue::deepCopy(const NimBLEAttValue & source) {
uint8_t* res = (uint8_t*)realloc( m_attr_value, source.m_capacity + 1); uint8_t* res = (uint8_t*)realloc( m_attr_value, source.m_capacity + 1);
assert(res && "deepCopy: realloc failed"); NIMBLE_CPP_DEBUG_ASSERT(res);
ble_npl_hw_enter_critical(); ble_npl_hw_enter_critical();
m_attr_value = res; m_attr_value = res;
@ -390,7 +390,7 @@ inline bool NimBLEAttValue::setValue(const uint8_t *value, uint16_t len) {
res = (uint8_t*)realloc(m_attr_value, (len + 1)); res = (uint8_t*)realloc(m_attr_value, (len + 1));
m_capacity = len; m_capacity = len;
} }
assert(res && "setValue: realloc failed"); NIMBLE_CPP_DEBUG_ASSERT(res);
#if CONFIG_NIMBLE_CPP_ATT_VALUE_TIMESTAMP_ENABLED #if CONFIG_NIMBLE_CPP_ATT_VALUE_TIMESTAMP_ENABLED
time_t t = time(nullptr); time_t t = time(nullptr);
@ -425,7 +425,7 @@ inline NimBLEAttValue& NimBLEAttValue::append(const uint8_t *value, uint16_t len
res = (uint8_t*)realloc(m_attr_value, (new_len + 1)); res = (uint8_t*)realloc(m_attr_value, (new_len + 1));
m_capacity = new_len; m_capacity = new_len;
} }
assert(res && "append: realloc failed"); NIMBLE_CPP_DEBUG_ASSERT(res);
#if CONFIG_NIMBLE_CPP_ATT_VALUE_TIMESTAMP_ENABLED #if CONFIG_NIMBLE_CPP_ATT_VALUE_TIMESTAMP_ENABLED
time_t t = time(nullptr); time_t t = time(nullptr);

View file

@ -1259,4 +1259,16 @@ void NimBLEDevice::setCustomGapHandler(gap_event_handler handler) {
} // setCustomGapHandler } // setCustomGapHandler
#endif // CONFIG_BT_ENABLED #if CONFIG_NIMBLE_CPP_DEBUG_ASSERT_ENABLED || __DOXYGEN__
/**
* @brief Debug assert - weak function.
* @param [in] file The file where the assert occurred.
* @param [in] line The line number where the assert occurred.
*/
void nimble_cpp_assert(const char *file, unsigned line) {
NIMBLE_LOGC("", "Assertion failed at %s:%u\n", file, line);
abort();
}
#endif // CONFIG_NIMBLE_CPP_DEBUG_ASSERT_ENABLED
#endif // CONFIG_BT_ENABLED

View file

@ -32,6 +32,18 @@
# endif # endif
#endif #endif
#if CONFIG_NIMBLE_CPP_DEBUG_ASSERT_ENABLED && !defined NDEBUG
void nimble_cpp_assert(const char *file, unsigned line) __attribute((weak, noreturn));
# define NIMBLE_ATT_VAL_FILE (__builtin_strrchr(__FILE__, '/') ? \
__builtin_strrchr (__FILE__, '/') + 1 : __FILE__)
# define NIMBLE_CPP_DEBUG_ASSERT(cond) \
if (!(cond)) { \
nimble_cpp_assert(NIMBLE_ATT_VAL_FILE, __LINE__); \
}
#else
# define NIMBLE_CPP_DEBUG_ASSERT(cond) (void(0))
#endif
#endif /* CONFIG_BT_ENABLED */ #endif /* CONFIG_BT_ENABLED */
#ifdef _DOXYGEN_ #ifdef _DOXYGEN_