From cbc75ed7fe26509afdd8f1ab2a4ed887555abe7f Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Mon, 15 Apr 2024 22:54:43 +0300 Subject: [PATCH 1/4] feat(ppp): Add support for PPP Modems --- CMakeLists.txt | 5 + Kconfig.projbuild | 10 + cores/esp32/esp32-hal-periman.c | 6 + cores/esp32/esp32-hal-periman.h | 6 + idf_component.yml | 1 + libraries/Network/src/NetworkEvents.cpp | 18 +- libraries/Network/src/NetworkEvents.h | 15 +- libraries/Network/src/NetworkInterface.cpp | 27 +- .../PPP/examples/PPP_Basic/PPP_Basic.ino | 131 +++ libraries/PPP/library.properties | 9 + libraries/PPP/src/PPP.cpp | 817 ++++++++++++++++++ libraries/PPP/src/PPP.h | 107 +++ libraries/PPP/src/ppp.c | 28 + 13 files changed, 1149 insertions(+), 31 deletions(-) create mode 100644 libraries/PPP/examples/PPP_Basic/PPP_Basic.ino create mode 100644 libraries/PPP/library.properties create mode 100644 libraries/PPP/src/PPP.cpp create mode 100644 libraries/PPP/src/PPP.h create mode 100644 libraries/PPP/src/ppp.c diff --git a/CMakeLists.txt b/CMakeLists.txt index aaa59b0fbb6..8e760225a04 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -95,6 +95,7 @@ set(ARDUINO_ALL_LIBRARIES LittleFS NetBIOS Network + PPP Preferences RainMaker SD_MMC @@ -157,6 +158,10 @@ set(ARDUINO_LIBRARY_LittleFS_SRCS libraries/LittleFS/src/LittleFS.cpp) set(ARDUINO_LIBRARY_NetBIOS_SRCS libraries/NetBIOS/src/NetBIOS.cpp) +set(ARDUINO_LIBRARY_PPP_SRCS + libraries/PPP/src/PPP.cpp + libraries/PPP/src/ppp.c) + set(ARDUINO_LIBRARY_Preferences_SRCS libraries/Preferences/src/Preferences.cpp) set(ARDUINO_LIBRARY_RainMaker_SRCS diff --git a/Kconfig.projbuild b/Kconfig.projbuild index d753f436f70..979afc02213 100644 --- a/Kconfig.projbuild +++ b/Kconfig.projbuild @@ -321,6 +321,16 @@ config ARDUINO_SELECTIVE_Networking depends on ARDUINO_SELECTIVE_COMPILATION default y +config ARDUINO_SELECTIVE_Ethernet + bool "Enable Ethernet" + depends on ARDUINO_SELECTIVE_COMPILATION + default y + +config ARDUINO_SELECTIVE_PPP + bool "Enable PPP" + depends on ARDUINO_SELECTIVE_COMPILATION + default y + config ARDUINO_SELECTIVE_ArduinoOTA bool "Enable ArduinoOTA" depends on ARDUINO_SELECTIVE_COMPILATION && ARDUINO_SELECTIVE_Networking diff --git a/cores/esp32/esp32-hal-periman.c b/cores/esp32/esp32-hal-periman.c index e6fc3e66b71..acd75dadcb3 100644 --- a/cores/esp32/esp32-hal-periman.c +++ b/cores/esp32/esp32-hal-periman.c @@ -104,6 +104,12 @@ const char* perimanGetTypeName(peripheral_bus_type_t type) { case ESP32_BUS_TYPE_ETHERNET_MCD: return "ETHERNET_MCD"; case ESP32_BUS_TYPE_ETHERNET_MDIO: return "ETHERNET_MDIO"; case ESP32_BUS_TYPE_ETHERNET_PWR: return "ETHERNET_PWR"; +#endif +#if CONFIG_LWIP_PPP_SUPPORT + case ESP32_BUS_TYPE_PPP_TX: return "PPP_MODEM_TX"; + case ESP32_BUS_TYPE_PPP_RX: return "PPP_MODEM_RX"; + case ESP32_BUS_TYPE_PPP_RTS: return "PPP_MODEM_RTS"; + case ESP32_BUS_TYPE_PPP_CTS: return "PPP_MODEM_CTS"; #endif default: return "UNKNOWN"; } diff --git a/cores/esp32/esp32-hal-periman.h b/cores/esp32/esp32-hal-periman.h index 989795d8ade..8dda5f85781 100644 --- a/cores/esp32/esp32-hal-periman.h +++ b/cores/esp32/esp32-hal-periman.h @@ -102,6 +102,12 @@ extern "C" { ESP32_BUS_TYPE_ETHERNET_MCD, // IO is used as ETHERNET MCD pin ESP32_BUS_TYPE_ETHERNET_MDIO, // IO is used as ETHERNET MDIO pin ESP32_BUS_TYPE_ETHERNET_PWR, // IO is used as ETHERNET PWR pin +#endif +#if CONFIG_LWIP_PPP_SUPPORT + ESP32_BUS_TYPE_PPP_TX, // IO is used as PPP Modem TX pin + ESP32_BUS_TYPE_PPP_RX, // IO is used as PPP Modem RX pin + ESP32_BUS_TYPE_PPP_RTS, // IO is used as PPP Modem RTS pin + ESP32_BUS_TYPE_PPP_CTS, // IO is used as PPP Modem CTS pin #endif ESP32_BUS_TYPE_MAX } peripheral_bus_type_t; diff --git a/idf_component.yml b/idf_component.yml index c9c0342647b..2a76aec4d81 100644 --- a/idf_component.yml +++ b/idf_component.yml @@ -45,6 +45,7 @@ dependencies: idf: ">=5.1" # mdns 1.2.1 is necessary to build H2 with no WiFi mdns: "^1.2.3" + espressif/esp_modem: "^1.1.0" chmorgan/esp-libhelix-mp3: version: "1.0.3" require: public diff --git a/libraries/Network/src/NetworkEvents.cpp b/libraries/Network/src/NetworkEvents.cpp index a7955ee6cf2..f8ff3e9544c 100644 --- a/libraries/Network/src/NetworkEvents.cpp +++ b/libraries/Network/src/NetworkEvents.cpp @@ -319,16 +319,14 @@ const char *NetworkEvents::eventName(arduino_event_id_t id) { case ARDUINO_EVENT_ETH_DISCONNECTED: return "ETH_DISCONNECTED"; case ARDUINO_EVENT_ETH_GOT_IP: return "ETH_GOT_IP"; case ARDUINO_EVENT_ETH_LOST_IP: return "ETH_LOST_IP"; - case ARDUINO_EVENT_ETH_GOT_IP6: - return "ETH_GOT_IP6"; - - // case ARDUINO_EVENT_PPP_START: return "PPP_START"; - // case ARDUINO_EVENT_PPP_STOP: return "PPP_STOP"; - // case ARDUINO_EVENT_PPP_CONNECTED: return "PPP_CONNECTED"; - // case ARDUINO_EVENT_PPP_DISCONNECTED: return "PPP_DISCONNECTED"; - // case ARDUINO_EVENT_PPP_GOT_IP: return "PPP_GOT_IP"; - // case ARDUINO_EVENT_PPP_LOST_IP: return "PPP_LOST_IP"; - // case ARDUINO_EVENT_PPP_GOT_IP6: return "PPP_GOT_IP6"; + case ARDUINO_EVENT_ETH_GOT_IP6: return "ETH_GOT_IP6"; + case ARDUINO_EVENT_PPP_START: return "PPP_START"; + case ARDUINO_EVENT_PPP_STOP: return "PPP_STOP"; + case ARDUINO_EVENT_PPP_CONNECTED: return "PPP_CONNECTED"; + case ARDUINO_EVENT_PPP_DISCONNECTED: return "PPP_DISCONNECTED"; + case ARDUINO_EVENT_PPP_GOT_IP: return "PPP_GOT_IP"; + case ARDUINO_EVENT_PPP_LOST_IP: return "PPP_LOST_IP"; + case ARDUINO_EVENT_PPP_GOT_IP6: return "PPP_GOT_IP6"; #if SOC_WIFI_SUPPORTED case ARDUINO_EVENT_WIFI_OFF: return "WIFI_OFF"; case ARDUINO_EVENT_WIFI_READY: return "WIFI_READY"; diff --git a/libraries/Network/src/NetworkEvents.h b/libraries/Network/src/NetworkEvents.h index 2d6042461fc..ffa0070f96b 100644 --- a/libraries/Network/src/NetworkEvents.h +++ b/libraries/Network/src/NetworkEvents.h @@ -78,13 +78,13 @@ typedef enum { ARDUINO_EVENT_PROV_CRED_FAIL, ARDUINO_EVENT_PROV_CRED_SUCCESS, #endif - // ARDUINO_EVENT_PPP_START, - // ARDUINO_EVENT_PPP_STOP, - // ARDUINO_EVENT_PPP_CONNECTED, - // ARDUINO_EVENT_PPP_DISCONNECTED, - // ARDUINO_EVENT_PPP_GOT_IP, - // ARDUINO_EVENT_PPP_LOST_IP, - // ARDUINO_EVENT_PPP_GOT_IP6, + ARDUINO_EVENT_PPP_START, + ARDUINO_EVENT_PPP_STOP, + ARDUINO_EVENT_PPP_CONNECTED, + ARDUINO_EVENT_PPP_DISCONNECTED, + ARDUINO_EVENT_PPP_GOT_IP, + ARDUINO_EVENT_PPP_LOST_IP, + ARDUINO_EVENT_PPP_GOT_IP6, ARDUINO_EVENT_MAX } arduino_event_id_t; @@ -146,6 +146,7 @@ class NetworkEvents { friend class ESP_NetworkInterface; friend class ETHClass; + friend class PPPClass; #if SOC_WIFI_SUPPORTED friend class STAClass; friend class APClass; diff --git a/libraries/Network/src/NetworkInterface.cpp b/libraries/Network/src/NetworkInterface.cpp index 37e30900804..d9429638bcf 100644 --- a/libraries/Network/src/NetworkInterface.cpp +++ b/libraries/Network/src/NetworkInterface.cpp @@ -71,9 +71,9 @@ void NetworkInterface::_onIpEvent(int32_t event_id, void* event_data) { arduino_event.event_id = ARDUINO_EVENT_WIFI_STA_GOT_IP; } else #endif - // if(_interface_id == ESP_NETIF_ID_PPP){ - // arduino_event.event_id = ARDUINO_EVENT_PPP_GOT_IP; - // } else + if(_interface_id == ESP_NETIF_ID_PPP){ + arduino_event.event_id = ARDUINO_EVENT_PPP_GOT_IP; + } else if (_interface_id >= ESP_NETIF_ID_ETH && _interface_id < ESP_NETIF_ID_MAX) { arduino_event.event_id = ARDUINO_EVENT_ETH_GOT_IP; } @@ -87,9 +87,9 @@ void NetworkInterface::_onIpEvent(int32_t event_id, void* event_data) { arduino_event.event_id = ARDUINO_EVENT_WIFI_STA_LOST_IP; } else #endif - // if(_interface_id == ESP_NETIF_ID_PPP){ - // arduino_event.event_id = ARDUINO_EVENT_PPP_LOST_IP; - // } else + if(_interface_id == ESP_NETIF_ID_PPP){ + arduino_event.event_id = ARDUINO_EVENT_PPP_LOST_IP; + } else if (_interface_id >= ESP_NETIF_ID_ETH && _interface_id < ESP_NETIF_ID_MAX) { arduino_event.event_id = ARDUINO_EVENT_ETH_LOST_IP; } @@ -117,9 +117,9 @@ void NetworkInterface::_onIpEvent(int32_t event_id, void* event_data) { arduino_event.event_id = ARDUINO_EVENT_WIFI_AP_GOT_IP6; } else #endif - // if(_interface_id == ESP_NETIF_ID_PPP){ - // arduino_event.event_id = ARDUINO_EVENT_PPP_GOT_IP6; - // } else + if(_interface_id == ESP_NETIF_ID_PPP){ + arduino_event.event_id = ARDUINO_EVENT_PPP_GOT_IP6; + } else if (_interface_id >= ESP_NETIF_ID_ETH && _interface_id < ESP_NETIF_ID_MAX) { arduino_event.event_id = ARDUINO_EVENT_ETH_GOT_IP6; } @@ -536,7 +536,7 @@ String NetworkInterface::impl_name(void) const { char netif_name[8]; esp_err_t err = esp_netif_get_netif_impl_name(_esp_netif, netif_name); if (err != ESP_OK) { - log_e("Failed to get netif impl_name: %d", err); + log_e("Failed to get netif impl_name: 0x%04x %s", err, esp_err_to_name(err)); return String(""); } return String(netif_name); @@ -562,7 +562,7 @@ bool NetworkInterface::setDefault() { } esp_err_t err = esp_netif_set_default_netif(_esp_netif); if (err != ESP_OK) { - log_e("Failed to set default netif: %d", err); + log_e("Failed to set default netif: 0x%04x %s", err, esp_err_to_name(err)); return false; } return true; @@ -576,15 +576,14 @@ bool NetworkInterface::isDefault() const { } uint8_t* NetworkInterface::macAddress(uint8_t* mac) const { - if (!mac || _esp_netif == NULL) { + if (!mac || _esp_netif == NULL || _interface_id == ESP_NETIF_ID_PPP) { return NULL; } esp_err_t err = esp_netif_get_mac(_esp_netif, mac); if (err != ESP_OK) { - log_e("Failed to get netif mac: %d", err); + log_e("Failed to get netif mac: 0x%04x %s", err, esp_err_to_name(err)); return NULL; } - // getMac(mac); return mac; } diff --git a/libraries/PPP/examples/PPP_Basic/PPP_Basic.ino b/libraries/PPP/examples/PPP_Basic/PPP_Basic.ino new file mode 100644 index 00000000000..78fda9d18bf --- /dev/null +++ b/libraries/PPP/examples/PPP_Basic/PPP_Basic.ino @@ -0,0 +1,131 @@ +#include + +#define PPP_MODEM_APN "internet" +#define PPP_MODEM_PIN "0000" // or NULL + +// WaveShare SIM7600 HW Flow Control +#define PPP_MODEM_RST 25 +#define PPP_MODEM_RST_LOW false //active HIGH +#define PPP_MODEM_TX 21 +#define PPP_MODEM_RX 22 +#define PPP_MODEM_RTS 26 +#define PPP_MODEM_CTS 27 +#define PPP_MODEM_FC ESP_MODEM_FLOW_CONTROL_HW +#define PPP_MODEM_MODEL PPP_MODEM_SIM7600 + +// SIM800 basic module with just TX,RX and RST +// #define PPP_MODEM_RST 0 +// #define PPP_MODEM_RST_LOW true //active LOW +// #define PPP_MODEM_TX 2 +// #define PPP_MODEM_RX 19 +// #define PPP_MODEM_RTS -1 +// #define PPP_MODEM_CTS -1 +// #define PPP_MODEM_FC ESP_MODEM_FLOW_CONTROL_NONE +// #define PPP_MODEM_MODEL PPP_MODEM_SIM800 + +void onEvent(arduino_event_id_t event, arduino_event_info_t info) +{ + switch (event) { + case ARDUINO_EVENT_PPP_START: + Serial.println("PPP Started"); + break; + case ARDUINO_EVENT_PPP_CONNECTED: + Serial.println("PPP Connected"); + break; + case ARDUINO_EVENT_PPP_GOT_IP: + Serial.println("PPP Got IP"); + break; + case ARDUINO_EVENT_PPP_LOST_IP: + Serial.println("PPP Lost IP"); + break; + case ARDUINO_EVENT_PPP_DISCONNECTED: + Serial.println("PPP Disconnected"); + break; + case ARDUINO_EVENT_PPP_STOP: + Serial.println("PPP Stopped"); + break; + default: + break; + } +} + +void testClient(const char * host, uint16_t port) { + NetworkClient client; + if (!client.connect(host, port)) { + Serial.println("Connection Failed"); + return; + } + client.printf("GET / HTTP/1.1\r\nHost: %s\r\n\r\n", host); + while (client.connected() && !client.available()); + while (client.available()) { + client.read();//Serial.write(client.read()); + } + + Serial.println("Connection Success"); + client.stop(); +} + +void setup() { + Serial.begin(115200); + + // Listen for modem events + Network.onEvent(onEvent); + + // Configure the modem + PPP.setApn(PPP_MODEM_APN); + PPP.setPin(PPP_MODEM_PIN); + PPP.setResetPin(PPP_MODEM_RST, PPP_MODEM_RST_LOW); + PPP.setPins(PPP_MODEM_TX, PPP_MODEM_RX, PPP_MODEM_RTS, PPP_MODEM_CTS, PPP_MODEM_FC); + + Serial.println("Starting the modem. It might take a while!"); + PPP.begin(PPP_MODEM_MODEL); + + Serial.print("Manufacturer: "); Serial.println(PPP.cmd("AT+CGMI", 10000)); + Serial.print("Model: "); Serial.println(PPP.moduleName()); + Serial.print("IMEI: "); Serial.println(PPP.IMEI()); + + bool attached = PPP.attached(); + if(!attached){ + int i=0; + unsigned int s = millis(); + Serial.print("Waiting to connect to network"); + while(!attached && ((++i) < 600)){ + Serial.print("."); + delay(100); + attached = PPP.attached(); + } + Serial.print((millis() - s) / 1000.0, 1); + Serial.println("s"); + attached = PPP.attached(); + } + + Serial.print("Attached: "); Serial.println(attached); + Serial.print("State: "); Serial.println(PPP.radioState()); + if(attached){ + Serial.print("Operator: "); Serial.println(PPP.operatorName()); + Serial.print("IMSI: "); Serial.println(PPP.IMSI()); + Serial.print("RSSI: "); Serial.println(PPP.RSSI()); + int ber = PPP.BER(); + if(ber > 0){ + Serial.print("BER: "); Serial.println(ber); + Serial.print("NetMode: "); Serial.println(PPP.networkMode()); + } + + Serial.println("Switching to data mode..."); + PPP.mode(ESP_MODEM_MODE_CMUX); // Data and Command mixed mode + if(!PPP.waitStatusBits(ESP_NETIF_CONNECTED_BIT, 1000)){ + Serial.println("Failed to connect to internet!"); + } else { + Serial.println("Connected to internet!"); + } + } else { + Serial.println("Failed to connect to network!"); + } +} + +void loop() { + if (PPP.connected()) { + testClient("google.com", 80); + } + delay(20000); +} diff --git a/libraries/PPP/library.properties b/libraries/PPP/library.properties new file mode 100644 index 00000000000..abc4fb21a71 --- /dev/null +++ b/libraries/PPP/library.properties @@ -0,0 +1,9 @@ +name=PPP +version=1.0.0 +author=Hristo Gochkov +maintainer=Hristo Gochkov +sentence=Enables network connection using GSM Modem. +paragraph=With this library you can instantiate Servers, Clients and send/receive UDP packets through GSM Modem. +category=Communication +url= +architectures=esp32 diff --git a/libraries/PPP/src/PPP.cpp b/libraries/PPP/src/PPP.cpp new file mode 100644 index 00000000000..6227fcf7f12 --- /dev/null +++ b/libraries/PPP/src/PPP.cpp @@ -0,0 +1,817 @@ +#define ARDUINO_CORE_BUILD +#include "PPP.h" +#if CONFIG_LWIP_PPP_SUPPORT +#include "esp32-hal-periman.h" +#include "esp_netif.h" +#include "esp_netif_ppp.h" +#include +#include "driver/uart.h" +#include "hal/uart_ll.h" + +typedef struct { void * arg; } PdpContext; +#include "esp_modem_api.h" + +// Because of how esp_modem functions are declared, we need to workaround some APIs that take strings as input (output works OK) +// Following APIs work only when called through this interface +extern "C" { + esp_err_t _esp_modem_at(esp_modem_dce_t *dce_wrap, const char *at, char *p_out, int timeout); + esp_err_t _esp_modem_at_raw(esp_modem_dce_t *dce_wrap, const char *cmd, char *p_out, const char *pass, const char *fail, int timeout); + esp_err_t _esp_modem_send_sms(esp_modem_dce_t *dce_wrap, const char *number, const char *message); + esp_err_t _esp_modem_set_pin(esp_modem_dce_t *dce_wrap, const char *pin); + esp_err_t _esp_modem_set_operator(esp_modem_dce_t *dce_wrap, int mode, int format, const char *oper); + esp_err_t _esp_modem_set_network_bands(esp_modem_dce_t *dce_wrap, const char *mode, const int *bands, int size); +}; + +static PPPClass * _esp_modem = NULL; +static esp_event_handler_instance_t _ppp_ev_instance = NULL; + +#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_VERBOSE +static const char * _ppp_event_name(int32_t event_id){ + switch(event_id){ + case NETIF_PPP_ERRORNONE : return "No error."; + case NETIF_PPP_ERRORPARAM : return "Invalid parameter."; + case NETIF_PPP_ERROROPEN : return "Unable to open PPP session."; + case NETIF_PPP_ERRORDEVICE : return "Invalid I/O device for PPP."; + case NETIF_PPP_ERRORALLOC : return "Unable to allocate resources."; + case NETIF_PPP_ERRORUSER : return "User interrupt."; + case NETIF_PPP_ERRORCONNECT : return "Connection lost."; + case NETIF_PPP_ERRORAUTHFAIL : return "Failed authentication challenge."; + case NETIF_PPP_ERRORPROTOCOL : return "Failed to meet protocol."; + case NETIF_PPP_ERRORPEERDEAD : return "Connection timeout"; + case NETIF_PPP_ERRORIDLETIMEOUT : return "Idle Timeout"; + case NETIF_PPP_ERRORCONNECTTIME : return "Max connect time reached"; + case NETIF_PPP_ERRORLOOPBACK : return "Loopback detected"; + case NETIF_PPP_PHASE_DEAD : return "Phase Dead"; + case NETIF_PPP_PHASE_MASTER : return "Phase Master"; + case NETIF_PPP_PHASE_HOLDOFF : return "Phase Hold Off"; + case NETIF_PPP_PHASE_INITIALIZE : return "Phase Initialize"; + case NETIF_PPP_PHASE_SERIALCONN : return "Phase Serial Conn"; + case NETIF_PPP_PHASE_DORMANT : return "Phase Dormant"; + case NETIF_PPP_PHASE_ESTABLISH : return "Phase Establish"; + case NETIF_PPP_PHASE_AUTHENTICATE: return "Phase Authenticate"; + case NETIF_PPP_PHASE_CALLBACK : return "Phase Callback"; + case NETIF_PPP_PHASE_NETWORK : return "Phase Network"; + case NETIF_PPP_PHASE_RUNNING : return "Phase Running"; + case NETIF_PPP_PHASE_TERMINATE : return "Phase Terminate"; + case NETIF_PPP_PHASE_DISCONNECT : return "Phase Disconnect"; + case NETIF_PPP_CONNECT_FAILED : return "Connect Failed"; + default: break; + } + return "UNKNOWN"; +} + +static const char * _ppp_terminal_error_name(esp_modem_terminal_error_t err){ + switch(err){ + case ESP_MODEM_TERMINAL_BUFFER_OVERFLOW: return "Buffer Overflow"; + case ESP_MODEM_TERMINAL_CHECKSUM_ERROR: return "Checksum Error"; + case ESP_MODEM_TERMINAL_UNEXPECTED_CONTROL_FLOW: return "Unexpected Control Flow"; + case ESP_MODEM_TERMINAL_DEVICE_GONE: return "Device Gone"; + case ESP_MODEM_TERMINAL_UNKNOWN_ERROR: return "Unknown Error"; + default: break; + } + return "UNKNOWN"; +} +#endif + +static void _ppp_event_cb(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data) { + if (event_base == NETIF_PPP_STATUS){ + if(_esp_modem != NULL){ + _esp_modem->_onPppEvent(event_id, event_data); + } + } +} + +static void onPppArduinoEvent(arduino_event_id_t event, arduino_event_info_t info) +{ + if(event >= ARDUINO_EVENT_PPP_START && event <= ARDUINO_EVENT_PPP_GOT_IP6){ + _esp_modem->_onPppArduinoEvent(event, info); + } +} + +// PPP Error Callback +static void _ppp_error_cb(esp_modem_terminal_error_t err){ + log_v("PPP Driver Error %ld: %s", err, _ppp_terminal_error_name(err)); +} + +// PPP Arduino Events Callback +void PPPClass::_onPppArduinoEvent(arduino_event_id_t event, arduino_event_info_t info){ + log_v("PPP Arduino Event %ld: %s", event, Network.eventName(event)); + // if(event == ARDUINO_EVENT_PPP_GOT_IP){ + // if((getStatusBits() & ESP_NETIF_CONNECTED_BIT) == 0){ + // setStatusBits(ESP_NETIF_CONNECTED_BIT); + // arduino_event_t arduino_event; + // arduino_event.event_id = ARDUINO_EVENT_PPP_CONNECTED; + // Network.postEvent(&arduino_event); + // } + // } else + if(event == ARDUINO_EVENT_PPP_LOST_IP){ + if((getStatusBits() & ESP_NETIF_CONNECTED_BIT) != 0){ + clearStatusBits(ESP_NETIF_CONNECTED_BIT); + arduino_event_t arduino_event; + arduino_event.event_id = ARDUINO_EVENT_PPP_DISCONNECTED; + Network.postEvent(&arduino_event); + } + } +} + +// PPP Driver Events Callback +void PPPClass::_onPppEvent(int32_t event, void* event_data){ + arduino_event_t arduino_event; + arduino_event.event_id = ARDUINO_EVENT_MAX; + + log_v("PPP Driver Event %ld: %s", event, _ppp_event_name(event)); + + if(event == NETIF_PPP_ERRORNONE){ + if((getStatusBits() & ESP_NETIF_CONNECTED_BIT) == 0){ + setStatusBits(ESP_NETIF_CONNECTED_BIT); + arduino_event_t arduino_event; + arduino_event.event_id = ARDUINO_EVENT_PPP_CONNECTED; + Network.postEvent(&arduino_event); + } + } + + if(arduino_event.event_id < ARDUINO_EVENT_MAX){ + Network.postEvent(&arduino_event); + } +} + +esp_modem_dce_t * PPPClass::handle() const { + return _dce; +} + +PPPClass::PPPClass() + :_dce(NULL) + ,_pin_tx(-1) + ,_pin_rx(-1) + ,_pin_rts(-1) + ,_pin_cts(-1) + ,_flow_ctrl(ESP_MODEM_FLOW_CONTROL_NONE) + ,_pin_rst(-1) + ,_pin_rst_act_low(true) + ,_pin(NULL) + ,_apn(NULL) + ,_rx_buffer_size(4096) + ,_tx_buffer_size(512) + ,_mode(ESP_MODEM_MODE_COMMAND) + ,_uart_num(UART_NUM_1) +{ +} + +PPPClass::~PPPClass() +{} + +bool PPPClass::pppDetachBus(void * bus_pointer){ + PPPClass *bus = (PPPClass *) bus_pointer; + bus->end(); + return true; +} + +void PPPClass::setResetPin(int8_t rst, bool active_low){ + _pin_rst = digitalPinToGPIONumber(rst); + _pin_rst_act_low = active_low; +} + +bool PPPClass::setPins(int8_t tx, int8_t rx, int8_t rts, int8_t cts, esp_modem_flow_ctrl_t flow_ctrl){ + perimanSetBusDeinit(ESP32_BUS_TYPE_PPP_TX, PPPClass::pppDetachBus); + perimanSetBusDeinit(ESP32_BUS_TYPE_PPP_RX, PPPClass::pppDetachBus); + perimanSetBusDeinit(ESP32_BUS_TYPE_PPP_RTS, PPPClass::pppDetachBus); + perimanSetBusDeinit(ESP32_BUS_TYPE_PPP_CTS, PPPClass::pppDetachBus); + + if(_pin_tx >= 0){ + if(!perimanClearPinBus(_pin_tx)){ return false; } + } + if(_pin_rx >= 0){ + if(!perimanClearPinBus(_pin_rx)){ return false; } + } + if(_pin_rts >= 0){ + if(!perimanClearPinBus(_pin_rts)){ return false; } + } + if(_pin_cts >= 0){ + if(!perimanClearPinBus(_pin_cts)){ return false; } + } + + _flow_ctrl = flow_ctrl; + _pin_tx = digitalPinToGPIONumber(tx); + _pin_rx = digitalPinToGPIONumber(rx); + _pin_rts = digitalPinToGPIONumber(rts); + _pin_cts = digitalPinToGPIONumber(cts); + + if(_pin_tx >= 0){ + if(!perimanSetPinBus(_pin_tx, ESP32_BUS_TYPE_PPP_TX, (void *)(this), -1, -1)){ return false; } + } + if(_pin_rx >= 0){ + if(!perimanSetPinBus(_pin_rx, ESP32_BUS_TYPE_PPP_RX, (void *)(this), -1, -1)){ return false; } + } + if(_pin_rts >= 0){ + if(!perimanSetPinBus(_pin_rts, ESP32_BUS_TYPE_PPP_RTS, (void *)(this), -1, -1)){ return false; } + } + if(_pin_cts >= 0){ + if(!perimanSetPinBus(_pin_cts, ESP32_BUS_TYPE_PPP_CTS, (void *)(this), -1, -1)){ return false; } + } + return true; +} + +bool PPPClass::begin(ppp_modem_model_t model, uint8_t uart_num, int baud_rate){ + esp_err_t ret = ESP_OK; + bool pin_ok = false; + int trys = 0; + + if(_esp_netif != NULL || _dce != NULL){ + log_w("PPP Already Started"); + return true; + } + + if(_apn == NULL){ + log_e("APN is not set. Call 'PPP.setApn()' first"); + return false; + } + + if(_pin_tx < 0 || _pin_rx < 0){ + log_e("UART pins not set. Call 'PPP.setPins()' first"); + return false; + } + + if((_pin_rts < 0 || _pin_cts < 0) && (_flow_ctrl != ESP_MODEM_FLOW_CONTROL_NONE)){ + log_e("UART CTS/RTS pins not set, but flow control is enabled!"); + return false; + } + + _uart_num = uart_num; + _esp_modem = this; + + Network.begin(); + + /* Listen for PPP status events */ + if(_ppp_ev_instance == NULL && esp_event_handler_instance_register(NETIF_PPP_STATUS, ESP_EVENT_ANY_ID, &_ppp_event_cb, NULL, &_ppp_ev_instance)){ + log_e("event_handler_instance_register for NETIF_PPP_STATUS Failed!"); + return false; + } + + /* Configure the PPP netif */ + esp_netif_config_t cfg = ESP_NETIF_DEFAULT_PPP(); + _esp_netif = esp_netif_new(&cfg); + if(_esp_netif == NULL){ + log_e("esp_netif_new failed"); + return false; + } + + /* Attach to receive IP events */ + initNetif(ESP_NETIF_ID_PPP); + + /* Configure the DTE */ + esp_modem_dte_config_t dte_config = ESP_MODEM_DTE_DEFAULT_CONFIG(); + dte_config.uart_config.tx_io_num = _pin_tx; + dte_config.uart_config.rx_io_num = _pin_rx; + dte_config.uart_config.rts_io_num = _pin_rts; + dte_config.uart_config.cts_io_num = _pin_cts; + dte_config.uart_config.flow_control = _flow_ctrl; + dte_config.uart_config.rx_buffer_size = _rx_buffer_size; + dte_config.uart_config.tx_buffer_size = _tx_buffer_size; + dte_config.uart_config.port_num = _uart_num; + dte_config.uart_config.baud_rate = baud_rate; + + /* Configure the DCE */ + esp_modem_dce_config_t dce_config = ESP_MODEM_DCE_DEFAULT_CONFIG(_apn); + + /* Reset the Modem */ + if(_pin_rst >= 0){ + log_v("Resetting the modem"); + if(_pin_rst_act_low){ + pinMode(_pin_rst, OUTPUT_OPEN_DRAIN); + } else { + pinMode(_pin_rst, OUTPUT); + } + digitalWrite(_pin_rst, !_pin_rst_act_low); + delay(200); + digitalWrite(_pin_rst, _pin_rst_act_low); + delay(100); + } + + /* Start the DCE */ + _dce = esp_modem_new_dev((esp_modem_dce_device_t)model, &dte_config, &dce_config, _esp_netif); + if(_dce == NULL){ + log_e("esp_modem_new_dev failed"); + goto err; + } + + esp_modem_set_error_cb(_dce, _ppp_error_cb); + + /* Wait for Modem to respond */ + if(_pin_rst >= 0){ + // wait to be able to talk to the modem + log_v("Waiting for response from the modem"); + while(esp_modem_sync(_dce) != ESP_OK && trys < 100){ + trys++; + delay(500); + } + if(trys >= 100){ + log_e("Failed to wait for communication"); + goto err; + } + } else { + // try to communicate with the modem + if(esp_modem_sync(_dce) != ESP_OK){ + log_v("Modem does not respond to AT, maybe in DATA mode? ...exiting network mode"); + esp_modem_set_mode(_dce, ESP_MODEM_MODE_COMMAND); + if(esp_modem_sync(_dce) != ESP_OK){ + log_e("Modem failed to respond to AT!"); + goto err; + } + } + } + + /* enable flow control */ + if (dte_config.uart_config.flow_control == ESP_MODEM_FLOW_CONTROL_HW) { + ret = esp_modem_set_flow_control(_dce, 2, 2); //2/2 means HW Flow Control. + if (ret != ESP_OK) { + log_e("Failed to set the hardware flow control: [%d] %s", ret, esp_err_to_name(ret)); + goto err; + } + } + + /* check if PIN needed */ + if (esp_modem_read_pin(_dce, pin_ok) == ESP_OK && pin_ok == false) { + if (_pin == NULL || _esp_modem_set_pin(_dce, _pin) != ESP_OK) { + log_e("PIN verification failed!"); + goto err; + } + } + + Network.onSysEvent(onPppArduinoEvent); + + setStatusBits(ESP_NETIF_STARTED_BIT); + arduino_event_t arduino_event; + arduino_event.event_id = ARDUINO_EVENT_PPP_START; + Network.postEvent(&arduino_event); + + return true; + +err: + PPPClass::pppDetachBus((void *)(this)); + return false; +} + +void PPPClass::end(void) +{ + if(_esp_modem && _esp_netif && _dce){ + + if((getStatusBits() & ESP_NETIF_CONNECTED_BIT) != 0){ + clearStatusBits(ESP_NETIF_CONNECTED_BIT | ESP_NETIF_HAS_IP_BIT | ESP_NETIF_HAS_LOCAL_IP6_BIT | ESP_NETIF_HAS_GLOBAL_IP6_BIT); + arduino_event_t disconnect_event; + disconnect_event.event_id = ARDUINO_EVENT_PPP_DISCONNECTED; + Network.postEvent(&disconnect_event); + } + + clearStatusBits(ESP_NETIF_STARTED_BIT | ESP_NETIF_CONNECTED_BIT | ESP_NETIF_HAS_IP_BIT | ESP_NETIF_HAS_LOCAL_IP6_BIT | ESP_NETIF_HAS_GLOBAL_IP6_BIT | ESP_NETIF_HAS_STATIC_IP_BIT); + arduino_event_t arduino_event; + arduino_event.event_id = ARDUINO_EVENT_PPP_STOP; + Network.postEvent(&arduino_event); + } + + destroyNetif(); + + if(_ppp_ev_instance != NULL){ + if(esp_event_handler_unregister(NETIF_PPP_STATUS, ESP_EVENT_ANY_ID, &_ppp_event_cb) == ESP_OK){ + _ppp_ev_instance = NULL; + } + } + _esp_modem = NULL; + + Network.removeEvent(onPppArduinoEvent); + + if(_dce != NULL){ + esp_modem_destroy(_dce); + _dce = NULL; + } + + int8_t pin = -1; + if(_pin_tx != -1){ + pin = _pin_tx; + _pin_tx = -1; + perimanClearPinBus(pin); + } + if(_pin_rx != -1){ + pin = _pin_rx; + _pin_rx = -1; + perimanClearPinBus(pin); + } + if(_pin_rts != -1){ + pin = _pin_rts; + _pin_rts = -1; + perimanClearPinBus(pin); + } + if(_pin_cts != -1){ + pin = _pin_cts; + _pin_cts = -1; + perimanClearPinBus(pin); + } + + _mode = ESP_MODEM_MODE_COMMAND; +} + +bool PPPClass::sync() const +{ + if(_dce == NULL){ + return false; + } + + if(_mode == ESP_MODEM_MODE_DATA){ + log_e("Wrong modem mode. Should be ESP_MODEM_MODE_COMMAND"); + return false; + } + return esp_modem_sync(_dce) == ESP_OK; +} + +bool PPPClass::attached() const +{ + if(_dce == NULL){ + return false; + } + + if(_mode == ESP_MODEM_MODE_DATA){ + log_e("Wrong modem mode. Should be ESP_MODEM_MODE_COMMAND"); + return false; + } + + int m = 0; + esp_err_t err = esp_modem_get_network_attachment_state(_dce, m); + if (err != ESP_OK) { + // log_e("esp_modem_get_network_attachment_state failed with %d %s", err, esp_err_to_name(err)); + return false; + } + return m != 0; +} + +bool PPPClass::mode(esp_modem_dce_mode_t m){ + if(_dce == NULL){ + return 0; + } + + if(_mode == m){ + return true; + } + esp_err_t err = esp_modem_set_mode(_dce, m); + if (err != ESP_OK) { + log_e("esp_modem_set_mode failed with %d %s", err, esp_err_to_name(err)); + return false; + } + _mode = m; + return true; +} + +bool PPPClass::setApn(const char * apn){ + if(_apn != NULL){ + free((void *)_apn); + _apn = NULL; + } + if(apn != NULL){ + _apn = strdup(apn); + if(_apn == NULL){ + log_e("Failed to strdup APN"); + return false; + } + } + return true; +} + +bool PPPClass::setPin(const char * pin){ + if(_pin != NULL){ + free((void *)_pin); + _pin = NULL; + } + if(pin != NULL){ + for(int i=0; i 0x39){ + log_e("Bad character '%c' in PIN. Should be only digits", pin[i]); + return false; + } + } + _pin = strdup(pin); + if(_pin == NULL){ + log_e("Failed to strdup PIN"); + return false; + } + } + return true; +} + +int PPPClass::RSSI() const +{ + if(_dce == NULL){ + return -1; + } + + if(_mode == ESP_MODEM_MODE_DATA){ + log_e("Wrong modem mode. Should be ESP_MODEM_MODE_COMMAND"); + return -1; + } + + int rssi, ber; + esp_err_t err = esp_modem_get_signal_quality(_dce, rssi, ber); + if (err != ESP_OK) { + // log_e("esp_modem_get_signal_quality failed with %d %s", err, esp_err_to_name(err)); + return -1; + } + return rssi; +} + +int PPPClass::BER() const +{ + if(_dce == NULL){ + return -1; + } + + if(_mode == ESP_MODEM_MODE_DATA){ + log_e("Wrong modem mode. Should be ESP_MODEM_MODE_COMMAND"); + return -1; + } + + int rssi, ber; + esp_err_t err = esp_modem_get_signal_quality(_dce, rssi, ber); + if (err != ESP_OK) { + // log_e("esp_modem_get_signal_quality failed with %d %s", err, esp_err_to_name(err)); + return -1; + } + return ber; +} + +String PPPClass::IMSI() const +{ + if(_dce == NULL){ + return String(); + } + + if(_mode == ESP_MODEM_MODE_DATA){ + log_e("Wrong modem mode. Should be ESP_MODEM_MODE_COMMAND"); + return String(); + } + + char imsi[32]; + esp_err_t err = esp_modem_get_imsi(_dce, (std::string&)imsi); + if (err != ESP_OK) { + log_e("esp_modem_get_imsi failed with %d %s", err, esp_err_to_name(err)); + return String(); + } + + return String(imsi); +} + +String PPPClass::IMEI() const +{ + if(_dce == NULL){ + return String(); + } + + if(_mode == ESP_MODEM_MODE_DATA){ + log_e("Wrong modem mode. Should be ESP_MODEM_MODE_COMMAND"); + return String(); + } + + char imei[32]; + esp_err_t err = esp_modem_get_imei(_dce, (std::string&)imei); + if (err != ESP_OK) { + log_e("esp_modem_get_imei failed with %d %s", err, esp_err_to_name(err)); + return String(); + } + + return String(imei); +} + +String PPPClass::moduleName() const +{ + if(_dce == NULL){ + return String(); + } + + if(_mode == ESP_MODEM_MODE_DATA){ + log_e("Wrong modem mode. Should be ESP_MODEM_MODE_COMMAND"); + return String(); + } + + char name[32]; + esp_err_t err = esp_modem_get_module_name(_dce, (std::string&)name); + if (err != ESP_OK) { + log_e("esp_modem_get_module_name failed with %d %s", err, esp_err_to_name(err)); + return String(); + } + + return String(name); +} + +String PPPClass::operatorName() const +{ + if(_dce == NULL){ + return String(); + } + + if(_mode == ESP_MODEM_MODE_DATA){ + log_e("Wrong modem mode. Should be ESP_MODEM_MODE_COMMAND"); + return String(); + } + + char oper[32]; + int act = 0; + esp_err_t err = esp_modem_get_operator_name(_dce, (std::string&)oper, act); + if (err != ESP_OK) { + log_e("esp_modem_get_operator_name failed with %d %s", err, esp_err_to_name(err)); + return String(); + } + + return String(oper); +} + +int PPPClass::networkMode() const +{ + if(_dce == NULL){ + return -1; + } + + if(_mode == ESP_MODEM_MODE_DATA){ + log_e("Wrong modem mode. Should be ESP_MODEM_MODE_COMMAND"); + return -1; + } + + int m = 0; + esp_err_t err = esp_modem_get_network_system_mode(_dce, m); + if (err != ESP_OK) { + log_e("esp_modem_get_network_system_mode failed with %d %s", err, esp_err_to_name(err)); + return -1; + } + return m; +} + +int PPPClass::radioState() const +{ + if(_dce == NULL){ + return -1; + } + + if(_mode == ESP_MODEM_MODE_DATA){ + log_e("Wrong modem mode. Should be ESP_MODEM_MODE_COMMAND"); + return -1; + } + + int m = 0; + esp_err_t err = esp_modem_get_radio_state(_dce, m); + if (err != ESP_OK) { + // log_e("esp_modem_get_radio_state failed with %d %s", err, esp_err_to_name(err)); + return -1; + } + return m; +} + +bool PPPClass::powerDown(){ + if(_dce == NULL){ + return false; + } + + if(_mode == ESP_MODEM_MODE_DATA){ + log_e("Wrong modem mode. Should be ESP_MODEM_MODE_COMMAND"); + return false; + } + + esp_err_t err = esp_modem_power_down(_dce); + if (err != ESP_OK) { + log_e("esp_modem_power_down failed with %d %s", err, esp_err_to_name(err)); + return false; + } + return true; +} + +bool PPPClass::reset(){ + if(_dce == NULL){ + return false; + } + + if(_mode == ESP_MODEM_MODE_DATA){ + log_e("Wrong modem mode. Should be ESP_MODEM_MODE_COMMAND"); + return false; + } + + esp_err_t err = esp_modem_reset(_dce); + if (err != ESP_OK) { + log_e("esp_modem_reset failed with %d %s", err, esp_err_to_name(err)); + return false; + } + return true; +} + +bool PPPClass::storeProfile(){ + if(_dce == NULL){ + return false; + } + + if(_mode == ESP_MODEM_MODE_DATA){ + log_e("Wrong modem mode. Should be ESP_MODEM_MODE_COMMAND"); + return false; + } + + esp_err_t err = esp_modem_store_profile(_dce); + if (err != ESP_OK) { + log_e("esp_modem_store_profile failed with %d %s", err, esp_err_to_name(err)); + return false; + } + return true; +} + +bool PPPClass::setBaudrate(int baudrate) { + if(_dce == NULL){ + return false; + } + + if(_mode == ESP_MODEM_MODE_DATA){ + log_e("Wrong modem mode. Should be ESP_MODEM_MODE_COMMAND"); + return false; + } + + esp_err_t err = esp_modem_set_baud(_dce, baudrate); + if (err != ESP_OK) { + log_e("esp_modem_set_baud failed with %d %s", err, esp_err_to_name(err)); + return false; + } + + uint32_t sclk_freq; + err = uart_get_sclk_freq(UART_SCLK_DEFAULT, &sclk_freq); + if(err != ESP_OK){ + log_e("uart_get_sclk_freq failed with %d %s", err, esp_err_to_name(err)); + return false; + } + uart_ll_set_baudrate(UART_LL_GET_HW(_uart_num), (uint32_t)baudrate, sclk_freq); + + return true; +} + +bool PPPClass::sms(const char * num, const char * message) { + if(_dce == NULL){ + return false; + } + + if(_mode == ESP_MODEM_MODE_DATA){ + log_e("Wrong modem mode. Should be ESP_MODEM_MODE_COMMAND"); + return false; + } + + for(int i=0; i 0x39)){ + log_e("Bad character '%c' in SMS Number. Should be only digits and +, # or *", num[i]); + return false; + } + } + + esp_err_t err = esp_modem_sms_txt_mode(_dce, true); + if (err != ESP_OK) { + log_e("Setting text mode failed %d %s", err, esp_err_to_name(err)); + return false; + } + + err = esp_modem_sms_character_set(_dce); + if (err != ESP_OK) { + log_e("Setting GSM character set failed %d %s", err, esp_err_to_name(err)); + return false; + } + + err = _esp_modem_send_sms(_dce, num, message); + if (err != ESP_OK) { + log_e("esp_modem_send_sms() failed with %d %s", err, esp_err_to_name(err)); + return false; + } + return true; +} + +String PPPClass::cmd(const char * at_command, int timeout){ + if(_dce == NULL){ + return String(); + } + + if(_mode == ESP_MODEM_MODE_DATA){ + log_e("Wrong modem mode. Should be ESP_MODEM_MODE_COMMAND"); + return String(); + } + char out[128] = {0}; + esp_err_t err = _esp_modem_at(_dce, at_command, out, timeout); + if (err != ESP_OK) { + log_e("esp_modem_at failed %d %s", err, esp_err_to_name(err)); + return String(); + } + return String(out); +} + +size_t PPPClass::printDriverInfo(Print & out) const { + size_t bytes = 0; + if(_dce == NULL || _mode == ESP_MODEM_MODE_DATA){ + return bytes; + } + if(attached()){ + bytes += out.print(","); + bytes += out.print(operatorName()); + } + bytes += out.print(",RSSI:"); + bytes += out.print(RSSI()); + bytes += out.print(",BER:"); + bytes += out.print(BER()); + return bytes; +} + +PPPClass PPP; + +#endif /* CONFIG_LWIP_PPP_SUPPORT */ diff --git a/libraries/PPP/src/PPP.h b/libraries/PPP/src/PPP.h new file mode 100644 index 00000000000..97ce62a5945 --- /dev/null +++ b/libraries/PPP/src/PPP.h @@ -0,0 +1,107 @@ +#pragma once + +#include "sdkconfig.h" +#if CONFIG_LWIP_PPP_SUPPORT +#include "Network.h" +#include "esp_modem_c_api_types.h" + +typedef enum { + PPP_MODEM_GENERIC = ESP_MODEM_DCE_GENETIC, + PPP_MODEM_SIM7600 = ESP_MODEM_DCE_SIM7600, + PPP_MODEM_SIM7070 = ESP_MODEM_DCE_SIM7070, + PPP_MODEM_SIM7000 = ESP_MODEM_DCE_SIM7000, + PPP_MODEM_BG96 = ESP_MODEM_DCE_BG96, + PPP_MODEM_SIM800 = ESP_MODEM_DCE_SIM800, +#if CONFIG_ESP_MODEM_ADD_CUSTOM_MODULE + PPP_MODEM_CUSTOM = ESP_MODEM_DCE_CUSTOM, +#endif + PPP_MODEM_MAX +} ppp_modem_model_t; + +class PPPClass: public NetworkInterface { + public: + PPPClass(); + ~PPPClass(); + + bool begin(ppp_modem_model_t model, uint8_t uart_num=1, int baud_rate=115200); + void end(); + + // Required for connecting to internet + bool setApn(const char * apn); + + // Required only if the SIM card is protected by PIN + bool setPin(const char * pin); + + // If the modem supports hardware flow control, it's best to use it + bool setPins(int8_t tx, int8_t rx, int8_t rts=-1, int8_t cts=-1, esp_modem_flow_ctrl_t flow_ctrl=ESP_MODEM_FLOW_CONTROL_NONE); + + // Using the reset pin of the module ensures that proper communication can be achieved + void setResetPin(int8_t rst, bool active_low=true); + + // Modem DCE APIs + int RSSI() const; + int BER() const; + String IMSI() const; + String IMEI() const; + String moduleName() const; // modem module name + String operatorName() const; // network operator name + int networkMode() const; // network type (GSM, LTE, etc.) + int radioState() const; // 0:minimal, 1:full + bool attached() const; // true is attached to network + bool sync() const; // true if responds to 'AT' + + // Switch the communication mode + bool mode(esp_modem_dce_mode_t m); + esp_modem_dce_mode_t mode() const { return _mode; } + + // Change temporary the baud rate of communication + bool setBaudrate(int baudrate); + + // Sens SMS message to a number + bool sms(const char * num, const char * message); + bool sms(String num, String message){ + return sms(num.c_str(), message.c_str()); + } + + // Send AT command with timeout in milliseconds + String cmd(const char * at_command, int timeout); + String cmd(String at_command, int timeout){ + return cmd(at_command.c_str(), timeout); + } + + // untested + bool powerDown(); + bool reset(); + bool storeProfile(); + + esp_modem_dce_t * handle() const; + + protected: + size_t printDriverInfo(Print & out) const; + + public: + void _onPppEvent(int32_t event_id, void* event_data); + void _onPppArduinoEvent(arduino_event_id_t event, arduino_event_info_t info); + + private: + esp_modem_dce_t *_dce; + int8_t _pin_tx; + int8_t _pin_rx; + int8_t _pin_rts; + int8_t _pin_cts; + esp_modem_flow_ctrl_t _flow_ctrl; + int8_t _pin_rst; + bool _pin_rst_act_low; + const char * _pin; + const char * _apn; + int _rx_buffer_size; + int _tx_buffer_size; + esp_modem_dce_mode_t _mode; + uint8_t _uart_num; + + static bool pppDetachBus(void * bus_pointer); +}; + +extern PPPClass PPP; + +#endif /* CONFIG_LWIP_PPP_SUPPORT */ diff --git a/libraries/PPP/src/ppp.c b/libraries/PPP/src/ppp.c new file mode 100644 index 00000000000..fafd6cc4525 --- /dev/null +++ b/libraries/PPP/src/ppp.c @@ -0,0 +1,28 @@ +#include "sdkconfig.h" +#if CONFIG_LWIP_PPP_SUPPORT +#include "esp_modem_api.h" + +esp_err_t _esp_modem_at(esp_modem_dce_t *dce_wrap, const char *at, char *p_out, int timeout){ + return esp_modem_at(dce_wrap, at, p_out, timeout); +} + +esp_err_t _esp_modem_send_sms(esp_modem_dce_t *dce_wrap, const char *number, const char *message){ + return esp_modem_send_sms(dce_wrap, number, message); +} + +esp_err_t _esp_modem_set_pin(esp_modem_dce_t *dce_wrap, const char *pin){ + return esp_modem_set_pin(dce_wrap, pin); +} + +esp_err_t _esp_modem_at_raw(esp_modem_dce_t *dce_wrap, const char *cmd, char *p_out, const char *pass, const char *fail, int timeout){ + return esp_modem_at_raw(dce_wrap, cmd, p_out, pass, fail, timeout); +} + +esp_err_t _esp_modem_set_operator(esp_modem_dce_t *dce_wrap, int mode, int format, const char *oper){ + return esp_modem_set_operator(dce_wrap, mode, format, oper); +} + +esp_err_t _esp_modem_set_network_bands(esp_modem_dce_t *dce_wrap, const char *mode, const int *bands, int size){ + return esp_modem_set_network_bands(dce_wrap, mode, bands, size); +} +#endif // CONFIG_LWIP_PPP_SUPPORT From 26e54eb3b1c65b1d7216ad556bbd9e3df5d68dad Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Mon, 15 Apr 2024 22:55:34 +0300 Subject: [PATCH 2/4] feat(sdk): Add libs with PPP enabled --- package/package_esp32_index.template.json | 68 +++++++++++------------ 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/package/package_esp32_index.template.json b/package/package_esp32_index.template.json index c8d48f1261e..ced6417798b 100644 --- a/package/package_esp32_index.template.json +++ b/package/package_esp32_index.template.json @@ -42,7 +42,7 @@ { "packager": "esp32", "name": "esp32-arduino-libs", - "version": "idf-release_v5.1-d23b7a0361" + "version": "idf--d23b7a0361" }, { "packager": "esp32", @@ -105,63 +105,63 @@ "tools": [ { "name": "esp32-arduino-libs", - "version": "idf-release_v5.1-d23b7a0361", + "version": "idf--d23b7a0361", "systems": [ { "host": "i686-mingw32", - "url": "https://codeload.github.com/espressif/esp32-arduino-libs/zip/0dbfb946a0af0e10f9caa0a22aa1ee4b5bd79799", - "archiveFileName": "esp32-arduino-libs-0dbfb946a0af0e10f9caa0a22aa1ee4b5bd79799.zip", - "checksum": "SHA-256:dae6b3bc63778977bf08a372630ba57dff217e9674fea85964c95da9f738f6f6", - "size": "359464912" + "url": "https://codeload.github.com/espressif/esp32-arduino-libs/zip/5daaf1a26c12b495975a367cf2c73b86ddee5d31", + "archiveFileName": "esp32-arduino-libs-5daaf1a26c12b495975a367cf2c73b86ddee5d31.zip", + "checksum": "SHA-256:6fe9a5643057449bbbe850cd0e7217f3f6753adc8d5da2807f0c071a1ccb44f1", + "size": "372257794" }, { "host": "x86_64-mingw32", - "url": "https://codeload.github.com/espressif/esp32-arduino-libs/zip/0dbfb946a0af0e10f9caa0a22aa1ee4b5bd79799", - "archiveFileName": "esp32-arduino-libs-0dbfb946a0af0e10f9caa0a22aa1ee4b5bd79799.zip", - "checksum": "SHA-256:dae6b3bc63778977bf08a372630ba57dff217e9674fea85964c95da9f738f6f6", - "size": "359464912" + "url": "https://codeload.github.com/espressif/esp32-arduino-libs/zip/5daaf1a26c12b495975a367cf2c73b86ddee5d31", + "archiveFileName": "esp32-arduino-libs-5daaf1a26c12b495975a367cf2c73b86ddee5d31.zip", + "checksum": "SHA-256:6fe9a5643057449bbbe850cd0e7217f3f6753adc8d5da2807f0c071a1ccb44f1", + "size": "372257794" }, { "host": "arm64-apple-darwin", - "url": "https://codeload.github.com/espressif/esp32-arduino-libs/zip/0dbfb946a0af0e10f9caa0a22aa1ee4b5bd79799", - "archiveFileName": "esp32-arduino-libs-0dbfb946a0af0e10f9caa0a22aa1ee4b5bd79799.zip", - "checksum": "SHA-256:dae6b3bc63778977bf08a372630ba57dff217e9674fea85964c95da9f738f6f6", - "size": "359464912" + "url": "https://codeload.github.com/espressif/esp32-arduino-libs/zip/5daaf1a26c12b495975a367cf2c73b86ddee5d31", + "archiveFileName": "esp32-arduino-libs-5daaf1a26c12b495975a367cf2c73b86ddee5d31.zip", + "checksum": "SHA-256:6fe9a5643057449bbbe850cd0e7217f3f6753adc8d5da2807f0c071a1ccb44f1", + "size": "372257794" }, { "host": "x86_64-apple-darwin", - "url": "https://codeload.github.com/espressif/esp32-arduino-libs/zip/0dbfb946a0af0e10f9caa0a22aa1ee4b5bd79799", - "archiveFileName": "esp32-arduino-libs-0dbfb946a0af0e10f9caa0a22aa1ee4b5bd79799.zip", - "checksum": "SHA-256:dae6b3bc63778977bf08a372630ba57dff217e9674fea85964c95da9f738f6f6", - "size": "359464912" + "url": "https://codeload.github.com/espressif/esp32-arduino-libs/zip/5daaf1a26c12b495975a367cf2c73b86ddee5d31", + "archiveFileName": "esp32-arduino-libs-5daaf1a26c12b495975a367cf2c73b86ddee5d31.zip", + "checksum": "SHA-256:6fe9a5643057449bbbe850cd0e7217f3f6753adc8d5da2807f0c071a1ccb44f1", + "size": "372257794" }, { "host": "x86_64-pc-linux-gnu", - "url": "https://codeload.github.com/espressif/esp32-arduino-libs/zip/0dbfb946a0af0e10f9caa0a22aa1ee4b5bd79799", - "archiveFileName": "esp32-arduino-libs-0dbfb946a0af0e10f9caa0a22aa1ee4b5bd79799.zip", - "checksum": "SHA-256:dae6b3bc63778977bf08a372630ba57dff217e9674fea85964c95da9f738f6f6", - "size": "359464912" + "url": "https://codeload.github.com/espressif/esp32-arduino-libs/zip/5daaf1a26c12b495975a367cf2c73b86ddee5d31", + "archiveFileName": "esp32-arduino-libs-5daaf1a26c12b495975a367cf2c73b86ddee5d31.zip", + "checksum": "SHA-256:6fe9a5643057449bbbe850cd0e7217f3f6753adc8d5da2807f0c071a1ccb44f1", + "size": "372257794" }, { "host": "i686-pc-linux-gnu", - "url": "https://codeload.github.com/espressif/esp32-arduino-libs/zip/0dbfb946a0af0e10f9caa0a22aa1ee4b5bd79799", - "archiveFileName": "esp32-arduino-libs-0dbfb946a0af0e10f9caa0a22aa1ee4b5bd79799.zip", - "checksum": "SHA-256:dae6b3bc63778977bf08a372630ba57dff217e9674fea85964c95da9f738f6f6", - "size": "359464912" + "url": "https://codeload.github.com/espressif/esp32-arduino-libs/zip/5daaf1a26c12b495975a367cf2c73b86ddee5d31", + "archiveFileName": "esp32-arduino-libs-5daaf1a26c12b495975a367cf2c73b86ddee5d31.zip", + "checksum": "SHA-256:6fe9a5643057449bbbe850cd0e7217f3f6753adc8d5da2807f0c071a1ccb44f1", + "size": "372257794" }, { "host": "aarch64-linux-gnu", - "url": "https://codeload.github.com/espressif/esp32-arduino-libs/zip/0dbfb946a0af0e10f9caa0a22aa1ee4b5bd79799", - "archiveFileName": "esp32-arduino-libs-0dbfb946a0af0e10f9caa0a22aa1ee4b5bd79799.zip", - "checksum": "SHA-256:dae6b3bc63778977bf08a372630ba57dff217e9674fea85964c95da9f738f6f6", - "size": "359464912" + "url": "https://codeload.github.com/espressif/esp32-arduino-libs/zip/5daaf1a26c12b495975a367cf2c73b86ddee5d31", + "archiveFileName": "esp32-arduino-libs-5daaf1a26c12b495975a367cf2c73b86ddee5d31.zip", + "checksum": "SHA-256:6fe9a5643057449bbbe850cd0e7217f3f6753adc8d5da2807f0c071a1ccb44f1", + "size": "372257794" }, { "host": "arm-linux-gnueabihf", - "url": "https://codeload.github.com/espressif/esp32-arduino-libs/zip/0dbfb946a0af0e10f9caa0a22aa1ee4b5bd79799", - "archiveFileName": "esp32-arduino-libs-0dbfb946a0af0e10f9caa0a22aa1ee4b5bd79799.zip", - "checksum": "SHA-256:dae6b3bc63778977bf08a372630ba57dff217e9674fea85964c95da9f738f6f6", - "size": "359464912" + "url": "https://codeload.github.com/espressif/esp32-arduino-libs/zip/5daaf1a26c12b495975a367cf2c73b86ddee5d31", + "archiveFileName": "esp32-arduino-libs-5daaf1a26c12b495975a367cf2c73b86ddee5d31.zip", + "checksum": "SHA-256:6fe9a5643057449bbbe850cd0e7217f3f6753adc8d5da2807f0c071a1ccb44f1", + "size": "372257794" } ] }, From e06719a532061ae3ee8d26a5c423aac32e30aad8 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci-lite[bot]" <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> Date: Mon, 15 Apr 2024 20:00:29 +0000 Subject: [PATCH 3/4] ci(pre-commit): Apply automatic fixes --- cores/esp32/esp32-hal-periman.h | 8 +- libraries/Network/src/NetworkInterface.cpp | 33 +- .../PPP/examples/PPP_Basic/PPP_Basic.ino | 82 +- libraries/PPP/src/PPP.cpp | 1383 ++++++++--------- libraries/PPP/src/PPP.h | 182 +-- libraries/PPP/src/ppp.c | 26 +- 6 files changed, 849 insertions(+), 865 deletions(-) diff --git a/cores/esp32/esp32-hal-periman.h b/cores/esp32/esp32-hal-periman.h index 8dda5f85781..c2d16017adb 100644 --- a/cores/esp32/esp32-hal-periman.h +++ b/cores/esp32/esp32-hal-periman.h @@ -104,10 +104,10 @@ extern "C" { ESP32_BUS_TYPE_ETHERNET_PWR, // IO is used as ETHERNET PWR pin #endif #if CONFIG_LWIP_PPP_SUPPORT - ESP32_BUS_TYPE_PPP_TX, // IO is used as PPP Modem TX pin - ESP32_BUS_TYPE_PPP_RX, // IO is used as PPP Modem RX pin - ESP32_BUS_TYPE_PPP_RTS, // IO is used as PPP Modem RTS pin - ESP32_BUS_TYPE_PPP_CTS, // IO is used as PPP Modem CTS pin + ESP32_BUS_TYPE_PPP_TX, // IO is used as PPP Modem TX pin + ESP32_BUS_TYPE_PPP_RX, // IO is used as PPP Modem RX pin + ESP32_BUS_TYPE_PPP_RTS, // IO is used as PPP Modem RTS pin + ESP32_BUS_TYPE_PPP_CTS, // IO is used as PPP Modem CTS pin #endif ESP32_BUS_TYPE_MAX } peripheral_bus_type_t; diff --git a/libraries/Network/src/NetworkInterface.cpp b/libraries/Network/src/NetworkInterface.cpp index d9429638bcf..46b06d9611a 100644 --- a/libraries/Network/src/NetworkInterface.cpp +++ b/libraries/Network/src/NetworkInterface.cpp @@ -71,12 +71,11 @@ void NetworkInterface::_onIpEvent(int32_t event_id, void* event_data) { arduino_event.event_id = ARDUINO_EVENT_WIFI_STA_GOT_IP; } else #endif - if(_interface_id == ESP_NETIF_ID_PPP){ - arduino_event.event_id = ARDUINO_EVENT_PPP_GOT_IP; - } else - if (_interface_id >= ESP_NETIF_ID_ETH && _interface_id < ESP_NETIF_ID_MAX) { - arduino_event.event_id = ARDUINO_EVENT_ETH_GOT_IP; - } + if (_interface_id == ESP_NETIF_ID_PPP) { + arduino_event.event_id = ARDUINO_EVENT_PPP_GOT_IP; + } else if (_interface_id >= ESP_NETIF_ID_ETH && _interface_id < ESP_NETIF_ID_MAX) { + arduino_event.event_id = ARDUINO_EVENT_ETH_GOT_IP; + } } else if (event_id == _lost_ip_event_id) { clearStatusBits(ESP_NETIF_HAS_IP_BIT); #if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_VERBOSE @@ -87,12 +86,11 @@ void NetworkInterface::_onIpEvent(int32_t event_id, void* event_data) { arduino_event.event_id = ARDUINO_EVENT_WIFI_STA_LOST_IP; } else #endif - if(_interface_id == ESP_NETIF_ID_PPP){ - arduino_event.event_id = ARDUINO_EVENT_PPP_LOST_IP; - } else - if (_interface_id >= ESP_NETIF_ID_ETH && _interface_id < ESP_NETIF_ID_MAX) { - arduino_event.event_id = ARDUINO_EVENT_ETH_LOST_IP; - } + if (_interface_id == ESP_NETIF_ID_PPP) { + arduino_event.event_id = ARDUINO_EVENT_PPP_LOST_IP; + } else if (_interface_id >= ESP_NETIF_ID_ETH && _interface_id < ESP_NETIF_ID_MAX) { + arduino_event.event_id = ARDUINO_EVENT_ETH_LOST_IP; + } } else if (event_id == IP_EVENT_GOT_IP6) { ip_event_got_ip6_t* event = (ip_event_got_ip6_t*)event_data; esp_ip6_addr_type_t addr_type = esp_netif_ip6_get_addr_type(&event->ip6_info.ip); @@ -117,12 +115,11 @@ void NetworkInterface::_onIpEvent(int32_t event_id, void* event_data) { arduino_event.event_id = ARDUINO_EVENT_WIFI_AP_GOT_IP6; } else #endif - if(_interface_id == ESP_NETIF_ID_PPP){ - arduino_event.event_id = ARDUINO_EVENT_PPP_GOT_IP6; - } else - if (_interface_id >= ESP_NETIF_ID_ETH && _interface_id < ESP_NETIF_ID_MAX) { - arduino_event.event_id = ARDUINO_EVENT_ETH_GOT_IP6; - } + if (_interface_id == ESP_NETIF_ID_PPP) { + arduino_event.event_id = ARDUINO_EVENT_PPP_GOT_IP6; + } else if (_interface_id >= ESP_NETIF_ID_ETH && _interface_id < ESP_NETIF_ID_MAX) { + arduino_event.event_id = ARDUINO_EVENT_ETH_GOT_IP6; + } #if SOC_WIFI_SUPPORTED } else if (event_id == IP_EVENT_AP_STAIPASSIGNED && _interface_id == ESP_NETIF_ID_AP) { setStatusBits(ESP_NETIF_HAS_IP_BIT); diff --git a/libraries/PPP/examples/PPP_Basic/PPP_Basic.ino b/libraries/PPP/examples/PPP_Basic/PPP_Basic.ino index 78fda9d18bf..16b30507703 100644 --- a/libraries/PPP/examples/PPP_Basic/PPP_Basic.ino +++ b/libraries/PPP/examples/PPP_Basic/PPP_Basic.ino @@ -1,17 +1,17 @@ #include -#define PPP_MODEM_APN "internet" -#define PPP_MODEM_PIN "0000" // or NULL +#define PPP_MODEM_APN "internet" +#define PPP_MODEM_PIN "0000" // or NULL // WaveShare SIM7600 HW Flow Control -#define PPP_MODEM_RST 25 -#define PPP_MODEM_RST_LOW false //active HIGH -#define PPP_MODEM_TX 21 -#define PPP_MODEM_RX 22 -#define PPP_MODEM_RTS 26 -#define PPP_MODEM_CTS 27 -#define PPP_MODEM_FC ESP_MODEM_FLOW_CONTROL_HW -#define PPP_MODEM_MODEL PPP_MODEM_SIM7600 +#define PPP_MODEM_RST 25 +#define PPP_MODEM_RST_LOW false //active HIGH +#define PPP_MODEM_TX 21 +#define PPP_MODEM_RX 22 +#define PPP_MODEM_RTS 26 +#define PPP_MODEM_CTS 27 +#define PPP_MODEM_FC ESP_MODEM_FLOW_CONTROL_HW +#define PPP_MODEM_MODEL PPP_MODEM_SIM7600 // SIM800 basic module with just TX,RX and RST // #define PPP_MODEM_RST 0 @@ -23,8 +23,7 @@ // #define PPP_MODEM_FC ESP_MODEM_FLOW_CONTROL_NONE // #define PPP_MODEM_MODEL PPP_MODEM_SIM800 -void onEvent(arduino_event_id_t event, arduino_event_info_t info) -{ +void onEvent(arduino_event_id_t event, arduino_event_info_t info) { switch (event) { case ARDUINO_EVENT_PPP_START: Serial.println("PPP Started"); @@ -49,16 +48,17 @@ void onEvent(arduino_event_id_t event, arduino_event_info_t info) } } -void testClient(const char * host, uint16_t port) { +void testClient(const char* host, uint16_t port) { NetworkClient client; if (!client.connect(host, port)) { Serial.println("Connection Failed"); return; } client.printf("GET / HTTP/1.1\r\nHost: %s\r\n\r\n", host); - while (client.connected() && !client.available()); + while (client.connected() && !client.available()) + ; while (client.available()) { - client.read();//Serial.write(client.read()); + client.read(); //Serial.write(client.read()); } Serial.println("Connection Success"); @@ -70,7 +70,7 @@ void setup() { // Listen for modem events Network.onEvent(onEvent); - + // Configure the modem PPP.setApn(PPP_MODEM_APN); PPP.setPin(PPP_MODEM_PIN); @@ -80,16 +80,19 @@ void setup() { Serial.println("Starting the modem. It might take a while!"); PPP.begin(PPP_MODEM_MODEL); - Serial.print("Manufacturer: "); Serial.println(PPP.cmd("AT+CGMI", 10000)); - Serial.print("Model: "); Serial.println(PPP.moduleName()); - Serial.print("IMEI: "); Serial.println(PPP.IMEI()); - + Serial.print("Manufacturer: "); + Serial.println(PPP.cmd("AT+CGMI", 10000)); + Serial.print("Model: "); + Serial.println(PPP.moduleName()); + Serial.print("IMEI: "); + Serial.println(PPP.IMEI()); + bool attached = PPP.attached(); - if(!attached){ - int i=0; + if (!attached) { + int i = 0; unsigned int s = millis(); Serial.print("Waiting to connect to network"); - while(!attached && ((++i) < 600)){ + while (!attached && ((++i) < 600)) { Serial.print("."); delay(100); attached = PPP.attached(); @@ -98,22 +101,29 @@ void setup() { Serial.println("s"); attached = PPP.attached(); } - - Serial.print("Attached: "); Serial.println(attached); - Serial.print("State: "); Serial.println(PPP.radioState()); - if(attached){ - Serial.print("Operator: "); Serial.println(PPP.operatorName()); - Serial.print("IMSI: "); Serial.println(PPP.IMSI()); - Serial.print("RSSI: "); Serial.println(PPP.RSSI()); + + Serial.print("Attached: "); + Serial.println(attached); + Serial.print("State: "); + Serial.println(PPP.radioState()); + if (attached) { + Serial.print("Operator: "); + Serial.println(PPP.operatorName()); + Serial.print("IMSI: "); + Serial.println(PPP.IMSI()); + Serial.print("RSSI: "); + Serial.println(PPP.RSSI()); int ber = PPP.BER(); - if(ber > 0){ - Serial.print("BER: "); Serial.println(ber); - Serial.print("NetMode: "); Serial.println(PPP.networkMode()); + if (ber > 0) { + Serial.print("BER: "); + Serial.println(ber); + Serial.print("NetMode: "); + Serial.println(PPP.networkMode()); } - + Serial.println("Switching to data mode..."); - PPP.mode(ESP_MODEM_MODE_CMUX); // Data and Command mixed mode - if(!PPP.waitStatusBits(ESP_NETIF_CONNECTED_BIT, 1000)){ + PPP.mode(ESP_MODEM_MODE_CMUX); // Data and Command mixed mode + if (!PPP.waitStatusBits(ESP_NETIF_CONNECTED_BIT, 1000)) { Serial.println("Failed to connect to internet!"); } else { Serial.println("Connected to internet!"); diff --git a/libraries/PPP/src/PPP.cpp b/libraries/PPP/src/PPP.cpp index 6227fcf7f12..2f47582e291 100644 --- a/libraries/PPP/src/PPP.cpp +++ b/libraries/PPP/src/PPP.cpp @@ -8,808 +8,783 @@ #include "driver/uart.h" #include "hal/uart_ll.h" -typedef struct { void * arg; } PdpContext; +typedef struct { + void *arg; +} PdpContext; #include "esp_modem_api.h" // Because of how esp_modem functions are declared, we need to workaround some APIs that take strings as input (output works OK) // Following APIs work only when called through this interface extern "C" { - esp_err_t _esp_modem_at(esp_modem_dce_t *dce_wrap, const char *at, char *p_out, int timeout); - esp_err_t _esp_modem_at_raw(esp_modem_dce_t *dce_wrap, const char *cmd, char *p_out, const char *pass, const char *fail, int timeout); - esp_err_t _esp_modem_send_sms(esp_modem_dce_t *dce_wrap, const char *number, const char *message); - esp_err_t _esp_modem_set_pin(esp_modem_dce_t *dce_wrap, const char *pin); - esp_err_t _esp_modem_set_operator(esp_modem_dce_t *dce_wrap, int mode, int format, const char *oper); - esp_err_t _esp_modem_set_network_bands(esp_modem_dce_t *dce_wrap, const char *mode, const int *bands, int size); + esp_err_t _esp_modem_at(esp_modem_dce_t *dce_wrap, const char *at, char *p_out, int timeout); + esp_err_t _esp_modem_at_raw(esp_modem_dce_t *dce_wrap, const char *cmd, char *p_out, const char *pass, const char *fail, int timeout); + esp_err_t _esp_modem_send_sms(esp_modem_dce_t *dce_wrap, const char *number, const char *message); + esp_err_t _esp_modem_set_pin(esp_modem_dce_t *dce_wrap, const char *pin); + esp_err_t _esp_modem_set_operator(esp_modem_dce_t *dce_wrap, int mode, int format, const char *oper); + esp_err_t _esp_modem_set_network_bands(esp_modem_dce_t *dce_wrap, const char *mode, const int *bands, int size); }; -static PPPClass * _esp_modem = NULL; +static PPPClass *_esp_modem = NULL; static esp_event_handler_instance_t _ppp_ev_instance = NULL; #if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_VERBOSE -static const char * _ppp_event_name(int32_t event_id){ - switch(event_id){ - case NETIF_PPP_ERRORNONE : return "No error."; - case NETIF_PPP_ERRORPARAM : return "Invalid parameter."; - case NETIF_PPP_ERROROPEN : return "Unable to open PPP session."; - case NETIF_PPP_ERRORDEVICE : return "Invalid I/O device for PPP."; - case NETIF_PPP_ERRORALLOC : return "Unable to allocate resources."; - case NETIF_PPP_ERRORUSER : return "User interrupt."; - case NETIF_PPP_ERRORCONNECT : return "Connection lost."; - case NETIF_PPP_ERRORAUTHFAIL : return "Failed authentication challenge."; - case NETIF_PPP_ERRORPROTOCOL : return "Failed to meet protocol."; - case NETIF_PPP_ERRORPEERDEAD : return "Connection timeout"; - case NETIF_PPP_ERRORIDLETIMEOUT : return "Idle Timeout"; - case NETIF_PPP_ERRORCONNECTTIME : return "Max connect time reached"; - case NETIF_PPP_ERRORLOOPBACK : return "Loopback detected"; - case NETIF_PPP_PHASE_DEAD : return "Phase Dead"; - case NETIF_PPP_PHASE_MASTER : return "Phase Master"; - case NETIF_PPP_PHASE_HOLDOFF : return "Phase Hold Off"; - case NETIF_PPP_PHASE_INITIALIZE : return "Phase Initialize"; - case NETIF_PPP_PHASE_SERIALCONN : return "Phase Serial Conn"; - case NETIF_PPP_PHASE_DORMANT : return "Phase Dormant"; - case NETIF_PPP_PHASE_ESTABLISH : return "Phase Establish"; - case NETIF_PPP_PHASE_AUTHENTICATE: return "Phase Authenticate"; - case NETIF_PPP_PHASE_CALLBACK : return "Phase Callback"; - case NETIF_PPP_PHASE_NETWORK : return "Phase Network"; - case NETIF_PPP_PHASE_RUNNING : return "Phase Running"; - case NETIF_PPP_PHASE_TERMINATE : return "Phase Terminate"; - case NETIF_PPP_PHASE_DISCONNECT : return "Phase Disconnect"; - case NETIF_PPP_CONNECT_FAILED : return "Connect Failed"; - default: break; - } - return "UNKNOWN"; -} - -static const char * _ppp_terminal_error_name(esp_modem_terminal_error_t err){ - switch(err){ - case ESP_MODEM_TERMINAL_BUFFER_OVERFLOW: return "Buffer Overflow"; - case ESP_MODEM_TERMINAL_CHECKSUM_ERROR: return "Checksum Error"; - case ESP_MODEM_TERMINAL_UNEXPECTED_CONTROL_FLOW: return "Unexpected Control Flow"; - case ESP_MODEM_TERMINAL_DEVICE_GONE: return "Device Gone"; - case ESP_MODEM_TERMINAL_UNKNOWN_ERROR: return "Unknown Error"; - default: break; - } - return "UNKNOWN"; +static const char *_ppp_event_name(int32_t event_id) { + switch (event_id) { + case NETIF_PPP_ERRORNONE: return "No error."; + case NETIF_PPP_ERRORPARAM: return "Invalid parameter."; + case NETIF_PPP_ERROROPEN: return "Unable to open PPP session."; + case NETIF_PPP_ERRORDEVICE: return "Invalid I/O device for PPP."; + case NETIF_PPP_ERRORALLOC: return "Unable to allocate resources."; + case NETIF_PPP_ERRORUSER: return "User interrupt."; + case NETIF_PPP_ERRORCONNECT: return "Connection lost."; + case NETIF_PPP_ERRORAUTHFAIL: return "Failed authentication challenge."; + case NETIF_PPP_ERRORPROTOCOL: return "Failed to meet protocol."; + case NETIF_PPP_ERRORPEERDEAD: return "Connection timeout"; + case NETIF_PPP_ERRORIDLETIMEOUT: return "Idle Timeout"; + case NETIF_PPP_ERRORCONNECTTIME: return "Max connect time reached"; + case NETIF_PPP_ERRORLOOPBACK: return "Loopback detected"; + case NETIF_PPP_PHASE_DEAD: return "Phase Dead"; + case NETIF_PPP_PHASE_MASTER: return "Phase Master"; + case NETIF_PPP_PHASE_HOLDOFF: return "Phase Hold Off"; + case NETIF_PPP_PHASE_INITIALIZE: return "Phase Initialize"; + case NETIF_PPP_PHASE_SERIALCONN: return "Phase Serial Conn"; + case NETIF_PPP_PHASE_DORMANT: return "Phase Dormant"; + case NETIF_PPP_PHASE_ESTABLISH: return "Phase Establish"; + case NETIF_PPP_PHASE_AUTHENTICATE: return "Phase Authenticate"; + case NETIF_PPP_PHASE_CALLBACK: return "Phase Callback"; + case NETIF_PPP_PHASE_NETWORK: return "Phase Network"; + case NETIF_PPP_PHASE_RUNNING: return "Phase Running"; + case NETIF_PPP_PHASE_TERMINATE: return "Phase Terminate"; + case NETIF_PPP_PHASE_DISCONNECT: return "Phase Disconnect"; + case NETIF_PPP_CONNECT_FAILED: return "Connect Failed"; + default: break; + } + return "UNKNOWN"; +} + +static const char *_ppp_terminal_error_name(esp_modem_terminal_error_t err) { + switch (err) { + case ESP_MODEM_TERMINAL_BUFFER_OVERFLOW: return "Buffer Overflow"; + case ESP_MODEM_TERMINAL_CHECKSUM_ERROR: return "Checksum Error"; + case ESP_MODEM_TERMINAL_UNEXPECTED_CONTROL_FLOW: return "Unexpected Control Flow"; + case ESP_MODEM_TERMINAL_DEVICE_GONE: return "Device Gone"; + case ESP_MODEM_TERMINAL_UNKNOWN_ERROR: return "Unknown Error"; + default: break; + } + return "UNKNOWN"; } #endif -static void _ppp_event_cb(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data) { - if (event_base == NETIF_PPP_STATUS){ - if(_esp_modem != NULL){ - _esp_modem->_onPppEvent(event_id, event_data); - } +static void _ppp_event_cb(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data) { + if (event_base == NETIF_PPP_STATUS) { + if (_esp_modem != NULL) { + _esp_modem->_onPppEvent(event_id, event_data); } + } } -static void onPppArduinoEvent(arduino_event_id_t event, arduino_event_info_t info) -{ - if(event >= ARDUINO_EVENT_PPP_START && event <= ARDUINO_EVENT_PPP_GOT_IP6){ - _esp_modem->_onPppArduinoEvent(event, info); - } +static void onPppArduinoEvent(arduino_event_id_t event, arduino_event_info_t info) { + if (event >= ARDUINO_EVENT_PPP_START && event <= ARDUINO_EVENT_PPP_GOT_IP6) { + _esp_modem->_onPppArduinoEvent(event, info); + } } // PPP Error Callback -static void _ppp_error_cb(esp_modem_terminal_error_t err){ - log_v("PPP Driver Error %ld: %s", err, _ppp_terminal_error_name(err)); +static void _ppp_error_cb(esp_modem_terminal_error_t err) { + log_v("PPP Driver Error %ld: %s", err, _ppp_terminal_error_name(err)); } // PPP Arduino Events Callback -void PPPClass::_onPppArduinoEvent(arduino_event_id_t event, arduino_event_info_t info){ - log_v("PPP Arduino Event %ld: %s", event, Network.eventName(event)); - // if(event == ARDUINO_EVENT_PPP_GOT_IP){ - // if((getStatusBits() & ESP_NETIF_CONNECTED_BIT) == 0){ - // setStatusBits(ESP_NETIF_CONNECTED_BIT); - // arduino_event_t arduino_event; - // arduino_event.event_id = ARDUINO_EVENT_PPP_CONNECTED; - // Network.postEvent(&arduino_event); - // } - // } else - if(event == ARDUINO_EVENT_PPP_LOST_IP){ - if((getStatusBits() & ESP_NETIF_CONNECTED_BIT) != 0){ - clearStatusBits(ESP_NETIF_CONNECTED_BIT); - arduino_event_t arduino_event; - arduino_event.event_id = ARDUINO_EVENT_PPP_DISCONNECTED; - Network.postEvent(&arduino_event); - } - } +void PPPClass::_onPppArduinoEvent(arduino_event_id_t event, arduino_event_info_t info) { + log_v("PPP Arduino Event %ld: %s", event, Network.eventName(event)); + // if(event == ARDUINO_EVENT_PPP_GOT_IP){ + // if((getStatusBits() & ESP_NETIF_CONNECTED_BIT) == 0){ + // setStatusBits(ESP_NETIF_CONNECTED_BIT); + // arduino_event_t arduino_event; + // arduino_event.event_id = ARDUINO_EVENT_PPP_CONNECTED; + // Network.postEvent(&arduino_event); + // } + // } else + if (event == ARDUINO_EVENT_PPP_LOST_IP) { + if ((getStatusBits() & ESP_NETIF_CONNECTED_BIT) != 0) { + clearStatusBits(ESP_NETIF_CONNECTED_BIT); + arduino_event_t arduino_event; + arduino_event.event_id = ARDUINO_EVENT_PPP_DISCONNECTED; + Network.postEvent(&arduino_event); + } + } } // PPP Driver Events Callback -void PPPClass::_onPppEvent(int32_t event, void* event_data){ - arduino_event_t arduino_event; - arduino_event.event_id = ARDUINO_EVENT_MAX; +void PPPClass::_onPppEvent(int32_t event, void *event_data) { + arduino_event_t arduino_event; + arduino_event.event_id = ARDUINO_EVENT_MAX; - log_v("PPP Driver Event %ld: %s", event, _ppp_event_name(event)); + log_v("PPP Driver Event %ld: %s", event, _ppp_event_name(event)); - if(event == NETIF_PPP_ERRORNONE){ - if((getStatusBits() & ESP_NETIF_CONNECTED_BIT) == 0){ - setStatusBits(ESP_NETIF_CONNECTED_BIT); - arduino_event_t arduino_event; - arduino_event.event_id = ARDUINO_EVENT_PPP_CONNECTED; - Network.postEvent(&arduino_event); - } - } - - if(arduino_event.event_id < ARDUINO_EVENT_MAX){ - Network.postEvent(&arduino_event); + if (event == NETIF_PPP_ERRORNONE) { + if ((getStatusBits() & ESP_NETIF_CONNECTED_BIT) == 0) { + setStatusBits(ESP_NETIF_CONNECTED_BIT); + arduino_event_t arduino_event; + arduino_event.event_id = ARDUINO_EVENT_PPP_CONNECTED; + Network.postEvent(&arduino_event); } -} - -esp_modem_dce_t * PPPClass::handle() const { - return _dce; -} + } -PPPClass::PPPClass() - :_dce(NULL) - ,_pin_tx(-1) - ,_pin_rx(-1) - ,_pin_rts(-1) - ,_pin_cts(-1) - ,_flow_ctrl(ESP_MODEM_FLOW_CONTROL_NONE) - ,_pin_rst(-1) - ,_pin_rst_act_low(true) - ,_pin(NULL) - ,_apn(NULL) - ,_rx_buffer_size(4096) - ,_tx_buffer_size(512) - ,_mode(ESP_MODEM_MODE_COMMAND) - ,_uart_num(UART_NUM_1) -{ -} - -PPPClass::~PPPClass() -{} - -bool PPPClass::pppDetachBus(void * bus_pointer){ - PPPClass *bus = (PPPClass *) bus_pointer; - bus->end(); - return true; + if (arduino_event.event_id < ARDUINO_EVENT_MAX) { + Network.postEvent(&arduino_event); + } } -void PPPClass::setResetPin(int8_t rst, bool active_low){ - _pin_rst = digitalPinToGPIONumber(rst); - _pin_rst_act_low = active_low; +esp_modem_dce_t *PPPClass::handle() const { + return _dce; } -bool PPPClass::setPins(int8_t tx, int8_t rx, int8_t rts, int8_t cts, esp_modem_flow_ctrl_t flow_ctrl){ - perimanSetBusDeinit(ESP32_BUS_TYPE_PPP_TX, PPPClass::pppDetachBus); - perimanSetBusDeinit(ESP32_BUS_TYPE_PPP_RX, PPPClass::pppDetachBus); - perimanSetBusDeinit(ESP32_BUS_TYPE_PPP_RTS, PPPClass::pppDetachBus); - perimanSetBusDeinit(ESP32_BUS_TYPE_PPP_CTS, PPPClass::pppDetachBus); - - if(_pin_tx >= 0){ - if(!perimanClearPinBus(_pin_tx)){ return false; } - } - if(_pin_rx >= 0){ - if(!perimanClearPinBus(_pin_rx)){ return false; } - } - if(_pin_rts >= 0){ - if(!perimanClearPinBus(_pin_rts)){ return false; } - } - if(_pin_cts >= 0){ - if(!perimanClearPinBus(_pin_cts)){ return false; } - } - - _flow_ctrl = flow_ctrl; - _pin_tx = digitalPinToGPIONumber(tx); - _pin_rx = digitalPinToGPIONumber(rx); - _pin_rts = digitalPinToGPIONumber(rts); - _pin_cts = digitalPinToGPIONumber(cts); - - if(_pin_tx >= 0){ - if(!perimanSetPinBus(_pin_tx, ESP32_BUS_TYPE_PPP_TX, (void *)(this), -1, -1)){ return false; } - } - if(_pin_rx >= 0){ - if(!perimanSetPinBus(_pin_rx, ESP32_BUS_TYPE_PPP_RX, (void *)(this), -1, -1)){ return false; } - } - if(_pin_rts >= 0){ - if(!perimanSetPinBus(_pin_rts, ESP32_BUS_TYPE_PPP_RTS, (void *)(this), -1, -1)){ return false; } - } - if(_pin_cts >= 0){ - if(!perimanSetPinBus(_pin_cts, ESP32_BUS_TYPE_PPP_CTS, (void *)(this), -1, -1)){ return false; } - } +PPPClass::PPPClass() + : _dce(NULL), _pin_tx(-1), _pin_rx(-1), _pin_rts(-1), _pin_cts(-1), _flow_ctrl(ESP_MODEM_FLOW_CONTROL_NONE), _pin_rst(-1), _pin_rst_act_low(true), _pin(NULL), _apn(NULL), _rx_buffer_size(4096), _tx_buffer_size(512), _mode(ESP_MODEM_MODE_COMMAND), _uart_num(UART_NUM_1) { +} + +PPPClass::~PPPClass() {} + +bool PPPClass::pppDetachBus(void *bus_pointer) { + PPPClass *bus = (PPPClass *)bus_pointer; + bus->end(); + return true; +} + +void PPPClass::setResetPin(int8_t rst, bool active_low) { + _pin_rst = digitalPinToGPIONumber(rst); + _pin_rst_act_low = active_low; +} + +bool PPPClass::setPins(int8_t tx, int8_t rx, int8_t rts, int8_t cts, esp_modem_flow_ctrl_t flow_ctrl) { + perimanSetBusDeinit(ESP32_BUS_TYPE_PPP_TX, PPPClass::pppDetachBus); + perimanSetBusDeinit(ESP32_BUS_TYPE_PPP_RX, PPPClass::pppDetachBus); + perimanSetBusDeinit(ESP32_BUS_TYPE_PPP_RTS, PPPClass::pppDetachBus); + perimanSetBusDeinit(ESP32_BUS_TYPE_PPP_CTS, PPPClass::pppDetachBus); + + if (_pin_tx >= 0) { + if (!perimanClearPinBus(_pin_tx)) { return false; } + } + if (_pin_rx >= 0) { + if (!perimanClearPinBus(_pin_rx)) { return false; } + } + if (_pin_rts >= 0) { + if (!perimanClearPinBus(_pin_rts)) { return false; } + } + if (_pin_cts >= 0) { + if (!perimanClearPinBus(_pin_cts)) { return false; } + } + + _flow_ctrl = flow_ctrl; + _pin_tx = digitalPinToGPIONumber(tx); + _pin_rx = digitalPinToGPIONumber(rx); + _pin_rts = digitalPinToGPIONumber(rts); + _pin_cts = digitalPinToGPIONumber(cts); + + if (_pin_tx >= 0) { + if (!perimanSetPinBus(_pin_tx, ESP32_BUS_TYPE_PPP_TX, (void *)(this), -1, -1)) { return false; } + } + if (_pin_rx >= 0) { + if (!perimanSetPinBus(_pin_rx, ESP32_BUS_TYPE_PPP_RX, (void *)(this), -1, -1)) { return false; } + } + if (_pin_rts >= 0) { + if (!perimanSetPinBus(_pin_rts, ESP32_BUS_TYPE_PPP_RTS, (void *)(this), -1, -1)) { return false; } + } + if (_pin_cts >= 0) { + if (!perimanSetPinBus(_pin_cts, ESP32_BUS_TYPE_PPP_CTS, (void *)(this), -1, -1)) { return false; } + } + return true; +} + +bool PPPClass::begin(ppp_modem_model_t model, uint8_t uart_num, int baud_rate) { + esp_err_t ret = ESP_OK; + bool pin_ok = false; + int trys = 0; + + if (_esp_netif != NULL || _dce != NULL) { + log_w("PPP Already Started"); return true; -} - -bool PPPClass::begin(ppp_modem_model_t model, uint8_t uart_num, int baud_rate){ - esp_err_t ret = ESP_OK; - bool pin_ok = false; - int trys = 0; + } - if(_esp_netif != NULL || _dce != NULL){ - log_w("PPP Already Started"); - return true; - } - - if(_apn == NULL){ - log_e("APN is not set. Call 'PPP.setApn()' first"); - return false; - } - - if(_pin_tx < 0 || _pin_rx < 0){ - log_e("UART pins not set. Call 'PPP.setPins()' first"); - return false; - } - - if((_pin_rts < 0 || _pin_cts < 0) && (_flow_ctrl != ESP_MODEM_FLOW_CONTROL_NONE)){ - log_e("UART CTS/RTS pins not set, but flow control is enabled!"); - return false; - } - - _uart_num = uart_num; - _esp_modem = this; + if (_apn == NULL) { + log_e("APN is not set. Call 'PPP.setApn()' first"); + return false; + } - Network.begin(); + if (_pin_tx < 0 || _pin_rx < 0) { + log_e("UART pins not set. Call 'PPP.setPins()' first"); + return false; + } - /* Listen for PPP status events */ - if(_ppp_ev_instance == NULL && esp_event_handler_instance_register(NETIF_PPP_STATUS, ESP_EVENT_ANY_ID, &_ppp_event_cb, NULL, &_ppp_ev_instance)){ - log_e("event_handler_instance_register for NETIF_PPP_STATUS Failed!"); - return false; - } + if ((_pin_rts < 0 || _pin_cts < 0) && (_flow_ctrl != ESP_MODEM_FLOW_CONTROL_NONE)) { + log_e("UART CTS/RTS pins not set, but flow control is enabled!"); + return false; + } - /* Configure the PPP netif */ - esp_netif_config_t cfg = ESP_NETIF_DEFAULT_PPP(); - _esp_netif = esp_netif_new(&cfg); - if(_esp_netif == NULL){ - log_e("esp_netif_new failed"); - return false; - } + _uart_num = uart_num; + _esp_modem = this; - /* Attach to receive IP events */ - initNetif(ESP_NETIF_ID_PPP); - - /* Configure the DTE */ - esp_modem_dte_config_t dte_config = ESP_MODEM_DTE_DEFAULT_CONFIG(); - dte_config.uart_config.tx_io_num = _pin_tx; - dte_config.uart_config.rx_io_num = _pin_rx; - dte_config.uart_config.rts_io_num = _pin_rts; - dte_config.uart_config.cts_io_num = _pin_cts; - dte_config.uart_config.flow_control = _flow_ctrl; - dte_config.uart_config.rx_buffer_size = _rx_buffer_size; - dte_config.uart_config.tx_buffer_size = _tx_buffer_size; - dte_config.uart_config.port_num = _uart_num; - dte_config.uart_config.baud_rate = baud_rate; - - /* Configure the DCE */ - esp_modem_dce_config_t dce_config = ESP_MODEM_DCE_DEFAULT_CONFIG(_apn); - - /* Reset the Modem */ - if(_pin_rst >= 0){ - log_v("Resetting the modem"); - if(_pin_rst_act_low){ - pinMode(_pin_rst, OUTPUT_OPEN_DRAIN); - } else { - pinMode(_pin_rst, OUTPUT); - } - digitalWrite(_pin_rst, !_pin_rst_act_low); - delay(200); - digitalWrite(_pin_rst, _pin_rst_act_low); - delay(100); - } + Network.begin(); - /* Start the DCE */ - _dce = esp_modem_new_dev((esp_modem_dce_device_t)model, &dte_config, &dce_config, _esp_netif); - if(_dce == NULL){ - log_e("esp_modem_new_dev failed"); - goto err; - } + /* Listen for PPP status events */ + if (_ppp_ev_instance == NULL && esp_event_handler_instance_register(NETIF_PPP_STATUS, ESP_EVENT_ANY_ID, &_ppp_event_cb, NULL, &_ppp_ev_instance)) { + log_e("event_handler_instance_register for NETIF_PPP_STATUS Failed!"); + return false; + } - esp_modem_set_error_cb(_dce, _ppp_error_cb); - - /* Wait for Modem to respond */ - if(_pin_rst >= 0){ - // wait to be able to talk to the modem - log_v("Waiting for response from the modem"); - while(esp_modem_sync(_dce) != ESP_OK && trys < 100){ - trys++; - delay(500); - } - if(trys >= 100){ - log_e("Failed to wait for communication"); - goto err; - } + /* Configure the PPP netif */ + esp_netif_config_t cfg = ESP_NETIF_DEFAULT_PPP(); + _esp_netif = esp_netif_new(&cfg); + if (_esp_netif == NULL) { + log_e("esp_netif_new failed"); + return false; + } + + /* Attach to receive IP events */ + initNetif(ESP_NETIF_ID_PPP); + + /* Configure the DTE */ + esp_modem_dte_config_t dte_config = ESP_MODEM_DTE_DEFAULT_CONFIG(); + dte_config.uart_config.tx_io_num = _pin_tx; + dte_config.uart_config.rx_io_num = _pin_rx; + dte_config.uart_config.rts_io_num = _pin_rts; + dte_config.uart_config.cts_io_num = _pin_cts; + dte_config.uart_config.flow_control = _flow_ctrl; + dte_config.uart_config.rx_buffer_size = _rx_buffer_size; + dte_config.uart_config.tx_buffer_size = _tx_buffer_size; + dte_config.uart_config.port_num = _uart_num; + dte_config.uart_config.baud_rate = baud_rate; + + /* Configure the DCE */ + esp_modem_dce_config_t dce_config = ESP_MODEM_DCE_DEFAULT_CONFIG(_apn); + + /* Reset the Modem */ + if (_pin_rst >= 0) { + log_v("Resetting the modem"); + if (_pin_rst_act_low) { + pinMode(_pin_rst, OUTPUT_OPEN_DRAIN); } else { - // try to communicate with the modem - if(esp_modem_sync(_dce) != ESP_OK){ - log_v("Modem does not respond to AT, maybe in DATA mode? ...exiting network mode"); - esp_modem_set_mode(_dce, ESP_MODEM_MODE_COMMAND); - if(esp_modem_sync(_dce) != ESP_OK){ - log_e("Modem failed to respond to AT!"); - goto err; - } - } + pinMode(_pin_rst, OUTPUT); + } + digitalWrite(_pin_rst, !_pin_rst_act_low); + delay(200); + digitalWrite(_pin_rst, _pin_rst_act_low); + delay(100); + } + + /* Start the DCE */ + _dce = esp_modem_new_dev((esp_modem_dce_device_t)model, &dte_config, &dce_config, _esp_netif); + if (_dce == NULL) { + log_e("esp_modem_new_dev failed"); + goto err; + } + + esp_modem_set_error_cb(_dce, _ppp_error_cb); + + /* Wait for Modem to respond */ + if (_pin_rst >= 0) { + // wait to be able to talk to the modem + log_v("Waiting for response from the modem"); + while (esp_modem_sync(_dce) != ESP_OK && trys < 100) { + trys++; + delay(500); + } + if (trys >= 100) { + log_e("Failed to wait for communication"); + goto err; + } + } else { + // try to communicate with the modem + if (esp_modem_sync(_dce) != ESP_OK) { + log_v("Modem does not respond to AT, maybe in DATA mode? ...exiting network mode"); + esp_modem_set_mode(_dce, ESP_MODEM_MODE_COMMAND); + if (esp_modem_sync(_dce) != ESP_OK) { + log_e("Modem failed to respond to AT!"); + goto err; + } } + } - /* enable flow control */ - if (dte_config.uart_config.flow_control == ESP_MODEM_FLOW_CONTROL_HW) { - ret = esp_modem_set_flow_control(_dce, 2, 2); //2/2 means HW Flow Control. - if (ret != ESP_OK) { - log_e("Failed to set the hardware flow control: [%d] %s", ret, esp_err_to_name(ret)); - goto err; - } + /* enable flow control */ + if (dte_config.uart_config.flow_control == ESP_MODEM_FLOW_CONTROL_HW) { + ret = esp_modem_set_flow_control(_dce, 2, 2); //2/2 means HW Flow Control. + if (ret != ESP_OK) { + log_e("Failed to set the hardware flow control: [%d] %s", ret, esp_err_to_name(ret)); + goto err; } + } - /* check if PIN needed */ - if (esp_modem_read_pin(_dce, pin_ok) == ESP_OK && pin_ok == false) { - if (_pin == NULL || _esp_modem_set_pin(_dce, _pin) != ESP_OK) { - log_e("PIN verification failed!"); - goto err; - } + /* check if PIN needed */ + if (esp_modem_read_pin(_dce, pin_ok) == ESP_OK && pin_ok == false) { + if (_pin == NULL || _esp_modem_set_pin(_dce, _pin) != ESP_OK) { + log_e("PIN verification failed!"); + goto err; } + } - Network.onSysEvent(onPppArduinoEvent); + Network.onSysEvent(onPppArduinoEvent); - setStatusBits(ESP_NETIF_STARTED_BIT); - arduino_event_t arduino_event; - arduino_event.event_id = ARDUINO_EVENT_PPP_START; - Network.postEvent(&arduino_event); + setStatusBits(ESP_NETIF_STARTED_BIT); + arduino_event_t arduino_event; + arduino_event.event_id = ARDUINO_EVENT_PPP_START; + Network.postEvent(&arduino_event); - return true; + return true; err: - PPPClass::pppDetachBus((void *)(this)); - return false; + PPPClass::pppDetachBus((void *)(this)); + return false; } -void PPPClass::end(void) -{ - if(_esp_modem && _esp_netif && _dce){ - - if((getStatusBits() & ESP_NETIF_CONNECTED_BIT) != 0){ - clearStatusBits(ESP_NETIF_CONNECTED_BIT | ESP_NETIF_HAS_IP_BIT | ESP_NETIF_HAS_LOCAL_IP6_BIT | ESP_NETIF_HAS_GLOBAL_IP6_BIT); - arduino_event_t disconnect_event; - disconnect_event.event_id = ARDUINO_EVENT_PPP_DISCONNECTED; - Network.postEvent(&disconnect_event); - } +void PPPClass::end(void) { + if (_esp_modem && _esp_netif && _dce) { - clearStatusBits(ESP_NETIF_STARTED_BIT | ESP_NETIF_CONNECTED_BIT | ESP_NETIF_HAS_IP_BIT | ESP_NETIF_HAS_LOCAL_IP6_BIT | ESP_NETIF_HAS_GLOBAL_IP6_BIT | ESP_NETIF_HAS_STATIC_IP_BIT); - arduino_event_t arduino_event; - arduino_event.event_id = ARDUINO_EVENT_PPP_STOP; - Network.postEvent(&arduino_event); + if ((getStatusBits() & ESP_NETIF_CONNECTED_BIT) != 0) { + clearStatusBits(ESP_NETIF_CONNECTED_BIT | ESP_NETIF_HAS_IP_BIT | ESP_NETIF_HAS_LOCAL_IP6_BIT | ESP_NETIF_HAS_GLOBAL_IP6_BIT); + arduino_event_t disconnect_event; + disconnect_event.event_id = ARDUINO_EVENT_PPP_DISCONNECTED; + Network.postEvent(&disconnect_event); } - destroyNetif(); - - if(_ppp_ev_instance != NULL){ - if(esp_event_handler_unregister(NETIF_PPP_STATUS, ESP_EVENT_ANY_ID, &_ppp_event_cb) == ESP_OK){ - _ppp_ev_instance = NULL; - } - } - _esp_modem = NULL; - - Network.removeEvent(onPppArduinoEvent); - - if(_dce != NULL){ - esp_modem_destroy(_dce); - _dce = NULL; - } - - int8_t pin = -1; - if(_pin_tx != -1){ - pin = _pin_tx; - _pin_tx = -1; - perimanClearPinBus(pin); - } - if(_pin_rx != -1){ - pin = _pin_rx; - _pin_rx = -1; - perimanClearPinBus(pin); - } - if(_pin_rts != -1){ - pin = _pin_rts; - _pin_rts = -1; - perimanClearPinBus(pin); - } - if(_pin_cts != -1){ - pin = _pin_cts; - _pin_cts = -1; - perimanClearPinBus(pin); - } - - _mode = ESP_MODEM_MODE_COMMAND; -} - -bool PPPClass::sync() const -{ - if(_dce == NULL){ - return false; - } + clearStatusBits(ESP_NETIF_STARTED_BIT | ESP_NETIF_CONNECTED_BIT | ESP_NETIF_HAS_IP_BIT | ESP_NETIF_HAS_LOCAL_IP6_BIT | ESP_NETIF_HAS_GLOBAL_IP6_BIT | ESP_NETIF_HAS_STATIC_IP_BIT); + arduino_event_t arduino_event; + arduino_event.event_id = ARDUINO_EVENT_PPP_STOP; + Network.postEvent(&arduino_event); + } + + destroyNetif(); + + if (_ppp_ev_instance != NULL) { + if (esp_event_handler_unregister(NETIF_PPP_STATUS, ESP_EVENT_ANY_ID, &_ppp_event_cb) == ESP_OK) { + _ppp_ev_instance = NULL; + } + } + _esp_modem = NULL; + + Network.removeEvent(onPppArduinoEvent); + + if (_dce != NULL) { + esp_modem_destroy(_dce); + _dce = NULL; + } + + int8_t pin = -1; + if (_pin_tx != -1) { + pin = _pin_tx; + _pin_tx = -1; + perimanClearPinBus(pin); + } + if (_pin_rx != -1) { + pin = _pin_rx; + _pin_rx = -1; + perimanClearPinBus(pin); + } + if (_pin_rts != -1) { + pin = _pin_rts; + _pin_rts = -1; + perimanClearPinBus(pin); + } + if (_pin_cts != -1) { + pin = _pin_cts; + _pin_cts = -1; + perimanClearPinBus(pin); + } + + _mode = ESP_MODEM_MODE_COMMAND; +} + +bool PPPClass::sync() const { + if (_dce == NULL) { + return false; + } - if(_mode == ESP_MODEM_MODE_DATA){ - log_e("Wrong modem mode. Should be ESP_MODEM_MODE_COMMAND"); - return false; - } - return esp_modem_sync(_dce) == ESP_OK; + if (_mode == ESP_MODEM_MODE_DATA) { + log_e("Wrong modem mode. Should be ESP_MODEM_MODE_COMMAND"); + return false; + } + return esp_modem_sync(_dce) == ESP_OK; } -bool PPPClass::attached() const -{ - if(_dce == NULL){ - return false; - } - - if(_mode == ESP_MODEM_MODE_DATA){ - log_e("Wrong modem mode. Should be ESP_MODEM_MODE_COMMAND"); - return false; - } - - int m = 0; - esp_err_t err = esp_modem_get_network_attachment_state(_dce, m); - if (err != ESP_OK) { - // log_e("esp_modem_get_network_attachment_state failed with %d %s", err, esp_err_to_name(err)); - return false; - } - return m != 0; -} +bool PPPClass::attached() const { + if (_dce == NULL) { + return false; + } -bool PPPClass::mode(esp_modem_dce_mode_t m){ - if(_dce == NULL){ - return 0; - } + if (_mode == ESP_MODEM_MODE_DATA) { + log_e("Wrong modem mode. Should be ESP_MODEM_MODE_COMMAND"); + return false; + } - if(_mode == m){ - return true; - } - esp_err_t err = esp_modem_set_mode(_dce, m); - if (err != ESP_OK) { - log_e("esp_modem_set_mode failed with %d %s", err, esp_err_to_name(err)); - return false; - } - _mode = m; - return true; + int m = 0; + esp_err_t err = esp_modem_get_network_attachment_state(_dce, m); + if (err != ESP_OK) { + // log_e("esp_modem_get_network_attachment_state failed with %d %s", err, esp_err_to_name(err)); + return false; + } + return m != 0; } -bool PPPClass::setApn(const char * apn){ - if(_apn != NULL){ - free((void *)_apn); - _apn = NULL; - } - if(apn != NULL){ - _apn = strdup(apn); - if(_apn == NULL){ - log_e("Failed to strdup APN"); - return false; - } - } - return true; -} +bool PPPClass::mode(esp_modem_dce_mode_t m) { + if (_dce == NULL) { + return 0; + } -bool PPPClass::setPin(const char * pin){ - if(_pin != NULL){ - free((void *)_pin); - _pin = NULL; - } - if(pin != NULL){ - for(int i=0; i 0x39){ - log_e("Bad character '%c' in PIN. Should be only digits", pin[i]); - return false; - } - } - _pin = strdup(pin); - if(_pin == NULL){ - log_e("Failed to strdup PIN"); - return false; - } - } + if (_mode == m) { return true; + } + esp_err_t err = esp_modem_set_mode(_dce, m); + if (err != ESP_OK) { + log_e("esp_modem_set_mode failed with %d %s", err, esp_err_to_name(err)); + return false; + } + _mode = m; + return true; +} + +bool PPPClass::setApn(const char *apn) { + if (_apn != NULL) { + free((void *)_apn); + _apn = NULL; + } + if (apn != NULL) { + _apn = strdup(apn); + if (_apn == NULL) { + log_e("Failed to strdup APN"); + return false; + } + } + return true; +} + +bool PPPClass::setPin(const char *pin) { + if (_pin != NULL) { + free((void *)_pin); + _pin = NULL; + } + if (pin != NULL) { + for (int i = 0; i < strlen(pin); i++) { + if (pin[i] < 0x30 || pin[i] > 0x39) { + log_e("Bad character '%c' in PIN. Should be only digits", pin[i]); + return false; + } + } + _pin = strdup(pin); + if (_pin == NULL) { + log_e("Failed to strdup PIN"); + return false; + } + } + return true; } -int PPPClass::RSSI() const -{ - if(_dce == NULL){ - return -1; - } - - if(_mode == ESP_MODEM_MODE_DATA){ - log_e("Wrong modem mode. Should be ESP_MODEM_MODE_COMMAND"); - return -1; - } - - int rssi, ber; - esp_err_t err = esp_modem_get_signal_quality(_dce, rssi, ber); - if (err != ESP_OK) { - // log_e("esp_modem_get_signal_quality failed with %d %s", err, esp_err_to_name(err)); - return -1; - } - return rssi; -} - -int PPPClass::BER() const -{ - if(_dce == NULL){ - return -1; - } - - if(_mode == ESP_MODEM_MODE_DATA){ - log_e("Wrong modem mode. Should be ESP_MODEM_MODE_COMMAND"); - return -1; - } - - int rssi, ber; - esp_err_t err = esp_modem_get_signal_quality(_dce, rssi, ber); - if (err != ESP_OK) { - // log_e("esp_modem_get_signal_quality failed with %d %s", err, esp_err_to_name(err)); - return -1; - } - return ber; -} - -String PPPClass::IMSI() const -{ - if(_dce == NULL){ - return String(); - } - - if(_mode == ESP_MODEM_MODE_DATA){ - log_e("Wrong modem mode. Should be ESP_MODEM_MODE_COMMAND"); - return String(); - } - - char imsi[32]; - esp_err_t err = esp_modem_get_imsi(_dce, (std::string&)imsi); - if (err != ESP_OK) { - log_e("esp_modem_get_imsi failed with %d %s", err, esp_err_to_name(err)); - return String(); - } - - return String(imsi); -} - -String PPPClass::IMEI() const -{ - if(_dce == NULL){ - return String(); - } - - if(_mode == ESP_MODEM_MODE_DATA){ - log_e("Wrong modem mode. Should be ESP_MODEM_MODE_COMMAND"); - return String(); - } - - char imei[32]; - esp_err_t err = esp_modem_get_imei(_dce, (std::string&)imei); - if (err != ESP_OK) { - log_e("esp_modem_get_imei failed with %d %s", err, esp_err_to_name(err)); - return String(); - } - - return String(imei); -} - -String PPPClass::moduleName() const -{ - if(_dce == NULL){ - return String(); - } - - if(_mode == ESP_MODEM_MODE_DATA){ - log_e("Wrong modem mode. Should be ESP_MODEM_MODE_COMMAND"); - return String(); - } - - char name[32]; - esp_err_t err = esp_modem_get_module_name(_dce, (std::string&)name); - if (err != ESP_OK) { - log_e("esp_modem_get_module_name failed with %d %s", err, esp_err_to_name(err)); - return String(); - } - - return String(name); -} - -String PPPClass::operatorName() const -{ - if(_dce == NULL){ - return String(); - } - - if(_mode == ESP_MODEM_MODE_DATA){ - log_e("Wrong modem mode. Should be ESP_MODEM_MODE_COMMAND"); - return String(); - } - - char oper[32]; - int act = 0; - esp_err_t err = esp_modem_get_operator_name(_dce, (std::string&)oper, act); - if (err != ESP_OK) { - log_e("esp_modem_get_operator_name failed with %d %s", err, esp_err_to_name(err)); - return String(); - } - - return String(oper); -} - -int PPPClass::networkMode() const -{ - if(_dce == NULL){ - return -1; - } - - if(_mode == ESP_MODEM_MODE_DATA){ - log_e("Wrong modem mode. Should be ESP_MODEM_MODE_COMMAND"); - return -1; - } - - int m = 0; - esp_err_t err = esp_modem_get_network_system_mode(_dce, m); - if (err != ESP_OK) { - log_e("esp_modem_get_network_system_mode failed with %d %s", err, esp_err_to_name(err)); - return -1; - } - return m; -} - -int PPPClass::radioState() const -{ - if(_dce == NULL){ - return -1; - } +int PPPClass::RSSI() const { + if (_dce == NULL) { + return -1; + } + + if (_mode == ESP_MODEM_MODE_DATA) { + log_e("Wrong modem mode. Should be ESP_MODEM_MODE_COMMAND"); + return -1; + } + + int rssi, ber; + esp_err_t err = esp_modem_get_signal_quality(_dce, rssi, ber); + if (err != ESP_OK) { + // log_e("esp_modem_get_signal_quality failed with %d %s", err, esp_err_to_name(err)); + return -1; + } + return rssi; +} - if(_mode == ESP_MODEM_MODE_DATA){ - log_e("Wrong modem mode. Should be ESP_MODEM_MODE_COMMAND"); - return -1; - } +int PPPClass::BER() const { + if (_dce == NULL) { + return -1; + } - int m = 0; - esp_err_t err = esp_modem_get_radio_state(_dce, m); - if (err != ESP_OK) { - // log_e("esp_modem_get_radio_state failed with %d %s", err, esp_err_to_name(err)); - return -1; - } - return m; + if (_mode == ESP_MODEM_MODE_DATA) { + log_e("Wrong modem mode. Should be ESP_MODEM_MODE_COMMAND"); + return -1; + } + + int rssi, ber; + esp_err_t err = esp_modem_get_signal_quality(_dce, rssi, ber); + if (err != ESP_OK) { + // log_e("esp_modem_get_signal_quality failed with %d %s", err, esp_err_to_name(err)); + return -1; + } + return ber; +} + +String PPPClass::IMSI() const { + if (_dce == NULL) { + return String(); + } + + if (_mode == ESP_MODEM_MODE_DATA) { + log_e("Wrong modem mode. Should be ESP_MODEM_MODE_COMMAND"); + return String(); + } + + char imsi[32]; + esp_err_t err = esp_modem_get_imsi(_dce, (std::string &)imsi); + if (err != ESP_OK) { + log_e("esp_modem_get_imsi failed with %d %s", err, esp_err_to_name(err)); + return String(); + } + + return String(imsi); +} + +String PPPClass::IMEI() const { + if (_dce == NULL) { + return String(); + } + + if (_mode == ESP_MODEM_MODE_DATA) { + log_e("Wrong modem mode. Should be ESP_MODEM_MODE_COMMAND"); + return String(); + } + + char imei[32]; + esp_err_t err = esp_modem_get_imei(_dce, (std::string &)imei); + if (err != ESP_OK) { + log_e("esp_modem_get_imei failed with %d %s", err, esp_err_to_name(err)); + return String(); + } + + return String(imei); +} + +String PPPClass::moduleName() const { + if (_dce == NULL) { + return String(); + } + + if (_mode == ESP_MODEM_MODE_DATA) { + log_e("Wrong modem mode. Should be ESP_MODEM_MODE_COMMAND"); + return String(); + } + + char name[32]; + esp_err_t err = esp_modem_get_module_name(_dce, (std::string &)name); + if (err != ESP_OK) { + log_e("esp_modem_get_module_name failed with %d %s", err, esp_err_to_name(err)); + return String(); + } + + return String(name); +} + +String PPPClass::operatorName() const { + if (_dce == NULL) { + return String(); + } + + if (_mode == ESP_MODEM_MODE_DATA) { + log_e("Wrong modem mode. Should be ESP_MODEM_MODE_COMMAND"); + return String(); + } + + char oper[32]; + int act = 0; + esp_err_t err = esp_modem_get_operator_name(_dce, (std::string &)oper, act); + if (err != ESP_OK) { + log_e("esp_modem_get_operator_name failed with %d %s", err, esp_err_to_name(err)); + return String(); + } + + return String(oper); +} + +int PPPClass::networkMode() const { + if (_dce == NULL) { + return -1; + } + + if (_mode == ESP_MODEM_MODE_DATA) { + log_e("Wrong modem mode. Should be ESP_MODEM_MODE_COMMAND"); + return -1; + } + + int m = 0; + esp_err_t err = esp_modem_get_network_system_mode(_dce, m); + if (err != ESP_OK) { + log_e("esp_modem_get_network_system_mode failed with %d %s", err, esp_err_to_name(err)); + return -1; + } + return m; +} + +int PPPClass::radioState() const { + if (_dce == NULL) { + return -1; + } + + if (_mode == ESP_MODEM_MODE_DATA) { + log_e("Wrong modem mode. Should be ESP_MODEM_MODE_COMMAND"); + return -1; + } + + int m = 0; + esp_err_t err = esp_modem_get_radio_state(_dce, m); + if (err != ESP_OK) { + // log_e("esp_modem_get_radio_state failed with %d %s", err, esp_err_to_name(err)); + return -1; + } + return m; } -bool PPPClass::powerDown(){ - if(_dce == NULL){ - return false; - } +bool PPPClass::powerDown() { + if (_dce == NULL) { + return false; + } - if(_mode == ESP_MODEM_MODE_DATA){ - log_e("Wrong modem mode. Should be ESP_MODEM_MODE_COMMAND"); - return false; - } + if (_mode == ESP_MODEM_MODE_DATA) { + log_e("Wrong modem mode. Should be ESP_MODEM_MODE_COMMAND"); + return false; + } - esp_err_t err = esp_modem_power_down(_dce); - if (err != ESP_OK) { - log_e("esp_modem_power_down failed with %d %s", err, esp_err_to_name(err)); - return false; - } - return true; + esp_err_t err = esp_modem_power_down(_dce); + if (err != ESP_OK) { + log_e("esp_modem_power_down failed with %d %s", err, esp_err_to_name(err)); + return false; + } + return true; } -bool PPPClass::reset(){ - if(_dce == NULL){ - return false; - } +bool PPPClass::reset() { + if (_dce == NULL) { + return false; + } - if(_mode == ESP_MODEM_MODE_DATA){ - log_e("Wrong modem mode. Should be ESP_MODEM_MODE_COMMAND"); - return false; - } + if (_mode == ESP_MODEM_MODE_DATA) { + log_e("Wrong modem mode. Should be ESP_MODEM_MODE_COMMAND"); + return false; + } - esp_err_t err = esp_modem_reset(_dce); - if (err != ESP_OK) { - log_e("esp_modem_reset failed with %d %s", err, esp_err_to_name(err)); - return false; - } - return true; + esp_err_t err = esp_modem_reset(_dce); + if (err != ESP_OK) { + log_e("esp_modem_reset failed with %d %s", err, esp_err_to_name(err)); + return false; + } + return true; } -bool PPPClass::storeProfile(){ - if(_dce == NULL){ - return false; - } +bool PPPClass::storeProfile() { + if (_dce == NULL) { + return false; + } - if(_mode == ESP_MODEM_MODE_DATA){ - log_e("Wrong modem mode. Should be ESP_MODEM_MODE_COMMAND"); - return false; - } + if (_mode == ESP_MODEM_MODE_DATA) { + log_e("Wrong modem mode. Should be ESP_MODEM_MODE_COMMAND"); + return false; + } - esp_err_t err = esp_modem_store_profile(_dce); - if (err != ESP_OK) { - log_e("esp_modem_store_profile failed with %d %s", err, esp_err_to_name(err)); - return false; - } - return true; + esp_err_t err = esp_modem_store_profile(_dce); + if (err != ESP_OK) { + log_e("esp_modem_store_profile failed with %d %s", err, esp_err_to_name(err)); + return false; + } + return true; } bool PPPClass::setBaudrate(int baudrate) { - if(_dce == NULL){ - return false; - } + if (_dce == NULL) { + return false; + } - if(_mode == ESP_MODEM_MODE_DATA){ - log_e("Wrong modem mode. Should be ESP_MODEM_MODE_COMMAND"); - return false; - } + if (_mode == ESP_MODEM_MODE_DATA) { + log_e("Wrong modem mode. Should be ESP_MODEM_MODE_COMMAND"); + return false; + } - esp_err_t err = esp_modem_set_baud(_dce, baudrate); - if (err != ESP_OK) { - log_e("esp_modem_set_baud failed with %d %s", err, esp_err_to_name(err)); - return false; - } + esp_err_t err = esp_modem_set_baud(_dce, baudrate); + if (err != ESP_OK) { + log_e("esp_modem_set_baud failed with %d %s", err, esp_err_to_name(err)); + return false; + } - uint32_t sclk_freq; - err = uart_get_sclk_freq(UART_SCLK_DEFAULT, &sclk_freq); - if(err != ESP_OK){ - log_e("uart_get_sclk_freq failed with %d %s", err, esp_err_to_name(err)); - return false; - } - uart_ll_set_baudrate(UART_LL_GET_HW(_uart_num), (uint32_t)baudrate, sclk_freq); + uint32_t sclk_freq; + err = uart_get_sclk_freq(UART_SCLK_DEFAULT, &sclk_freq); + if (err != ESP_OK) { + log_e("uart_get_sclk_freq failed with %d %s", err, esp_err_to_name(err)); + return false; + } + uart_ll_set_baudrate(UART_LL_GET_HW(_uart_num), (uint32_t)baudrate, sclk_freq); - return true; + return true; } -bool PPPClass::sms(const char * num, const char * message) { - if(_dce == NULL){ - return false; - } - - if(_mode == ESP_MODEM_MODE_DATA){ - log_e("Wrong modem mode. Should be ESP_MODEM_MODE_COMMAND"); - return false; - } - - for(int i=0; i 0x39)){ - log_e("Bad character '%c' in SMS Number. Should be only digits and +, # or *", num[i]); - return false; - } - } - - esp_err_t err = esp_modem_sms_txt_mode(_dce, true); - if (err != ESP_OK) { - log_e("Setting text mode failed %d %s", err, esp_err_to_name(err)); - return false; - } +bool PPPClass::sms(const char *num, const char *message) { + if (_dce == NULL) { + return false; + } - err = esp_modem_sms_character_set(_dce); - if (err != ESP_OK) { - log_e("Setting GSM character set failed %d %s", err, esp_err_to_name(err)); - return false; - } + if (_mode == ESP_MODEM_MODE_DATA) { + log_e("Wrong modem mode. Should be ESP_MODEM_MODE_COMMAND"); + return false; + } - err = _esp_modem_send_sms(_dce, num, message); - if (err != ESP_OK) { - log_e("esp_modem_send_sms() failed with %d %s", err, esp_err_to_name(err)); - return false; + for (int i = 0; i < strlen(num); i++) { + if (num[i] != '+' && num[i] != '#' && num[i] != '*' && (num[i] < 0x30 || num[i] > 0x39)) { + log_e("Bad character '%c' in SMS Number. Should be only digits and +, # or *", num[i]); + return false; } - return true; -} + } -String PPPClass::cmd(const char * at_command, int timeout){ - if(_dce == NULL){ - return String(); - } + esp_err_t err = esp_modem_sms_txt_mode(_dce, true); + if (err != ESP_OK) { + log_e("Setting text mode failed %d %s", err, esp_err_to_name(err)); + return false; + } - if(_mode == ESP_MODEM_MODE_DATA){ - log_e("Wrong modem mode. Should be ESP_MODEM_MODE_COMMAND"); - return String(); - } - char out[128] = {0}; - esp_err_t err = _esp_modem_at(_dce, at_command, out, timeout); - if (err != ESP_OK) { - log_e("esp_modem_at failed %d %s", err, esp_err_to_name(err)); - return String(); - } - return String(out); -} + err = esp_modem_sms_character_set(_dce); + if (err != ESP_OK) { + log_e("Setting GSM character set failed %d %s", err, esp_err_to_name(err)); + return false; + } -size_t PPPClass::printDriverInfo(Print & out) const { - size_t bytes = 0; - if(_dce == NULL || _mode == ESP_MODEM_MODE_DATA){ - return bytes; - } - if(attached()){ - bytes += out.print(","); - bytes += out.print(operatorName()); - } - bytes += out.print(",RSSI:"); - bytes += out.print(RSSI()); - bytes += out.print(",BER:"); - bytes += out.print(BER()); + err = _esp_modem_send_sms(_dce, num, message); + if (err != ESP_OK) { + log_e("esp_modem_send_sms() failed with %d %s", err, esp_err_to_name(err)); + return false; + } + return true; +} + +String PPPClass::cmd(const char *at_command, int timeout) { + if (_dce == NULL) { + return String(); + } + + if (_mode == ESP_MODEM_MODE_DATA) { + log_e("Wrong modem mode. Should be ESP_MODEM_MODE_COMMAND"); + return String(); + } + char out[128] = { 0 }; + esp_err_t err = _esp_modem_at(_dce, at_command, out, timeout); + if (err != ESP_OK) { + log_e("esp_modem_at failed %d %s", err, esp_err_to_name(err)); + return String(); + } + return String(out); +} + +size_t PPPClass::printDriverInfo(Print &out) const { + size_t bytes = 0; + if (_dce == NULL || _mode == ESP_MODEM_MODE_DATA) { return bytes; + } + if (attached()) { + bytes += out.print(","); + bytes += out.print(operatorName()); + } + bytes += out.print(",RSSI:"); + bytes += out.print(RSSI()); + bytes += out.print(",BER:"); + bytes += out.print(BER()); + return bytes; } PPPClass PPP; diff --git a/libraries/PPP/src/PPP.h b/libraries/PPP/src/PPP.h index 97ce62a5945..0333aaf6b0c 100644 --- a/libraries/PPP/src/PPP.h +++ b/libraries/PPP/src/PPP.h @@ -6,100 +6,102 @@ #include "esp_modem_c_api_types.h" typedef enum { - PPP_MODEM_GENERIC = ESP_MODEM_DCE_GENETIC, - PPP_MODEM_SIM7600 = ESP_MODEM_DCE_SIM7600, - PPP_MODEM_SIM7070 = ESP_MODEM_DCE_SIM7070, - PPP_MODEM_SIM7000 = ESP_MODEM_DCE_SIM7000, - PPP_MODEM_BG96 = ESP_MODEM_DCE_BG96, - PPP_MODEM_SIM800 = ESP_MODEM_DCE_SIM800, + PPP_MODEM_GENERIC = ESP_MODEM_DCE_GENETIC, + PPP_MODEM_SIM7600 = ESP_MODEM_DCE_SIM7600, + PPP_MODEM_SIM7070 = ESP_MODEM_DCE_SIM7070, + PPP_MODEM_SIM7000 = ESP_MODEM_DCE_SIM7000, + PPP_MODEM_BG96 = ESP_MODEM_DCE_BG96, + PPP_MODEM_SIM800 = ESP_MODEM_DCE_SIM800, #if CONFIG_ESP_MODEM_ADD_CUSTOM_MODULE - PPP_MODEM_CUSTOM = ESP_MODEM_DCE_CUSTOM, + PPP_MODEM_CUSTOM = ESP_MODEM_DCE_CUSTOM, #endif - PPP_MODEM_MAX + PPP_MODEM_MAX } ppp_modem_model_t; -class PPPClass: public NetworkInterface { - public: - PPPClass(); - ~PPPClass(); - - bool begin(ppp_modem_model_t model, uint8_t uart_num=1, int baud_rate=115200); - void end(); - - // Required for connecting to internet - bool setApn(const char * apn); - - // Required only if the SIM card is protected by PIN - bool setPin(const char * pin); - - // If the modem supports hardware flow control, it's best to use it - bool setPins(int8_t tx, int8_t rx, int8_t rts=-1, int8_t cts=-1, esp_modem_flow_ctrl_t flow_ctrl=ESP_MODEM_FLOW_CONTROL_NONE); - - // Using the reset pin of the module ensures that proper communication can be achieved - void setResetPin(int8_t rst, bool active_low=true); - - // Modem DCE APIs - int RSSI() const; - int BER() const; - String IMSI() const; - String IMEI() const; - String moduleName() const; // modem module name - String operatorName() const; // network operator name - int networkMode() const; // network type (GSM, LTE, etc.) - int radioState() const; // 0:minimal, 1:full - bool attached() const; // true is attached to network - bool sync() const; // true if responds to 'AT' - - // Switch the communication mode - bool mode(esp_modem_dce_mode_t m); - esp_modem_dce_mode_t mode() const { return _mode; } - - // Change temporary the baud rate of communication - bool setBaudrate(int baudrate); - - // Sens SMS message to a number - bool sms(const char * num, const char * message); - bool sms(String num, String message){ - return sms(num.c_str(), message.c_str()); - } - - // Send AT command with timeout in milliseconds - String cmd(const char * at_command, int timeout); - String cmd(String at_command, int timeout){ - return cmd(at_command.c_str(), timeout); - } - - // untested - bool powerDown(); - bool reset(); - bool storeProfile(); - - esp_modem_dce_t * handle() const; - - protected: - size_t printDriverInfo(Print & out) const; - - public: - void _onPppEvent(int32_t event_id, void* event_data); - void _onPppArduinoEvent(arduino_event_id_t event, arduino_event_info_t info); - - private: - esp_modem_dce_t *_dce; - int8_t _pin_tx; - int8_t _pin_rx; - int8_t _pin_rts; - int8_t _pin_cts; - esp_modem_flow_ctrl_t _flow_ctrl; - int8_t _pin_rst; - bool _pin_rst_act_low; - const char * _pin; - const char * _apn; - int _rx_buffer_size; - int _tx_buffer_size; - esp_modem_dce_mode_t _mode; - uint8_t _uart_num; - - static bool pppDetachBus(void * bus_pointer); +class PPPClass : public NetworkInterface { +public: + PPPClass(); + ~PPPClass(); + + bool begin(ppp_modem_model_t model, uint8_t uart_num = 1, int baud_rate = 115200); + void end(); + + // Required for connecting to internet + bool setApn(const char* apn); + + // Required only if the SIM card is protected by PIN + bool setPin(const char* pin); + + // If the modem supports hardware flow control, it's best to use it + bool setPins(int8_t tx, int8_t rx, int8_t rts = -1, int8_t cts = -1, esp_modem_flow_ctrl_t flow_ctrl = ESP_MODEM_FLOW_CONTROL_NONE); + + // Using the reset pin of the module ensures that proper communication can be achieved + void setResetPin(int8_t rst, bool active_low = true); + + // Modem DCE APIs + int RSSI() const; + int BER() const; + String IMSI() const; + String IMEI() const; + String moduleName() const; // modem module name + String operatorName() const; // network operator name + int networkMode() const; // network type (GSM, LTE, etc.) + int radioState() const; // 0:minimal, 1:full + bool attached() const; // true is attached to network + bool sync() const; // true if responds to 'AT' + + // Switch the communication mode + bool mode(esp_modem_dce_mode_t m); + esp_modem_dce_mode_t mode() const { + return _mode; + } + + // Change temporary the baud rate of communication + bool setBaudrate(int baudrate); + + // Sens SMS message to a number + bool sms(const char* num, const char* message); + bool sms(String num, String message) { + return sms(num.c_str(), message.c_str()); + } + + // Send AT command with timeout in milliseconds + String cmd(const char* at_command, int timeout); + String cmd(String at_command, int timeout) { + return cmd(at_command.c_str(), timeout); + } + + // untested + bool powerDown(); + bool reset(); + bool storeProfile(); + + esp_modem_dce_t* handle() const; + +protected: + size_t printDriverInfo(Print& out) const; + +public: + void _onPppEvent(int32_t event_id, void* event_data); + void _onPppArduinoEvent(arduino_event_id_t event, arduino_event_info_t info); + +private: + esp_modem_dce_t* _dce; + int8_t _pin_tx; + int8_t _pin_rx; + int8_t _pin_rts; + int8_t _pin_cts; + esp_modem_flow_ctrl_t _flow_ctrl; + int8_t _pin_rst; + bool _pin_rst_act_low; + const char* _pin; + const char* _apn; + int _rx_buffer_size; + int _tx_buffer_size; + esp_modem_dce_mode_t _mode; + uint8_t _uart_num; + + static bool pppDetachBus(void* bus_pointer); }; extern PPPClass PPP; diff --git a/libraries/PPP/src/ppp.c b/libraries/PPP/src/ppp.c index fafd6cc4525..db8ba0760bd 100644 --- a/libraries/PPP/src/ppp.c +++ b/libraries/PPP/src/ppp.c @@ -2,27 +2,27 @@ #if CONFIG_LWIP_PPP_SUPPORT #include "esp_modem_api.h" -esp_err_t _esp_modem_at(esp_modem_dce_t *dce_wrap, const char *at, char *p_out, int timeout){ - return esp_modem_at(dce_wrap, at, p_out, timeout); +esp_err_t _esp_modem_at(esp_modem_dce_t *dce_wrap, const char *at, char *p_out, int timeout) { + return esp_modem_at(dce_wrap, at, p_out, timeout); } -esp_err_t _esp_modem_send_sms(esp_modem_dce_t *dce_wrap, const char *number, const char *message){ - return esp_modem_send_sms(dce_wrap, number, message); +esp_err_t _esp_modem_send_sms(esp_modem_dce_t *dce_wrap, const char *number, const char *message) { + return esp_modem_send_sms(dce_wrap, number, message); } -esp_err_t _esp_modem_set_pin(esp_modem_dce_t *dce_wrap, const char *pin){ - return esp_modem_set_pin(dce_wrap, pin); +esp_err_t _esp_modem_set_pin(esp_modem_dce_t *dce_wrap, const char *pin) { + return esp_modem_set_pin(dce_wrap, pin); } -esp_err_t _esp_modem_at_raw(esp_modem_dce_t *dce_wrap, const char *cmd, char *p_out, const char *pass, const char *fail, int timeout){ - return esp_modem_at_raw(dce_wrap, cmd, p_out, pass, fail, timeout); +esp_err_t _esp_modem_at_raw(esp_modem_dce_t *dce_wrap, const char *cmd, char *p_out, const char *pass, const char *fail, int timeout) { + return esp_modem_at_raw(dce_wrap, cmd, p_out, pass, fail, timeout); } -esp_err_t _esp_modem_set_operator(esp_modem_dce_t *dce_wrap, int mode, int format, const char *oper){ - return esp_modem_set_operator(dce_wrap, mode, format, oper); +esp_err_t _esp_modem_set_operator(esp_modem_dce_t *dce_wrap, int mode, int format, const char *oper) { + return esp_modem_set_operator(dce_wrap, mode, format, oper); } -esp_err_t _esp_modem_set_network_bands(esp_modem_dce_t *dce_wrap, const char *mode, const int *bands, int size){ - return esp_modem_set_network_bands(dce_wrap, mode, bands, size); +esp_err_t _esp_modem_set_network_bands(esp_modem_dce_t *dce_wrap, const char *mode, const int *bands, int size) { + return esp_modem_set_network_bands(dce_wrap, mode, bands, size); } -#endif // CONFIG_LWIP_PPP_SUPPORT +#endif // CONFIG_LWIP_PPP_SUPPORT From 2f09fbaf66faf3f0e0b89f4e9ef21b4743bddd97 Mon Sep 17 00:00:00 2001 From: Me No Dev Date: Thu, 18 Apr 2024 11:04:00 +0300 Subject: [PATCH 4/4] IDF c432c692fa (#9527) --- package/package_esp32_index.template.json | 68 +++++++++++------------ 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/package/package_esp32_index.template.json b/package/package_esp32_index.template.json index ced6417798b..a1fb157c99e 100644 --- a/package/package_esp32_index.template.json +++ b/package/package_esp32_index.template.json @@ -42,7 +42,7 @@ { "packager": "esp32", "name": "esp32-arduino-libs", - "version": "idf--d23b7a0361" + "version": "idf--c432c692fa" }, { "packager": "esp32", @@ -105,63 +105,63 @@ "tools": [ { "name": "esp32-arduino-libs", - "version": "idf--d23b7a0361", + "version": "idf--c432c692fa", "systems": [ { "host": "i686-mingw32", - "url": "https://codeload.github.com/espressif/esp32-arduino-libs/zip/5daaf1a26c12b495975a367cf2c73b86ddee5d31", - "archiveFileName": "esp32-arduino-libs-5daaf1a26c12b495975a367cf2c73b86ddee5d31.zip", - "checksum": "SHA-256:6fe9a5643057449bbbe850cd0e7217f3f6753adc8d5da2807f0c071a1ccb44f1", - "size": "372257794" + "url": "https://codeload.github.com/espressif/esp32-arduino-libs/zip/fbc464148f35fbcc0e93b17a7a21e25b035efedb", + "archiveFileName": "esp32-arduino-libs-fbc464148f35fbcc0e93b17a7a21e25b035efedb.zip", + "checksum": "SHA-256:bbf2d324c310e8a80e0a4c0c6b2464a7d0ffb2509ae2cc2d06e65a260f3d8bae", + "size": "371625301" }, { "host": "x86_64-mingw32", - "url": "https://codeload.github.com/espressif/esp32-arduino-libs/zip/5daaf1a26c12b495975a367cf2c73b86ddee5d31", - "archiveFileName": "esp32-arduino-libs-5daaf1a26c12b495975a367cf2c73b86ddee5d31.zip", - "checksum": "SHA-256:6fe9a5643057449bbbe850cd0e7217f3f6753adc8d5da2807f0c071a1ccb44f1", - "size": "372257794" + "url": "https://codeload.github.com/espressif/esp32-arduino-libs/zip/fbc464148f35fbcc0e93b17a7a21e25b035efedb", + "archiveFileName": "esp32-arduino-libs-fbc464148f35fbcc0e93b17a7a21e25b035efedb.zip", + "checksum": "SHA-256:bbf2d324c310e8a80e0a4c0c6b2464a7d0ffb2509ae2cc2d06e65a260f3d8bae", + "size": "371625301" }, { "host": "arm64-apple-darwin", - "url": "https://codeload.github.com/espressif/esp32-arduino-libs/zip/5daaf1a26c12b495975a367cf2c73b86ddee5d31", - "archiveFileName": "esp32-arduino-libs-5daaf1a26c12b495975a367cf2c73b86ddee5d31.zip", - "checksum": "SHA-256:6fe9a5643057449bbbe850cd0e7217f3f6753adc8d5da2807f0c071a1ccb44f1", - "size": "372257794" + "url": "https://codeload.github.com/espressif/esp32-arduino-libs/zip/fbc464148f35fbcc0e93b17a7a21e25b035efedb", + "archiveFileName": "esp32-arduino-libs-fbc464148f35fbcc0e93b17a7a21e25b035efedb.zip", + "checksum": "SHA-256:bbf2d324c310e8a80e0a4c0c6b2464a7d0ffb2509ae2cc2d06e65a260f3d8bae", + "size": "371625301" }, { "host": "x86_64-apple-darwin", - "url": "https://codeload.github.com/espressif/esp32-arduino-libs/zip/5daaf1a26c12b495975a367cf2c73b86ddee5d31", - "archiveFileName": "esp32-arduino-libs-5daaf1a26c12b495975a367cf2c73b86ddee5d31.zip", - "checksum": "SHA-256:6fe9a5643057449bbbe850cd0e7217f3f6753adc8d5da2807f0c071a1ccb44f1", - "size": "372257794" + "url": "https://codeload.github.com/espressif/esp32-arduino-libs/zip/fbc464148f35fbcc0e93b17a7a21e25b035efedb", + "archiveFileName": "esp32-arduino-libs-fbc464148f35fbcc0e93b17a7a21e25b035efedb.zip", + "checksum": "SHA-256:bbf2d324c310e8a80e0a4c0c6b2464a7d0ffb2509ae2cc2d06e65a260f3d8bae", + "size": "371625301" }, { "host": "x86_64-pc-linux-gnu", - "url": "https://codeload.github.com/espressif/esp32-arduino-libs/zip/5daaf1a26c12b495975a367cf2c73b86ddee5d31", - "archiveFileName": "esp32-arduino-libs-5daaf1a26c12b495975a367cf2c73b86ddee5d31.zip", - "checksum": "SHA-256:6fe9a5643057449bbbe850cd0e7217f3f6753adc8d5da2807f0c071a1ccb44f1", - "size": "372257794" + "url": "https://codeload.github.com/espressif/esp32-arduino-libs/zip/fbc464148f35fbcc0e93b17a7a21e25b035efedb", + "archiveFileName": "esp32-arduino-libs-fbc464148f35fbcc0e93b17a7a21e25b035efedb.zip", + "checksum": "SHA-256:bbf2d324c310e8a80e0a4c0c6b2464a7d0ffb2509ae2cc2d06e65a260f3d8bae", + "size": "371625301" }, { "host": "i686-pc-linux-gnu", - "url": "https://codeload.github.com/espressif/esp32-arduino-libs/zip/5daaf1a26c12b495975a367cf2c73b86ddee5d31", - "archiveFileName": "esp32-arduino-libs-5daaf1a26c12b495975a367cf2c73b86ddee5d31.zip", - "checksum": "SHA-256:6fe9a5643057449bbbe850cd0e7217f3f6753adc8d5da2807f0c071a1ccb44f1", - "size": "372257794" + "url": "https://codeload.github.com/espressif/esp32-arduino-libs/zip/fbc464148f35fbcc0e93b17a7a21e25b035efedb", + "archiveFileName": "esp32-arduino-libs-fbc464148f35fbcc0e93b17a7a21e25b035efedb.zip", + "checksum": "SHA-256:bbf2d324c310e8a80e0a4c0c6b2464a7d0ffb2509ae2cc2d06e65a260f3d8bae", + "size": "371625301" }, { "host": "aarch64-linux-gnu", - "url": "https://codeload.github.com/espressif/esp32-arduino-libs/zip/5daaf1a26c12b495975a367cf2c73b86ddee5d31", - "archiveFileName": "esp32-arduino-libs-5daaf1a26c12b495975a367cf2c73b86ddee5d31.zip", - "checksum": "SHA-256:6fe9a5643057449bbbe850cd0e7217f3f6753adc8d5da2807f0c071a1ccb44f1", - "size": "372257794" + "url": "https://codeload.github.com/espressif/esp32-arduino-libs/zip/fbc464148f35fbcc0e93b17a7a21e25b035efedb", + "archiveFileName": "esp32-arduino-libs-fbc464148f35fbcc0e93b17a7a21e25b035efedb.zip", + "checksum": "SHA-256:bbf2d324c310e8a80e0a4c0c6b2464a7d0ffb2509ae2cc2d06e65a260f3d8bae", + "size": "371625301" }, { "host": "arm-linux-gnueabihf", - "url": "https://codeload.github.com/espressif/esp32-arduino-libs/zip/5daaf1a26c12b495975a367cf2c73b86ddee5d31", - "archiveFileName": "esp32-arduino-libs-5daaf1a26c12b495975a367cf2c73b86ddee5d31.zip", - "checksum": "SHA-256:6fe9a5643057449bbbe850cd0e7217f3f6753adc8d5da2807f0c071a1ccb44f1", - "size": "372257794" + "url": "https://codeload.github.com/espressif/esp32-arduino-libs/zip/fbc464148f35fbcc0e93b17a7a21e25b035efedb", + "archiveFileName": "esp32-arduino-libs-fbc464148f35fbcc0e93b17a7a21e25b035efedb.zip", + "checksum": "SHA-256:bbf2d324c310e8a80e0a4c0c6b2464a7d0ffb2509ae2cc2d06e65a260f3d8bae", + "size": "371625301" } ] },