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 72f141ec8..516cc054e 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 @@ -104,6 +104,15 @@ public: pdp = std::move(new_pdp); } + /** + * @brief Simplified version of operator name (without the ACT, which is included in the command library) + */ + command_result get_operator_name(std::string& name) + { + int dummy_act; + return get_operator_name(name, dummy_act); + } + /** * @brief Common DCE commands generated from the API AT list */ 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 8a5a4b8cb..f4b71c30f 100644 --- a/components/esp_modem/include/generate/esp_modem_command_declare.inc +++ b/components/esp_modem/include/generate/esp_modem_command_declare.inc @@ -50,9 +50,10 @@ ESP_MODEM_DECLARE_DCE_COMMAND(sync, command_result, 0) \ /** * @brief Reads the operator name * @param[out] operator name + * @param[out] access technology * @return OK, FAIL or TIMEOUT */ \ -ESP_MODEM_DECLARE_DCE_COMMAND(get_operator_name, command_result, 1, STRING_OUT(p1, name)) \ +ESP_MODEM_DECLARE_DCE_COMMAND(get_operator_name, command_result, 2, STRING_OUT(p1, name), INT_OUT(p2, act)) \ \ /** * @brief Stores current user profile @@ -97,7 +98,7 @@ ESP_MODEM_DECLARE_DCE_COMMAND(set_echo, command_result, 1, BOOL_IN(p1, echo_on)) ESP_MODEM_DECLARE_DCE_COMMAND(sms_txt_mode, command_result, 1, BOOL_IN(p1, txt)) \ \ /** - * @brief Sets the default (GSM) charater set + * @brief Sets the default (GSM) character set * @return OK, FAIL or TIMEOUT */ \ ESP_MODEM_DECLARE_DCE_COMMAND(sms_character_set, command_result, 0) \ diff --git a/components/esp_modem/src/esp_modem_command_library.cpp b/components/esp_modem/src/esp_modem_command_library.cpp index 867ca20ad..dd79e8e98 100644 --- a/components/esp_modem/src/esp_modem_command_library.cpp +++ b/components/esp_modem/src/esp_modem_command_library.cpp @@ -228,7 +228,7 @@ command_result set_flow_control(CommandableIf *t, int dce_flow, int dte_flow) 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) +command_result get_operator_name(CommandableIf *t, std::string &operator_name, int &act) { ESP_LOGV(TAG, "%s", __func__ ); std::string_view out; @@ -239,9 +239,19 @@ command_result get_operator_name(CommandableIf *t, std::string &operator_name) auto pos = out.find("+COPS"); auto property = 0; while (pos != std::string::npos) { - // Looking for: +COPS: [, [, ]] + // Looking for: +COPS: [, [, [, ]]] if (property++ == 2) { // operator name is after second comma (as a 3rd property of COPS string) operator_name = out.substr(++pos); + auto additional_comma = operator_name.find(','); // check for the optional ACT + if (additional_comma != std::string::npos && std::from_chars(operator_name.data() + additional_comma + 1,operator_name.data() + operator_name.length(), act).ec != std::errc::invalid_argument) { + operator_name = operator_name.substr(0, additional_comma); + } + // and strip quotes if present + auto quote1 = operator_name.find('"'); + auto quote2 = operator_name.rfind('"'); + if (quote1 != std::string::npos && quote2 != std::string::npos) { + operator_name = operator_name.substr(quote1+1, quote2-1); + } return command_result::OK; } pos = out.find(',', ++pos); diff --git a/components/esp_modem/test/host_test/main/LoopbackTerm.cpp b/components/esp_modem/test/host_test/main/LoopbackTerm.cpp index f3f30227a..936a13597 100644 --- a/components/esp_modem/test/host_test/main/LoopbackTerm.cpp +++ b/components/esp_modem/test/host_test/main/LoopbackTerm.cpp @@ -34,6 +34,8 @@ int LoopbackTerm::write(uint8_t *data, size_t len) response = "+CSQ: 123,456\n\r\nOK\r\n"; } else if (command.find("AT+CGMM\r") != std::string::npos) { response = "0G Dummy Model\n\r\nOK\r\n"; + } else if (command.find("AT+COPS?\r") != std::string::npos) { + response = "+COPS: 0,0,\"OperatorName\",5\n\r\nOK\r\n"; } else if (command.find("AT+CBC\r") != std::string::npos) { response = is_bg96 ? "+CBC: 1,20,123456\r\r\n\r\nOK\r\n\n\r\n" : "+CBC: 123.456V\r\r\n\r\nOK\r\n\n\r\n"; diff --git a/components/esp_modem/test/host_test/main/test_modem.cpp b/components/esp_modem/test/host_test/main/test_modem.cpp index 881754b37..3e3d4a9aa 100644 --- a/components/esp_modem/test/host_test/main/test_modem.cpp +++ b/components/esp_modem/test/host_test/main/test_modem.cpp @@ -56,6 +56,14 @@ TEST_CASE("DCE AT parser", "[esp_modem]") std::string model; CHECK(dce->get_module_name(model) == command_result::OK); CHECK(model == "0G Dummy Model"); + + std::string operator_name; + int act = 99; + CHECK(dce->get_operator_name(operator_name) == command_result::OK); + CHECK(operator_name == "OperatorName"); + CHECK(dce->get_operator_name(operator_name, act) == command_result::OK); + CHECK(operator_name == "OperatorName"); + CHECK(act == 5); }