feat(modem): Add enhanced URC observer API

This commit is contained in:
David Cermak
2025-09-04 10:46:30 +02:00
parent 134247d88f
commit 4889dd6fcb
7 changed files with 441 additions and 41 deletions

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -115,6 +115,42 @@ public:
{
command_cb.urc_handler = std::move(line_cb);
}
/**
* @brief Enhanced URC handler with buffer consumption control
* @param buffer_info Information about the current buffer state
* @return Information about how much of the buffer to consume
*/
struct UrcBufferInfo {
const uint8_t* buffer_start; // Start of entire buffer
size_t buffer_total_size; // Total buffer size
size_t processed_offset; // Offset of already processed data
size_t new_data_size; // Size of new data since last call
const uint8_t* new_data_start; // Pointer to start of new data
bool is_command_active; // Whether a command is currently waiting for response
};
enum class UrcConsumeResult {
CONSUME_NONE, // Don't consume anything, continue waiting
CONSUME_PARTIAL, // Consume only part of the buffer
CONSUME_ALL // Consume entire buffer
};
struct UrcConsumeInfo {
UrcConsumeResult result;
size_t consume_size; // How many bytes to consume (0 = none, SIZE_MAX = all)
};
typedef std::function<UrcConsumeInfo(const UrcBufferInfo &)> enhanced_urc_cb;
/**
* @brief Set enhanced URC callback with buffer consumption control
* @param enhanced_cb Enhanced callback that can control buffer consumption
*/
void set_enhanced_urc_cb(enhanced_urc_cb enhanced_cb)
{
command_cb.enhanced_urc_handler = std::move(enhanced_cb);
}
#endif
/**
@@ -171,6 +207,33 @@ private:
[[nodiscard]] bool exit_cmux(); /*!< Exit of CMUX mode and cleanup */
void exit_cmux_internal(); /*!< Cleanup CMUX */
#ifdef CONFIG_ESP_MODEM_URC_HANDLER
/**
* @brief Buffer state tracking for enhanced URC processing
*/
struct BufferState {
size_t total_processed = 0; /*!< Total bytes processed by URC handlers */
size_t last_urc_processed = 0; /*!< Last offset processed by URC */
bool command_waiting = false; /*!< Whether command is waiting for response */
size_t command_start_offset = 0; /*!< Where current command response started */
} buffer_state;
/**
* @brief Update buffer state when new data arrives
* @param new_data_size Size of new data added to buffer
*/
void update_buffer_state(size_t new_data_size);
/**
* @brief Create URC buffer information for enhanced handlers
* @param data Buffer data pointer
* @param consumed Already consumed bytes
* @param len New data length
* @return UrcBufferInfo structure with complete buffer context
*/
UrcBufferInfo create_urc_info(uint8_t* data, size_t consumed, size_t len);
#endif
Lock internal_lock{}; /*!< Locks DTE operations */
unique_buffer buffer; /*!< DTE buffer */
std::shared_ptr<CMux> cmux_term; /*!< Primary terminal for this DTE */
@@ -216,6 +279,7 @@ private:
struct command_cb {
#ifdef CONFIG_ESP_MODEM_URC_HANDLER
got_line_cb urc_handler {}; /*!< URC callback if enabled */
enhanced_urc_cb enhanced_urc_handler {}; /*!< Enhanced URC callback with consumption control */
#endif
static const size_t GOT_LINE = SignalGroup::bit0; /*!< Bit indicating response available */
got_line_cb got_line; /*!< Supplied command callback */
@@ -223,7 +287,7 @@ private:
char separator{}; /*!< Command reply separator (end of line/processing unit) */
command_result result{}; /*!< Command return code */
SignalGroup signal; /*!< Event group used to signal request-response operations */
bool process_line(uint8_t *data, size_t consumed, size_t len); /*!< Lets the processing callback handle one line (processing unit) */
bool process_line(uint8_t *data, size_t consumed, size_t len, DTE* dte = nullptr); /*!< Lets the processing callback handle one line (processing unit) */
bool wait_for_line(uint32_t time_ms) /*!< Waiting for command processing */
{
return signal.wait_any(command_cb::GOT_LINE, time_ms);