diff --git a/esp_modem/examples/modem_console/main/console_helper.cpp b/esp_modem/examples/modem_console/main/console_helper.cpp index 4c32ccb41..90c61bd86 100644 --- a/esp_modem/examples/modem_console/main/console_helper.cpp +++ b/esp_modem/examples/modem_console/main/console_helper.cpp @@ -12,13 +12,13 @@ static const char *TAG = "modem_console_helper"; -ConsoleCommand::ConsoleCommand(const char* command, const char* help, std::vector& args, std::function f): +ConsoleCommand::ConsoleCommand(const char* command, const char* help, const std::vector& args, std::function f): func(std::move(f)) { RegisterCommand(command, help, args); } -void ConsoleCommand::RegisterCommand(const char* command, const char* help, std::vector& args) +void ConsoleCommand::RegisterCommand(const char* command, const char* help, const std::vector& args) { assert(last_command <= MAX_REPEAT_NR); void * common_arg = nullptr; diff --git a/esp_modem/examples/modem_console/main/console_helper.hpp b/esp_modem/examples/modem_console/main/console_helper.hpp index f7c2475a4..3175a856a 100644 --- a/esp_modem/examples/modem_console/main/console_helper.hpp +++ b/esp_modem/examples/modem_console/main/console_helper.hpp @@ -53,7 +53,7 @@ public: RegisterCommand(command, help, args); } - explicit ConsoleCommand(const char* command, const char* help, std::vector& args, std::function f); + explicit ConsoleCommand(const char* command, const char* help, const std::vector& args, std::function f); int get_count(int index); template int get_count_of(CommandArgs T::*member) { return get_count(index_arg(member)); } template std::string get_string_of(CommandArgs T::*member) { return get_string(index_arg(member)); } @@ -63,7 +63,7 @@ public: int get_int(int index); private: - void RegisterCommand(const char* command, const char* help, std::vector& args); + void RegisterCommand(const char* command, const char* help, const std::vector& args); template static constexpr size_t index_arg(CommandArgs T::*member) { return ((uint8_t *)&((T*)nullptr->*member) - (uint8_t *)nullptr)/sizeof(CommandArgs); } std::function func; diff --git a/esp_modem/examples/modem_console/main/modem_console_main.cpp b/esp_modem/examples/modem_console/main/modem_console_main.cpp index 67d8388ce..baab7a1e1 100644 --- a/esp_modem/examples/modem_console/main/modem_console_main.cpp +++ b/esp_modem/examples/modem_console/main/modem_console_main.cpp @@ -30,7 +30,6 @@ static esp_console_repl_t *s_repl = nullptr; using namespace esp_modem; - #define CHECK_ERR(cmd, success_action) do { \ auto err = cmd; \ if (err == command_result::OK) { \ @@ -49,9 +48,8 @@ extern "C" void app_main(void) // init the DTE esp_modem_dte_config_t dte_config = ESP_MODEM_DTE_DEFAULT_CONFIG(); - dte_config.pattern_queue_size = 100; - dte_config.event_task_stack_size = 4096; - dte_config.event_task_priority = 15; + dte_config.uart_config.event_task_stack_size = 4096; + dte_config.uart_config.event_task_priority = 15; esp_netif_config_t ppp_netif_config = ESP_NETIF_DEFAULT_PPP(); esp_netif_t *esp_netif = esp_netif_new(&ppp_netif_config); @@ -70,12 +68,11 @@ extern "C" void app_main(void) modem_console_register_http(); modem_console_register_ping(); - const struct SetModeArgs { SetModeArgs(): mode(STR1, nullptr, nullptr, "", "PPP or CMD") {} CommandArgs mode; } set_mode_args; - ConsoleCommand SetModeParser("set_mode", "sets modem mode", &set_mode_args, sizeof(set_mode_args), [&](ConsoleCommand *c){ + const ConsoleCommand SetModeParser("set_mode", "sets modem mode", &set_mode_args, sizeof(set_mode_args), [&](ConsoleCommand *c){ if (c->get_count_of(&SetModeArgs::mode)) { auto mode = c->get_string_of(&SetModeArgs::mode); if (mode == "CMD") { @@ -96,7 +93,7 @@ extern "C" void app_main(void) SetPinArgs(): pin(STR1, nullptr, nullptr, "", "PIN") {} CommandArgs pin; } set_pin_args; - ConsoleCommand SetPinParser("set_pin", "sets SIM card PIN", &set_pin_args, sizeof(set_pin_args), [&](ConsoleCommand *c){ + const ConsoleCommand SetPinParser("set_pin", "sets SIM card PIN", &set_pin_args, sizeof(set_pin_args), [&](ConsoleCommand *c){ if (c->get_count_of(&SetPinArgs::pin)) { auto pin = c->get_string_of(&SetPinArgs::pin); ESP_LOGI(TAG, "Setting pin=%s...", pin.c_str()); @@ -111,8 +108,8 @@ extern "C" void app_main(void) return 0; }); - std::vector no_args; - ConsoleCommand ReadPinArgs("read_pin", "checks if SIM is unlocked", no_args, [&](ConsoleCommand *c){ + const std::vector no_args; + const ConsoleCommand ReadPinArgs("read_pin", "checks if SIM is unlocked", no_args, [&](ConsoleCommand *c){ bool pin_ok; ESP_LOGI(TAG, "Checking pin..."); auto err = dce->read_pin(pin_ok); @@ -125,7 +122,7 @@ extern "C" void app_main(void) return 0; }); - ConsoleCommand GetModuleName("get_module_name", "reads the module name", no_args, [&](ConsoleCommand *c){ + const ConsoleCommand GetModuleName("get_module_name", "reads the module name", no_args, [&](ConsoleCommand *c){ std::string module_name; ESP_LOGI(TAG, "Reading module name..."); CHECK_ERR(dce->get_module_name(module_name), ESP_LOGI(TAG, "OK. Module name: %s", module_name.c_str())); @@ -167,14 +164,15 @@ extern "C" void app_main(void) CHECK_ERR(dce->get_signal_quality(rssi, ber), ESP_LOGI(TAG, "OK. rssi=%d, ber=%d", rssi, ber)); }); signal_group exit_signal; - const ConsoleCommand ExitConsole("exit", "exit the console appliation", no_args, [&](ConsoleCommand *c){ + const ConsoleCommand ExitConsole("exit", "exit the console application", no_args, [&](ConsoleCommand *c){ ESP_LOGI(TAG, "Exiting..."); exit_signal.set(1); s_repl->del(s_repl); - return true; + return 0; }); // start console REPL ESP_ERROR_CHECK(esp_console_start_repl(s_repl)); + ESP_LOGI(TAG, "Exiting...%d", esp_get_free_heap_size()); // wait till for exit exit_signal.wait_any(1, UINT32_MAX); } diff --git a/esp_modem/examples/simple_cxx_client/main/simple_client.cpp b/esp_modem/examples/simple_cxx_client/main/simple_client.cpp index 729b8d5c5..4cfc42245 100644 --- a/esp_modem/examples/simple_cxx_client/main/simple_client.cpp +++ b/esp_modem/examples/simple_cxx_client/main/simple_client.cpp @@ -141,17 +141,7 @@ extern "C" void app_main(void) assert(esp_netif); auto dce = create_SIM7600_dce(&dce_config, uart_dte, esp_netif); - /// TEST - { -// std::string str; -// dce->set_mode(esp_modem::modem_mode::CMUX_MODE); -// while (1) { -// dce->get_imsi(str); -// std::cout << "Modem IMSI number:" << str << "|" << std::endl; -// } - } -// return; - //// TEST + dce->set_command_mode(); std::string str; diff --git a/esp_modem/include/cxx_include/esp_modem_api.hpp b/esp_modem/include/cxx_include/esp_modem_api.hpp index 6dc86e4d9..f9efc8502 100644 --- a/esp_modem/include/cxx_include/esp_modem_api.hpp +++ b/esp_modem/include/cxx_include/esp_modem_api.hpp @@ -79,6 +79,11 @@ std::unique_ptr create_SIM800_dce(const dce_config *config, std::shared_ptr */ std::unique_ptr create_BG96_dce(const dce_config *config, std::shared_ptr dte, esp_netif_t *netif); +/** + * @brief Create generic DCE + */ +std::unique_ptr create_generic_dce(const dce_config *config, std::shared_ptr dte, esp_netif_t *netif); + /** * @} */ diff --git a/esp_modem/include/cxx_include/esp_modem_dte.hpp b/esp_modem/include/cxx_include/esp_modem_dte.hpp index c8c96b6d6..f6ba7aec0 100644 --- a/esp_modem/include/cxx_include/esp_modem_dte.hpp +++ b/esp_modem/include/cxx_include/esp_modem_dte.hpp @@ -24,6 +24,8 @@ #include "cxx_include/esp_modem_cmux.hpp" #include "cxx_include/esp_modem_types.hpp" +struct esp_modem_dte_config; + namespace esp_modem { /** @@ -39,7 +41,7 @@ namespace esp_modem { */ class DTE : public CommandableIf { public: - explicit DTE(std::unique_ptr t); + explicit DTE(const esp_modem_dte_config *config, std::unique_ptr t); ~DTE() = default; @@ -97,7 +99,7 @@ public: } command_result command(const std::string &command, got_line_cb got_line, uint32_t time_ms) override; - command_result command(const std::string &command, got_line_cb got_line, uint32_t time_ms, const char separator) override; + command_result command(const std::string &command, got_line_cb got_line, uint32_t time_ms, char separator) override; private: @@ -106,7 +108,7 @@ private: [[nodiscard]] bool setup_cmux(); static const size_t GOT_LINE = signal_group::bit0; - size_t buffer_size; + size_t buffer_size{}; size_t consumed; std::unique_ptr buffer; std::unique_ptr term; diff --git a/esp_modem/include/esp_modem_config.h b/esp_modem/include/esp_modem_config.h index aa020b2b7..a2ef11037 100644 --- a/esp_modem/include/esp_modem_config.h +++ b/esp_modem/include/esp_modem_config.h @@ -40,7 +40,7 @@ typedef enum { * @brief DTE configuration structure * */ -struct esp_modem_dte_config { +struct esp_modem_uart_term_config { uart_port_t port_num; /*!< UART port number */ uart_word_length_t data_bits; /*!< Data bits of UART */ uart_stop_bits_t stop_bits; /*!< Stop bits of UART */ @@ -53,36 +53,41 @@ struct esp_modem_dte_config { int cts_io_num; /*!< CTS Pin Number */ int rx_buffer_size; /*!< UART RX Buffer Size */ int tx_buffer_size; /*!< UART TX Buffer Size */ - int pattern_queue_size; /*!< UART Pattern Queue Size */ int event_queue_size; /*!< UART Event Queue Size */ uint32_t event_task_stack_size; /*!< UART Event Task Stack size */ int event_task_priority; /*!< UART Event Task Priority */ - int line_buffer_size; /*!< Line buffer size for command mode */ }; +struct esp_modem_dte_config { + size_t dte_buffer_size; + struct esp_modem_uart_term_config uart_config; +}; + + /** * @brief ESP Modem DTE Default Configuration * */ -#define ESP_MODEM_DTE_DEFAULT_CONFIG() \ - { \ - .port_num = UART_NUM_1, \ - .data_bits = UART_DATA_8_BITS, \ - .stop_bits = UART_STOP_BITS_1, \ - .parity = UART_PARITY_DISABLE, \ - .flow_control = ESP_MODEM_FLOW_CONTROL_NONE,\ - .baud_rate = 115200, \ - .tx_io_num = 25, \ - .rx_io_num = 26, \ - .rts_io_num = 27, \ - .cts_io_num = 23, \ - .rx_buffer_size = 1024, \ - .tx_buffer_size = 512, \ - .pattern_queue_size = 20, \ - .event_queue_size = 30, \ - .event_task_stack_size = 4096, \ - .event_task_priority = 5, \ - .line_buffer_size = 512 \ +#define ESP_MODEM_DTE_DEFAULT_CONFIG() \ + { \ + .dte_buffer_size = 512, \ + .uart_config = { \ + .port_num = UART_NUM_1, \ + .data_bits = UART_DATA_8_BITS, \ + .stop_bits = UART_STOP_BITS_1, \ + .parity = UART_PARITY_DISABLE, \ + .flow_control = ESP_MODEM_FLOW_CONTROL_NONE,\ + .baud_rate = 115200, \ + .tx_io_num = 25, \ + .rx_io_num = 26, \ + .rts_io_num = 27, \ + .cts_io_num = 23, \ + .rx_buffer_size = 1024, \ + .tx_buffer_size = 512, \ + .event_queue_size = 30, \ + .event_task_stack_size = 4096, \ + .event_task_priority = 5, \ + } \ } typedef struct esp_modem_dte_config esp_modem_dte_config_t; diff --git a/esp_modem/src/esp_modem_api.cpp b/esp_modem/src/esp_modem_api.cpp index 447c52022..7b29f61eb 100644 --- a/esp_modem/src/esp_modem_api.cpp +++ b/esp_modem/src/esp_modem_api.cpp @@ -32,7 +32,7 @@ static const char *TAG = "modem_api"; std::shared_ptr create_uart_dte(const dte_config *config) { TRY_CATCH_RET_NULL( auto term = create_uart_terminal(config); - return std::make_shared(std::move(term)); + return std::make_shared(config, std::move(term)); ) } @@ -56,4 +56,8 @@ std::unique_ptr create_BG96_dce(const dce_config *config, std::shared_ptr create_generic_dce(const dce_config *config, std::shared_ptr dte, esp_netif_t *netif) { + return create_modem_dce(dce_factory::Modem::GenericModule, config, std::move(dte), netif); +} + } // namespace esp_modem diff --git a/esp_modem/src/esp_modem_dte.cpp b/esp_modem/src/esp_modem_dte.cpp index c98533a7c..f77093cf4 100644 --- a/esp_modem/src/esp_modem_dte.cpp +++ b/esp_modem/src/esp_modem_dte.cpp @@ -12,16 +12,15 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "cxx_include/esp_modem_dte.hpp" #include #include "esp_log.h" +#include "cxx_include/esp_modem_dte.hpp" +#include "esp_modem_config.h" using namespace esp_modem; -const int DTE_BUFFER_SIZE = 1024; - -DTE::DTE(std::unique_ptr terminal): - buffer_size(DTE_BUFFER_SIZE), consumed(0), +DTE::DTE(const esp_modem_dte_config *config, std::unique_ptr terminal): + buffer_size(config->dte_buffer_size), consumed(0), buffer(std::make_unique(buffer_size)), term(std::move(terminal)), command_term(term.get()), other_term(nullptr), mode(modem_mode::UNDEF) {} @@ -56,6 +55,11 @@ command_result DTE::command(const std::string &command, got_line_cb got_line, ui return res; } +command_result DTE::command(const std::string &cmd, got_line_cb got_line, uint32_t time_ms) +{ + return command(cmd, got_line, time_ms, '\n'); +} + bool DTE::setup_cmux() { auto original_term = std::move(term); @@ -74,8 +78,3 @@ bool DTE::setup_cmux() other_term = std::make_unique(cmux_term, 1); return true; } - -command_result DTE::command(const std::string &cmd, got_line_cb got_line, uint32_t time_ms) -{ - return command(cmd, got_line, time_ms, '\n'); -} diff --git a/esp_modem/src/esp_modem_uart.cpp b/esp_modem/src/esp_modem_uart.cpp index 6a591cce4..03864f4f5 100644 --- a/esp_modem/src/esp_modem_uart.cpp +++ b/esp_modem/src/esp_modem_uart.cpp @@ -17,13 +17,10 @@ #include "freertos/task.h" #include "freertos/semphr.h" #include "esp_log.h" -#include "esp_event.h" #include "driver/uart.h" #include "esp_modem_config.h" #include "exception_stub.hpp" -#define ESP_MODEM_EVENT_QUEUE_SIZE (16) - static const char *TAG = "uart_terminal"; namespace esp_modem { @@ -44,14 +41,12 @@ struct uart_resource { uart_port_t port; /*!< UART port */ QueueHandle_t event_queue; /*!< UART event queue handle */ - int line_buffer_size; /*!< line buffer size in command mode */ - int pattern_queue_size; /*!< UART pattern queue size */ }; struct uart_task { explicit uart_task(size_t stack_size, size_t priority, void *task_param, TaskFunction_t task_function) : task_handle(nullptr) { - BaseType_t ret = xTaskCreate(task_function, "uart_task", 10000, task_param, priority, &task_handle); + BaseType_t ret = xTaskCreate(task_function, "uart_task", stack_size, task_param, priority, &task_handle); throw_if_false(ret == pdTRUE, "create uart event task failed"); } @@ -62,23 +57,8 @@ struct uart_task { TaskHandle_t task_handle; /*!< UART event task handle */ }; - -struct uart_event_loop { - explicit uart_event_loop() : event_loop_hdl(nullptr) { - esp_event_loop_args_t loop_args = {}; - loop_args.queue_size = ESP_MODEM_EVENT_QUEUE_SIZE; - loop_args.task_name = nullptr; - throw_if_esp_fail(esp_event_loop_create(&loop_args, &event_loop_hdl), "create event loop failed"); - } - - void run() { esp_event_loop_run(event_loop_hdl, pdMS_TO_TICKS(0)); } - - ~uart_event_loop() { if (event_loop_hdl) esp_event_loop_delete(event_loop_hdl); } - - esp_event_loop_handle_t event_loop_hdl; -}; - -uart_resource::~uart_resource() { +uart_resource::~uart_resource() +{ if (port >= UART_NUM_0 && port < UART_NUM_MAX) { uart_driver_delete(port); } @@ -86,54 +66,54 @@ uart_resource::~uart_resource() { uart_resource::uart_resource(const esp_modem_dte_config *config) : - port(-1) { + port(-1) +{ esp_err_t res; - line_buffer_size = config->line_buffer_size; /* Config UART */ uart_config_t uart_config = {}; - uart_config.baud_rate = config->baud_rate; - uart_config.data_bits = config->data_bits; - uart_config.parity = config->parity; - uart_config.stop_bits = config->stop_bits; - uart_config.flow_ctrl = (config->flow_control == ESP_MODEM_FLOW_CONTROL_HW) ? UART_HW_FLOWCTRL_CTS_RTS - : UART_HW_FLOWCTRL_DISABLE; + uart_config.baud_rate = config->uart_config.baud_rate; + uart_config.data_bits = config->uart_config.data_bits; + uart_config.parity = config->uart_config.parity; + uart_config.stop_bits = config->uart_config.stop_bits; + uart_config.flow_ctrl = (config->uart_config.flow_control == ESP_MODEM_FLOW_CONTROL_HW) ? UART_HW_FLOWCTRL_CTS_RTS + : UART_HW_FLOWCTRL_DISABLE; uart_config.source_clk = UART_SCLK_REF_TICK; - throw_if_esp_fail(uart_param_config(config->port_num, &uart_config), "config uart parameter failed"); + throw_if_esp_fail(uart_param_config(config->uart_config.port_num, &uart_config), "config uart parameter failed"); - if (config->flow_control == ESP_MODEM_FLOW_CONTROL_HW) { - res = uart_set_pin(config->port_num, config->tx_io_num, config->rx_io_num, - config->rts_io_num, config->cts_io_num); + if (config->uart_config.flow_control == ESP_MODEM_FLOW_CONTROL_HW) { + res = uart_set_pin(config->uart_config.port_num, config->uart_config.tx_io_num, config->uart_config.rx_io_num, + config->uart_config.rts_io_num, config->uart_config.cts_io_num); } else { - res = uart_set_pin(config->port_num, config->tx_io_num, config->rx_io_num, + res = uart_set_pin(config->uart_config.port_num, config->uart_config.tx_io_num, config->uart_config.rx_io_num, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE); } throw_if_esp_fail(res, "config uart gpio failed"); /* Set flow control threshold */ - if (config->flow_control == ESP_MODEM_FLOW_CONTROL_HW) { - res = uart_set_hw_flow_ctrl(config->port_num, UART_HW_FLOWCTRL_CTS_RTS, UART_FIFO_LEN - 8); - } else if (config->flow_control == ESP_MODEM_FLOW_CONTROL_SW) { - res = uart_set_sw_flow_ctrl(config->port_num, true, 8, UART_FIFO_LEN - 8); + if (config->uart_config.flow_control == ESP_MODEM_FLOW_CONTROL_HW) { + res = uart_set_hw_flow_ctrl(config->uart_config.port_num, UART_HW_FLOWCTRL_CTS_RTS, UART_FIFO_LEN - 8); + } else if (config->uart_config.flow_control == ESP_MODEM_FLOW_CONTROL_SW) { + res = uart_set_sw_flow_ctrl(config->uart_config.port_num, true, 8, UART_FIFO_LEN - 8); } throw_if_esp_fail(res, "config uart flow control failed"); /* Install UART driver and get event queue used inside driver */ - res = uart_driver_install(config->port_num, config->rx_buffer_size, config->tx_buffer_size, - config->event_queue_size, &(event_queue), 0); + res = uart_driver_install(config->uart_config.port_num, config->uart_config.rx_buffer_size, config->uart_config.tx_buffer_size, + config->uart_config.event_queue_size, &(event_queue), 0); throw_if_esp_fail(res, "install uart driver failed"); - throw_if_esp_fail(uart_set_rx_timeout(config->port_num, 1), "set rx timeout failed"); + throw_if_esp_fail(uart_set_rx_timeout(config->uart_config.port_num, 1), "set rx timeout failed"); - uart_set_rx_full_threshold(config->port_num, 64); + uart_set_rx_full_threshold(config->uart_config.port_num, 64); throw_if_esp_fail(res, "config uart pattern failed"); /* mark UART as initialized */ - port = config->port_num; + port = config->uart_config.port_num; } class uart_terminal : public Terminal { public: explicit uart_terminal(const esp_modem_dte_config *config) : - uart(config), event_loop(), signal(), - task_handle(config->event_task_stack_size, config->event_task_priority, this, s_task) {} + uart(config), signal(), + task_handle(config->uart_config.event_task_stack_size, config->uart_config.event_task_priority, this, s_task) {} ~uart_terminal() override = default; @@ -168,12 +148,9 @@ private: static const size_t TASK_STOP = BIT2; static const size_t TASK_PARAMS = BIT3; - uart_resource uart; - uart_event_loop event_loop; signal_group signal; uart_task task_handle; - }; std::unique_ptr create_uart_terminal(const esp_modem_dte_config *config) { @@ -194,7 +171,6 @@ void uart_terminal::task() { return; // exits to the static method where the task gets deleted } while (signal.is_any(TASK_START)) { - event_loop.run(); if (uart.get_event(event, 100)) { if (signal.is_any(TASK_PARAMS)) { on_data_priv = on_data; @@ -202,10 +178,7 @@ void uart_terminal::task() { } switch (event.type) { case UART_DATA: -// ESP_LOGI(TAG, "UART_DATA"); -// ESP_LOG_BUFFER_HEXDUMP("esp-modem-pattern: debug_data", esp_dte->buffer, length, ESP_LOG_DEBUG); uart_get_buffered_data_len(uart.port, &len); -// ESP_LOGI(TAG, "UART_DATA len=%d, on_data=%d", len, (bool)on_data); if (len && on_data_priv) { if (on_data_priv(nullptr, len)) { on_data_priv = nullptr; @@ -214,23 +187,30 @@ void uart_terminal::task() { break; case UART_FIFO_OVF: ESP_LOGW(TAG, "HW FIFO Overflow"); + if (on_error) + on_error(terminal_error::BUFFER_OVERFLOW); uart.reset_events(); break; case UART_BUFFER_FULL: ESP_LOGW(TAG, "Ring Buffer Full"); + if (on_error) + on_error(terminal_error::BUFFER_OVERFLOW); uart.reset_events(); break; case UART_BREAK: ESP_LOGW(TAG, "Rx Break"); + if (on_error) + on_error(terminal_error::UNEXPECTED_CONTROL_FLOW); break; case UART_PARITY_ERR: ESP_LOGE(TAG, "Parity Error"); + if (on_error) + on_error(terminal_error::CHECKSUM_ERROR); break; case UART_FRAME_ERR: ESP_LOGE(TAG, "Frame Error"); - break; - case UART_PATTERN_DET: - ESP_LOGI(TAG, "UART_PATTERN_DET"); + if (on_error) + on_error(terminal_error::UNEXPECTED_CONTROL_FLOW); break; default: ESP_LOGW(TAG, "unknown uart event type: %d", event.type);