esp_iot_framework  v0.1.0-alpha
© 2026 AmakeSasha, distributed under a license Apache-2.0
Checkers

Sequential error handling and parameter validation macros. More...

Macros

#define EIF_IF_OK_CHECK_NOT_NULL(m_result, m_ptr, m_error)
 Validates a pointer variable if the current execution state is successful. More...
 
#define EIF_IF_OK_CHECK_ESP_ERR_T(m_result, m_expr, m_format, ...)
 Executes and validates an ESP-IDF expression sequentially. More...
 
#define EIF_IF_OK_CHECK_CONDITION(m_ret, m_cond, m_err, m_format, ...)
 Checks a condition and sets an error status if the condition is true, only when the current status is OK. More...
 
#define EIF_IF_OK_CHECK_MBEDTLS_ERR(m_ret, m_expr, func_name)
 Executes and validates an MbedTLS expression sequentially. More...
 

Detailed Description

These macros execute code in chains using a status variable (m_result). If a previous operation failed, subsequent steps are skipped, avoiding deeply nested if-else statements while maintaining strict MISRA C compliance (without goto and return in the middle of the function).

Macro Definition Documentation

◆ EIF_IF_OK_CHECK_NOT_NULL

#define EIF_IF_OK_CHECK_NOT_NULL (   m_result,
  m_ptr,
  m_error 
)
Value:
do { \
if ((m_result) == (ESP_OK)) { \
if ((m_ptr) == NULL) { \
/* @deviation [Rule 20.10] The '#' stringification operator is used
* exclusively for diagnostic logging to evaluate the parameter
* identifier. The expansion evaluates strictly to a well-formed,
* immutable string literal, completely eliminating risks of side
* effects or undefined behavior. */ \
EIF_LOG_E("PARAMETER_IS_NULL: '%s'", #m_ptr); \
(m_result) = (m_error); \
} \
} \
} while(false)

This macro performs a conditional validation check. It verifies whether the provided pointer m_ptr is NULL, but only if m_result currently equals ESP_OK. If the pointer is NULL, the status variable m_result is set to m_error, and it logs a critical error containing the stringified name of the failed parameter. If m_result already contains an error, the check is skipped entirely.

Parameters
[in,out]m_resultVariable holding the active sequence status (esp_err_t).
[in]m_ptrThe pointer identifier or reference to be checked against NULL.
[in]m_errorThe custom error status code to assign to m_result if validation fails (type esp_err_t).

Example of use:

#include <esp_log.h>
#include <esp_wifi.h>
#include <esp_iot_framework_core_macros.h>
esp_err_t wifi_quick_init(const wifi_config_t *cfg) {
EIF_TAG_WITH_UNUSED "WIFI_INIT";
esp_err_t ret = ESP_OK;
// If any macro fails, 'ret' changes and all subsequent macros are skipped.
EIF_IF_OK_CHECK_NOT_NULL(ret, cfg, ESP_ERR_INVALID_ARG);
EIF_IF_OK_CHECK_ESP_ERR_T(ret, esp_wifi_set_mode(WIFI_MODE_STA),
"Set mode failed");
EIF_IF_OK_CHECK_ESP_ERR_T(ret, esp_wifi_set_config(WIFI_IF_STA, (wifi_config_t*)cfg),
"Set config failed");
EIF_IF_OK_CHECK_ESP_ERR_T(ret, esp_wifi_start(),
"Start failed");
return ret;
}
#define EIF_IF_OK_CHECK_ESP_ERR_T(m_result, m_expr, m_format,...)
Executes and validates an ESP-IDF expression sequentially.
Definition: esp_iot_framework_core_macros.h:420
#define EIF_IF_OK_CHECK_NOT_NULL(m_result, m_ptr, m_error)
Validates a pointer variable if the current execution state is successful.
Definition: esp_iot_framework_core_macros.h:358
#define EIF_TAG_WITH_UNUSED
Helper to define a local logging 'TAG' identifier.
Definition: esp_iot_framework_core_macros.h:88

◆ EIF_IF_OK_CHECK_ESP_ERR_T

#define EIF_IF_OK_CHECK_ESP_ERR_T (   m_result,
  m_expr,
  m_format,
  ... 
)
Value:
do { \
if ((m_result) == (ESP_OK)) { \
(m_result) = (m_expr); \
if ((m_result) != (ESP_OK)) { \
const char* l_err_name = esp_err_to_name((m_result)); \
EIF_LOG_E("%s: " m_format, \
((l_err_name != NULL) ? l_err_name : "UNKNOWN_ERROR") \
/* @deviation [Rule 20.10] The '##' token pasting operator is
* utilized strictly for the compiler-specific comma deletion
* extension. The expansion is completely deterministic and
* guaranteed to yield valid, predictable syntax without risk
* of expression corruption. */ \
, ##__VA_ARGS__); \
} \
} \
} while(false)

If m_result equals ESP_OK, this macro executes m_expr and writes its return status directly into m_result. On failure (result is not ESP_OK), it extracts the error name via esp_err_to_name() and logs a critical error prefixed with that name. If m_result is already an error state (is not ESP_OK), m_expr is skipped entirely.

Parameters
[in,out]m_resultStatus variable (esp_err_t). Checked before execution; overwritten with the return value of m_expr.
[in]m_exprThe function call or expression returning esp_err_t.
[in]m_formatPrintf-compliant format string for custom error details.
[in]...Optional variadic format arguments matching the format string.

Example of use:

#include <esp_log.h>
#include <esp_wifi.h>
#include <esp_iot_framework_core_macros.h>
esp_err_t wifi_quick_init(const wifi_config_t *cfg) {
EIF_TAG_WITH_UNUSED "WIFI_INIT";
esp_err_t ret = ESP_OK;
// If any macro fails, 'ret' changes and all subsequent macros are skipped.
EIF_IF_OK_CHECK_NOT_NULL(ret, cfg, ESP_ERR_INVALID_ARG);
EIF_IF_OK_CHECK_ESP_ERR_T(ret, esp_wifi_set_mode(WIFI_MODE_STA),
"Set mode failed");
EIF_IF_OK_CHECK_ESP_ERR_T(ret, esp_wifi_set_config(WIFI_IF_STA, (wifi_config_t*)cfg),
"Set config failed");
EIF_IF_OK_CHECK_ESP_ERR_T(ret, esp_wifi_start(),
"Start failed");
return ret;
}

◆ EIF_IF_OK_CHECK_CONDITION

#define EIF_IF_OK_CHECK_CONDITION (   m_ret,
  m_cond,
  m_err,
  m_format,
  ... 
)
Value:
do { \
if ((m_ret) == ESP_OK) { \
if ((m_cond)) { \
/* @deviation [Rule 20.10] The '##' token pasting operator is
* used here to delete the comma when '__VA_ARGS__' is empty.
* This is a necessary compiler-specific extension for
* variadic logging. Compilation is impossible without '##'. */ \
EIF_LOG_E(m_format, ##__VA_ARGS__); \
(m_ret) = (m_err); \
} \
} \
} while(false)

If m_ret equals ESP_OK, this macro evaluates m_cond. If the condition evaluates to true, it logs a critical error using the provided message (m_info) and sets m_ret to the specified error code (m_err). If m_ret is already in an error state (not ESP_OK), the condition check and logging are skipped entirely.

This macro is useful for validating preconditions (e.g., null checks, range checks) that must be satisfied before proceeding with further operations.

Parameters
[in,out]m_retStatus variable (esp_err_t). Checked before evaluation; overwritten with m_err if m_cond is true.
[in]m_condThe condition to evaluate. Must be an expression that can be interpreted as boolean (true/false).
[in]m_errThe error code (esp_err_t) to assign to m_ret if m_cond is true.
[in]m_formatPrintf-compliant format string for custom error details.
[in]...Optional variadic format arguments matching the format string.

Example of use:

#include <esp_log.h>
#include <esp_iot_framework_core_macros.h>
esp_err_t process_data(const char* data, size_t length) {
EIF_TAG_WITH_UNUSED "PROCESS_DATA";
esp_err_t ret = ESP_OK;
// Check for invalid arguments only if no previous error occurred
EIF_IF_OK_CHECK_CONDITION(ret, data == NULL, ESP_ERR_INVALID_ARG,
"Data pointer is NULL");
EIF_IF_OK_CHECK_CONDITION(ret, length == 0, ESP_ERR_INVALID_SIZE,
"Data length is zero");
if (ret == ESP_OK) {
// Proceed with processing only if all checks passed
ret = perform_actual_processing(data, length);
if (ret != ESP_OK) {
EIF_LOG_E("Processing failed: %s", esp_err_to_name(ret));
}
}
return ret;
}
#define EIF_IF_OK_CHECK_CONDITION(m_ret, m_cond, m_err, m_format,...)
Checks a condition and sets an error status if the condition is true, only when the current status is...
Definition: esp_iot_framework_core_macros.h:494
#define EIF_LOG_E(...)
Logs an error message using the ESP_LOGE severity.
Definition: esp_iot_framework_core_macros.h:221

◆ EIF_IF_OK_CHECK_MBEDTLS_ERR

#define EIF_IF_OK_CHECK_MBEDTLS_ERR (   m_ret,
  m_expr,
  func_name 
)
Value:
do { \
if ((m_ret) == (0)) { \
(m_ret) = (m_expr); \
if ((m_ret) != 0) { \
char err_buf[100] = {0}; \
mbedtls_strerror((m_ret), err_buf, sizeof(err_buf)); \
EIF_LOG_E("MbedTLS %s failed: %s (-0x%04x)", \
(func_name), err_buf, -(m_ret)); \
} \
} \
} while(false)
Note
Only available if the Kconfig option CONFIG_EIF_ENABLE_TLS is enabled.

This macro operates similarly to EIF_IF_OK_CHECK_ESP_ERR_T, but is specifically designed for the MbedTLS library, which uses int (where 0 is success and negative values are errors) instead of esp_err_t.

If m_ret equals 0, it executes m_expr and stores the result back in m_ret. On failure, it converts the MbedTLS error code into a human-readable string using mbedtls_strerror() and logs it along with the absolute hex value and func_name.

Note
The variable passed to m_ret must be of type int, NOT esp_err_t. Additionally, human-readable error strings require CONFIG_MBEDTLS_ERROR_C to be enabled in the project configuration. Otherwise, mbedtls_strerror might output a generic or empty string.
Parameters
[in,out]m_retStatus variable (int). Checked before execution; overwritten with the return value of m_expr.
[in]m_exprThe MbedTLS function call returning an int.
[in]func_nameString literal representing the operation name (for logging).

Example of use:

#include <esp_log.h>
#include <mbedtls/ssl.h>
#include <esp_iot_framework_core_macros.h>
int open_secure_socket(mbedtls_ssl_context *ssl) {
EIF_TAG_WITH_UNUSED "TLS_WRAP";
int ret = 0; // MbedTLS uses int
EIF_IF_OK_CHECK_MBEDTLS_ERR(ret, mbedtls_ssl_session_reset(ssl), "Session reset");
EIF_IF_OK_CHECK_MBEDTLS_ERR(ret, mbedtls_ssl_handshake(ssl), "Handshake");
return ret;
}
#define EIF_IF_OK_CHECK_MBEDTLS_ERR(m_ret, m_expr, func_name)
Executes and validates an MbedTLS expression sequentially.
Definition: esp_iot_framework_core_macros.h:558