From 8560f02191b194e804b0c5c54cef8733e93cb1e9 Mon Sep 17 00:00:00 2001 From: robbedptechnics Date: Wed, 19 Mar 2025 14:45:32 +0100 Subject: [PATCH 1/4] feat(module): add support for sequans GM02S modem --- .../include/cxx_include/esp_modem_api.hpp | 6 +- .../cxx_include/esp_modem_dce_factory.hpp | 7 ++ .../cxx_include/esp_modem_dce_module.hpp | 9 +++ .../esp_modem/include/esp_modem_c_api_types.h | 1 + .../generate/esp_modem_command_declare.inc | 64 ++++++++++++++++- components/esp_modem/src/esp_modem_api.cpp | 5 ++ components/esp_modem/src/esp_modem_c_api.cpp | 68 +++++++++++++++++++ .../src/esp_modem_command_library.cpp | 65 ++++++++++++++++++ .../esp_modem/src/esp_modem_modules.cpp | 55 +++++++++++++++ 9 files changed, 278 insertions(+), 2 deletions(-) diff --git a/components/esp_modem/include/cxx_include/esp_modem_api.hpp b/components/esp_modem/include/cxx_include/esp_modem_api.hpp index 690d7b324..33a76ef01 100644 --- a/components/esp_modem/include/cxx_include/esp_modem_api.hpp +++ b/components/esp_modem/include/cxx_include/esp_modem_api.hpp @@ -84,7 +84,6 @@ std::unique_ptr create_SIM7070_dce(const dce_config *config, std::shared_pt */ std::unique_ptr create_SIM7000_dce(const dce_config *config, std::shared_ptr dte, esp_netif_t *netif); - /** * @brief Create DCE based on SIM800 module */ @@ -95,6 +94,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 DCE based on Sequans GM02S module + */ +std::unique_ptr create_SQNGM02S_dce(const dce_config *config, std::shared_ptr dte, esp_netif_t *netif); + /** * @brief Create generic DCE */ 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 b3cac79da..faa4b179e 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 @@ -118,6 +118,7 @@ enum class ModemType { SIM7000, /*!< Derived from the GenericModule, specifics applied to SIM7000 model */ BG96, /*!< Derived from the GenericModule, specifics applied to BG69 model */ SIM800, /*!< Derived from the GenericModule with specifics applied to SIM800 model */ + SQNGM02S, /*!< Derived from the GenericModule, specifics applied to GM02S model */ }; /** @@ -178,6 +179,8 @@ public: return build_shared_module(cfg, std::forward(args)...); case ModemType::BG96: return build_shared_module(cfg, std::forward(args)...); + case ModemType::SQNGM02S: + return build_shared_module(cfg, std::forward(args)...); case ModemType::GenericModule: return build_shared_module(cfg, std::forward(args)...); default: @@ -207,6 +210,8 @@ public: return build_unique(cfg, std::forward(args)...); case ModemType::BG96: return build_unique(cfg, std::forward(args)...); + case ModemType::SQNGM02S: + return build_unique(cfg, std::forward(args)...); case ModemType::GenericModule: return build_unique(cfg, std::forward(args)...); default: @@ -229,6 +234,8 @@ public: return build(cfg, std::forward(args)...); case ModemType::BG96: return build(cfg, std::forward(args)...); + case ModemType::SQNGM02S: + return build(cfg, std::forward(args)...); case ModemType::GenericModule: return build(cfg, std::forward(args)...); default: diff --git a/components/esp_modem/include/cxx_include/esp_modem_dce_module.hpp b/components/esp_modem/include/cxx_include/esp_modem_dce_module.hpp index ad32bd601..46fc356d2 100644 --- a/components/esp_modem/include/cxx_include/esp_modem_dce_module.hpp +++ b/components/esp_modem/include/cxx_include/esp_modem_dce_module.hpp @@ -177,6 +177,15 @@ public: command_result set_pdp_context(PdpContext &pdp) override; }; +class SQNGM02S : public GenericModule +{ + using GenericModule::GenericModule; + +public: + command_result connect(PdpContext &pdp); + bool setup_data_mode() override; +}; + /** * @} */ 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 b82e929b6..9b454f155 100644 --- a/components/esp_modem/include/esp_modem_c_api_types.h +++ b/components/esp_modem/include/esp_modem_c_api_types.h @@ -60,6 +60,7 @@ typedef enum esp_modem_dce_device { ESP_MODEM_DCE_BG96, ESP_MODEM_DCE_EC20, ESP_MODEM_DCE_SIM800, + ESP_MODEM_DCE_SQNGM02S, ESP_MODEM_DCE_CUSTOM } esp_modem_dce_device_t; 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 0f7b122f3..a158b3395 100644 --- a/components/esp_modem/include/generate/esp_modem_command_declare.inc +++ b/components/esp_modem/include/generate/esp_modem_command_declare.inc @@ -290,7 +290,69 @@ ESP_MODEM_DECLARE_DCE_COMMAND(set_gnss_power_mode, command_result, 1, INT_IN(p1, */ \ ESP_MODEM_DECLARE_DCE_COMMAND(get_gnss_power_mode, command_result, 1, INT_OUT(p1, mode)) \ \ - +/** + * @brief Configure PSM + * @param[in] mode psm mode (0 - off, 1 - on, 2 - off & discard stored params) + * @return OK, FAIL or TIMEOUT + */ \ +ESP_MODEM_DECLARE_DCE_COMMAND(config_psm, command_result, 3, INT_IN(p1, mode), STRING_IN(p2, tau), STRING_IN(p3, active_time)) \ + \ +/** + * @brief Configure CEREG urc + * @param[in] value + * value = 0 - Disable network URC + * value = 1 - Enable network URC + * value = 2 - Enable network URC with location information + * value = 3 - Enable network URC with location information and EMM cause + * value = 4 - Enable network URC with location information and PSM value + * value = 5 - Enable network URC with location information and PSM value, EMM cause + */ \ +ESP_MODEM_DECLARE_DCE_COMMAND(config_network_registration_urc, command_result, 1, INT_IN(p1, value)) \ + \ +/** + * @brief Gets the current network registration state + * @param[out] state The current network registration state + * state = 0 - Not registered, MT is not currently searching an operator to register to + * state = 1 - Registered, home network + * state = 2 - Not registered, but MT is currently trying to attach or searching an operator to register to + * state = 3 - Registration denied + * state = 4 - Unknown + * state = 5 - Registered, Roaming + * state = 6 - Registered, for SMS only, home network (NB-IoT only) + * state = 7 - Registered, for SMS only, roaming (NB-IoT only) + * state = 8 - Attached for emergency bearer services only + * state = 9 - Registered for CSFB not preferred, home network + * state = 10 - Registered for CSFB not preferred, roaming + */ \ +ESP_MODEM_DECLARE_DCE_COMMAND(get_network_registration_state, command_result, 1, INT_OUT(p1,state)) \ + \ +/** + * @brief Configures the mobile termination error (+CME ERROR) + * @param[in] mode The form of the final result code + * mode = 0 - Disable, use and send ERROR instead + * mode = 1 - Enable, use numeric error values + * mode = 2 - Enable, result code and use verbose error values + */ \ +ESP_MODEM_DECLARE_DCE_COMMAND(config_mobile_termination_error, command_result, 1, INT_IN(p1, mode)) \ + \ +/** + * @brief Configure eDRX + * @param[in] mode + * mode = 0 - Disable + * mode = 1 - Enable + * mode = 2 - Enable + URC + * mode = 3 - Disable + Reset parameter. + * @param[in] access_technology + * act = 0 - ACT is not using eDRX (used in URC) + * act = 1 - EC-GSM-IoT (A/Gb mode) + * act = 2 - GSM (A/Gb mode) + * act = 3 - UTRAN (Iu mode) + * act = 4 - E-UTRAN (WB-S1 mode) + * act = 5 - E-UTRAN (NB-S1 mode) + * @param[in] edrx_value nible string containing encoded eDRX time + * @param[in] ptw_value nible string containing encoded Paging Time Window + */ \ +ESP_MODEM_DECLARE_DCE_COMMAND(config_edrx, command_result, 3, INT_IN(p1, mode), INT_IN(p2, access_technology), STRING_IN(p3, edrx_value), STRING_IN(p4, ptw_value)) \ #ifdef GENERATE_DOCS // cat ../include/generate/esp_modem_command_declare.inc | clang++ -E -P -CC -xc++ -I../include -DGENERATE_DOCS - | sed -n '1,/DCE command documentation/!p' diff --git a/components/esp_modem/src/esp_modem_api.cpp b/components/esp_modem/src/esp_modem_api.cpp index 832774d0a..9cc9d511f 100644 --- a/components/esp_modem/src/esp_modem_api.cpp +++ b/components/esp_modem/src/esp_modem_api.cpp @@ -66,6 +66,11 @@ std::unique_ptr create_BG96_dce(const dce_config *config, std::shared_ptr create_SQNGM02S_dce(const dce_config *config, std::shared_ptr dte, esp_netif_t *netif) +{ + return create_modem_dce(dce_factory::ModemType::SQNGM02S, config, std::move(dte), netif); +} + std::unique_ptr create_generic_dce(const dce_config *config, std::shared_ptr dte, esp_netif_t *netif) { return create_modem_dce(dce_factory::ModemType::GenericModule, config, std::move(dte), netif); diff --git a/components/esp_modem/src/esp_modem_c_api.cpp b/components/esp_modem/src/esp_modem_c_api.cpp index e9698995e..1d4d5ac3b 100644 --- a/components/esp_modem/src/esp_modem_c_api.cpp +++ b/components/esp_modem/src/esp_modem_c_api.cpp @@ -439,6 +439,74 @@ extern "C" esp_err_t esp_modem_get_gnss_power_mode(esp_modem_dce_t *dce_wrap, in return ret; } +extern "C" esp_err_t esp_modem_config_psm(esp_modem_dce_t *dce_wrap, int mode, const char *tau, const char *active_time) +{ + if (dce_wrap == nullptr || dce_wrap->dce == nullptr || mode > 3) { + return ESP_ERR_INVALID_ARG; + } + + if (mode == 1 && (strlen(tau) != 8 || strlen(active_time) != 8)) { + return ESP_ERR_INVALID_ARG; + } + + return command_response_to_esp_err(dce_wrap->dce->config_psm(mode, std::string(tau), std::string(active_time))); +} + +extern "C" esp_err_t esp_modem_config_network_registration_urc(esp_modem_dce_t *dce_wrap, int value) +{ + if (dce_wrap == nullptr || dce_wrap->dce == nullptr || value > 5) + { + return ESP_ERR_INVALID_ARG; + } + + return command_response_to_esp_err(dce_wrap->dce->configure_network_registration_urc(value)); +} + +extern "C" esp_err_t esp_modem_get_network_registration_state(esp_modem_dce_t *dce_wrap, int *p_state) +{ + if (dce_wrap == nullptr || dce_wrap->dce == nullptr || p_state == nullptr) + { + return ESP_ERR_INVALID_ARG; + } + + int state; + auto ret = command_response_to_esp_err(dce_wrap->dce->get_network_registration_state(state)); + + if (ret == ESP_OK) + { + *p_state = state; + } + return ret; +} + +extern "C" esp_err_t esp_modem_config_mobile_termination_error(esp_modem_dce_t *dce_wrap, int mode) +{ + if (dce_wrap == nullptr || dce_wrap->dce == nullptr || mode > 2) + { + return ESP_ERR_INVALID_ARG; + } + + return command_response_to_esp_err(dce_wrap->dce->config_mobile_termination_error(mode)); +} + +extern "C" esp_err_t esp_modem_config_edrx(esp_modem_dce_t *dce, int value, const char *access_technology) +{ + +} + +extern "C" esp_err_t esp_modem_sqns_gm02s_connect(esp_modem_dce_t *dce, const esp_modem_PdpContext_t *pdp_context) +{ + if (dce_wrap == nullptr || dce_wrap->dce == nullptr || dce_wrap->modem_type != ESP_MODEM_DCE_SQNGM02S) + { + return ESP_ERR_INVALID_ARG; + } + + esp_modem::PdpContext pdp{pdp_context->apn}; + pdp.context_id = pdp_context->context_id; + pdp.protocol_type = pdp_context->protocol_type; + return command_response_to_esp_err(static_cast(dce_wrap->dce->get_module())->connect(pdp)); +} + extern "C" esp_err_t esp_modem_reset(esp_modem_dce_t *dce_wrap) { return command_response_to_esp_err(dce_wrap->dce->reset()); diff --git a/components/esp_modem/src/esp_modem_command_library.cpp b/components/esp_modem/src/esp_modem_command_library.cpp index 6f06bb7bd..c48ff60bf 100644 --- a/components/esp_modem/src/esp_modem_command_library.cpp +++ b/components/esp_modem/src/esp_modem_command_library.cpp @@ -607,6 +607,71 @@ command_result get_gnss_power_mode(CommandableIf *t, int &mode) return command_result::OK; } +command_result config_psm(CommandableIf *t, int enabled, const std::string &TAU, const std::string &activeTime) +{ + ESP_LOGV(TAG, "%s", __func__); + if (enabled == true) + { + return generic_command_common(t, "AT+CPSMS=1,,,\"" + TAU + "\"" + ",\"" + activeTime + "\"\r", 500); + } + return generic_command_common(t, "AT+CPSMS=" + std::to_string(enabled), 500); +} + +command_result config_network_registration_urc(CommandableIf *t, int value) +{ + ESP_LOGV(TAG, "%s", __func__); + return generic_command_common(t,"AT+CEREG=" + std::to_string(state) + "\r", 500); +} + +command_result get_network_registration_state(CommandableIf *t, int& state) +{ + ESP_LOGV(TAG, "%s", __func__); + std::string out; + + auto ret = generic_get_string(t, "AT+CEREG?\r", out, 500); + if (ret != command_result::OK) { + return ret; + } + + constexpr std::string_view pattern = "+CEREG: "; + int state_pos_start; + int state_pos_end; + if (out.find(pattern) == std::string::npos || (state_pos_start = out.find(',')) == std::string::npos) { + return command_result::FAIL; + } + + if (out.find(pattern) == std::string::npos || (state_pos_end = out.find(',',state_pos_start)) == std::string::npos){ + if (std::from_chars(out.data() + state_pos_start, out.data() + out.size(), state).ec == std::errc::invalid_argument) { + return command_result::FAIL; + } + } else if (std::from_chars(out.data() + state_pos_start, out.data() + state_pos_end, state).ec == std::errc::invalid_argument) { + return command_result::FAIL; + } + + return command_result::OK; +} + +command_result config_mobile_termination_error(CommandableIf *t, int value) +{ + ESP_LOGV(TAG, "%s", __func__); + return generic_command_common(t, "AT+CMEE=" + std::to_string(value) + "\r"); +} +command_result config_edrx(int mode, int access_technology, const std::string &edrx_value, const std::string &ptw_value) +{ + if (mode == 1 || enabled == 2) + { + return dce_commands::generic_command_common(dte.get(), + "AT+SQNEDRX=" + + std::to_string(mode) + + "," + + std::to_string(access_technology) + + ",\"" + + edrx_value + + "\",\"" + + ptw_value + "\"\r"); + } + return dce_commands::generic_command_common(dte.get(), "AT+SQNEDRX=" + std::to_string(mode), 500); +} command_result set_gnss_power_mode_sim76xx(CommandableIf *t, int mode) { ESP_LOGV(TAG, "%s", __func__ ); diff --git a/components/esp_modem/src/esp_modem_modules.cpp b/components/esp_modem/src/esp_modem_modules.cpp index 563403494..033f9c433 100644 --- a/components/esp_modem/src/esp_modem_modules.cpp +++ b/components/esp_modem/src/esp_modem_modules.cpp @@ -87,4 +87,59 @@ command_result BG96::set_pdp_context(esp_modem::PdpContext &pdp) return dce_commands::set_pdp_context(dte.get(), pdp, 300); } +command_result urc_callback(uint8_t *line, size_t len) +{ + ESP_LOGI("WalterModem", "Received: %s", line); + if (strstr((const char *)line, "+CEREG: 1")) + { + return command_result::OK; // Succesfully registered + } + else if (strstr((const char *)line, "+CEREG: 5")) + { + return command_result::OK; // Succesfully registered + } + else if (strstr((const char *)line, "+CEREG: 3")) + { + return command_result::FAIL; // Permission denied + } + return command_result::TIMEOUT; +} + +command_result SQNGM02S::connect(PdpContext &pdp) +{ + command_result res; + res = set_pdp_context(pdp); + if (res != command_result::OK) + return res; + res = config_network_registration_urc(1); + if (res != command_result::OK) + return res; + + res = set_radio_state(1); + if (res != command_result::OK) + return res; + + //wait for +CEREG: 5 or +CEREG: 1. + + do + { + res = dte->command("", urc_callback, 20000, '\r'); + } while (res == command_result::TIMEOUT); + + if (res != command_result::OK) + return res; + + res = config_network_registration_urc(0); + if (res != command_result::OK) + return res; + + return command_result::OK; +} + +bool SQNGM02S::setup_data_mode() +{ + ESP_LOGI("SQNGM02S", "setyp data mode"); + return set_echo(false) == command_result::OK; + // PDP context has already been set before hand because SEQUANS modem must have already been connected/registered before setting up cmux +} } From b97dfc08b8fef08568183e2df071fc975a487099 Mon Sep 17 00:00:00 2001 From: robbedptechnics Date: Wed, 19 Mar 2025 15:02:20 +0100 Subject: [PATCH 2/4] feat(modem): added sqn_gm02s connect function --- .../esp_modem/include/esp_modem_c_api_types.h | 2 ++ components/esp_modem/src/esp_modem_c_api.cpp | 25 +++++++++++-------- 2 files changed, 17 insertions(+), 10 deletions(-) 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 9b454f155..17f39444b 100644 --- a/components/esp_modem/include/esp_modem_c_api_types.h +++ b/components/esp_modem/include/esp_modem_c_api_types.h @@ -163,6 +163,8 @@ esp_err_t esp_modem_set_apn(esp_modem_dce_t *dce, const char *apn); esp_err_t esp_modem_set_urc(esp_modem_dce_t *dce, esp_err_t(*got_line_cb)(uint8_t *data, size_t len)); #endif +esp_err_t esp_modem_sqns_gm02s_connect(esp_modem_dce_t *dce, const esp_modem_PdpContext_t *pdp_context); + /** * @brief This API provides support for temporarily pausing networking in order * to send/receive AT commands and resume networking afterwards. diff --git a/components/esp_modem/src/esp_modem_c_api.cpp b/components/esp_modem/src/esp_modem_c_api.cpp index 1d4d5ac3b..b763b38c5 100644 --- a/components/esp_modem/src/esp_modem_c_api.cpp +++ b/components/esp_modem/src/esp_modem_c_api.cpp @@ -459,21 +459,19 @@ extern "C" esp_err_t esp_modem_config_network_registration_urc(esp_modem_dce_t * return ESP_ERR_INVALID_ARG; } - return command_response_to_esp_err(dce_wrap->dce->configure_network_registration_urc(value)); + return command_response_to_esp_err(dce_wrap->dce->config_network_registration_urc(value)); } extern "C" esp_err_t esp_modem_get_network_registration_state(esp_modem_dce_t *dce_wrap, int *p_state) { - if (dce_wrap == nullptr || dce_wrap->dce == nullptr || p_state == nullptr) - { + if (dce_wrap == nullptr || dce_wrap->dce == nullptr || p_state == nullptr) { return ESP_ERR_INVALID_ARG; } int state; auto ret = command_response_to_esp_err(dce_wrap->dce->get_network_registration_state(state)); - if (ret == ESP_OK) - { + if (ret == ESP_OK) { *p_state = state; } return ret; @@ -481,22 +479,29 @@ extern "C" esp_err_t esp_modem_get_network_registration_state(esp_modem_dce_t *d extern "C" esp_err_t esp_modem_config_mobile_termination_error(esp_modem_dce_t *dce_wrap, int mode) { - if (dce_wrap == nullptr || dce_wrap->dce == nullptr || mode > 2) - { + if (dce_wrap == nullptr || dce_wrap->dce == nullptr || mode > 2) { return ESP_ERR_INVALID_ARG; } return command_response_to_esp_err(dce_wrap->dce->config_mobile_termination_error(mode)); } -extern "C" esp_err_t esp_modem_config_edrx(esp_modem_dce_t *dce, int value, const char *access_technology) +extern "C" esp_err_t esp_modem_config_edrx(esp_modem_dce_t *dce, int mode, int access_technology, const char *edrx_value, const char *ptw_value) { + if (dce_wrap == nullptr || dce_wrap->dce == nullptr || mode > 3 || access_technology > 5) { + return ESP_ERR_INVALID_ARG; + } + if ((mode == 1 || mode == 2 ) && (strlen(edrx_value) != 4 || strlen(ptw_value) != 4)) { + return ESP_ERR_INVALID_ARG; + } + + return command_response_to_esp_err(dce_wrap->dce->config_edrx(mode,access_technology,std::string(edrx_value),std::string(ptw_value))); } -extern "C" esp_err_t esp_modem_sqns_gm02s_connect(esp_modem_dce_t *dce, const esp_modem_PdpContext_t *pdp_context) +extern "C" esp_err_t esp_modem_sqns_gm02s_connect(esp_modem_dce_t *dce_wrap, const esp_modem_PdpContext_t *pdp_context) { - if (dce_wrap == nullptr || dce_wrap->dce == nullptr || dce_wrap->modem_type != ESP_MODEM_DCE_SQNGM02S) + if (dce_wrap == nullptr || dce_wrap->dce == nullptr) { return ESP_ERR_INVALID_ARG; } From 317faf89ff3f953f426a0f1908f99350302d1390 Mon Sep 17 00:00:00 2001 From: robbedptechnics Date: Wed, 19 Mar 2025 15:46:04 +0100 Subject: [PATCH 3/4] fix(modem): fixed minor code mistakes. --- .pre-commit-config.yaml | 16 +- .../esp_modem_command_library_17.hpp | 19 +++ .../cxx_include/esp_modem_dce_module.hpp | 7 +- .../include/esp_private/c_api_wrapper.hpp | 2 + .../generate/esp_modem_command_declare.inc | 2 +- components/esp_modem/src/esp_modem_c_api.cpp | 2 +- .../src/esp_modem_command_library.cpp | 143 +++++++++--------- .../esp_modem/src/esp_modem_modules.cpp | 55 +++---- 8 files changed, 123 insertions(+), 123 deletions(-) create mode 100644 components/esp_modem/include/cxx17_include/esp_modem_command_library_17.hpp diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 93dde2c6a..c0137d145 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -2,7 +2,7 @@ # See https://pre-commit.com/hooks.html for more hooks repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.3.0 + rev: v5.0.0 hooks: - id: check-yaml - id: check-added-large-files @@ -13,12 +13,12 @@ repos: - id: mixed-line-ending - id: debug-statements - repo: https://github.com/pycqa/flake8 - rev: 5.0.4 + rev: 7.1.2 hooks: - id: flake8 args: ['--config=.flake8', '--tee', '--benchmark'] - repo: https://github.com/pre-commit/mirrors-mypy - rev: v0.981 + rev: v1.14.1 hooks: - id: mypy exclude: > @@ -39,25 +39,25 @@ repos: hooks: - id: isort - repo: https://github.com/myint/eradicate/ - rev: v2.1.0 + rev: 2.3.0 hooks: - id: eradicate - repo: https://github.com/espressif/check-copyright/ - rev: v1.0.3 + rev: v1.1.0 hooks: - id: check-copyright args: ['--ignore', 'ci/check_copyright_ignore.txt', '--config', 'ci/check_copyright_config.yaml'] - repo: https://github.com/igrr/astyle_py.git - rev: v1.0.5 + rev: v1.1.0 hooks: - id: astyle_py args: ['--style=otbs', '--attach-namespaces', '--attach-classes', '--indent=spaces=4', '--convert-tabs', '--align-reference=name', '--keep-one-line-statements', '--pad-header', '--pad-oper', '--unpad-paren', '--max-continuation-indent=120', '--exclude-list=ci/ignore_astyle.txt'] - repo: https://github.com/commitizen-tools/commitizen - rev: v2.42.1 + rev: v4.4.1 hooks: - id: commitizen - id: commitizen-branch - stages: [push, manual] + stages: [pre-push, manual] - repo: local hooks: - id: commit message scopes diff --git a/components/esp_modem/include/cxx17_include/esp_modem_command_library_17.hpp b/components/esp_modem/include/cxx17_include/esp_modem_command_library_17.hpp new file mode 100644 index 000000000..6992e1d86 --- /dev/null +++ b/components/esp_modem/include/cxx17_include/esp_modem_command_library_17.hpp @@ -0,0 +1,19 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include "esp_log.h" +#include "cxx_include/esp_modem_dte.hpp" +#include "cxx_include/esp_modem_dce_module.hpp" + +static const char *TAG = "command_lib"; + +namespace esp_modem::dce_commands { +command_result generic_command(CommandableIf *t, const std::string &command, + const std::list &pass_phrase, + const std::list &fail_phrase, + uint32_t timeout_ms); +} diff --git a/components/esp_modem/include/cxx_include/esp_modem_dce_module.hpp b/components/esp_modem/include/cxx_include/esp_modem_dce_module.hpp index 46fc356d2..4f8f0c94c 100644 --- a/components/esp_modem/include/cxx_include/esp_modem_dce_module.hpp +++ b/components/esp_modem/include/cxx_include/esp_modem_dce_module.hpp @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -115,7 +115,7 @@ public: #define ESP_MODEM_DECLARE_DCE_COMMAND(name, return_type, num, ...) \ virtual return_type name(__VA_ARGS__); - DECLARE_ALL_COMMAND_APIS(virtual return_type name(...); ) + DECLARE_ALL_COMMAND_APIS(virtual return_type name(...);) #undef ESP_MODEM_DECLARE_DCE_COMMAND @@ -177,8 +177,7 @@ public: command_result set_pdp_context(PdpContext &pdp) override; }; -class SQNGM02S : public GenericModule -{ +class SQNGM02S : public GenericModule { using GenericModule::GenericModule; public: diff --git a/components/esp_modem/include/esp_private/c_api_wrapper.hpp b/components/esp_modem/include/esp_private/c_api_wrapper.hpp index 7a60304e9..0678f5507 100644 --- a/components/esp_modem/include/esp_private/c_api_wrapper.hpp +++ b/components/esp_modem/include/esp_private/c_api_wrapper.hpp @@ -43,6 +43,8 @@ inline dce_factory::ModemType convert_modem_enum(esp_modem_dce_device_t module) return esp_modem::dce_factory::ModemType::BG96; case ESP_MODEM_DCE_SIM800: return esp_modem::dce_factory::ModemType::SIM800; + case ESP_MODEM_DCE_SQNGM02S: + return esp_modem::dce_factory::ModemType::SQNGM02S; default: case ESP_MODEM_DCE_GENERIC: return esp_modem::dce_factory::ModemType::GenericModule; 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 a158b3395..a984cf034 100644 --- a/components/esp_modem/include/generate/esp_modem_command_declare.inc +++ b/components/esp_modem/include/generate/esp_modem_command_declare.inc @@ -352,7 +352,7 @@ ESP_MODEM_DECLARE_DCE_COMMAND(config_mobile_termination_error, command_result, 1 * @param[in] edrx_value nible string containing encoded eDRX time * @param[in] ptw_value nible string containing encoded Paging Time Window */ \ -ESP_MODEM_DECLARE_DCE_COMMAND(config_edrx, command_result, 3, INT_IN(p1, mode), INT_IN(p2, access_technology), STRING_IN(p3, edrx_value), STRING_IN(p4, ptw_value)) \ +ESP_MODEM_DECLARE_DCE_COMMAND(config_edrx, command_result, 3, INT_IN(p1, mode), INT_IN(p2, access_technology), STRING_IN(p3, edrx_value)) \ #ifdef GENERATE_DOCS // cat ../include/generate/esp_modem_command_declare.inc | clang++ -E -P -CC -xc++ -I../include -DGENERATE_DOCS - | sed -n '1,/DCE command documentation/!p' diff --git a/components/esp_modem/src/esp_modem_c_api.cpp b/components/esp_modem/src/esp_modem_c_api.cpp index b763b38c5..75250a0f6 100644 --- a/components/esp_modem/src/esp_modem_c_api.cpp +++ b/components/esp_modem/src/esp_modem_c_api.cpp @@ -486,7 +486,7 @@ extern "C" esp_err_t esp_modem_config_mobile_termination_error(esp_modem_dce_t * return command_response_to_esp_err(dce_wrap->dce->config_mobile_termination_error(mode)); } -extern "C" esp_err_t esp_modem_config_edrx(esp_modem_dce_t *dce, int mode, int access_technology, const char *edrx_value, const char *ptw_value) +extern "C" esp_err_t esp_modem_config_edrx(esp_modem_dce_t *dce_wrap, int mode, int access_technology, const char *edrx_value, const char *ptw_value) { if (dce_wrap == nullptr || dce_wrap->dce == nullptr || mode > 3 || access_technology > 5) { return ESP_ERR_INVALID_ARG; diff --git a/components/esp_modem/src/esp_modem_command_library.cpp b/components/esp_modem/src/esp_modem_command_library.cpp index c48ff60bf..a29284a24 100644 --- a/components/esp_modem/src/esp_modem_command_library.cpp +++ b/components/esp_modem/src/esp_modem_command_library.cpp @@ -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 */ @@ -12,14 +12,15 @@ #include "cxx_include/esp_modem_command_library.hpp" #include "cxx_include/esp_modem_command_library_utils.hpp" +#include "cxx17_include/esp_modem_command_library_17.hpp" + namespace esp_modem::dce_commands { -static const char *TAG = "command_lib"; -static command_result generic_command(CommandableIf *t, const std::string &command, - const std::list &pass_phrase, - const std::list &fail_phrase, - uint32_t timeout_ms) +command_result generic_command(CommandableIf *t, const std::string &command, + const std::list &pass_phrase, + const std::list &fail_phrase, + uint32_t timeout_ms) { ESP_LOGD(TAG, "%s command %s\n", __func__, command.c_str()); return t->command(command, [&](uint8_t *data, size_t len) { @@ -45,7 +46,7 @@ command_result generic_command(CommandableIf *t, const std::string &command, const std::string &pass_phrase, const std::string &fail_phrase, uint32_t timeout_ms) { - ESP_LOGV(TAG, "%s", __func__ ); + ESP_LOGV(TAG, "%s", __func__); const auto pass = std::list({pass_phrase}); const auto fail = std::list({fail_phrase}); return generic_command(t, command, pass, fail, timeout_ms); @@ -81,7 +82,7 @@ bool set(std::span &dest, std::string_view &src) template command_result generic_get_string(CommandableIf *t, const std::string &command, T &output, uint32_t timeout_ms) { - ESP_LOGV(TAG, "%s", __func__ ); + ESP_LOGV(TAG, "%s", __func__); return t->command(command, [&](uint8_t *data, size_t len) { size_t pos = 0; std::string_view response((char *)data, len); @@ -110,67 +111,67 @@ template command_result generic_get_string(CommandableIf *t, const command_result generic_command_common(CommandableIf *t, const std::string &command, uint32_t timeout_ms) { - ESP_LOGV(TAG, "%s", __func__ ); + ESP_LOGV(TAG, "%s", __func__); return generic_command(t, command, "OK", "ERROR", timeout_ms); } command_result sync(CommandableIf *t) { - ESP_LOGV(TAG, "%s", __func__ ); + ESP_LOGV(TAG, "%s", __func__); return generic_command_common(t, "AT\r"); } command_result store_profile(CommandableIf *t) { - ESP_LOGV(TAG, "%s", __func__ ); + ESP_LOGV(TAG, "%s", __func__); return generic_command_common(t, "AT&W\r"); } command_result power_down(CommandableIf *t) { - ESP_LOGV(TAG, "%s", __func__ ); + ESP_LOGV(TAG, "%s", __func__); return generic_command(t, "AT+QPOWD=1\r", "POWERED DOWN", "ERROR", 1000); } command_result power_down_sim76xx(CommandableIf *t) { - ESP_LOGV(TAG, "%s", __func__ ); + ESP_LOGV(TAG, "%s", __func__); return generic_command_common(t, "AT+CPOF\r", 1000); } command_result power_down_sim70xx(CommandableIf *t) { - ESP_LOGV(TAG, "%s", __func__ ); + ESP_LOGV(TAG, "%s", __func__); return generic_command(t, "AT+CPOWD=1\r", "POWER DOWN", "ERROR", 1000); } command_result power_down_sim8xx(CommandableIf *t) { - ESP_LOGV(TAG, "%s", __func__ ); + ESP_LOGV(TAG, "%s", __func__); return generic_command(t, "AT+CPOWD=1\r", "POWER DOWN", "ERROR", 1000); } command_result reset(CommandableIf *t) { - ESP_LOGV(TAG, "%s", __func__ ); + ESP_LOGV(TAG, "%s", __func__); return generic_command(t, "AT+CRESET\r", "PB DONE", "ERROR", 60000); } command_result set_baud(CommandableIf *t, int baud) { - ESP_LOGV(TAG, "%s", __func__ ); + ESP_LOGV(TAG, "%s", __func__); return generic_command_common(t, "AT+IPR=" + std::to_string(baud) + "\r"); } command_result hang_up(CommandableIf *t) { - ESP_LOGV(TAG, "%s", __func__ ); + ESP_LOGV(TAG, "%s", __func__); return generic_command_common(t, "ATH\r", 90000); } command_result get_battery_status(CommandableIf *t, int &voltage, int &bcs, int &bcl) { - ESP_LOGV(TAG, "%s", __func__ ); + ESP_LOGV(TAG, "%s", __func__); std::string out; auto ret = generic_get_string(t, "AT+CBC\r", out); if (ret != command_result::OK) { @@ -206,7 +207,7 @@ command_result get_battery_status(CommandableIf *t, int &voltage, int &bcs, int command_result get_battery_status_sim7xxx(CommandableIf *t, int &voltage, int &bcs, int &bcl) { - ESP_LOGV(TAG, "%s", __func__ ); + ESP_LOGV(TAG, "%s", __func__); std::string out; auto ret = generic_get_string(t, "AT+CBC\r", out); if (ret != command_result::OK) { @@ -235,13 +236,13 @@ command_result get_battery_status_sim7xxx(CommandableIf *t, int &voltage, int &b command_result set_flow_control(CommandableIf *t, int dce_flow, int dte_flow) { - ESP_LOGV(TAG, "%s", __func__ ); + ESP_LOGV(TAG, "%s", __func__); return generic_command_common(t, "AT+IFC=" + std::to_string(dce_flow) + "," + std::to_string(dte_flow) + "\r"); } command_result get_operator_name(CommandableIf *t, std::string &operator_name, int &act) { - ESP_LOGV(TAG, "%s", __func__ ); + ESP_LOGV(TAG, "%s", __func__); std::string out; auto ret = generic_get_string(t, "AT+COPS?\r", out, 75000); if (ret != command_result::OK) { @@ -272,7 +273,7 @@ command_result get_operator_name(CommandableIf *t, std::string &operator_name, i command_result set_echo(CommandableIf *t, bool on) { - ESP_LOGV(TAG, "%s", __func__ ); + ESP_LOGV(TAG, "%s", __func__); if (on) { return generic_command_common(t, "ATE1\r"); } @@ -281,7 +282,7 @@ command_result set_echo(CommandableIf *t, bool on) command_result set_pdp_context(CommandableIf *t, PdpContext &pdp, uint32_t timeout_ms) { - ESP_LOGV(TAG, "%s", __func__ ); + ESP_LOGV(TAG, "%s", __func__); std::string pdp_command = "AT+CGDCONT=" + std::to_string(pdp.context_id) + ",\"" + pdp.protocol_type + "\",\"" + pdp.apn + "\"\r"; return generic_command_common(t, pdp_command, timeout_ms); @@ -294,25 +295,25 @@ command_result set_pdp_context(CommandableIf *t, PdpContext &pdp) command_result set_data_mode(CommandableIf *t) { - ESP_LOGV(TAG, "%s", __func__ ); + ESP_LOGV(TAG, "%s", __func__); return generic_command(t, "ATD*99#\r", "CONNECT", "ERROR", 5000); } command_result set_data_mode_alt(CommandableIf *t) { - ESP_LOGV(TAG, "%s", __func__ ); + ESP_LOGV(TAG, "%s", __func__); return generic_command(t, "ATD*99##\r", "CONNECT", "ERROR", 5000); } command_result resume_data_mode(CommandableIf *t) { - ESP_LOGV(TAG, "%s", __func__ ); + ESP_LOGV(TAG, "%s", __func__); return generic_command(t, "ATO\r", "CONNECT", "ERROR", 5000); } command_result set_command_mode(CommandableIf *t) { - ESP_LOGV(TAG, "%s", __func__ ); + ESP_LOGV(TAG, "%s", __func__); const auto pass = std::list({"NO CARRIER", "OK"}); const auto fail = std::list({"ERROR"}); return generic_command(t, "+++", pass, fail, 5000); @@ -320,25 +321,25 @@ command_result set_command_mode(CommandableIf *t) command_result get_imsi(CommandableIf *t, std::string &imsi_number) { - ESP_LOGV(TAG, "%s", __func__ ); + ESP_LOGV(TAG, "%s", __func__); return generic_get_string(t, "AT+CIMI\r", imsi_number, 5000); } command_result get_imei(CommandableIf *t, std::string &out) { - ESP_LOGV(TAG, "%s", __func__ ); + ESP_LOGV(TAG, "%s", __func__); return generic_get_string(t, "AT+CGSN\r", out, 5000); } command_result get_module_name(CommandableIf *t, std::string &out) { - ESP_LOGV(TAG, "%s", __func__ ); + ESP_LOGV(TAG, "%s", __func__); return generic_get_string(t, "AT+CGMM\r", out, 5000); } command_result sms_txt_mode(CommandableIf *t, bool txt = true) { - ESP_LOGV(TAG, "%s", __func__ ); + ESP_LOGV(TAG, "%s", __func__); if (txt) { return generic_command_common(t, "AT+CMGF=1\r"); // Text mode (default) } @@ -348,13 +349,13 @@ command_result sms_txt_mode(CommandableIf *t, bool txt = true) command_result sms_character_set(CommandableIf *t) { // Sets the default GSM character set - ESP_LOGV(TAG, "%s", __func__ ); + ESP_LOGV(TAG, "%s", __func__); return generic_command_common(t, "AT+CSCS=\"GSM\"\r"); } command_result send_sms(CommandableIf *t, const std::string &number, const std::string &message) { - ESP_LOGV(TAG, "%s", __func__ ); + ESP_LOGV(TAG, "%s", __func__); auto ret = t->command("AT+CMGS=\"" + number + "\"\r", [&](uint8_t *data, size_t len) { std::string_view response((char *)data, len); ESP_LOGD(TAG, "Send SMS response %.*s", static_cast(response.size()), response.data()); @@ -372,13 +373,13 @@ command_result send_sms(CommandableIf *t, const std::string &number, const std:: command_result set_cmux(CommandableIf *t) { - ESP_LOGV(TAG, "%s", __func__ ); + ESP_LOGV(TAG, "%s", __func__); return generic_command_common(t, "AT+CMUX=0\r"); } command_result read_pin(CommandableIf *t, bool &pin_ok) { - ESP_LOGV(TAG, "%s", __func__ ); + ESP_LOGV(TAG, "%s", __func__); std::string out; auto ret = generic_get_string(t, "AT+CPIN?\r", out); if (ret != command_result::OK) { @@ -400,21 +401,21 @@ command_result read_pin(CommandableIf *t, bool &pin_ok) command_result set_pin(CommandableIf *t, const std::string &pin) { - ESP_LOGV(TAG, "%s", __func__ ); + ESP_LOGV(TAG, "%s", __func__); std::string set_pin_command = "AT+CPIN=" + pin + "\r"; return generic_command_common(t, set_pin_command); } command_result at(CommandableIf *t, const std::string &cmd, std::string &out, int timeout = 500) { - ESP_LOGV(TAG, "%s", __func__ ); + ESP_LOGV(TAG, "%s", __func__); std::string at_command = cmd + "\r"; return generic_get_string(t, at_command, out, timeout); } command_result at_raw(CommandableIf *t, const std::string &cmd, std::string &out, const std::string &pass, const std::string &fail, int timeout = 500) { - ESP_LOGV(TAG, "%s", __func__ ); + ESP_LOGV(TAG, "%s", __func__); return t->command(cmd, [&](uint8_t *data, size_t len) { out.assign(reinterpret_cast(data), len); @@ -430,7 +431,7 @@ command_result at_raw(CommandableIf *t, const std::string &cmd, std::string &out command_result get_signal_quality(CommandableIf *t, int &rssi, int &ber) { - ESP_LOGV(TAG, "%s", __func__ ); + ESP_LOGV(TAG, "%s", __func__); std::string out; auto ret = generic_get_string(t, "AT+CSQ\r", out); if (ret != command_result::OK) { @@ -456,19 +457,19 @@ command_result get_signal_quality(CommandableIf *t, int &rssi, int &ber) command_result set_operator(CommandableIf *t, int mode, int format, const std::string &oper) { - ESP_LOGV(TAG, "%s", __func__ ); + ESP_LOGV(TAG, "%s", __func__); return generic_command_common(t, "AT+COPS=" + std::to_string(mode) + "," + std::to_string(format) + ",\"" + oper + "\"\r", 90000); } command_result set_network_attachment_state(CommandableIf *t, int state) { - ESP_LOGV(TAG, "%s", __func__ ); + ESP_LOGV(TAG, "%s", __func__); return generic_command_common(t, "AT+CGATT=" + std::to_string(state) + "\r"); } command_result get_network_attachment_state(CommandableIf *t, int &state) { - ESP_LOGV(TAG, "%s", __func__ ); + ESP_LOGV(TAG, "%s", __func__); std::string out; auto ret = generic_get_string(t, "AT+CGATT?\r", out); if (ret != command_result::OK) { @@ -489,13 +490,13 @@ command_result get_network_attachment_state(CommandableIf *t, int &state) command_result set_radio_state(CommandableIf *t, int state) { - ESP_LOGV(TAG, "%s", __func__ ); + ESP_LOGV(TAG, "%s", __func__); return generic_command_common(t, "AT+CFUN=" + std::to_string(state) + "\r", 15000); } command_result get_radio_state(CommandableIf *t, int &state) { - ESP_LOGV(TAG, "%s", __func__ ); + ESP_LOGV(TAG, "%s", __func__); std::string out; auto ret = generic_get_string(t, "AT+CFUN?\r", out); if (ret != command_result::OK) { @@ -516,19 +517,19 @@ command_result get_radio_state(CommandableIf *t, int &state) command_result set_network_mode(CommandableIf *t, int mode) { - ESP_LOGV(TAG, "%s", __func__ ); + ESP_LOGV(TAG, "%s", __func__); return generic_command_common(t, "AT+CNMP=" + std::to_string(mode) + "\r"); } command_result set_preferred_mode(CommandableIf *t, int mode) { - ESP_LOGV(TAG, "%s", __func__ ); + ESP_LOGV(TAG, "%s", __func__); return generic_command_common(t, "AT+CMNB=" + std::to_string(mode) + "\r"); } command_result set_network_bands(CommandableIf *t, const std::string &mode, const int *bands, int size) { - ESP_LOGV(TAG, "%s", __func__ ); + ESP_LOGV(TAG, "%s", __func__); std::string band_string = ""; for (int i = 0; i < size - 1; ++i) { band_string += std::to_string(bands[i]) + ","; @@ -542,7 +543,7 @@ command_result set_network_bands(CommandableIf *t, const std::string &mode, cons // any_mode = "0xFFFFFFFF7FFFFFFF"; command_result set_network_bands_sim76xx(CommandableIf *t, const std::string &mode, const int *bands, int size) { - ESP_LOGV(TAG, "%s", __func__ ); + ESP_LOGV(TAG, "%s", __func__); static const char *hexDigits = "0123456789ABCDEF"; uint64_t band_bits = 0; int hex_len = 16; @@ -560,7 +561,7 @@ command_result set_network_bands_sim76xx(CommandableIf *t, const std::string &mo command_result get_network_system_mode(CommandableIf *t, int &mode) { - ESP_LOGV(TAG, "%s", __func__ ); + ESP_LOGV(TAG, "%s", __func__); std::string out; auto ret = generic_get_string(t, "AT+CNSMOD?\r", out); if (ret != command_result::OK) { @@ -582,13 +583,13 @@ command_result get_network_system_mode(CommandableIf *t, int &mode) command_result set_gnss_power_mode(CommandableIf *t, int mode) { - ESP_LOGV(TAG, "%s", __func__ ); + ESP_LOGV(TAG, "%s", __func__); return generic_command_common(t, "AT+CGNSPWR=" + std::to_string(mode) + "\r"); } command_result get_gnss_power_mode(CommandableIf *t, int &mode) { - ESP_LOGV(TAG, "%s", __func__ ); + ESP_LOGV(TAG, "%s", __func__); std::string out; auto ret = generic_get_string(t, "AT+CGNSPWR?\r", out); if (ret != command_result::OK) { @@ -610,20 +611,19 @@ command_result get_gnss_power_mode(CommandableIf *t, int &mode) command_result config_psm(CommandableIf *t, int enabled, const std::string &TAU, const std::string &activeTime) { ESP_LOGV(TAG, "%s", __func__); - if (enabled == true) - { - return generic_command_common(t, "AT+CPSMS=1,,,\"" + TAU + "\"" + ",\"" + activeTime + "\"\r", 500); + if (enabled == true) { + return generic_command_common(t, "AT+CPSMS=1,,,\"" + TAU + "\"" + ",\"" + activeTime + "\"\r", 5000); } - return generic_command_common(t, "AT+CPSMS=" + std::to_string(enabled), 500); + return generic_command_common(t, "AT+CPSMS=" + std::to_string(enabled) + "\r", 5000); } command_result config_network_registration_urc(CommandableIf *t, int value) { ESP_LOGV(TAG, "%s", __func__); - return generic_command_common(t,"AT+CEREG=" + std::to_string(state) + "\r", 500); + return generic_command_common(t, "AT+CEREG=" + std::to_string(value) + "\r", 500); } -command_result get_network_registration_state(CommandableIf *t, int& state) +command_result get_network_registration_state(CommandableIf *t, int &state) { ESP_LOGV(TAG, "%s", __func__); std::string out; @@ -640,7 +640,7 @@ command_result get_network_registration_state(CommandableIf *t, int& state) return command_result::FAIL; } - if (out.find(pattern) == std::string::npos || (state_pos_end = out.find(',',state_pos_start)) == std::string::npos){ + if (out.find(pattern) == std::string::npos || (state_pos_end = out.find(',', state_pos_start)) == std::string::npos) { if (std::from_chars(out.data() + state_pos_start, out.data() + out.size(), state).ec == std::errc::invalid_argument) { return command_result::FAIL; } @@ -656,25 +656,22 @@ command_result config_mobile_termination_error(CommandableIf *t, int value) ESP_LOGV(TAG, "%s", __func__); return generic_command_common(t, "AT+CMEE=" + std::to_string(value) + "\r"); } -command_result config_edrx(int mode, int access_technology, const std::string &edrx_value, const std::string &ptw_value) +command_result config_edrx(CommandableIf *t, int mode, int access_technology, const std::string &edrx_value) { - if (mode == 1 || enabled == 2) - { - return dce_commands::generic_command_common(dte.get(), - "AT+SQNEDRX=" + - std::to_string(mode) + - "," + - std::to_string(access_technology) + - ",\"" + - edrx_value + - "\",\"" + - ptw_value + "\"\r"); + if (mode == 1 || mode == 2) { + return dce_commands::generic_command_common(t, + "AT+CEDRXS=" + + std::to_string(mode) + + "," + + std::to_string(access_technology) + + ",\"" + + edrx_value + "\"\r"); } - return dce_commands::generic_command_common(dte.get(), "AT+SQNEDRX=" + std::to_string(mode), 500); + return dce_commands::generic_command_common(t, "AT+SQNEDRX=" + std::to_string(mode), 500); } command_result set_gnss_power_mode_sim76xx(CommandableIf *t, int mode) { - ESP_LOGV(TAG, "%s", __func__ ); + ESP_LOGV(TAG, "%s", __func__); return generic_command_common(t, "AT+CGPS=" + std::to_string(mode) + "\r"); } diff --git a/components/esp_modem/src/esp_modem_modules.cpp b/components/esp_modem/src/esp_modem_modules.cpp index 033f9c433..251a4aaff 100644 --- a/components/esp_modem/src/esp_modem_modules.cpp +++ b/components/esp_modem/src/esp_modem_modules.cpp @@ -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 */ @@ -7,6 +7,7 @@ #include "cxx_include/esp_modem_api.hpp" #include "cxx_include/esp_modem_dce_module.hpp" #include "generate/esp_modem_command_declare.inc" +#include "cxx17_include/esp_modem_command_library_17.hpp" namespace esp_modem { @@ -35,7 +36,7 @@ GenericModule::GenericModule(std::shared_ptr dte, const dce_config *config) #define ESP_MODEM_DECLARE_DCE_COMMAND(name, return_type, arg_nr, ...) \ return_type GenericModule::name(__VA_ARGS__) { return esp_modem::dce_commands::name(dte.get() ARGS(arg_nr) ); } -DECLARE_ALL_COMMAND_APIS(return_type name(...) ) +DECLARE_ALL_COMMAND_APIS(return_type name(...)) #undef ESP_MODEM_DECLARE_DCE_COMMAND @@ -87,59 +88,41 @@ command_result BG96::set_pdp_context(esp_modem::PdpContext &pdp) return dce_commands::set_pdp_context(dte.get(), pdp, 300); } -command_result urc_callback(uint8_t *line, size_t len) +bool SQNGM02S::setup_data_mode() { - ESP_LOGI("WalterModem", "Received: %s", line); - if (strstr((const char *)line, "+CEREG: 1")) - { - return command_result::OK; // Succesfully registered - } - else if (strstr((const char *)line, "+CEREG: 5")) - { - return command_result::OK; // Succesfully registered - } - else if (strstr((const char *)line, "+CEREG: 3")) - { - return command_result::FAIL; // Permission denied - } - return command_result::TIMEOUT; + return true; } command_result SQNGM02S::connect(PdpContext &pdp) { command_result res; - res = set_pdp_context(pdp); - if (res != command_result::OK) - return res; + configure_pdp_context(std::make_unique(pdp)); + set_pdp_context(*this->pdp); res = config_network_registration_urc(1); - if (res != command_result::OK) + if (res != command_result::OK) { return res; + } res = set_radio_state(1); - if (res != command_result::OK) + if (res != command_result::OK) { return res; + } //wait for +CEREG: 5 or +CEREG: 1. + const auto pass = std::list({"+CEREG: 1", "+CEREG: 5"}); + const auto fail = std::list({"ERROR"}); + res = esp_modem::dce_commands::generic_command(dte.get(), "", pass, fail, 1200000); - do - { - res = dte->command("", urc_callback, 20000, '\r'); - } while (res == command_result::TIMEOUT); - - if (res != command_result::OK) + if (res != command_result::OK) { + config_network_registration_urc(0); return res; + } res = config_network_registration_urc(0); - if (res != command_result::OK) + if (res != command_result::OK) { return res; + } return command_result::OK; } - -bool SQNGM02S::setup_data_mode() -{ - ESP_LOGI("SQNGM02S", "setyp data mode"); - return set_echo(false) == command_result::OK; - // PDP context has already been set before hand because SEQUANS modem must have already been connected/registered before setting up cmux -} } From 74b7d85d4ab9c503b65a4dc59cf45ca171b5f696 Mon Sep 17 00:00:00 2001 From: robbedptechnics Date: Fri, 21 Mar 2025 10:16:14 +0100 Subject: [PATCH 4/4] feat(modem): added config_edrx api function --- .pre-commit-config.yaml | 16 ++++++++-------- .../esp_modem_command_library_17.hpp | 2 -- .../esp_modem/include/esp_modem_c_api_types.h | 2 +- components/esp_modem/src/esp_modem_c_api.cpp | 16 +++++++--------- .../esp_modem/src/esp_modem_command_library.cpp | 1 + 5 files changed, 17 insertions(+), 20 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index c0137d145..93dde2c6a 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -2,7 +2,7 @@ # See https://pre-commit.com/hooks.html for more hooks repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v5.0.0 + rev: v4.3.0 hooks: - id: check-yaml - id: check-added-large-files @@ -13,12 +13,12 @@ repos: - id: mixed-line-ending - id: debug-statements - repo: https://github.com/pycqa/flake8 - rev: 7.1.2 + rev: 5.0.4 hooks: - id: flake8 args: ['--config=.flake8', '--tee', '--benchmark'] - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.14.1 + rev: v0.981 hooks: - id: mypy exclude: > @@ -39,25 +39,25 @@ repos: hooks: - id: isort - repo: https://github.com/myint/eradicate/ - rev: 2.3.0 + rev: v2.1.0 hooks: - id: eradicate - repo: https://github.com/espressif/check-copyright/ - rev: v1.1.0 + rev: v1.0.3 hooks: - id: check-copyright args: ['--ignore', 'ci/check_copyright_ignore.txt', '--config', 'ci/check_copyright_config.yaml'] - repo: https://github.com/igrr/astyle_py.git - rev: v1.1.0 + rev: v1.0.5 hooks: - id: astyle_py args: ['--style=otbs', '--attach-namespaces', '--attach-classes', '--indent=spaces=4', '--convert-tabs', '--align-reference=name', '--keep-one-line-statements', '--pad-header', '--pad-oper', '--unpad-paren', '--max-continuation-indent=120', '--exclude-list=ci/ignore_astyle.txt'] - repo: https://github.com/commitizen-tools/commitizen - rev: v4.4.1 + rev: v2.42.1 hooks: - id: commitizen - id: commitizen-branch - stages: [pre-push, manual] + stages: [push, manual] - repo: local hooks: - id: commit message scopes diff --git a/components/esp_modem/include/cxx17_include/esp_modem_command_library_17.hpp b/components/esp_modem/include/cxx17_include/esp_modem_command_library_17.hpp index 6992e1d86..efabb8af0 100644 --- a/components/esp_modem/include/cxx17_include/esp_modem_command_library_17.hpp +++ b/components/esp_modem/include/cxx17_include/esp_modem_command_library_17.hpp @@ -9,8 +9,6 @@ #include "cxx_include/esp_modem_dte.hpp" #include "cxx_include/esp_modem_dce_module.hpp" -static const char *TAG = "command_lib"; - namespace esp_modem::dce_commands { command_result generic_command(CommandableIf *t, const std::string &command, const std::list &pass_phrase, 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 17f39444b..c74076418 100644 --- a/components/esp_modem/include/esp_modem_c_api_types.h +++ b/components/esp_modem/include/esp_modem_c_api_types.h @@ -163,7 +163,7 @@ esp_err_t esp_modem_set_apn(esp_modem_dce_t *dce, const char *apn); esp_err_t esp_modem_set_urc(esp_modem_dce_t *dce, esp_err_t(*got_line_cb)(uint8_t *data, size_t len)); #endif -esp_err_t esp_modem_sqns_gm02s_connect(esp_modem_dce_t *dce, const esp_modem_PdpContext_t *pdp_context); +esp_err_t esp_modem_sqn_gm02s_connect(esp_modem_dce_t *dce, const esp_modem_PdpContext_t *pdp_context); /** * @brief This API provides support for temporarily pausing networking in order diff --git a/components/esp_modem/src/esp_modem_c_api.cpp b/components/esp_modem/src/esp_modem_c_api.cpp index 75250a0f6..6c85d9d46 100644 --- a/components/esp_modem/src/esp_modem_c_api.cpp +++ b/components/esp_modem/src/esp_modem_c_api.cpp @@ -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 */ @@ -454,8 +454,7 @@ extern "C" esp_err_t esp_modem_config_psm(esp_modem_dce_t *dce_wrap, int mode, c extern "C" esp_err_t esp_modem_config_network_registration_urc(esp_modem_dce_t *dce_wrap, int value) { - if (dce_wrap == nullptr || dce_wrap->dce == nullptr || value > 5) - { + if (dce_wrap == nullptr || dce_wrap->dce == nullptr || value > 5) { return ESP_ERR_INVALID_ARG; } @@ -486,23 +485,22 @@ extern "C" esp_err_t esp_modem_config_mobile_termination_error(esp_modem_dce_t * return command_response_to_esp_err(dce_wrap->dce->config_mobile_termination_error(mode)); } -extern "C" esp_err_t esp_modem_config_edrx(esp_modem_dce_t *dce_wrap, int mode, int access_technology, const char *edrx_value, const char *ptw_value) +extern "C" esp_err_t esp_modem_config_edrx(esp_modem_dce_t *dce_wrap, int mode, int access_technology, const char *edrx_value) { if (dce_wrap == nullptr || dce_wrap->dce == nullptr || mode > 3 || access_technology > 5) { return ESP_ERR_INVALID_ARG; } - if ((mode == 1 || mode == 2 ) && (strlen(edrx_value) != 4 || strlen(ptw_value) != 4)) { + if ((mode == 1 || mode == 2) && strlen(edrx_value) != 4) { return ESP_ERR_INVALID_ARG; } - return command_response_to_esp_err(dce_wrap->dce->config_edrx(mode,access_technology,std::string(edrx_value),std::string(ptw_value))); + return command_response_to_esp_err(dce_wrap->dce->config_edrx(mode, access_technology, std::string(edrx_value))); } -extern "C" esp_err_t esp_modem_sqns_gm02s_connect(esp_modem_dce_t *dce_wrap, const esp_modem_PdpContext_t *pdp_context) +extern "C" esp_err_t esp_modem_sqn_gm02s_connect(esp_modem_dce_t *dce_wrap, const esp_modem_PdpContext_t *pdp_context) { - if (dce_wrap == nullptr || dce_wrap->dce == nullptr) - { + if (dce_wrap == nullptr || dce_wrap->dce == nullptr) { return ESP_ERR_INVALID_ARG; } diff --git a/components/esp_modem/src/esp_modem_command_library.cpp b/components/esp_modem/src/esp_modem_command_library.cpp index a29284a24..024008fcf 100644 --- a/components/esp_modem/src/esp_modem_command_library.cpp +++ b/components/esp_modem/src/esp_modem_command_library.cpp @@ -16,6 +16,7 @@ namespace esp_modem::dce_commands { +static const char *TAG = "command_lib"; command_result generic_command(CommandableIf *t, const std::string &command, const std::list &pass_phrase,