// 1-channel LoRa Gateway for ESP8266 // Copyright (c) 2016-2020 Maarten Westenberg version for ESP8266 // // based on work done by Thomas Telkamp for Raspberry PI 1ch gateway // and many others. // // All rights reserved. This program and the accompanying materials // are made available under the terms of the MIT License // which accompanies this distribution, and is available at // https://opensource.org/licenses/mit-license.php // // NO WARRANTY OF ANY KIND IS PROVIDED // // Author: Maarten Westenberg (mw12554@hotmail.com) // // This file contains the LoRa filesystem specific code // ---------------------------------------------------------------------------- // WLANSTATUS prints the status of the Wlan. // The status of the Wlan "connection" can change if we have no relation // with the well known router anymore. Normally this relation is preserved // but sometimes we have to reconfirm to the router again and we get the same // address too. // So, if the router is still in range we can "survive" with the same address // and we may have to renew the "connection" from time to time. // But when we loose the SSID connection, we may have to look for another router. // // Parameters: // Return value: Returns 1 when still WL_CONNETED, otherwise returns 0 // ---------------------------------------------------------------------------- int WlanStatus() { switch (WiFi.status()) { case WL_CONNECTED: # if _MONITOR>=1 if ( debug>=1 ) { mPrint("WlanStatus:: CONNECTED ssid=" + String(WiFi.SSID())); // 3 } # endif //_MONITOR WiFi.setAutoReconnect(true); // Reconect to this AP if DISCONNECTED return(1); break; // In case we get disconnected from the AP we lose the IP address. // The ESP is configured to reconnect to the last router in memory. case WL_DISCONNECTED: # if _MONITOR>=1 if ( debug>=0 ) { mPrint("WlanStatus:: DISCONNECTED, IP=" + String(WiFi.localIP().toString())); // 6 } # endif //while (! WiFi.isConnected() ) { delay(100); //} return(0); break; // When still pocessing case WL_IDLE_STATUS: # if _MONITOR>=1 if ( debug>=0 ) { mPrint("WlanStatus:: IDLE"); // 0 } # endif //_MONITOR break; // This code is generated as soonas the AP is out of range // Whene detected, the program will search for a better AP in range case WL_NO_SSID_AVAIL: # if _MONITOR>=1 if ( debug>=0 ) mPrint("WlanStatus:: NO SSID"); // 1 # endif //_MONITOR break; case WL_CONNECT_FAILED: # if _MONITOR>=1 if ( debug>=0 ) mPrint("WlanStatus:: Connect FAILED"); // 4 # endif //_MONITOR break; // Never seen this code case WL_SCAN_COMPLETED: # if _MONITOR>=1 if ( debug>=0 ) mPrint("WlanStatus:: SCAN COMPLETE"); // 2 # endif //_MONITOR break; // Never seen this code case WL_CONNECTION_LOST: # if _MONITOR>=1 if ( debug>=0 ) mPrint("WlanStatus:: Connection LOST"); // 5 # endif //_MONITOR break; // This code is generated for example when WiFi.begin() has not been called // before accessing WiFi functions case WL_NO_SHIELD: # if _MONITOR>=1 if ( debug>=0 ) mPrint("WlanStatus:: WL_NO_SHIELD"); // # endif //_MONITOR break; default: # if _MONITOR>=1 if ( debug>=0 ) { mPrint("WlanStatus Error:: code=" + String(WiFi.status())); // 255 means ERROR } # endif //_MONITOR break; } return(-1); } // WlanStatus // ---------------------------------------------------------------------------- // When ESP WiFi Manager, do this // ---------------------------------------------------------------------------- int wifiMgr() { #if _WIFIMANAGER==1 ESP_WiFiManager ESP_wifiManager; # if _MONITOR>=1 if (debug>=1) { mPrint("Starting Access Point Mode"); mPrint("Connect Wifi to accesspoint: "+String(AP_NAME)+" and connect to IP: 192.168.4.1"); } # endif //_MONITOR // Add the ID to the SSID of the WiFiManager String ssid = String(AP_NAME) + "-" + String(ESP_getChipId(), HEX); char s [ssid.length() + 1]; strncpy(s, ssid.c_str(), ssid.length()); s[ssid.length()]= 0; ESP_wifiManager.setConfigPortalTimeout(120); ESP_wifiManager.startConfigPortal(s, AP_PASSWD ); # if _MONITOR>=1 if ((debug>=1) && (pdebug & P_MAIN)) { mPrint("WlanConnect:: Now starting WlanStatus"); delay(1); int i = WlanStatus(); switch (i) { case 1: mPrint("WlanConnect:: WlanStatus Connected"); break; case 0: mPrint("WlanConnect:: WlanStatus Disconnected"); break; default: mPrint("WlatConnect:: WlanStatus other"); } } # endif //_MONITOR // At this point, there IS a Wifi Access Point found and connected // We must connect to the local SPIFFS storage to store the access point //String s = WiFi.SSID(); # if defined(ESP32_ARCH) // # else // Now look for the password struct station_config sta_conf; wifi_station_get_config(&sta_conf); # endif //ESP32_ARCH #endif //_WIFIMANAGER return 1; } // ---------------------------------------------------------------------------- // Function to join the Wifi Network (as defined in sta array // It is a matter of returning to the main loop() asap and make sure in next loop // the reconnect is done first thing. By default the system will reconnect to the // samen SSID as it was connected to before. // Parameters: // int maxTry: Number of retries we do: // 0: Used during Setup first CONNECT // 1: Try once and if unsuccessful return(1); // x: Try x times // // Returns: // On failure: Return -1 // On connect: return 1 // On Disconnect state: return 0 // // XXX After a few retries, the ESP should be reset. Note: Switching between // two SSID's does the trick. Retrying the same SSID does not. // Workaround is found below: Let the ESP forget the SSID // // NOTE: The Serial works only on debug setting and not on pdebug. This is // because WiFi problems would make webserver (which works on WiFi) useless. // ---------------------------------------------------------------------------- int WlanConnect(int maxTry) { unsigned char agains = 0; unsigned char wpa_index = 0; // WiFi.persistent(false); // WiFi.mode(WIFI_OFF); // this is a temporary line, to be removed after SDK update to 1.5.4 // Else: try to connect to WLAN as long as we are not connected. // The try parameters tells us how many times we try before giving up // Value 0 is reserved for setup() first time connect int i=0; while ( (WiFi.status() != WL_CONNECTED) && (( i<= maxTry ) || (maxTry==0)) ) { // We try every SSID in wpa array until success for (int j=wpa_index; (j< (sizeof(wpa)/sizeof(wpa[0]))) && (WiFi.status() != WL_CONNECTED ); j++) { // Start with well-known access points in the list char *ssid = wpa[j].login; char *password = wpa[j].passw; # if _MONITOR>=1 if (debug>=1) { Serial.print(i); Serial.print(':'); Serial.print(j); Serial.print(':'); Serial.print(sizeof(wpa)/sizeof(wpa[0])); Serial.print(F(". WlanConnect SSID=")); Serial.print(ssid); if ( debug>=2 ) { Serial.print(F(", pass=")); Serial.print(password); } Serial.println(); } # endif //_MONITOR // Count the number of times we call WiFi.begin gwayConfig.wifis++; WiFi.mode(WIFI_STA); delay(1000); WiFi.begin(ssid, password); delay(8000); // Check the connection status again, return values // 1 = CONNECTED // 0 = DISCONNECTED (will reconnect) // -1 = No SSID or other cause int stat = WlanStatus(); if ( stat == 1) { writeGwayCfg(CONFIGFILE, &gwayConfig ); // Write configuration to SPIFFS return(1); } // We increase the time for connect but try the same SSID // We try for several times agains=1; while (((WiFi.status()) != WL_CONNECTED) && (agains < 8)) { agains++; delay(8000); //delay(agains*500); # if _MONITOR>=1 if ( debug>=0 ) { Serial.print("."); // Serial only } # endif //_MONITOR } // Make sure that we can connect to different AP's than 1 // this is a patch. Normally we connect to previous one. WiFi.persistent(false); WiFi.mode(WIFI_OFF); // this is a temporary line, to be removed after SDK update to 1.5.4 } //for next WPA defined AP i++; // Number of times we try to connect } //while # if _MONITOR>=1 if ((debug>=2) & (pdebug & P_MAIN)) { mPrint("WlanConnect:: Connected="+ String(WiFi.SSID()) ); } # endif //_MONITOR yield(); return(1); } //WlanConnect // ---------------------------------------------------------------------------- // resolveHost // This function will use MDNS or DNS to resolve a hostname. // So it may be .local or a normal hostname. // Parameters: // svrName: Name of the server we want the IP address from // maxTry: The number we triue to get the value. 0 means: wait forever. // Return: // svrIP: 4 byte IP address of machine resolved // ---------------------------------------------------------------------------- IPAddress resolveHost(String svrName, int maxTry) { IPAddress svrIP; if (svrName.endsWith(".local")) { # if defined(ESP32_ARCH) svrName=svrName.substring(0,svrName.length()-6); svrIP = MDNS.queryHost(svrName); for (byte i=0; i=1) mPrint("ReTrying to resolve with mDNS"); # endif //_MONITOR delay(12000); } # else char cc[svrName.length() +1 ]; strncpy(cc, svrName.c_str(),svrName.length()); cc[svrName.length()]=0; for (byte i=0; i