Merge pull request #620 from david-cermak/feat/modem_urc

[modem]: Add support for handling URC
This commit is contained in:
david-cermak
2024-09-17 09:54:15 +02:00
committed by GitHub
6 changed files with 56 additions and 37 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) {

View File

@ -1,6 +1,5 @@
idf_component_register(SRCS "pppd_test.cpp" idf_component_register(SRCS "pppd_test.cpp"
"NetworkDCE.cpp" "NetworkDCE.cpp"
INCLUDE_DIRS "$ENV{IDF_PATH}/tools/catch"
REQUIRES esp_modem) REQUIRES esp_modem)
set_target_properties(${COMPONENT_LIB} PROPERTIES set_target_properties(${COMPONENT_LIB} PROPERTIES

View File

@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Unlicense OR CC0-1.0 * SPDX-License-Identifier: Unlicense OR CC0-1.0
*/ */
@ -17,9 +17,6 @@
#include "freertos/FreeRTOS.h" #include "freertos/FreeRTOS.h"
#include "freertos/event_groups.h" #include "freertos/event_groups.h"
#define CATCH_CONFIG_MAIN
#include "catch.hpp"
static const char *TAG = "pppd_test"; static const char *TAG = "pppd_test";
static EventGroupHandle_t event_group = NULL; static EventGroupHandle_t event_group = NULL;
@ -76,6 +73,9 @@ esp_err_t modem_init_network(esp_netif_t *netif);
void modem_start_network(); void modem_start_network();
void modem_stop_network(); void modem_stop_network();
bool test_connect();
bool test_disconnect();
extern "C" void app_main(void) extern "C" void app_main(void)
{ {
@ -99,41 +99,27 @@ extern "C" void app_main(void)
#endif #endif
modem_start_network(); modem_start_network();
Catch::Session session;
int numFailed = session.run(); bool t1 = test_connect();
if (numFailed > 0) { bool t2 = test_disconnect();
ESP_LOGE(TAG, "Test FAILED!");
if (t1 && t2) {
ESP_LOGI(TAG, "All tests passed");
} else { } else {
ESP_LOGI(TAG, "Test passed!"); ESP_LOGE(TAG, "Test FAILED!");
} }
} }
TEST_CASE("Connect test", "[esp_modem]") bool test_connect() //("Connect test", "[esp_modem]")
{ {
EventBits_t b = xEventGroupWaitBits(event_group, 1, pdTRUE, pdFALSE, pdMS_TO_TICKS(15000)); EventBits_t b = xEventGroupWaitBits(event_group, 1, pdTRUE, pdFALSE, pdMS_TO_TICKS(15000));
CHECK(b == 1); return b == 1;
} }
TEST_CASE("Disconnection test", "[esp_modem]") bool test_disconnect() //("Disconnection test", "[esp_modem]")
{ {
modem_stop_network(); modem_stop_network();
EventBits_t b = xEventGroupWaitBits(event_group, 2, pdTRUE, pdFALSE, pdMS_TO_TICKS(15000)); EventBits_t b = xEventGroupWaitBits(event_group, 2, pdTRUE, pdFALSE, pdMS_TO_TICKS(15000));
CHECK(b == 2); return b == 2;
}
extern "C" {
static void handle(int nr)
{
ESP_LOGE(TAG, "Signal handler %d", nr);
}
_sig_func_ptr signal (int nr, _sig_func_ptr)
{
return handle;
}
} }