From 4c42fb00d5222511a68abfdab0e35f4478119d88 Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Mon, 8 Apr 2024 21:34:34 +0300 Subject: [PATCH 1/8] Add esp_modem component --- idf_component.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/idf_component.yml b/idf_component.yml index 634d364ba3a..9e7b566ee3b 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 From 20a7102d8fb41206dc0f6935f44ddfe438efab5c Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Mon, 8 Apr 2024 21:35:48 +0300 Subject: [PATCH 2/8] Add initial PPP Modem support --- cores/esp32/esp32-hal-periman.c | 9 + cores/esp32/esp32-hal-periman.h | 6 + libraries/Network/src/NetworkEvents.cpp | 14 +- libraries/Network/src/NetworkEvents.h | 15 +- libraries/Network/src/NetworkInterface.cpp | 18 +- libraries/PPP/library.properties | 9 + libraries/PPP/src/PPP.cpp | 397 +++++++++++++++++++++ libraries/PPP/src/PPP.h | 69 ++++ 8 files changed, 514 insertions(+), 23 deletions(-) create mode 100644 libraries/PPP/library.properties create mode 100644 libraries/PPP/src/PPP.cpp create mode 100644 libraries/PPP/src/PPP.h diff --git a/cores/esp32/esp32-hal-periman.c b/cores/esp32/esp32-hal-periman.c index dd3a2f32a21..8b5fa431090 100644 --- a/cores/esp32/esp32-hal-periman.c +++ b/cores/esp32/esp32-hal-periman.c @@ -54,14 +54,17 @@ const char* perimanGetTypeName(peripheral_bus_type_t type) { case ESP32_BUS_TYPE_I2S_STD_WS: return "I2S_STD_WS"; case ESP32_BUS_TYPE_I2S_STD_DOUT: return "I2S_STD_DOUT"; case ESP32_BUS_TYPE_I2S_STD_DIN: return "I2S_STD_DIN"; + case ESP32_BUS_TYPE_I2S_TDM_MCLK: return "I2S_TDM_MCLK"; case ESP32_BUS_TYPE_I2S_TDM_BCLK: return "I2S_TDM_BCLK"; case ESP32_BUS_TYPE_I2S_TDM_WS: return "I2S_TDM_WS"; case ESP32_BUS_TYPE_I2S_TDM_DOUT: return "I2S_TDM_DOUT"; case ESP32_BUS_TYPE_I2S_TDM_DIN: return "I2S_TDM_DIN"; + case ESP32_BUS_TYPE_I2S_PDM_TX_CLK: return "I2S_PDM_TX_CLK"; case ESP32_BUS_TYPE_I2S_PDM_TX_DOUT0: return "I2S_PDM_TX_DOUT0"; case ESP32_BUS_TYPE_I2S_PDM_TX_DOUT1: return "I2S_PDM_TX_DOUT1"; + case ESP32_BUS_TYPE_I2S_PDM_RX_CLK: return "I2S_PDM_RX_CLK"; case ESP32_BUS_TYPE_I2S_PDM_RX_DIN0: return "I2S_PDM_RX_DIN0"; case ESP32_BUS_TYPE_I2S_PDM_RX_DIN1: return "I2S_PDM_RX_DIN1"; @@ -104,6 +107,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 aa3de699502..1989ecdb35a 100644 --- a/cores/esp32/esp32-hal-periman.h +++ b/cores/esp32/esp32-hal-periman.h @@ -103,6 +103,12 @@ typedef enum { 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/libraries/Network/src/NetworkEvents.cpp b/libraries/Network/src/NetworkEvents.cpp index 5f24e23a894..5db470f4fce 100644 --- a/libraries/Network/src/NetworkEvents.cpp +++ b/libraries/Network/src/NetworkEvents.cpp @@ -334,13 +334,13 @@ const char * NetworkEvents::eventName(arduino_event_id_t id) { 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_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 eaee117d0fc..5ee4972fdd9 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 01dc53093a9..8800bc69f96 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; } @@ -115,9 +115,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; } 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..5b11915ce2e --- /dev/null +++ b/libraries/PPP/src/PPP.cpp @@ -0,0 +1,397 @@ +#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 + +typedef struct { void * arg; } PdpContext; +#include "esp_modem_api.h" + +static PPPClass * _esp_modem = NULL; +static esp_event_handler_instance_t _ppp_ev_instance = NULL; + +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); + } + } +} + +// This callback needs to be aware of which interface it should match against +static void onPppConnected(arduino_event_id_t event, arduino_event_info_t info) +{ + if(event == ARDUINO_EVENT_PPP_CONNECTED){ + if (_esp_modem->getStatusBits() & ESP_NETIF_WANT_IP6_BIT){ + esp_err_t err = esp_netif_create_ip6_linklocal(_esp_modem->netif()); + if(err != ESP_OK){ + log_e("Failed to enable IPv6 Link Local on PPP: [%d] %s", err, esp_err_to_name(err)); + } else { + log_v("Enabled IPv6 Link Local on %s", _esp_modem->desc()); + } + } + } +} + +esp_modem_dce_t * PPPClass::handle() const { + return _dce; +} + +void PPPClass::_onPppEvent(int32_t event_id, void* event_data){ + arduino_event_t arduino_event; + arduino_event.event_id = ARDUINO_EVENT_MAX; + + log_v("PPP EVENT %ld", event_id); + + // if (event_id == ETHERNET_EVENT_CONNECTED) { + // log_v("%s Connected", desc()); + // arduino_event.event_id = ARDUINO_EVENT_ETH_CONNECTED; + // arduino_event.event_info.eth_connected = handle(); + // setStatusBits(ESP_NETIF_CONNECTED_BIT); + // } else if (event_id == ETHERNET_EVENT_DISCONNECTED) { + // log_v("%s Disconnected", desc()); + // arduino_event.event_id = ARDUINO_EVENT_ETH_DISCONNECTED; + // clearStatusBits(ESP_NETIF_CONNECTED_BIT | ESP_NETIF_HAS_IP_BIT | ESP_NETIF_HAS_LOCAL_IP6_BIT | ESP_NETIF_HAS_GLOBAL_IP6_BIT); + // } else if (event_id == ETHERNET_EVENT_START) { + // log_v("%s Started", desc()); + // arduino_event.event_id = ARDUINO_EVENT_ETH_START; + // setStatusBits(ESP_NETIF_STARTED_BIT); + // } else if (event_id == ETHERNET_EVENT_STOP) { + // log_v("%s Stopped", desc()); + // arduino_event.event_id = ARDUINO_EVENT_ETH_STOP; + // 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); + // } + + if(arduino_event.event_id < ARDUINO_EVENT_MAX){ + Network.postEvent(&arduino_event); + } +} + +PPPClass::PPPClass() + :_dce(NULL) + ,_pin_tx(-1) + ,_pin_rx(-1) + ,_pin_rts(-1) + ,_pin_cts(-1) + ,_pin(NULL) + ,_apn(NULL) + ,_rx_buffer_size(1024) + ,_tx_buffer_size(512) + ,_mode(ESP_MODEM_MODE_COMMAND) +{ +} + +PPPClass::~PPPClass() +{} + +bool PPPClass::pppDetachBus(void * bus_pointer){ + PPPClass *bus = (PPPClass *) bus_pointer; + bus->end(); + return true; +} + +bool PPPClass::begin(ppp_modem_model_t model, int8_t tx, int8_t rx, int8_t rts, int8_t cts, esp_modem_flow_ctrl_t flow_ctrl){ + esp_err_t ret = ESP_OK; + bool pin_ok = false; + + 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; + } + + 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 != -1){ + if(!perimanClearPinBus(_pin_tx)){ return false; } + } + if(_pin_rx != -1){ + if(!perimanClearPinBus(_pin_rx)){ return false; } + } + if(_pin_rts != -1){ + if(!perimanClearPinBus(_pin_rts)){ return false; } + } + if(_pin_cts != -1){ + 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); + + Network.begin(); + _esp_modem = this; + 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 events */ + initNetif(ESP_NETIF_ID_PPP); + + /* Configure the DTE */ + esp_modem_dte_config_t dte_config = ESP_MODEM_DTE_DEFAULT_CONFIG(); + /* setup UART specific configuration based on kconfig options */ + 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.event_queue_size = 20; + dte_config.task_stack_size = 2048; + dte_config.task_priority = 5; + dte_config.dte_buffer_size = _rx_buffer_size / 2; + + /* Configure the DCE */ + esp_modem_dce_config_t dce_config = ESP_MODEM_DCE_DEFAULT_CONFIG(_apn); + _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; + } + + 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 set_flow_control mode: [%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; + } + // delay(1000); + } + + if(_pin_tx != -1){ + if(!perimanSetPinBus(_pin_tx, ESP32_BUS_TYPE_PPP_TX, (void *)(this), -1, -1)){ goto err; } + } + if(_pin_rx != -1){ + if(!perimanSetPinBus(_pin_rx, ESP32_BUS_TYPE_PPP_RX, (void *)(this), -1, -1)){ goto err; } + } + if(_pin_rts != -1){ + if(!perimanSetPinBus(_pin_rts, ESP32_BUS_TYPE_PPP_RTS, (void *)(this), -1, -1)){ goto err; } + } + if(_pin_cts != -1){ + if(!perimanSetPinBus(_pin_cts, ESP32_BUS_TYPE_PPP_CTS, (void *)(this), -1, -1)){ goto err; } + } + + Network.onSysEvent(onPppConnected, ARDUINO_EVENT_PPP_CONNECTED); + + return true; + +err: + log_e("Failed to set all pins bus to ETHERNET"); + PPPClass::pppDetachBus((void *)(this)); + return false; +} + +void PPPClass::end(void) +{ + 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(onPppConnected, ARDUINO_EVENT_PPP_CONNECTED); + + if(_dce != NULL){ + esp_modem_destroy(_dce); + _dce = NULL; + } + + if(_pin_tx != -1){ + perimanClearPinBus(_pin_tx); + _pin_tx = -1; + } + if(_pin_rx != -1){ + perimanClearPinBus(_pin_rx); + _pin_rx = -1; + } + if(_pin_rts != -1){ + perimanClearPinBus(_pin_rts); + _pin_rts = -1; + } + if(_pin_cts != -1){ + perimanClearPinBus(_pin_cts); + _pin_cts = -1; + } + + _mode = ESP_MODEM_MODE_COMMAND; +} + +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 0; + } + + if(_mode != ESP_MODEM_MODE_COMMAND){ + log_e("Wrong modem mode. Should be ESP_MODEM_MODE_COMMAND"); + return 0; + } + + 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 0; + } + return rssi; +} + +int PPPClass::BER() const +{ + if(_dce == NULL){ + return 0; + } + + if(_mode != ESP_MODEM_MODE_COMMAND){ + log_e("Wrong modem mode. Should be ESP_MODEM_MODE_COMMAND"); + return 0; + } + + 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 0; + } + return ber; +} + +String PPPClass::IMSI() const +{ + if(_dce == NULL){ + return String(); + } + + if(_mode != ESP_MODEM_MODE_COMMAND){ + 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::getOperator() const +{ + if(_dce == NULL){ + return String(); + } + + if(_mode != ESP_MODEM_MODE_COMMAND){ + 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); +} + +size_t PPPClass::printDriverInfo(Print & out) const { + size_t bytes = 0; + //bytes += out.print(","); + 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..1a39305264a --- /dev/null +++ b/libraries/PPP/src/PPP.h @@ -0,0 +1,69 @@ +#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 setApn(const char * apn); + bool setPin(const char * pin); + + bool begin(ppp_modem_model_t model, 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); + void end(); + + esp_modem_dce_mode_t mode() const { + return _mode; + } + bool mode(esp_modem_dce_mode_t m); + + // Modem DCE APIs + int RSSI() const; + int BER() const; + String IMSI() const; + String getOperator() const; + + esp_modem_dce_t * handle() const; + + protected: + size_t printDriverInfo(Print & out) const; + + public: + void _onPppEvent(int32_t event_id, void* event_data); + + 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; + const char * _pin; + const char * _apn; + int _rx_buffer_size; + int _tx_buffer_size; + esp_modem_dce_mode_t _mode; + + static bool pppDetachBus(void * bus_pointer); +}; + +extern PPPClass PPP; + +#endif /* CONFIG_LWIP_PPP_SUPPORT */ From 70a74944a67535c531eb94f89b641b53aaa2a47a Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Mon, 8 Apr 2024 23:54:45 +0300 Subject: [PATCH 3/8] Add more access methods --- libraries/PPP/src/PPP.cpp | 203 +++++++++++++++++++++++++++++++++++++- libraries/PPP/src/PPP.h | 19 +++- 2 files changed, 215 insertions(+), 7 deletions(-) diff --git a/libraries/PPP/src/PPP.cpp b/libraries/PPP/src/PPP.cpp index 5b11915ce2e..4234f55655c 100644 --- a/libraries/PPP/src/PPP.cpp +++ b/libraries/PPP/src/PPP.cpp @@ -13,7 +13,7 @@ static PPPClass * _esp_modem = NULL; static esp_event_handler_instance_t _ppp_ev_instance = NULL; static void _ppp_event_cb(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data) { - + log_v("PPP EVENT %ld::%ld", (int)event_base, event_id); if (event_base == NETIF_PPP_STATUS){ if(_esp_modem != NULL){ _esp_modem->_onPppEvent(event_id, event_data); @@ -21,7 +21,10 @@ static void _ppp_event_cb(void* arg, esp_event_base_t event_base, int32_t event_ } } -// This callback needs to be aware of which interface it should match against +static void _ppp_error_cb(esp_modem_terminal_error_t err){ + +} + static void onPppConnected(arduino_event_id_t event, arduino_event_info_t info) { if(event == ARDUINO_EVENT_PPP_CONNECTED){ @@ -172,6 +175,8 @@ bool PPPClass::begin(ppp_modem_model_t model, int8_t tx, int8_t rx, int8_t rts, goto err; } + esp_modem_set_error_cb(_dce, _ppp_error_cb); + 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) { @@ -364,6 +369,48 @@ String PPPClass::IMSI() const return String(imsi); } +String PPPClass::IMEI() const +{ + if(_dce == NULL){ + return String(); + } + + if(_mode != ESP_MODEM_MODE_COMMAND){ + 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_COMMAND){ + 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::getOperator() const { if(_dce == NULL){ @@ -386,6 +433,158 @@ String PPPClass::getOperator() const return String(oper); } +int PPPClass::networkMode() const +{ + if(_dce == NULL){ + return 0; + } + + if(_mode != ESP_MODEM_MODE_COMMAND){ + log_e("Wrong modem mode. Should be ESP_MODEM_MODE_COMMAND"); + return 0; + } + + 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 0; + } + return m; +} + +int PPPClass::radioState() const +{ + if(_dce == NULL){ + return 0; + } + + if(_mode != ESP_MODEM_MODE_COMMAND){ + log_e("Wrong modem mode. Should be ESP_MODEM_MODE_COMMAND"); + return 0; + } + + 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 0; + } + return m; +} + +bool PPPClass::attached() const +{ + if(_dce == NULL){ + return false; + } + + if(_mode != ESP_MODEM_MODE_COMMAND){ + 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::powerDown(){ + if(_dce == NULL){ + return false; + } + + if(_mode != ESP_MODEM_MODE_COMMAND){ + 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_COMMAND){ + 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_COMMAND){ + 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::sms(const char * num, const char * message) { + if(_dce == NULL){ + return false; + } + + if(_mode != ESP_MODEM_MODE_COMMAND){ + 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; +} + size_t PPPClass::printDriverInfo(Print & out) const { size_t bytes = 0; //bytes += out.print(","); diff --git a/libraries/PPP/src/PPP.h b/libraries/PPP/src/PPP.h index 1a39305264a..a9bae8d57d4 100644 --- a/libraries/PPP/src/PPP.h +++ b/libraries/PPP/src/PPP.h @@ -29,16 +29,25 @@ class PPPClass: public NetworkInterface { bool begin(ppp_modem_model_t model, 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); void end(); - esp_modem_dce_mode_t mode() const { - return _mode; - } - bool mode(esp_modem_dce_mode_t m); - // Modem DCE APIs int RSSI() const; int BER() const; String IMSI() const; + String IMEI() const; + String moduleName() const; String getOperator() const; + int networkMode() const; + int radioState() const; + bool attached() const; + + esp_modem_dce_mode_t mode() const { return _mode; } + bool mode(esp_modem_dce_mode_t m); + + bool powerDown(); + bool reset(); + bool storeProfile(); + + bool sms(const char * num, const char * message); esp_modem_dce_t * handle() const; From bcfa7ae02eec62d9e9b7666db5311185cae7c0e5 Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Mon, 8 Apr 2024 23:59:03 +0300 Subject: [PATCH 4/8] Rename Method --- libraries/PPP/src/PPP.cpp | 2 +- libraries/PPP/src/PPP.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/PPP/src/PPP.cpp b/libraries/PPP/src/PPP.cpp index 4234f55655c..cb26ecc2b07 100644 --- a/libraries/PPP/src/PPP.cpp +++ b/libraries/PPP/src/PPP.cpp @@ -411,7 +411,7 @@ String PPPClass::moduleName() const return String(name); } -String PPPClass::getOperator() const +String PPPClass::operatorName() const { if(_dce == NULL){ return String(); diff --git a/libraries/PPP/src/PPP.h b/libraries/PPP/src/PPP.h index a9bae8d57d4..8c38d386cd8 100644 --- a/libraries/PPP/src/PPP.h +++ b/libraries/PPP/src/PPP.h @@ -35,7 +35,7 @@ class PPPClass: public NetworkInterface { String IMSI() const; String IMEI() const; String moduleName() const; - String getOperator() const; + String operatorName() const; int networkMode() const; int radioState() const; bool attached() const; From d70ff49f10e370b094dc787a987630f3a991a1de Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Tue, 9 Apr 2024 00:55:37 +0300 Subject: [PATCH 5/8] Add PPP to configurations --- CMakeLists.txt | 2 ++ Kconfig.projbuild | 10 ++++++++++ 2 files changed, 12 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index cc294494f43..120ed6df967 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -157,6 +157,8 @@ 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) + set(ARDUINO_LIBRARY_Preferences_SRCS libraries/Preferences/src/Preferences.cpp) set(ARDUINO_LIBRARY_RainMaker_SRCS diff --git a/Kconfig.projbuild b/Kconfig.projbuild index af772bd4618..3e45e358d55 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 From e2970a8588de53a702facfc121c0c9fd9576b9be Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Tue, 9 Apr 2024 01:00:55 +0300 Subject: [PATCH 6/8] Update CMakeLists.txt --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 120ed6df967..eeae7e57104 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -95,6 +95,7 @@ set(ARDUINO_ALL_LIBRARIES LittleFS NetBIOS Network + PPP Preferences RainMaker SD_MMC From 4401ef8e0fc60b6e6d918958a3bbf4335cc7c7b5 Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Tue, 9 Apr 2024 01:25:15 +0300 Subject: [PATCH 7/8] fix(ble): rename esp_ble_gap_ext_adv_report_t --- .../BLE/examples/BLE5_extended_scan/BLE5_extended_scan.ino | 2 +- .../BLE/examples/BLE5_periodic_sync/BLE5_periodic_sync.ino | 2 +- libraries/BLE/src/BLEAdvertisedDevice.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/libraries/BLE/examples/BLE5_extended_scan/BLE5_extended_scan.ino b/libraries/BLE/examples/BLE5_extended_scan/BLE5_extended_scan.ino index ebba036e812..ec0f3965175 100644 --- a/libraries/BLE/examples/BLE5_extended_scan/BLE5_extended_scan.ino +++ b/libraries/BLE/examples/BLE5_extended_scan/BLE5_extended_scan.ino @@ -20,7 +20,7 @@ uint32_t scanTime = 100; //In 10ms (1000ms) BLEScan* pBLEScan; class MyBLEExtAdvertisingCallbacks: public BLEExtAdvertisingCallbacks { - void onResult(esp_ble_gap_ext_adv_reprot_t report) { + void onResult(esp_ble_gap_ext_adv_report_t report) { if(report.event_type & ESP_BLE_GAP_SET_EXT_ADV_PROP_LEGACY){ // here we can receive regular advertising data from BLE4.x devices Serial.println("BLE4.2"); diff --git a/libraries/BLE/examples/BLE5_periodic_sync/BLE5_periodic_sync.ino b/libraries/BLE/examples/BLE5_periodic_sync/BLE5_periodic_sync.ino index c3d9eb6cd2b..6be284e2480 100644 --- a/libraries/BLE/examples/BLE5_periodic_sync/BLE5_periodic_sync.ino +++ b/libraries/BLE/examples/BLE5_periodic_sync/BLE5_periodic_sync.ino @@ -28,7 +28,7 @@ static esp_ble_gap_periodic_adv_sync_params_t periodic_adv_sync_params = { class MyBLEExtAdvertisingCallbacks : public BLEExtAdvertisingCallbacks { - void onResult(esp_ble_gap_ext_adv_reprot_t params) + void onResult(esp_ble_gap_ext_adv_report_t params) { uint8_t *adv_name = NULL; uint8_t adv_name_len = 0; diff --git a/libraries/BLE/src/BLEAdvertisedDevice.h b/libraries/BLE/src/BLEAdvertisedDevice.h index e449a0c0799..9e24156da29 100644 --- a/libraries/BLE/src/BLEAdvertisedDevice.h +++ b/libraries/BLE/src/BLEAdvertisedDevice.h @@ -145,7 +145,7 @@ class BLEExtAdvertisingCallbacks { * As we are scanning, we will find new devices. When found, this call back is invoked with a reference to the * device that was found. During any individual scan, a device will only be detected one time. */ - virtual void onResult(esp_ble_gap_ext_adv_reprot_t report) = 0; + virtual void onResult(esp_ble_gap_ext_adv_report_t report) = 0; }; #endif // SOC_BLE_50_SUPPORTED From bcbdba5aa2befe7a55caffae929652607b72f441 Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Tue, 9 Apr 2024 00:13:55 +0000 Subject: [PATCH 8/8] IDF d23b7a0361 --- 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 94bb5c1f75f..533798c9896 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-3662303f31" + "version": "idf--d23b7a0361" }, { "packager": "esp32", @@ -105,63 +105,63 @@ "tools": [ { "name": "esp32-arduino-libs", - "version": "idf-release_v5.1-3662303f31", + "version": "idf--d23b7a0361", "systems": [ { "host": "i686-mingw32", - "url": "https://codeload.github.com/espressif/esp32-arduino-libs/zip/2c6907b9e2b6ff8d7d47c93d622827575190b806", - "archiveFileName": "esp32-arduino-libs-2c6907b9e2b6ff8d7d47c93d622827575190b806.zip", - "checksum": "SHA-256:33998f3ba0cf1080ef6a3c70d477b9d535944191a045f9078d427ee5e79afbe1", - "size": "352415499" + "url": "https://codeload.github.com/espressif/esp32-arduino-libs/zip/465fde8c3158ea6598a7ae140c05c69a8f37d47a", + "archiveFileName": "esp32-arduino-libs-465fde8c3158ea6598a7ae140c05c69a8f37d47a.zip", + "checksum": "SHA-256:8671cabef12826ce6fabe58d0856dec14508890fa0c517a06b5411b331764baa", + "size": "372302667" }, { "host": "x86_64-mingw32", - "url": "https://codeload.github.com/espressif/esp32-arduino-libs/zip/2c6907b9e2b6ff8d7d47c93d622827575190b806", - "archiveFileName": "esp32-arduino-libs-2c6907b9e2b6ff8d7d47c93d622827575190b806.zip", - "checksum": "SHA-256:33998f3ba0cf1080ef6a3c70d477b9d535944191a045f9078d427ee5e79afbe1", - "size": "352415499" + "url": "https://codeload.github.com/espressif/esp32-arduino-libs/zip/465fde8c3158ea6598a7ae140c05c69a8f37d47a", + "archiveFileName": "esp32-arduino-libs-465fde8c3158ea6598a7ae140c05c69a8f37d47a.zip", + "checksum": "SHA-256:8671cabef12826ce6fabe58d0856dec14508890fa0c517a06b5411b331764baa", + "size": "372302667" }, { "host": "arm64-apple-darwin", - "url": "https://codeload.github.com/espressif/esp32-arduino-libs/zip/2c6907b9e2b6ff8d7d47c93d622827575190b806", - "archiveFileName": "esp32-arduino-libs-2c6907b9e2b6ff8d7d47c93d622827575190b806.zip", - "checksum": "SHA-256:33998f3ba0cf1080ef6a3c70d477b9d535944191a045f9078d427ee5e79afbe1", - "size": "352415499" + "url": "https://codeload.github.com/espressif/esp32-arduino-libs/zip/465fde8c3158ea6598a7ae140c05c69a8f37d47a", + "archiveFileName": "esp32-arduino-libs-465fde8c3158ea6598a7ae140c05c69a8f37d47a.zip", + "checksum": "SHA-256:8671cabef12826ce6fabe58d0856dec14508890fa0c517a06b5411b331764baa", + "size": "372302667" }, { "host": "x86_64-apple-darwin", - "url": "https://codeload.github.com/espressif/esp32-arduino-libs/zip/2c6907b9e2b6ff8d7d47c93d622827575190b806", - "archiveFileName": "esp32-arduino-libs-2c6907b9e2b6ff8d7d47c93d622827575190b806.zip", - "checksum": "SHA-256:33998f3ba0cf1080ef6a3c70d477b9d535944191a045f9078d427ee5e79afbe1", - "size": "352415499" + "url": "https://codeload.github.com/espressif/esp32-arduino-libs/zip/465fde8c3158ea6598a7ae140c05c69a8f37d47a", + "archiveFileName": "esp32-arduino-libs-465fde8c3158ea6598a7ae140c05c69a8f37d47a.zip", + "checksum": "SHA-256:8671cabef12826ce6fabe58d0856dec14508890fa0c517a06b5411b331764baa", + "size": "372302667" }, { "host": "x86_64-pc-linux-gnu", - "url": "https://codeload.github.com/espressif/esp32-arduino-libs/zip/2c6907b9e2b6ff8d7d47c93d622827575190b806", - "archiveFileName": "esp32-arduino-libs-2c6907b9e2b6ff8d7d47c93d622827575190b806.zip", - "checksum": "SHA-256:33998f3ba0cf1080ef6a3c70d477b9d535944191a045f9078d427ee5e79afbe1", - "size": "352415499" + "url": "https://codeload.github.com/espressif/esp32-arduino-libs/zip/465fde8c3158ea6598a7ae140c05c69a8f37d47a", + "archiveFileName": "esp32-arduino-libs-465fde8c3158ea6598a7ae140c05c69a8f37d47a.zip", + "checksum": "SHA-256:8671cabef12826ce6fabe58d0856dec14508890fa0c517a06b5411b331764baa", + "size": "372302667" }, { "host": "i686-pc-linux-gnu", - "url": "https://codeload.github.com/espressif/esp32-arduino-libs/zip/2c6907b9e2b6ff8d7d47c93d622827575190b806", - "archiveFileName": "esp32-arduino-libs-2c6907b9e2b6ff8d7d47c93d622827575190b806.zip", - "checksum": "SHA-256:33998f3ba0cf1080ef6a3c70d477b9d535944191a045f9078d427ee5e79afbe1", - "size": "352415499" + "url": "https://codeload.github.com/espressif/esp32-arduino-libs/zip/465fde8c3158ea6598a7ae140c05c69a8f37d47a", + "archiveFileName": "esp32-arduino-libs-465fde8c3158ea6598a7ae140c05c69a8f37d47a.zip", + "checksum": "SHA-256:8671cabef12826ce6fabe58d0856dec14508890fa0c517a06b5411b331764baa", + "size": "372302667" }, { "host": "aarch64-linux-gnu", - "url": "https://codeload.github.com/espressif/esp32-arduino-libs/zip/2c6907b9e2b6ff8d7d47c93d622827575190b806", - "archiveFileName": "esp32-arduino-libs-2c6907b9e2b6ff8d7d47c93d622827575190b806.zip", - "checksum": "SHA-256:33998f3ba0cf1080ef6a3c70d477b9d535944191a045f9078d427ee5e79afbe1", - "size": "352415499" + "url": "https://codeload.github.com/espressif/esp32-arduino-libs/zip/465fde8c3158ea6598a7ae140c05c69a8f37d47a", + "archiveFileName": "esp32-arduino-libs-465fde8c3158ea6598a7ae140c05c69a8f37d47a.zip", + "checksum": "SHA-256:8671cabef12826ce6fabe58d0856dec14508890fa0c517a06b5411b331764baa", + "size": "372302667" }, { "host": "arm-linux-gnueabihf", - "url": "https://codeload.github.com/espressif/esp32-arduino-libs/zip/2c6907b9e2b6ff8d7d47c93d622827575190b806", - "archiveFileName": "esp32-arduino-libs-2c6907b9e2b6ff8d7d47c93d622827575190b806.zip", - "checksum": "SHA-256:33998f3ba0cf1080ef6a3c70d477b9d535944191a045f9078d427ee5e79afbe1", - "size": "352415499" + "url": "https://codeload.github.com/espressif/esp32-arduino-libs/zip/465fde8c3158ea6598a7ae140c05c69a8f37d47a", + "archiveFileName": "esp32-arduino-libs-465fde8c3158ea6598a7ae140c05c69a8f37d47a.zip", + "checksum": "SHA-256:8671cabef12826ce6fabe58d0856dec14508890fa0c517a06b5411b331764baa", + "size": "372302667" } ] },