From d9f5794b577f3fda3a55c6f646e90658f1060967 Mon Sep 17 00:00:00 2001 From: h2zero Date: Thu, 4 Jul 2024 10:49:09 -0600 Subject: [PATCH] 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. --- Kconfig | 13 ++++++++++--- src/NimBLEAttValue.h | 12 ++++++------ src/NimBLEDevice.cpp | 14 +++++++++++++- src/nimconfig.h | 12 ++++++++++++ 4 files changed, 41 insertions(+), 10 deletions(-) diff --git a/Kconfig b/Kconfig index 730f8cd..0878176 100644 --- a/Kconfig +++ b/Kconfig @@ -33,7 +33,7 @@ config NIMBLE_CPP_ENABLE_RETURN_CODE_TEXT Enabling this option will display return code values as text messages in the debug log. This will use approximately 8kB of flash memory. - + config NIMBLE_CPP_ENABLE_GAP_EVENT_CODE_TEXT bool "Show NimBLE gap events as text in debug log." default "n" @@ -47,7 +47,7 @@ config NIMBLE_CPP_ENABLE_ADVERTISEMENT_TYPE_TEXT default "n" help 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. 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 characteristic or descriptor is constructed before a value is read/notifed. 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 diff --git a/src/NimBLEAttValue.h b/src/NimBLEAttValue.h index 786bc8b..cc8599a 100644 --- a/src/NimBLEAttValue.h +++ b/src/NimBLEAttValue.h @@ -42,7 +42,6 @@ # error CONFIG_NIMBLE_CPP_ATT_VALUE_INIT_LENGTH cannot be less than 1; Range = 1 : 512 #endif - /* Used to determine if the type passed to a template has a c_str() and length() method. */ template struct Has_c_str_len : std::false_type {}; @@ -267,7 +266,8 @@ public: /** @brief Subscript operator */ 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. */ operator std::vector() const { @@ -312,7 +312,7 @@ public: inline NimBLEAttValue::NimBLEAttValue(uint16_t init_len, uint16_t max_len) { 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_len = 0; m_capacity = init_len; @@ -355,7 +355,7 @@ inline NimBLEAttValue& NimBLEAttValue::operator =(const NimBLEAttValue & source) inline void NimBLEAttValue::deepCopy(const NimBLEAttValue & source) { 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(); 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)); m_capacity = len; } - assert(res && "setValue: realloc failed"); + NIMBLE_CPP_DEBUG_ASSERT(res); #if CONFIG_NIMBLE_CPP_ATT_VALUE_TIMESTAMP_ENABLED 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)); m_capacity = new_len; } - assert(res && "append: realloc failed"); + NIMBLE_CPP_DEBUG_ASSERT(res); #if CONFIG_NIMBLE_CPP_ATT_VALUE_TIMESTAMP_ENABLED time_t t = time(nullptr); diff --git a/src/NimBLEDevice.cpp b/src/NimBLEDevice.cpp index a746d38..99b5410 100644 --- a/src/NimBLEDevice.cpp +++ b/src/NimBLEDevice.cpp @@ -1259,4 +1259,16 @@ void NimBLEDevice::setCustomGapHandler(gap_event_handler handler) { } // 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 \ No newline at end of file diff --git a/src/nimconfig.h b/src/nimconfig.h index 9c19031..d96e37c 100644 --- a/src/nimconfig.h +++ b/src/nimconfig.h @@ -32,6 +32,18 @@ # 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 */ #ifdef _DOXYGEN_