Applied astyle code formatting

This commit is contained in:
David Cermak
2021-06-01 10:21:51 +02:00
parent dc64f862c4
commit a61e9e2d40
43 changed files with 865 additions and 662 deletions

View File

@ -58,8 +58,9 @@ public:
[[nodiscard]] 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) {
return false; return false;
}
return true; return true;
} }
@ -83,15 +84,18 @@ public:
// 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
bool is_pin_ok; bool is_pin_ok;
if (read_pin(is_pin_ok) != command_result::OK) if (read_pin(is_pin_ok) != command_result::OK) {
return false; return false;
}
if (!is_pin_ok) { if (!is_pin_ok) {
if (set_pin(pin) != command_result::OK) if (set_pin(pin) != command_result::OK) {
return false; return false;
}
vTaskDelay(pdMS_TO_TICKS(1000)); vTaskDelay(pdMS_TO_TICKS(1000));
if (read_pin(is_pin_ok) != command_result::OK || !is_pin_ok) if (read_pin(is_pin_ok) != command_result::OK || !is_pin_ok) {
return false; return false;
} }
}
return true; return true;
} }
@ -99,12 +103,30 @@ private:
std::shared_ptr<DTE> dte; std::shared_ptr<DTE> dte;
std::string apn; std::string apn;
[[nodiscard]] command_result set_pdp_context(PdpContext& pdp) { return dce_commands::set_pdp_context(dte.get(),pdp); } [[nodiscard]] command_result set_pdp_context(PdpContext &pdp)
[[nodiscard]] command_result set_pin(const std::string &pin) { return dce_commands::set_pin(dte.get(), pin); } {
[[nodiscard]] command_result read_pin(bool& pin_ok) { return dce_commands::read_pin(dte.get(), pin_ok); } return dce_commands::set_pdp_context(dte.get(), pdp);
[[nodiscard]] command_result set_data_mode() { return dce_commands::set_data_mode(dte.get()); } }
[[nodiscard]] command_result resume_data_mode() { return dce_commands::resume_data_mode(dte.get()); } [[nodiscard]] command_result set_pin(const std::string &pin)
[[nodiscard]] command_result set_command_mode() { return dce_commands::set_command_mode(dte.get()); } {
return dce_commands::set_pin(dte.get(), pin);
}
[[nodiscard]] command_result read_pin(bool &pin_ok)
{
return dce_commands::read_pin(dte.get(), pin_ok);
}
[[nodiscard]] command_result set_data_mode()
{
return dce_commands::set_data_mode(dte.get());
}
[[nodiscard]] command_result resume_data_mode()
{
return dce_commands::resume_data_mode(dte.get());
}
[[nodiscard]] command_result set_command_mode()
{
return dce_commands::set_command_mode(dte.get());
}
}; };
@ -132,13 +154,15 @@ extern "C" esp_err_t modem_init_network(esp_netif_t *netif)
// 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 CONFIG_EXAMPLE_NEED_SIM_PIN == 1 #if CONFIG_EXAMPLE_NEED_SIM_PIN == 1
if (!dev->init_sim(CONFIG_EXAMPLE_SIM_PIN)) if (!dev->init_sim(CONFIG_EXAMPLE_SIM_PIN)) {
return ESP_FAIL; return ESP_FAIL;
}
#endif #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) {
return ESP_FAIL; return ESP_FAIL;
}
return ESP_OK; return ESP_OK;
} }

View File

@ -70,8 +70,9 @@ int main()
ESP_LOGI(TAG, "Modem IMSI number: %s", str.c_str()); ESP_LOGI(TAG, "Modem IMSI number: %s", str.c_str());
dce->get_imei(str); dce->get_imei(str);
ESP_LOGI(TAG, "Modem IMEI number: %s", str.c_str()); ESP_LOGI(TAG, "Modem IMEI number: %s", str.c_str());
while (command_result::OK != dce->get_operator_name(str)) while (command_result::OK != dce->get_operator_name(str)) {
{ printf(".\n"); } printf(".\n");
}
ESP_LOGI(TAG, "Operator name: %s", str.c_str()); ESP_LOGI(TAG, "Operator name: %s", str.c_str());
dce->set_mode(esp_modem::modem_mode::DATA_MODE); dce->set_mode(esp_modem::modem_mode::DATA_MODE);

View File

@ -86,7 +86,8 @@ int ConsoleCommand::get_int(int index)
} }
int ConsoleCommand::command_func(int argc, char **argv) { int ConsoleCommand::command_func(int argc, char **argv)
{
arg_type *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) {

View File

@ -62,7 +62,9 @@ class ConsoleCommand {
struct arg_lit *lit; struct arg_lit *lit;
struct arg_end *end; struct arg_end *end;
void *__raw_ptr; void *__raw_ptr;
bool is_null() const { return __raw_ptr; } bool is_null() const {
return __raw_ptr;
}
}; };
friend class StaticCommands; friend class StaticCommands;
@ -92,9 +94,18 @@ public:
/** /**
* @brief Utility getters of various params from the argument list * @brief Utility getters of various params from the argument list
*/ */
template<typename T> int get_count_of(CommandArgs T::*member) { return get_count(index_arg(member)); } template<typename T> int get_count_of(CommandArgs T::*member)
template<typename T> std::string get_string_of(CommandArgs T::*member) { return get_string(index_arg(member)); } {
template<typename T> int get_int_of(CommandArgs T::*member) { return get_int(index_arg(member)); } return get_count(index_arg(member));
}
template<typename T> std::string get_string_of(CommandArgs T::*member)
{
return get_string(index_arg(member));
}
template<typename T> int get_int_of(CommandArgs T::*member)
{
return get_int(index_arg(member));
}
std::string get_string(int index); std::string get_string(int index);
int get_int(int index); int get_int(int index);
@ -102,7 +113,9 @@ private:
int get_count(int index); int get_count(int index);
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<arg_type> arg_table; std::vector<arg_type> arg_table;
int command_func(int argc, char **argv); int command_func(int argc, char **argv);

View File

@ -165,10 +165,12 @@ extern "C" void app_main(void)
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());
if (pattern.empty() || response.find(pattern) != std::string::npos) if (pattern.empty() || response.find(pattern) != std::string::npos) {
return command_result::OK; return command_result::OK;
if (response.find(pattern) != std::string::npos) }
if (response.find(pattern) != std::string::npos) {
return command_result::OK; return command_result::OK;
}
return command_result::TIMEOUT; return command_result::TIMEOUT;
}, timeout),); }, timeout),);
}); });

View File

@ -22,8 +22,7 @@ ESP_EVENT_DECLARE_BASE(MQTT_EVENTS);
/** /**
* Thin wrapper around C mqtt_client * Thin wrapper around C mqtt_client
*/ */
struct MqttClientHandle struct MqttClientHandle {
{
explicit MqttClientHandle(const std::string &uri) explicit MqttClientHandle(const std::string &uri)
{ {
esp_mqtt_client_config_t config = { }; esp_mqtt_client_config_t config = { };

View File

@ -92,9 +92,18 @@ class CMuxInstance: public Terminal {
public: public:
explicit CMuxInstance(std::shared_ptr<CMux> parent, int i): cmux(std::move(parent)), instance(i) {} explicit CMuxInstance(std::shared_ptr<CMux> parent, int i): cmux(std::move(parent)), instance(i) {}
int write(uint8_t *data, size_t len) override { return cmux->write(instance, data, len); } int write(uint8_t *data, size_t len) override
void set_read_cb(std::function<bool(uint8_t *data, size_t len)> f) override { return cmux->set_read_cb(instance, std::move(f)); } {
int read(uint8_t *data, size_t len) override { return 0; } return cmux->write(instance, data, len);
}
void set_read_cb(std::function<bool(uint8_t *data, size_t len)> f) override
{
return cmux->set_read_cb(instance, std::move(f));
}
int read(uint8_t *data, size_t len) override
{
return 0;
}
void start() override { } void start() override { }
void stop() override { } void stop() override { }
private: private:

View File

@ -61,20 +61,35 @@ public:
/** /**
* @brief Set data mode! * @brief Set data mode!
*/ */
void set_data() { set_mode(modem_mode::DATA_MODE); } void set_data()
{
set_mode(modem_mode::DATA_MODE);
}
void exit_data() { set_mode(modem_mode::COMMAND_MODE); } void exit_data()
{
set_mode(modem_mode::COMMAND_MODE);
}
void set_cmux() { set_mode(modem_mode::CMUX_MODE); } void set_cmux()
{
set_mode(modem_mode::CMUX_MODE);
}
SpecificModule* get_module() { return device.get(); } SpecificModule *get_module()
{
return device.get();
}
command_result command(const std::string &command, got_line_cb got_line, uint32_t time_ms) command_result command(const std::string &command, got_line_cb got_line, uint32_t time_ms)
{ {
return dte->command(command, std::move(got_line), time_ms); return dte->command(command, std::move(got_line), time_ms);
} }
bool set_mode(modem_mode m) { return mode.set(dte.get(), device.get(), netif, m); } bool set_mode(modem_mode m)
{
return mode.set(dte.get(), device.get(), netif, m);
}
protected: protected:
std::shared_ptr<DTE> dte; std::shared_ptr<DTE> dte;
@ -98,7 +113,10 @@ public:
return device->name(std::forward<Agrs>(args)...); \ return device->name(std::forward<Agrs>(args)...); \
} }
DECLARE_ALL_COMMAND_APIS(forwards name(...) { device->name(...); } ) DECLARE_ALL_COMMAND_APIS(forwards name(...)
{
device->name(...);
} )
#undef ESP_MODEM_DECLARE_DCE_COMMAND #undef ESP_MODEM_DECLARE_DCE_COMMAND

View File

@ -93,13 +93,15 @@ public:
template<typename T_Dce, typename T_Ptr> template<typename T_Dce, typename T_Ptr>
auto create(const esp_modem_dce_config *config) -> T_Ptr auto create(const esp_modem_dce_config *config) -> T_Ptr
{ {
if (dte == nullptr) if (dte == nullptr) {
return nullptr; return nullptr;
}
if (device == nullptr) { if (device == nullptr) {
device = create_module<decltype(device)>(config); device = create_module<decltype(device)>(config);
if (device == nullptr) if (device == nullptr) {
return nullptr; return nullptr;
} }
}
return FactoryHelper::make<T_Dce, T_Ptr>(std::move(dte), std::move(device), netif); return FactoryHelper::make<T_Dce, T_Ptr>(std::move(dte), std::move(device), netif);
} }

View File

@ -58,10 +58,12 @@ public:
*/ */
bool setup_data_mode() override bool setup_data_mode() override
{ {
if (set_echo(false) != command_result::OK) if (set_echo(false) != command_result::OK) {
return false; return false;
if (set_pdp_context(*pdp) != command_result::OK) }
if (set_pdp_context(*pdp) != command_result::OK) {
return false; return false;
}
return true; return true;
} }
@ -72,8 +74,9 @@ public:
bool set_mode(modem_mode mode) override bool set_mode(modem_mode mode) override
{ {
if (mode == modem_mode::DATA_MODE) { if (mode == modem_mode::DATA_MODE) {
if (set_data_mode() != command_result::OK) if (set_data_mode() != command_result::OK) {
return resume_data_mode() == command_result::OK; return resume_data_mode() == command_result::OK;
}
return true; return true;
} else if (mode == modem_mode::COMMAND_MODE) { } else if (mode == modem_mode::COMMAND_MODE) {
return set_command_mode() == command_result::OK; return set_command_mode() == command_result::OK;

View File

@ -26,9 +26,13 @@ public:
explicit esp_err_exception(esp_err_t err): esp_err(err) {} explicit esp_err_exception(esp_err_t err): esp_err(err) {}
explicit esp_err_exception(std::string msg): esp_err(ESP_FAIL), message(std::move(msg)) {} explicit esp_err_exception(std::string msg): esp_err(ESP_FAIL), message(std::move(msg)) {}
explicit esp_err_exception(std::string msg, esp_err_t err): esp_err(err), message(std::move(msg)) {} explicit esp_err_exception(std::string msg, esp_err_t err): esp_err(err), message(std::move(msg)) {}
virtual esp_err_t get_err_t() { return esp_err; } virtual esp_err_t get_err_t()
{
return esp_err;
}
~esp_err_exception() noexcept override = default; ~esp_err_exception() noexcept override = default;
virtual const char* what() const noexcept { virtual const char *what() const noexcept
{
return message.c_str(); return message.c_str();
} }
private: private:

View File

@ -56,8 +56,14 @@ static constexpr uint32_t portMAX_DELAY = UINT32_MAX;
template<class T> template<class T>
class Scoped { class Scoped {
public: public:
explicit Scoped(T &l):lock(l) { lock.lock(); } explicit Scoped(T &l): lock(l)
~Scoped() { lock.unlock(); } {
lock.lock();
}
~Scoped()
{
lock.unlock();
}
private: private:
T &lock; T &lock;

View File

@ -50,9 +50,15 @@ class Terminal {
public: public:
virtual ~Terminal() = default; virtual ~Terminal() = default;
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_read = 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

View File

@ -35,8 +35,7 @@ class NetifStorage;
void read_task(NetifStorage *netif); void read_task(NetifStorage *netif);
class NetifStorage: public esp_netif_obj class NetifStorage: public esp_netif_obj {
{
public: public:
explicit NetifStorage(const esp_netif_config_t *config) : esp_netif_obj(), exit(false) explicit NetifStorage(const esp_netif_config_t *config) : esp_netif_obj(), exit(false)
{ {

View File

@ -30,14 +30,16 @@ struct PdpContext;
static const char *TAG = "modem_api"; static const char *TAG = "modem_api";
#endif #endif
std::shared_ptr<DTE> create_uart_dte(const dte_config *config) { std::shared_ptr<DTE> create_uart_dte(const dte_config *config)
{
TRY_CATCH_RET_NULL( TRY_CATCH_RET_NULL(
auto term = create_uart_terminal(config); auto term = create_uart_terminal(config);
return std::make_shared<DTE>(config, std::move(term)); return std::make_shared<DTE>(config, std::move(term));
) )
} }
std::shared_ptr<DTE> create_vfs_dte(const dte_config *config) { std::shared_ptr<DTE> create_vfs_dte(const dte_config *config)
{
TRY_CATCH_RET_NULL( TRY_CATCH_RET_NULL(
auto term = create_vfs_terminal(config); auto term = create_vfs_terminal(config);
return std::make_shared<DTE>(config, std::move(term)); return std::make_shared<DTE>(config, std::move(term));
@ -46,26 +48,31 @@ std::shared_ptr<DTE> create_vfs_dte(const dte_config *config) {
static inline std::unique_ptr<DCE> static inline std::unique_ptr<DCE>
create_modem_dce(dce_factory::ModemType m, const dce_config *config, std::shared_ptr<DTE> dte, esp_netif_t *netif) { create_modem_dce(dce_factory::ModemType m, const dce_config *config, std::shared_ptr<DTE> dte, esp_netif_t *netif)
{
dce_factory::Factory f(m); dce_factory::Factory f(m);
TRY_CATCH_RET_NULL( TRY_CATCH_RET_NULL(
return f.build_unique(config, std::move(dte), netif); return f.build_unique(config, std::move(dte), netif);
) )
} }
std::unique_ptr<DCE> create_SIM7600_dce(const dce_config *config, std::shared_ptr<DTE> dte, esp_netif_t *netif) { std::unique_ptr<DCE> create_SIM7600_dce(const dce_config *config, std::shared_ptr<DTE> dte, esp_netif_t *netif)
{
return create_modem_dce(dce_factory::ModemType::SIM7600, config, std::move(dte), netif); return create_modem_dce(dce_factory::ModemType::SIM7600, config, std::move(dte), netif);
} }
std::unique_ptr<DCE> create_SIM800_dce(const dce_config *config, std::shared_ptr<DTE> dte, esp_netif_t *netif) { std::unique_ptr<DCE> create_SIM800_dce(const dce_config *config, std::shared_ptr<DTE> dte, esp_netif_t *netif)
{
return create_modem_dce(dce_factory::ModemType::SIM800, config, std::move(dte), netif); return create_modem_dce(dce_factory::ModemType::SIM800, config, std::move(dte), netif);
} }
std::unique_ptr<DCE> create_BG96_dce(const dce_config *config, std::shared_ptr<DTE> dte, esp_netif_t *netif) { std::unique_ptr<DCE> create_BG96_dce(const dce_config *config, std::shared_ptr<DTE> dte, esp_netif_t *netif)
{
return create_modem_dce(dce_factory::ModemType::BG96, config, std::move(dte), netif); return create_modem_dce(dce_factory::ModemType::BG96, config, std::move(dte), netif);
} }
std::unique_ptr<DCE> create_generic_dce(const dce_config *config, std::shared_ptr<DTE> dte, esp_netif_t *netif) { std::unique_ptr<DCE> create_generic_dce(const dce_config *config, std::shared_ptr<DTE> dte, esp_netif_t *netif)
{
return create_modem_dce(dce_factory::ModemType::GenericModule, config, std::move(dte), netif); return create_modem_dce(dce_factory::ModemType::GenericModule, config, std::move(dte), netif);
} }

View File

@ -27,8 +27,7 @@
// C API definitions // C API definitions
using namespace esp_modem; using namespace esp_modem;
struct esp_modem_dce_wrap // need to mimic the polymorphic dispatch as CPP uses templated dispatch struct esp_modem_dce_wrap { // need to mimic the polymorphic dispatch as CPP uses templated dispatch
{
enum class modem_wrap_dte_type { UART, } dte_type; enum class modem_wrap_dte_type { UART, } dte_type;
dce_factory::ModemType modem_type; dce_factory::ModemType modem_type;
DCE *dce; DCE *dce;
@ -65,8 +64,9 @@ static inline dce_factory::ModemType convert_modem_enum(esp_modem_dce_device_t m
extern "C" esp_modem_dce_t *esp_modem_new_dev(esp_modem_dce_device_t module, const esp_modem_dte_config_t *dte_config, const esp_modem_dce_config_t *dce_config, esp_netif_t *netif) extern "C" esp_modem_dce_t *esp_modem_new_dev(esp_modem_dce_device_t module, const esp_modem_dte_config_t *dte_config, const esp_modem_dce_config_t *dce_config, esp_netif_t *netif)
{ {
auto dce_wrap = new (std::nothrow) esp_modem_dce_wrap; auto dce_wrap = new (std::nothrow) esp_modem_dce_wrap;
if (dce_wrap == nullptr) if (dce_wrap == nullptr) {
return nullptr; return nullptr;
}
auto dte = create_uart_dte(dte_config); auto dte = create_uart_dte(dte_config);
if (dte == nullptr) { if (dte == nullptr) {
delete dce_wrap; delete dce_wrap;
@ -98,8 +98,9 @@ extern "C" void esp_modem_destroy(esp_modem_dce_t * dce_wrap)
extern "C" esp_err_t esp_modem_set_mode(esp_modem_dce_t *dce_wrap, esp_modem_dce_mode_t mode) extern "C" esp_err_t esp_modem_set_mode(esp_modem_dce_t *dce_wrap, esp_modem_dce_mode_t mode)
{ {
if (dce_wrap == nullptr || dce_wrap->dce == nullptr) if (dce_wrap == nullptr || dce_wrap->dce == nullptr) {
return ESP_ERR_INVALID_ARG; return ESP_ERR_INVALID_ARG;
}
if (mode == ESP_MODEM_MODE_DATA) { if (mode == ESP_MODEM_MODE_DATA) {
dce_wrap->dce->set_data(); dce_wrap->dce->set_data();
} else if (mode == ESP_MODEM_MODE_COMMAND) { } else if (mode == ESP_MODEM_MODE_COMMAND) {
@ -112,24 +113,27 @@ extern "C" esp_err_t esp_modem_set_mode(esp_modem_dce_t * dce_wrap, esp_modem_dc
extern "C" esp_err_t esp_modem_read_pin(esp_modem_dce_t *dce_wrap, bool *pin) extern "C" esp_err_t esp_modem_read_pin(esp_modem_dce_t *dce_wrap, bool *pin)
{ {
if (dce_wrap == nullptr || dce_wrap->dce == nullptr) if (dce_wrap == nullptr || dce_wrap->dce == nullptr) {
return ESP_ERR_INVALID_ARG; return ESP_ERR_INVALID_ARG;
}
return command_response_to_esp_err(dce_wrap->dce->read_pin(*pin)); return command_response_to_esp_err(dce_wrap->dce->read_pin(*pin));
} }
extern "C" esp_err_t esp_modem_sms_txt_mode(esp_modem_dce_t *dce_wrap, bool txt) extern "C" esp_err_t esp_modem_sms_txt_mode(esp_modem_dce_t *dce_wrap, bool txt)
{ {
if (dce_wrap == nullptr || dce_wrap->dce == nullptr) if (dce_wrap == nullptr || dce_wrap->dce == nullptr) {
return ESP_ERR_INVALID_ARG; return ESP_ERR_INVALID_ARG;
}
return command_response_to_esp_err(dce_wrap->dce->sms_txt_mode(txt)); return command_response_to_esp_err(dce_wrap->dce->sms_txt_mode(txt));
} }
extern "C" esp_err_t esp_modem_send_sms(esp_modem_dce_t *dce_wrap, const char *number, const char *message) extern "C" esp_err_t esp_modem_send_sms(esp_modem_dce_t *dce_wrap, const char *number, const char *message)
{ {
if (dce_wrap == nullptr || dce_wrap->dce == nullptr) if (dce_wrap == nullptr || dce_wrap->dce == nullptr) {
return ESP_ERR_INVALID_ARG; return ESP_ERR_INVALID_ARG;
}
std::string number_str(number); std::string number_str(number);
std::string message_str(message); std::string message_str(message);
return command_response_to_esp_err(dce_wrap->dce->send_sms(number_str, message_str)); return command_response_to_esp_err(dce_wrap->dce->send_sms(number_str, message_str));
@ -137,31 +141,35 @@ extern "C" esp_err_t esp_modem_send_sms(esp_modem_dce_t * dce_wrap, const char *
extern "C" esp_err_t esp_modem_sms_character_set(esp_modem_dce_t *dce_wrap) extern "C" esp_err_t esp_modem_sms_character_set(esp_modem_dce_t *dce_wrap)
{ {
if (dce_wrap == nullptr || dce_wrap->dce == nullptr) if (dce_wrap == nullptr || dce_wrap->dce == nullptr) {
return ESP_ERR_INVALID_ARG; return ESP_ERR_INVALID_ARG;
}
return command_response_to_esp_err(dce_wrap->dce->sms_character_set()); return command_response_to_esp_err(dce_wrap->dce->sms_character_set());
} }
extern "C" esp_err_t esp_modem_set_pin(esp_modem_dce_t *dce_wrap, const char *pin) extern "C" esp_err_t esp_modem_set_pin(esp_modem_dce_t *dce_wrap, const char *pin)
{ {
if (dce_wrap == nullptr || dce_wrap->dce == nullptr) if (dce_wrap == nullptr || dce_wrap->dce == nullptr) {
return ESP_ERR_INVALID_ARG; return ESP_ERR_INVALID_ARG;
}
std::string pin_str(pin); std::string pin_str(pin);
return command_response_to_esp_err(dce_wrap->dce->set_pin(pin_str)); return command_response_to_esp_err(dce_wrap->dce->set_pin(pin_str));
} }
extern "C" esp_err_t esp_modem_get_signal_quality(esp_modem_dce_t *dce_wrap, int *rssi, int *ber) extern "C" esp_err_t esp_modem_get_signal_quality(esp_modem_dce_t *dce_wrap, int *rssi, int *ber)
{ {
if (dce_wrap == nullptr || dce_wrap->dce == nullptr) if (dce_wrap == nullptr || dce_wrap->dce == nullptr) {
return ESP_ERR_INVALID_ARG; return ESP_ERR_INVALID_ARG;
}
return command_response_to_esp_err(dce_wrap->dce->get_signal_quality(*rssi, *ber)); return command_response_to_esp_err(dce_wrap->dce->get_signal_quality(*rssi, *ber));
} }
extern "C" esp_err_t esp_modem_get_imsi(esp_modem_dce_t *dce_wrap, char *p_imsi) extern "C" esp_err_t esp_modem_get_imsi(esp_modem_dce_t *dce_wrap, char *p_imsi)
{ {
if (dce_wrap == nullptr || dce_wrap->dce == nullptr) if (dce_wrap == nullptr || dce_wrap->dce == nullptr) {
return ESP_ERR_INVALID_ARG; return ESP_ERR_INVALID_ARG;
}
std::string imsi; std::string imsi;
auto ret = command_response_to_esp_err(dce_wrap->dce->get_imsi(imsi)); auto ret = command_response_to_esp_err(dce_wrap->dce->get_imsi(imsi));
if (ret == ESP_OK && !imsi.empty()) { if (ret == ESP_OK && !imsi.empty()) {

View File

@ -262,8 +262,7 @@ bool CMux::init()
}); });
sabm_ack = -1; sabm_ack = -1;
for (size_t i = 0; i < 3; i++) for (size_t i = 0; i < 3; i++) {
{
int timeout = 0; int timeout = 0;
send_sabm(i); send_sabm(i);
while (true) { while (true) {
@ -273,10 +272,11 @@ bool CMux::init()
sabm_ack = -1; sabm_ack = -1;
break; break;
} }
if (timeout++ > 100) if (timeout++ > 100) {
return false; return false;
} }
} }
}
return true; return true;
} }
@ -288,8 +288,9 @@ int CMux::write(int virtual_term, uint8_t *data, size_t len)
size_t need_write = len; size_t need_write = len;
while (need_write > 0) { while (need_write > 0) {
size_t batch_len = need_write; size_t batch_len = need_write;
if (batch_len > cmux_max_len) if (batch_len > cmux_max_len) {
batch_len = cmux_max_len; batch_len = cmux_max_len;
}
uint8_t frame[6]; uint8_t frame[6];
frame[0] = SOF_MARKER; frame[0] = SOF_MARKER;
frame[1] = (i << 2) + 1; frame[1] = (i << 2) + 1;
@ -310,7 +311,9 @@ int CMux::write(int virtual_term, uint8_t *data, size_t len)
return len; return len;
} }
void CMux::set_read_cb(int inst, std::function<bool(uint8_t *, size_t)> f) { void CMux::set_read_cb(int inst, std::function<bool(uint8_t *, size_t)> f)
if (inst < max_terms) {
if (inst < max_terms) {
read_cb[inst] = std::move(f); read_cb[inst] = std::move(f);
} }
}

View File

@ -31,15 +31,18 @@ command_result generic_command(CommandableIf* t, const std::string &command,
ESP_LOGD(TAG, "%s command %s\n", __func__, command.c_str()); ESP_LOGD(TAG, "%s command %s\n", __func__, command.c_str());
return t->command(command, [&](uint8_t *data, size_t len) { return t->command(command, [&](uint8_t *data, size_t len) {
std::string_view response((char *)data, len); std::string_view response((char *)data, len);
if (data == nullptr || len == 0 || response.empty()) if (data == nullptr || len == 0 || response.empty()) {
return command_result::TIMEOUT; return command_result::TIMEOUT;
}
ESP_LOGD(TAG, "Response: %.*s\n", (int)response.length(), response.data()); ESP_LOGD(TAG, "Response: %.*s\n", (int)response.length(), response.data());
for (auto &it : pass_phrase) for (auto &it : pass_phrase)
if (response.find(it) != std::string::npos) if (response.find(it) != std::string::npos) {
return command_result::OK; return command_result::OK;
}
for (auto &it : fail_phrase) for (auto &it : fail_phrase)
if (response.find(it) != std::string::npos) if (response.find(it) != std::string::npos) {
return command_result::FAIL; return command_result::FAIL;
}
return command_result::TIMEOUT; return command_result::TIMEOUT;
}, timeout_ms); }, timeout_ms);
@ -64,8 +67,9 @@ static inline command_result generic_get_string(CommandableIf* t, const std::str
while ((pos = response.find('\n')) != std::string::npos) { while ((pos = response.find('\n')) != std::string::npos) {
std::string_view token = response.substr(0, pos); std::string_view token = response.substr(0, pos);
for (auto it = token.end() - 1; it > token.begin(); it--) // strip trailing CR or LF for (auto it = token.end() - 1; it > token.begin(); it--) // strip trailing CR or LF
if (*it == '\r' || *it == '\n') if (*it == '\r' || *it == '\n') {
token.remove_suffix(1); token.remove_suffix(1);
}
ESP_LOGV(TAG, "Token: {%.*s}\n", static_cast<int>(token.size()), token.data()); ESP_LOGV(TAG, "Token: {%.*s}\n", static_cast<int>(token.size()), token.data());
if (token.find("OK") != std::string::npos) { if (token.find("OK") != std::string::npos) {
@ -86,8 +90,9 @@ static inline command_result generic_get_string(CommandableIf* t, const std::str
ESP_LOGV(TAG, "%s", __func__ ); ESP_LOGV(TAG, "%s", __func__ );
std::string_view out; std::string_view out;
auto ret = generic_get_string(t, command, out, timeout_ms); auto ret = generic_get_string(t, command, out, timeout_ms);
if (ret == command_result::OK) if (ret == command_result::OK) {
output = out; output = out;
}
return ret; return ret;
} }
@ -151,18 +156,21 @@ command_result get_battery_status(CommandableIf* t, int& voltage, int &bcs, int
ESP_LOGV(TAG, "%s", __func__ ); ESP_LOGV(TAG, "%s", __func__ );
std::string_view out; std::string_view out;
auto ret = generic_get_string(t, "AT+CBC\r", out); auto ret = generic_get_string(t, "AT+CBC\r", out);
if (ret != command_result::OK) if (ret != command_result::OK) {
return ret; return ret;
}
constexpr std::string_view pattern = "+CBC: "; constexpr std::string_view pattern = "+CBC: ";
if (out.find(pattern) == std::string_view::npos) if (out.find(pattern) == std::string_view::npos) {
return command_result::FAIL; return command_result::FAIL;
}
// Parsing +CBC: <bcs>,<bcl>,<voltage> // Parsing +CBC: <bcs>,<bcl>,<voltage>
out = out.substr(pattern.size()); out = out.substr(pattern.size());
int pos, value, property = 0; int pos, value, property = 0;
while ((pos = out.find(',') != std::string::npos)) { while ((pos = out.find(',') != std::string::npos)) {
if (std::from_chars(out.data(), out.data() + pos, value).ec == std::errc::invalid_argument) if (std::from_chars(out.data(), out.data() + pos, value).ec == std::errc::invalid_argument) {
return command_result::FAIL; return command_result::FAIL;
}
switch (property++) { switch (property++) {
case 0: bcs = value; case 0: bcs = value;
break; break;
@ -173,8 +181,9 @@ command_result get_battery_status(CommandableIf* t, int& voltage, int &bcs, int
} }
out = out.substr(pos + 1); out = out.substr(pos + 1);
} }
if (std::from_chars(out.data(), out.data() + out.size(), voltage).ec == std::errc::invalid_argument) if (std::from_chars(out.data(), out.data() + out.size(), voltage).ec == std::errc::invalid_argument) {
return command_result::FAIL; return command_result::FAIL;
}
return command_result::OK; return command_result::OK;
} }
@ -183,21 +192,25 @@ command_result get_battery_status_sim7xxx(CommandableIf* t, int& voltage, int &b
ESP_LOGV(TAG, "%s", __func__ ); ESP_LOGV(TAG, "%s", __func__ );
std::string_view out; std::string_view out;
auto ret = generic_get_string(t, "AT+CBC\r", out); auto ret = generic_get_string(t, "AT+CBC\r", out);
if (ret != command_result::OK) if (ret != command_result::OK) {
return ret; return ret;
}
// Parsing +CBC: <voltage in Volts> V // Parsing +CBC: <voltage in Volts> V
constexpr std::string_view pattern = "+CBC: "; constexpr std::string_view pattern = "+CBC: ";
constexpr int num_pos = pattern.size(); constexpr int num_pos = pattern.size();
int dot_pos; int dot_pos;
if (out.find(pattern) == std::string::npos || if (out.find(pattern) == std::string::npos ||
(dot_pos = out.find('.')) == std::string::npos) (dot_pos = out.find('.')) == std::string::npos) {
return command_result::FAIL; return command_result::FAIL;
}
int volt, fraction; int volt, fraction;
if (std::from_chars(out.data() + num_pos, out.data() + dot_pos, volt).ec == std::errc::invalid_argument) if (std::from_chars(out.data() + num_pos, out.data() + dot_pos, volt).ec == std::errc::invalid_argument) {
return command_result::FAIL; return command_result::FAIL;
if (std::from_chars(out.data() + dot_pos + 1, out.data() + out.size() - 1, fraction).ec == std::errc::invalid_argument) }
if (std::from_chars(out.data() + dot_pos + 1, out.data() + out.size() - 1, fraction).ec == std::errc::invalid_argument) {
return command_result::FAIL; return command_result::FAIL;
}
bcl = bcs = -1; // not available for these models bcl = bcs = -1; // not available for these models
voltage = 1000 * volt + fraction; voltage = 1000 * volt + fraction;
return command_result::OK; return command_result::OK;
@ -214,8 +227,9 @@ command_result get_operator_name(CommandableIf* t, std::string& operator_name)
ESP_LOGV(TAG, "%s", __func__ ); ESP_LOGV(TAG, "%s", __func__ );
std::string_view out; std::string_view out;
auto ret = generic_get_string(t, "AT+COPS?\r", out, 75000); auto ret = generic_get_string(t, "AT+COPS?\r", out, 75000);
if (ret != command_result::OK) if (ret != command_result::OK) {
return ret; return ret;
}
auto pos = out.find("+COPS"); auto pos = out.find("+COPS");
auto property = 0; auto property = 0;
while (pos != std::string::npos) { while (pos != std::string::npos) {
@ -232,8 +246,9 @@ command_result get_operator_name(CommandableIf* t, std::string& operator_name)
command_result set_echo(CommandableIf *t, bool on) command_result set_echo(CommandableIf *t, bool on)
{ {
ESP_LOGV(TAG, "%s", __func__ ); ESP_LOGV(TAG, "%s", __func__ );
if (on) if (on) {
return generic_command_common(t, "ATE1\r"); return generic_command_common(t, "ATE1\r");
}
return generic_command_common(t, "ATE0\r"); return generic_command_common(t, "ATE0\r");
} }
@ -292,8 +307,9 @@ command_result get_module_name(CommandableIf* t, std::string& out)
command_result sms_txt_mode(CommandableIf *t, bool txt = true) command_result sms_txt_mode(CommandableIf *t, bool txt = true)
{ {
ESP_LOGV(TAG, "%s", __func__ ); ESP_LOGV(TAG, "%s", __func__ );
if (txt) if (txt) {
return generic_command_common(t, "AT+CMGF=1\r"); // Text mode (default) return generic_command_common(t, "AT+CMGF=1\r"); // Text mode (default)
}
return generic_command_common(t, "AT+CMGF=0\r"); // PDU mode return generic_command_common(t, "AT+CMGF=0\r"); // PDU mode
} }
@ -315,8 +331,9 @@ command_result send_sms(CommandableIf* t, const std::string& number, const std::
} }
return command_result::TIMEOUT; return command_result::TIMEOUT;
}, 5000, ' '); }, 5000, ' ');
if (ret != command_result::OK) if (ret != command_result::OK) {
return ret; return ret;
}
return generic_command_common(t, message + "\x1A", 120000); return generic_command_common(t, message + "\x1A", 120000);
} }
@ -332,10 +349,12 @@ command_result read_pin(CommandableIf* t, bool& pin_ok)
ESP_LOGV(TAG, "%s", __func__ ); ESP_LOGV(TAG, "%s", __func__ );
std::string_view out; std::string_view out;
auto ret = generic_get_string(t, "AT+CPIN?\r", out); auto ret = generic_get_string(t, "AT+CPIN?\r", out);
if (ret != command_result::OK) if (ret != command_result::OK) {
return ret; return ret;
if (out.find("+CPIN:") == std::string::npos) }
if (out.find("+CPIN:") == std::string::npos) {
return command_result::FAIL; return command_result::FAIL;
}
if (out.find("SIM PIN") != std::string::npos || out.find("SIM PUK") != std::string::npos) { if (out.find("SIM PIN") != std::string::npos || out.find("SIM PUK") != std::string::npos) {
pin_ok = false; pin_ok = false;
return command_result::OK; return command_result::OK;
@ -359,20 +378,24 @@ command_result get_signal_quality(CommandableIf* t, int &rssi, int &ber)
ESP_LOGV(TAG, "%s", __func__ ); ESP_LOGV(TAG, "%s", __func__ );
std::string_view out; std::string_view out;
auto ret = generic_get_string(t, "AT+CSQ\r", out); auto ret = generic_get_string(t, "AT+CSQ\r", out);
if (ret != command_result::OK) if (ret != command_result::OK) {
return ret; return ret;
}
constexpr std::string_view pattern = "+CSQ: "; constexpr std::string_view pattern = "+CSQ: ";
constexpr int rssi_pos = pattern.size(); constexpr int rssi_pos = pattern.size();
int ber_pos; int ber_pos;
if (out.find(pattern) == std::string::npos || if (out.find(pattern) == std::string::npos ||
(ber_pos = out.find(',')) == std::string::npos) (ber_pos = out.find(',')) == std::string::npos) {
return command_result::FAIL; return command_result::FAIL;
}
if (std::from_chars(out.data() + rssi_pos, out.data() + ber_pos, rssi).ec == std::errc::invalid_argument) if (std::from_chars(out.data() + rssi_pos, out.data() + ber_pos, rssi).ec == std::errc::invalid_argument) {
return command_result::FAIL; return command_result::FAIL;
if (std::from_chars(out.data() + ber_pos + 1, out.data() + out.size(), ber).ec == std::errc::invalid_argument) }
if (std::from_chars(out.data() + ber_pos + 1, out.data() + out.size(), ber).ec == std::errc::invalid_argument) {
return command_result::FAIL; return command_result::FAIL;
}
return command_result::OK; return command_result::OK;
} }

View File

@ -25,39 +25,48 @@ bool DCE_Mode::set(DTE *dte, ModuleIf *device, Netif &netif, modem_mode m)
case modem_mode::UNDEF: case modem_mode::UNDEF:
break; break;
case modem_mode::COMMAND_MODE: case modem_mode::COMMAND_MODE:
if (mode == modem_mode::COMMAND_MODE) if (mode == modem_mode::COMMAND_MODE) {
return false; return false;
}
netif.stop(); netif.stop();
if (!device->set_mode(modem_mode::COMMAND_MODE)) if (!device->set_mode(modem_mode::COMMAND_MODE)) {
return false; return false;
}
dte->set_read_cb([&](uint8_t *data, size_t len) -> bool { dte->set_read_cb([&](uint8_t *data, size_t len) -> bool {
ESP_LOG_BUFFER_HEXDUMP("esp-modem: debug_data", data, len, ESP_LOG_INFO); ESP_LOG_BUFFER_HEXDUMP("esp-modem: debug_data", data, len, ESP_LOG_INFO);
return false; return false;
}); });
netif.wait_until_ppp_exits(); netif.wait_until_ppp_exits();
dte->set_read_cb(nullptr); dte->set_read_cb(nullptr);
if (!dte->set_mode(modem_mode::COMMAND_MODE)) if (!dte->set_mode(modem_mode::COMMAND_MODE)) {
return false; return false;
}
mode = m; mode = m;
return true; return true;
case modem_mode::DATA_MODE: case modem_mode::DATA_MODE:
if (mode == modem_mode::DATA_MODE) if (mode == modem_mode::DATA_MODE) {
return false; return false;
if (!device->setup_data_mode()) }
if (!device->setup_data_mode()) {
return false; return false;
if (!device->set_mode(modem_mode::DATA_MODE)) }
if (!device->set_mode(modem_mode::DATA_MODE)) {
return false; return false;
if (!dte->set_mode(modem_mode::DATA_MODE)) }
if (!dte->set_mode(modem_mode::DATA_MODE)) {
return false; return false;
}
netif.start(); netif.start();
mode = m; mode = m;
return true; return true;
case modem_mode::CMUX_MODE: case modem_mode::CMUX_MODE:
if (mode == modem_mode::DATA_MODE || mode == modem_mode::CMUX_MODE) if (mode == modem_mode::DATA_MODE || mode == modem_mode::CMUX_MODE) {
return false; return false;
}
device->set_mode(modem_mode::CMUX_MODE); device->set_mode(modem_mode::CMUX_MODE);
if (!dte->set_mode(modem_mode::CMUX_MODE)) if (!dte->set_mode(modem_mode::CMUX_MODE)) {
return false; return false;
}
mode = modem_mode::COMMAND_MODE; mode = modem_mode::COMMAND_MODE;
return true; return true;
} }

View File

@ -72,17 +72,21 @@ command_result DTE::command(const std::string &cmd, got_line_cb got_line, uint32
bool DTE::setup_cmux() bool DTE::setup_cmux()
{ {
auto original_term = std::move(term); auto original_term = std::move(term);
if (original_term == nullptr) if (original_term == nullptr) {
return false; return false;
}
auto cmux_term = std::make_shared<CMux>(std::move(original_term), std::move(buffer), buffer_size); auto cmux_term = std::make_shared<CMux>(std::move(original_term), std::move(buffer), buffer_size);
if (cmux_term == nullptr) if (cmux_term == nullptr) {
return false; return false;
}
buffer_size = 0; buffer_size = 0;
if (!cmux_term->init()) if (!cmux_term->init()) {
return false; return false;
}
term = std::make_unique<CMuxInstance>(cmux_term, 0); term = std::make_unique<CMuxInstance>(cmux_term, 0);
if (term == nullptr) if (term == nullptr) {
return false; return false;
}
command_term = term.get(); // use command terminal as previously command_term = term.get(); // use command terminal as previously
other_term = std::make_unique<CMuxInstance>(cmux_term, 1); other_term = std::make_unique<CMuxInstance>(cmux_term, 1);
return true; return true;
@ -110,8 +114,9 @@ void DTE::set_read_cb(std::function<bool(uint8_t *, size_t)> f)
data = buffer.get(); data = buffer.get();
len = term->read(buffer.get(), buffer_size); len = term->read(buffer.get(), buffer_size);
} }
if (on_data) if (on_data) {
return on_data(data, len); return on_data(data, len);
}
return false; return false;
}); });
} }

View File

@ -42,7 +42,8 @@ std::shared_ptr<SIM7600> create_SIM7600_module(const std::shared_ptr<DTE>& dte,
#include "cxx_include/esp_modem_dce_factory.hpp" #include "cxx_include/esp_modem_dce_factory.hpp"
namespace esp_modem::dce_factory { namespace esp_modem::dce_factory {
std::unique_ptr<PdpContext> FactoryHelper::create_pdp_context(std::string &apn) { std::unique_ptr<PdpContext> FactoryHelper::create_pdp_context(std::string &apn)
{
return std::unique_ptr<PdpContext>(); return std::unique_ptr<PdpContext>();
} }

View File

@ -50,33 +50,40 @@ DECLARE_ALL_COMMAND_APIS(return_type name(...) )
// //
// Handle specific commands for specific supported modems // Handle specific commands for specific supported modems
// //
command_result SIM7600::get_module_name(std::string &name) { command_result SIM7600::get_module_name(std::string &name)
{
name = "7600"; name = "7600";
return command_result::OK; return command_result::OK;
} }
command_result SIM7600::get_battery_status(int& voltage, int &bcs, int &bcl) { command_result SIM7600::get_battery_status(int &voltage, int &bcs, int &bcl)
{
return dce_commands::get_battery_status_sim7xxx(dte.get(), voltage, bcs, bcl); return dce_commands::get_battery_status_sim7xxx(dte.get(), voltage, bcs, bcl);
} }
command_result SIM7600::power_down() { command_result SIM7600::power_down()
{
return dce_commands::power_down_sim7xxx(dte.get()); return dce_commands::power_down_sim7xxx(dte.get());
} }
command_result SIM800::get_module_name(std::string &name) { command_result SIM800::get_module_name(std::string &name)
{
name = "800L"; name = "800L";
return command_result::OK; return command_result::OK;
} }
command_result SIM800::power_down() { command_result SIM800::power_down()
{
return dce_commands::power_down_sim8xx(dte.get()); return dce_commands::power_down_sim8xx(dte.get());
} }
command_result SIM800::set_data_mode() { command_result SIM800::set_data_mode()
{
return dce_commands::set_data_mode_sim8xx(dte.get()); return dce_commands::set_data_mode_sim8xx(dte.get());
} }
command_result BG96::get_module_name(std::string &name) { command_result BG96::get_module_name(std::string &name)
{
name = "BG96"; name = "BG96";
return command_result::OK; return command_result::OK;
} }

View File

@ -24,7 +24,8 @@
namespace esp_modem { namespace esp_modem {
void Netif::on_ppp_changed(void *arg, esp_event_base_t event_base, void Netif::on_ppp_changed(void *arg, esp_event_base_t event_base,
int32_t event_id, void *event_data) { int32_t event_id, void *event_data)
{
auto *ppp = static_cast<Netif *>(arg); auto *ppp = static_cast<Netif *>(arg);
if (event_id < NETIF_PP_PHASE_OFFSET) { if (event_id < NETIF_PP_PHASE_OFFSET) {
ESP_LOGI("esp_modem_netif", "PPP state changed event %d", event_id); ESP_LOGI("esp_modem_netif", "PPP state changed event %d", event_id);
@ -33,7 +34,8 @@ void Netif::on_ppp_changed(void *arg, esp_event_base_t event_base,
} }
} }
esp_err_t Netif::esp_modem_dte_transmit(void *h, void *buffer, size_t len) { esp_err_t Netif::esp_modem_dte_transmit(void *h, void *buffer, size_t len)
{
auto *ppp = static_cast<Netif *>(h); auto *ppp = static_cast<Netif *>(h);
if (ppp->signal.is_any(PPP_STARTED)) { if (ppp->signal.is_any(PPP_STARTED)) {
if (ppp->ppp_dte && ppp->ppp_dte->write((uint8_t *) buffer, len) > 0) { if (ppp->ppp_dte && ppp->ppp_dte->write((uint8_t *) buffer, len) > 0) {
@ -43,7 +45,8 @@ esp_err_t Netif::esp_modem_dte_transmit(void *h, void *buffer, size_t len) {
return ESP_FAIL; return ESP_FAIL;
} }
esp_err_t Netif::esp_modem_post_attach(esp_netif_t *esp_netif, void *args) { esp_err_t Netif::esp_modem_post_attach(esp_netif_t *esp_netif, void *args)
{
auto d = (ppp_netif_driver *) args; auto d = (ppp_netif_driver *) args;
esp_netif_driver_ifconfig_t driver_ifconfig = {}; esp_netif_driver_ifconfig_t driver_ifconfig = {};
driver_ifconfig.transmit = Netif::esp_modem_dte_transmit; driver_ifconfig.transmit = Netif::esp_modem_dte_transmit;
@ -53,7 +56,8 @@ esp_err_t Netif::esp_modem_post_attach(esp_netif_t *esp_netif, void *args) {
// check if PPP error events are enabled, if not, do enable the error occurred/state changed // check if PPP error events are enabled, if not, do enable the error occurred/state changed
// to notify the modem layer when switching modes // to notify the modem layer when switching modes
esp_netif_ppp_config_t ppp_config = { .ppp_phase_event_enabled = true, // assuming phase enabled, as earlier IDFs esp_netif_ppp_config_t ppp_config = { .ppp_phase_event_enabled = true, // assuming phase enabled, as earlier IDFs
.ppp_error_event_enabled = false }; // don't provide cfg getters so we enable both events .ppp_error_event_enabled = false
}; // don't provide cfg getters so we enable both events
#if ESP_IDF_VERSION_MAJOR >= 4 && ESP_IDF_VERSION_MINOR >= 4 #if ESP_IDF_VERSION_MAJOR >= 4 && ESP_IDF_VERSION_MINOR >= 4
esp_netif_ppp_get_params(esp_netif, &ppp_config); esp_netif_ppp_get_params(esp_netif, &ppp_config);
#endif // ESP-IDF >= v4.4 #endif // ESP-IDF >= v4.4
@ -65,14 +69,16 @@ esp_err_t Netif::esp_modem_post_attach(esp_netif_t *esp_netif, void *args) {
return ESP_OK; return ESP_OK;
} }
void Netif::receive(uint8_t *data, size_t len) { void Netif::receive(uint8_t *data, size_t len)
{
if (signal.is_any(PPP_STARTED)) { if (signal.is_any(PPP_STARTED)) {
esp_netif_receive(driver.base.netif, data, len, nullptr); esp_netif_receive(driver.base.netif, data, len, nullptr);
} }
} }
Netif::Netif(std::shared_ptr<DTE> e, esp_netif_t *ppp_netif) : Netif::Netif(std::shared_ptr<DTE> e, esp_netif_t *ppp_netif) :
ppp_dte(std::move(e)), netif(ppp_netif) { ppp_dte(std::move(e)), netif(ppp_netif)
{
driver.base.netif = ppp_netif; driver.base.netif = ppp_netif;
driver.ppp = this; driver.ppp = this;
driver.base.post_attach = esp_modem_post_attach; driver.base.post_attach = esp_modem_post_attach;
@ -83,7 +89,8 @@ Netif::Netif(std::shared_ptr<DTE> e, esp_netif_t *ppp_netif) :
throw_if_esp_fail(esp_netif_attach(ppp_netif, &driver)); throw_if_esp_fail(esp_netif_attach(ppp_netif, &driver));
} }
void Netif::start() { void Netif::start()
{
ppp_dte->set_read_cb([this](uint8_t *data, size_t len) -> bool { ppp_dte->set_read_cb([this](uint8_t *data, size_t len) -> bool {
receive(data, len); receive(data, len);
return false; return false;
@ -92,12 +99,14 @@ void Netif::start() {
signal.set(PPP_STARTED); signal.set(PPP_STARTED);
} }
void Netif::stop() { void Netif::stop()
{
esp_netif_action_stop(driver.base.netif, nullptr, 0, nullptr); esp_netif_action_stop(driver.base.netif, nullptr, 0, nullptr);
signal.clear(PPP_STARTED); signal.clear(PPP_STARTED);
} }
Netif::~Netif() { Netif::~Netif()
{
if (signal.is_any(PPP_STARTED)) { if (signal.is_any(PPP_STARTED)) {
esp_netif_action_stop(driver.base.netif, nullptr, 0, nullptr); esp_netif_action_stop(driver.base.netif, nullptr, 0, nullptr);
signal.clear(PPP_STARTED); signal.clear(PPP_STARTED);
@ -108,7 +117,8 @@ Netif::~Netif() {
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);
} }
void Netif::wait_until_ppp_exits() { void Netif::wait_until_ppp_exits()
{
signal.wait(PPP_EXIT, 30000); signal.wait(PPP_EXIT, 30000);
} }

View File

@ -19,7 +19,8 @@
namespace esp_modem { namespace esp_modem {
void Netif::on_ppp_changed(void *arg, esp_event_base_t event_base, void Netif::on_ppp_changed(void *arg, esp_event_base_t event_base,
int32_t event_id, void *event_data) { int32_t event_id, void *event_data)
{
} }
esp_err_t Netif::esp_modem_dte_transmit(void *h, void *buffer, size_t len) esp_err_t Netif::esp_modem_dte_transmit(void *h, void *buffer, size_t len)
@ -29,7 +30,8 @@ esp_err_t Netif::esp_modem_dte_transmit(void *h, void *buffer, size_t len)
return len; return len;
} }
esp_err_t Netif::esp_modem_post_attach(esp_netif_t *esp_netif, void *args) { esp_err_t Netif::esp_modem_post_attach(esp_netif_t *esp_netif, void *args)
{
return ESP_OK; return ESP_OK;
} }
@ -56,7 +58,8 @@ void Netif::stop() {}
Netif::~Netif() = default; Netif::~Netif() = default;
void Netif::wait_until_ppp_exits() { void Netif::wait_until_ppp_exits()
{
} }

View File

@ -20,7 +20,8 @@
namespace esp_modem { namespace esp_modem {
void Lock::unlock() { void Lock::unlock()
{
xSemaphoreGiveRecursive(m); xSemaphoreGiveRecursive(m);
} }
@ -30,11 +31,13 @@ Lock::Lock(): m(nullptr)
throw_if_false(m != nullptr, "create signal event group failed"); throw_if_false(m != nullptr, "create signal event group failed");
} }
Lock::~Lock() { Lock::~Lock()
{
vSemaphoreDelete(m); vSemaphoreDelete(m);
} }
void Lock::lock() { void Lock::lock()
{
xSemaphoreTakeRecursive(m, portMAX_DELAY); xSemaphoreTakeRecursive(m, portMAX_DELAY);
} }
@ -74,9 +77,10 @@ bool SignalGroup::wait_any(uint32_t flags, uint32_t time_ms)
SignalGroup::~SignalGroup() SignalGroup::~SignalGroup()
{ {
if (event_group) if (event_group) {
vEventGroupDelete(event_group); vEventGroupDelete(event_group);
} }
}
Task::Task(size_t stack_size, size_t priority, void *task_param, TaskFunction_t task_function) Task::Task(size_t stack_size, size_t priority, void *task_param, TaskFunction_t task_function)
: task_handle(nullptr) : task_handle(nullptr)
@ -87,9 +91,10 @@ Task::Task(size_t stack_size, size_t priority, void *task_param, TaskFunction_t
Task::~Task() Task::~Task()
{ {
if (task_handle) if (task_handle) {
vTaskDelete(task_handle); vTaskDelete(task_handle);
} }
}
void Task::Delete() void Task::Delete()
{ {

View File

@ -47,7 +47,8 @@ bool SignalGroup::wait(uint32_t flags, uint32_t time_ms)
{ {
std::unique_lock<std::mutex> lock(event_group->m); std::unique_lock<std::mutex> lock(event_group->m);
return event_group->notify.wait_for(lock, std::chrono::milliseconds(time_ms), [&] { return event_group->notify.wait_for(lock, std::chrono::milliseconds(time_ms), [&] {
if ((flags&event_group->flags) == flags) { if ((flags & event_group->flags) == flags)
{
event_group->flags &= ~flags; event_group->flags &= ~flags;
return true; return true;
} }

View File

@ -29,7 +29,8 @@ struct File {
fd(config->vfs_config.fd), deleter(config->vfs_config.deleter), resource(config->vfs_config.resource) fd(config->vfs_config.fd), deleter(config->vfs_config.deleter), resource(config->vfs_config.resource)
{} {}
~File() { ~File()
{
if (deleter) { if (deleter) {
deleter(fd, resource); deleter(fd, resource);
} }
@ -45,11 +46,13 @@ public:
~FdTerminal() override; ~FdTerminal() override;
void start() override { void start() override
{
signal.set(TASK_START); signal.set(TASK_START);
} }
void stop() override { void stop() override
{
signal.clear(TASK_START); signal.clear(TASK_START);
} }
@ -57,7 +60,8 @@ 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_read = std::move(f); on_read = std::move(f);
signal.set(TASK_PARAMS); signal.set(TASK_PARAMS);
} }
@ -75,7 +79,8 @@ private:
Task task_handle; Task task_handle;
}; };
std::unique_ptr<Terminal> create_vfs_terminal(const esp_modem_dte_config *config) { std::unique_ptr<Terminal> create_vfs_terminal(const esp_modem_dte_config *config)
{
TRY_CATCH_RET_NULL( TRY_CATCH_RET_NULL(
auto term = std::make_unique<FdTerminal>(config); auto term = std::make_unique<FdTerminal>(config);
term->start(); term->start();
@ -85,7 +90,8 @@ std::unique_ptr<Terminal> create_vfs_terminal(const esp_modem_dte_config *config
FdTerminal::FdTerminal(const esp_modem_dte_config *config) : FdTerminal::FdTerminal(const esp_modem_dte_config *config) :
f(config), signal(), f(config), signal(),
task_handle(config->task_stack_size, config->task_priority, this, [](void* p){ task_handle(config->task_stack_size, config->task_priority, this, [](void *p)
{
auto t = static_cast<FdTerminal *>(p); auto t = static_cast<FdTerminal *>(p);
t->task(); t->task();
Task::Delete(); Task::Delete();

View File

@ -30,13 +30,17 @@ namespace esp_modem {
struct uart_task { struct uart_task {
explicit uart_task(size_t stack_size, size_t priority, void *task_param, TaskFunction_t task_function) : explicit uart_task(size_t stack_size, size_t priority, void *task_param, TaskFunction_t task_function) :
task_handle(nullptr) { task_handle(nullptr)
{
BaseType_t ret = xTaskCreate(task_function, "uart_task", stack_size, task_param, priority, &task_handle); BaseType_t ret = xTaskCreate(task_function, "uart_task", stack_size, task_param, priority, &task_handle);
throw_if_false(ret == pdTRUE, "create uart event task failed"); throw_if_false(ret == pdTRUE, "create uart event task failed");
} }
~uart_task() { ~uart_task()
if (task_handle) vTaskDelete(task_handle); {
if (task_handle) {
vTaskDelete(task_handle);
}
} }
TaskHandle_t task_handle; /*!< UART event task handle */ TaskHandle_t task_handle; /*!< UART event task handle */
@ -52,11 +56,13 @@ public:
~UartTerminal() override = default; ~UartTerminal() override = default;
void start() override { void start() override
{
signal.set(TASK_START); signal.set(TASK_START);
} }
void stop() override { void stop() override
{
signal.set(TASK_STOP); signal.set(TASK_STOP);
} }
@ -64,24 +70,28 @@ 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_read = std::move(f); on_read = std::move(f);
signal.set(TASK_PARAMS); signal.set(TASK_PARAMS);
} }
private: private:
static void s_task(void *task_param) { static void s_task(void *task_param)
{
auto t = static_cast<UartTerminal *>(task_param); auto t = static_cast<UartTerminal *>(task_param);
t->task(); t->task();
vTaskDelete(nullptr); vTaskDelete(nullptr);
} }
void task(); void task();
bool get_event(uart_event_t &event, uint32_t time_ms) { bool get_event(uart_event_t &event, uint32_t time_ms)
{
return xQueueReceive(event_queue, &event, pdMS_TO_TICKS(time_ms)); return xQueueReceive(event_queue, &event, pdMS_TO_TICKS(time_ms));
} }
void reset_events() { void reset_events()
{
uart_flush_input(uart.port); uart_flush_input(uart.port);
xQueueReset(event_queue); xQueueReset(event_queue);
} }
@ -97,7 +107,8 @@ private:
uart_task task_handle; uart_task task_handle;
}; };
std::unique_ptr<Terminal> create_uart_terminal(const esp_modem_dte_config *config) { std::unique_ptr<Terminal> create_uart_terminal(const esp_modem_dte_config *config)
{
TRY_CATCH_RET_NULL( TRY_CATCH_RET_NULL(
auto term = std::make_unique<UartTerminal>(config); auto term = std::make_unique<UartTerminal>(config);
term->start(); term->start();
@ -105,7 +116,8 @@ 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_read_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;
@ -131,30 +143,35 @@ void UartTerminal::task() {
break; break;
case UART_FIFO_OVF: case UART_FIFO_OVF:
ESP_LOGW(TAG, "HW FIFO Overflow"); ESP_LOGW(TAG, "HW FIFO Overflow");
if (on_error) if (on_error) {
on_error(terminal_error::BUFFER_OVERFLOW); on_error(terminal_error::BUFFER_OVERFLOW);
}
reset_events(); reset_events();
break; break;
case UART_BUFFER_FULL: case UART_BUFFER_FULL:
ESP_LOGW(TAG, "Ring Buffer Full"); ESP_LOGW(TAG, "Ring Buffer Full");
if (on_error) if (on_error) {
on_error(terminal_error::BUFFER_OVERFLOW); on_error(terminal_error::BUFFER_OVERFLOW);
}
reset_events(); reset_events();
break; break;
case UART_BREAK: case UART_BREAK:
ESP_LOGW(TAG, "Rx Break"); ESP_LOGW(TAG, "Rx Break");
if (on_error) if (on_error) {
on_error(terminal_error::UNEXPECTED_CONTROL_FLOW); on_error(terminal_error::UNEXPECTED_CONTROL_FLOW);
}
break; break;
case UART_PARITY_ERR: case UART_PARITY_ERR:
ESP_LOGE(TAG, "Parity Error"); ESP_LOGE(TAG, "Parity Error");
if (on_error) if (on_error) {
on_error(terminal_error::CHECKSUM_ERROR); on_error(terminal_error::CHECKSUM_ERROR);
}
break; break;
case UART_FRAME_ERR: case UART_FRAME_ERR:
ESP_LOGE(TAG, "Frame Error"); ESP_LOGE(TAG, "Frame Error");
if (on_error) if (on_error) {
on_error(terminal_error::UNEXPECTED_CONTROL_FLOW); on_error(terminal_error::UNEXPECTED_CONTROL_FLOW);
}
break; break;
default: default:
ESP_LOGW(TAG, "unknown uart event type: %d", event.type); ESP_LOGW(TAG, "unknown uart event type: %d", event.type);

View File

@ -49,9 +49,9 @@ int LoopbackTerm::write(uint8_t *data, size_t len)
} }
if (len > 2 && data[0] == 0xf9) { // Simple CMUX responder if (len > 2 && data[0] == 0xf9) { // Simple CMUX responder
// turn the request into a reply -> implements CMUX loopback // turn the request into a reply -> implements CMUX loopback
if (data[2] == 0x3f) // SABM command if (data[2] == 0x3f) { // SABM command
data[2] = 0x73; data[2] = 0x73;
else if (data[2] == 0xef) { // Generic request } else if (data[2] == 0xef) { // Generic request
data[2] = 0xff; // generic reply data[2] = 0xff; // generic reply
} }
} }
@ -66,8 +66,9 @@ int LoopbackTerm::read(uint8_t *data, size_t len)
{ {
size_t read_len = std::min(data_len, len); size_t read_len = std::min(data_len, len);
if (read_len) { if (read_len) {
if (loopback_data.capacity() < len) if (loopback_data.capacity() < len) {
loopback_data.reserve(len); loopback_data.reserve(len);
}
memcpy(data, &loopback_data[0], read_len); memcpy(data, &loopback_data[0], read_len);
loopback_data.erase(loopback_data.begin(), loopback_data.begin() + read_len); loopback_data.erase(loopback_data.begin(), loopback_data.begin() + read_len);
data_len -= read_len; data_len -= read_len;

View File

@ -114,7 +114,8 @@ TEST_CASE("DCE modes", "[esp_modem]")
CHECK(dce->set_mode(esp_modem::modem_mode::COMMAND_MODE) == true); CHECK(dce->set_mode(esp_modem::modem_mode::COMMAND_MODE) == true);
} }
TEST_CASE("DCE CMUX test", "[esp_modem]") { TEST_CASE("DCE CMUX test", "[esp_modem]")
{
auto term = std::make_unique<LoopbackTerm>(); auto term = std::make_unique<LoopbackTerm>();
auto dte = std::make_shared<DTE>(std::move(term)); auto dte = std::make_shared<DTE>(std::move(term));
CHECK(term == nullptr); CHECK(term == nullptr);

View File

@ -62,9 +62,18 @@ public:
return dce == nullptr ? ESP_FAIL : ESP_OK; return dce == nullptr ? ESP_FAIL : ESP_OK;
} }
static void deinit() { delete dce; } static void deinit()
static void start() { dce->set_data(); } {
static void stop() { dce->exit_data(); } delete dce;
}
static void start()
{
dce->set_data();
}
static void stop()
{
dce->exit_data();
}
private: private:
static NetDCE *dce; static NetDCE *dce;