mirror of
https://github.com/espressif/esp-protocols.git
synced 2025-07-19 05:22:21 +02:00
esp-modem(Docs): Update documentation and minor fixes
This commit is contained in:
committed by
David Cermak
parent
28433de4ad
commit
e0e65856f0
@ -1,6 +1,6 @@
|
|||||||
# ESP MODEM
|
# 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.
|
that support AT commands and PPP protocol as a network interface.
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
@ -36,11 +36,11 @@ After the object is created, the application interaction with the DCE is in
|
|||||||
* switching between data and command mode
|
* switching between data and command mode
|
||||||
|
|
||||||
### DTE
|
### 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
|
### Module
|
||||||
|
|
||||||
@ -48,7 +48,7 @@ Abstraction of the specific modem device. Currently the component supports SIM80
|
|||||||
|
|
||||||
## Use cases
|
## 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.
|
* Switch between command and data mode to connect to the internet via cellular network.
|
||||||
* Send various commands to the device (e.g. send SMS)
|
* 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:
|
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/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
|
* `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.
|
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
|
### CMUX
|
||||||
|
|
||||||
Implementation of virtual terminals is an experimental feature, which allows users to also issue commands in the data mode,
|
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
|
### DTE's
|
||||||
|
|
||||||
|
@ -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
|
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
|
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
|
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<dce_factory>`, but build the DCE with
|
the appropriate DCE of this module, application could use :ref:`the DCE factory<dce_factory>`, and build the DCE with
|
||||||
the specific module, using :cpp:func:`esp_modem::dce_factory::Factory::build`.
|
the specific module, using :cpp:func:`esp_modem::dce_factory::Factory::build`.
|
||||||
|
|
||||||
Please refer to the implementation of the existing modules.
|
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
|
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<dce_factory>`. The DCE is typically created in two steps:
|
a custom DTE object and supply it into :ref:`the DCE factory<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
|
- Create the DTE which uses the custom Terminal
|
||||||
|
|
||||||
Please refer to the implementation of the existing UART DTE.
|
Please refer to the implementation of the existing UART DTE.
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
.. _c_api:
|
.. _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:`lifecycle_api`
|
||||||
- :ref:`modem_commands`
|
- :ref:`modem_commands`
|
||||||
|
|
||||||
Typical application workflow is to:
|
The Typical application workflow is to:
|
||||||
|
|
||||||
- Create a DCE instance (using :cpp:func:`esp_modem_new`)
|
- Create a DCE instance (using :cpp:func:`esp_modem_new`)
|
||||||
- Call specific functions to issue AT commands (:ref:`modem_commands`)
|
- Call specific functions to issue AT commands (:ref:`modem_commands`)
|
||||||
|
@ -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`
|
|
@ -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);
|
|
@ -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<GenericModule> {
|
|
||||||
public:
|
|
||||||
using DCE_T<GenericModule>::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);
|
|
||||||
};
|
|
@ -19,5 +19,5 @@ doxygen
|
|||||||
# Generate the docs
|
# Generate the docs
|
||||||
python -u -m sphinx.cmd.build -b html . html
|
python -u -m sphinx.cmd.build -b html . html
|
||||||
|
|
||||||
# Cleanup the doxygen xml's
|
# Cleanup the doxygen xml's and temporary headers
|
||||||
rm -rf xml
|
rm -rf xml esp_modem_api_commands.h esp_modem_dce.hpp cxx_api_links.rst
|
||||||
|
@ -31,9 +31,16 @@ menu "Example Configuration"
|
|||||||
help
|
help
|
||||||
Set APN (Access Point Name), a logical name to choose data network
|
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
|
config EXAMPLE_SIM_PIN
|
||||||
string "Set SIM PIN"
|
string "Set SIM PIN"
|
||||||
default "1234"
|
default "1234"
|
||||||
|
depends on EXAMPLE_NEED_SIM_PIN
|
||||||
help
|
help
|
||||||
Pin to unlock the SIM
|
Pin to unlock the SIM
|
||||||
|
|
||||||
|
@ -93,7 +93,6 @@ static void wifi_event_handler(void* arg, esp_event_base_t event_base,
|
|||||||
|
|
||||||
void wifi_init_softap(void)
|
void wifi_init_softap(void)
|
||||||
{
|
{
|
||||||
|
|
||||||
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
|
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
|
||||||
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
|
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
|
||||||
|
|
||||||
|
@ -19,40 +19,28 @@ using namespace esp_modem;
|
|||||||
using namespace esp_modem::dce_factory;
|
using namespace esp_modem::dce_factory;
|
||||||
|
|
||||||
class NetModule;
|
class NetModule;
|
||||||
typedef DCE_T<NetModule> NetDCE;
|
using NetDCE = DCE_T<NetModule>;
|
||||||
|
|
||||||
/**
|
|
||||||
* @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;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief The PPP network is a singleton, allocate statically here
|
* @brief The PPP network is a singleton, allocate statically here
|
||||||
*/
|
*/
|
||||||
static PPPNetwork ppp_network;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Custom factory for creating NetDCE and NetModule
|
* @brief Custom factory for creating NetDCE and NetModule
|
||||||
*/
|
*/
|
||||||
class NetDCE_Factory: public Factory {
|
class NetDCE_Factory: public Factory {
|
||||||
public:
|
public:
|
||||||
template <typename T, typename ...Args>
|
template <typename Module, typename ...Args>
|
||||||
static DCE_T<T>* create(const config *cfg, Args&&... args)
|
static DCE_T<Module>* create(const config *cfg, Args&&... args)
|
||||||
{
|
{
|
||||||
return build_generic_DCE<T>(cfg, std::forward<Args>(args)...);
|
return build_generic_DCE<Module>(cfg, std::forward<Args>(args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename ...Args>
|
template <typename Module, typename ...Args>
|
||||||
static std::shared_ptr<T> create_module(const config *cfg, Args&&... args)
|
static std::shared_ptr<Module> create_module(const config *cfg, Args&&... args)
|
||||||
{
|
{
|
||||||
return build_shared_module<T>(cfg, std::forward<Args>(args)...);
|
return build_shared_module<Module>(cfg, std::forward<Args>(args)...);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -67,7 +55,7 @@ public:
|
|||||||
explicit NetModule(std::shared_ptr<DTE> dte, const esp_modem_dce_config *cfg):
|
explicit NetModule(std::shared_ptr<DTE> dte, const esp_modem_dce_config *cfg):
|
||||||
dte(std::move(dte)), apn(std::string(cfg->apn)) {}
|
dte(std::move(dte)), apn(std::string(cfg->apn)) {}
|
||||||
|
|
||||||
bool setup_data_mode() override
|
[[nodiscard]] bool setup_data_mode() override
|
||||||
{
|
{
|
||||||
PdpContext pdp(apn);
|
PdpContext pdp(apn);
|
||||||
if (set_pdp_context(pdp) != command_result::OK)
|
if (set_pdp_context(pdp) != command_result::OK)
|
||||||
@ -77,18 +65,20 @@ public:
|
|||||||
|
|
||||||
bool set_mode(modem_mode mode) override
|
bool set_mode(modem_mode mode) override
|
||||||
{
|
{
|
||||||
if (mode == modem_mode::DATA_MODE) {
|
switch (mode) {
|
||||||
if (set_data_mode() != command_result::OK)
|
case esp_modem::modem_mode::DATA_MODE:
|
||||||
return resume_data_mode() == command_result::OK;
|
if (set_data_mode() != command_result::OK) {
|
||||||
return true;
|
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)
|
// switch to command mode (in case we were in PPP mode)
|
||||||
static_cast<void>(set_command_mode()); // ignore the potential failure, as we might be in command mode after startup
|
static_cast<void>(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
|
// configure
|
||||||
esp_modem_dte_config_t dte_config = ESP_MODEM_DTE_DEFAULT_CONFIG();
|
esp_modem_dte_config_t dte_config = ESP_MODEM_DTE_DEFAULT_CONFIG();
|
||||||
dte_config.uart_config.rx_buffer_size = 16384;
|
dte_config.uart_config.rx_buffer_size = 16384;
|
||||||
dte_config.uart_config.tx_buffer_size = 2048;
|
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
|
// create DTE and minimal network DCE
|
||||||
auto uart_dte = create_uart_dte(&dte_config);
|
auto uart_dte = create_uart_dte(&dte_config);
|
||||||
|
|
||||||
// create the specific device (and initialize it)
|
// create the specific device (and initialize it)
|
||||||
auto dev = NetDCE_Factory::create_module<NetModule>(&dce_config, uart_dte, netif);
|
auto dev = NetDCE_Factory::create_module<NetModule>(&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;
|
return ESP_FAIL;
|
||||||
|
#endif
|
||||||
// now create the DCE from our already existent device
|
// now create the DCE from our already existent device
|
||||||
dce = NetDCE_Factory::create<NetModule>(&dce_config, uart_dte, netif, dev);
|
dce = NetDCE_Factory::create<NetModule>(&dce_config, uart_dte, netif, dev);
|
||||||
if (dce == nullptr)
|
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;
|
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);
|
free(dce);
|
||||||
dce = nullptr;
|
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();
|
|
||||||
}
|
|
@ -15,7 +15,7 @@
|
|||||||
|
|
||||||
using namespace esp_modem;
|
using namespace esp_modem;
|
||||||
|
|
||||||
[[maybe_unused]] static const char *TAG = "linux_modem_main";
|
[[maybe_unused]] constexpr auto TAG = "linux_modem_main";
|
||||||
|
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
|
@ -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.)
|
(See the README.md file in the upper level 'examples' directory for more information about examples.)
|
||||||
|
|
||||||
|
@ -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<CommandArgs>& args)
|
void ConsoleCommand::RegisterCommand(const char* command, const char* help, const std::vector<CommandArgs>& args)
|
||||||
{
|
{
|
||||||
assert(last_command <= MAX_REPEAT_NR);
|
assert(last_command <= MAX_REPEAT_NR);
|
||||||
void * common_arg = nullptr;
|
arg_type common_arg = { };
|
||||||
for (auto it: args) {
|
for (auto& it: args) {
|
||||||
switch(it.type) {
|
switch(it.type) {
|
||||||
case ARG_END:
|
case ARG_END:
|
||||||
break;
|
break;
|
||||||
case STR0:
|
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;
|
break;
|
||||||
case STR1:
|
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;
|
break;
|
||||||
case INT0:
|
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;
|
break;
|
||||||
case INT1:
|
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;
|
break;
|
||||||
case LIT0:
|
case LIT0:
|
||||||
common_arg = arg_lit0(it.shortopts, it.longopts, it.glossary);
|
common_arg.lit = arg_lit0(it.shortopts, it.longopts, it.glossary);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (common_arg) {
|
if (common_arg.is_null()) {
|
||||||
arg_table.emplace_back(common_arg);
|
arg_table.emplace_back(common_arg);
|
||||||
} else {
|
} else {
|
||||||
ESP_LOGE(TAG, "Creating argument parser failed for %s", it.glossary);
|
ESP_LOGE(TAG, "Creating argument parser failed for %s", it.glossary);
|
||||||
abort();
|
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 = {
|
const esp_console_cmd_t command_def = {
|
||||||
.command = command,
|
.command = command,
|
||||||
.help = help,
|
.help = help,
|
||||||
@ -64,13 +66,13 @@ void ConsoleCommand::RegisterCommand(const char* command, const char* help, cons
|
|||||||
|
|
||||||
int ConsoleCommand::get_count(int index)
|
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)
|
std::string ConsoleCommand::get_string(int index)
|
||||||
{
|
{
|
||||||
if (get_count(index) > 0) {
|
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();
|
return std::string();
|
||||||
}
|
}
|
||||||
@ -78,17 +80,17 @@ std::string ConsoleCommand::get_string(int index)
|
|||||||
int ConsoleCommand::get_int(int index)
|
int ConsoleCommand::get_int(int index)
|
||||||
{
|
{
|
||||||
if (get_count(index) > 0) {
|
if (get_count(index) > 0) {
|
||||||
return *((struct arg_int *)arg_table[index])->ival;
|
return *(arg_table[index].intx)->ival;
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int ConsoleCommand::command_func(int argc, char **argv) {
|
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);
|
int nerrors = arg_parse(argc, argv, (void **)plain_arg_array);
|
||||||
if (nerrors != 0) {
|
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;
|
return 1;
|
||||||
}
|
}
|
||||||
if (func) {
|
if (func) {
|
||||||
|
@ -53,6 +53,19 @@ class StaticCommands;
|
|||||||
* @brief This class simplifies console command definition in more object wise fashion
|
* @brief This class simplifies console command definition in more object wise fashion
|
||||||
*/
|
*/
|
||||||
class ConsoleCommand {
|
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;
|
friend class StaticCommands;
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
@ -91,7 +104,7 @@ private:
|
|||||||
void RegisterCommand(const char* command, const char* help, const std::vector<CommandArgs>& args);
|
void RegisterCommand(const char* command, const char* help, const std::vector<CommandArgs>& args);
|
||||||
template<typename T> static constexpr size_t index_arg(CommandArgs T::*member)
|
template<typename T> static constexpr size_t index_arg(CommandArgs T::*member)
|
||||||
{ return ((uint8_t *)&((T*)nullptr->*member) - (uint8_t *)nullptr)/sizeof(CommandArgs); }
|
{ return ((uint8_t *)&((T*)nullptr->*member) - (uint8_t *)nullptr)/sizeof(CommandArgs); }
|
||||||
std::vector<void*> arg_table;
|
std::vector<arg_type> arg_table;
|
||||||
int command_func(int argc, char **argv);
|
int command_func(int argc, char **argv);
|
||||||
|
|
||||||
static int last_command;
|
static int last_command;
|
||||||
|
@ -157,11 +157,11 @@ extern "C" void app_main(void)
|
|||||||
auto cmd = c->get_string_of(&GenericCommandArgs::cmd);
|
auto cmd = c->get_string_of(&GenericCommandArgs::cmd);
|
||||||
auto timeout = c->get_count_of(&GenericCommandArgs::timeout) ? c->get_int_of(&GenericCommandArgs::timeout)
|
auto timeout = c->get_count_of(&GenericCommandArgs::timeout) ? c->get_int_of(&GenericCommandArgs::timeout)
|
||||||
: 1000;
|
: 1000;
|
||||||
|
ESP_LOGI(TAG, "Sending command %s with timeout %d", cmd.c_str(), timeout);
|
||||||
auto pattern = c->get_string_of(&GenericCommandArgs::pattern);
|
auto pattern = c->get_string_of(&GenericCommandArgs::pattern);
|
||||||
if (c->get_count_of(&GenericCommandArgs::no_cr) == 0) {
|
if (c->get_count_of(&GenericCommandArgs::no_cr) == 0) {
|
||||||
cmd += '\r';
|
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) {
|
CHECK_ERR(dce->command(cmd, [&](uint8_t *data, size_t len) {
|
||||||
std::string response((char *) data, len);
|
std::string response((char *) data, len);
|
||||||
ESP_LOGI(TAG, "%s", response.c_str());
|
ESP_LOGI(TAG, "%s", response.c_str());
|
||||||
|
@ -51,7 +51,7 @@ class CMuxInstance;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief CMux class which consumes the original terminal and creates multiple virtual terminals from it.
|
* @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 {
|
class CMux {
|
||||||
public:
|
public:
|
||||||
@ -100,7 +100,7 @@ public:
|
|||||||
void stop() override { }
|
void stop() override { }
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<CMux> cmux;
|
std::shared_ptr<CMux> cmux;
|
||||||
int instance;
|
size_t instance;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -88,7 +88,7 @@ protected:
|
|||||||
* @brief Common abstraction of the modem DCE, specialized by the GenericModule which is a parent class for the supported
|
* @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.
|
* defices and most common modems, as well.
|
||||||
*/
|
*/
|
||||||
class DCE: public DCE_T<GenericModule> {
|
class DCE : public DCE_T<GenericModule> {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
using DCE_T<GenericModule>::DCE_T;
|
using DCE_T<GenericModule>::DCE_T;
|
||||||
|
@ -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 {
|
class Terminal {
|
||||||
public:
|
public:
|
||||||
@ -53,7 +53,7 @@ public:
|
|||||||
|
|
||||||
void set_error_cb(std::function<void(terminal_error)> f) { on_error = std::move(f); }
|
void set_error_cb(std::function<void(terminal_error)> f) { on_error = std::move(f); }
|
||||||
|
|
||||||
virtual void set_read_cb(std::function<bool(uint8_t *data, size_t len)> f) { on_data = std::move(f); }
|
virtual void set_read_cb(std::function<bool(uint8_t *data, size_t len)> f) { on_read = std::move(f); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Writes data to the terminal
|
* @brief Writes data to the terminal
|
||||||
@ -76,7 +76,7 @@ public:
|
|||||||
virtual void stop() = 0;
|
virtual void stop() = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::function<bool(uint8_t *data, size_t len)> on_data;
|
std::function<bool(uint8_t *data, size_t len)> on_read;
|
||||||
std::function<void(terminal_error)> on_error;
|
std::function<void(terminal_error)> on_error;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -17,6 +17,10 @@
|
|||||||
#include "driver/uart.h"
|
#include "driver/uart.h"
|
||||||
#include "esp_modem_dce_config.h"
|
#include "esp_modem_dce_config.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @defgroup ESP_MODEM_CONFIG
|
* @defgroup ESP_MODEM_CONFIG
|
||||||
* @brief Configuration structures for DTE and DCE
|
* @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 */
|
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
|
* @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_
|
#endif // _ESP_MODEM_CONFIG_H_
|
||||||
|
@ -15,6 +15,10 @@
|
|||||||
#ifndef _ESP_MODEM_DCE_CONFIG_H_
|
#ifndef _ESP_MODEM_DCE_CONFIG_H_
|
||||||
#define _ESP_MODEM_DCE_CONFIG_H_
|
#define _ESP_MODEM_DCE_CONFIG_H_
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
/** @addtogroup ESP_MODEM_CONFIG
|
/** @addtogroup ESP_MODEM_CONFIG
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
@ -41,5 +45,8 @@ struct esp_modem_dce_config {
|
|||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif // _ESP_MODEM_DCE_CONFIG_H_
|
#endif // _ESP_MODEM_DCE_CONFIG_H_
|
||||||
|
@ -213,7 +213,7 @@ ESP_MODEM_DECLARE_DCE_COMMAND(set_baud, command_result, 1, INT_IN(x, baud))
|
|||||||
#define _ARG(param, name) name
|
#define _ARG(param, name) name
|
||||||
// --- DCE command documentation starts here ---
|
// --- DCE command documentation starts here ---
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
class esp_modem::DCE: public DCE_T<GenericModule> {
|
class esp_modem::DCE : public DCE_T<GenericModule> {
|
||||||
public:
|
public:
|
||||||
using DCE_T<GenericModule>::DCE_T;
|
using DCE_T<GenericModule>::DCE_T;
|
||||||
#define ESP_MODEM_DECLARE_DCE_COMMAND(name, return_type, TEMPLATE_ARG, ...) return_type name (__VA_ARGS__);
|
#define ESP_MODEM_DECLARE_DCE_COMMAND(name, return_type, TEMPLATE_ARG, ...) return_type name (__VA_ARGS__);
|
||||||
|
@ -58,7 +58,7 @@ public:
|
|||||||
int read(uint8_t *data, size_t len) override;
|
int read(uint8_t *data, size_t len) override;
|
||||||
|
|
||||||
void set_read_cb(std::function<bool(uint8_t *data, size_t len)> f) override {
|
void set_read_cb(std::function<bool(uint8_t *data, size_t len)> f) override {
|
||||||
on_data = std::move(f);
|
on_read = std::move(f);
|
||||||
signal.set(TASK_PARAMS);
|
signal.set(TASK_PARAMS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,7 +94,7 @@ FdTerminal::FdTerminal(const esp_modem_dte_config *config) :
|
|||||||
|
|
||||||
void FdTerminal::task()
|
void FdTerminal::task()
|
||||||
{
|
{
|
||||||
std::function<bool(uint8_t *data, size_t len)> on_data_priv = nullptr;
|
std::function<bool(uint8_t *data, size_t len)> on_read_priv = nullptr;
|
||||||
signal.set(TASK_INIT);
|
signal.set(TASK_INIT);
|
||||||
signal.wait_any(TASK_START | TASK_STOP, portMAX_DELAY);
|
signal.wait_any(TASK_START | TASK_STOP, portMAX_DELAY);
|
||||||
if (signal.is_any(TASK_STOP)) {
|
if (signal.is_any(TASK_STOP)) {
|
||||||
@ -113,7 +113,7 @@ void FdTerminal::task()
|
|||||||
|
|
||||||
s = select(f.fd + 1, &rfds, nullptr, nullptr, &tv);
|
s = select(f.fd + 1, &rfds, nullptr, nullptr, &tv);
|
||||||
if (signal.is_any(TASK_PARAMS)) {
|
if (signal.is_any(TASK_PARAMS)) {
|
||||||
on_data_priv = on_data;
|
on_read_priv = on_read;
|
||||||
signal.clear(TASK_PARAMS);
|
signal.clear(TASK_PARAMS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -123,9 +123,9 @@ void FdTerminal::task()
|
|||||||
// ESP_LOGV(TAG, "Select exited with timeout");
|
// ESP_LOGV(TAG, "Select exited with timeout");
|
||||||
} else {
|
} else {
|
||||||
if (FD_ISSET(f.fd, &rfds)) {
|
if (FD_ISSET(f.fd, &rfds)) {
|
||||||
if (on_data_priv) {
|
if (on_read_priv) {
|
||||||
if (on_data_priv(nullptr, 0)) {
|
if (on_read_priv(nullptr, 0)) {
|
||||||
on_data_priv = nullptr;
|
on_read_priv = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -65,7 +65,7 @@ public:
|
|||||||
int read(uint8_t *data, size_t len) override;
|
int read(uint8_t *data, size_t len) override;
|
||||||
|
|
||||||
void set_read_cb(std::function<bool(uint8_t *data, size_t len)> f) override {
|
void set_read_cb(std::function<bool(uint8_t *data, size_t len)> f) override {
|
||||||
on_data = std::move(f);
|
on_read = std::move(f);
|
||||||
signal.set(TASK_PARAMS);
|
signal.set(TASK_PARAMS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,7 +106,7 @@ std::unique_ptr<Terminal> create_uart_terminal(const esp_modem_dte_config *confi
|
|||||||
}
|
}
|
||||||
|
|
||||||
void UartTerminal::task() {
|
void UartTerminal::task() {
|
||||||
std::function<bool(uint8_t *data, size_t len)> on_data_priv = nullptr;
|
std::function<bool(uint8_t *data, size_t len)> on_read_priv = nullptr;
|
||||||
uart_event_t event;
|
uart_event_t event;
|
||||||
size_t len;
|
size_t len;
|
||||||
signal.set(TASK_INIT);
|
signal.set(TASK_INIT);
|
||||||
@ -117,15 +117,15 @@ void UartTerminal::task() {
|
|||||||
while (signal.is_any(TASK_START)) {
|
while (signal.is_any(TASK_START)) {
|
||||||
if (get_event(event, 100)) {
|
if (get_event(event, 100)) {
|
||||||
if (signal.is_any(TASK_PARAMS)) {
|
if (signal.is_any(TASK_PARAMS)) {
|
||||||
on_data_priv = on_data;
|
on_read_priv = on_read;
|
||||||
signal.clear(TASK_PARAMS);
|
signal.clear(TASK_PARAMS);
|
||||||
}
|
}
|
||||||
switch (event.type) {
|
switch (event.type) {
|
||||||
case UART_DATA:
|
case UART_DATA:
|
||||||
uart_get_buffered_data_len(uart.port, &len);
|
uart_get_buffered_data_len(uart.port, &len);
|
||||||
if (len && on_data_priv) {
|
if (len && on_read_priv) {
|
||||||
if (on_data_priv(nullptr, len)) {
|
if (on_read_priv(nullptr, len)) {
|
||||||
on_data_priv = nullptr;
|
on_read_priv = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
Reference in New Issue
Block a user