diff --git a/esp_modem/CMakeLists.txt b/esp_modem/CMakeLists.txt index c98b05dcf..9a03093b1 100644 --- a/esp_modem/CMakeLists.txt +++ b/esp_modem/CMakeLists.txt @@ -8,7 +8,8 @@ set(srcs "src/esp_modem.c" "src/esp_sim800.c" "src/esp_sim7600.c" "src/esp_bg96.c" - "src/esp_modem_dte.cpp") + "src/esp_modem_dte.cpp" + "src/ppp_netif.cpp") set(include_dirs "include") diff --git a/esp_modem/examples/simple_cxx_client/main/simple_client.cpp b/esp_modem/examples/simple_cxx_client/main/simple_client.cpp index 0d1d5a1ef..de58f6ed0 100644 --- a/esp_modem/examples/simple_cxx_client/main/simple_client.cpp +++ b/esp_modem/examples/simple_cxx_client/main/simple_client.cpp @@ -264,13 +264,31 @@ static void modem_test_app(esp_modem_dte_config_t *dte_config, esp_modem_dce_con int actual_len = 0; auto ddd = create_dte(dte_config); ddd->set_mode(dte_mode::UNDEF); - ddd->send_command("AT\r", [&](uint8_t *data, size_t len) { + ddd->send_command("AT+CPIN?\r", [&](uint8_t *data, size_t len) { std::string response((char*)data, len); ESP_LOGI("in the lambda", "len=%d data %s", len, (char*)data); std::cout << response << std::endl; return true; }, 1000); +// ddd->send_command("AT+CPIN=1234\r", [&](uint8_t *data, size_t len) { +// std::string response((char*)data, len); +// ESP_LOGI("in the lambda", "len=%d data %s", len, (char*)data); +// std::cout << response << std::endl; +// return true; +// }, 1000); + esp_netif_t *esp_netif = esp_netif_new(ppp_config); + assert(esp_netif); + + auto my_dce = create_dce(ddd, esp_netif); + + ddd->send_command("AT+COPS=?\r", [&](uint8_t *data, size_t len) { + std::string response((char*)data, len); + ESP_LOGI("in the lambda", "len=%d data %s", len, (char*)data); + std::cout << response << std::endl; + return true; + }, 60000); + // auto uart = create_uart_terminal(dte_config); // uart->set_data_cb([&](size_t len){ // actual_len = uart->read(data, 32); @@ -300,7 +318,7 @@ static void modem_test_app(esp_modem_dte_config_t *dte_config, esp_modem_dce_con assert(dce != NULL); /* create netif object */ - esp_netif_t *esp_netif = esp_netif_new(ppp_config); +// esp_netif_t *esp_netif = esp_netif_new(ppp_config); assert(esp_netif); #if !defined(CONFIG_EXAMPLE_MODEM_PPP_AUTH_NONE) && (defined(CONFIG_LWIP_PPP_PAP_SUPPORT) || defined(CONFIG_LWIP_PPP_CHAP_SUPPORT)) #if CONFIG_LWIP_PPP_PAP_SUPPORT diff --git a/esp_modem/include/cxx_include/esp_modem_dte.hpp b/esp_modem/include/cxx_include/esp_modem_dte.hpp index d25586030..c69660ad2 100644 --- a/esp_modem/include/cxx_include/esp_modem_dte.hpp +++ b/esp_modem/include/cxx_include/esp_modem_dte.hpp @@ -9,7 +9,7 @@ #include #include "esp_err.h" #include "terminal_objects.hpp" - +#include "ppp_netif.hpp" enum class terminal_error { @@ -62,10 +62,14 @@ typedef std::function got_line_cb; class dte { public: - explicit dte(std::unique_ptr terminal); + explicit dte(std::unique_ptr t); ~dte() = default; // void set_line_cb(got_line f) { on_line_cb = std::move(f); } + int write(uint8_t *data, size_t len) { return term->write(data, len); } + int read(uint8_t *data, size_t len) { return term->read(data, len); } + void start() { term->start(); } + void data_mode_closed() { term->stop(); } void set_mode(dte_mode m) { term->start(); mode = m; } bool send_command(const std::string& command, got_line_cb got_line, uint32_t time_ms); @@ -81,6 +85,14 @@ private: }; +class dce { +public: + explicit dce(std::shared_ptr d, esp_netif_t * netif); +private: + std::shared_ptr _dte; + ppp ppp_netif; +}; + #endif //SIMPLE_CXX_CLIENT_ESP_MODEM_DTE_HPP diff --git a/esp_modem/include/cxx_include/ppp_netif.hpp b/esp_modem/include/cxx_include/ppp_netif.hpp new file mode 100644 index 000000000..defe31fe8 --- /dev/null +++ b/esp_modem/include/cxx_include/ppp_netif.hpp @@ -0,0 +1,30 @@ +// +// Created by david on 2/26/21. +// + +#ifndef SIMPLE_CXX_CLIENT_PPP_NETIF_HPP +#define SIMPLE_CXX_CLIENT_PPP_NETIF_HPP + +#include "esp_netif.h" + +class dte; + +//struct ppp_netif_driver; +struct ppp_netif_driver { + esp_netif_driver_base_t base; + dte *e; +}; + + +class ppp { +public: + explicit ppp(std::shared_ptr e, esp_netif_t *netif); + +private: + esp_netif_t *netif; + std::shared_ptr _dte; + struct ppp_netif_driver driver; +}; + + +#endif //SIMPLE_CXX_CLIENT_PPP_NETIF_HPP diff --git a/esp_modem/include/cxx_include/uart_terminal.hpp b/esp_modem/include/cxx_include/uart_terminal.hpp index eeed20345..ef7d769b0 100644 --- a/esp_modem/include/cxx_include/uart_terminal.hpp +++ b/esp_modem/include/cxx_include/uart_terminal.hpp @@ -12,6 +12,9 @@ std::unique_ptr create_uart_terminal(const struct dte_config *config); class dte; -std::unique_ptr create_dte(const struct dte_config *config); +std::shared_ptr create_dte(const struct dte_config *config); + +std::unique_ptr create_dce(const std::shared_ptr& e, esp_netif_t *netif); + #endif //SIMPLE_CXX_CLIENT_UART_TERMINAL_HPP diff --git a/esp_modem/src/esp_modem_dte.cpp b/esp_modem/src/esp_modem_dte.cpp index 695b6384c..b99eea6c1 100644 --- a/esp_modem/src/esp_modem_dte.cpp +++ b/esp_modem/src/esp_modem_dte.cpp @@ -219,11 +219,11 @@ std::unique_ptr create_uart_terminal(const struct dte_config *config) } -std::unique_ptr create_dte(const struct dte_config *config) +std::shared_ptr create_dte(const struct dte_config *config) { try { - auto term = std::make_unique(std::make_unique(config)); -// term->start(); +// auto term = std::make_unique(std::make_unique(config)); + auto term = std::make_shared(std::make_unique(config)); return term; } catch (std::bad_alloc& e) { ESP_LOGE(TAG, "Out of memory"); @@ -237,6 +237,21 @@ std::unique_ptr create_dte(const struct dte_config *config) } +std::unique_ptr create_dce(const std::shared_ptr& e, esp_netif_t *netif) +{ + try { + return std::make_unique(e, netif); + } catch (std::bad_alloc& e) { + ESP_LOGE(TAG, "Out of memory"); + return nullptr; + } catch (esp_err_exception& e) { + esp_err_t err = e.get_err_t(); + ESP_LOGE(TAG, "Error occurred during UART term init: %d", err); + ESP_LOGE(TAG, "%s", e.what()); + return nullptr; + } +} + void uart_terminal::task() { @@ -321,14 +336,18 @@ bool dte::send_command(const std::string& command, got_line_cb got_line, uint32_ auto actual_len = term->read(data, data_to_read); consumed += actual_len; if (memchr(data, '\n', actual_len)) { - ESP_LOGI("in the lambda", "FOUND"); + ESP_LOGD("in the lambda", "FOUND"); if (got_line(buffer.get(), consumed)) { signal.set(GOT_LINE); } } - ESP_LOGI("in the lambda", "len=%d data %s", len, (char*)buffer.get()); }); auto res = signal.wait(GOT_LINE, time_ms); consumed = 0; return res; -} \ No newline at end of file +} + +dce::dce(std::shared_ptr e, esp_netif_t * netif): +_dte(std::move(e)), ppp_netif(e, netif) +{ } + diff --git a/esp_modem/src/ppp_netif.cpp b/esp_modem/src/ppp_netif.cpp new file mode 100644 index 000000000..639b7b763 --- /dev/null +++ b/esp_modem/src/ppp_netif.cpp @@ -0,0 +1,69 @@ +// +// Created by david on 2/26/21. +// +#include +#include +#include +#include +#include "cxx_include/ppp_netif.hpp" +#include "cxx_include/esp_modem_dte.hpp" +#include "esp_netif_ppp.h" + + +//struct ppp_netif_driver { +// esp_netif_driver_base_t base; +//}; + +static void on_ppp_changed(void *arg, esp_event_base_t event_base, + int32_t event_id, void *event_data) +{ + dte *e = (dte*)arg; + if (event_id < NETIF_PP_PHASE_OFFSET) { + ESP_LOGI("TAG", "PPP state changed event %d", event_id); + // only notify the modem on state/error events, ignoring phase transitions + e->data_mode_closed(); +// esp_modem_notify_ppp_netif_closed(dte); + } +} + +static esp_err_t esp_modem_dte_transmit(void *h, void *buffer, size_t len) +{ + dte *e = (dte*)h; + if (e->write((uint8_t*)buffer, len) > 0) { + return ESP_OK; + } + return ESP_FAIL; +} + + +static esp_err_t esp_modem_post_attach(esp_netif_t * esp_netif, void * args) +{ + ppp_netif_driver *d = (ppp_netif_driver*)args; + esp_netif_driver_ifconfig_t driver_ifconfig = { }; + driver_ifconfig.transmit = esp_modem_dte_transmit; + driver_ifconfig.handle = (void*)d->e; + + d->base.netif = esp_netif; + ESP_ERROR_CHECK(esp_netif_set_driver_config(esp_netif, &driver_ifconfig)); + // check if PPP error events are enabled, if not, do enable the error occurred/state changed + // to notify the modem layer when switching modes + esp_netif_ppp_config_t ppp_config; + esp_netif_ppp_get_params(esp_netif, &ppp_config); + if (!ppp_config.ppp_error_event_enabled) { + ppp_config.ppp_error_event_enabled = true; + esp_netif_ppp_set_params(esp_netif, &ppp_config); + } + + ESP_ERROR_CHECK(esp_event_handler_register(NETIF_PPP_STATUS, ESP_EVENT_ANY_ID, &on_ppp_changed, (void*)d->e)); + return ESP_OK; +} + + +ppp::ppp(std::shared_ptr e, esp_netif_t *ppp_netif): + netif(ppp_netif), _dte(std::move(e)) +{ + driver.base.netif = ppp_netif; + driver.e = this->_dte.get(); + driver.base.post_attach = esp_modem_post_attach; + throw_if_esp_fail(esp_netif_attach(ppp_netif, &driver)); +}