From 2661b4d28c12240f6a88f37e6a71b9b10ffc4e46 Mon Sep 17 00:00:00 2001 From: David Cermak Date: Thu, 2 Nov 2023 08:23:18 +0100 Subject: [PATCH 1/3] fix(modem): Fix CRLF issue with esp_modem_c_api.cpp --- components/esp_modem/src/esp_modem_c_api.cpp | 850 +++++++++---------- 1 file changed, 425 insertions(+), 425 deletions(-) diff --git a/components/esp_modem/src/esp_modem_c_api.cpp b/components/esp_modem/src/esp_modem_c_api.cpp index 87e66f78e4..ac4db3f72d 100644 --- a/components/esp_modem/src/esp_modem_c_api.cpp +++ b/components/esp_modem/src/esp_modem_c_api.cpp @@ -1,425 +1,425 @@ -/* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include "cxx_include/esp_modem_dte.hpp" -#include "uart_terminal.hpp" -#include "esp_log.h" -#include "cxx_include/esp_modem_api.hpp" -#include "cxx_include/esp_modem_dce_factory.hpp" -#include "esp_modem_c_api_types.h" -#include "esp_modem_config.h" -#include "exception_stub.hpp" -#include "esp_private/c_api_wrapper.hpp" -#include "cstring" - -#ifndef ESP_MODEM_C_API_STR_MAX -#define ESP_MODEM_C_API_STR_MAX 64 -#endif - -#ifndef HAVE_STRLCPY -size_t strlcpy(char *dest, const char *src, size_t len); -#endif - -// -// C API definitions -using namespace esp_modem; - -extern "C" esp_modem_dce_t *esp_modem_new_dev(esp_modem_dce_device_t module, const esp_modem_dte_config_t *dte_config, const esp_modem_dce_config_t *dce_config, esp_netif_t *netif) -{ - auto dce_wrap = new (std::nothrow) esp_modem_dce_wrap; - if (dce_wrap == nullptr) { - return nullptr; - } - auto dte = create_uart_dte(dte_config); - if (dte == nullptr) { - delete dce_wrap; - return nullptr; - } - dce_wrap->dte = dte; - dce_factory::Factory f(convert_modem_enum(module)); - dce_wrap->dce = f.build(dce_config, std::move(dte), netif); - if (dce_wrap->dce == nullptr) { - delete dce_wrap; - return nullptr; - } - dce_wrap->modem_type = convert_modem_enum(module); - dce_wrap->dte_type = esp_modem_dce_wrap::modem_wrap_dte_type::UART; - return dce_wrap; -} - -extern "C" esp_modem_dce_t *esp_modem_new(const esp_modem_dte_config_t *dte_config, const esp_modem_dce_config_t *dce_config, esp_netif_t *netif) -{ - return esp_modem_new_dev(ESP_MODEM_DCE_GENETIC, dte_config, dce_config, netif); -} - -extern "C" void esp_modem_destroy(esp_modem_dce_t *dce_wrap) -{ - if (dce_wrap) { - delete dce_wrap->dce; - delete dce_wrap; - } -} - -extern "C" esp_err_t esp_modem_set_error_cb(esp_modem_dce_t *dce_wrap, esp_modem_terminal_error_cbt err_cb) -{ - if (dce_wrap == nullptr || dce_wrap->dce == nullptr || dce_wrap->dte == nullptr) { - return ESP_ERR_INVALID_ARG; - } - - if (err_cb) { - dce_wrap->dte->set_error_cb([err_cb](terminal_error err) { - err_cb(convert_terminal_error_enum(err)); - }); - } else { - dce_wrap->dte->set_error_cb(nullptr); - } - return ESP_OK; -} - -extern "C" esp_err_t esp_modem_sync(esp_modem_dce_t *dce_wrap) -{ - if (dce_wrap == nullptr || dce_wrap->dce == nullptr) { - return ESP_ERR_INVALID_ARG; - } - return command_response_to_esp_err(dce_wrap->dce->sync()); -} - -extern "C" esp_err_t esp_modem_set_mode(esp_modem_dce_t *dce_wrap, esp_modem_dce_mode_t mode) -{ - if (dce_wrap == nullptr || dce_wrap->dce == nullptr) { - return ESP_ERR_INVALID_ARG; - } - switch (mode) { - case ESP_MODEM_MODE_DATA: - return dce_wrap->dce->set_mode(modem_mode::DATA_MODE) ? ESP_OK : ESP_FAIL; - case ESP_MODEM_MODE_COMMAND: - return dce_wrap->dce->set_mode(modem_mode::COMMAND_MODE) ? ESP_OK : ESP_FAIL; - case ESP_MODEM_MODE_CMUX: - return dce_wrap->dce->set_mode(modem_mode::CMUX_MODE) ? ESP_OK : ESP_FAIL; - case ESP_MODEM_MODE_CMUX_MANUAL: - return dce_wrap->dce->set_mode(modem_mode::CMUX_MANUAL_MODE) ? ESP_OK : ESP_FAIL; - case ESP_MODEM_MODE_CMUX_MANUAL_EXIT: - return dce_wrap->dce->set_mode(modem_mode::CMUX_MANUAL_EXIT) ? ESP_OK : ESP_FAIL; - case ESP_MODEM_MODE_CMUX_MANUAL_SWAP: - return dce_wrap->dce->set_mode(modem_mode::CMUX_MANUAL_SWAP) ? ESP_OK : ESP_FAIL; - case ESP_MODEM_MODE_CMUX_MANUAL_DATA: - return dce_wrap->dce->set_mode(modem_mode::CMUX_MANUAL_DATA) ? ESP_OK : ESP_FAIL; - case ESP_MODEM_MODE_CMUX_MANUAL_COMMAND: - return dce_wrap->dce->set_mode(modem_mode::CMUX_MANUAL_COMMAND) ? ESP_OK : ESP_FAIL; - } - return ESP_ERR_NOT_SUPPORTED; -} - -extern "C" esp_err_t esp_modem_read_pin(esp_modem_dce_t *dce_wrap, bool *pin) -{ - if (dce_wrap == nullptr || dce_wrap->dce == nullptr) { - return ESP_ERR_INVALID_ARG; - } - - return command_response_to_esp_err(dce_wrap->dce->read_pin(*pin)); -} - -extern "C" esp_err_t esp_modem_sms_txt_mode(esp_modem_dce_t *dce_wrap, bool txt) -{ - if (dce_wrap == nullptr || dce_wrap->dce == nullptr) { - return ESP_ERR_INVALID_ARG; - } - - return command_response_to_esp_err(dce_wrap->dce->sms_txt_mode(txt)); -} - -extern "C" esp_err_t esp_modem_send_sms(esp_modem_dce_t *dce_wrap, const char *number, const char *message) -{ - if (dce_wrap == nullptr || dce_wrap->dce == nullptr) { - return ESP_ERR_INVALID_ARG; - } - std::string number_str(number); - std::string message_str(message); - return command_response_to_esp_err(dce_wrap->dce->send_sms(number_str, message_str)); -} - -extern "C" esp_err_t esp_modem_sms_character_set(esp_modem_dce_t *dce_wrap) -{ - if (dce_wrap == nullptr || dce_wrap->dce == nullptr) { - return ESP_ERR_INVALID_ARG; - } - - return command_response_to_esp_err(dce_wrap->dce->sms_character_set()); -} - -extern "C" esp_err_t esp_modem_set_pin(esp_modem_dce_t *dce_wrap, const char *pin) -{ - if (dce_wrap == nullptr || dce_wrap->dce == nullptr) { - return ESP_ERR_INVALID_ARG; - } - std::string pin_str(pin); - return command_response_to_esp_err(dce_wrap->dce->set_pin(pin_str)); -} - -extern "C" esp_err_t esp_modem_at(esp_modem_dce_t *dce_wrap, const char *at, char *p_out, int timeout) -{ - if (dce_wrap == nullptr || dce_wrap->dce == nullptr) { - return ESP_ERR_INVALID_ARG; - } - std::string out; - std::string at_str(at); - auto ret = command_response_to_esp_err(dce_wrap->dce->at(at_str, out, timeout)); - if ((p_out != NULL) && (!out.empty())) { - strlcpy(p_out, out.c_str(), ESP_MODEM_C_API_STR_MAX); - } - return ret; -} - -extern "C" esp_err_t esp_modem_get_signal_quality(esp_modem_dce_t *dce_wrap, int *rssi, int *ber) -{ - if (dce_wrap == nullptr || dce_wrap->dce == nullptr) { - return ESP_ERR_INVALID_ARG; - } - return command_response_to_esp_err(dce_wrap->dce->get_signal_quality(*rssi, *ber)); -} - -extern "C" esp_err_t esp_modem_get_imsi(esp_modem_dce_t *dce_wrap, char *p_imsi) -{ - if (dce_wrap == nullptr || dce_wrap->dce == nullptr) { - return ESP_ERR_INVALID_ARG; - } - std::string imsi; - auto ret = command_response_to_esp_err(dce_wrap->dce->get_imsi(imsi)); - if (ret == ESP_OK && !imsi.empty()) { - strlcpy(p_imsi, imsi.c_str(), ESP_MODEM_C_API_STR_MAX); - } - return ret; -} - -extern "C" esp_err_t esp_modem_set_flow_control(esp_modem_dce_t *dce_wrap, int dce_flow, int dte_flow) -{ - if (dce_wrap == nullptr || dce_wrap->dce == nullptr) { - return ESP_ERR_INVALID_ARG; - } - return command_response_to_esp_err(dce_wrap->dce->set_flow_control(dce_flow, dte_flow)); -} - -extern "C" esp_err_t esp_modem_store_profile(esp_modem_dce_t *dce_wrap) -{ - if (dce_wrap == nullptr || dce_wrap->dce == nullptr) { - return ESP_ERR_INVALID_ARG; - } - return command_response_to_esp_err(dce_wrap->dce->store_profile()); -} - -extern "C" esp_err_t esp_modem_get_imei(esp_modem_dce_t *dce_wrap, char *p_imei) -{ - if (dce_wrap == nullptr || dce_wrap->dce == nullptr) { - return ESP_ERR_INVALID_ARG; - } - std::string imei; - auto ret = command_response_to_esp_err(dce_wrap->dce->get_imei(imei)); - if (ret == ESP_OK && !imei.empty()) { - strlcpy(p_imei, imei.c_str(), ESP_MODEM_C_API_STR_MAX); - } - return ret; -} - -extern "C" esp_err_t esp_modem_get_operator_name(esp_modem_dce_t *dce_wrap, char *p_name, int *p_act) -{ - if (dce_wrap == nullptr || dce_wrap->dce == nullptr || p_name == nullptr || p_act == nullptr) { - return ESP_ERR_INVALID_ARG; - } - std::string name; - int act; - auto ret = command_response_to_esp_err(dce_wrap->dce->get_operator_name(name, act)); - if (ret == ESP_OK && !name.empty()) { - strlcpy(p_name, name.c_str(), ESP_MODEM_C_API_STR_MAX); - *p_act = act; - } - return ret; -} - -extern "C" esp_err_t esp_modem_get_module_name(esp_modem_dce_t *dce_wrap, char *p_name) -{ - if (dce_wrap == nullptr || dce_wrap->dce == nullptr) { - return ESP_ERR_INVALID_ARG; - } - std::string name; - auto ret = command_response_to_esp_err(dce_wrap->dce->get_module_name(name)); - if (ret == ESP_OK && !name.empty()) { - strlcpy(p_name, name.c_str(), ESP_MODEM_C_API_STR_MAX); - } - return ret; -} - -extern "C" esp_err_t esp_modem_get_battery_status(esp_modem_dce_t *dce_wrap, int *p_volt, int *p_bcs, int *p_bcl) -{ - if (dce_wrap == nullptr || dce_wrap->dce == nullptr || p_bcs == nullptr || p_bcl == nullptr || p_volt == nullptr) { - return ESP_ERR_INVALID_ARG; - } - int bcs, bcl, volt; - auto ret = command_response_to_esp_err(dce_wrap->dce->get_battery_status(volt, bcs, bcl)); - if (ret == ESP_OK) { - *p_volt = volt; - *p_bcs = bcs; - *p_bcl = bcl; - } - return ret; -} - -extern "C" esp_err_t esp_modem_power_down(esp_modem_dce_t *dce_wrap) -{ - if (dce_wrap == nullptr || dce_wrap->dce == nullptr) { - return ESP_ERR_INVALID_ARG; - } - return command_response_to_esp_err(dce_wrap->dce->power_down()); -} - -extern "C" esp_err_t esp_modem_set_operator(esp_modem_dce_t *dce_wrap, int mode, int format, const char *oper) -{ - if (dce_wrap == nullptr || dce_wrap->dce == nullptr) { - return ESP_ERR_INVALID_ARG; - } - std::string operator_str(oper); - return command_response_to_esp_err(dce_wrap->dce->set_operator(mode, format, operator_str)); -} - -extern "C" esp_err_t esp_modem_set_network_attachment_state(esp_modem_dce_t *dce_wrap, int state) -{ - if (dce_wrap == nullptr || dce_wrap->dce == nullptr) { - return ESP_ERR_INVALID_ARG; - } - return command_response_to_esp_err(dce_wrap->dce->set_network_attachment_state(state)); -} - -extern "C" esp_err_t esp_modem_get_network_attachment_state(esp_modem_dce_t *dce_wrap, int *p_state) -{ - if (dce_wrap == nullptr || dce_wrap->dce == nullptr) { - return ESP_ERR_INVALID_ARG; - } - int state; - auto ret = command_response_to_esp_err(dce_wrap->dce->get_network_attachment_state(state)); - if (ret == ESP_OK) { - *p_state = state; - } - return ret; -} - -extern "C" esp_err_t esp_modem_set_radio_state(esp_modem_dce_t *dce_wrap, int state) -{ - if (dce_wrap == nullptr || dce_wrap->dce == nullptr) { - return ESP_ERR_INVALID_ARG; - } - return command_response_to_esp_err(dce_wrap->dce->set_radio_state(state)); -} - -extern "C" esp_err_t esp_modem_get_radio_state(esp_modem_dce_t *dce_wrap, int *p_state) -{ - if (dce_wrap == nullptr || dce_wrap->dce == nullptr) { - return ESP_ERR_INVALID_ARG; - } - int state; - auto ret = command_response_to_esp_err(dce_wrap->dce->get_radio_state(state)); - if (ret == ESP_OK) { - *p_state = state; - } - return ret; -} - -extern "C" esp_err_t esp_modem_set_network_mode(esp_modem_dce_t *dce_wrap, int mode) -{ - if (dce_wrap == nullptr || dce_wrap->dce == nullptr) { - return ESP_ERR_INVALID_ARG; - } - return command_response_to_esp_err(dce_wrap->dce->set_network_mode(mode)); -} - -extern "C" esp_err_t esp_modem_set_preferred_mode(esp_modem_dce_t *dce_wrap, int mode) -{ - if (dce_wrap == nullptr || dce_wrap->dce == nullptr) { - return ESP_ERR_INVALID_ARG; - } - return command_response_to_esp_err(dce_wrap->dce->set_preferred_mode(mode)); -} - -extern "C" esp_err_t esp_modem_set_network_bands(esp_modem_dce_t *dce_wrap, const char *mode, const int *bands, int size) -{ - if (dce_wrap == nullptr || dce_wrap->dce == nullptr) { - return ESP_ERR_INVALID_ARG; - } - std::string mode_str(mode); - return command_response_to_esp_err(dce_wrap->dce->set_network_bands(mode, bands, size)); -} - -extern "C" esp_err_t esp_modem_get_network_system_mode(esp_modem_dce_t *dce_wrap, int *p_mode) -{ - if (dce_wrap == nullptr || dce_wrap->dce == nullptr) { - return ESP_ERR_INVALID_ARG; - } - int mode; - auto ret = command_response_to_esp_err(dce_wrap->dce->get_network_system_mode(mode)); - if (ret == ESP_OK) { - *p_mode = mode; - } - return ret; -} - -extern "C" esp_err_t esp_modem_set_gnss_power_mode(esp_modem_dce_t *dce_wrap, int mode) -{ - if (dce_wrap == nullptr || dce_wrap->dce == nullptr) { - return ESP_ERR_INVALID_ARG; - } - return command_response_to_esp_err(dce_wrap->dce->set_gnss_power_mode(mode)); -} - -extern "C" esp_err_t esp_modem_get_gnss_power_mode(esp_modem_dce_t *dce_wrap, int *p_mode) -{ - if (dce_wrap == nullptr || dce_wrap->dce == nullptr) { - return ESP_ERR_INVALID_ARG; - } - int mode; - auto ret = command_response_to_esp_err(dce_wrap->dce->get_gnss_power_mode(mode)); - if (ret == ESP_OK) { - *p_mode = mode; - } - return ret; -} - -extern "C" esp_err_t esp_modem_reset(esp_modem_dce_t *dce_wrap) -{ - return command_response_to_esp_err(dce_wrap->dce->reset()); -} - -extern "C" esp_err_t esp_modem_set_pdp_context(esp_modem_dce_t *dce_wrap, esp_modem_PdpContext_t *c_api_pdp) -{ - if (dce_wrap == nullptr || dce_wrap->dce == nullptr) { - return ESP_ERR_INVALID_ARG; - } - esp_modem::PdpContext pdp{c_api_pdp->apn}; - pdp.context_id = c_api_pdp->context_id; - pdp.protocol_type = c_api_pdp->protocol_type; - return command_response_to_esp_err(dce_wrap->dce->set_pdp_context(pdp)); -} - -extern "C" esp_err_t esp_modem_command(esp_modem_dce_t *dce_wrap, const char *command, esp_err_t(*got_line_fn)(uint8_t *data, size_t len), uint32_t timeout_ms) -{ - if (dce_wrap == nullptr || dce_wrap->dce == nullptr || command == nullptr || got_line_fn == nullptr) { - return ESP_ERR_INVALID_ARG; - } - std::string cmd(command); - return command_response_to_esp_err(dce_wrap->dce->command(cmd, [got_line_fn](uint8_t *data, size_t len) { - switch (got_line_fn(data, len)) { - case ESP_OK: - return command_result::OK; - case ESP_FAIL: - return command_result::FAIL; - default: - return command_result::TIMEOUT; - } - }, timeout_ms)); -} - -extern "C" esp_err_t esp_modem_set_baud(esp_modem_dce_t *dce_wrap, int baud) -{ - return command_response_to_esp_err(dce_wrap->dce->set_baud(baud)); -} +/* + * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "cxx_include/esp_modem_dte.hpp" +#include "uart_terminal.hpp" +#include "esp_log.h" +#include "cxx_include/esp_modem_api.hpp" +#include "cxx_include/esp_modem_dce_factory.hpp" +#include "esp_modem_c_api_types.h" +#include "esp_modem_config.h" +#include "exception_stub.hpp" +#include "esp_private/c_api_wrapper.hpp" +#include "cstring" + +#ifndef ESP_MODEM_C_API_STR_MAX +#define ESP_MODEM_C_API_STR_MAX 64 +#endif + +#ifndef HAVE_STRLCPY +size_t strlcpy(char *dest, const char *src, size_t len); +#endif + +// +// C API definitions +using namespace esp_modem; + +extern "C" esp_modem_dce_t *esp_modem_new_dev(esp_modem_dce_device_t module, const esp_modem_dte_config_t *dte_config, const esp_modem_dce_config_t *dce_config, esp_netif_t *netif) +{ + auto dce_wrap = new (std::nothrow) esp_modem_dce_wrap; + if (dce_wrap == nullptr) { + return nullptr; + } + auto dte = create_uart_dte(dte_config); + if (dte == nullptr) { + delete dce_wrap; + return nullptr; + } + dce_wrap->dte = dte; + dce_factory::Factory f(convert_modem_enum(module)); + dce_wrap->dce = f.build(dce_config, std::move(dte), netif); + if (dce_wrap->dce == nullptr) { + delete dce_wrap; + return nullptr; + } + dce_wrap->modem_type = convert_modem_enum(module); + dce_wrap->dte_type = esp_modem_dce_wrap::modem_wrap_dte_type::UART; + return dce_wrap; +} + +extern "C" esp_modem_dce_t *esp_modem_new(const esp_modem_dte_config_t *dte_config, const esp_modem_dce_config_t *dce_config, esp_netif_t *netif) +{ + return esp_modem_new_dev(ESP_MODEM_DCE_GENETIC, dte_config, dce_config, netif); +} + +extern "C" void esp_modem_destroy(esp_modem_dce_t *dce_wrap) +{ + if (dce_wrap) { + delete dce_wrap->dce; + delete dce_wrap; + } +} + +extern "C" esp_err_t esp_modem_set_error_cb(esp_modem_dce_t *dce_wrap, esp_modem_terminal_error_cbt err_cb) +{ + if (dce_wrap == nullptr || dce_wrap->dce == nullptr || dce_wrap->dte == nullptr) { + return ESP_ERR_INVALID_ARG; + } + + if (err_cb) { + dce_wrap->dte->set_error_cb([err_cb](terminal_error err) { + err_cb(convert_terminal_error_enum(err)); + }); + } else { + dce_wrap->dte->set_error_cb(nullptr); + } + return ESP_OK; +} + +extern "C" esp_err_t esp_modem_sync(esp_modem_dce_t *dce_wrap) +{ + if (dce_wrap == nullptr || dce_wrap->dce == nullptr) { + return ESP_ERR_INVALID_ARG; + } + return command_response_to_esp_err(dce_wrap->dce->sync()); +} + +extern "C" esp_err_t esp_modem_set_mode(esp_modem_dce_t *dce_wrap, esp_modem_dce_mode_t mode) +{ + if (dce_wrap == nullptr || dce_wrap->dce == nullptr) { + return ESP_ERR_INVALID_ARG; + } + switch (mode) { + case ESP_MODEM_MODE_DATA: + return dce_wrap->dce->set_mode(modem_mode::DATA_MODE) ? ESP_OK : ESP_FAIL; + case ESP_MODEM_MODE_COMMAND: + return dce_wrap->dce->set_mode(modem_mode::COMMAND_MODE) ? ESP_OK : ESP_FAIL; + case ESP_MODEM_MODE_CMUX: + return dce_wrap->dce->set_mode(modem_mode::CMUX_MODE) ? ESP_OK : ESP_FAIL; + case ESP_MODEM_MODE_CMUX_MANUAL: + return dce_wrap->dce->set_mode(modem_mode::CMUX_MANUAL_MODE) ? ESP_OK : ESP_FAIL; + case ESP_MODEM_MODE_CMUX_MANUAL_EXIT: + return dce_wrap->dce->set_mode(modem_mode::CMUX_MANUAL_EXIT) ? ESP_OK : ESP_FAIL; + case ESP_MODEM_MODE_CMUX_MANUAL_SWAP: + return dce_wrap->dce->set_mode(modem_mode::CMUX_MANUAL_SWAP) ? ESP_OK : ESP_FAIL; + case ESP_MODEM_MODE_CMUX_MANUAL_DATA: + return dce_wrap->dce->set_mode(modem_mode::CMUX_MANUAL_DATA) ? ESP_OK : ESP_FAIL; + case ESP_MODEM_MODE_CMUX_MANUAL_COMMAND: + return dce_wrap->dce->set_mode(modem_mode::CMUX_MANUAL_COMMAND) ? ESP_OK : ESP_FAIL; + } + return ESP_ERR_NOT_SUPPORTED; +} + +extern "C" esp_err_t esp_modem_read_pin(esp_modem_dce_t *dce_wrap, bool *pin) +{ + if (dce_wrap == nullptr || dce_wrap->dce == nullptr) { + return ESP_ERR_INVALID_ARG; + } + + return command_response_to_esp_err(dce_wrap->dce->read_pin(*pin)); +} + +extern "C" esp_err_t esp_modem_sms_txt_mode(esp_modem_dce_t *dce_wrap, bool txt) +{ + if (dce_wrap == nullptr || dce_wrap->dce == nullptr) { + return ESP_ERR_INVALID_ARG; + } + + return command_response_to_esp_err(dce_wrap->dce->sms_txt_mode(txt)); +} + +extern "C" esp_err_t esp_modem_send_sms(esp_modem_dce_t *dce_wrap, const char *number, const char *message) +{ + if (dce_wrap == nullptr || dce_wrap->dce == nullptr) { + return ESP_ERR_INVALID_ARG; + } + std::string number_str(number); + std::string message_str(message); + return command_response_to_esp_err(dce_wrap->dce->send_sms(number_str, message_str)); +} + +extern "C" esp_err_t esp_modem_sms_character_set(esp_modem_dce_t *dce_wrap) +{ + if (dce_wrap == nullptr || dce_wrap->dce == nullptr) { + return ESP_ERR_INVALID_ARG; + } + + return command_response_to_esp_err(dce_wrap->dce->sms_character_set()); +} + +extern "C" esp_err_t esp_modem_set_pin(esp_modem_dce_t *dce_wrap, const char *pin) +{ + if (dce_wrap == nullptr || dce_wrap->dce == nullptr) { + return ESP_ERR_INVALID_ARG; + } + std::string pin_str(pin); + return command_response_to_esp_err(dce_wrap->dce->set_pin(pin_str)); +} + +extern "C" esp_err_t esp_modem_at(esp_modem_dce_t *dce_wrap, const char *at, char *p_out, int timeout) +{ + if (dce_wrap == nullptr || dce_wrap->dce == nullptr) { + return ESP_ERR_INVALID_ARG; + } + std::string out; + std::string at_str(at); + auto ret = command_response_to_esp_err(dce_wrap->dce->at(at_str, out, timeout)); + if ((p_out != NULL) && (!out.empty())) { + strlcpy(p_out, out.c_str(), ESP_MODEM_C_API_STR_MAX); + } + return ret; +} + +extern "C" esp_err_t esp_modem_get_signal_quality(esp_modem_dce_t *dce_wrap, int *rssi, int *ber) +{ + if (dce_wrap == nullptr || dce_wrap->dce == nullptr) { + return ESP_ERR_INVALID_ARG; + } + return command_response_to_esp_err(dce_wrap->dce->get_signal_quality(*rssi, *ber)); +} + +extern "C" esp_err_t esp_modem_get_imsi(esp_modem_dce_t *dce_wrap, char *p_imsi) +{ + if (dce_wrap == nullptr || dce_wrap->dce == nullptr) { + return ESP_ERR_INVALID_ARG; + } + std::string imsi; + auto ret = command_response_to_esp_err(dce_wrap->dce->get_imsi(imsi)); + if (ret == ESP_OK && !imsi.empty()) { + strlcpy(p_imsi, imsi.c_str(), ESP_MODEM_C_API_STR_MAX); + } + return ret; +} + +extern "C" esp_err_t esp_modem_set_flow_control(esp_modem_dce_t *dce_wrap, int dce_flow, int dte_flow) +{ + if (dce_wrap == nullptr || dce_wrap->dce == nullptr) { + return ESP_ERR_INVALID_ARG; + } + return command_response_to_esp_err(dce_wrap->dce->set_flow_control(dce_flow, dte_flow)); +} + +extern "C" esp_err_t esp_modem_store_profile(esp_modem_dce_t *dce_wrap) +{ + if (dce_wrap == nullptr || dce_wrap->dce == nullptr) { + return ESP_ERR_INVALID_ARG; + } + return command_response_to_esp_err(dce_wrap->dce->store_profile()); +} + +extern "C" esp_err_t esp_modem_get_imei(esp_modem_dce_t *dce_wrap, char *p_imei) +{ + if (dce_wrap == nullptr || dce_wrap->dce == nullptr) { + return ESP_ERR_INVALID_ARG; + } + std::string imei; + auto ret = command_response_to_esp_err(dce_wrap->dce->get_imei(imei)); + if (ret == ESP_OK && !imei.empty()) { + strlcpy(p_imei, imei.c_str(), ESP_MODEM_C_API_STR_MAX); + } + return ret; +} + +extern "C" esp_err_t esp_modem_get_operator_name(esp_modem_dce_t *dce_wrap, char *p_name, int *p_act) +{ + if (dce_wrap == nullptr || dce_wrap->dce == nullptr || p_name == nullptr || p_act == nullptr) { + return ESP_ERR_INVALID_ARG; + } + std::string name; + int act; + auto ret = command_response_to_esp_err(dce_wrap->dce->get_operator_name(name, act)); + if (ret == ESP_OK && !name.empty()) { + strlcpy(p_name, name.c_str(), ESP_MODEM_C_API_STR_MAX); + *p_act = act; + } + return ret; +} + +extern "C" esp_err_t esp_modem_get_module_name(esp_modem_dce_t *dce_wrap, char *p_name) +{ + if (dce_wrap == nullptr || dce_wrap->dce == nullptr) { + return ESP_ERR_INVALID_ARG; + } + std::string name; + auto ret = command_response_to_esp_err(dce_wrap->dce->get_module_name(name)); + if (ret == ESP_OK && !name.empty()) { + strlcpy(p_name, name.c_str(), ESP_MODEM_C_API_STR_MAX); + } + return ret; +} + +extern "C" esp_err_t esp_modem_get_battery_status(esp_modem_dce_t *dce_wrap, int *p_volt, int *p_bcs, int *p_bcl) +{ + if (dce_wrap == nullptr || dce_wrap->dce == nullptr || p_bcs == nullptr || p_bcl == nullptr || p_volt == nullptr) { + return ESP_ERR_INVALID_ARG; + } + int bcs, bcl, volt; + auto ret = command_response_to_esp_err(dce_wrap->dce->get_battery_status(volt, bcs, bcl)); + if (ret == ESP_OK) { + *p_volt = volt; + *p_bcs = bcs; + *p_bcl = bcl; + } + return ret; +} + +extern "C" esp_err_t esp_modem_power_down(esp_modem_dce_t *dce_wrap) +{ + if (dce_wrap == nullptr || dce_wrap->dce == nullptr) { + return ESP_ERR_INVALID_ARG; + } + return command_response_to_esp_err(dce_wrap->dce->power_down()); +} + +extern "C" esp_err_t esp_modem_set_operator(esp_modem_dce_t *dce_wrap, int mode, int format, const char *oper) +{ + if (dce_wrap == nullptr || dce_wrap->dce == nullptr) { + return ESP_ERR_INVALID_ARG; + } + std::string operator_str(oper); + return command_response_to_esp_err(dce_wrap->dce->set_operator(mode, format, operator_str)); +} + +extern "C" esp_err_t esp_modem_set_network_attachment_state(esp_modem_dce_t *dce_wrap, int state) +{ + if (dce_wrap == nullptr || dce_wrap->dce == nullptr) { + return ESP_ERR_INVALID_ARG; + } + return command_response_to_esp_err(dce_wrap->dce->set_network_attachment_state(state)); +} + +extern "C" esp_err_t esp_modem_get_network_attachment_state(esp_modem_dce_t *dce_wrap, int *p_state) +{ + if (dce_wrap == nullptr || dce_wrap->dce == nullptr) { + return ESP_ERR_INVALID_ARG; + } + int state; + auto ret = command_response_to_esp_err(dce_wrap->dce->get_network_attachment_state(state)); + if (ret == ESP_OK) { + *p_state = state; + } + return ret; +} + +extern "C" esp_err_t esp_modem_set_radio_state(esp_modem_dce_t *dce_wrap, int state) +{ + if (dce_wrap == nullptr || dce_wrap->dce == nullptr) { + return ESP_ERR_INVALID_ARG; + } + return command_response_to_esp_err(dce_wrap->dce->set_radio_state(state)); +} + +extern "C" esp_err_t esp_modem_get_radio_state(esp_modem_dce_t *dce_wrap, int *p_state) +{ + if (dce_wrap == nullptr || dce_wrap->dce == nullptr) { + return ESP_ERR_INVALID_ARG; + } + int state; + auto ret = command_response_to_esp_err(dce_wrap->dce->get_radio_state(state)); + if (ret == ESP_OK) { + *p_state = state; + } + return ret; +} + +extern "C" esp_err_t esp_modem_set_network_mode(esp_modem_dce_t *dce_wrap, int mode) +{ + if (dce_wrap == nullptr || dce_wrap->dce == nullptr) { + return ESP_ERR_INVALID_ARG; + } + return command_response_to_esp_err(dce_wrap->dce->set_network_mode(mode)); +} + +extern "C" esp_err_t esp_modem_set_preferred_mode(esp_modem_dce_t *dce_wrap, int mode) +{ + if (dce_wrap == nullptr || dce_wrap->dce == nullptr) { + return ESP_ERR_INVALID_ARG; + } + return command_response_to_esp_err(dce_wrap->dce->set_preferred_mode(mode)); +} + +extern "C" esp_err_t esp_modem_set_network_bands(esp_modem_dce_t *dce_wrap, const char *mode, const int *bands, int size) +{ + if (dce_wrap == nullptr || dce_wrap->dce == nullptr) { + return ESP_ERR_INVALID_ARG; + } + std::string mode_str(mode); + return command_response_to_esp_err(dce_wrap->dce->set_network_bands(mode, bands, size)); +} + +extern "C" esp_err_t esp_modem_get_network_system_mode(esp_modem_dce_t *dce_wrap, int *p_mode) +{ + if (dce_wrap == nullptr || dce_wrap->dce == nullptr) { + return ESP_ERR_INVALID_ARG; + } + int mode; + auto ret = command_response_to_esp_err(dce_wrap->dce->get_network_system_mode(mode)); + if (ret == ESP_OK) { + *p_mode = mode; + } + return ret; +} + +extern "C" esp_err_t esp_modem_set_gnss_power_mode(esp_modem_dce_t *dce_wrap, int mode) +{ + if (dce_wrap == nullptr || dce_wrap->dce == nullptr) { + return ESP_ERR_INVALID_ARG; + } + return command_response_to_esp_err(dce_wrap->dce->set_gnss_power_mode(mode)); +} + +extern "C" esp_err_t esp_modem_get_gnss_power_mode(esp_modem_dce_t *dce_wrap, int *p_mode) +{ + if (dce_wrap == nullptr || dce_wrap->dce == nullptr) { + return ESP_ERR_INVALID_ARG; + } + int mode; + auto ret = command_response_to_esp_err(dce_wrap->dce->get_gnss_power_mode(mode)); + if (ret == ESP_OK) { + *p_mode = mode; + } + return ret; +} + +extern "C" esp_err_t esp_modem_reset(esp_modem_dce_t *dce_wrap) +{ + return command_response_to_esp_err(dce_wrap->dce->reset()); +} + +extern "C" esp_err_t esp_modem_set_pdp_context(esp_modem_dce_t *dce_wrap, esp_modem_PdpContext_t *c_api_pdp) +{ + if (dce_wrap == nullptr || dce_wrap->dce == nullptr) { + return ESP_ERR_INVALID_ARG; + } + esp_modem::PdpContext pdp{c_api_pdp->apn}; + pdp.context_id = c_api_pdp->context_id; + pdp.protocol_type = c_api_pdp->protocol_type; + return command_response_to_esp_err(dce_wrap->dce->set_pdp_context(pdp)); +} + +extern "C" esp_err_t esp_modem_command(esp_modem_dce_t *dce_wrap, const char *command, esp_err_t(*got_line_fn)(uint8_t *data, size_t len), uint32_t timeout_ms) +{ + if (dce_wrap == nullptr || dce_wrap->dce == nullptr || command == nullptr || got_line_fn == nullptr) { + return ESP_ERR_INVALID_ARG; + } + std::string cmd(command); + return command_response_to_esp_err(dce_wrap->dce->command(cmd, [got_line_fn](uint8_t *data, size_t len) { + switch (got_line_fn(data, len)) { + case ESP_OK: + return command_result::OK; + case ESP_FAIL: + return command_result::FAIL; + default: + return command_result::TIMEOUT; + } + }, timeout_ms)); +} + +extern "C" esp_err_t esp_modem_set_baud(esp_modem_dce_t *dce_wrap, int baud) +{ + return command_response_to_esp_err(dce_wrap->dce->set_baud(baud)); +} From 0254d50128b91825d9d3578c37fdf7d7bb88de04 Mon Sep 17 00:00:00 2001 From: David Cermak Date: Wed, 1 Nov 2023 17:08:26 +0100 Subject: [PATCH 2/3] fix(modem): Support for custom modules with C-API MAJOR CHANGE: Added support for implementing user defined modules in standard C-API --- components/esp_modem/CMakeLists.txt | 3 + components/esp_modem/Kconfig | 18 +++++ .../pppos_client/main/Kconfig.projbuild | 7 ++ .../pppos_client/main/custom_module.hpp | 79 +++++++++++++++++++ .../pppos_client/main/pppos_client_main.c | 19 +++++ .../cxx_include/esp_modem_dce_factory.hpp | 13 +-- .../esp_modem/include/esp_modem_c_api_types.h | 1 + components/esp_modem/src/esp_modem_c_api.cpp | 17 +++- docs/esp_modem/en/README.rst | 4 + 9 files changed, 152 insertions(+), 9 deletions(-) create mode 100644 components/esp_modem/examples/pppos_client/main/custom_module.hpp diff --git a/components/esp_modem/CMakeLists.txt b/components/esp_modem/CMakeLists.txt index 10d39577c7..447d94af77 100644 --- a/components/esp_modem/CMakeLists.txt +++ b/components/esp_modem/CMakeLists.txt @@ -42,6 +42,9 @@ set_target_properties(${COMPONENT_LIB} PROPERTIES CXX_EXTENSIONS ON ) +if(CONFIG_ESP_MODEM_ADD_CUSTOM_MODULE) + idf_component_optional_requires(PUBLIC main) +endif() if(${target} STREQUAL "linux") # This is needed for ESP_LOGx() macros, as integer formats differ on ESP32(..) and x64 diff --git a/components/esp_modem/Kconfig b/components/esp_modem/Kconfig index d4e6b282af..6896428d07 100644 --- a/components/esp_modem/Kconfig +++ b/components/esp_modem/Kconfig @@ -45,4 +45,22 @@ menu "esp-modem" to make the protocol more robust on noisy environments or when underlying transport gets corrupted often (for example by Rx buffer overflows) + config ESP_MODEM_ADD_CUSTOM_MODULE + bool "Add support for custom module in C-API" + default n + help + If enabled, we adapt the C-API to create a DCE from a user defined class + + config ESP_MODEM_CUSTOM_MODULE_HEADER + string "Header file name which defines custom DCE creation" + depends on ESP_MODEM_ADD_CUSTOM_MODULE + default "custom_module.hpp" + help + Name of the header file in the main component which implements esp_modem_create_custom_dce() + called from C-API for creating esp_modem_dce object. + This header provides definition of the custom module with some additional and/or updated commands + and API. It also defines creation of DCE based on this custom module, typically calling: + dce_factory::Factory::create_unique_dce_from(dce_config, std::move(dte), netif) + Please refer to the pppos_client example for more details. + endmenu diff --git a/components/esp_modem/examples/pppos_client/main/Kconfig.projbuild b/components/esp_modem/examples/pppos_client/main/Kconfig.projbuild index 07a61d59ff..8afc7bf989 100644 --- a/components/esp_modem/examples/pppos_client/main/Kconfig.projbuild +++ b/components/esp_modem/examples/pppos_client/main/Kconfig.projbuild @@ -48,6 +48,13 @@ menu "Example Configuration" bool "A7670" help A7670X is Multi-Band LTE-FDD/LTE-TDD/GSM/GPRS/EDGE module. + + config EXAMPLE_MODEM_DEVICE_CUSTOM + select ESP_MODEM_ADD_CUSTOM_MODULE + bool "Custom device" + help + This demonstrates use of a custom device in C-API. + endchoice config EXAMPLE_MODEM_PPP_APN diff --git a/components/esp_modem/examples/pppos_client/main/custom_module.hpp b/components/esp_modem/examples/pppos_client/main/custom_module.hpp new file mode 100644 index 0000000000..13125ba7d2 --- /dev/null +++ b/components/esp_modem/examples/pppos_client/main/custom_module.hpp @@ -0,0 +1,79 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +#pragma once +#include "cxx_include/esp_modem_api.hpp" +#include "cxx_include/esp_modem_command_library_utils.hpp" + +/** + * @brief Definition of a custom module based on some already defined module + * Here we use GenericModule, but you can use any kind of device + * that is closer to your CustomModule. + */ +class SIM7600_WITH_TIME: public GenericModule { + /** + * @brief Need to reuse the constructors of our ancestor + */ + using GenericModule::GenericModule; +public: + /** + * @brief New command that is not defined in the GenericModule + */ + command_result get_time(std::string &time) + { + return esp_modem::dce_commands::generic_get_string(dte.get(), "AT+CCLK?\r", time); + } + + /** + * @brief This command is already defined in the GenericModule + * + * Here we just modify get_signal_quality() to return zeroes + * for demonstration purpose only, since it's called within this example + */ + command_result get_signal_quality(int &rssi, int &ber) override + { + rssi = ber = 0; + return esp_modem::command_result::OK; + } + +}; + +/** + * @brief esp_modem_create_custom_dce() needs to be defined, as it is called in C-API wrapper when creating esp_modem_dce + * + * This uses public factory function for creating a common DCE with our CustomModule. Creating raw DCE pointer is only needed + * for the C-API wrapper; C++API users would create DCE (any kind of smart pointer) directly with + * Factory::create_unique_dce_from(dce_config, std::move(dte), netif); + */ +DCE *esp_modem_create_custom_dce(const esp_modem_dce_config_t *dce_config, std::shared_ptr dte, esp_netif_t *netif) +{ + return dce_factory::Factory::create_unique_dce_from(dce_config, std::move(dte), netif); +} + +/** + * @brief This API is only needed for extending standard C-API, since we added get_time() method to our CustomModule + * + * @note This header is included from esp_modem_c_api.cpp, so it could use ESP_MODEM_C_API_STR_MAX macro + * indicating maximum C-API string size + * + * @note In order to access the newly added API get_time(), we have to static_cast<> the GenericModule from DCE + * to our CustomModule. + * Alternatively we could use the modem Factory to build our specific DCE_T, but in that case + * we couldn't use our C-API wrappers which expect DCE type, DCE_T with lib commands (this alternative + * is cleaner, but more suitable for C++ users) + */ +extern "C" esp_err_t esp_modem_get_time(esp_modem_dce_t *dce_wrap, char *p_time) +{ + if (dce_wrap == nullptr || dce_wrap->dce == nullptr) { + return ESP_ERR_INVALID_ARG; + } + std::string time{ESP_MODEM_C_API_STR_MAX}; + auto ret = command_response_to_esp_err(static_cast(dce_wrap->dce->get_module())->get_time(time)); + if (ret == ESP_OK && !time.empty()) { + strlcpy(p_time, time.c_str(), ESP_MODEM_C_API_STR_MAX); + } + return ret; +} diff --git a/components/esp_modem/examples/pppos_client/main/pppos_client_main.c b/components/esp_modem/examples/pppos_client/main/pppos_client_main.c index cb5ff954ad..ba3d58a445 100644 --- a/components/esp_modem/examples/pppos_client/main/pppos_client_main.c +++ b/components/esp_modem/examples/pppos_client/main/pppos_client_main.c @@ -37,6 +37,10 @@ static const int CONNECT_BIT = BIT0; static const int GOT_DATA_BIT = BIT2; static const int USB_DISCONNECTED_BIT = BIT3; // Used only with USB DTE but we define it unconditionally, to avoid too many #ifdefs in the code +#ifdef CONFIG_EXAMPLE_MODEM_DEVICE_CUSTOM +esp_err_t esp_modem_get_time(esp_modem_dce_t *dce_wrap, char *p_time); +#endif + #if defined(CONFIG_EXAMPLE_SERIAL_CONFIG_USB) #include "esp_modem_usb_c_api.h" #include "esp_modem_usb_config.h" @@ -192,6 +196,9 @@ void app_main(void) #elif CONFIG_EXAMPLE_MODEM_DEVICE_SIM7600 == 1 ESP_LOGI(TAG, "Initializing esp_modem for the SIM7600 module..."); esp_modem_dce_t *dce = esp_modem_new_dev(ESP_MODEM_DCE_SIM7600, &dte_config, &dce_config, esp_netif); +#elif CONFIG_EXAMPLE_MODEM_DEVICE_CUSTOM == 1 + ESP_LOGI(TAG, "Initializing esp_modem with custom module..."); + esp_modem_dce_t *dce = esp_modem_new_dev(ESP_MODEM_DCE_CUSTOM, &dte_config, &dce_config, esp_netif); #else ESP_LOGI(TAG, "Initializing esp_modem for a generic module..."); esp_modem_dce_t *dce = esp_modem_new(&dte_config, &dce_config, esp_netif); @@ -258,6 +265,18 @@ void app_main(void) } ESP_LOGI(TAG, "Signal quality: rssi=%d, ber=%d", rssi, ber); +#ifdef CONFIG_EXAMPLE_MODEM_DEVICE_CUSTOM + { + char time[64]; + err = esp_modem_get_time(dce, time); + if (err != ESP_OK) { + ESP_LOGE(TAG, "esp_modem_get_time failed with %d %s", err, esp_err_to_name(err)); + return; + } + ESP_LOGI(TAG, "esp_modem_get_time: %s", time); + } +#endif + #if CONFIG_EXAMPLE_SEND_MSG if (esp_modem_sms_txt_mode(dce, true) != ESP_OK || esp_modem_sms_character_set(dce) != ESP_OK) { ESP_LOGE(TAG, "Setting text mode or GSM character set failed"); diff --git a/components/esp_modem/include/cxx_include/esp_modem_dce_factory.hpp b/components/esp_modem/include/cxx_include/esp_modem_dce_factory.hpp index 5bcb39070c..b3cac79da8 100644 --- a/components/esp_modem/include/cxx_include/esp_modem_dce_factory.hpp +++ b/components/esp_modem/include/cxx_include/esp_modem_dce_factory.hpp @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -12,6 +12,7 @@ * @brief DCE modem factory */ +#define esp_modem_create_dce_from dce_factory::Factory::create_unique_dce_from namespace esp_modem::dce_factory { @@ -236,12 +237,12 @@ class Factory { return nullptr; } - template - static std::unique_ptr create_unique_dce_from(const esp_modem::dce_config *config, - std::shared_ptr dte, - esp_netif_t *netif) + template > + static Ptr create_unique_dce_from(const esp_modem::dce_config *config, + std::shared_ptr dte, + esp_netif_t *netif) { - return build_generic_DCE>(config, std::move(dte), netif); + return build_generic_DCE(config, std::move(dte), netif); } private: diff --git a/components/esp_modem/include/esp_modem_c_api_types.h b/components/esp_modem/include/esp_modem_c_api_types.h index f47e2a064c..fcc54701c8 100644 --- a/components/esp_modem/include/esp_modem_c_api_types.h +++ b/components/esp_modem/include/esp_modem_c_api_types.h @@ -53,6 +53,7 @@ typedef enum esp_modem_dce_device { ESP_MODEM_DCE_SIM7000, ESP_MODEM_DCE_BG96, ESP_MODEM_DCE_SIM800, + ESP_MODEM_DCE_CUSTOM } esp_modem_dce_device_t; /** diff --git a/components/esp_modem/src/esp_modem_c_api.cpp b/components/esp_modem/src/esp_modem_c_api.cpp index ac4db3f72d..7178bda1a5 100644 --- a/components/esp_modem/src/esp_modem_c_api.cpp +++ b/components/esp_modem/src/esp_modem_c_api.cpp @@ -4,6 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include #include #include "cxx_include/esp_modem_dte.hpp" #include "uart_terminal.hpp" @@ -14,7 +15,6 @@ #include "esp_modem_config.h" #include "exception_stub.hpp" #include "esp_private/c_api_wrapper.hpp" -#include "cstring" #ifndef ESP_MODEM_C_API_STR_MAX #define ESP_MODEM_C_API_STR_MAX 64 @@ -24,6 +24,10 @@ size_t strlcpy(char *dest, const char *src, size_t len); #endif +#ifdef CONFIG_ESP_MODEM_ADD_CUSTOM_MODULE +#include CONFIG_ESP_MODEM_CUSTOM_MODULE_HEADER +#endif + // // C API definitions using namespace esp_modem; @@ -40,8 +44,15 @@ extern "C" esp_modem_dce_t *esp_modem_new_dev(esp_modem_dce_device_t module, con return nullptr; } dce_wrap->dte = dte; - dce_factory::Factory f(convert_modem_enum(module)); - dce_wrap->dce = f.build(dce_config, std::move(dte), netif); +#ifdef CONFIG_ESP_MODEM_ADD_CUSTOM_MODULE + if (module == ESP_MODEM_DCE_CUSTOM) { + dce_wrap->dce = esp_modem_create_custom_dce(dce_config, dte, netif); + } else +#endif + { + dce_factory::Factory f(convert_modem_enum(module)); + dce_wrap->dce = f.build(dce_config, std::move(dte), netif); + } if (dce_wrap->dce == nullptr) { delete dce_wrap; return nullptr; diff --git a/docs/esp_modem/en/README.rst b/docs/esp_modem/en/README.rst index e87ad5a274..4542b54471 100644 --- a/docs/esp_modem/en/README.rst +++ b/docs/esp_modem/en/README.rst @@ -110,6 +110,10 @@ commands might have a different implementation. Adding a new device means to provide a new implementation as a class derived from ``GenericModule``, where we could add new commands or modify the existing ones. +If you have to support a custom device with C-API, please refer to +the example ``examples/pppos_client`` and enable ``ESP_MODEM_ADD_CUSTOM_MODULE``. +For advanced use-case, mainly with C++ API and/or usage of esp_modem's +Factory class, please read . Configuration ------------- From 020b407472dac0e34f122f75cecbd09ca59b4b60 Mon Sep 17 00:00:00 2001 From: David Cermak Date: Thu, 2 Nov 2023 15:25:30 +0100 Subject: [PATCH 3/3] fix(modem): Fixed API docs within doxygen comments --- .../include/cxx_include/esp_modem_types.hpp | 1 + .../generate/esp_modem_command_declare.inc | 8 +++++--- docs/esp_modem/en/README.rst | 17 +++++++---------- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/components/esp_modem/include/cxx_include/esp_modem_types.hpp b/components/esp_modem/include/cxx_include/esp_modem_types.hpp index 513b1f8476..944427156d 100644 --- a/components/esp_modem/include/cxx_include/esp_modem_types.hpp +++ b/components/esp_modem/include/cxx_include/esp_modem_types.hpp @@ -76,6 +76,7 @@ class CommandableIf { * @param command Command to be sent * @param got_line callback if a line received * @param time_ms timeout in milliseconds + * @param separator Character treated as a line separator, typically '\n' * @return OK, FAIL or TIMEOUT */ virtual command_result command(const std::string &command, got_line_cb got_line, uint32_t time_ms, const char separator) = 0; diff --git a/components/esp_modem/include/generate/esp_modem_command_declare.inc b/components/esp_modem/include/generate/esp_modem_command_declare.inc index 3664963e52..70f3a83be8 100644 --- a/components/esp_modem/include/generate/esp_modem_command_declare.inc +++ b/components/esp_modem/include/generate/esp_modem_command_declare.inc @@ -25,8 +25,8 @@ ESP_MODEM_DECLARE_DCE_COMMAND(sync, command_result, 0) \ \ /** * @brief Reads the operator name - * @param[out] operator name - * @param[out] access technology + * @param[out] name operator name + * @param[out] act access technology * @return OK, FAIL or TIMEOUT */ \ ESP_MODEM_DECLARE_DCE_COMMAND(get_operator_name, command_result, 2, STRING_OUT(p1, name), INT_OUT(p2, act)) \ @@ -46,7 +46,7 @@ ESP_MODEM_DECLARE_DCE_COMMAND(set_pin, command_result, 1, STRING_IN(p1, pin)) \ \ /** * @brief Execute the supplied AT command - * @param[in] at AT command + * @param[in] cmd AT command * @param[out] out Command output string * @param[in] timeout AT command timeout in milliseconds * @return OK, FAIL or TIMEOUT @@ -252,6 +252,8 @@ ESP_MODEM_DECLARE_DCE_COMMAND(set_preferred_mode, command_result, 1, INT_IN(p1, /** * @brief Set network bands for CAT-M or NB-IoT * @param[in] mode CAT-M or NB-IoT + * @param[in] bands bitmap in hex representing bands + * @param[in] size size of teh bands bitmap * @return OK, FAIL or TIMEOUT */ \ ESP_MODEM_DECLARE_DCE_COMMAND(set_network_bands, command_result, 3, STRING_IN(p1, mode), INTEGER_LIST_IN(p2, bands), INT_IN(p3, size)) \ diff --git a/docs/esp_modem/en/README.rst b/docs/esp_modem/en/README.rst index 4542b54471..cab8b87459 100644 --- a/docs/esp_modem/en/README.rst +++ b/docs/esp_modem/en/README.rst @@ -67,22 +67,19 @@ supports SIM800, BG96, SIM7600. Use cases --------- -Users interact with the esp-modem using the DCE’s interface, to -basically +Users interact with the esp-modem using the DCE's interface, to basically - Switch between command and data mode to connect to the internet via cellular network. -- Send various commands to the device (e.g. send SMS) +- Send various commands to the device (e.g. send SMS) The applications typically register handlers for network events to receive notification on the network availability and IP address changes. Common use cases of the esp-modem are also listed as the examples: -- ``examples/pppos_client`` – simple client which reads some module properties and switches to the data mode to connect to a public mqtt broker. -- ``examples/modem_console`` – is an example to exercise all possible module commands in a console application. -- ``examples/ap_to_pppos`` – this example focuses on the network -connectivity of the esp-modem and provides a WiFi AP that forwards -packets (and uses NAT) to and from the PPPoS connection. +- ``examples/pppos_client`` simple client which reads some module properties and switches to the data mode to connect to a public mqtt broker. +- ``examples/modem_console`` is an example to exercise all possible module commands in a console application. +- ``examples/ap_to_pppos`` this example focuses on the network connectivity of the esp-modem and provides a WiFi AP that forwards packets (and uses NAT) to and from the PPPoS connection. Extensibility ------------- @@ -95,8 +92,8 @@ allows users to also issue commands in the data mode, after creating multiple virtual terminals, designating some of them solely to data mode, others solely to command mode. -DTE’s -~~~~~ +DTE +~~~ Currently, we support only UART (and USB as a preview feature), but modern modules support other communication interfaces, such as USB, SPI.