feat(modem): Add support for handling URC

Closes https://github.com/espressif/esp-protocols/issues/180
This commit is contained in:
David Cermak
2024-07-24 09:33:57 +02:00
parent d2880418e5
commit 1b6a3b3b75
4 changed files with 41 additions and 7 deletions

View File

@@ -67,7 +67,13 @@ menu "esp-modem"
int "Size in bytes for response from AT commands returning textual values (C-API)" int "Size in bytes for response from AT commands returning textual values (C-API)"
default 128 default 128
help help
Some AT commands returns textrual values which C-API copy as c-string to user allocated space, Some AT commands returns textual values which C-API copy as c-string to user allocated space,
it also truncates the output data to this size. Increase this if some AT answers are truncated. it also truncates the output data to this size. Increase this if some AT answers are truncated.
config ESP_MODEM_URC_HANDLER
bool "Enable support for adding URC handler"
default n
help
If enabled, APIs to add URC handler are available
endmenu endmenu

View File

@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -89,6 +89,13 @@ public:
return dte->recover(); return dte->recover();
} }
#ifdef CONFIG_ESP_MODEM_URC_HANDLER
void set_urc(got_line_cb on_read_cb)
{
dte->set_urc_cb(on_read_cb);
}
#endif
protected: protected:
std::shared_ptr<DTE> dte; std::shared_ptr<DTE> dte;
std::shared_ptr<SpecificModule> device; std::shared_ptr<SpecificModule> device;

View File

@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -94,6 +94,17 @@ public:
*/ */
void set_error_cb(std::function<void(terminal_error err)> f); void set_error_cb(std::function<void(terminal_error err)> f);
#ifdef CONFIG_ESP_MODEM_URC_HANDLER
/**
* @brief Allow setting a line callback for all incoming data
* @param line_cb
*/
void set_urc_cb(got_line_cb line_cb)
{
command_cb.urc_handler = std::move(line_cb);
}
#endif
/** /**
* @brief Sets the DTE to desired mode (Command/Data/Cmux) * @brief Sets the DTE to desired mode (Command/Data/Cmux)
* @param m Desired operation mode * @param m Desired operation mode
@@ -191,6 +202,9 @@ private:
* @brief This abstracts command callback processing and implements its locking, signaling of completion and timeouts. * @brief This abstracts command callback processing and implements its locking, signaling of completion and timeouts.
*/ */
struct command_cb { struct command_cb {
#ifdef CONFIG_ESP_MODEM_URC_HANDLER
got_line_cb urc_handler {}; /*!< URC callback if enabled */
#endif
static const size_t GOT_LINE = SignalGroup::bit0; /*!< Bit indicating response available */ static const size_t GOT_LINE = SignalGroup::bit0; /*!< Bit indicating response available */
got_line_cb got_line; /*!< Supplied command callback */ got_line_cb got_line; /*!< Supplied command callback */
Lock line_lock{}; /*!< Command callback locking mechanism */ Lock line_lock{}; /*!< Command callback locking mechanism */

View File

@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -50,9 +50,11 @@ void DTE::set_command_callbacks()
{ {
primary_term->set_read_cb([this](uint8_t *data, size_t len) { primary_term->set_read_cb([this](uint8_t *data, size_t len) {
Scoped<Lock> l(command_cb.line_lock); Scoped<Lock> l(command_cb.line_lock);
if (command_cb.got_line == nullptr) { #ifndef CONFIG_ESP_MODEM_URC_HANDLER
return false; if (command_cb.got_line == nullptr || command_cb.result != command_result::TIMEOUT) {
return false; // this line has been processed already (got OK or FAIL previously)
} }
#endif
if (data) { if (data) {
// For terminals which post data directly with the callback (CMUX) // For terminals which post data directly with the callback (CMUX)
// we cannot defragment unless we allocate, but // we cannot defragment unless we allocate, but
@@ -347,9 +349,14 @@ void DTE::on_read(got_line_cb on_read_cb)
bool DTE::command_cb::process_line(uint8_t *data, size_t consumed, size_t len) bool DTE::command_cb::process_line(uint8_t *data, size_t consumed, size_t len)
{ {
if (result != command_result::TIMEOUT) { #ifdef CONFIG_ESP_MODEM_URC_HANDLER
if (urc_handler) {
urc_handler(data, consumed + len);
}
if (result != command_result::TIMEOUT || got_line == nullptr) {
return false; // this line has been processed already (got OK or FAIL previously) return false; // this line has been processed already (got OK or FAIL previously)
} }
#endif
if (memchr(data + consumed, separator, len)) { if (memchr(data + consumed, separator, len)) {
result = got_line(data, consumed + len); result = got_line(data, consumed + len);
if (result == command_result::OK || result == command_result::FAIL) { if (result == command_result::OK || result == command_result::FAIL) {