mirror of
https://github.com/espressif/esp-protocols.git
synced 2025-07-17 20:42:21 +02:00
CMUX: Fix batch write, add recovery
This commit is contained in:
@ -2,6 +2,9 @@
|
|||||||
- :cpp:func:`esp_modem::DCE::set_pin`
|
- :cpp:func:`esp_modem::DCE::set_pin`
|
||||||
- :cpp:func:`esp_modem::DCE::read_pin`
|
- :cpp:func:`esp_modem::DCE::read_pin`
|
||||||
- :cpp:func:`esp_modem::DCE::set_echo`
|
- :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::resume_data_mode`
|
||||||
- :cpp:func:`esp_modem::DCE::set_pdp_context`
|
- :cpp:func:`esp_modem::DCE::set_pdp_context`
|
||||||
- :cpp:func:`esp_modem::DCE::set_command_mode`
|
- :cpp:func:`esp_modem::DCE::set_command_mode`
|
||||||
|
@ -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 -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
|
// 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 ---
|
// --- DCE command documentation starts here ---
|
||||||
/**
|
/**
|
||||||
* @brief Sends the supplied PIN code
|
* @brief Sets the supplied PIN code
|
||||||
*
|
* @param[in] pin Pin
|
||||||
* @param pin Pin
|
* @return OK, FAIL or TIMEOUT
|
||||||
*
|
*/command_result esp_modem_set_pin (const char* pin); /**
|
||||||
*/ command_result esp_modem_set_pin (const char* pin); /**
|
|
||||||
* @brief Checks if the SIM needs a 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
|
||||||
* @param[out] pin_ok Pin
|
* @return OK, FAIL or TIMEOUT
|
||||||
*/ command_result esp_modem_read_pin (bool* pin_ok); /**
|
*/ command_result esp_modem_read_pin (bool* pin_ok); /**
|
||||||
* @brief Reads the module name
|
* @brief Sets echo mode
|
||||||
*
|
* @param[in] echo_on true if echo mode on (repeats the commands)
|
||||||
* @param[out] name module name
|
* @return OK, FAIL or TIMEOUT
|
||||||
*/ command_result esp_modem_set_echo (const bool x); /**
|
*/ command_result esp_modem_set_echo (const bool echo_on); /**
|
||||||
* @brief Reads the module name
|
* @brief Sets the Txt or Pdu mode for SMS (only txt is supported)
|
||||||
*
|
* @param[in] txt true if txt mode
|
||||||
* @param[out] name module name
|
* @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 (); /**
|
*/ command_result esp_modem_resume_data_mode (); /**
|
||||||
* @brief Reads the module name
|
* @brief Sets php context
|
||||||
*
|
* @param[in] x PdP context struct to setup modem cellular connection
|
||||||
* @param[out] name module name
|
* @return OK, FAIL or TIMEOUT
|
||||||
*/ command_result esp_modem_set_pdp_context (struct PdpContext* x); /**
|
*/ command_result esp_modem_set_pdp_context (struct PdpContext* x); /**
|
||||||
* @brief Reads the module name
|
* @brief Switches to the command mode
|
||||||
*
|
* @return OK, FAIL or TIMEOUT
|
||||||
* @param[out] name module name
|
|
||||||
*/ command_result esp_modem_set_command_mode (); /**
|
*/ command_result esp_modem_set_command_mode (); /**
|
||||||
* @brief Reads the module name
|
* @brief Switches to the CMUX mode
|
||||||
*
|
* @return OK, FAIL or TIMEOUT
|
||||||
* @param[out] name module name
|
|
||||||
*/ command_result esp_modem_set_cmux (); /**
|
*/ 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
|
* @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
|
* @param[out] name module name
|
||||||
|
* @return OK, FAIL or TIMEOUT
|
||||||
*/ command_result esp_modem_get_module_name (char* name); /**
|
*/ command_result esp_modem_get_module_name (char* name); /**
|
||||||
* @brief Sets the modem to data mode
|
* @brief Sets the modem to data mode
|
||||||
*
|
* @return OK, FAIL or TIMEOUT
|
||||||
*/ command_result esp_modem_set_data_mode (); /**
|
*/ command_result esp_modem_set_data_mode (); /**
|
||||||
* @brief Get Signal quality
|
* @brief Get Signal quality
|
||||||
*
|
* @param[out] rssi signal strength indication
|
||||||
*/ command_result esp_modem_get_signal_quality (int* x, int* y);
|
* @param[out] ber channel bit error rate
|
||||||
|
* @return OK, FAIL or TIMEOUT
|
||||||
|
*/ command_result esp_modem_get_signal_quality (int* rssi, int* ber);
|
||||||
|
@ -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 -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
|
// 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 ---
|
// --- DCE command documentation starts here ---
|
||||||
|
|
||||||
class esp_modem::DCE: public DCE_T<GenericModule> {
|
class esp_modem::DCE: public DCE_T<GenericModule> {
|
||||||
@ -13,51 +17,61 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Sends the supplied PIN code
|
* @brief Sets the supplied PIN code
|
||||||
*
|
* @param[in] pin Pin
|
||||||
* @param pin Pin
|
* @return OK, FAIL or TIMEOUT
|
||||||
*
|
*/command_result set_pin (const std::string& pin); /**
|
||||||
*/ command_result set_pin (const std::string& pin); /**
|
|
||||||
* @brief Checks if the SIM needs a 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
|
||||||
* @param[out] pin_ok Pin
|
* @return OK, FAIL or TIMEOUT
|
||||||
*/ command_result read_pin (bool& pin_ok); /**
|
*/ command_result read_pin (bool& pin_ok); /**
|
||||||
* @brief Reads the module name
|
* @brief Sets echo mode
|
||||||
*
|
* @param[in] echo_on true if echo mode on (repeats the commands)
|
||||||
* @param[out] name module name
|
* @return OK, FAIL or TIMEOUT
|
||||||
*/ command_result set_echo (const bool x); /**
|
*/ command_result set_echo (const bool echo_on); /**
|
||||||
* @brief Reads the module name
|
* @brief Sets the Txt or Pdu mode for SMS (only txt is supported)
|
||||||
*
|
* @param[in] txt true if txt mode
|
||||||
* @param[out] name module name
|
* @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 (); /**
|
*/ command_result resume_data_mode (); /**
|
||||||
* @brief Reads the module name
|
* @brief Sets php context
|
||||||
*
|
* @param[in] x PdP context struct to setup modem cellular connection
|
||||||
* @param[out] name module name
|
* @return OK, FAIL or TIMEOUT
|
||||||
*/ command_result set_pdp_context (PdpContext& x); /**
|
*/ command_result set_pdp_context (PdpContext& x); /**
|
||||||
* @brief Reads the module name
|
* @brief Switches to the command mode
|
||||||
*
|
* @return OK, FAIL or TIMEOUT
|
||||||
* @param[out] name module name
|
|
||||||
*/ command_result set_command_mode (); /**
|
*/ command_result set_command_mode (); /**
|
||||||
* @brief Reads the module name
|
* @brief Switches to the CMUX mode
|
||||||
*
|
* @return OK, FAIL or TIMEOUT
|
||||||
* @param[out] name module name
|
|
||||||
*/ command_result set_cmux (); /**
|
*/ 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
|
* @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
|
* @param[out] name module name
|
||||||
|
* @return OK, FAIL or TIMEOUT
|
||||||
*/ command_result get_module_name (std::string& name); /**
|
*/ command_result get_module_name (std::string& name); /**
|
||||||
* @brief Sets the modem to data mode
|
* @brief Sets the modem to data mode
|
||||||
*
|
* @return OK, FAIL or TIMEOUT
|
||||||
*/ command_result set_data_mode (); /**
|
*/ command_result set_data_mode (); /**
|
||||||
* @brief Get Signal quality
|
* @brief Get Signal quality
|
||||||
*
|
* @param[out] rssi signal strength indication
|
||||||
*/ command_result get_signal_quality (int& x, int& y);
|
* @param[out] ber channel bit error rate
|
||||||
|
* @return OK, FAIL or TIMEOUT
|
||||||
|
*/ command_result get_signal_quality (int& rssi, int& ber);
|
||||||
};
|
};
|
||||||
|
@ -24,7 +24,7 @@ using namespace esp_modem;
|
|||||||
|
|
||||||
static const char *TAG = "cmux_example";
|
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 CONNECT_BIT = BIT0;
|
||||||
static const int STOP_BIT = BIT1;
|
static const int STOP_BIT = BIT1;
|
||||||
static const int GOT_DATA_BIT = BIT2;
|
static const int GOT_DATA_BIT = BIT2;
|
||||||
@ -141,6 +141,17 @@ extern "C" void app_main(void)
|
|||||||
assert(esp_netif);
|
assert(esp_netif);
|
||||||
|
|
||||||
auto dce = create_SIM7600_dce(&dce_config, uart_dte, 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();
|
dce->set_command_mode();
|
||||||
|
|
||||||
std::string str;
|
std::string str;
|
||||||
@ -163,7 +174,7 @@ extern "C" void app_main(void)
|
|||||||
esp_mqtt_client_config_t mqtt_config = { };
|
esp_mqtt_client_config_t mqtt_config = { };
|
||||||
mqtt_config.uri = BROKER_URL;
|
mqtt_config.uri = BROKER_URL;
|
||||||
esp_mqtt_client_handle_t mqtt_client = esp_mqtt_client_init(&mqtt_config);
|
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);
|
esp_mqtt_client_start(mqtt_client);
|
||||||
|
|
||||||
EventBits_t got_data = 0;
|
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));
|
got_data = xEventGroupWaitBits(event_group, GOT_DATA_BIT, pdTRUE, pdTRUE, pdMS_TO_TICKS(500));
|
||||||
}
|
}
|
||||||
esp_mqtt_client_destroy(mqtt_client);
|
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
|
ESP_LOGI(TAG, "Example finished");
|
||||||
dce->get_imsi(str);
|
|
||||||
std::cout << "Modem IMSI number:" << str << "|" << std::endl;
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ namespace dce_commands {
|
|||||||
/**
|
/**
|
||||||
* @brief Declaration of all commands is generated from esp_modem_command_declare.inc
|
* @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__);
|
return_type name(CommandableIf *t, ## __VA_ARGS__);
|
||||||
|
|
||||||
DECLARE_ALL_COMMAND_APIS(declare name(Commandable *p, ...);)
|
DECLARE_ALL_COMMAND_APIS(declare name(Commandable *p, ...);)
|
||||||
|
@ -95,7 +95,7 @@ class 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, MUX_ARG, ...) \
|
#define ESP_MODEM_DECLARE_DCE_COMMAND(name, return_type, num, ...) \
|
||||||
template <typename ...Agrs> \
|
template <typename ...Agrs> \
|
||||||
return_type name(Agrs&&... args) \
|
return_type name(Agrs&&... args) \
|
||||||
{ \
|
{ \
|
||||||
|
@ -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__);
|
virtual return_type name(__VA_ARGS__);
|
||||||
|
|
||||||
DECLARE_ALL_COMMAND_APIS(virtual return_type name(...); )
|
DECLARE_ALL_COMMAND_APIS(virtual return_type name(...); )
|
||||||
|
@ -23,7 +23,7 @@ extern "C" {
|
|||||||
#endif
|
#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__);
|
esp_err_t esp_modem_ ## name(esp_modem_dce_t *dce, ##__VA_ARGS__);
|
||||||
|
|
||||||
DECLARE_ALL_COMMAND_APIS(declares esp_modem_<API>(esp_modem_t * dce, ...);)
|
DECLARE_ALL_COMMAND_APIS(declares esp_modem_<API>(esp_modem_t * dce, ...);)
|
||||||
|
@ -15,12 +15,11 @@
|
|||||||
#ifndef _ESP_MODEM_COMMAND_DECLARE_INC_
|
#ifndef _ESP_MODEM_COMMAND_DECLARE_INC_
|
||||||
#define _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
|
#ifdef __cplusplus
|
||||||
#include <string>
|
#include <string>
|
||||||
#define STRING_IN(param, name) const std::string& _ARG(param, name)
|
#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
|
#define STRUCT_OUT(struct_name, x) struct struct_name* x
|
||||||
#endif
|
#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(...) \
|
#define DECLARE_ALL_COMMAND_APIS(...) \
|
||||||
/**
|
/**
|
||||||
* @brief Sends the supplied PIN code
|
* @brief Sets the supplied PIN code
|
||||||
*
|
* @param[in] pin Pin
|
||||||
* @param pin Pin
|
* @return OK, FAIL or TIMEOUT
|
||||||
*
|
*/\
|
||||||
*/ \
|
ESP_MODEM_DECLARE_DCE_COMMAND(set_pin, command_result, 1, STRING_IN(x, pin)) \
|
||||||
\
|
|
||||||
ESP_MODEM_DECLARE_DCE_COMMAND(set_pin, command_result, 1, MUX_ARG, STRING_IN(x, pin)) \
|
|
||||||
\
|
|
||||||
\
|
\
|
||||||
/**
|
/**
|
||||||
* @brief Checks if the SIM needs a 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
|
||||||
* @param[out] pin_ok Pin
|
* @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
|
* @brief Reads the module name
|
||||||
*
|
|
||||||
* @param[out] name 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(get_module_name, command_result, 1, STRING_OUT(x, name)) \
|
||||||
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)) \
|
|
||||||
\
|
\
|
||||||
/**
|
/**
|
||||||
* @brief Sets the modem to data mode
|
* @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
|
* @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
|
#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'
|
||||||
// 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 -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
|
// 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 ---
|
// --- 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, 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)
|
#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
|
#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
|
#endif
|
||||||
|
|
||||||
DECLARE_ALL_COMMAND_APIS()
|
DECLARE_ALL_COMMAND_APIS()
|
||||||
|
@ -18,10 +18,8 @@
|
|||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
#include "cxx_include/esp_modem_api.hpp"
|
#include "cxx_include/esp_modem_api.hpp"
|
||||||
#include "cxx_include/esp_modem_dce_factory.hpp"
|
#include "cxx_include/esp_modem_dce_factory.hpp"
|
||||||
#include "esp_modem_c_api_types.h"
|
|
||||||
#include "esp_modem_config.h"
|
#include "esp_modem_config.h"
|
||||||
#include "exception_stub.hpp"
|
#include "exception_stub.hpp"
|
||||||
#include "cstring"
|
|
||||||
|
|
||||||
namespace esp_modem {
|
namespace esp_modem {
|
||||||
|
|
||||||
|
@ -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);
|
ESP_LOG_BUFFER_HEXDUMP("Received", data, actual_len, ESP_LOG_DEBUG);
|
||||||
uint8_t* frame = data;
|
uint8_t* frame = data;
|
||||||
|
uint8_t* recover_ptr;
|
||||||
auto available_len = actual_len;
|
auto available_len = actual_len;
|
||||||
size_t payload_offset = 0;
|
size_t payload_offset = 0;
|
||||||
size_t footer_offset = 0;
|
size_t footer_offset = 0;
|
||||||
while (available_len > 0) {
|
while (available_len > 0) {
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case cmux_state::RECOVER:
|
case cmux_state::RECOVER:
|
||||||
// TODO: Implement recovery, looking for SOF_MARKER's
|
if (frame[0] == SOF_MARKER) {
|
||||||
break;
|
// already init state
|
||||||
|
state = cmux_state::INIT;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
recover_ptr = static_cast<uint8_t*>(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:
|
case cmux_state::INIT:
|
||||||
if (frame[0] != SOF_MARKER) {
|
if (frame[0] != SOF_MARKER) {
|
||||||
ESP_LOGW("CMUX", "TODO: Recover!");
|
ESP_LOGI("CMUX", "Protocol mismatch!");
|
||||||
return true;
|
state = cmux_state::RECOVER;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if (available_len > 1 && frame[1] == SOF_MARKER) {
|
if (available_len > 1 && frame[1] == SOF_MARKER) {
|
||||||
ESP_LOGI("CMUX", "Empty frame");
|
|
||||||
// empty frame
|
// empty frame
|
||||||
available_len -= 2;
|
available_len -= 1;
|
||||||
frame += 2;
|
frame += 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
state = cmux_state::HEADER;
|
state = cmux_state::HEADER;
|
||||||
@ -140,7 +159,7 @@ bool CMux::on_cmux(uint8_t *data, size_t actual_len)
|
|||||||
dlci = frame_header[1] >> 2;
|
dlci = frame_header[1] >> 2;
|
||||||
type = frame_header[2];
|
type = frame_header[2];
|
||||||
payload_len = (frame_header[3] >> 1);
|
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;
|
frame += payload_offset;
|
||||||
available_len -= payload_offset;
|
available_len -= payload_offset;
|
||||||
state = cmux_state::PAYLOAD;
|
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);
|
footer_offset = std::min(available_len, 6 - frame_header_offset);
|
||||||
memcpy(frame_header + frame_header_offset, frame, footer_offset);
|
memcpy(frame_header + frame_header_offset, frame, footer_offset);
|
||||||
if (frame_header[5] != SOF_MARKER) {
|
if (frame_header[5] != SOF_MARKER) {
|
||||||
ESP_LOGW("CMUX", "TODO: Recover!");
|
ESP_LOGI("CMUX", "Protocol mismatch!");
|
||||||
return true;
|
state = cmux_state::RECOVER;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if (payload_len == 0) {
|
if (payload_len == 0) {
|
||||||
data_available(frame_header, 0); // Null payload
|
data_available(frame_header, 0); // Null payload
|
||||||
@ -190,6 +210,7 @@ void CMux::init()
|
|||||||
frame_header_offset = 0;
|
frame_header_offset = 0;
|
||||||
state = cmux_state::INIT;
|
state = cmux_state::INIT;
|
||||||
term->set_read_cb([this](uint8_t *data, size_t len) {
|
term->set_read_cb([this](uint8_t *data, size_t len) {
|
||||||
|
Scoped<Lock> l(lock);
|
||||||
this->on_cmux(data, len);
|
this->on_cmux(data, len);
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
@ -203,22 +224,31 @@ void CMux::init()
|
|||||||
|
|
||||||
int CMux::write(int virtual_term, uint8_t *data, size_t len)
|
int CMux::write(int virtual_term, uint8_t *data, size_t len)
|
||||||
{
|
{
|
||||||
|
const size_t cmux_max_len = 127;
|
||||||
Scoped<Lock> l(lock);
|
Scoped<Lock> l(lock);
|
||||||
int i = virtual_term + 1;
|
int i = virtual_term + 1;
|
||||||
uint8_t frame[6];
|
size_t need_write = len;
|
||||||
frame[0] = SOF_MARKER;
|
while (need_write > 0) {
|
||||||
frame[1] = (i << 2) + 1;
|
size_t batch_len = need_write;
|
||||||
frame[2] = FT_UIH;
|
if (batch_len > cmux_max_len)
|
||||||
frame[3] = (len << 1) + 1;
|
batch_len = cmux_max_len;
|
||||||
frame[4] = 0xFF - fcs_crc(frame);
|
uint8_t frame[6];
|
||||||
frame[5] = SOF_MARKER;
|
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(frame, 4);
|
||||||
term->write(data, len);
|
term->write(data, batch_len);
|
||||||
term->write(frame + 4, 2);
|
term->write(frame + 4, 2);
|
||||||
ESP_LOG_BUFFER_HEXDUMP("Send", frame, 4, ESP_LOG_VERBOSE);
|
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", data, batch_len, ESP_LOG_VERBOSE);
|
||||||
ESP_LOG_BUFFER_HEXDUMP("Send", frame+4, 2, ESP_LOG_VERBOSE);
|
ESP_LOG_BUFFER_HEXDUMP("Send", frame+4, 2, ESP_LOG_VERBOSE);
|
||||||
|
need_write -= batch_len;
|
||||||
|
data += batch_len;
|
||||||
|
}
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ GenericModule::GenericModule(std::shared_ptr<DTE> dte, const dce_config *config)
|
|||||||
#define _ARGS(x) ARGS ## x
|
#define _ARGS(x) ARGS ## x
|
||||||
#define ARGS(x) _ARGS(x)
|
#define ARGS(x) _ARGS(x)
|
||||||
#define TEMPLATE_ARG
|
#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) ); }
|
return_type GenericModule::name(__VA_ARGS__) { return esp_modem::dce_commands::name(dte.get() ARGS(arg_nr) ); }
|
||||||
|
|
||||||
DECLARE_ALL_COMMAND_APIS(return_type name(...) {
|
DECLARE_ALL_COMMAND_APIS(return_type name(...) {
|
||||||
|
@ -95,6 +95,11 @@ void Netif::stop() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Netif::~Netif() {
|
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(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_GOT_IP, esp_netif_action_connected);
|
||||||
esp_event_handler_unregister(IP_EVENT, IP_EVENT_PPP_LOST_IP, esp_netif_action_disconnected);
|
esp_event_handler_unregister(IP_EVENT, IP_EVENT_PPP_LOST_IP, esp_netif_action_disconnected);
|
||||||
|
Reference in New Issue
Block a user