diff --git a/esp_modem/docs/cxx_api_links.rst b/esp_modem/docs/cxx_api_links.rst index 40289e5df..d903010fe 100644 --- a/esp_modem/docs/cxx_api_links.rst +++ b/esp_modem/docs/cxx_api_links.rst @@ -2,6 +2,9 @@ - :cpp:func:`esp_modem::DCE::set_pin` - :cpp:func:`esp_modem::DCE::read_pin` - :cpp:func:`esp_modem::DCE::set_echo` +- :cpp:func:`esp_modem::DCE::sms_txt_mode` +- :cpp:func:`esp_modem::DCE::sms_character_set` +- :cpp:func:`esp_modem::DCE::send_sms` - :cpp:func:`esp_modem::DCE::resume_data_mode` - :cpp:func:`esp_modem::DCE::set_pdp_context` - :cpp:func:`esp_modem::DCE::set_command_mode` diff --git a/esp_modem/docs/esp_modem_api_commands.h b/esp_modem/docs/esp_modem_api_commands.h index 826d8c9d7..12d8a9627 100644 --- a/esp_modem/docs/esp_modem_api_commands.h +++ b/esp_modem/docs/esp_modem_api_commands.h @@ -1,51 +1,65 @@ // cat ../include/generate/esp_modem_command_declare.inc | clang -E -P -CC -xc -I../include -DGENERATE_DOCS - | sed -n '1,/DCE command documentation/!p' > c_api.h // cat ../include/generate/esp_modem_command_declare.inc | clang -E -P -xc -I../include -DGENERATE_DOCS -DGENERATE_RST_LINKS - | sed 's/NL/\n/g' > cxx_api_links.rst + +// call parametrs by names for documentation + + // --- DCE command documentation starts here --- /** - * @brief Sends the supplied PIN code - * - * @param pin Pin - * - */ command_result esp_modem_set_pin (const char* pin); /** + * @brief Sets the supplied PIN code + * @param[in] pin Pin + * @return OK, FAIL or TIMEOUT + */command_result esp_modem_set_pin (const char* pin); /** * @brief Checks if the SIM needs a PIN - * - * @param[out] pin_ok Pin + * @param[out] pin_ok true if the SIM card doesn't need a PIN to unlock + * @return OK, FAIL or TIMEOUT */ command_result esp_modem_read_pin (bool* pin_ok); /** - * @brief Reads the module name - * - * @param[out] name module name - */ command_result esp_modem_set_echo (const bool x); /** - * @brief Reads the module name - * - * @param[out] name module name + * @brief Sets echo mode + * @param[in] echo_on true if echo mode on (repeats the commands) + * @return OK, FAIL or TIMEOUT + */ command_result esp_modem_set_echo (const bool echo_on); /** + * @brief Sets the Txt or Pdu mode for SMS (only txt is supported) + * @param[in] txt true if txt mode + * @return OK, FAIL or TIMEOUT + */ command_result esp_modem_sms_txt_mode (const bool txt); /** + * @brief Sets the default (GSM) charater set + * @return OK, FAIL or TIMEOUT + */ command_result esp_modem_sms_character_set (); /** + * @brief Sends SMS message in txt mode + * @param[in] number Phone number to send the message to + * @param[in] message Text message to be sent + * @return OK, FAIL or TIMEOUT + */ command_result esp_modem_send_sms (const char* number, const char* message); /** + * @brief Resumes data mode (Switches back to th data mode, which was temporarily suspended) + * @return OK, FAIL or TIMEOUT */ command_result esp_modem_resume_data_mode (); /** - * @brief Reads the module name - * - * @param[out] name module name + * @brief Sets php context + * @param[in] x PdP context struct to setup modem cellular connection + * @return OK, FAIL or TIMEOUT */ command_result esp_modem_set_pdp_context (struct PdpContext* x); /** - * @brief Reads the module name - * - * @param[out] name module name + * @brief Switches to the command mode + * @return OK, FAIL or TIMEOUT */ command_result esp_modem_set_command_mode (); /** - * @brief Reads the module name - * - * @param[out] name module name + * @brief Switches to the CMUX mode + * @return OK, FAIL or TIMEOUT */ command_result esp_modem_set_cmux (); /** + * @brief Reads the IMSI number + * @param[out] imsi Module's IMSI number + * @return OK, FAIL or TIMEOUT + */ command_result esp_modem_get_imsi (char* imsi); /** + * @brief Reads the IMEI number + * @param[out] imei Module's IMEI number + * @return OK, FAIL or TIMEOUT + */ command_result esp_modem_get_imei (char* imei); /** * @brief Reads the module name - * - * @param[out] name module name - */ command_result esp_modem_get_imsi (char* x); /** - * @brief Reads the module name - * - * @param[out] name module name - */ command_result esp_modem_get_imei (char* x); /** - * @brief Reads the module name - * * @param[out] name module name + * @return OK, FAIL or TIMEOUT */ command_result esp_modem_get_module_name (char* name); /** * @brief Sets the modem to data mode - * + * @return OK, FAIL or TIMEOUT */ command_result esp_modem_set_data_mode (); /** * @brief Get Signal quality - * - */ command_result esp_modem_get_signal_quality (int* x, int* y); + * @param[out] rssi signal strength indication + * @param[out] ber channel bit error rate + * @return OK, FAIL or TIMEOUT + */ command_result esp_modem_get_signal_quality (int* rssi, int* ber); diff --git a/esp_modem/docs/esp_modem_dce.hpp b/esp_modem/docs/esp_modem_dce.hpp index c06c1f08c..2610a7158 100644 --- a/esp_modem/docs/esp_modem_dce.hpp +++ b/esp_modem/docs/esp_modem_dce.hpp @@ -1,5 +1,9 @@ // cat ../include/generate/esp_modem_command_declare.inc | clang -E -P -CC -xc -I../include -DGENERATE_DOCS - | sed -n '1,/DCE command documentation/!p' > c_api.h // cat ../include/generate/esp_modem_command_declare.inc | clang -E -P -xc -I../include -DGENERATE_DOCS -DGENERATE_RST_LINKS - | sed 's/NL/\n/g' > cxx_api_links.rst + +// call parametrs by names for documentation + + // --- DCE command documentation starts here --- class esp_modem::DCE: public DCE_T { @@ -13,51 +17,61 @@ public: /** - * @brief Sends the supplied PIN code - * - * @param pin Pin - * - */ command_result set_pin (const std::string& pin); /** + * @brief Sets the supplied PIN code + * @param[in] pin Pin + * @return OK, FAIL or TIMEOUT + */command_result set_pin (const std::string& pin); /** * @brief Checks if the SIM needs a PIN - * - * @param[out] pin_ok Pin + * @param[out] pin_ok true if the SIM card doesn't need a PIN to unlock + * @return OK, FAIL or TIMEOUT */ command_result read_pin (bool& pin_ok); /** - * @brief Reads the module name - * - * @param[out] name module name - */ command_result set_echo (const bool x); /** - * @brief Reads the module name - * - * @param[out] name module name + * @brief Sets echo mode + * @param[in] echo_on true if echo mode on (repeats the commands) + * @return OK, FAIL or TIMEOUT + */ command_result set_echo (const bool echo_on); /** + * @brief Sets the Txt or Pdu mode for SMS (only txt is supported) + * @param[in] txt true if txt mode + * @return OK, FAIL or TIMEOUT + */ command_result sms_txt_mode (const bool txt); /** + * @brief Sets the default (GSM) charater set + * @return OK, FAIL or TIMEOUT + */ command_result sms_character_set (); /** + * @brief Sends SMS message in txt mode + * @param[in] number Phone number to send the message to + * @param[in] message Text message to be sent + * @return OK, FAIL or TIMEOUT + */ command_result send_sms (const std::string& number, const std::string& message); /** + * @brief Resumes data mode (Switches back to th data mode, which was temporarily suspended) + * @return OK, FAIL or TIMEOUT */ command_result resume_data_mode (); /** - * @brief Reads the module name - * - * @param[out] name module name + * @brief Sets php context + * @param[in] x PdP context struct to setup modem cellular connection + * @return OK, FAIL or TIMEOUT */ command_result set_pdp_context (PdpContext& x); /** - * @brief Reads the module name - * - * @param[out] name module name + * @brief Switches to the command mode + * @return OK, FAIL or TIMEOUT */ command_result set_command_mode (); /** - * @brief Reads the module name - * - * @param[out] name module name + * @brief Switches to the CMUX mode + * @return OK, FAIL or TIMEOUT */ command_result set_cmux (); /** + * @brief Reads the IMSI number + * @param[out] imsi Module's IMSI number + * @return OK, FAIL or TIMEOUT + */ command_result get_imsi (std::string& imsi); /** + * @brief Reads the IMEI number + * @param[out] imei Module's IMEI number + * @return OK, FAIL or TIMEOUT + */ command_result get_imei (std::string& imei); /** * @brief Reads the module name - * - * @param[out] name module name - */ command_result get_imsi (std::string& x); /** - * @brief Reads the module name - * - * @param[out] name module name - */ command_result get_imei (std::string& x); /** - * @brief Reads the module name - * * @param[out] name module name + * @return OK, FAIL or TIMEOUT */ command_result get_module_name (std::string& name); /** * @brief Sets the modem to data mode - * + * @return OK, FAIL or TIMEOUT */ command_result set_data_mode (); /** * @brief Get Signal quality - * - */ command_result get_signal_quality (int& x, int& y); + * @param[out] rssi signal strength indication + * @param[out] ber channel bit error rate + * @return OK, FAIL or TIMEOUT + */ command_result get_signal_quality (int& rssi, int& ber); }; diff --git a/esp_modem/examples/simple_cxx_client/main/simple_client.cpp b/esp_modem/examples/simple_cxx_client/main/simple_client.cpp index d16b7b5ac..729b8d5c5 100644 --- a/esp_modem/examples/simple_cxx_client/main/simple_client.cpp +++ b/esp_modem/examples/simple_cxx_client/main/simple_client.cpp @@ -24,7 +24,7 @@ using namespace esp_modem; static const char *TAG = "cmux_example"; -static EventGroupHandle_t event_group = NULL; +static EventGroupHandle_t event_group = nullptr; static const int CONNECT_BIT = BIT0; static const int STOP_BIT = BIT1; static const int GOT_DATA_BIT = BIT2; @@ -141,6 +141,17 @@ extern "C" void app_main(void) assert(esp_netif); auto dce = create_SIM7600_dce(&dce_config, uart_dte, esp_netif); + /// TEST + { +// std::string str; +// dce->set_mode(esp_modem::modem_mode::CMUX_MODE); +// while (1) { +// dce->get_imsi(str); +// std::cout << "Modem IMSI number:" << str << "|" << std::endl; +// } + } +// return; + //// TEST dce->set_command_mode(); std::string str; @@ -163,7 +174,7 @@ extern "C" void app_main(void) esp_mqtt_client_config_t mqtt_config = { }; mqtt_config.uri = BROKER_URL; esp_mqtt_client_handle_t mqtt_client = esp_mqtt_client_init(&mqtt_config); - esp_mqtt_client_register_event(mqtt_client, MQTT_EVENT_ANY, mqtt_event_handler, NULL); + esp_mqtt_client_register_event(mqtt_client, MQTT_EVENT_ANY, mqtt_event_handler, nullptr); esp_mqtt_client_start(mqtt_client); EventBits_t got_data = 0; @@ -173,13 +184,11 @@ extern "C" void app_main(void) got_data = xEventGroupWaitBits(event_group, GOT_DATA_BIT, pdTRUE, pdTRUE, pdMS_TO_TICKS(500)); } esp_mqtt_client_destroy(mqtt_client); + dce->get_imsi(str); + std::cout << "Modem IMSI number:" << str << "|" << std::endl; + vTaskDelay(pdMS_TO_TICKS(1000)); - while (true) { // reading IMSI number after - dce->get_imsi(str); - std::cout << "Modem IMSI number:" << str << "|" << std::endl; - vTaskDelay(pdMS_TO_TICKS(1000)); - } - + ESP_LOGI(TAG, "Example finished"); } diff --git a/esp_modem/include/cxx_include/esp_modem_command_library.hpp b/esp_modem/include/cxx_include/esp_modem_command_library.hpp index 45fbe592b..427d88ddf 100644 --- a/esp_modem/include/cxx_include/esp_modem_command_library.hpp +++ b/esp_modem/include/cxx_include/esp_modem_command_library.hpp @@ -34,7 +34,7 @@ namespace dce_commands { /** * @brief Declaration of all commands is generated from esp_modem_command_declare.inc */ -#define ESP_MODEM_DECLARE_DCE_COMMAND(name, return_type, TEMPLATE_ARG, MUX_ARG, ...) \ +#define ESP_MODEM_DECLARE_DCE_COMMAND(name, return_type, num, ...) \ return_type name(CommandableIf *t, ## __VA_ARGS__); DECLARE_ALL_COMMAND_APIS(declare name(Commandable *p, ...);) diff --git a/esp_modem/include/cxx_include/esp_modem_dce.hpp b/esp_modem/include/cxx_include/esp_modem_dce.hpp index 89abcdb84..af297b3ce 100644 --- a/esp_modem/include/cxx_include/esp_modem_dce.hpp +++ b/esp_modem/include/cxx_include/esp_modem_dce.hpp @@ -95,7 +95,7 @@ class DCE: public DCE_T { public: using DCE_T::DCE_T; -#define ESP_MODEM_DECLARE_DCE_COMMAND(name, return_type, TEMPLATE_ARG, MUX_ARG, ...) \ +#define ESP_MODEM_DECLARE_DCE_COMMAND(name, return_type, num, ...) \ template \ return_type name(Agrs&&... args) \ { \ diff --git a/esp_modem/include/cxx_include/esp_modem_dce_module.hpp b/esp_modem/include/cxx_include/esp_modem_dce_module.hpp index 1640b12e7..4083104c9 100644 --- a/esp_modem/include/cxx_include/esp_modem_dce_module.hpp +++ b/esp_modem/include/cxx_include/esp_modem_dce_module.hpp @@ -71,7 +71,7 @@ public: } -#define ESP_MODEM_DECLARE_DCE_COMMAND(name, return_type, TEMPLATE_ARG, MUX_ARG, ...) \ +#define ESP_MODEM_DECLARE_DCE_COMMAND(name, return_type, num, ...) \ virtual return_type name(__VA_ARGS__); DECLARE_ALL_COMMAND_APIS(virtual return_type name(...); ) diff --git a/esp_modem/include/esp_modem_api.h b/esp_modem/include/esp_modem_api.h index 48c6df4a7..ba134abcf 100644 --- a/esp_modem/include/esp_modem_api.h +++ b/esp_modem/include/esp_modem_api.h @@ -23,7 +23,7 @@ extern "C" { #endif -#define ESP_MODEM_DECLARE_DCE_COMMAND(name, return_type, TEMPLATE_ARG, MUX_ARG, ...) \ +#define ESP_MODEM_DECLARE_DCE_COMMAND(name, return_type, num, ...) \ esp_err_t esp_modem_ ## name(esp_modem_dce_t *dce, ##__VA_ARGS__); DECLARE_ALL_COMMAND_APIS(declares esp_modem_(esp_modem_t * dce, ...);) diff --git a/esp_modem/include/generate/esp_modem_command_declare.inc b/esp_modem/include/generate/esp_modem_command_declare.inc index 9886a52ef..600820e97 100644 --- a/esp_modem/include/generate/esp_modem_command_declare.inc +++ b/esp_modem/include/generate/esp_modem_command_declare.inc @@ -15,12 +15,11 @@ #ifndef _ESP_MODEM_COMMAND_DECLARE_INC_ #define _ESP_MODEM_COMMAND_DECLARE_INC_ -#if GENERATE_DOCS -#define _ARG(param, name) name -#else -#define _ARG(param, name) param -#endif +// Parameters +// * handle different parameters for C++ and C API +// * make parameter unique names, so they could be easily referenced and forwarded +#define _ARG(param, name) param #ifdef __cplusplus #include #define STRING_IN(param, name) const std::string& _ARG(param, name) @@ -39,114 +38,127 @@ #define STRUCT_OUT(struct_name, x) struct struct_name* x #endif -#define _ESP_MODEM_COMMAND_DECLARE_INC_ -#define ESP_MODEM_DEFINE_DCE_COMMAND(...) ESP_MODEM_DECLARE_DCE_COMMAND(##__VA_ARGS__) -#define DEFINE_ALL_COMMAND_APIS() DECLARE_ALL_COMMAND_APIS() - #define DECLARE_ALL_COMMAND_APIS(...) \ /** - * @brief Sends the supplied PIN code - * - * @param pin Pin - * - */ \ - \ -ESP_MODEM_DECLARE_DCE_COMMAND(set_pin, command_result, 1, MUX_ARG, STRING_IN(x, pin)) \ -\ + * @brief Sets the supplied PIN code + * @param[in] pin Pin + * @return OK, FAIL or TIMEOUT + */\ +ESP_MODEM_DECLARE_DCE_COMMAND(set_pin, command_result, 1, STRING_IN(x, pin)) \ \ /** * @brief Checks if the SIM needs a PIN - * - * @param[out] pin_ok Pin + * @param[out] pin_ok true if the SIM card doesn't need a PIN to unlock + * @return OK, FAIL or TIMEOUT */ \ -ESP_MODEM_DECLARE_DCE_COMMAND(read_pin, command_result, 1, MUX_ARG, BOOL_OUT(x, pin_ok)) \ +ESP_MODEM_DECLARE_DCE_COMMAND(read_pin, command_result, 1, BOOL_OUT(x, pin_ok)) \ + \ +/** + * @brief Sets echo mode + * @param[in] echo_on true if echo mode on (repeats the commands) + * @return OK, FAIL or TIMEOUT + */ \ +ESP_MODEM_DECLARE_DCE_COMMAND(set_echo, command_result, 1, BOOL_IN(x, echo_on)) \ + \ +/** + * @brief Sets the Txt or Pdu mode for SMS (only txt is supported) + * @param[in] txt true if txt mode + * @return OK, FAIL or TIMEOUT + */ \ +ESP_MODEM_DECLARE_DCE_COMMAND(sms_txt_mode, command_result, 1, BOOL_IN(x, txt)) \ + \ +/** + * @brief Sets the default (GSM) charater set + * @return OK, FAIL or TIMEOUT + */ \ +ESP_MODEM_DECLARE_DCE_COMMAND(sms_character_set, command_result, 0) \ + \ +/** + * @brief Sends SMS message in txt mode + * @param[in] number Phone number to send the message to + * @param[in] message Text message to be sent + * @return OK, FAIL or TIMEOUT + */ \ +ESP_MODEM_DECLARE_DCE_COMMAND(send_sms, command_result, 2, STRING_IN(x, number), STRING_IN(y, message)) \ + \ +/** + * @brief Resumes data mode (Switches back to th data mode, which was temporarily suspended) + * @return OK, FAIL or TIMEOUT + */ \ +ESP_MODEM_DECLARE_DCE_COMMAND(resume_data_mode, command_result, 0) \ + \ +/** + * @brief Sets php context + * @param[in] x PdP context struct to setup modem cellular connection + * @return OK, FAIL or TIMEOUT + */ \ +ESP_MODEM_DECLARE_DCE_COMMAND(set_pdp_context, command_result, 1, STRUCT_OUT(PdpContext, x)) \ + \ +/** + * @brief Switches to the command mode + * @return OK, FAIL or TIMEOUT + */ \ +ESP_MODEM_DECLARE_DCE_COMMAND(set_command_mode, command_result, 0) \ + \ +/** + * @brief Switches to the CMUX mode + * @return OK, FAIL or TIMEOUT + */ \ +ESP_MODEM_DECLARE_DCE_COMMAND(set_cmux, command_result, 0) \ + \ +/** + * @brief Reads the IMSI number + * @param[out] imsi Module's IMSI number + * @return OK, FAIL or TIMEOUT + */ \ +ESP_MODEM_DECLARE_DCE_COMMAND(get_imsi, command_result, 1, STRING_OUT(x, imsi)) \ + \ +/** + * @brief Reads the IMEI number + * @param[out] imei Module's IMEI number + * @return OK, FAIL or TIMEOUT + */ \ +ESP_MODEM_DECLARE_DCE_COMMAND(get_imei, command_result, 1, STRING_OUT(x, imei)) \ \ /** * @brief Reads the module name - * * @param[out] name module name + * @return OK, FAIL or TIMEOUT */ \ -ESP_MODEM_DECLARE_DCE_COMMAND(set_echo, command_result, 1, MUX_ARG, BOOL_IN(x, echo_on)) \ -ESP_MODEM_DECLARE_DCE_COMMAND(sms_txt_mode, command_result, 1, MUX_ARG, BOOL_IN(x, txt)) \ -ESP_MODEM_DECLARE_DCE_COMMAND(sms_character_set, command_result, 0, MUX_ARG) \ -ESP_MODEM_DECLARE_DCE_COMMAND(send_sms, command_result, 2, MUX_ARG, STRING_IN(x, number), STRING_IN(y, message)) \ - \ - \ -/** - * @brief Reads the module name - * - * @param[out] name module name - */ \ -ESP_MODEM_DECLARE_DCE_COMMAND(resume_data_mode, command_result, 0, MUX_ARG) \ - \ -/** - * @brief Reads the module name - * - * @param[out] name module name - */ \ -ESP_MODEM_DECLARE_DCE_COMMAND(set_pdp_context, command_result, 1, MUX_ARG, STRUCT_OUT(PdpContext, x)) \ - \ -/** - * @brief Reads the module name - * - * @param[out] name module name - */ \ -ESP_MODEM_DECLARE_DCE_COMMAND(set_command_mode, command_result, 0, MUX_ARG) \ - \ -/** - * @brief Reads the module name - * - * @param[out] name module name - */ \ -ESP_MODEM_DECLARE_DCE_COMMAND(set_cmux, command_result, 0, MUX_ARG) \ - \ -/** - * @brief Reads the module name - * - * @param[out] name module name - */ \ -ESP_MODEM_DECLARE_DCE_COMMAND(get_imsi, command_result, 1, MUX_ARG, STRING_OUT(x, imsi)) \ - \ -/** - * @brief Reads the module name - * - * @param[out] name module name - */ \ -ESP_MODEM_DECLARE_DCE_COMMAND(get_imei, command_result, 1, MUX_ARG, STRING_OUT(x, name)) \ - \ -/** - * @brief Reads the module name - * - * @param[out] name module name - */ \ -ESP_MODEM_DECLARE_DCE_COMMAND(get_module_name, command_result, 1, MUX_ARG, STRING_OUT(x, name)) \ +ESP_MODEM_DECLARE_DCE_COMMAND(get_module_name, command_result, 1, STRING_OUT(x, name)) \ \ /** * @brief Sets the modem to data mode - * + * @return OK, FAIL or TIMEOUT */ \ -ESP_MODEM_DECLARE_DCE_COMMAND(set_data_mode, command_result, 0, MUX_ARG) \ +ESP_MODEM_DECLARE_DCE_COMMAND(set_data_mode, command_result, 0) \ \ /** * @brief Get Signal quality - * + * @param[out] rssi signal strength indication + * @param[out] ber channel bit error rate + * @return OK, FAIL or TIMEOUT */ \ -ESP_MODEM_DECLARE_DCE_COMMAND(get_signal_quality, command_result, 2, MUX_ARG, INT_OUT(x, rssi), INT_OUT(y, ber)) +ESP_MODEM_DECLARE_DCE_COMMAND(get_signal_quality, command_result, 2, INT_OUT(x, rssi), INT_OUT(y, ber)) #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' // cat ../include/generate/esp_modem_command_declare.inc | clang -E -P -CC -xc -I../include -DGENERATE_DOCS - | sed -n '1,/DCE command documentation/!p' > c_api.h // cat ../include/generate/esp_modem_command_declare.inc | clang -E -P -xc -I../include -DGENERATE_DOCS -DGENERATE_RST_LINKS - | sed 's/NL/\n/g' > cxx_api_links.rst + +// call parametrs by names for documentation +#undef _ARG +#define _ARG(param, name) name // --- DCE command documentation starts here --- #ifdef __cplusplus class esp_modem::DCE: public DCE_T { public: using DCE_T::DCE_T; -#define ESP_MODEM_DECLARE_DCE_COMMAND(name, return_type, TEMPLATE_ARG, MUX_ARG, ...) return_type name (__VA_ARGS__); +#define ESP_MODEM_DECLARE_DCE_COMMAND(name, return_type, TEMPLATE_ARG, ...) return_type name (__VA_ARGS__); #elif defined(GENERATE_RST_LINKS) -#define ESP_MODEM_DECLARE_DCE_COMMAND(name, return_type, TEMPLATE_ARG, MUX_ARG, ...) NL- :cpp:func:`esp_modem::DCE::name` +#define ESP_MODEM_DECLARE_DCE_COMMAND(name, return_type, TEMPLATE_ARG, ...) NL- :cpp:func:`esp_modem::DCE::name` #else -#define ESP_MODEM_DECLARE_DCE_COMMAND(name, return_type, TEMPLATE_ARG, MUX_ARG, ...) return_type esp_modem_ ## name (__VA_ARGS__); +#define ESP_MODEM_DECLARE_DCE_COMMAND(name, return_type, TEMPLATE_ARG, ...) return_type esp_modem_ ## name (__VA_ARGS__); #endif DECLARE_ALL_COMMAND_APIS() diff --git a/esp_modem/src/esp_modem_api.cpp b/esp_modem/src/esp_modem_api.cpp index 85a4b90cd..447c52022 100644 --- a/esp_modem/src/esp_modem_api.cpp +++ b/esp_modem/src/esp_modem_api.cpp @@ -18,10 +18,8 @@ #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 "cstring" namespace esp_modem { diff --git a/esp_modem/src/esp_modem_cmux.cpp b/esp_modem/src/esp_modem_cmux.cpp index 52984d33a..0008f4afd 100644 --- a/esp_modem/src/esp_modem_cmux.cpp +++ b/esp_modem/src/esp_modem_cmux.cpp @@ -103,24 +103,43 @@ bool CMux::on_cmux(uint8_t *data, size_t actual_len) } ESP_LOG_BUFFER_HEXDUMP("Received", data, actual_len, ESP_LOG_DEBUG); uint8_t* frame = data; + uint8_t* recover_ptr; auto available_len = actual_len; size_t payload_offset = 0; size_t footer_offset = 0; while (available_len > 0) { switch (state) { case cmux_state::RECOVER: - // TODO: Implement recovery, looking for SOF_MARKER's - break; + if (frame[0] == SOF_MARKER) { + // already init state + state = cmux_state::INIT; + break; + } + recover_ptr = static_cast(memchr(frame, SOF_MARKER, available_len)); + if (recover_ptr && available_len > recover_ptr - frame) { + available_len -= (recover_ptr - frame); + frame = recover_ptr; + state = cmux_state::INIT; + ESP_LOGD("CMUX", "Protocol recovered"); + if (available_len > 1 && frame[1] == SOF_MARKER) { + // empty frame + available_len -= 1; + frame += 1; + } + break; + } + // marker not found, continue with recovery + return false; case cmux_state::INIT: if (frame[0] != SOF_MARKER) { - ESP_LOGW("CMUX", "TODO: Recover!"); - return true; + ESP_LOGI("CMUX", "Protocol mismatch!"); + state = cmux_state::RECOVER; + break; } if (available_len > 1 && frame[1] == SOF_MARKER) { - ESP_LOGI("CMUX", "Empty frame"); // empty frame - available_len -= 2; - frame += 2; + available_len -= 1; + frame += 1; break; } state = cmux_state::HEADER; @@ -140,7 +159,7 @@ bool CMux::on_cmux(uint8_t *data, size_t actual_len) dlci = frame_header[1] >> 2; type = frame_header[2]; payload_len = (frame_header[3] >> 1); - ESP_LOGI("CMUX", "CMUX FR: A:%02x T:%02x L:%d", dlci, type, payload_len); + ESP_LOGD("CMUX", "CMUX FR: A:%02x T:%02x L:%d", dlci, type, payload_len); frame += payload_offset; available_len -= payload_offset; state = cmux_state::PAYLOAD; @@ -169,8 +188,9 @@ bool CMux::on_cmux(uint8_t *data, size_t actual_len) footer_offset = std::min(available_len, 6 - frame_header_offset); memcpy(frame_header + frame_header_offset, frame, footer_offset); if (frame_header[5] != SOF_MARKER) { - ESP_LOGW("CMUX", "TODO: Recover!"); - return true; + ESP_LOGI("CMUX", "Protocol mismatch!"); + state = cmux_state::RECOVER; + break; } if (payload_len == 0) { data_available(frame_header, 0); // Null payload @@ -190,6 +210,7 @@ void CMux::init() frame_header_offset = 0; state = cmux_state::INIT; term->set_read_cb([this](uint8_t *data, size_t len) { + Scoped l(lock); this->on_cmux(data, len); return false; }); @@ -203,22 +224,31 @@ void CMux::init() int CMux::write(int virtual_term, uint8_t *data, size_t len) { + const size_t cmux_max_len = 127; Scoped l(lock); int i = virtual_term + 1; - uint8_t frame[6]; - frame[0] = SOF_MARKER; - frame[1] = (i << 2) + 1; - frame[2] = FT_UIH; - frame[3] = (len << 1) + 1; - frame[4] = 0xFF - fcs_crc(frame); - frame[5] = SOF_MARKER; + size_t need_write = len; + while (need_write > 0) { + size_t batch_len = need_write; + if (batch_len > cmux_max_len) + batch_len = cmux_max_len; + uint8_t frame[6]; + frame[0] = SOF_MARKER; + frame[1] = (i << 2) + 1; + frame[2] = FT_UIH; + frame[3] = (batch_len << 1) + 1; + frame[4] = 0xFF - fcs_crc(frame); + frame[5] = SOF_MARKER; - term->write(frame, 4); - term->write(data, len); - term->write(frame + 4, 2); - ESP_LOG_BUFFER_HEXDUMP("Send", frame, 4, ESP_LOG_VERBOSE); - ESP_LOG_BUFFER_HEXDUMP("Send", data, len, ESP_LOG_VERBOSE); - ESP_LOG_BUFFER_HEXDUMP("Send", frame+4, 2, ESP_LOG_VERBOSE); + term->write(frame, 4); + term->write(data, batch_len); + term->write(frame + 4, 2); + ESP_LOG_BUFFER_HEXDUMP("Send", frame, 4, ESP_LOG_VERBOSE); + ESP_LOG_BUFFER_HEXDUMP("Send", data, batch_len, ESP_LOG_VERBOSE); + ESP_LOG_BUFFER_HEXDUMP("Send", frame+4, 2, ESP_LOG_VERBOSE); + need_write -= batch_len; + data += batch_len; + } return len; } diff --git a/esp_modem/src/esp_modem_modules.cpp b/esp_modem/src/esp_modem_modules.cpp index fa53b406d..8ff9d0afc 100644 --- a/esp_modem/src/esp_modem_modules.cpp +++ b/esp_modem/src/esp_modem_modules.cpp @@ -28,7 +28,7 @@ GenericModule::GenericModule(std::shared_ptr dte, const dce_config *config) #define _ARGS(x) ARGS ## x #define ARGS(x) _ARGS(x) #define TEMPLATE_ARG -#define ESP_MODEM_DECLARE_DCE_COMMAND(name, return_type, arg_nr, MUX_ARG, ...) \ +#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(...) { diff --git a/esp_modem/src/esp_modem_netif.cpp b/esp_modem/src/esp_modem_netif.cpp index bfa80e99c..02805f4d3 100644 --- a/esp_modem/src/esp_modem_netif.cpp +++ b/esp_modem/src/esp_modem_netif.cpp @@ -95,6 +95,11 @@ void Netif::stop() { } Netif::~Netif() { + if (signal.is_any(PPP_STARTED)) { + esp_netif_action_stop(driver.base.netif, nullptr, 0, nullptr); + signal.clear(PPP_STARTED); + signal.wait(PPP_EXIT, 30000); + } esp_event_handler_unregister(NETIF_PPP_STATUS, ESP_EVENT_ANY_ID, &on_ppp_changed); esp_event_handler_unregister(IP_EVENT, IP_EVENT_PPP_GOT_IP, esp_netif_action_connected); esp_event_handler_unregister(IP_EVENT, IP_EVENT_PPP_LOST_IP, esp_netif_action_disconnected);