From e0e65856f0b81a21c85ed7e86144b5a3c4f402e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20=C4=8Cerm=C3=A1k?= Date: Wed, 26 May 2021 16:41:19 +0800 Subject: [PATCH] esp-modem(Docs): Update documentation and minor fixes --- components/esp_modem/README.md | 2 +- components/esp_modem/docs/README.md | 12 +- components/esp_modem/docs/advanced_api.rst | 4 +- components/esp_modem/docs/api_docs.rst | 8 +- components/esp_modem/docs/cxx_api_links.rst | 25 ---- .../esp_modem/docs/esp_modem_api_commands.h | 99 ---------------- components/esp_modem/docs/esp_modem_dce.hpp | 111 ------------------ components/esp_modem/docs/generate_docs | 4 +- .../ap_to_pppos/main/Kconfig.projbuild | 7 ++ .../examples/ap_to_pppos/main/ap_to_pppos.c | 1 - .../examples/ap_to_pppos/main/network_dce.cpp | 109 ++++++++--------- .../examples/linux_modem/main/modem_main.cpp | 2 +- .../examples/modem_console/README.md | 2 +- .../modem_console/main/console_helper.cpp | 30 ++--- .../modem_console/main/console_helper.hpp | 15 ++- .../modem_console/main/modem_console_main.cpp | 2 +- .../include/cxx_include/esp_modem_cmux.hpp | 4 +- .../include/cxx_include/esp_modem_dce.hpp | 2 +- .../cxx_include/esp_modem_terminal.hpp | 6 +- .../esp_modem/include/esp_modem_config.h | 11 ++ .../esp_modem/include/esp_modem_dce_config.h | 7 ++ .../generate/esp_modem_command_declare.inc | 2 +- .../esp_modem/src/esp_modem_term_fs.cpp | 12 +- components/esp_modem/src/esp_modem_uart.cpp | 12 +- 24 files changed, 139 insertions(+), 350 deletions(-) delete mode 100644 components/esp_modem/docs/cxx_api_links.rst delete mode 100644 components/esp_modem/docs/esp_modem_api_commands.h delete mode 100644 components/esp_modem/docs/esp_modem_dce.hpp diff --git a/components/esp_modem/README.md b/components/esp_modem/README.md index b0b37b3c4..8e6994a43 100644 --- a/components/esp_modem/README.md +++ b/components/esp_modem/README.md @@ -1,6 +1,6 @@ # ESP MODEM -The `esp-modem` component is a managed component for `esp-idf` that could be used for communication with GSM/LTE modems +The `esp-modem` component is a managed component for `esp-idf` that is used for communication with GSM/LTE modems that support AT commands and PPP protocol as a network interface. ## Examples diff --git a/components/esp_modem/docs/README.md b/components/esp_modem/docs/README.md index 38fb22cb5..68d929e93 100644 --- a/components/esp_modem/docs/README.md +++ b/components/esp_modem/docs/README.md @@ -36,11 +36,11 @@ After the object is created, the application interaction with the DCE is in * switching between data and command mode ### DTE -Is an abstraction of the connected interface. Current implementation supports only UART +Is an abstraction of the physical interface connected to the modem. Current implementation supports only UART -### PPP +### PPP netif -Is used to connect the specific network interface to the modem data mode. Currently implementation supports only PPPoS protocol. +Is used to attach the specific network interface to a network communication protocol used by the modem. Currently implementation supports only PPPoS protocol. ### Module @@ -48,7 +48,7 @@ Abstraction of the specific modem device. Currently the component supports SIM80 ## Use cases -Users could 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) @@ -57,7 +57,7 @@ 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 modules commands in a console application. +* `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. @@ -66,7 +66,7 @@ Common use cases of the esp-modem are also listed as the examples: ### CMUX Implementation of virtual terminals is an experimental feature, which allows users to also issue commands in the data mode, -after creating multiple virtual terminals, designating some of them solely to the data mode, while other to command mode. +after creating multiple virtual terminals, designating some of them solely to data mode, others solely to command mode. ### DTE's diff --git a/components/esp_modem/docs/advanced_api.rst b/components/esp_modem/docs/advanced_api.rst index fd7e7af39..965f59cd7 100644 --- a/components/esp_modem/docs/advanced_api.rst +++ b/components/esp_modem/docs/advanced_api.rst @@ -26,7 +26,7 @@ Create custom module Creating a custom module is necessary if the application needs to use a specific device that is not supported and their commands differ from any of the supported devices. In this case it is recommended to define a new class representing this specific device and derive from the :cpp:class:`GenericModule`. In order to instantiate -the appropriate DCE of this module, application could use :ref:`the DCE factory`, but build the DCE with +the appropriate DCE of this module, application could use :ref:`the DCE factory`, and build the DCE with the specific module, using :cpp:func:`esp_modem::dce_factory::Factory::build`. Please refer to the implementation of the existing modules. @@ -41,7 +41,7 @@ Create new communication interface In order to connect to a device using an unsupported interface (e.g. SPI or I2C), it is necessary to implement a custom DTE object and supply it into :ref:`the DCE factory`. The DCE is typically created in two steps: -- Define and create the corresponding terminal, which can communicate on the custom interface. This terminal should support basic IO methods defined in :cpp:class:`esp_modem::Terminal` and derive from it. +- Define and create the corresponding terminal, which communicates on the custom interface. This terminal should support basic IO methods defined in :cpp:class:`esp_modem::Terminal` and derive from it. - Create the DTE which uses the custom Terminal Please refer to the implementation of the existing UART DTE. diff --git a/components/esp_modem/docs/api_docs.rst b/components/esp_modem/docs/api_docs.rst index 23506b257..70386e178 100644 --- a/components/esp_modem/docs/api_docs.rst +++ b/components/esp_modem/docs/api_docs.rst @@ -1,15 +1,15 @@ .. _c_api: -API Guide for C interface -========================= +C API Documentation +=================== -C API is very simple and consist of these two basic parts: +The C API is very simple and consist of these two basic parts: - :ref:`lifecycle_api` - :ref:`modem_commands` -Typical application workflow is to: +The Typical application workflow is to: - Create a DCE instance (using :cpp:func:`esp_modem_new`) - Call specific functions to issue AT commands (:ref:`modem_commands`) diff --git a/components/esp_modem/docs/cxx_api_links.rst b/components/esp_modem/docs/cxx_api_links.rst deleted file mode 100644 index 73d33092c..000000000 --- a/components/esp_modem/docs/cxx_api_links.rst +++ /dev/null @@ -1,25 +0,0 @@ - -- :cpp:func:`esp_modem::DCE::sync` -- :cpp:func:`esp_modem::DCE::get_operator_name` -- :cpp:func:`esp_modem::DCE::store_profile` -- :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` -- :cpp:func:`esp_modem::DCE::set_cmux` -- :cpp:func:`esp_modem::DCE::get_imsi` -- :cpp:func:`esp_modem::DCE::get_imei` -- :cpp:func:`esp_modem::DCE::get_module_name` -- :cpp:func:`esp_modem::DCE::set_data_mode` -- :cpp:func:`esp_modem::DCE::get_signal_quality` -- :cpp:func:`esp_modem::DCE::set_flow_control` -- :cpp:func:`esp_modem::DCE::hang_up` -- :cpp:func:`esp_modem::DCE::get_battery_status` -- :cpp:func:`esp_modem::DCE::power_down` -- :cpp:func:`esp_modem::DCE::reset` -- :cpp:func:`esp_modem::DCE::set_baud` diff --git a/components/esp_modem/docs/esp_modem_api_commands.h b/components/esp_modem/docs/esp_modem_api_commands.h deleted file mode 100644 index 1d14f91e2..000000000 --- a/components/esp_modem/docs/esp_modem_api_commands.h +++ /dev/null @@ -1,99 +0,0 @@ -// 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 initial AT sequence to sync up with the device - * @return OK, FAIL or TIMEOUT - */ command_result esp_modem_sync (); /** - * @brief Reads the operator name - * @param[out] name module name - * @return OK, FAIL or TIMEOUT - */ command_result esp_modem_get_operator_name (char* name); /** - * @brief Stores current user profile - * @return OK, FAIL or TIMEOUT - */ command_result esp_modem_store_profile (); /** - * @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 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 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 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 Switches to the command mode - * @return OK, FAIL or TIMEOUT - */ command_result esp_modem_set_command_mode (); /** - * @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 - * @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 - * @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); /** - * @brief Sets HW control flow - * @param[in] dce_flow 0=none, 2=RTS hw flow control of DCE - * @param[in] dte_flow 0=none, 2=CTS hw flow control of DTE - * @return OK, FAIL or TIMEOUT - */ command_result esp_modem_set_flow_control (int dce_flow, int dte_flow); /** - * @brief Hangs up current data call - * @return OK, FAIL or TIMEOUT - */ command_result esp_modem_hang_up (); /** - * @brief Get voltage levels of modem power up circuitry - * @param[out] voltage Current status in mV - * @param[out] bcs charge status (-1-Not available, 0-Not charging, 1-Charging, 2-Charging done) - * @param[out] bcl 1-100% battery capacity, -1-Not available - * @return OK, FAIL or TIMEOUT - */ command_result esp_modem_get_battery_status (int* voltage, int* bcs, int* bcl); /** - * @brief Power down the module - * @return OK, FAIL or TIMEOUT - */ command_result esp_modem_power_down (); /** - * @brief Reset the module - * @return OK, FAIL or TIMEOUT - */ command_result esp_modem_reset (); /** - * @brief Configures the baudrate - * @param[in] baud Desired baud rate of the DTE - * @return OK, FAIL or TIMEOUT - */ command_result esp_modem_set_baud (int baud); diff --git a/components/esp_modem/docs/esp_modem_dce.hpp b/components/esp_modem/docs/esp_modem_dce.hpp deleted file mode 100644 index 3ad40854d..000000000 --- a/components/esp_modem/docs/esp_modem_dce.hpp +++ /dev/null @@ -1,111 +0,0 @@ -// 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 { -public: - using DCE_T::DCE_T; - - - - - - - -/** - * @brief Sends the initial AT sequence to sync up with the device - * @return OK, FAIL or TIMEOUT - */ command_result sync (); /** - * @brief Reads the operator name - * @param[out] name module name - * @return OK, FAIL or TIMEOUT - */ command_result get_operator_name (std::string& name); /** - * @brief Stores current user profile - * @return OK, FAIL or TIMEOUT - */ command_result store_profile (); /** - * @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 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 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 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 Switches to the command mode - * @return OK, FAIL or TIMEOUT - */ command_result set_command_mode (); /** - * @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 - * @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 - * @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); /** - * @brief Sets HW control flow - * @param[in] dce_flow 0=none, 2=RTS hw flow control of DCE - * @param[in] dte_flow 0=none, 2=CTS hw flow control of DTE - * @return OK, FAIL or TIMEOUT - */ command_result set_flow_control (int dce_flow, int dte_flow); /** - * @brief Hangs up current data call - * @return OK, FAIL or TIMEOUT - */ command_result hang_up (); /** - * @brief Get voltage levels of modem power up circuitry - * @param[out] voltage Current status in mV - * @param[out] bcs charge status (-1-Not available, 0-Not charging, 1-Charging, 2-Charging done) - * @param[out] bcl 1-100% battery capacity, -1-Not available - * @return OK, FAIL or TIMEOUT - */ command_result get_battery_status (int& voltage, int& bcs, int& bcl); /** - * @brief Power down the module - * @return OK, FAIL or TIMEOUT - */ command_result power_down (); /** - * @brief Reset the module - * @return OK, FAIL or TIMEOUT - */ command_result reset (); /** - * @brief Configures the baudrate - * @param[in] baud Desired baud rate of the DTE - * @return OK, FAIL or TIMEOUT - */ command_result set_baud (int baud); -}; diff --git a/components/esp_modem/docs/generate_docs b/components/esp_modem/docs/generate_docs index 4ff1feee6..8a0c2715b 100755 --- a/components/esp_modem/docs/generate_docs +++ b/components/esp_modem/docs/generate_docs @@ -19,5 +19,5 @@ doxygen # Generate the docs python -u -m sphinx.cmd.build -b html . html -# Cleanup the doxygen xml's -rm -rf xml +# Cleanup the doxygen xml's and temporary headers +rm -rf xml esp_modem_api_commands.h esp_modem_dce.hpp cxx_api_links.rst diff --git a/components/esp_modem/examples/ap_to_pppos/main/Kconfig.projbuild b/components/esp_modem/examples/ap_to_pppos/main/Kconfig.projbuild index c757f8778..a8051abc4 100644 --- a/components/esp_modem/examples/ap_to_pppos/main/Kconfig.projbuild +++ b/components/esp_modem/examples/ap_to_pppos/main/Kconfig.projbuild @@ -31,9 +31,16 @@ menu "Example Configuration" help Set APN (Access Point Name), a logical name to choose data network + config EXAMPLE_NEED_SIM_PIN + bool "SIM PIN needed" + default n + help + Enable to set SIM PIN before starting the example + config EXAMPLE_SIM_PIN string "Set SIM PIN" default "1234" + depends on EXAMPLE_NEED_SIM_PIN help Pin to unlock the SIM diff --git a/components/esp_modem/examples/ap_to_pppos/main/ap_to_pppos.c b/components/esp_modem/examples/ap_to_pppos/main/ap_to_pppos.c index 31b326156..3a9e55075 100644 --- a/components/esp_modem/examples/ap_to_pppos/main/ap_to_pppos.c +++ b/components/esp_modem/examples/ap_to_pppos/main/ap_to_pppos.c @@ -93,7 +93,6 @@ static void wifi_event_handler(void* arg, esp_event_base_t event_base, void wifi_init_softap(void) { - wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); ESP_ERROR_CHECK(esp_wifi_init(&cfg)); diff --git a/components/esp_modem/examples/ap_to_pppos/main/network_dce.cpp b/components/esp_modem/examples/ap_to_pppos/main/network_dce.cpp index bdcd44a1b..d91d9bbc9 100644 --- a/components/esp_modem/examples/ap_to_pppos/main/network_dce.cpp +++ b/components/esp_modem/examples/ap_to_pppos/main/network_dce.cpp @@ -19,40 +19,28 @@ using namespace esp_modem; using namespace esp_modem::dce_factory; class NetModule; -typedef DCE_T NetDCE; - -/** - * @brief Local network object used to setup PPP network - */ -class PPPNetwork { -public: - esp_err_t init(esp_netif_t *netif, const std::string& apn, const std::string &pin_number); - void deinit(); - NetDCE * get_dce(); -private: - NetDCE *dce; -}; +using NetDCE = DCE_T; /** * @brief The PPP network is a singleton, allocate statically here */ -static PPPNetwork ppp_network; + /** * @brief Custom factory for creating NetDCE and NetModule */ class NetDCE_Factory: public Factory { public: - template - static DCE_T* create(const config *cfg, Args&&... args) + template + static DCE_T* create(const config *cfg, Args&&... args) { - return build_generic_DCE(cfg, std::forward(args)...); + return build_generic_DCE(cfg, std::forward(args)...); } - template - static std::shared_ptr create_module(const config *cfg, Args&&... args) + template + static std::shared_ptr create_module(const config *cfg, Args&&... args) { - return build_shared_module(cfg, std::forward(args)...); + return build_shared_module(cfg, std::forward(args)...); } }; @@ -67,7 +55,7 @@ public: explicit NetModule(std::shared_ptr dte, const esp_modem_dce_config *cfg): dte(std::move(dte)), apn(std::string(cfg->apn)) {} - bool setup_data_mode() override + [[nodiscard]] bool setup_data_mode() override { PdpContext pdp(apn); if (set_pdp_context(pdp) != command_result::OK) @@ -77,18 +65,20 @@ public: bool set_mode(modem_mode mode) override { - if (mode == modem_mode::DATA_MODE) { - if (set_data_mode() != command_result::OK) - return resume_data_mode() == command_result::OK; - return true; + switch (mode) { + case esp_modem::modem_mode::DATA_MODE: + if (set_data_mode() != command_result::OK) { + return resume_data_mode() == command_result::OK; + } + return true; + case esp_modem::modem_mode::COMMAND_MODE: + return set_command_mode() == command_result::OK; + default: + return false; } - if (mode == modem_mode::COMMAND_MODE) { - return set_command_mode() == command_result::OK; - } - return false; } - bool init(const std::string& pin) + [[maybe_unused]] bool init_sim(const std::string& pin) { // switch to command mode (in case we were in PPP mode) static_cast(set_command_mode()); // ignore the potential failure, as we might be in command mode after startup @@ -118,22 +108,33 @@ private: }; -esp_err_t PPPNetwork::init(esp_netif_t *netif, const std::string& apn, const std::string &pin_number) +/** + * @brief Implement the C-API for the AP-2-PPP functionality + */ +namespace { + +/** + * @brief Local network object used to setup PPP network + */ +NetDCE *dce = nullptr; + +extern "C" esp_err_t modem_init_network(esp_netif_t *netif) { // configure esp_modem_dte_config_t dte_config = ESP_MODEM_DTE_DEFAULT_CONFIG(); dte_config.uart_config.rx_buffer_size = 16384; dte_config.uart_config.tx_buffer_size = 2048; - esp_modem_dce_config dce_config = ESP_MODEM_DCE_DEFAULT_CONFIG(apn.c_str()); + esp_modem_dce_config dce_config = ESP_MODEM_DCE_DEFAULT_CONFIG(CONFIG_EXAMPLE_MODEM_PPP_APN); // create DTE and minimal network DCE auto uart_dte = create_uart_dte(&dte_config); // create the specific device (and initialize it) auto dev = NetDCE_Factory::create_module(&dce_config, uart_dte, netif); - if (!dev->init(pin_number)) +#if CONFIG_EXAMPLE_NEED_SIM_PIN == 1 + if (!dev->init_sim(CONFIG_EXAMPLE_SIM_PIN)) return ESP_FAIL; - +#endif // now create the DCE from our already existent device dce = NetDCE_Factory::create(&dce_config, uart_dte, netif, dev); if (dce == nullptr) @@ -141,36 +142,20 @@ esp_err_t PPPNetwork::init(esp_netif_t *netif, const std::string& apn, const std return ESP_OK; } -void PPPNetwork::deinit() +extern "C" void modem_start_network() +{ + dce->set_mode(esp_modem::modem_mode::DATA_MODE); +} + +extern "C" void modem_stop_network() +{ + dce->set_mode(esp_modem::modem_mode::COMMAND_MODE); +} + +extern "C" void modem_deinit_network() { free(dce); dce = nullptr; } -NetDCE *PPPNetwork::get_dce() -{ - return dce; -} - -/** - * @brief Implement the C-API for the AP-2-PPP functionality - */ -extern "C" esp_err_t modem_init_network(esp_netif_t *netif) -{ - return ppp_network.init(netif, CONFIG_EXAMPLE_MODEM_PPP_APN, CONFIG_EXAMPLE_SIM_PIN); -} - -extern "C" void modem_start_network() -{ - ppp_network.get_dce()->set_mode(esp_modem::modem_mode::DATA_MODE); -} - -extern "C" void modem_stop_network() -{ - ppp_network.get_dce()->set_mode(esp_modem::modem_mode::COMMAND_MODE); -} - -extern "C" void modem_deinit_network() -{ - ppp_network.deinit(); -} +} \ No newline at end of file diff --git a/components/esp_modem/examples/linux_modem/main/modem_main.cpp b/components/esp_modem/examples/linux_modem/main/modem_main.cpp index 46c9449ec..7697387c9 100644 --- a/components/esp_modem/examples/linux_modem/main/modem_main.cpp +++ b/components/esp_modem/examples/linux_modem/main/modem_main.cpp @@ -15,7 +15,7 @@ using namespace esp_modem; -[[maybe_unused]] static const char *TAG = "linux_modem_main"; +[[maybe_unused]] constexpr auto TAG = "linux_modem_main"; int main() diff --git a/components/esp_modem/examples/modem_console/README.md b/components/esp_modem/examples/modem_console/README.md index 852ec533f..66ade1809 100644 --- a/components/esp_modem/examples/modem_console/README.md +++ b/components/esp_modem/examples/modem_console/README.md @@ -1,4 +1,4 @@ -# PPPoS simple client example +# Modem console example (See the README.md file in the upper level 'examples' directory for more information about examples.) diff --git a/components/esp_modem/examples/modem_console/main/console_helper.cpp b/components/esp_modem/examples/modem_console/main/console_helper.cpp index 7c294e08f..8686f16bd 100644 --- a/components/esp_modem/examples/modem_console/main/console_helper.cpp +++ b/components/esp_modem/examples/modem_console/main/console_helper.cpp @@ -21,35 +21,37 @@ ConsoleCommand::ConsoleCommand(const char* command, const char* help, const std: void ConsoleCommand::RegisterCommand(const char* command, const char* help, const std::vector& args) { assert(last_command <= MAX_REPEAT_NR); - void * common_arg = nullptr; - for (auto it: args) { + arg_type common_arg = { }; + for (auto& it: args) { switch(it.type) { case ARG_END: break; case STR0: - common_arg = arg_str0(it.shortopts, it.longopts, it.datatype, it.glossary); + common_arg.str = arg_str0(it.shortopts, it.longopts, it.datatype, it.glossary); break; case STR1: - common_arg = arg_str1(it.shortopts, it.longopts, it.datatype, it.glossary); + common_arg.str = arg_str1(it.shortopts, it.longopts, it.datatype, it.glossary); break; case INT0: - common_arg = arg_int0(it.shortopts, it.longopts, it.datatype, it.glossary); + common_arg.intx = arg_int0(it.shortopts, it.longopts, it.datatype, it.glossary); break; case INT1: - common_arg = arg_int1(it.shortopts, it.longopts, it.datatype, it.glossary); + common_arg.intx = arg_int1(it.shortopts, it.longopts, it.datatype, it.glossary); break; case LIT0: - common_arg = arg_lit0(it.shortopts, it.longopts, it.glossary); + common_arg.lit = arg_lit0(it.shortopts, it.longopts, it.glossary); break; } - if (common_arg) { + if (common_arg.is_null()) { arg_table.emplace_back(common_arg); } else { ESP_LOGE(TAG, "Creating argument parser failed for %s", it.glossary); abort(); } } - arg_table.emplace_back( arg_end(1)); + + arg_type end = { .end = arg_end(1) }; + arg_table.emplace_back(end); const esp_console_cmd_t command_def = { .command = command, .help = help, @@ -64,13 +66,13 @@ void ConsoleCommand::RegisterCommand(const char* command, const char* help, cons int ConsoleCommand::get_count(int index) { - return ((struct arg_str *)arg_table[index])->count; + return (arg_table[index].str)->count; } std::string ConsoleCommand::get_string(int index) { if (get_count(index) > 0) { - return std::string(((struct arg_str *)arg_table[index])->sval[0]); + return std::string(arg_table[index].str->sval[0]); } return std::string(); } @@ -78,17 +80,17 @@ std::string ConsoleCommand::get_string(int index) int ConsoleCommand::get_int(int index) { if (get_count(index) > 0) { - return *((struct arg_int *)arg_table[index])->ival; + return *(arg_table[index].intx)->ival; } return -1; } int ConsoleCommand::command_func(int argc, char **argv) { - void * plain_arg_array = &arg_table[0]; + arg_type* plain_arg_array = &arg_table[0]; int nerrors = arg_parse(argc, argv, (void **)plain_arg_array); if (nerrors != 0) { - arg_print_errors(stderr, (struct arg_end *) arg_table.back(), argv[0]); + arg_print_errors(stderr, arg_table.back().end, argv[0]); return 1; } if (func) { diff --git a/components/esp_modem/examples/modem_console/main/console_helper.hpp b/components/esp_modem/examples/modem_console/main/console_helper.hpp index cde8f0a0c..c5e8b718d 100644 --- a/components/esp_modem/examples/modem_console/main/console_helper.hpp +++ b/components/esp_modem/examples/modem_console/main/console_helper.hpp @@ -53,6 +53,19 @@ class StaticCommands; * @brief This class simplifies console command definition in more object wise fashion */ class ConsoleCommand { + /** + * @brief Common argument types to be stored internally for parsing later + */ + using arg_type = + union { + struct arg_int *intx; + struct arg_str *str; + struct arg_lit *lit; + struct arg_end *end; + void *__raw_ptr; + bool is_null() const { return __raw_ptr; } + }; + friend class StaticCommands; public: /** @@ -91,7 +104,7 @@ private: void RegisterCommand(const char* command, const char* help, const std::vector& args); template static constexpr size_t index_arg(CommandArgs T::*member) { return ((uint8_t *)&((T*)nullptr->*member) - (uint8_t *)nullptr)/sizeof(CommandArgs); } - std::vector arg_table; + std::vector arg_table; int command_func(int argc, char **argv); static int last_command; diff --git a/components/esp_modem/examples/modem_console/main/modem_console_main.cpp b/components/esp_modem/examples/modem_console/main/modem_console_main.cpp index 0a193ff55..e3cc4d140 100644 --- a/components/esp_modem/examples/modem_console/main/modem_console_main.cpp +++ b/components/esp_modem/examples/modem_console/main/modem_console_main.cpp @@ -157,11 +157,11 @@ extern "C" void app_main(void) auto cmd = c->get_string_of(&GenericCommandArgs::cmd); auto timeout = c->get_count_of(&GenericCommandArgs::timeout) ? c->get_int_of(&GenericCommandArgs::timeout) : 1000; + ESP_LOGI(TAG, "Sending command %s with timeout %d", cmd.c_str(), timeout); auto pattern = c->get_string_of(&GenericCommandArgs::pattern); if (c->get_count_of(&GenericCommandArgs::no_cr) == 0) { cmd += '\r'; } - ESP_LOGI(TAG, "Sending command %s with timeout %d", cmd.c_str(), timeout); CHECK_ERR(dce->command(cmd, [&](uint8_t *data, size_t len) { std::string response((char *) data, len); ESP_LOGI(TAG, "%s", response.c_str()); diff --git a/components/esp_modem/include/cxx_include/esp_modem_cmux.hpp b/components/esp_modem/include/cxx_include/esp_modem_cmux.hpp index ffa088819..a8d075490 100644 --- a/components/esp_modem/include/cxx_include/esp_modem_cmux.hpp +++ b/components/esp_modem/include/cxx_include/esp_modem_cmux.hpp @@ -51,7 +51,7 @@ class CMuxInstance; /** * @brief CMux class which consumes the original terminal and creates multiple virtual terminals from it. - * This class is not usable applicable as a DTE terminal + * This class itself is not usable as a DTE terminal, only via its instances defined in `CMuxInstance` */ class CMux { public: @@ -100,7 +100,7 @@ public: void stop() override { } private: std::shared_ptr cmux; - int instance; + size_t instance; }; /** diff --git a/components/esp_modem/include/cxx_include/esp_modem_dce.hpp b/components/esp_modem/include/cxx_include/esp_modem_dce.hpp index 5666b8fa2..47b2d4b23 100644 --- a/components/esp_modem/include/cxx_include/esp_modem_dce.hpp +++ b/components/esp_modem/include/cxx_include/esp_modem_dce.hpp @@ -88,7 +88,7 @@ protected: * @brief Common abstraction of the modem DCE, specialized by the GenericModule which is a parent class for the supported * defices and most common modems, as well. */ -class DCE: public DCE_T { +class DCE : public DCE_T { public: using DCE_T::DCE_T; diff --git a/components/esp_modem/include/cxx_include/esp_modem_terminal.hpp b/components/esp_modem/include/cxx_include/esp_modem_terminal.hpp index 98b4560a3..5a77d0e6b 100644 --- a/components/esp_modem/include/cxx_include/esp_modem_terminal.hpp +++ b/components/esp_modem/include/cxx_include/esp_modem_terminal.hpp @@ -45,7 +45,7 @@ enum class terminal_error { }; /** - * @brief Terminal interface. All communication interfaces must comply this interface in order to be used as a DTE + * @brief Terminal interface. All communication interfaces must comply to this interface in order to be used as a DTE */ class Terminal { public: @@ -53,7 +53,7 @@ public: void set_error_cb(std::function f) { on_error = std::move(f); } - virtual void set_read_cb(std::function f) { on_data = std::move(f); } + virtual void set_read_cb(std::function f) { on_read = std::move(f); } /** * @brief Writes data to the terminal @@ -76,7 +76,7 @@ public: virtual void stop() = 0; protected: - std::function on_data; + std::function on_read; std::function on_error; }; diff --git a/components/esp_modem/include/esp_modem_config.h b/components/esp_modem/include/esp_modem_config.h index 40f8f670a..de1c79a25 100644 --- a/components/esp_modem/include/esp_modem_config.h +++ b/components/esp_modem/include/esp_modem_config.h @@ -17,6 +17,10 @@ #include "driver/uart.h" #include "esp_modem_dce_config.h" +#ifdef __cplusplus +extern "C" { +#endif + /** * @defgroup ESP_MODEM_CONFIG * @brief Configuration structures for DTE and DCE @@ -56,6 +60,9 @@ struct esp_modem_uart_term_config { int event_queue_size; /*!< UART Event Queue Size, set to 0 if no event queue needed */ }; +// Forward declare the resource struct +struct esp_modem_vfs_resource; + /** * @brief VFS configuration structure * @@ -116,4 +123,8 @@ typedef struct esp_modem_dte_config esp_modem_dte_config_t; * @} */ +#ifdef __cplusplus +} +#endif + #endif // _ESP_MODEM_CONFIG_H_ diff --git a/components/esp_modem/include/esp_modem_dce_config.h b/components/esp_modem/include/esp_modem_dce_config.h index 6f1931dfd..53db234dc 100644 --- a/components/esp_modem/include/esp_modem_dce_config.h +++ b/components/esp_modem/include/esp_modem_dce_config.h @@ -15,6 +15,10 @@ #ifndef _ESP_MODEM_DCE_CONFIG_H_ #define _ESP_MODEM_DCE_CONFIG_H_ +#ifdef __cplusplus +extern "C" { +#endif + /** @addtogroup ESP_MODEM_CONFIG * @{ */ @@ -41,5 +45,8 @@ struct esp_modem_dce_config { * @} */ +#ifdef __cplusplus +} +#endif #endif // _ESP_MODEM_DCE_CONFIG_H_ 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 05afaa027..2c26d37f6 100644 --- a/components/esp_modem/include/generate/esp_modem_command_declare.inc +++ b/components/esp_modem/include/generate/esp_modem_command_declare.inc @@ -213,7 +213,7 @@ ESP_MODEM_DECLARE_DCE_COMMAND(set_baud, command_result, 1, INT_IN(x, baud)) #define _ARG(param, name) name // --- DCE command documentation starts here --- #ifdef __cplusplus -class esp_modem::DCE: public DCE_T { +class esp_modem::DCE : public DCE_T { public: using DCE_T::DCE_T; #define ESP_MODEM_DECLARE_DCE_COMMAND(name, return_type, TEMPLATE_ARG, ...) return_type name (__VA_ARGS__); diff --git a/components/esp_modem/src/esp_modem_term_fs.cpp b/components/esp_modem/src/esp_modem_term_fs.cpp index c23e2c15c..00a09224f 100644 --- a/components/esp_modem/src/esp_modem_term_fs.cpp +++ b/components/esp_modem/src/esp_modem_term_fs.cpp @@ -58,7 +58,7 @@ public: int read(uint8_t *data, size_t len) override; void set_read_cb(std::function f) override { - on_data = std::move(f); + on_read = std::move(f); signal.set(TASK_PARAMS); } @@ -94,7 +94,7 @@ FdTerminal::FdTerminal(const esp_modem_dte_config *config) : void FdTerminal::task() { - std::function on_data_priv = nullptr; + std::function on_read_priv = nullptr; signal.set(TASK_INIT); signal.wait_any(TASK_START | TASK_STOP, portMAX_DELAY); if (signal.is_any(TASK_STOP)) { @@ -113,7 +113,7 @@ void FdTerminal::task() s = select(f.fd + 1, &rfds, nullptr, nullptr, &tv); if (signal.is_any(TASK_PARAMS)) { - on_data_priv = on_data; + on_read_priv = on_read; signal.clear(TASK_PARAMS); } @@ -123,9 +123,9 @@ void FdTerminal::task() // ESP_LOGV(TAG, "Select exited with timeout"); } else { if (FD_ISSET(f.fd, &rfds)) { - if (on_data_priv) { - if (on_data_priv(nullptr, 0)) { - on_data_priv = nullptr; + if (on_read_priv) { + if (on_read_priv(nullptr, 0)) { + on_read_priv = nullptr; } } } diff --git a/components/esp_modem/src/esp_modem_uart.cpp b/components/esp_modem/src/esp_modem_uart.cpp index 95acd31d6..2d73eafa9 100644 --- a/components/esp_modem/src/esp_modem_uart.cpp +++ b/components/esp_modem/src/esp_modem_uart.cpp @@ -65,7 +65,7 @@ public: int read(uint8_t *data, size_t len) override; void set_read_cb(std::function f) override { - on_data = std::move(f); + on_read = std::move(f); signal.set(TASK_PARAMS); } @@ -106,7 +106,7 @@ std::unique_ptr create_uart_terminal(const esp_modem_dte_config *confi } void UartTerminal::task() { - std::function on_data_priv = nullptr; + std::function on_read_priv = nullptr; uart_event_t event; size_t len; signal.set(TASK_INIT); @@ -117,15 +117,15 @@ void UartTerminal::task() { while (signal.is_any(TASK_START)) { if (get_event(event, 100)) { if (signal.is_any(TASK_PARAMS)) { - on_data_priv = on_data; + on_read_priv = on_read; signal.clear(TASK_PARAMS); } switch (event.type) { case UART_DATA: uart_get_buffered_data_len(uart.port, &len); - if (len && on_data_priv) { - if (on_data_priv(nullptr, len)) { - on_data_priv = nullptr; + if (len && on_read_priv) { + if (on_read_priv(nullptr, len)) { + on_read_priv = nullptr; } } break;