Skip to content

Commit cbc75ed

Browse files
committed
feat(ppp): Add support for PPP Modems
1 parent da5c6ab commit cbc75ed

13 files changed

+1149
-31
lines changed

CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ set(ARDUINO_ALL_LIBRARIES
9595
LittleFS
9696
NetBIOS
9797
Network
98+
PPP
9899
Preferences
99100
RainMaker
100101
SD_MMC
@@ -157,6 +158,10 @@ set(ARDUINO_LIBRARY_LittleFS_SRCS libraries/LittleFS/src/LittleFS.cpp)
157158

158159
set(ARDUINO_LIBRARY_NetBIOS_SRCS libraries/NetBIOS/src/NetBIOS.cpp)
159160

161+
set(ARDUINO_LIBRARY_PPP_SRCS
162+
libraries/PPP/src/PPP.cpp
163+
libraries/PPP/src/ppp.c)
164+
160165
set(ARDUINO_LIBRARY_Preferences_SRCS libraries/Preferences/src/Preferences.cpp)
161166

162167
set(ARDUINO_LIBRARY_RainMaker_SRCS

Kconfig.projbuild

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,16 @@ config ARDUINO_SELECTIVE_Networking
321321
depends on ARDUINO_SELECTIVE_COMPILATION
322322
default y
323323

324+
config ARDUINO_SELECTIVE_Ethernet
325+
bool "Enable Ethernet"
326+
depends on ARDUINO_SELECTIVE_COMPILATION
327+
default y
328+
329+
config ARDUINO_SELECTIVE_PPP
330+
bool "Enable PPP"
331+
depends on ARDUINO_SELECTIVE_COMPILATION
332+
default y
333+
324334
config ARDUINO_SELECTIVE_ArduinoOTA
325335
bool "Enable ArduinoOTA"
326336
depends on ARDUINO_SELECTIVE_COMPILATION && ARDUINO_SELECTIVE_Networking

cores/esp32/esp32-hal-periman.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,12 @@ const char* perimanGetTypeName(peripheral_bus_type_t type) {
104104
case ESP32_BUS_TYPE_ETHERNET_MCD: return "ETHERNET_MCD";
105105
case ESP32_BUS_TYPE_ETHERNET_MDIO: return "ETHERNET_MDIO";
106106
case ESP32_BUS_TYPE_ETHERNET_PWR: return "ETHERNET_PWR";
107+
#endif
108+
#if CONFIG_LWIP_PPP_SUPPORT
109+
case ESP32_BUS_TYPE_PPP_TX: return "PPP_MODEM_TX";
110+
case ESP32_BUS_TYPE_PPP_RX: return "PPP_MODEM_RX";
111+
case ESP32_BUS_TYPE_PPP_RTS: return "PPP_MODEM_RTS";
112+
case ESP32_BUS_TYPE_PPP_CTS: return "PPP_MODEM_CTS";
107113
#endif
108114
default: return "UNKNOWN";
109115
}

cores/esp32/esp32-hal-periman.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,12 @@ extern "C" {
102102
ESP32_BUS_TYPE_ETHERNET_MCD, // IO is used as ETHERNET MCD pin
103103
ESP32_BUS_TYPE_ETHERNET_MDIO, // IO is used as ETHERNET MDIO pin
104104
ESP32_BUS_TYPE_ETHERNET_PWR, // IO is used as ETHERNET PWR pin
105+
#endif
106+
#if CONFIG_LWIP_PPP_SUPPORT
107+
ESP32_BUS_TYPE_PPP_TX, // IO is used as PPP Modem TX pin
108+
ESP32_BUS_TYPE_PPP_RX, // IO is used as PPP Modem RX pin
109+
ESP32_BUS_TYPE_PPP_RTS, // IO is used as PPP Modem RTS pin
110+
ESP32_BUS_TYPE_PPP_CTS, // IO is used as PPP Modem CTS pin
105111
#endif
106112
ESP32_BUS_TYPE_MAX
107113
} peripheral_bus_type_t;

idf_component.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ dependencies:
4545
idf: ">=5.1"
4646
# mdns 1.2.1 is necessary to build H2 with no WiFi
4747
mdns: "^1.2.3"
48+
espressif/esp_modem: "^1.1.0"
4849
chmorgan/esp-libhelix-mp3:
4950
version: "1.0.3"
5051
require: public

libraries/Network/src/NetworkEvents.cpp

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -319,16 +319,14 @@ const char *NetworkEvents::eventName(arduino_event_id_t id) {
319319
case ARDUINO_EVENT_ETH_DISCONNECTED: return "ETH_DISCONNECTED";
320320
case ARDUINO_EVENT_ETH_GOT_IP: return "ETH_GOT_IP";
321321
case ARDUINO_EVENT_ETH_LOST_IP: return "ETH_LOST_IP";
322-
case ARDUINO_EVENT_ETH_GOT_IP6:
323-
return "ETH_GOT_IP6";
324-
325-
// case ARDUINO_EVENT_PPP_START: return "PPP_START";
326-
// case ARDUINO_EVENT_PPP_STOP: return "PPP_STOP";
327-
// case ARDUINO_EVENT_PPP_CONNECTED: return "PPP_CONNECTED";
328-
// case ARDUINO_EVENT_PPP_DISCONNECTED: return "PPP_DISCONNECTED";
329-
// case ARDUINO_EVENT_PPP_GOT_IP: return "PPP_GOT_IP";
330-
// case ARDUINO_EVENT_PPP_LOST_IP: return "PPP_LOST_IP";
331-
// case ARDUINO_EVENT_PPP_GOT_IP6: return "PPP_GOT_IP6";
322+
case ARDUINO_EVENT_ETH_GOT_IP6: return "ETH_GOT_IP6";
323+
case ARDUINO_EVENT_PPP_START: return "PPP_START";
324+
case ARDUINO_EVENT_PPP_STOP: return "PPP_STOP";
325+
case ARDUINO_EVENT_PPP_CONNECTED: return "PPP_CONNECTED";
326+
case ARDUINO_EVENT_PPP_DISCONNECTED: return "PPP_DISCONNECTED";
327+
case ARDUINO_EVENT_PPP_GOT_IP: return "PPP_GOT_IP";
328+
case ARDUINO_EVENT_PPP_LOST_IP: return "PPP_LOST_IP";
329+
case ARDUINO_EVENT_PPP_GOT_IP6: return "PPP_GOT_IP6";
332330
#if SOC_WIFI_SUPPORTED
333331
case ARDUINO_EVENT_WIFI_OFF: return "WIFI_OFF";
334332
case ARDUINO_EVENT_WIFI_READY: return "WIFI_READY";

libraries/Network/src/NetworkEvents.h

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -78,13 +78,13 @@ typedef enum {
7878
ARDUINO_EVENT_PROV_CRED_FAIL,
7979
ARDUINO_EVENT_PROV_CRED_SUCCESS,
8080
#endif
81-
// ARDUINO_EVENT_PPP_START,
82-
// ARDUINO_EVENT_PPP_STOP,
83-
// ARDUINO_EVENT_PPP_CONNECTED,
84-
// ARDUINO_EVENT_PPP_DISCONNECTED,
85-
// ARDUINO_EVENT_PPP_GOT_IP,
86-
// ARDUINO_EVENT_PPP_LOST_IP,
87-
// ARDUINO_EVENT_PPP_GOT_IP6,
81+
ARDUINO_EVENT_PPP_START,
82+
ARDUINO_EVENT_PPP_STOP,
83+
ARDUINO_EVENT_PPP_CONNECTED,
84+
ARDUINO_EVENT_PPP_DISCONNECTED,
85+
ARDUINO_EVENT_PPP_GOT_IP,
86+
ARDUINO_EVENT_PPP_LOST_IP,
87+
ARDUINO_EVENT_PPP_GOT_IP6,
8888
ARDUINO_EVENT_MAX
8989
} arduino_event_id_t;
9090

@@ -146,6 +146,7 @@ class NetworkEvents {
146146

147147
friend class ESP_NetworkInterface;
148148
friend class ETHClass;
149+
friend class PPPClass;
149150
#if SOC_WIFI_SUPPORTED
150151
friend class STAClass;
151152
friend class APClass;

libraries/Network/src/NetworkInterface.cpp

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,9 @@ void NetworkInterface::_onIpEvent(int32_t event_id, void* event_data) {
7171
arduino_event.event_id = ARDUINO_EVENT_WIFI_STA_GOT_IP;
7272
} else
7373
#endif
74-
// if(_interface_id == ESP_NETIF_ID_PPP){
75-
// arduino_event.event_id = ARDUINO_EVENT_PPP_GOT_IP;
76-
// } else
74+
if(_interface_id == ESP_NETIF_ID_PPP){
75+
arduino_event.event_id = ARDUINO_EVENT_PPP_GOT_IP;
76+
} else
7777
if (_interface_id >= ESP_NETIF_ID_ETH && _interface_id < ESP_NETIF_ID_MAX) {
7878
arduino_event.event_id = ARDUINO_EVENT_ETH_GOT_IP;
7979
}
@@ -87,9 +87,9 @@ void NetworkInterface::_onIpEvent(int32_t event_id, void* event_data) {
8787
arduino_event.event_id = ARDUINO_EVENT_WIFI_STA_LOST_IP;
8888
} else
8989
#endif
90-
// if(_interface_id == ESP_NETIF_ID_PPP){
91-
// arduino_event.event_id = ARDUINO_EVENT_PPP_LOST_IP;
92-
// } else
90+
if(_interface_id == ESP_NETIF_ID_PPP){
91+
arduino_event.event_id = ARDUINO_EVENT_PPP_LOST_IP;
92+
} else
9393
if (_interface_id >= ESP_NETIF_ID_ETH && _interface_id < ESP_NETIF_ID_MAX) {
9494
arduino_event.event_id = ARDUINO_EVENT_ETH_LOST_IP;
9595
}
@@ -117,9 +117,9 @@ void NetworkInterface::_onIpEvent(int32_t event_id, void* event_data) {
117117
arduino_event.event_id = ARDUINO_EVENT_WIFI_AP_GOT_IP6;
118118
} else
119119
#endif
120-
// if(_interface_id == ESP_NETIF_ID_PPP){
121-
// arduino_event.event_id = ARDUINO_EVENT_PPP_GOT_IP6;
122-
// } else
120+
if(_interface_id == ESP_NETIF_ID_PPP){
121+
arduino_event.event_id = ARDUINO_EVENT_PPP_GOT_IP6;
122+
} else
123123
if (_interface_id >= ESP_NETIF_ID_ETH && _interface_id < ESP_NETIF_ID_MAX) {
124124
arduino_event.event_id = ARDUINO_EVENT_ETH_GOT_IP6;
125125
}
@@ -536,7 +536,7 @@ String NetworkInterface::impl_name(void) const {
536536
char netif_name[8];
537537
esp_err_t err = esp_netif_get_netif_impl_name(_esp_netif, netif_name);
538538
if (err != ESP_OK) {
539-
log_e("Failed to get netif impl_name: %d", err);
539+
log_e("Failed to get netif impl_name: 0x%04x %s", err, esp_err_to_name(err));
540540
return String("");
541541
}
542542
return String(netif_name);
@@ -562,7 +562,7 @@ bool NetworkInterface::setDefault() {
562562
}
563563
esp_err_t err = esp_netif_set_default_netif(_esp_netif);
564564
if (err != ESP_OK) {
565-
log_e("Failed to set default netif: %d", err);
565+
log_e("Failed to set default netif: 0x%04x %s", err, esp_err_to_name(err));
566566
return false;
567567
}
568568
return true;
@@ -576,15 +576,14 @@ bool NetworkInterface::isDefault() const {
576576
}
577577

578578
uint8_t* NetworkInterface::macAddress(uint8_t* mac) const {
579-
if (!mac || _esp_netif == NULL) {
579+
if (!mac || _esp_netif == NULL || _interface_id == ESP_NETIF_ID_PPP) {
580580
return NULL;
581581
}
582582
esp_err_t err = esp_netif_get_mac(_esp_netif, mac);
583583
if (err != ESP_OK) {
584-
log_e("Failed to get netif mac: %d", err);
584+
log_e("Failed to get netif mac: 0x%04x %s", err, esp_err_to_name(err));
585585
return NULL;
586586
}
587-
// getMac(mac);
588587
return mac;
589588
}
590589

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
#include <PPP.h>
2+
3+
#define PPP_MODEM_APN "internet"
4+
#define PPP_MODEM_PIN "0000" // or NULL
5+
6+
// WaveShare SIM7600 HW Flow Control
7+
#define PPP_MODEM_RST 25
8+
#define PPP_MODEM_RST_LOW false //active HIGH
9+
#define PPP_MODEM_TX 21
10+
#define PPP_MODEM_RX 22
11+
#define PPP_MODEM_RTS 26
12+
#define PPP_MODEM_CTS 27
13+
#define PPP_MODEM_FC ESP_MODEM_FLOW_CONTROL_HW
14+
#define PPP_MODEM_MODEL PPP_MODEM_SIM7600
15+
16+
// SIM800 basic module with just TX,RX and RST
17+
// #define PPP_MODEM_RST 0
18+
// #define PPP_MODEM_RST_LOW true //active LOW
19+
// #define PPP_MODEM_TX 2
20+
// #define PPP_MODEM_RX 19
21+
// #define PPP_MODEM_RTS -1
22+
// #define PPP_MODEM_CTS -1
23+
// #define PPP_MODEM_FC ESP_MODEM_FLOW_CONTROL_NONE
24+
// #define PPP_MODEM_MODEL PPP_MODEM_SIM800
25+
26+
void onEvent(arduino_event_id_t event, arduino_event_info_t info)
27+
{
28+
switch (event) {
29+
case ARDUINO_EVENT_PPP_START:
30+
Serial.println("PPP Started");
31+
break;
32+
case ARDUINO_EVENT_PPP_CONNECTED:
33+
Serial.println("PPP Connected");
34+
break;
35+
case ARDUINO_EVENT_PPP_GOT_IP:
36+
Serial.println("PPP Got IP");
37+
break;
38+
case ARDUINO_EVENT_PPP_LOST_IP:
39+
Serial.println("PPP Lost IP");
40+
break;
41+
case ARDUINO_EVENT_PPP_DISCONNECTED:
42+
Serial.println("PPP Disconnected");
43+
break;
44+
case ARDUINO_EVENT_PPP_STOP:
45+
Serial.println("PPP Stopped");
46+
break;
47+
default:
48+
break;
49+
}
50+
}
51+
52+
void testClient(const char * host, uint16_t port) {
53+
NetworkClient client;
54+
if (!client.connect(host, port)) {
55+
Serial.println("Connection Failed");
56+
return;
57+
}
58+
client.printf("GET / HTTP/1.1\r\nHost: %s\r\n\r\n", host);
59+
while (client.connected() && !client.available());
60+
while (client.available()) {
61+
client.read();//Serial.write(client.read());
62+
}
63+
64+
Serial.println("Connection Success");
65+
client.stop();
66+
}
67+
68+
void setup() {
69+
Serial.begin(115200);
70+
71+
// Listen for modem events
72+
Network.onEvent(onEvent);
73+
74+
// Configure the modem
75+
PPP.setApn(PPP_MODEM_APN);
76+
PPP.setPin(PPP_MODEM_PIN);
77+
PPP.setResetPin(PPP_MODEM_RST, PPP_MODEM_RST_LOW);
78+
PPP.setPins(PPP_MODEM_TX, PPP_MODEM_RX, PPP_MODEM_RTS, PPP_MODEM_CTS, PPP_MODEM_FC);
79+
80+
Serial.println("Starting the modem. It might take a while!");
81+
PPP.begin(PPP_MODEM_MODEL);
82+
83+
Serial.print("Manufacturer: "); Serial.println(PPP.cmd("AT+CGMI", 10000));
84+
Serial.print("Model: "); Serial.println(PPP.moduleName());
85+
Serial.print("IMEI: "); Serial.println(PPP.IMEI());
86+
87+
bool attached = PPP.attached();
88+
if(!attached){
89+
int i=0;
90+
unsigned int s = millis();
91+
Serial.print("Waiting to connect to network");
92+
while(!attached && ((++i) < 600)){
93+
Serial.print(".");
94+
delay(100);
95+
attached = PPP.attached();
96+
}
97+
Serial.print((millis() - s) / 1000.0, 1);
98+
Serial.println("s");
99+
attached = PPP.attached();
100+
}
101+
102+
Serial.print("Attached: "); Serial.println(attached);
103+
Serial.print("State: "); Serial.println(PPP.radioState());
104+
if(attached){
105+
Serial.print("Operator: "); Serial.println(PPP.operatorName());
106+
Serial.print("IMSI: "); Serial.println(PPP.IMSI());
107+
Serial.print("RSSI: "); Serial.println(PPP.RSSI());
108+
int ber = PPP.BER();
109+
if(ber > 0){
110+
Serial.print("BER: "); Serial.println(ber);
111+
Serial.print("NetMode: "); Serial.println(PPP.networkMode());
112+
}
113+
114+
Serial.println("Switching to data mode...");
115+
PPP.mode(ESP_MODEM_MODE_CMUX); // Data and Command mixed mode
116+
if(!PPP.waitStatusBits(ESP_NETIF_CONNECTED_BIT, 1000)){
117+
Serial.println("Failed to connect to internet!");
118+
} else {
119+
Serial.println("Connected to internet!");
120+
}
121+
} else {
122+
Serial.println("Failed to connect to network!");
123+
}
124+
}
125+
126+
void loop() {
127+
if (PPP.connected()) {
128+
testClient("google.com", 80);
129+
}
130+
delay(20000);
131+
}

libraries/PPP/library.properties

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
name=PPP
2+
version=1.0.0
3+
author=Hristo Gochkov
4+
maintainer=Hristo Gochkov <hristo@espressif.com>
5+
sentence=Enables network connection using GSM Modem.
6+
paragraph=With this library you can instantiate Servers, Clients and send/receive UDP packets through GSM Modem.
7+
category=Communication
8+
url=
9+
architectures=esp32

0 commit comments

Comments
 (0)