Adafruit Library
Wippersnapper_ESP32.h
Go to the documentation of this file.
1 
17 #ifndef Wippersnapper_ESP32_H
18 #define Wippersnapper_ESP32_H
19 
20 #ifdef ARDUINO_ARCH_ESP32
21 #include "Wippersnapper.h"
22 
23 #include "Adafruit_MQTT.h"
24 #include "Adafruit_MQTT_Client.h"
25 #include "Arduino.h"
26 #include "WiFi.h"
27 #include "WiFiMulti.h"
28 #include <NetworkClient.h>
29 #include <NetworkClientSecure.h>
30 extern Wippersnapper WS;
31 
32 /****************************************************************************/
36 /****************************************************************************/
38 
39 public:
40  /**************************************************************************/
44  /**************************************************************************/
46  _ssid = 0;
47  _pass = 0;
48  }
49 
50  /**************************************************************************/
54  /**************************************************************************/
57  delete _mqtt_client_secure;
59  delete _mqtt_client_insecure;
60  }
61 
62  /********************************************************/
70  /********************************************************/
71  void set_ssid_pass(const char *ssid, const char *ssidPassword) {
72  _ssid = ssid;
73 
74  // set the AP password
75  // check if ssidPassword was "" in secrets.json
76  if ((ssidPassword != NULL) && (strlen(ssidPassword) == 0)) {
77  _pass = NULL; // Set as NULL for open networks
78  } else {
79  _pass = ssidPassword;
80  }
81  }
82 
83  /**********************************************************/
87  /**********************************************************/
88  void set_ssid_pass() {
89  _ssid = WS._config.network.ssid;
90  _pass = WS._config.network.pass;
91  }
92 
93  /***********************************************************/
98  /***********************************************************/
100  // Set WiFi to station mode and disconnect from an AP if it was previously
101  // connected
102  WiFi.mode(WIFI_STA);
103  WiFi.disconnect();
104  delay(100);
105 
106 // For boards with a "3D Antenna", we need to reduce the TX power
107 // to prevent flaky operation.
108 // NOTE: This is a known issue with the QT Py series of boards.
109 #if defined(ARDUINO_ADAFRUIT_QTPY_ESP32S2) || \
110  defined(ARDUINO_ADAFRUIT_QTPY_ESP32S3_NOPSRAM) || \
111  defined(ARDUINO_ADAFRUIT_QTPY_ESP32S3_N4R2) || \
112  defined(ARDUINO_ADAFRUIT_QTPY_ESP32C3) || \
113  defined(ARDUINO_ADAFRUIT_QTPY_ESP32_PICO)
114  WiFi.setTxPower(WIFI_POWER_15dBm);
115 #endif
116 
117  // Perform a network scan
118  int n = WiFi.scanNetworks();
119  if (n == 0) {
120  WS_DEBUG_PRINTLN("ERROR: No WiFi networks found!");
121  return false;
122  }
123 
124  bool foundNetwork = false;
125 
126  WS_DEBUG_PRINTLN("WipperSnapper found these WiFi networks:");
127  for (uint8_t i = 0; i < n; i++) {
128  if (!foundNetwork && strcmp(WiFi.SSID(i).c_str(), _ssid) == 0) {
129  foundNetwork = true;
130  } else if (!foundNetwork && WS._isWiFiMulti) {
131  // multi network mode
132  for (int j = 0; j < WS_MAX_ALT_WIFI_NETWORKS; j++) {
133  if (strcmp(WS._multiNetworks[j].ssid, WiFi.SSID(i).c_str()) == 0) {
134  foundNetwork = true;
135  }
136  }
137  }
138  WS_DEBUG_PRINT(WiFi.SSID(i));
139  WS_DEBUG_PRINT(" (");
140  uint8_t BSSID[WL_MAC_ADDR_LENGTH];
141  WiFi.BSSID(i, BSSID);
142  for (int m = 0; m < WL_MAC_ADDR_LENGTH; m++) {
143  if (m != 0)
144  WS_DEBUG_PRINT(":");
145  WS_DEBUG_PRINTHEX(BSSID[m]);
146  }
147  WS_DEBUG_PRINT(") ");
148  WS_DEBUG_PRINT(WiFi.RSSI(i));
149  WS_DEBUG_PRINT("dB (ch");
150  WS_DEBUG_PRINT(WiFi.channel(i))
151  WS_DEBUG_PRINTLN(")");
152  }
153 
154  if (!foundNetwork) {
155  WS_DEBUG_PRINTLN("ERROR: Your requested WiFi network was not found!");
156  }
157  return foundNetwork;
158  }
159 
160  /********************************************************/
165  /********************************************************/
166  void getMacAddr() {
167  uint8_t mac[6] = {0};
168  Network.macAddress(mac);
169  memcpy(WS._macAddr, mac, sizeof(mac));
170  }
171 
172  /********************************************************/
177  /********************************************************/
178  int32_t getRSSI() { return WiFi.RSSI(); }
179 
180  /********************************************************/
186  /********************************************************/
187  void setupMQTTClient(const char *clientID) {
188  if (strcmp(WS._config.aio_url, "io.adafruit.com") == 0 ||
189  strcmp(WS._config.aio_url, "io.adafruit.us") == 0) {
190  _mqtt_client_secure = new NetworkClientSecure();
191  _mqtt_client_secure->setCACert(
192  strcmp(WS._config.aio_url, "io.adafruit.com") == 0
195  WS._mqtt = new Adafruit_MQTT_Client(
196  _mqtt_client_secure, WS._config.aio_url, WS._config.io_port, clientID,
197  WS._config.aio_user, WS._config.aio_key);
198  } else {
199  if (WS._config.io_port == 8883) {
200  _mqtt_client_secure = new NetworkClientSecure();
201  _mqtt_client_secure->setInsecure();
202  WS._mqtt = new Adafruit_MQTT_Client(
203  _mqtt_client_secure, WS._config.aio_url, WS._config.io_port,
204  clientID, WS._config.aio_user, WS._config.aio_key);
205  } else {
206  // Insecure connections require a NetworkClient object rather than a
207  // NetworkClientSecure object
208  _mqtt_client_insecure = new NetworkClient();
209  WS._mqtt = new Adafruit_MQTT_Client(
210  _mqtt_client_insecure, WS._config.aio_url, WS._config.io_port,
211  clientID, WS._config.aio_user, WS._config.aio_key);
212  }
213  }
214  }
215 
216  /********************************************************/
221  /********************************************************/
223  switch (WiFi.status()) {
224  case WL_CONNECTED:
225  return WS_NET_CONNECTED;
226  case WL_CONNECT_FAILED:
227  return WS_NET_CONNECT_FAILED;
228  case WL_IDLE_STATUS:
229  return WS_IDLE;
230  default:
231  return WS_NET_DISCONNECTED;
232  }
233  }
234 
235  /*******************************************************************/
240  /*******************************************************************/
241  const char *connectionType() { return "ESP32"; }
242 
243 protected:
244  const char *_ssid;
245  const char *_pass;
246  NetworkClientSecure
248  NetworkClient
250  WiFiMulti _wifiMulti;
251 
252  const char *_aio_root_ca_staging =
253  "-----BEGIN CERTIFICATE-----\n"
254  "MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw\n"
255  "TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh\n"
256  "cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4\n"
257  "WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu\n"
258  "ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY\n"
259  "MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc\n"
260  "h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+\n"
261  "0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U\n"
262  "A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW\n"
263  "T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH\n"
264  "B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC\n"
265  "B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv\n"
266  "KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn\n"
267  "OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn\n"
268  "jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw\n"
269  "qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI\n"
270  "rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV\n"
271  "HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq\n"
272  "hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL\n"
273  "ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ\n"
274  "3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK\n"
275  "NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5\n"
276  "ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur\n"
277  "TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC\n"
278  "jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc\n"
279  "oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq\n"
280  "4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA\n"
281  "mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d\n"
282  "emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc=\n"
283  "-----END CERTIFICATE-----\n";
284 
285  const char *_aio_root_ca_prod =
286  "-----BEGIN CERTIFICATE-----\n"
287  "MIIEjTCCA3WgAwIBAgIQDQd4KhM/xvmlcpbhMf/ReTANBgkqhkiG9w0BAQsFADBh\n"
288  "MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3\n"
289  "d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH\n"
290  "MjAeFw0xNzExMDIxMjIzMzdaFw0yNzExMDIxMjIzMzdaMGAxCzAJBgNVBAYTAlVT\n"
291  "MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j\n"
292  "b20xHzAdBgNVBAMTFkdlb1RydXN0IFRMUyBSU0EgQ0EgRzEwggEiMA0GCSqGSIb3\n"
293  "DQEBAQUAA4IBDwAwggEKAoIBAQC+F+jsvikKy/65LWEx/TMkCDIuWegh1Ngwvm4Q\n"
294  "yISgP7oU5d79eoySG3vOhC3w/3jEMuipoH1fBtp7m0tTpsYbAhch4XA7rfuD6whU\n"
295  "gajeErLVxoiWMPkC/DnUvbgi74BJmdBiuGHQSd7LwsuXpTEGG9fYXcbTVN5SATYq\n"
296  "DfbexbYxTMwVJWoVb6lrBEgM3gBBqiiAiy800xu1Nq07JdCIQkBsNpFtZbIZhsDS\n"
297  "fzlGWP4wEmBQ3O67c+ZXkFr2DcrXBEtHam80Gp2SNhou2U5U7UesDL/xgLK6/0d7\n"
298  "6TnEVMSUVJkZ8VeZr+IUIlvoLrtjLbqugb0T3OYXW+CQU0kBAgMBAAGjggFAMIIB\n"
299  "PDAdBgNVHQ4EFgQUlE/UXYvkpOKmgP792PkA76O+AlcwHwYDVR0jBBgwFoAUTiJU\n"
300  "IBiV5uNu5g/6+rkS7QYXjzkwDgYDVR0PAQH/BAQDAgGGMB0GA1UdJQQWMBQGCCsG\n"
301  "AQUFBwMBBggrBgEFBQcDAjASBgNVHRMBAf8ECDAGAQH/AgEAMDQGCCsGAQUFBwEB\n"
302  "BCgwJjAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tMEIGA1Ud\n"
303  "HwQ7MDkwN6A1oDOGMWh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEds\n"
304  "b2JhbFJvb3RHMi5jcmwwPQYDVR0gBDYwNDAyBgRVHSAAMCowKAYIKwYBBQUHAgEW\n"
305  "HGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNvbS9DUFMwDQYJKoZIhvcNAQELBQADggEB\n"
306  "AIIcBDqC6cWpyGUSXAjjAcYwsK4iiGF7KweG97i1RJz1kwZhRoo6orU1JtBYnjzB\n"
307  "c4+/sXmnHJk3mlPyL1xuIAt9sMeC7+vreRIF5wFBC0MCN5sbHwhNN1JzKbifNeP5\n"
308  "ozpZdQFmkCo+neBiKR6HqIA+LMTMCMMuv2khGGuPHmtDze4GmEGZtYLyF8EQpa5Y\n"
309  "jPuV6k2Cr/N3XxFpT3hRpt/3usU/Zb9wfKPtWpoznZ4/44c1p9rzFcZYrWkj3A+7\n"
310  "TNBJE0GmP2fhXhP1D/XVfIW/h0yCJGEiV9Glm/uGOa3DXHlmbAcxSyCRraG+ZBkA\n"
311  "7h4SeM6Y8l/7MBRpPCz6l8Y=\n"
312  "-----END CERTIFICATE-----\n";
313 
314  /**************************************************************************/
318  /**************************************************************************/
319  void _connect() {
320 
321  if (WiFi.status() == WL_CONNECTED)
322  return;
323 
324  if (strlen(_ssid) == 0) {
325  _status = WS_SSID_INVALID;
326  } else {
327  WiFi.setAutoReconnect(false);
328  _disconnect();
329  delay(100);
330  if (WS._isWiFiMulti) {
331  // multi network mode
332  _wifiMulti.APlistClean();
333  _wifiMulti.setAllowOpenAP(false);
334  // add default network
335  _wifiMulti.addAP(_ssid, _pass);
336  // add array of alternative networks
337  for (int i = 0; i < WS_MAX_ALT_WIFI_NETWORKS; i++) {
338  if (strlen(WS._multiNetworks[i].ssid) > 0) {
339  _wifiMulti.addAP(WS._multiNetworks[i].ssid,
340  WS._multiNetworks[i].pass);
341  }
342  }
343  if (_wifiMulti.run(20000) == WL_CONNECTED) {
344  _status = WS_NET_CONNECTED;
345  } else {
346  _status = WS_NET_DISCONNECTED;
347  }
348  } else {
349  // single network mode
350  WiFi.begin(_ssid, _pass);
351  _status = WS_NET_DISCONNECTED;
352  WS.feedWDT();
353  delay(5000);
354  }
355  WS.feedWDT();
356  }
357  }
358 
359  /**************************************************************************/
363  /**************************************************************************/
364  void _disconnect() {
365  WiFi.disconnect();
366  delay(500);
367  }
368 };
369 
370 #endif // ARDUINO_ARCH_ESP32_H
371 #endif // Wippersnapper_ESP32_H
void set_ssid_pass()
Sets the WiFi client&#39;s ssid and password.
Definition: Wippersnapper_ESP32.h:88
#define WS_DEBUG_PRINT(...)
Prints debug output.
Definition: Wippersnapper.h:51
Class for using the ESP32 network interface.
Definition: Wippersnapper_ESP32.h:37
void set_ssid_pass(const char *ssid, const char *ssidPassword)
Sets the WiFi client&#39;s ssid and password.
Definition: Wippersnapper_ESP32.h:71
void _connect()
Establishes a connection with the wireless network.
Definition: Wippersnapper_ESP32.h:319
Wippersnapper_ESP32()
Initializes the Adafruit IO class for ESP32 devices.
Definition: Wippersnapper_ESP32.h:45
bool check_valid_ssid()
Performs a scan of local WiFi networks.
Definition: Wippersnapper_ESP32.h:99
void getMacAddr()
Sets the ESP32&#39;s unique client identifier.
Definition: Wippersnapper_ESP32.h:166
const char * _ssid
WiFi SSID.
Definition: Wippersnapper_ESP32.h:244
#define WS_DEBUG_PRINTHEX(...)
Prints debug output.
Definition: Wippersnapper.h:57
secretsConfig _config
Definition: Wippersnapper.h:399
#define WL_MAC_ADDR_LENGTH
MAC address length - from RP2040 BSP.
Definition: Wippersnapper_Networking.h:20
NetworkClientSecure * _mqtt_client_secure
Pointer to a secure network client object.
Definition: Wippersnapper_ESP32.h:247
ws_status_t
Definition: Wippersnapper.h:188
Class that provides storage and functions for the Adafruit IO Wippersnapper interface.
Definition: Wippersnapper.h:278
int32_t getRSSI()
Gets the current network RSSI value.
Definition: Wippersnapper_ESP32.h:178
ws_status_t networkStatus()
Returns the network status of an ESP32 module.
Definition: Wippersnapper_ESP32.h:222
#define WS_MAX_ALT_WIFI_NETWORKS
Maximum number of alternative networks.
Definition: Wippersnapper.h:249
const char * _pass
WiFi password.
Definition: Wippersnapper_ESP32.h:245
void _disconnect()
Disconnects from the wireless network.
Definition: Wippersnapper_ESP32.h:364
void feedWDT()
Feeds the WDT to prevent hardware reset.
Definition: Wippersnapper.cpp:2628
bool _isWiFiMulti
Definition: Wippersnapper.h:401
const char * _aio_root_ca_prod
Root certificate for io.adafruit.com.
Definition: Wippersnapper_ESP32.h:285
networkConfig _multiNetworks[3]
Definition: Wippersnapper.h:400
Wippersnapper WS
Global WS instance.
Definition: Wippersnapper.cpp:36
const char * _aio_root_ca_staging
Root certificate for io.adafruit.us.
Definition: Wippersnapper_ESP32.h:252
#define WS_DEBUG_PRINTLN(...)
Prints line from debug output.
Definition: Wippersnapper.h:54
void setupMQTTClient(const char *clientID)
Initializes the MQTT client.
Definition: Wippersnapper_ESP32.h:187
~Wippersnapper_ESP32()
Destructor for the Adafruit IO AirLift class.
Definition: Wippersnapper_ESP32.h:55
WiFiMulti _wifiMulti
WiFiMulti object for multi-network mode.
Definition: Wippersnapper_ESP32.h:250
ws_status_t _status
Definition: Wippersnapper.h:476
NetworkClient * _mqtt_client_insecure
Pointer to an insecure network client object.
Definition: Wippersnapper_ESP32.h:249
uint8_t _macAddr[6]
Definition: Wippersnapper.h:393
Adafruit_MQTT * _mqtt
Definition: Wippersnapper.h:397
const char * connectionType()
Returns the type of network connection used by Wippersnapper.
Definition: Wippersnapper_ESP32.h:241