367 wiersze
10 KiB
C++
367 wiersze
10 KiB
C++
// 1-channel LoRa Gateway for ESP8266
|
|
// Copyright (c) 2016, 2017, 2018 Maarten Westenberg version for ESP8266
|
|
// Version 5.3.2
|
|
// Date: 2018-07-07
|
|
//
|
|
// 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: <none>
|
|
// Return value: Returns 1 when still WL_CONNETED, otherwise returns 0
|
|
// ----------------------------------------------------------------------------
|
|
int WlanStatus() {
|
|
|
|
switch (WiFi.status()) {
|
|
case WL_CONNECTED:
|
|
#if DUSB>=1
|
|
if (debug>=0) {
|
|
Serial.print(F("WlanCStatus:: CONNECTED to")); // 3
|
|
Serial.println(WiFi.SSID());
|
|
}
|
|
#endif
|
|
WiFi.setAutoReconnect(true); // Reconenct to this AP if DISCONNECTED
|
|
return(1);
|
|
break;
|
|
|
|
// In case we get disconnected from the AP we loose the IP address.
|
|
// The ESP is configured to reconnect to the last router in memory.
|
|
case WL_DISCONNECTED:
|
|
#if DUSB>=1
|
|
if (debug>=0) {
|
|
Serial.print(F("WlanStatus:: DISCONNECTED, IP=")); // 6
|
|
Serial.println(WiFi.localIP());
|
|
}
|
|
#endif
|
|
//while (! WiFi.isConnected() ) {
|
|
// Wait
|
|
delay(1);
|
|
//}
|
|
return(0);
|
|
break;
|
|
|
|
// When still pocessing
|
|
case WL_IDLE_STATUS:
|
|
#if DUSB>=1
|
|
if (debug>=0)
|
|
Serial.println(F("WlanStatus:: IDLE")); // 0
|
|
#endif
|
|
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 DUSB>=1
|
|
if (debug>=0)
|
|
Serial.println(F("WlanStatus:: NO SSID")); // 1
|
|
#endif
|
|
break;
|
|
|
|
case WL_CONNECT_FAILED:
|
|
#if DUSB>=1
|
|
if (debug>=0)
|
|
Serial.println(F("WlanStatus:: FAILED")); // 4
|
|
#endif
|
|
break;
|
|
|
|
// Never seen this code
|
|
case WL_SCAN_COMPLETED:
|
|
#if DUSB>=1
|
|
if (debug>=0)
|
|
Serial.println(F("WlanStatus:: SCAN COMPLETE")); // 2
|
|
#endif
|
|
break;
|
|
|
|
// Never seen this code
|
|
case WL_CONNECTION_LOST:
|
|
#if DUSB>=1
|
|
if (debug>=0)
|
|
Serial.println(F("WlanStatus:: LOST")); // 5
|
|
#endif
|
|
break;
|
|
|
|
// This code is generated for example when WiFi.begin() has not been called
|
|
// before accessing WiFi functions
|
|
case WL_NO_SHIELD:
|
|
#if DUSB>=1
|
|
if (debug>=0)
|
|
Serial.println(F("WlanStatus:: WL_NO_SHIELD")); //
|
|
#endif
|
|
break;
|
|
|
|
default:
|
|
#if DUSB>=1
|
|
if (debug>=0) {
|
|
Serial.print(F("WlanStatus:: code="));
|
|
Serial.println(WiFi.status()); // 255 means ERROR
|
|
}
|
|
#endif
|
|
break;
|
|
}
|
|
return(-1);
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// config.txt is a text file that contains lines(!) with WPA configuration items
|
|
// Each line contains an KEY vaue pair describing the gateway configuration
|
|
//
|
|
// ----------------------------------------------------------------------------
|
|
int WlanReadWpa() {
|
|
|
|
readConfig( CONFIGFILE, &gwayConfig);
|
|
|
|
if (gwayConfig.sf != (uint8_t) 0) sf = (sf_t) gwayConfig.sf;
|
|
ifreq = gwayConfig.ch;
|
|
debug = gwayConfig.debug;
|
|
pdebug = gwayConfig.pdebug;
|
|
_cad = gwayConfig.cad;
|
|
_hop = gwayConfig.hop;
|
|
gwayConfig.boots++; // Every boot of the system we increase the reset
|
|
|
|
#if GATEWAYNODE==1
|
|
if (gwayConfig.fcnt != (uint8_t) 0) frameCount = gwayConfig.fcnt+10;
|
|
#endif
|
|
|
|
#if WIFIMANAGER==1
|
|
String ssid=gwayConfig.ssid;
|
|
String pass=gwayConfig.pass;
|
|
|
|
char ssidBuf[ssid.length()+1];
|
|
ssid.toCharArray(ssidBuf,ssid.length()+1);
|
|
char passBuf[pass.length()+1];
|
|
pass.toCharArray(passBuf,pass.length()+1);
|
|
Serial.print(F("WlanReadWpa: ")); Serial.print(ssidBuf); Serial.print(F(", ")); Serial.println(passBuf);
|
|
|
|
strcpy(wpa[0].login, ssidBuf); // XXX changed from wpa[0][0] = ssidBuf
|
|
strcpy(wpa[0].passw, passBuf);
|
|
|
|
Serial.print(F("WlanReadWpa: <"));
|
|
Serial.print(wpa[0].login); // XXX
|
|
Serial.print(F(">, <"));
|
|
Serial.print(wpa[0].passw);
|
|
Serial.println(F(">"));
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// Print the WPA data of last WiFiManager to the config file
|
|
// ----------------------------------------------------------------------------
|
|
#if WIFIMANAGER==1
|
|
int WlanWriteWpa( char* ssid, char *pass) {
|
|
|
|
#if DUSB>=1
|
|
if (( debug >=0 ) && ( pdebug & P_MAIN )) {
|
|
Serial.print(F("WlanWriteWpa:: ssid="));
|
|
Serial.print(ssid);
|
|
Serial.print(F(", pass="));
|
|
Serial.print(pass);
|
|
Serial.println();
|
|
}
|
|
#endif
|
|
// Version 3.3 use of config file
|
|
String s((char *) ssid);
|
|
gwayConfig.ssid = s;
|
|
|
|
String p((char *) pass);
|
|
gwayConfig.pass = p;
|
|
|
|
#if GATEWAYNODE==1
|
|
gwayConfig.fcnt = frameCount;
|
|
#endif
|
|
gwayConfig.ch = ifreq;
|
|
gwayConfig.sf = sf;
|
|
gwayConfig.cad = _cad;
|
|
gwayConfig.hop = _hop;
|
|
|
|
writeConfig( CONFIGFILE, &gwayConfig);
|
|
return 1;
|
|
}
|
|
#endif
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// Function to join the Wifi Network
|
|
// 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 ESP8266 should be reset. Note: Switching between
|
|
// two SSID's does the trick. Rettrying the same SSID does not.
|
|
// Workaround is found below: Let the ESP8266 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) {
|
|
|
|
#if WIFIMANAGER==1
|
|
WiFiManager wifiManager;
|
|
#endif
|
|
|
|
unsigned char agains = 0;
|
|
unsigned char wpa_index = (WIFIMANAGER >0 ? 0 : 1); // Skip over first record for WiFiManager
|
|
|
|
// The initial setup() call is done with parameter 0
|
|
// We clear the WiFi memory and start with previous AP.
|
|
//
|
|
if (maxTry==0) {
|
|
Serial.println(F("WlanConnect:: Init para 0"));
|
|
WiFi.persistent(false);
|
|
WiFi.mode(WIFI_OFF); // this is a temporary line, to be removed after SDK update to 1.5.4
|
|
if (gwayConfig.ssid.length() >0) {
|
|
WiFi.begin(gwayConfig.ssid.c_str(), gwayConfig.pass.c_str());
|
|
delay(100);
|
|
}
|
|
}
|
|
|
|
// So 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 ) )
|
|
{
|
|
|
|
// 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 DUSB>=1
|
|
if (debug>=0) {
|
|
Serial.print(i);
|
|
Serial.print(':');
|
|
Serial.print(j);
|
|
Serial.print(F(". WiFi connect SSID="));
|
|
Serial.print(ssid);
|
|
if ( debug>=1 ) {
|
|
Serial.print(F(", pass="));
|
|
Serial.print(password);
|
|
}
|
|
Serial.println();
|
|
}
|
|
#endif
|
|
// 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); // XXX Write cnfiguration to SPIFFS
|
|
return(1);
|
|
}
|
|
|
|
// We increase the time for connect but try the same SSID
|
|
// We try for 10 times
|
|
agains=1;
|
|
while (((WiFi.status()) != WL_CONNECTED) && (agains < 10)) {
|
|
agains++;
|
|
delay(agains*500);
|
|
#if DUSB>=1
|
|
if ( debug>=0 ) {
|
|
Serial.print(".");
|
|
}
|
|
#endif
|
|
}
|
|
|
|
if ( WiFi.status() == WL_DISCONNECTED) return(0); // wait
|
|
|
|
|
|
// 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 we are not connected to a well known AP
|
|
// we can invoike WIFIMANAGER or else return unsuccessful.
|
|
if (WiFi.status() != WL_CONNECTED) {
|
|
#if WIFIMANAGER==1
|
|
#if DUSB>=1
|
|
Serial.println(F("Starting Access Point Mode"));
|
|
Serial.print(F("Connect Wifi to accesspoint: "));
|
|
Serial.print(AP_NAME);
|
|
Serial.print(F(" and connect to IP: 192.168.4.1"));
|
|
Serial.println();
|
|
#endif
|
|
wifiManager.autoConnect(AP_NAME, AP_PASSWD );
|
|
//wifiManager.startConfigPortal(AP_NAME, AP_PASSWD );
|
|
// 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();
|
|
//char ssidBuf[s.length()+1];
|
|
//s.toCharArray(ssidBuf,s.length()+1);
|
|
// Now look for the password
|
|
struct station_config sta_conf;
|
|
wifi_station_get_config(&sta_conf);
|
|
|
|
//WlanWriteWpa(ssidBuf, (char *)sta_conf.password);
|
|
WlanWriteWpa((char *)sta_conf.ssid, (char *)sta_conf.password);
|
|
#else
|
|
#if DUSB>=1
|
|
if (debug>=0) {
|
|
Serial.println(F("WlanConnect:: Not connected after all"));
|
|
Serial.print(F("WLAN retry="));
|
|
Serial.print(i);
|
|
Serial.print(F(" , stat="));
|
|
Serial.print(WiFi.status() ); // Status. 3 is WL_CONNECTED
|
|
Serial.println();
|
|
}
|
|
#endif// DUSB
|
|
return(-1);
|
|
#endif
|
|
}
|
|
|
|
yield();
|
|
return(1);
|
|
}
|