ESP3D Lib  1.0
3D Printer WiFi Library
wificonfig.cpp
Go to the documentation of this file.
1 /*
2  wificonfig.cpp - wifi functions class
3 
4  Copyright (c) 2014 Luc Lebosse. All rights reserved.
5 
6  This library is free software; you can redistribute it and/or
7  modify it under the terms of the GNU Lesser General Public
8  License as published by the Free Software Foundation; either
9  version 2.1 of the License, or (at your option) any later version.
10 
11  This library is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  Lesser General Public License for more details.
15 
16  You should have received a copy of the GNU Lesser General Public
17  License along with this library; if not, write to the Free Software
18  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20 
21 #ifdef ARDUINO_ARCH_ESP32
22 
23 #include "esplibconfig.h"
24 
25 #if ENABLED(ESP3D_WIFISUPPORT)
26 #include <WiFi.h>
27 #include <esp_wifi.h>
28 #include <ESPmDNS.h>
29 #include <FS.h>
30 #include <SPIFFS.h>
31 #include <Preferences.h>
32 #include "wificonfig.h"
33 #include "wifiservices.h"
34 
35 #ifdef __cplusplus
36 extern "C" {
37 #endif
38 esp_err_t esp_task_wdt_reset();
39 #ifdef __cplusplus
40 }
41 #endif
42 
44 
45 bool WiFiConfig::restart_ESP_module = false;
46 
48 }
49 
51  end();
52 }
53 
58 uint32_t WiFiConfig::IP_int_from_string(String & s){
59  uint32_t ip_int = 0;
60  IPAddress ipaddr;
61  if (ipaddr.fromString(s)) ip_int = ipaddr;
62  return ip_int;
63 }
64 
69 String WiFiConfig::IP_string_from_int(uint32_t ip_int){
70  IPAddress ipaddr(ip_int);
71  return ipaddr.toString();
72 }
73 
78 bool WiFiConfig::isHostnameValid (const char * hostname)
79 {
80  //limited size
81  char c;
82  if (strlen (hostname) > MAX_HOSTNAME_LENGTH || strlen (hostname) < MIN_HOSTNAME_LENGTH) {
83  return false;
84  }
85  //only letter and digit
86  for (int i = 0; i < strlen (hostname); i++) {
87  c = hostname[i];
88  if (! (isdigit (c) || isalpha (c) || c == '_') ) {
89  return false;
90  }
91  if (c == ' ') {
92  return false;
93  }
94  }
95  return true;
96 }
97 
102 bool WiFiConfig::isSSIDValid (const char * ssid)
103 {
104  //limited size
105  //char c;
106  if (strlen (ssid) > MAX_SSID_LENGTH || strlen (ssid) < MIN_SSID_LENGTH) {
107  return false;
108  }
109  //only printable
110  for (int i = 0; i < strlen (ssid); i++) {
111  if (!isPrintable (ssid[i]) ) {
112  return false;
113  }
114  }
115  return true;
116 }
117 
122 bool WiFiConfig::isPasswordValid (const char * password)
123 {
124  if (strlen (password) == 0) return true; //open network
125  //limited size
126  if ((strlen (password) > MAX_PASSWORD_LENGTH) || (strlen (password) < MIN_PASSWORD_LENGTH)) {
127  return false;
128  }
129  //no space allowed ?
130  /* for (int i = 0; i < strlen (password); i++)
131  if (password[i] == ' ') {
132  return false;
133  }*/
134  return true;
135 }
136 
140 bool WiFiConfig::isValidIP(const char * string){
141  IPAddress ip;
142  return ip.fromString(string);
143 }
144 
145 /*
146  * delay is to avoid with asyncwebserver and may need to wait sometimes
147  */
148 void WiFiConfig::wait(uint32_t milliseconds){
149  uint32_t timeout = millis();
150  vTaskDelay(1 / portTICK_RATE_MS); // Yield to other tasks
151  esp_task_wdt_reset(); //for a wait 0;
152  //wait feeding WDT
153  while ( (millis() - timeout) < milliseconds) {
154  esp_task_wdt_reset();
155  vTaskDelay(1 / portTICK_RATE_MS); // Yield to other tasks
156  }
157 }
158 
188 void WiFiConfig::WiFiEvent(WiFiEvent_t event)
189 {
190  switch (event)
191  {
192  case SYSTEM_EVENT_STA_GOT_IP:
193  MYSERIAL0.println ("Connected");
194  MYSERIAL0.println(WiFi.localIP());
195  break;
196  case SYSTEM_EVENT_STA_DISCONNECTED:
197  MYSERIAL0.println("WiFi lost connection");
198  break;
199  default:
200  break;
201  }
202 }
203 
204 /*
205  * Get WiFi signal strength
206  */
207 int32_t WiFiConfig::getSignal (int32_t RSSI)
208 {
209  if (RSSI <= -100) {
210  return 0;
211  }
212  if (RSSI >= -50) {
213  return 100;
214  }
215  return (2 * (RSSI + 100) );
216 }
217 
218 /*
219  * Connect client to AP
220  */
221 
222 bool WiFiConfig::ConnectSTA2AP(){
223  String msg, msg_out;
224  uint8_t count = 0;
225  uint8_t dot = 0;
226  wl_status_t status = WiFi.status();
227  while (status != WL_CONNECTED && count < 40) {
228 
229  switch (status) {
230  case WL_NO_SSID_AVAIL:
231  msg="No SSID";
232  break;
233  case WL_CONNECT_FAILED:
234  msg="Connection failed";
235  break;
236  case WL_CONNECTED:
237  break;
238  default:
239  if ((dot>3) || (dot==0) ){
240  dot=0;
241  msg_out = "Connecting";
242  }
243  msg_out+=".";
244  msg= msg_out;
245  dot++;
246  break;
247  }
248  MYSERIAL0.println(msg.c_str());
249  wait (500);
250  count++;
251  status = WiFi.status();
252  }
253  return (status == WL_CONNECTED);
254 }
255 
256 /*
257  * Start client mode (Station)
258  */
259 
260 bool WiFiConfig::StartSTA(){
261  String defV;
262  Preferences prefs;
263  //stop active service
264  wifi_services.end();
265  //Sanity check
266  if((WiFi.getMode() == WIFI_STA) || (WiFi.getMode() == WIFI_AP_STA))WiFi.disconnect();
267  if((WiFi.getMode() == WIFI_AP) || (WiFi.getMode() == WIFI_AP_STA))WiFi.softAPdisconnect();
268  WiFi.enableAP (false);
269  WiFi.mode(WIFI_STA);
270  //Get parameters for STA
271  prefs.begin(NAMESPACE, true);
272  defV = DEFAULT_HOSTNAME;
273  String h = prefs.getString(HOSTNAME_ENTRY, defV);
274  WiFi.setHostname(h.c_str());
275  //SSID
276  defV = DEFAULT_STA_SSID;
277  String SSID = prefs.getString(STA_SSID_ENTRY, defV);
278  if (SSID.length() == 0)SSID = DEFAULT_STA_SSID;
279  //password
280  defV = DEFAULT_STA_PWD;
281  String password = prefs.getString(STA_PWD_ENTRY, defV);
282  int8_t IP_mode = prefs.getChar(STA_IP_MODE_ENTRY, DHCP_MODE);
283  //IP
284  defV = DEFAULT_STA_IP;
285  int32_t IP = prefs.getInt(STA_IP_ENTRY, IP_int_from_string(defV));
286  //GW
287  defV = DEFAULT_STA_GW;
288  int32_t GW = prefs.getInt(STA_GW_ENTRY, IP_int_from_string(defV));
289  //MK
290  defV = DEFAULT_STA_MK;
291  int32_t MK = prefs.getInt(STA_MK_ENTRY, IP_int_from_string(defV));
292  prefs.end();
293  //if not DHCP
294  if (IP_mode != DHCP_MODE) {
295  IPAddress ip(IP), mask(MK), gateway(GW);
296  WiFi.config(ip, gateway,mask);
297  }
298  if (WiFi.begin(SSID.c_str(), (password.length() > 0)?password.c_str():NULL)){
299  MYSERIAL0.print("\nClient Started\nConnecting ");
300  MYSERIAL0.println(SSID.c_str());
301  return ConnectSTA2AP();
302  } else {
303  MYSERIAL0.println("\nStarting client failed");
304  return false;
305  }
306 }
307 
312 bool WiFiConfig::StartAP(){
313  String defV;
314  Preferences prefs;
315  //stop active services
316  wifi_services.end();
317  //Sanity check
318  if((WiFi.getMode() == WIFI_STA) || (WiFi.getMode() == WIFI_AP_STA))WiFi.disconnect();
319  if((WiFi.getMode() == WIFI_AP) || (WiFi.getMode() == WIFI_AP_STA))WiFi.softAPdisconnect();
320  WiFi.enableSTA (false);
321  WiFi.mode(WIFI_AP);
322  //Get parameters for AP
323  prefs.begin(NAMESPACE, true);
324  //SSID
325  defV = DEFAULT_AP_SSID;
326  String SSID = prefs.getString(AP_SSID_ENTRY, defV);
327  if (SSID.length() == 0)SSID = DEFAULT_AP_SSID;
328  //password
329  defV = DEFAULT_AP_PWD;
330  String password = prefs.getString(AP_PWD_ENTRY, defV);
331  //channel
332  int8_t channel = prefs.getChar(AP_CHANNEL_ENTRY, DEFAULT_AP_CHANNEL);
333  if (channel == 0)channel = DEFAULT_AP_CHANNEL;
334  //IP
335  defV = DEFAULT_AP_IP;
336  int32_t IP = prefs.getInt(AP_IP_ENTRY, IP_int_from_string(defV));
337  if (IP==0){
338  IP = IP_int_from_string(defV);
339  }
340  prefs.end();
341  IPAddress ip(IP);
342  IPAddress mask;
343  mask.fromString(DEFAULT_AP_MK);
344  //Set static IP
345  WiFi.softAPConfig(ip, ip, mask);
346  //Start AP
347  if(WiFi.softAP(SSID.c_str(), (password.length() > 0)?password.c_str():NULL, channel)) {
348  MYSERIAL0.print("\nAP Started ");
349  MYSERIAL0.println(WiFi.softAPIP().toString());
350  return true;
351  } else {
352  MYSERIAL0.println("\nStarting AP failed");
353  return false;
354  }
355 }
356 
361 void WiFiConfig::StopWiFi(){
362  //Sanity check
363  if((WiFi.getMode() == WIFI_STA) || (WiFi.getMode() == WIFI_AP_STA))WiFi.disconnect(true);
364  if((WiFi.getMode() == WIFI_AP) || (WiFi.getMode() == WIFI_AP_STA))WiFi.softAPdisconnect(true);
365  wifi_services.end();
366  WiFi.mode(WIFI_OFF);
367  MYSERIAL0.println("\nWiFi Off");
368 }
369 
373 void WiFiConfig::begin() {
374  Preferences prefs;
375  //stop active services
376  wifi_services.end();
377  //setup events
378  WiFi.onEvent(WiFiConfig::WiFiEvent);
379  //open preferences as read-only
380  prefs.begin(NAMESPACE, true);
381  int8_t wifiMode = prefs.getChar(ESP_WIFI_MODE, DEFAULT_WIFI_MODE);
382  prefs.end();
383  if (wifiMode == ESP_WIFI_AP) {
384  StartAP();
385  //start services
387  } else if (wifiMode == ESP_WIFI_STA){
388  if(!StartSTA()){
389  MYSERIAL0.println("\nCannot connect to AP");
390  StartAP();
391  }
392  //start services
394  }else WiFi.mode(WIFI_OFF);
395 }
396 
400 void WiFiConfig::end() {
401  StopWiFi();
402 }
403 
408  restart_ESP_module=true;
409 }
410 
414 void WiFiConfig::handle() {
415  //in case of restart requested
416  if (restart_ESP_module) {
417  end();
418  ESP.restart();
419  while (1) {};
420  }
421 
422  //Services
424 }
425 
426 
427 #endif // ENABLE_WIFI
428 
429 #endif // ARDUINO_ARCH_ESP32
STA_SSID_ENTRY
#define STA_SSID_ENTRY
Definition: wificonfig.h:38
MAX_HOSTNAME_LENGTH
#define MAX_HOSTNAME_LENGTH
Definition: wificonfig.h:90
wifi_config
WiFiConfig wifi_config
AP_IP_ENTRY
#define AP_IP_ENTRY
Definition: wificonfig.h:46
WiFiServices::end
static void end()
MAX_SSID_LENGTH
#define MAX_SSID_LENGTH
Definition: wificonfig.h:84
DEFAULT_AP_PWD
#define DEFAULT_AP_PWD
Definition: wificonfig.h:75
WiFiConfig::begin
static void begin()
DEFAULT_STA_IP
#define DEFAULT_STA_IP
Definition: wificonfig.h:70
ESP_WIFI_STA
#define ESP_WIFI_STA
Definition: wificonfig.h:56
WiFiServices::begin
static bool begin()
WiFiConfig::StopWiFi
static void StopWiFi()
WiFiConfig
Definition: wificonfig.h:105
AP_SSID_ENTRY
#define AP_SSID_ENTRY
Definition: wificonfig.h:44
DHCP_MODE
#define DHCP_MODE
Definition: wificonfig.h:59
STA_GW_ENTRY
#define STA_GW_ENTRY
Definition: wificonfig.h:41
DEFAULT_STA_MK
#define DEFAULT_STA_MK
Definition: wificonfig.h:72
WiFiConfig::isPasswordValid
static bool isPasswordValid(const char *password)
STA_IP_MODE_ENTRY
#define STA_IP_MODE_ENTRY
Definition: wificonfig.h:52
DEFAULT_WIFI_MODE
#define DEFAULT_WIFI_MODE
Definition: wificonfig.h:73
WiFiConfig::end
static void end()
WiFiConfig::StartAP
static bool StartAP()
MIN_HOSTNAME_LENGTH
#define MIN_HOSTNAME_LENGTH
Definition: wificonfig.h:91
wifiservices.h
WiFiConfig::isHostnameValid
static bool isHostnameValid(const char *hostname)
WiFiServices::handle
static void handle()
WiFiConfig::handle
static void handle()
DEFAULT_STA_GW
#define DEFAULT_STA_GW
Definition: wificonfig.h:71
WiFiConfig::getSignal
static int32_t getSignal(int32_t RSSI)
STA_MK_ENTRY
#define STA_MK_ENTRY
Definition: wificonfig.h:42
WiFiConfig::isValidIP
static bool isValidIP(const char *string)
MYSERIAL0
#define MYSERIAL0
Definition: esplibconfig.h:29
esplibconfig.h
WiFiConfig::~WiFiConfig
~WiFiConfig()
WiFiConfig::WiFiConfig
WiFiConfig()
DEFAULT_AP_CHANNEL
#define DEFAULT_AP_CHANNEL
Definition: wificonfig.h:78
MIN_SSID_LENGTH
#define MIN_SSID_LENGTH
Definition: wificonfig.h:85
ESP_WIFI_MODE
#define ESP_WIFI_MODE
Definition: wificonfig.h:43
MIN_PASSWORD_LENGTH
#define MIN_PASSWORD_LENGTH
Definition: wificonfig.h:89
WiFiConfig::StartSTA
static bool StartSTA()
DEFAULT_STA_PWD
#define DEFAULT_STA_PWD
Definition: wificonfig.h:69
wifi_services
WiFiServices wifi_services
STA_PWD_ENTRY
#define STA_PWD_ENTRY
Definition: wificonfig.h:39
wificonfig.h
NAMESPACE
#define NAMESPACE
Definition: wificonfig.h:36
DEFAULT_STA_SSID
#define DEFAULT_STA_SSID
Definition: wificonfig.h:68
DEFAULT_AP_IP
#define DEFAULT_AP_IP
Definition: wificonfig.h:76
WiFiConfig::IP_string_from_int
static String IP_string_from_int(uint32_t ip_int)
WiFiConfig::isSSIDValid
static bool isSSIDValid(const char *ssid)
WiFiConfig::restart_ESP
static void restart_ESP()
STA_IP_ENTRY
#define STA_IP_ENTRY
Definition: wificonfig.h:40
WiFiConfig::wait
static void wait(uint32_t milliseconds)
DEFAULT_HOSTNAME
#define DEFAULT_HOSTNAME
Definition: wificonfig.h:67
ESP_WIFI_AP
#define ESP_WIFI_AP
Definition: wificonfig.h:57
DEFAULT_AP_SSID
#define DEFAULT_AP_SSID
Definition: wificonfig.h:74
MAX_PASSWORD_LENGTH
#define MAX_PASSWORD_LENGTH
Definition: wificonfig.h:86
AP_PWD_ENTRY
#define AP_PWD_ENTRY
Definition: wificonfig.h:45
HOSTNAME_ENTRY
#define HOSTNAME_ENTRY
Definition: wificonfig.h:37
DEFAULT_AP_MK
#define DEFAULT_AP_MK
Definition: wificonfig.h:77
AP_CHANNEL_ENTRY
#define AP_CHANNEL_ENTRY
Definition: wificonfig.h:47
WiFiConfig::IP_int_from_string
static uint32_t IP_int_from_string(String &s)