diff --git a/components/esp_modem/docs/api_docs.rst b/components/esp_modem/docs/api_docs.rst index 70386e178..6727de13e 100644 --- a/components/esp_modem/docs/api_docs.rst +++ b/components/esp_modem/docs/api_docs.rst @@ -41,6 +41,9 @@ Modem commands These functions are the actual commands to communicate with the modem using AT command interface. +Note that the functions which implement AT commands returning textual values use plain ``char *`` +pointer as the return value. The API expects the output data to point to user allocated space of at least +``ESP_MODEM_C_API_STR_MAX`` (64 by default) bytes, it also truncates the output data to this size. .. doxygenfile:: esp_modem_api_commands.h 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 ccecdce58..4dc28ee5a 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 @@ -79,6 +79,7 @@ public: } return true; } else if (mode == modem_mode::COMMAND_MODE) { + Task::Delay(1000); // Mandatory 1s pause return set_command_mode() == command_result::OK; } else if (mode == modem_mode::CMUX_MODE) { return set_cmux() == command_result::OK; diff --git a/components/esp_modem/include/cxx_include/esp_modem_primitives.hpp b/components/esp_modem/include/cxx_include/esp_modem_primitives.hpp index 52263faf2..bd402f089 100644 --- a/components/esp_modem/include/cxx_include/esp_modem_primitives.hpp +++ b/components/esp_modem/include/cxx_include/esp_modem_primitives.hpp @@ -76,6 +76,7 @@ public: static void Delete(); static void Relinquish(); + static void Delay(uint32_t delay); private: TaskT task_handle; }; diff --git a/components/esp_modem/src/esp_modem_c_api.cpp b/components/esp_modem/src/esp_modem_c_api.cpp index 390fa103d..ec508fa80 100644 --- a/components/esp_modem/src/esp_modem_c_api.cpp +++ b/components/esp_modem/src/esp_modem_c_api.cpp @@ -23,6 +23,10 @@ #include "exception_stub.hpp" #include "cstring" +#ifndef ESP_MODEM_C_API_STR_MAX +#define ESP_MODEM_C_API_STR_MAX 64 +#endif + // // C API definitions using namespace esp_modem; @@ -173,7 +177,85 @@ extern "C" esp_err_t esp_modem_get_imsi(esp_modem_dce_t *dce_wrap, char *p_imsi) std::string imsi; auto ret = command_response_to_esp_err(dce_wrap->dce->get_imsi(imsi)); if (ret == ESP_OK && !imsi.empty()) { - strcpy(p_imsi, imsi.c_str()); + strlcpy(p_imsi, imsi.c_str(), ESP_MODEM_C_API_STR_MAX); } return ret; -} \ No newline at end of file +} + +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) +{ + 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_operator_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_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()); +} diff --git a/components/esp_modem/src/esp_modem_primitives_freertos.cpp b/components/esp_modem/src/esp_modem_primitives_freertos.cpp index 6e0e50384..66ddcc29e 100644 --- a/components/esp_modem/src/esp_modem_primitives_freertos.cpp +++ b/components/esp_modem/src/esp_modem_primitives_freertos.cpp @@ -106,4 +106,9 @@ void Task::Relinquish() vTaskDelay(1); } +void Task::Delay(uint32_t ms) +{ + vTaskDelay(pdMS_TO_TICKS(ms)); +} + } // namespace esp_modem \ No newline at end of file