瀏覽代碼

Version 6.2.5; Initial Version

platenspeler 5 年之前
父節點
當前提交
83bf977eb3
共有 21 個文件被更改,包括 772 次插入627 次删除
  1. 9 0
      CHANGELOG.md
  2. 16 15
      README.md
  3. 6 2
      platformio.ini
  4. 35 30
      src/ESP-sc-gway.ino
  5. 3 3
      src/_WiFi.ino
  6. 2 2
      src/_gatewayMgt.ino
  7. 97 73
      src/_loraFiles.ino
  8. 24 16
      src/_loraModem.ino
  9. 6 6
      src/_oLED.ino
  10. 20 20
      src/_sensor.ino
  11. 23 23
      src/_stateMachine.ino
  12. 1 1
      src/_tcpTTN.ino
  13. 55 95
      src/_txRx.ino
  14. 79 64
      src/_udpSemtech.ino
  15. 13 12
      src/_utils.ino
  16. 295 199
      src/_wwwServer.ino
  17. 59 47
      src/configGway.h
  18. 9 0
      src/configNode.h
  19. 6 6
      src/loraFiles.h
  20. 7 6
      src/loraModem.h
  21. 7 7
      src/oLED.h

+ 9 - 0
CHANGELOG.md

@@ -16,6 +16,15 @@ Maintained by Maarten Westenberg (mw12554@hotmail.com)
 
 
 # Release Notes
 # Release Notes
 
 
+Features release 6.2.5 (April 30, 2020)
+- Repaired SF and BW for upstream
+- Rewrote Monitoring to output only the most significant messages for debug==1
+- Make definitions of LASTSEEN and PACKAGE STATISTICS dynamic. Allowing GUI resizing. 
+Look in expert mode to change these settings
+- Rewrote the addLog() function
+- Repaired typos
+- Removed unncessary serial and MONITOR prints
+
 Features release 6.2.4 (April 25, 2020)
 Features release 6.2.4 (April 25, 2020)
 - Changes the date layout used in the output to be more standard: 3 characters weekday, months and day 2 chars
 - Changes the date layout used in the output to be more standard: 3 characters weekday, months and day 2 chars
 - Changed the configGway.h file a lot ro define default values for parameters while at the 
 - Changed the configGway.h file a lot ro define default values for parameters while at the 

+ 16 - 15
README.md

@@ -1,7 +1,7 @@
 # Single Channel LoRaWAN Gateway
 # Single Channel LoRaWAN Gateway
 
 
-Version 6.2.4, 
-Data: April 25, 2020  
+Version 6.2.5, 
+Data: May 21, 2020  
 Author: M. Westenberg (mw12554@hotmail.com)  
 Author: M. Westenberg (mw12554@hotmail.com)  
 Copyright: M. Westenberg (mw12554@hotmail.com)  
 Copyright: M. Westenberg (mw12554@hotmail.com)  
 
 
@@ -13,13 +13,14 @@ without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 
 
 Maintained by Maarten Westenberg (mw12554@hotmail.com) 
 Maintained by Maarten Westenberg (mw12554@hotmail.com) 
 
 
-
+![logo](https://github.com/things4u/ESP-1ch-Gateway/blob/master/images/illustration-Maarten-In.jpg?raw=true "aap")
+ 
 # Description
 # Description
 
 
 First of all: PLEASE READ THIS FILE AND [Documentation](http://things4u.github.io/Projects/SingleChannelGateway) 
 First of all: PLEASE READ THIS FILE AND [Documentation](http://things4u.github.io/Projects/SingleChannelGateway) 
 it should contain most of the information you need to get going.
 it should contain most of the information you need to get going.
 Unfortunately I do not have the time to follow up on all emails, and as most information including pin-outs 
 Unfortunately I do not have the time to follow up on all emails, and as most information including pin-outs 
-etc etc are contained on these pages I hope you have the time to read them and post any remaining questions.
+etc. etc. are contained on these pages I hope you have the time to read them and post any remaining questions.
 
 
 I do have more than 10 Wemos D1 mini boards running, some I built myself, 
 I do have more than 10 Wemos D1 mini boards running, some I built myself, 
 some 10+ on Hallard, 3 on ComResult and 4 ESP32 boards. They ALL work without problems
 some 10+ on Hallard, 3 on ComResult and 4 ESP32 boards. They ALL work without problems
@@ -55,23 +56,23 @@ At this moment the src directory contains the PlatformIO source, and therefore w
 The applies to the libraries.
 The applies to the libraries.
 
 
 ## PlatformIO
 ## PlatformIO
-When in PlatformIO, choose <File> and then <Add folder to Workspace...> and select the new LoRa-1ch-ESP-Gateway 
+When in PlatformIO, choose <File> and then <Add folder to Workspace...> and select your new LoRa-1ch-ESP-Gateway 
 top directory.
 top directory.
 Then just open the ESP-sc-gway.ino file at src directory and build or upload
 Then just open the ESP-sc-gway.ino file at src directory and build or upload
 
 
 ## Arduino IDE
 ## Arduino IDE
 
 
-Create a place on your filesystem to work on the files. In this directory create the source directory "ESP-sc-gway" 
+Create a place on you filesystem to work on the files. In this directory create the source directory "ESP-sc-gway" 
 and the libraries directory "libraries". When unpacking the source at github: 
 and the libraries directory "libraries". When unpacking the source at github: 
 Copy the content of the "src" directory to the Aruino IDE "ESP-sc-gway" directory and copy the contents 
 Copy the content of the "src" directory to the Aruino IDE "ESP-sc-gway" directory and copy the contents 
-of the "lib" to the Arduino IDE "libraries" directory;
+of the "lib" directory to the Arduino IDE "libraries" directory;
 
 
 ## testing
 ## testing
 
 
 The single channel gateway has been tested on a gateway with the Wemos D1 Mini, 
 The single channel gateway has been tested on a gateway with the Wemos D1 Mini, 
 using a HopeRF RFM95W transceiver.  Tests were done on 868 version of LoRa and some 
 using a HopeRF RFM95W transceiver.  Tests were done on 868 version of LoRa and some 
 testing on 433 MHz.
 testing on 433 MHz.
-The LoRa nodes tested againts this gateway are:
+The LoRa nodes tested against this gateway are:
 
 
 - TeensyLC with HopeRF RFM95 radio
 - TeensyLC with HopeRF RFM95 radio
 - Arduino Pro-Mini (default Armega328 model, 8MHz 3.3V and 16MHz 3.3V)
 - Arduino Pro-Mini (default Armega328 model, 8MHz 3.3V and 16MHz 3.3V)
@@ -203,13 +204,14 @@ Also the gateway may or may not support Class B, which is a superset of class A.
  
  
 ### Selecting you standard pin-out
 ### Selecting you standard pin-out
 
 
-We support two pin-out configurations out-of-the-box: HALLARD and COMPRESULT.
-If you use one of these two, just set the parameter to the right value.
-If your pin definitions are different, update the loraModem.h file to reflect these settings.
+We support five pin-out configurations out-of-the-box, see below.
+If you use one of these, just set the parameter to the right value.
+If your pin definitions are different, update the loraModem.h and oLED.h file to reflect these settings.
 	1: HALLARD
 	1: HALLARD
 	2: COMRESULT pin out
 	2: COMRESULT pin out
-	3: ESP32 pin out
-	4: Other, define your own in loraModem.h
+	3: ESP32/Wemos based board
+	4: ESP32/TTGO based ESP32 boarda
+	5: ESP32/Heltec Wifi LoRA 32(V2)
 
 
  \#define _PIN_OUT 1
  \#define _PIN_OUT 1
 
 
@@ -484,8 +486,7 @@ The following things are still on my wish list to make to the single channel gat
 - Use the SPIFFS for storing .css files
 - Use the SPIFFS for storing .css files
 - Look at Class B and C support
 - Look at Class B and C support
 
 
-![logo](https://github.com/things4u/ESP-1ch-Gateway/blob/master/images/illustration-Maarten-In.jpg?raw=true "aap")
- 
+
 # License
 # License
 
 
 The source files of the gateway sketch in this repository is made available under the MIT
 The source files of the gateway sketch in this repository is made available under the MIT

+ 6 - 2
platformio.ini

@@ -15,33 +15,37 @@ board = d1_mini
 board_build.mcu = esp8266
 board_build.mcu = esp8266
 board_build.f_cpu = 80000000L
 board_build.f_cpu = 80000000L
 build_flags =
 build_flags =
+  -D _PIN_OUT=1
   -D _WIFIMANAGER=0
   -D _WIFIMANAGER=0
   -D _SPIFFS_FORMAT=0
   -D _SPIFFS_FORMAT=0
   -D _OLED=0
   -D _OLED=0
   -D _DUSB=1
   -D _DUSB=1
   -D _PROFILER=1
   -D _PROFILER=1
+  -D _STAT_LOG=1
 framework = arduino
 framework = arduino
 upload_protocol = espota
 upload_protocol = espota
 board_build.flash_mode = qio
 board_build.flash_mode = qio
 upload_speed = 115200
 upload_speed = 115200
 upload_port = 192.168.2.21
 upload_port = 192.168.2.21
 
 
-[env:Gateway_30]
+[env:Gateway_29]
 platform = espressif8266
 platform = espressif8266
 board = d1_mini
 board = d1_mini
 board_build.mcu = esp8266
 board_build.mcu = esp8266
 board_build.f_cpu = 80000000L
 board_build.f_cpu = 80000000L
 build_flags =
 build_flags =
+  -D _PIN_OUT=2
   -D _WIFIMANAGER=0
   -D _WIFIMANAGER=0
   -D _SPIFFS_FORMAT=0
   -D _SPIFFS_FORMAT=0
   -D _OLED=0
   -D _OLED=0
   -D _DUSB=1
   -D _DUSB=1
   -D _PROFILER=1
   -D _PROFILER=1
+  -D _STAT_LOG=0
 framework = arduino
 framework = arduino
 upload_protocol = espota
 upload_protocol = espota
 board_build.flash_mode = qio
 board_build.flash_mode = qio
 upload_speed = 115200
 upload_speed = 115200
-upload_port = 192.168.2.30
+upload_port = 192.168.2.29
 
 
 [env:Gateway_72]
 [env:Gateway_72]
 platform = espressif32
 platform = espressif32

+ 35 - 30
src/ESP-sc-gway.ino

@@ -27,7 +27,7 @@
 #if defined (ARDUINO_ARCH_ESP32) || defined(ESP32)
 #if defined (ARDUINO_ARCH_ESP32) || defined(ESP32)
 #	define ESP32_ARCH 1
 #	define ESP32_ARCH 1
 #	ifndef _PIN_OUT
 #	ifndef _PIN_OUT
-#		define _PIN_OUT 4										// For ESP32 this pin-out is standard
+#		define _PIN_OUT 4									// For ESP32 pin-out 4 is default
 #	endif
 #	endif
 #elif defined(ARDUINO_ARCH_ESP8266)
 #elif defined(ARDUINO_ARCH_ESP8266)
 	//
 	//
@@ -76,7 +76,7 @@ extern "C" {
 
 
 // ----------- Specific ESP32 stuff --------------
 // ----------- Specific ESP32 stuff --------------
 #if defined(ESP32_ARCH)
 #if defined(ESP32_ARCH)
-#	include <WiFi.h>										// MMM added 20Feb
+#	include <WiFi.h>
 #	include <ESPmDNS.h>
 #	include <ESPmDNS.h>
 #	include <SPIFFS.h>
 #	include <SPIFFS.h>
 #	include <WiFiManager.h>								// Standard lib for ESP WiFi config through an AP
 #	include <WiFiManager.h>								// Standard lib for ESP WiFi config through an AP
@@ -86,7 +86,7 @@ extern "C" {
 #	if _SERVER==1
 #	if _SERVER==1
 #		include <WebServer.h>								// Standard Webserver for ESP32
 #		include <WebServer.h>								// Standard Webserver for ESP32
 #		include <Streaming.h>          						// http://arduiniana.org/libraries/streaming/
 #		include <Streaming.h>          						// http://arduiniana.org/libraries/streaming/
-		WebServer server(_SERVERPORT); // MMM added 20Feb
+		WebServer server(_SERVERPORT);
 #	endif //_SERVER
 #	endif //_SERVER
 
 
 #	if _OTA==1
 #	if _OTA==1
@@ -130,7 +130,7 @@ extern "C" {
 // ----------- Declaration of variables --------------
 // ----------- Declaration of variables --------------
 
 
 uint8_t debug=1;											// Debug level! 0 is no msgs, 1 normal, 2 extensive
 uint8_t debug=1;											// Debug level! 0 is no msgs, 1 normal, 2 extensive
-uint8_t pdebug= P_MAIN | P_GUI;								// Initially only MAIN and GUI
+uint8_t pdebug= P_MAIN ;									// Initially only MAIN and GUI
 
 
 #if _GATEWAYNODE==1
 #if _GATEWAYNODE==1
 #	if _GPS==1
 #	if _GPS==1
@@ -152,8 +152,7 @@ uint8_t		MAC_array[6];
 // ----------------------------------------------------------------------------
 // ----------------------------------------------------------------------------
 
 
 // Set spreading factor (SF7 - SF12)
 // Set spreading factor (SF7 - SF12)
-sf_t sf 			= _SPREADING;
-sf_t sfi 			= _SPREADING;							// Initial value of SF
+sf_t sf 			= _SPREADING;							// Initial value of SF					
 
 
 // Set location, description and other configuration parameters
 // Set location, description and other configuration parameters
 // Defined in ESP-sc_gway.h
 // Defined in ESP-sc_gway.h
@@ -183,7 +182,7 @@ uint32_t doneTime = 0;										// Time to expire when CDDONE takes too long
 uint32_t statTime = 0;										// last time we sent a stat message to server
 uint32_t statTime = 0;										// last time we sent a stat message to server
 uint32_t pullTime = 0;										// last time we sent a pull_data request to server
 uint32_t pullTime = 0;										// last time we sent a pull_data request to server
 uint32_t rstTime  = 0;										// When to reset the timer
 uint32_t rstTime  = 0;										// When to reset the timer
-uint32_t fileTime = 0;										// Wite the configuration to file
+uint32_t fileTime = 0;										// Write the configuration to file
 
 
 #define TX_BUFF_SIZE  1024									// Upstream buffer to send to MQTT
 #define TX_BUFF_SIZE  1024									// Upstream buffer to send to MQTT
 #define RX_BUFF_SIZE  1024									// Downstream received from MQTT
 #define RX_BUFF_SIZE  1024									// Downstream received from MQTT
@@ -286,6 +285,8 @@ void setup() {
 	MAC_char[18] = 0;
 	MAC_char[18] = 0;
 	char hostname[12];										// hostname space
 	char hostname[12];										// hostname space
 
 
+	initConfig(&gwayConfig);
+		
 #	if _DUSB>=1
 #	if _DUSB>=1
 		Serial.begin(_BAUDRATE);							// As fast as possible for bus
 		Serial.begin(_BAUDRATE);							// As fast as possible for bus
 		delay(500);
 		delay(500);
@@ -318,7 +319,7 @@ void setup() {
 		msg_oLED("FORMAT");
 		msg_oLED("FORMAT");
 		SPIFFS.format();
 		SPIFFS.format();
 		delay(500);
 		delay(500);
-		initConfig(&gwayConfig);
+		initConfig(&gwayConfig);							// After a format reinit variables
 	}
 	}
 	
 	
 	// If we set SPIFFS_FORMAT in 
 	// If we set SPIFFS_FORMAT in 
@@ -329,7 +330,7 @@ void setup() {
 	initConfig(&gwayConfig);
 	initConfig(&gwayConfig);
 	gwayConfig.formatCntr++;
 	gwayConfig.formatCntr++;
 	if ((debug>=1) && (pdebug & P_MAIN)) {
 	if ((debug>=1) && (pdebug & P_MAIN)) {
-		mPrint("Format SPIFFS Filesystem Done");
+		mPrint("SPIFFS Format Done");
 	}
 	}
 #	endif //_SPIFFS_FORMAT>=1
 #	endif //_SPIFFS_FORMAT>=1
 
 
@@ -349,8 +350,9 @@ void setup() {
 	// Read the config file for all parameters not set in the setup() or configGway.h file
 	// Read the config file for all parameters not set in the setup() or configGway.h file
 	// This file should be read just after SPIFFS is initializen and before
 	// This file should be read just after SPIFFS is initializen and before
 	// other configuration parameters are used.
 	// other configuration parameters are used.
+	// It will overwrite any settings given by initConfig
 	//
 	//
-	if (readGwayCfg(CONFIGFILE, &gwayConfig) > 0) {			// read the Gateway Config
+	if (readGwayCfg(_CONFIGFILE, &gwayConfig) > 0) {			// read the Gateway Config
 #		if _MONITOR>=1
 #		if _MONITOR>=1
 		if (debug>=0) {
 		if (debug>=0) {
 			mPrint("readGwayCfg:: return OK");
 			mPrint("readGwayCfg:: return OK");
@@ -400,7 +402,7 @@ void setup() {
 	yield();
 	yield();
 
 
 #	if _MONITOR>=1
 #	if _MONITOR>=1
-	if ((debug>=1) & ( pdebug & P_MAIN )) {
+	if ((debug>=1) & (pdebug & P_MAIN)) {
 		mPrint("setup:: WlanConnect="+String(WiFi.SSID()) );
 		mPrint("setup:: WlanConnect="+String(WiFi.SSID()) );
 	}
 	}
 #	endif
 #	endif
@@ -461,7 +463,7 @@ void setup() {
 	pinMode(pins.rst, OUTPUT);
 	pinMode(pins.rst, OUTPUT);
     pinMode(pins.dio0, INPUT);								// This pin is interrupt
     pinMode(pins.dio0, INPUT);								// This pin is interrupt
 	pinMode(pins.dio1, INPUT);								// This pin is interrupt
 	pinMode(pins.dio1, INPUT);								// This pin is interrupt
-	//pinMode(pins.dio2, INPUT);							// XXX future expansion
+	//pinMode(pins.dio2, INPUT);								// XXX future expansion
 
 
 	// Init the SPI pins
 	// Init the SPI pins
 #if defined(ESP32_ARCH)
 #if defined(ESP32_ARCH)
@@ -545,7 +547,7 @@ void setup() {
 		}
 		}
 #		endif //_MONITOR
 #		endif //_MONITOR
 
 
-		writeGwayCfg(CONFIGFILE, &gwayConfig );
+		writeGwayCfg(_CONFIGFILE, &gwayConfig );
 	}
 	}
 #	endif //NTP_INTR
 #	endif //NTP_INTR
 
 
@@ -613,17 +615,24 @@ void setup() {
 	// Or in the traditional Comresult case
 	// Or in the traditional Comresult case
 	else {
 	else {
 		attachInterrupt(pins.dio0, Interrupt_0, RISING);	// Separate interrupts
 		attachInterrupt(pins.dio0, Interrupt_0, RISING);	// Separate interrupts
-		attachInterrupt(pins.dio1, Interrupt_1, RISING);	// Separate interrupts		
+		attachInterrupt(pins.dio1, Interrupt_1, RISING);	// Separate interrupts
+		//attachInterrupt(pins.dio2, Interrupt_2, RISING);	// Separate interrupts		
 	}
 	}
-	
-	writeConfig(CONFIGFILE, &gwayConfig);					// Write config
+
+#	if _MONITOR>=1
+	if ((debug>=2) && (pdebug & P_TX)) {
+		mPrint("sendPacket:: STRICT=" + String(_STRICT_1CH) );
+	}
+#	endif //_MONITOR
+
+	writeConfig(_CONFIGFILE, &gwayConfig);					// Write config
 	writeSeen(_SEENFILE, listSeen);							// Write the last time record  is seen
 	writeSeen(_SEENFILE, listSeen);							// Write the last time record  is seen
 
 
 	// activate Oled display
 	// activate Oled display
 #	if _OLED>=1
 #	if _OLED>=1
 		acti_oLED();
 		acti_oLED();
 		addr_oLED();
 		addr_oLED();
-#	endif // _OLED
+#	endif //_OLED
 
 
 	mPrint(" --- Setup() ended, Starting loop() ---");
 	mPrint(" --- Setup() ended, Starting loop() ---");
 
 
@@ -673,7 +682,7 @@ void loop ()
 	//
 	//
 	while( (packetSize= Udp.parsePacket()) > 0) {
 	while( (packetSize= Udp.parsePacket()) > 0) {
 #		if _MONITOR>=1
 #		if _MONITOR>=1
-		if ((debug>=2) && (pdebug & P_TX)){
+		if ((debug>=3) && (pdebug & P_TX)) {
 			mPrint("loop:: readUdp available");
 			mPrint("loop:: readUdp available");
 		}
 		}
 #		endif //_MONITOR
 #		endif //_MONITOR
@@ -712,11 +721,11 @@ void loop ()
 	// So it will kick in if there are not many messages for the gateway.
 	// So it will kick in if there are not many messages for the gateway.
 	// Note: Be careful that it does not happen too often in normal operation.
 	// Note: Be careful that it does not happen too often in normal operation.
 	//
 	//
-	if ( ((nowSeconds - statr[0].time) > _MSG_INTERVAL ) &&
+	if ( ((nowSeconds - statr[0].time) > _MSG_INTERVAL) &&
 		(msgTime <= statr[0].time) ) 
 		(msgTime <= statr[0].time) ) 
 	{
 	{
 #		if _MONITOR>=1
 #		if _MONITOR>=1
-		if (( debug>=2 ) && ( pdebug & P_MAIN )) {
+		if ((debug>=2) && (pdebug & P_MAIN)) {
 			String response="";
 			String response="";
 			response += "REINIT:: ";
 			response += "REINIT:: ";
 			response += String( _MSG_INTERVAL );
 			response += String( _MSG_INTERVAL );
@@ -798,7 +807,7 @@ void loop ()
 				if ((debug>=1) || (pdebug & P_MAIN)) {
 				if ((debug>=1) || (pdebug & P_MAIN)) {
 					mPrint("sensorPacket: Error");
 					mPrint("sensorPacket: Error");
 				}
 				}
-#				endif// _MONITOR
+#				endif //_MONITOR
 			}
 			}
 		}
 		}
 #		endif//_GATEWAYNODE
 #		endif//_GATEWAYNODE
@@ -818,7 +827,7 @@ void loop ()
 		pullTime = nowSeconds;
 		pullTime = nowSeconds;
 		
 		
 #		if _MONITOR>=1
 #		if _MONITOR>=1
-		if ((debug>=1) && (pdebug & P_RX)) {
+		if ((debug>=2) && (pdebug & P_RX)) {
 			String response = "UP ESP-sc-gway:: PKT_PULL_DATA message sent: micr=";
 			String response = "UP ESP-sc-gway:: PKT_PULL_DATA message sent: micr=";
 			printInt(micros(), response);
 			printInt(micros(), response);
 			mPrint(response);
 			mPrint(response);
@@ -867,22 +876,18 @@ void loop ()
 			}
 			}
 			else {
 			else {
 				setTime(newTime);
 				setTime(newTime);
-				if (year(now()) != 1970) {
-#					if _MONITOR>=1
-					if ((debug>=1) && (pdebug & P_MAIN)) {
-						ntptimer = nowSeconds;					// Do not when year(now())=="1970" beacause of "FORMAT"
-					}
-#					endif
+				if (year(now()) != 1970) {						// Do not when year(now())=="1970"
+					ntptimer = nowSeconds;						// beacause of "FORMAT"
 				}
 				}
 			}
 			}
 		}
 		}
 #	endif//NTP_INTR
 #	endif//NTP_INTR
 
 
-#	if _MAXSEEN >= 1
+#	if _MAXSEEN>=1
 		if ((nowSeconds - fileTime) >= _FILE_INTERVAL) {
 		if ((nowSeconds - fileTime) >= _FILE_INTERVAL) {
 			writeSeen(_SEENFILE, listSeen);
 			writeSeen(_SEENFILE, listSeen);
 			fileTime = nowSeconds;
 			fileTime = nowSeconds;
 		}
 		}
-#	endif // _MAXSEEN
+#	endif //_MAXSEEN
 
 
 }//loop
 }//loop

+ 3 - 3
src/_WiFi.ino

@@ -64,7 +64,7 @@ int WlanStatus() {
 #			endif //_MONITOR
 #			endif //_MONITOR
 			break;
 			break;
 		
 		
-		// This code is generated as soonas the AP is out of range
+		// This code is generated as soon as the AP is out of range
 		// Whene detected, the program will search for a better AP in range
 		// Whene detected, the program will search for a better AP in range
 		case WL_NO_SSID_AVAIL:
 		case WL_NO_SSID_AVAIL:
 #			if _MONITOR>=1
 #			if _MONITOR>=1
@@ -161,7 +161,7 @@ int wifiMgr()
 		switch (i) {
 		switch (i) {
 			case 1: mPrint("WlanConnect:: WlanStatus Connected"); break;
 			case 1: mPrint("WlanConnect:: WlanStatus Connected"); break;
 			case 0: mPrint("WlanConnect:: WlanStatus Disconnected"); break;
 			case 0: mPrint("WlanConnect:: WlanStatus Disconnected"); break;
-			default: mPrint("WlatConnect:: WlanStatus other");
+			default: mPrint("WlanConnect:: WlanStatus other");
 		}
 		}
 	}
 	}
 #	endif //_MONITOR 
 #	endif //_MONITOR 
@@ -275,7 +275,7 @@ int WlanConnect(int maxTry) {
 			// -1	= No SSID or other cause			
 			// -1	= No SSID or other cause			
 			int stat = WlanStatus();
 			int stat = WlanStatus();
 			if ( stat == 1) {
 			if ( stat == 1) {
-				writeGwayCfg(CONFIGFILE, &gwayConfig );					// Write configuration to SPIFFS
+				writeGwayCfg(_CONFIGFILE, &gwayConfig );					// Write configuration to SPIFFS
 				return(1);
 				return(1);
 			}
 			}
 		
 		

+ 2 - 2
src/_gatewayMgt.ino

@@ -59,7 +59,7 @@ void gateway_mgt(uint8_t size, uint8_t *buff) {
 		case MGT_RESET:
 		case MGT_RESET:
 #			if _MONITOR>=1
 #			if _MONITOR>=1
 				mPrint(F("gateway_mgt:: RESET"));
 				mPrint(F("gateway_mgt:: RESET"));
-#			endif // _MONITOR
+#			endif //_MONITOR
 			// No further parameters, just reset the GWay
 			// No further parameters, just reset the GWay
 			setup();								// Call the sketch setup function
 			setup();								// Call the sketch setup function
 			// Send Ack to server
 			// Send Ack to server
@@ -74,7 +74,7 @@ void gateway_mgt(uint8_t size, uint8_t *buff) {
 		case MGT_SET_FREQ:
 		case MGT_SET_FREQ:
 #			if _MONITOR>=1
 #			if _MONITOR>=1
 				mPrint(F("gateway_mgt:: SET FREQ"));
 				mPrint(F("gateway_mgt:: SET FREQ"));
-#			endif // _MONITOR
+#			endif //_MONITOR
 			// Byte [4] contains index of Frequency
 			// Byte [4] contains index of Frequency
 		break;
 		break;
 		default:
 		default:

+ 97 - 73
src/_loraFiles.ino

@@ -16,7 +16,7 @@
 // This file contains the LoRa filesystem specific code
 // This file contains the LoRa filesystem specific code
 
 
 
 
-#if _MONITOR>=1
+
 // ----------------------------------------------------------------------------
 // ----------------------------------------------------------------------------
 // LoRa Monitor logging code.
 // LoRa Monitor logging code.
 // Define one print function and depending on the logging parameter output
 // Define one print function and depending on the logging parameter output
@@ -24,14 +24,15 @@
 // ----------------------------------------------------------------------------
 // ----------------------------------------------------------------------------
 int initMonitor(struct moniLine *monitor) 
 int initMonitor(struct moniLine *monitor) 
 {
 {
-	for (int i=0; i< _MAXMONITOR; i++) {
+#if _MONITOR>=1
+	for (int i=0; i< gwayConfig.maxMoni; i++) {
 		monitor[i].txt= "-";						// Make all lines empty
 		monitor[i].txt= "-";						// Make all lines empty
 	}
 	}
 	iMoni=0;										// Init the index
 	iMoni=0;										// Init the index
+#endif //_MONITOR
 	return(1);
 	return(1);
 }
 }
 
 
-#endif //_MONITOR
 
 
 
 
 // ============================================================================
 // ============================================================================
@@ -45,7 +46,7 @@ int initMonitor(struct moniLine *monitor)
 void id_print (String id, String val) 
 void id_print (String id, String val) 
 {
 {
 #if _MONITOR>=1
 #if _MONITOR>=1
-	if (( debug>=0 ) && ( pdebug & P_MAIN )) {
+	if ((debug>=0) && (pdebug & P_MAIN)) {
 		Serial.print(id);
 		Serial.print(id);
 		Serial.print(F("=\t"));
 		Serial.print(F("=\t"));
 		Serial.println(val);
 		Serial.println(val);
@@ -78,6 +79,34 @@ void initConfig(struct espGwayConfig *c)
 	(*c).trusted = 1;
 	(*c).trusted = 1;
 	(*c).txDelay = 0;					// First Value without saving is 0;
 	(*c).txDelay = 0;					// First Value without saving is 0;
 	(*c).dusbStat = true;
 	(*c).dusbStat = true;
+	
+	(*c).maxSeen = _MAXSEEN;
+	(*c).maxStat = _MAXSTAT;
+	(*c).maxMoni = _MAXMONITOR;
+	
+	// We clean all the file statistics. Maybe we can leave them in, but after a fornat
+	// all data has disappeared.
+	(*c).logFileRec = 0;				// In new logFile start with record 0
+	(*c).logFileNo = 0;					// Increase file ID
+
+	// Declarations that are dependent on the init settings
+	// The structure definitions below make it possible to dynamically size and resize the
+	// information in the GUI
+	free(statr); delay(10);
+	statr = (struct stat_t *) malloc((*c).maxStat * sizeof(struct stat_t));
+	for (int i=0; i<(*c).maxStat; i++) {
+		//statr[i].data=0;
+		statr[i].time=0;						// Time since 1970 in seconds		
+		statr[i].node=0;						// 4-byte DEVaddr (the only one known to gateway)
+		statr[i].ch=0;							// Channel index to freqs array
+		statr[i].sf=0;							// Init Spreading Factor
+	}
+
+	free(listSeen); delay(10);
+	listSeen = (struct nodeSeen *) malloc((*c).maxSeen * sizeof(struct nodeSeen));
+	for (int i=0; i<(*c).maxSeen; i+=1) {
+		listSeen[i].idSeen=0;
+	}
 
 
 } // initConfig()
 } // initConfig()
 
 
@@ -107,7 +136,7 @@ int readGwayCfg(const char *fn, struct espGwayConfig *c)
 		}
 		}
 #	endif
 #	endif
 
 
-	writeGwayCfg(CONFIGFILE, &gwayConfig );				// And writeback the configuration, not to miss a boot
+	writeGwayCfg(_CONFIGFILE, &gwayConfig );				// And writeback the configuration, not to miss a boot
 
 
 	return 1;
 	return 1;
 	
 	
@@ -141,7 +170,7 @@ int readConfig(const char *fn, struct espGwayConfig *c)
 	while (f.available()) {
 	while (f.available()) {
 		
 		
 #		if _MONITOR>=1
 #		if _MONITOR>=1
-		if (( debug>=0 ) && ( pdebug & P_MAIN )) {
+		if ((debug>=0) && (pdebug & P_MAIN)) {
 			Serial.print('.');
 			Serial.print('.');
 		}
 		}
 #		endif //_MONITOR
 #		endif //_MONITOR
@@ -254,10 +283,6 @@ int readConfig(const char *fn, struct espGwayConfig *c)
 			id_print(id, val);
 			id_print(id, val);
 			(*c).logFileRec = (uint16_t) val.toInt();
 			(*c).logFileRec = (uint16_t) val.toInt();
 		}
 		}
-		else if (id == "FILENUM") {								// FILEREC setting
-			id_print(id, val);
-			(*c).logFileNum = (uint16_t) val.toInt();
-		}
 		else if (id == "EXPERT") {								// EXPERT button setting
 		else if (id == "EXPERT") {								// EXPERT button setting
 			id_print(id, val);
 			id_print(id, val);
 			(*c).expert = (bool) val.toInt();
 			(*c).expert = (bool) val.toInt();
@@ -357,7 +382,6 @@ int writeConfig(const char *fn, struct espGwayConfig *c)
 	f.print("NTPS");	f.print('='); f.print((*c).ntps);		f.print('\n');
 	f.print("NTPS");	f.print('='); f.print((*c).ntps);		f.print('\n');
 	f.print("FILEREC");	f.print('='); f.print((*c).logFileRec); f.print('\n');
 	f.print("FILEREC");	f.print('='); f.print((*c).logFileRec); f.print('\n');
 	f.print("FILENO");	f.print('='); f.print((*c).logFileNo);	f.print('\n');
 	f.print("FILENO");	f.print('='); f.print((*c).logFileNo);	f.print('\n');
-	f.print("FILENUM");	f.print('='); f.print((*c).logFileNum); f.print('\n');
 	f.print("FORMAT");	f.print('='); f.print((*c).formatCntr); f.print('\n');
 	f.print("FORMAT");	f.print('='); f.print((*c).formatCntr); f.print('\n');
 	f.print("DELAY");	f.print('='); f.print((*c).txDelay); 	f.print('\n');
 	f.print("DELAY");	f.print('='); f.print((*c).txDelay); 	f.print('\n');
 	f.print("TRUSTED");	f.print('='); f.print((*c).trusted); 	f.print('\n');
 	f.print("TRUSTED");	f.print('='); f.print((*c).trusted); 	f.print('\n');
@@ -387,86 +411,85 @@ int writeConfig(const char *fn, struct espGwayConfig *c)
 // ----------------------------------------------------------------------------
 // ----------------------------------------------------------------------------
 int addLog(const unsigned char * line, int cnt) 
 int addLog(const unsigned char * line, int cnt) 
 {
 {
-#	if _STAT_LOG==1
 
 
+#if _STAT_LOG==1
+	File f;
 	char fn[16];
 	char fn[16];
+
+	// If the records does not fit in the file anymore, open a new file
+	
+	if (gwayConfig.logFileRec > LOGFILEREC) {		// If number of records is ;arger than filesize
 	
 	
-	if (gwayConfig.logFileRec > LOGFILEREC) {		// Have to make define for this
 		gwayConfig.logFileRec = 0;					// In new logFile start with record 0
 		gwayConfig.logFileRec = 0;					// In new logFile start with record 0
 		gwayConfig.logFileNo++;						// Increase file ID
 		gwayConfig.logFileNo++;						// Increase file ID
-		gwayConfig.logFileNum++;					// Increase number of log files
-	}
-	gwayConfig.logFileRec++;
-	
-	// If we have too many logfies, delete the oldest
-	//
-	if (gwayConfig.logFileNum > LOGFILEMAX){
-		sprintf(fn,"/log-%d", gwayConfig.logFileNo - LOGFILEMAX);
-#		if _MONITOR>=1
-		if (( debug>=2 ) && ( pdebug & P_GUI )) {
-			mPrint("addLog:: Too many logfiles, deleting="+String(fn));
+		
+		f.close();									// Close the old file
+		
+		sprintf(fn,"/log-%d", gwayConfig.logFileNo);// Make the new name
+
+		if (gwayConfig.logFileNo > LOGFILEMAX) {	// If we have too many logfies, delete the oldest
+			sprintf(fn,"/log-%d", gwayConfig.logFileNo-LOGFILEMAX );
+#			if _MONITOR>=1
+			if ((debug>=1) && (pdebug & P_RX)) {
+				mPrint("addLog:: Too many logfiles, deleting="+String(fn));
+			}
+#			endif //_MONITOR
+			SPIFFS.remove(fn);
 		}
 		}
-#		endif //_MONITOR
-		SPIFFS.remove(fn);
-		gwayConfig.logFileNum--;
 	}
 	}
-	
-	// Make sure we have the right fileno
-	sprintf(fn,"/log-%d", gwayConfig.logFileNo); 
+
+	sprintf(fn,"/log-%d", gwayConfig.logFileNo);	// Make sure we have the right fileno
 	
 	
 	// If there is no SPIFFS, Error
 	// If there is no SPIFFS, Error
 	// Make sure to write the config record/line also
 	// Make sure to write the config record/line also
 	if (!SPIFFS.exists(fn)) {
 	if (!SPIFFS.exists(fn)) {
 #		if _MONITOR>=1
 #		if _MONITOR>=1
-		if (( debug >= 2 ) && ( pdebug & P_GUI )) {
-			mPrint("addLog:: WARNING file="+String(fn)+" does not exist .. rec="+String(gwayConfig.logFileRec) );
+		if ((debug >= 1) && (pdebug & P_RX)) {
+			mPrint("addLog:: WARNING file="+String(fn)+" does not exist. record="+String(gwayConfig.logFileRec) );
 		}
 		}
 #		endif //_MONITOR
 #		endif //_MONITOR
 	}
 	}
 	
 	
-	File f = SPIFFS.open(fn, "a");
+	f = SPIFFS.open(fn, "a");
 	if (!f) {
 	if (!f) {
 #		if _MONITOR>=1
 #		if _MONITOR>=1
-		if (( debug>=1 ) && ( pdebug & P_GUI )) {
+		if ((debug>=1) && (pdebug & P_RX)) {
 			mPrint("addLOG:: ERROR file open failed="+String(fn));
 			mPrint("addLOG:: ERROR file open failed="+String(fn));
 		}
 		}
 #		endif //_MONITOR
 #		endif //_MONITOR
 		return(0);								// If file open failed, return
 		return(0);								// If file open failed, return
 	}
 	}
-	
+#	if _MONITOR>=2
+	else {
+		mPrint("addLog:: Opening adding file="+String(fn));
+	}
+#	endif
+
+
 	int i=0;
 	int i=0;
 #	if _MONITOR>=1
 #	if _MONITOR>=1
-	if (( debug>=2 ) && ( pdebug & P_GUI )) {
-		Serial.print(F("addLog:: fileno="));
-		Serial.print(gwayConfig.logFileNo);
-		Serial.print(F(", rec="));
-		Serial.print(gwayConfig.logFileRec);
-
-		Serial.print(F(": "));
-#		if _MONITOR>=2
-		{
-			for (i=0; i< 12; i++) {				// The first 12 bytes contain non printable characters
-				Serial.print(line[i],HEX);
-				Serial.print(' ');
-			}
-		}
-#		else //_MONITOR>=2
-			i+=12;
-#		endif //_DUSB>=2
-		Serial.print((char *) &line[i]);	// The rest if the buffer contains ascii
-		Serial.println();
+	if ((debug>=1) && (pdebug & P_RX)) {
+		char s[256];
+		i+=12;									// First 12 chars are non printable
+		sprintf(s, "addLog:: fileno=%d, rec=%d : %s",gwayConfig.logFileNo,gwayConfig.logFileRec,&line[i]);
+		mPrint(s);
 	}
 	}
 #	endif //_MONITOR
 #	endif //_MONITOR
 
 
-	for (i=0; i< 12; i++) {					// The first 12 bytes contain non printable characters
+	for (i=0; i< 12; i++) {						// The first 12 bytes contain non printable characters
 	//	f.print(line[i],HEX);
 	//	f.print(line[i],HEX);
 		f.print('*');
 		f.print('*');
 	}
 	}
-	f.write(&(line[i]), cnt-12);			// write/append the line to the file
+	f.print(now());
+	f.print(':');
+	f.write(&(line[i]), cnt-12);				// write/append the line to the file
 	f.print('\n');
 	f.print('\n');
-	f.close();								// Close the file after appending to it
+	
+	f.close();									// Close the file after appending to it
 
 
-#	endif //_STAT_LOG
+#endif //_STAT_LOG
+
+	gwayConfig.logFileRec++;
 
 
 	return(1);
 	return(1);
 } //addLog()
 } //addLog()
@@ -480,7 +503,7 @@ int addLog(const unsigned char * line, int cnt)
 
 
 // ----------------------------------------------------------------------------
 // ----------------------------------------------------------------------------
 // initSeen
 // initSeen
-// Init the lisrScreen array
+// Init the listScreen array
 // Return:
 // Return:
 //	1: Success
 //	1: Success
 // Parameters:
 // Parameters:
@@ -488,8 +511,8 @@ int addLog(const unsigned char * line, int cnt)
 // ----------------------------------------------------------------------------
 // ----------------------------------------------------------------------------
 int initSeen(struct nodeSeen *listSeen) 
 int initSeen(struct nodeSeen *listSeen) 
 {
 {
-#if _MAXSEEN >= 1
-	for (int i=0; i< _MAXSEEN; i++) {
+#if _MAXSEEN>=1
+	for (int i=0; i< gwayConfig.maxSeen; i++) {
 		listSeen[i].idSeen=0;
 		listSeen[i].idSeen=0;
 		listSeen[i].sfSeen=0;
 		listSeen[i].sfSeen=0;
 		listSeen[i].cntSeen=0;
 		listSeen[i].cntSeen=0;
@@ -497,7 +520,7 @@ int initSeen(struct nodeSeen *listSeen)
 		listSeen[i].timSeen=(time_t) 0;					// 1 jan 1970 0:00:00 hrs
 		listSeen[i].timSeen=(time_t) 0;					// 1 jan 1970 0:00:00 hrs
 	}
 	}
 	iSeen= 0;											// Init index to 0
 	iSeen= 0;											// Init index to 0
-#endif // _MAXSEEN
+#endif //_MAXSEEN
 	return(1);
 	return(1);
 
 
 } // initSeen()
 } // initSeen()
@@ -515,7 +538,7 @@ int initSeen(struct nodeSeen *listSeen)
 // ----------------------------------------------------------------------------
 // ----------------------------------------------------------------------------
 int readSeen(const char *fn, struct nodeSeen *listSeen)
 int readSeen(const char *fn, struct nodeSeen *listSeen)
 {
 {
-#if _MAXSEEN >= 1
+#if _MAXSEEN>=1
 	int i;
 	int i;
 	iSeen= 0;												// Init the index at 0
 	iSeen= 0;												// Init the index at 0
 	
 	
@@ -537,7 +560,7 @@ int readSeen(const char *fn, struct nodeSeen *listSeen)
 
 
 	delay(1000);
 	delay(1000);
 	
 	
-	for (i=0; i<_MAXSEEN; i++) {
+	for (i=0; i<gwayConfig.maxSeen; i++) {
 		delay(200);
 		delay(200);
 		String val="";
 		String val="";
 		
 		
@@ -562,7 +585,7 @@ int readSeen(const char *fn, struct nodeSeen *listSeen)
 	}
 	}
 	f.close();
 	f.close();
 
 
-#endif // _MAXSEEN
+#endif //_MAXSEEN
 
 
 	// So we read iSeen records
 	// So we read iSeen records
 	return 1;
 	return 1;
@@ -581,7 +604,7 @@ int readSeen(const char *fn, struct nodeSeen *listSeen)
 // ----------------------------------------------------------------------------
 // ----------------------------------------------------------------------------
 int writeSeen(const char *fn, struct nodeSeen *listSeen)
 int writeSeen(const char *fn, struct nodeSeen *listSeen)
 {
 {
-#if _MAXSEEN >= 1
+#if _MAXSEEN>=1
 	int i;
 	int i;
 	if (!SPIFFS.exists(fn)) {
 	if (!SPIFFS.exists(fn)) {
 #		if _MONITOR>=1
 #		if _MONITOR>=1
@@ -608,9 +631,10 @@ int writeSeen(const char *fn, struct nodeSeen *listSeen)
 	}
 	}
 	
 	
 	f.close();
 	f.close();
-#endif // _MAXSEEN
+#endif //_MAXSEEN
 	return(1);
 	return(1);
-}
+	
+} //writeseen()
 
 
 
 
 
 
@@ -629,7 +653,7 @@ int writeSeen(const char *fn, struct nodeSeen *listSeen)
 // ----------------------------------------------------------------------------
 // ----------------------------------------------------------------------------
 int addSeen(struct nodeSeen *listSeen, struct stat_t stat) 
 int addSeen(struct nodeSeen *listSeen, struct stat_t stat) 
 {
 {
-#if _MAXSEEN >= 1
+#if _MAXSEEN>=1
 	int i;
 	int i;
 	for (i=0; i<iSeen; i++) {						// For all known records
 	for (i=0; i<iSeen; i++) {						// For all known records
 
 
@@ -654,8 +678,8 @@ int addSeen(struct nodeSeen *listSeen, struct stat_t stat)
 		}
 		}
 	}
 	}
 	
 	
-	// else: We did not find the current record so make a new Seen entry
-	if ((i>=iSeen) && (i<_MAXSEEN)) {
+	// else: We did not find the current record so make a new listSeen entry
+	if ((i>=iSeen) && (i<gwayConfig.maxSeen)) {
 		listSeen[i].idSeen = stat.node;
 		listSeen[i].idSeen = stat.node;
 		listSeen[i].chnSeen = stat.ch;
 		listSeen[i].chnSeen = stat.ch;
 		listSeen[i].sfSeen = stat.sf;				// The SF argument
 		listSeen[i].sfSeen = stat.sf;				// The SF argument
@@ -679,11 +703,11 @@ int addSeen(struct nodeSeen *listSeen, struct stat_t stat)
 
 
 		mPrint(response);
 		mPrint(response);
 	}
 	}
-#	endif // _MONITOR
+#	endif //_MONITOR
 
 
 #endif //_MAXSEEN>=1 
 #endif //_MAXSEEN>=1 
 	return 1;
 	return 1;
 	
 	
-} // addSeen()
+} //addSeen()
 
 
 // End of File
 // End of File

+ 24 - 16
src/_loraModem.ino

@@ -196,7 +196,7 @@ void setRate(uint8_t sf, uint8_t crc)
 
 
 	if ((sf<SF7) || (sf>SF12)) {
 	if ((sf<SF7) || (sf>SF12)) {
 #		if _MONITOR>=2
 #		if _MONITOR>=2
-		if (( debug>=1 ) && ( pdebug & P_RADIO )) {
+		if ((debug>=1) && (pdebug & P_RADIO)) {
 			mPrint("setRate:: SF=" + String(sf));
 			mPrint("setRate:: SF=" + String(sf));
 		}
 		}
 #		endif //_MONITOR
 #		endif //_MONITOR
@@ -351,7 +351,7 @@ void hop()
 	// the hop function until printed below
 	// the hop function until printed below
 	//
 	//
 #	if _MONITOR>=1
 #	if _MONITOR>=1
-	if (( debug>=2 ) && ( pdebug & P_RADIO )){
+	if ((debug>=2) && (pdebug & P_RADIO)){
 			String response = "hop:: hopTime:: " + String(micros() - hopTime);
 			String response = "hop:: hopTime:: " + String(micros() - hopTime);
 			mStat(0, response);
 			mStat(0, response);
 			mPrint(response);
 			mPrint(response);
@@ -413,7 +413,7 @@ uint8_t receivePkt(uint8_t *payload)
     if (irqflags & IRQ_LORA_CRCERR_MASK)								// Is CRC error?
     if (irqflags & IRQ_LORA_CRCERR_MASK)								// Is CRC error?
     {
     {
 #		if _MONITOR>=1
 #		if _MONITOR>=1
-        if (( debug>=0) && ( pdebug & P_RADIO )) {
+        if ((debug>=0) && (pdebug & P_RADIO)) {
 			String response=("rxPkt:: Err CRC, t=");
 			String response=("rxPkt:: Err CRC, t=");
 			stringTime(now(), response);
 			stringTime(now(), response);
 			mPrint(response);
 			mPrint(response);
@@ -428,7 +428,7 @@ uint8_t receivePkt(uint8_t *payload)
 	else if ((irqflags & IRQ_LORA_HEADER_MASK) == false)				// Header not ok?
 	else if ((irqflags & IRQ_LORA_HEADER_MASK) == false)				// Header not ok?
     {
     {
 #		if _MONITOR>=1
 #		if _MONITOR>=1
-			if (( debug>=0) && ( pdebug & P_RADIO )) {
+			if ((debug>=0) && (pdebug & P_RADIO)) {
 				mPrint("rxPkt:: Err HEADER");
 				mPrint("rxPkt:: Err HEADER");
 			}
 			}
 #		endif //_MONITOR
 #		endif //_MONITOR
@@ -448,8 +448,8 @@ uint8_t receivePkt(uint8_t *payload)
 		}
 		}
 
 
 		if (readRegister(REG_FIFO_RX_CURRENT_ADDR) != readRegister(REG_FIFO_RX_BASE_AD)) {
 		if (readRegister(REG_FIFO_RX_CURRENT_ADDR) != readRegister(REG_FIFO_RX_BASE_AD)) {
-#if			_MONITOR>=1
-			if (( debug>=1 ) && ( pdebug & P_RADIO )) {
+#		if _MONITOR>=1
+			if ((debug>=1) && (pdebug & P_RADIO)) {
 				mPrint("RX BASE <" + String(readRegister(REG_FIFO_RX_BASE_AD)) + "> != RX CURRENT <" + String(readRegister(REG_FIFO_RX_CURRENT_ADDR)) + ">"	);
 				mPrint("RX BASE <" + String(readRegister(REG_FIFO_RX_BASE_AD)) + "> != RX CURRENT <" + String(readRegister(REG_FIFO_RX_CURRENT_ADDR)) + ">"	);
 			}
 			}
 #			endif //_MONITOR
 #			endif //_MONITOR
@@ -467,7 +467,7 @@ uint8_t receivePkt(uint8_t *payload)
 
 
 		if (receivedCount > PAYLOAD_LENGTH) {
 		if (receivedCount > PAYLOAD_LENGTH) {
 #			if _MONITOR>=1
 #			if _MONITOR>=1
-				if (( debug>=0 ) & ( pdebug & P_RADIO )) {
+				if ((debug>=0) & (pdebug & P_RADIO)) {
 					mPrint("rxPkt:: ERROR Payliad receivedCount="+String(receivedCount));
 					mPrint("rxPkt:: ERROR Payliad receivedCount="+String(receivedCount));
 				}
 				}
 #			endif //_MONITOR
 #			endif //_MONITOR
@@ -484,7 +484,7 @@ uint8_t receivePkt(uint8_t *payload)
 		// As long as _MONITOR is enabled, and P_RX debug messages are selected,
 		// As long as _MONITOR is enabled, and P_RX debug messages are selected,
 		// the received packet is displayed on the output.
 		// the received packet is displayed on the output.
 #		if _MONITOR>=1
 #		if _MONITOR>=1
-		if ((debug>=1) && (pdebug & P_RX)){
+		if ((debug>=1) && (pdebug & P_RX)) {
 		
 		
 			String response = "UP receivePkt:: rxPkt: t=";
 			String response = "UP receivePkt:: rxPkt: t=";
 			stringTime(now(), response);
 			stringTime(now(), response);
@@ -517,7 +517,7 @@ uint8_t receivePkt(uint8_t *payload)
 					mPrint(", Ind="+String(index));
 					mPrint(", Ind="+String(index));
 				}
 				}
 				else if (debug>=1) {	
 				else if (debug>=1) {	
-					mPrint(", ERRRO No Index");
+					mPrint(", ERROR No Index");
 					return(receivedCount);
 					return(receivedCount);
 				}	
 				}	
 
 
@@ -557,11 +557,11 @@ uint8_t receivePkt(uint8_t *payload)
 					Serial.print(' ');
 					Serial.print(' ');
 				}
 				}
 			}
 			}
-#			endif // _TRUSTED_DECODE
+#			endif //_TRUSTED_DECODE
 			
 			
 			mPrint(response);							// Print response for Serial or mPrint
 			mPrint(response);							// Print response for Serial or mPrint
 		}
 		}
-#		endif //MONITOR
+#		endif //_MONITOR
 		return(receivedCount);
 		return(receivedCount);
     }
     }
 
 
@@ -628,22 +628,30 @@ bool sendPkt(uint8_t *payLoad, uint8_t payLength)
 
 
 void loraWait(struct LoraDown *LoraDown)
 void loraWait(struct LoraDown *LoraDown)
 {
 {
+	if (LoraDown->imme == 1) {
+		if ((debug>=1) && (pdebug & P_TX)) {
+			mPrint("loraWait:: imme is 1");
+		}
+		return;
+	}
+	
 	int32_t delayTmst = (int32_t)(LoraDown->tmst - micros()) + gwayConfig.txDelay;
 	int32_t delayTmst = (int32_t)(LoraDown->tmst - micros()) + gwayConfig.txDelay;
 												// delayTmst based on txDelay and spreading factor
 												// delayTmst based on txDelay and spreading factor
 	
 	
-	if ((delayTmst > 8000000) || (delayTmst < 0)) {					// Delay is  > 8 secs
+	if ((delayTmst > 8000000) || (delayTmst < 0)) {		// Delay is  > 8 secs
 #		if _MONITOR>=1
 #		if _MONITOR>=1
+		if (delayTmst > 8000000) {
 			String response= "Dwn loraWait:: ERROR: ";
 			String response= "Dwn loraWait:: ERROR: ";
 			printDwn(LoraDown,response);
 			printDwn(LoraDown,response);
 			mPrint(response);
 			mPrint(response);
-#		endif // _MONITOR
+		}
+#		endif //_MONITOR
 		gwayConfig.waitErr++;
 		gwayConfig.waitErr++;
 		return;
 		return;
 	}
 	}
 
 
 	// For larger delay times we use delay() since that is for > 15ms
 	// For larger delay times we use delay() since that is for > 15ms
 	// This is the most efficient way.
 	// This is the most efficient way.
-	// MMM Check for huge wait times
 	while (delayTmst > 15000) {
 	while (delayTmst > 15000) {
 		delay(15);										// ms delay including yield, slightly shorter
 		delay(15);										// ms delay including yield, slightly shorter
 //		delayMicroseconds(15000);						// ms delay including yield, slightly shorter
 //		delayMicroseconds(15000);						// ms delay including yield, slightly shorter
@@ -754,7 +762,7 @@ void txLoraModem(struct LoraDown *LoraDown)
 	opmode(OPMODE_TX);											// set 0x01 to 0x03 (actual value becomes 0x83)
 	opmode(OPMODE_TX);											// set 0x01 to 0x03 (actual value becomes 0x83)
 
 
 #	if _MONITOR>=1
 #	if _MONITOR>=1
-	if (( debug>=1 ) && ( pdebug & P_TX )) {
+	if ((debug>=1) && (pdebug & P_TX)) {
 		String response = "Dwn txLoraModem:: end: ";
 		String response = "Dwn txLoraModem:: end: ";
 		printDwn(LoraDown, response);
 		printDwn(LoraDown, response);
 		mPrint(response);
 		mPrint(response);
@@ -1045,7 +1053,7 @@ void startReceiver()
 	initLoraModem();								// XXX 180326, after adapting this function 
 	initLoraModem();								// XXX 180326, after adapting this function 
 	if (gwayConfig.cad) {
 	if (gwayConfig.cad) {
 #		if _DUSB>=1
 #		if _DUSB>=1
-		if (( debug>=1 ) && ( pdebug & P_SCAN )) {
+		if ((debug>=1) && (pdebug & P_SCAN)) {
 			Serial.println(F("S PULL:: _state set to S_SCAN"));
 			Serial.println(F("S PULL:: _state set to S_SCAN"));
 			if (debug>=2) Serial.flush();
 			if (debug>=2) Serial.flush();
 		}
 		}

+ 6 - 6
src/_oLED.ino

@@ -61,7 +61,7 @@ void acti_oLED()
 #if _OLED>=1
 #if _OLED>=1
 	// Initialising the UI will init the display too.
 	// Initialising the UI will init the display too.
 	display.clear();
 	display.clear();
-	
+
 # if _OLED==1
 # if _OLED==1
 	display.setFont(ArialMT_Plain_16);
 	display.setFont(ArialMT_Plain_16);
 	display.drawString(0, 0, "READY,  SSID=");
 	display.drawString(0, 0, "READY,  SSID=");
@@ -74,11 +74,11 @@ void acti_oLED()
 	display.drawString(0, 16, WiFi.SSID());
 	display.drawString(0, 16, WiFi.SSID());
 	display.drawString(0, 32, "IP=");
 	display.drawString(0, 32, "IP=");
 	display.drawString(0, 48, WiFi.localIP().toString().c_str() );
 	display.drawString(0, 48, WiFi.localIP().toString().c_str() );
-# endif
+# endif //_OLED
 
 
 	display.display();
 	display.display();
-	
-#endif // _OLED
+
+#endif //_OLED
 	delay(4000);
 	delay(4000);
 }
 }
 
 
@@ -99,7 +99,7 @@ void msg_oLED(String mesg)
 
 
     display.display();
     display.display();
 	yield();
 	yield();
-#endif // _OLED
+#endif //_OLED
 }
 }
 
 
 // Print a larger Oled message consisting of two strings
 // Print a larger Oled message consisting of two strings
@@ -117,7 +117,7 @@ void msg_lLED(String mesg, String mesg2)
 	
 	
     display.display();
     display.display();
 	yield();
 	yield();
-#endif // _OLED
+#endif //_OLED
 }
 }
 
 
 // --------------------------------------------------------------------
 // --------------------------------------------------------------------

+ 20 - 20
src/_sensor.ino

@@ -154,11 +154,11 @@ int LoRaSensors(uint8_t *buf) {
 			}
 			}
 			// Raw coding of LoRa messages to server so add the GPS data raw to the string
 			// Raw coding of LoRa messages to server so add the GPS data raw to the string
 #			if _MONITOR>=1
 #			if _MONITOR>=1
-			if ((debug>=1) && ( pdebug & P_MAIN )){
+			if ((debug>=1) && (pdebug & P_MAIN)){
 				mPrint("Gps raw:: lat="+String(gps.location.lat())+", lng="+String(gps.location.lng())+", alt="+String(gps.altitude.feet()/3.2808)+", sats="+String(gps.satellites.value()) );
 				mPrint("Gps raw:: lat="+String(gps.location.lat())+", lng="+String(gps.location.lng())+", alt="+String(gps.altitude.feet()/3.2808)+", sats="+String(gps.satellites.value()) );
 				//mPrint("Gps raw:: sizeof double="+String(sizeof(double)) );
 				//mPrint("Gps raw:: sizeof double="+String(sizeof(double)) );
 			}
 			}
-#			endif // _MONITOR
+#			endif //_MONITOR
 			// Length of lat and lng is double
 			// Length of lat and lng is double
 			double lat = gps.location.lat();
 			double lat = gps.location.lat();
 			double lng = gps.location.lng();
 			double lng = gps.location.lng();
@@ -181,7 +181,7 @@ int LoRaSensors(uint8_t *buf) {
 			memcpy((buf+tchars), &volts, sizeof(float)); tchars += sizeof(float);
 			memcpy((buf+tchars), &volts, sizeof(float)); tchars += sizeof(float);
 			
 			
 #			if _MONITOR>=1
 #			if _MONITOR>=1
-			if ((debug>=1) && ( pdebug & P_MAIN )){
+			if ((debug>=1) && (pdebug & P_MAIN)){
 				mPrint("Battery raw="+String(volts));
 				mPrint("Battery raw="+String(volts));
 			}
 			}
 #			endif //_MONITOR
 #			endif //_MONITOR
@@ -196,7 +196,7 @@ int LoRaSensors(uint8_t *buf) {
 
 
 // GENERAL part
 // GENERAL part
 #	if _DUSB>=1 && _GPS==1
 #	if _DUSB>=1 && _GPS==1
-	if (( debug>=2 ) && ( pdebug & P_MAIN )) {
+	if ((debug>=2) && (pdebug & P_MAIN)) {
 		Serial.print("GPS sensor");
 		Serial.print("GPS sensor");
 		Serial.print("\tLatitude  : ");
 		Serial.print("\tLatitude  : ");
 		Serial.println(gps.location.lat(), 5);
 		Serial.println(gps.location.lat(), 5);
@@ -552,7 +552,7 @@ int sensorPacket() {
 	uint8_t PayLength = LoRaSensors((uint8_t *)(LUP.payLoad + LUP.payLength));
 	uint8_t PayLength = LoRaSensors((uint8_t *)(LUP.payLoad + LUP.payLength));
 
 
 #if _DUSB>=1
 #if _DUSB>=1
-	if ((debug>=2) && (pdebug & P_RADIO )) {
+	if ((debug>=2) && (pdebug & P_RADIO)) {
 		String response="";
 		String response="";
 		Serial.print(F("old: "));
 		Serial.print(F("old: "));
 		for (int i=0; i<PayLength; i++) {
 		for (int i=0; i<PayLength; i++) {
@@ -567,7 +567,7 @@ int sensorPacket() {
 	uint8_t CodeLength = encodePacket((uint8_t *)(LUP.payLoad + LUP.payLength), PayLength, (uint16_t)frameCount, DevAddr, AppSKey, 0);
 	uint8_t CodeLength = encodePacket((uint8_t *)(LUP.payLoad + LUP.payLength), PayLength, (uint16_t)frameCount, DevAddr, AppSKey, 0);
 
 
 #if _DUSB>=1
 #if _DUSB>=1
-	if ((debug>=2) && (pdebug & P_RADIO )) {
+	if ((debug>=2) && (pdebug & P_RADIO)) {
 		Serial.print(F("new: "));
 		Serial.print(F("new: "));
 		for (int i=0; i<CodeLength; i++) {
 		for (int i=0; i<CodeLength; i++) {
 			Serial.print(LUP.payLoad[i],HEX);
 			Serial.print(LUP.payLoad[i],HEX);
@@ -588,7 +588,7 @@ int sensorPacket() {
 	LUP.payLength += micPacket((uint8_t *)(LUP.payLoad), LUP.payLength, (uint16_t)frameCount, NwkSKey, 0);
 	LUP.payLength += micPacket((uint8_t *)(LUP.payLoad), LUP.payLength, (uint16_t)frameCount, NwkSKey, 0);
 
 
 #if _DUSB>=1
 #if _DUSB>=1
-	if ((debug>=2) && (pdebug & P_RADIO )) {
+	if ((debug>=2) && (pdebug & P_RADIO)) {
 		Serial.print(F("mic: "));
 		Serial.print(F("mic: "));
 		for (int i=0; i<LUP.payLength; i++) {
 		for (int i=0; i<LUP.payLength; i++) {
 			Serial.print(LUP.payLoad[i],HEX);
 			Serial.print(LUP.payLoad[i],HEX);
@@ -608,7 +608,7 @@ int sensorPacket() {
 	frameCount++;
 	frameCount++;
 	statc.msg_ttl++;					// XXX Should we count sensor messages as well?
 	statc.msg_ttl++;					// XXX Should we count sensor messages as well?
 	statc.msg_sens++;
 	statc.msg_sens++;
-	switch(gwayConfig.ch) {			// MMM remove when possible
+	switch(gwayConfig.ch) {
 		case 0: statc.msg_sens_0++; break;
 		case 0: statc.msg_sens_0++; break;
 		case 1: statc.msg_sens_1++; break;
 		case 1: statc.msg_sens_1++; break;
 		case 2: statc.msg_sens_2++; break;
 		case 2: statc.msg_sens_2++; break;
@@ -619,7 +619,7 @@ int sensorPacket() {
 	// 10 value when restarting the gateway.
 	// 10 value when restarting the gateway.
 	// NOTE: This means that preferences are NOT saved unless >=10 messages have been received.
 	// NOTE: This means that preferences are NOT saved unless >=10 messages have been received.
 	//
 	//
-	if ((frameCount % 10)==0) writeGwayCfg(CONFIGFILE, &gwayConfig );
+	if ((frameCount % 10)==0) writeGwayCfg(_CONFIGFILE, &gwayConfig );
 	
 	
 	if (buff_index > 512) {
 	if (buff_index > 512) {
 		if (debug>0) 
 		if (debug>0) 
@@ -642,7 +642,7 @@ int sensorPacket() {
 #if _DUSB>=1
 #if _DUSB>=1
 	// If all is right, we should after decoding (which is the same as encoding) get
 	// If all is right, we should after decoding (which is the same as encoding) get
 	// the original message back again.
 	// the original message back again.
-	if ((debug>=2) && (pdebug & P_RADIO )) {
+	if ((debug>=2) && (pdebug & P_RADIO)) {
 		CodeLength = encodePacket((uint8_t *)(LUP.payLoad + 9), PayLength, (uint16_t)frameCount-1, DevAddr, AppSKey, 0);
 		CodeLength = encodePacket((uint8_t *)(LUP.payLoad + 9), PayLength, (uint16_t)frameCount-1, DevAddr, AppSKey, 0);
 		Serial.print(F("rev: "));
 		Serial.print(F("rev: "));
 		for (int i=0; i<CodeLength; i++) {
 		for (int i=0; i<CodeLength; i++) {
@@ -656,7 +656,7 @@ int sensorPacket() {
 		}
 		}
 		Serial.println();
 		Serial.println();
 	}
 	}
-#endif // _DUSB
+#endif //_DUSB
 
 
 	if (gwayConfig.cad) {
 	if (gwayConfig.cad) {
 		// Set the state to CAD scanning after sending a packet
 		// Set the state to CAD scanning after sending a packet
@@ -704,15 +704,15 @@ int sensorPacket() {
 uint8_t encodePacket(uint8_t *Data, uint8_t DataLength, uint16_t FrameCount, uint8_t *DevAddr, uint8_t *AppSKey, uint8_t Direction)
 uint8_t encodePacket(uint8_t *Data, uint8_t DataLength, uint16_t FrameCount, uint8_t *DevAddr, uint8_t *AppSKey, uint8_t Direction)
 {
 {
 
 
-#if _DUSB>=1
-	if (( debug>=2 ) && ( pdebug & P_GUI )) {
-		Serial.print(F("G encodePacket:: DevAddr="));
-		for (int i=0; i<4; i++ ) { Serial.print(DevAddr[i],HEX); Serial.print(' '); }
-		Serial.print(F("G encodePacket:: AppSKey="));
-		for (int i=0; i<16; i++ ) { Serial.print(AppSKey[i],HEX); Serial.print(' '); }
-		Serial.println();
+#if _MONITOR>=1
+	if ((debug>=2) && (pdebug & P_MAIN)) {
+		String response="encodePacket:: DevAddr=";
+		for (int i=0; i<4; i++ ) { response+=(String(DevAddr[i],HEX)+(' ')); }
+		response+=", encodePacket:: AppSKey=";
+		for (int i=0; i<16; i++ ) { response+=(String(AppSKey[i],HEX)+(' ')); }
+		mPrint(response);
 	}
 	}
-#endif // _DUSB
+#endif //_MONITOR
 
 
 	//unsigned char AppSKey[16] = _APPSKEY ;	// see configGway.h
 	//unsigned char AppSKey[16] = _APPSKEY ;	// see configGway.h
 	uint8_t i, j;
 	uint8_t i, j;
@@ -762,4 +762,4 @@ uint8_t encodePacket(uint8_t *Data, uint8_t DataLength, uint16_t FrameCount, uin
 	return(DataLength);				// or only 16*(numBlocks-1)+bLen;
 	return(DataLength);				// or only 16*(numBlocks-1)+bLen;
 }
 }
 
 
-#endif // _GATEWAYNODE || _LOCALSERVER
+#endif //_GATEWAYNODE || _LOCALSERVER

+ 23 - 23
src/_stateMachine.ino

@@ -320,7 +320,7 @@ void stateMachine()
 			if (rssi > (RSSI_LIMIT - (gwayConfig.hop * 7)))		// Is set to 35, or 29 for HOP
 			if (rssi > (RSSI_LIMIT - (gwayConfig.hop * 7)))		// Is set to 35, or 29 for HOP
 			{
 			{
 #				if _MONITOR>=1
 #				if _MONITOR>=1
-				if (( debug>=2 ) && ( pdebug & P_SCAN )) {
+				if ((debug>=2) && (pdebug & P_SCAN)) {
 					String response = "SCAN:: -> CAD: ";
 					String response = "SCAN:: -> CAD: ";
 					mStat(intr, response);
 					mStat(intr, response);
 					mPrint(response);
 					mPrint(response);
@@ -334,7 +334,7 @@ void stateMachine()
 			// and go back to scanning
 			// and go back to scanning
 			else {
 			else {
 #				if _MONITOR>=1
 #				if _MONITOR>=1
-				if (( debug>=2 ) && ( pdebug & P_SCAN )) {
+				if ((debug>=2) && (pdebug & P_SCAN)) {
 					String response = "SCAN:: rssi=";
 					String response = "SCAN:: rssi=";
 					response += String(rssi);
 					response += String(rssi);
 					response += ": ";
 					response += ": ";
@@ -376,7 +376,7 @@ void stateMachine()
 		//
 		//
 		else {
 		else {
 #			if _MONITOR>=1
 #			if _MONITOR>=1
-			if (( debug>=0 ) && ( pdebug & P_SCAN )) {
+			if ((debug>=0) && (pdebug & P_SCAN)) {
 				String response = "SCAN unknown:: ";
 				String response = "SCAN unknown:: ";
 				mStat(intr, response);
 				mStat(intr, response);
 				mPrint(response);
 				mPrint(response);
@@ -480,7 +480,7 @@ void stateMachine()
 				rssi = readRegister(REG_RSSI);						// Read the RSSI
 				rssi = readRegister(REG_RSSI);						// Read the RSSI
 
 
 #				if _MONITOR>=1
 #				if _MONITOR>=1
-				if (( debug>=3 ) && ( pdebug & P_CAD )) {
+				if ((debug>=3) && (pdebug & P_CAD)) {
 					mPrint("S_CAD:: CDONE, SF=" + String(sf) );
 					mPrint("S_CAD:: CDONE, SF=" + String(sf) );
 				}
 				}
 #				endif //_MONITOR
 #				endif //_MONITOR
@@ -501,7 +501,7 @@ void stateMachine()
 				cadScanner();										// Which will reset SF to lowest SF
 				cadScanner();										// Which will reset SF to lowest SF
 
 
 #				if _MONITOR>=1		
 #				if _MONITOR>=1		
-				if (( debug>=3 ) && ( pdebug & P_CAD )) {
+				if ((debug>=3) && (pdebug & P_CAD)) {
 					mPrint("CAD->SCAN:: " + String(intr) );
 					mPrint("CAD->SCAN:: " + String(intr) );
 				}
 				}
 #				endif //_MONITOR
 #				endif //_MONITOR
@@ -518,7 +518,7 @@ void stateMachine()
 		//
 		//
 		else if (intr == 0x00) {
 		else if (intr == 0x00) {
 #			if _MONITOR>=1
 #			if _MONITOR>=1
-			if (( debug>=3 ) && ( pdebug & P_CAD )) {
+			if ((debug>=3) && (pdebug & P_CAD)) {
 				mPrint ("CAD:: intr is 0x00");
 				mPrint ("CAD:: intr is 0x00");
 			}
 			}
 #			endif //_MONITOR
 #			endif //_MONITOR
@@ -666,7 +666,7 @@ void stateMachine()
 			//
 			//
 			if (receivePacket() <= 0) {								// read is not successful
 			if (receivePacket() <= 0) {								// read is not successful
 #				if _MONITOR>=1
 #				if _MONITOR>=1
-				if (( debug>=0 ) && ( pdebug & P_RX )) {
+				if ((debug>=0) && (pdebug & P_RX)) {
 					mPrint("sMach:: ERROR receivePacket");
 					mPrint("sMach:: ERROR receivePacket");
 				}
 				}
 #				endif //_MONITOR
 #				endif //_MONITOR
@@ -711,7 +711,7 @@ void stateMachine()
 			if ((gwayConfig.cad) || (gwayConfig.hop)) {
 			if ((gwayConfig.cad) || (gwayConfig.hop)) {
 				// Set the state to CAD scanning
 				// Set the state to CAD scanning
 #				if _MONITOR>=1
 #				if _MONITOR>=1
-				if (( debug>=2 ) && ( pdebug & P_RX )) {
+				if ((debug>=2) && (pdebug & P_RX)) {
 					String response = "RXTOUT:: ";
 					String response = "RXTOUT:: ";
 					mStat(intr, response);
 					mStat(intr, response);
 					mPrint(response);
 					mPrint(response);
@@ -764,7 +764,7 @@ void stateMachine()
 		// as HEADER interrupt comes just before RXDONE
 		// as HEADER interrupt comes just before RXDONE
 		else {							
 		else {							
 #			if _MONITOR>=1
 #			if _MONITOR>=1
-			if (( debug>=0 ) && ( pdebug & P_RX )) {
+			if ((debug>=0) && (pdebug & P_RX)) {
 				mPrint("R S_RX:: no RXDONE, RXTOUT, HEADER:: " + String(intr));
 				mPrint("R S_RX:: no RXDONE, RXTOUT, HEADER:: " + String(intr));
 			}
 			}
 #			endif //_MONITOR
 #			endif //_MONITOR
@@ -789,13 +789,19 @@ void stateMachine()
 		// we have a timeout in the main program (Keep Alive)
 		// we have a timeout in the main program (Keep Alive)
 		if (intr == 0x00) {
 		if (intr == 0x00) {
 #			if _MONITOR>=1
 #			if _MONITOR>=1
-			if (( debug>=2 ) && ( pdebug & P_TX )) {
+			if ((debug>=2) && (pdebug & P_TX)) {
 				mPrint("TX:: 0x00");
 				mPrint("TX:: 0x00");
 			}
 			}
 #			endif //_MONITOR
 #			endif //_MONITOR
 			_event= 1;
 			_event= 1;
 		}
 		}
 
 
+#		if _MONITOR>=1
+		if ((debug>=1) && (pdebug & P_MAIN)) {
+			mPrint("TX stateMachine:: calling loraWait");
+		}
+#		endif
+
 		loraWait(&LoraDown);
 		loraWait(&LoraDown);
 	
 	
 		// Set state to transmit
 		// Set state to transmit
@@ -813,7 +819,7 @@ void stateMachine()
 		_event=1;													// Or remove the break below
 		_event=1;													// Or remove the break below
 
 
 #		if _MONITOR>=1
 #		if _MONITOR>=1
-		if (( debug>=1 ) && ( pdebug & P_TX )) {
+		if ((debug>=1) && (pdebug & P_TX)) {
 			String response="TX fini:: ";
 			String response="TX fini:: ";
 			mStat(intr, response);
 			mStat(intr, response);
 			mPrint(response); 
 			mPrint(response); 
@@ -835,11 +841,11 @@ void stateMachine()
 		if (intr & IRQ_LORA_TXDONE_MASK) {
 		if (intr & IRQ_LORA_TXDONE_MASK) {
 
 
 #			if _MONITOR>=1
 #			if _MONITOR>=1
-			if (( debug>=1 ) && ( pdebug & P_TX )) {
-				String response =  "Dwns TXDONE:: OK: rcvd=";
+			if ((debug>=1) && (pdebug & P_TX)) {
+				String response =  "Dwn stateMachine: TXDONE OK: rcvd=";
 				printInt(micros(),response);
 				printInt(micros(),response);
 				if (micros() < LoraDown.tmst) {
 				if (micros() < LoraDown.tmst) {
-					response += ", diff=-" ;
+					response += ", diff=- " ;
 					printInt(LoraDown.tmst - micros(), response );
 					printInt(LoraDown.tmst - micros(), response );
 				}
 				}
 				else {
 				else {
@@ -865,18 +871,12 @@ void stateMachine()
 			_event=0;
 			_event=0;
 			writeRegister(REG_IRQ_FLAGS_MASK, (uint8_t) 0x00);
 			writeRegister(REG_IRQ_FLAGS_MASK, (uint8_t) 0x00);
 			writeRegister(REG_IRQ_FLAGS, (uint8_t) 0xFF);			// reset interrupt flags
 			writeRegister(REG_IRQ_FLAGS, (uint8_t) 0xFF);			// reset interrupt flags
-			
-#			if _MONITOR>=1
-			if (( debug>=2 ) && ( pdebug & P_TX )) {
-				mPrint("TXDONE:: done OK");
-			}
-#			endif //_MONITOR
 		}
 		}
 		
 		
 		// If a soft _event==0 interrupt and no transmission finished:
 		// If a soft _event==0 interrupt and no transmission finished:
 		else if ( intr != 0 ) {
 		else if ( intr != 0 ) {
 #			if _MONITOR>=1
 #			if _MONITOR>=1
-			if (( debug>=0 ) && ( pdebug & P_TX )) {
+			if ((debug>=0) && (pdebug & P_TX)) {
 				String response =  "TXDONE:: Error unknown intr=";
 				String response =  "TXDONE:: Error unknown intr=";
 				mStat(intr, response);
 				mStat(intr, response);
 				mPrint(response);
 				mPrint(response);
@@ -897,7 +897,7 @@ void stateMachine()
 			if ( sendTime > micros() ) sendTime = 0;				// This could be omitted for usigned ints
 			if ( sendTime > micros() ) sendTime = 0;				// This could be omitted for usigned ints
 			if (( _state == S_TXDONE ) && (( micros() - sendTime) > 7000000 )) {
 			if (( _state == S_TXDONE ) && (( micros() - sendTime) > 7000000 )) {
 #				if _MONITOR>=1
 #				if _MONITOR>=1
-				if (( debug>=1 ) && ( pdebug & P_TX )) {
+				if ((debug>=1) && (pdebug & P_TX)) {
 					mPrint("TXDONE:: reset TX");
 					mPrint("TXDONE:: reset TX");
 				}
 				}
 #				endif //_MONITOR
 #				endif //_MONITOR
@@ -915,7 +915,7 @@ void stateMachine()
 	  // make sure that we pick up next interrupt
 	  // make sure that we pick up next interrupt
 	  default:
 	  default:
 #		if _MONITOR>=1
 #		if _MONITOR>=1
-		if (( debug>=0) && ( pdebug & P_PRE )) {
+		if ((debug>=0) && (pdebug & P_PRE)) {
 			mPrint("ERR state=" + String(_state));	
 			mPrint("ERR state=" + String(_state));	
 		}
 		}
 #		endif //_MONITOR
 #		endif //_MONITOR

+ 1 - 1
src/_tcpTTN.ino

@@ -62,4 +62,4 @@ int sendTtn(IPAddress server, int port, uint8_t *msg, int length) {
 
 
 
 
 
 
-#endif// _TTNROUTER
+#endif //_TTNROUTER

+ 55 - 95
src/_txRx.ino

@@ -20,7 +20,7 @@
 
 
 // ------------------------------- DOWN ----------------------------------------
 // ------------------------------- DOWN ----------------------------------------
 //
 //
-// Send DOWN a LoRa packet over the air to the node. This function does all the 
+// Prepare DOWN a LoRa packet in down buffer. This function does all the 
 // decoding of the server message and prepares a Payload buffer.
 // decoding of the server message and prepares a Payload buffer.
 // The payload is actually transmitted by the sendPkt() function.
 // The payload is actually transmitted by the sendPkt() function.
 // This function is used for regular downstream messages and for JOIN_ACCEPT
 // This function is used for regular downstream messages and for JOIN_ACCEPT
@@ -43,6 +43,7 @@ int sendPacket(uint8_t *buf, uint8_t length)
 	// size	: 21
 	// size	: 21
 	// tmst : 1800642 									// for example
 	// tmst : 1800642 									// for example
 	// datr	: "SF7BW125"
 	// datr	: "SF7BW125"
+	// imme :											// Immediately transfer
 	
 	
 	// 12-byte header;
 	// 12-byte header;
 	//		HDR (1 byte)
 	//		HDR (1 byte)
@@ -56,13 +57,12 @@ int sendPacket(uint8_t *buf, uint8_t length)
 	//		CFList (fill to 16 bytes)
 	//		CFList (fill to 16 bytes)
 			
 			
 	int i=0;
 	int i=0;
-	//StaticJsonDocument<312> jsonBuffer;							// Use of arduinoJson version 6!
 	char * bufPtr = (char *) (buf);
 	char * bufPtr = (char *) (buf);
 	buf[length] = 0;
 	buf[length] = 0;
 	
 	
 #	if _MONITOR>=1
 #	if _MONITOR>=1
-	if (( debug>=2) && (pdebug & P_TX)) {
-		mPrint("Dwn sendPacket:: " + String((char *)buf) + "< ");
+	if (( debug>=1) && (pdebug & P_TX)) {
+		mPrint("Dwn sendPacket:: " + String((char *)buf));
 	}
 	}
 #	endif //_MONITOR
 #	endif //_MONITOR
 
 
@@ -89,19 +89,20 @@ int sendPacket(uint8_t *buf, uint8_t length)
 	const char * data	= root["txpk"]["data"];			// Downstream Payload
 	const char * data	= root["txpk"]["data"];			// Downstream Payload
 	uint8_t psize		= root["txpk"]["size"];			// Payload size
 	uint8_t psize		= root["txpk"]["size"];			// Payload size
 	bool ipol			= root["txpk"]["ipol"];
 	bool ipol			= root["txpk"]["ipol"];
-//	uint8_t powe		= root["txpk"]["powe"];			// power, e.g. 14 or 27
-	
-	// Not used in the protocol of Gateway TTN:
+
 	const char * datr	= root["txpk"]["datr"];			// eg "SF7BW125"
 	const char * datr	= root["txpk"]["datr"];			// eg "SF7BW125"
 	//const char * modu	= root["txpk"]["modu"];			// =="LORA"
 	//const char * modu	= root["txpk"]["modu"];			// =="LORA"
 	//const char * codr	= root["txpk"]["codr"];			// e.g. "4/5"
 	//const char * codr	= root["txpk"]["codr"];			// e.g. "4/5"
-	//if (root["txpk"].containsKey("imme") ) {
-	//	const bool imme = root["txpk"]["imme"];			// Immediate Transmit (tmst don't care)
-	//}
+	if (root["txpk"].containsKey("imme") ) {
+		LoraDown.imme = root["txpk"]["imme"];			// Immediate Transmit (tmst don't care)
+	}
+	if (root["txpk"].containsKey("powe") ) {
+		uint8_t powe	= root["txpk"]["powe"];			// power, e.g. 14 or 27
+	}
 
 
 	if ( data != NULL ) {
 	if ( data != NULL ) {
 #		if _MONITOR>=1
 #		if _MONITOR>=1
-		if (( debug>=2 ) && ( pdebug & P_TX )) { 
+		if ((debug>=2) && (pdebug & P_TX)) { 
 			mPrint("sendPacket:: data=" + String(data)); 
 			mPrint("sendPacket:: data=" + String(data)); 
 		}
 		}
 #		endif //_MONITOR
 #		endif //_MONITOR
@@ -138,33 +139,6 @@ int sendPacket(uint8_t *buf, uint8_t length)
 
 
 	LoraDown.powe	= 14;								// On all freqs except 869.5MHz power is limited
 	LoraDown.powe	= 14;								// On all freqs except 869.5MHz power is limited
 	LoraDown.freq	= freqs[gwayConfig.ch].dwnFreq;		// Use the requestor Down frequency (always)
 	LoraDown.freq	= freqs[gwayConfig.ch].dwnFreq;		// Use the requestor Down frequency (always)
-	
-	// Wait time RX1, between 1 and 2 seconds, or OTAA between 6 and 7 seconds
-	if (((w>0000000) && (w<2000000)) ||
-		((w>5000000) && (w<6000000)) )
-	{ 													// LoraDown.sfTx set by initiator
-#		ifdef _PROFILER
-		if ((debug>=2) && (pdebug & P_TX)) {
-			mPrint("loraPacket:: RX1: micros="+String(micros())); 
-		}
-#		endif //_PROFILER
-	}
-
-	// RX2. 
-	else if (((w>2000000) && (w<3000000)) ||
-			 ((w>6000000) && (w<7000000)) )
-	{ 
-		LoraDown.sfTx= _RX2_SF;							// Use the RX2 downstream SF (may be dedicated to TTN)
-	}
-	
-	else {
-#		if _MONITOR>=1
-		if ((debug>=2) && (pdebug & P_TX)) {
-			mPrint("_STRICT==1:: Not RX1 or RX2, wait= "+String(w/1000000)+"."+String(w%1000000)+", SF="+String(LoraDown.sfTx)+", Freq="+LoraDown.freq );
-		}
-#		endif //_MONITOR
-		// And do not convert the down SF.
-	}
 
 
 #else
 #else
 // elif _STRICT_1CH == 0, we will receive messags from the TTN gateway presumably on SF9/869.5MHz
 // elif _STRICT_1CH == 0, we will receive messags from the TTN gateway presumably on SF9/869.5MHz
@@ -178,6 +152,7 @@ int sendPacket(uint8_t *buf, uint8_t length)
 	const float ff	= root["txpk"]["freq"];				// eg 869.525
 	const float ff	= root["txpk"]["freq"];				// eg 869.525
 	// convert double frequency (MHz) into uint32_t frequency in Hz.
 	// convert double frequency (MHz) into uint32_t frequency in Hz.
 	LoraDown.freq = (uint32_t) ((uint32_t)((ff+0.000035)*1000)) * 1000;
 	LoraDown.freq = (uint32_t) ((uint32_t)((ff+0.000035)*1000)) * 1000;
+
 #endif //_STRICT_1CH
 #endif //_STRICT_1CH
 
 
 	yield();
 	yield();
@@ -185,10 +160,10 @@ int sendPacket(uint8_t *buf, uint8_t length)
 	LoraDown.payLoad = payLoad;				
 	LoraDown.payLoad = payLoad;				
 
 
 #	if _MONITOR>=1
 #	if _MONITOR>=1
-	if (( debug>=2 ) && ( pdebug & P_TX)) {
+	if ((debug>=2) && (pdebug & P_TX)) {
 		mPrint("Dwn sendPacket:: TX tmst=" + String(LoraDown.tmst));
 		mPrint("Dwn sendPacket:: TX tmst=" + String(LoraDown.tmst));
 	}
 	}
-#	endif // _MONITOR
+#	endif //_MONITOR
 
 
 	if (LoraDown.payLength != psize) {
 	if (LoraDown.payLength != psize) {
 #		if _MONITOR>=1
 #		if _MONITOR>=1
@@ -198,7 +173,7 @@ int sendPacket(uint8_t *buf, uint8_t length)
 #		endif //_MONITOR
 #		endif //_MONITOR
 	}
 	}
 #	if _MONITOR>=1
 #	if _MONITOR>=1
-	else if (( debug >= 2 ) && ( pdebug & P_TX )) {
+	else if ((debug >= 2) && (pdebug & P_TX)) {
 		Serial.print(F("T Payload="));
 		Serial.print(F("T Payload="));
 		for (i=0; i<LoraDown.payLength; i++) {
 		for (i=0; i<LoraDown.payLength; i++) {
 			Serial.print(payLoad[i],HEX); 
 			Serial.print(payLoad[i],HEX); 
@@ -219,13 +194,7 @@ int sendPacket(uint8_t *buf, uint8_t length)
 	// All data is in Payload and parameters and need to be transmitted.
 	// All data is in Payload and parameters and need to be transmitted.
 	// The function is called in user-space
 	// The function is called in user-space
 	_state = S_TX;										// _state set to transmit
 	_state = S_TX;										// _state set to transmit
-	
-#	if _MONITOR>=1
-	if ((debug>=2) && ( pdebug & P_TX)) {
-		mPrint("sendPacket:: STRICT=" + String(_STRICT_1CH) );
-	}
-#	endif //_MONITOR
-	
+
 	return 1;
 	return 1;
 } //sendPacket DOWN
 } //sendPacket DOWN
 
 
@@ -262,7 +231,7 @@ int buildPacket(uint8_t *buff_up, struct LoraUp *LoraUp, bool internal)
 #if _CHECK_MIC==1
 #if _CHECK_MIC==1
 	unsigned char NwkSKey[16] = _NWKSKEY;
 	unsigned char NwkSKey[16] = _NWKSKEY;
 	checkMic(message, messageLength, NwkSKey);
 	checkMic(message, messageLength, NwkSKey);
-#endif // _CHECK_MIC
+#endif //_CHECK_MIC
 
 
 	// Read SNR and RSSI from the register. Note: Not for internal sensors!
 	// Read SNR and RSSI from the register. Note: Not for internal sensors!
 	// For internal sensor we fake these values as we cannot read a register
 	// For internal sensor we fake these values as we cannot read a register
@@ -282,7 +251,7 @@ int buildPacket(uint8_t *buff_up, struct LoraUp *LoraUp, bool internal)
 	// and fill the new top line with the latest received sensor values.
 	// and fill the new top line with the latest received sensor values.
 	// This works fine for the sensor, EXCEPT when we decode data for _LOCALSERVER
 	// This works fine for the sensor, EXCEPT when we decode data for _LOCALSERVER
 	//
 	//
-	for (int m=( _MAXSTAT -1); m>0; m--) statr[m]=statr[m-1];
+	for (int m=( gwayConfig.maxStat -1); m>0; m--) statr[m]=statr[m-1];
 	
 	
 	// From now on we can fill statr[0] with sensor data
 	// From now on we can fill statr[0] with sensor data
 #if _LOCALSERVER==1
 #if _LOCALSERVER==1
@@ -336,7 +305,7 @@ int buildPacket(uint8_t *buff_up, struct LoraUp *LoraUp, bool internal)
 		case SF11: statc.sf11++; break;
 		case SF11: statc.sf11++; break;
 		case SF12: statc.sf12++; break;
 		case SF12: statc.sf12++; break;
 	}
 	}
-#endif // _STATISTICS >= 2
+#endif //_STATISTICS >= 2
 
 
 
 
 
 
@@ -381,7 +350,7 @@ int buildPacket(uint8_t *buff_up, struct LoraUp *LoraUp, bool internal)
 #endif //_STATISTICS >= 2
 #endif //_STATISTICS >= 2
 
 
 #if _MONITOR>=1	
 #if _MONITOR>=1	
-	if (( debug>=2 ) && ( pdebug & P_RADIO )){
+	if ((debug>=2) && (pdebug & P_RADIO)) {
 		Serial.print(F("R buildPacket:: pRSSI="));
 		Serial.print(F("R buildPacket:: pRSSI="));
 		Serial.print(prssi-rssicorr);
 		Serial.print(prssi-rssicorr);
 		Serial.print(F(" RSSI: "));
 		Serial.print(F(" RSSI: "));
@@ -399,7 +368,7 @@ int buildPacket(uint8_t *buff_up, struct LoraUp *LoraUp, bool internal)
 		Serial.println();
 		Serial.println();
 		yield();										// only if debug>=2
 		yield();										// only if debug>=2
 	}
 	}
-#endif // _MONITOR
+#endif //_MONITOR
 
 
 // Show received message status on Oled display
 // Show received message status on Oled display
 #if _OLED>=1
 #if _OLED>=1
@@ -430,7 +399,7 @@ int buildPacket(uint8_t *buff_up, struct LoraUp *LoraUp, bool internal)
     display.drawString(40, 48, String((int)messageLength) );
     display.drawString(40, 48, String((int)messageLength) );
     display.display();
     display.display();
 
 
-#endif // _OLED>=1
+#endif //_OLED>=1
 			
 			
 //	int j;
 //	int j;
 	
 	
@@ -444,7 +413,7 @@ int buildPacket(uint8_t *buff_up, struct LoraUp *LoraUp, bool internal)
 		mPrint("R buildPacket:: b64 err, len=" + String(encodedLen));
 		mPrint("R buildPacket:: b64 err, len=" + String(encodedLen));
 		return(-1);
 		return(-1);
 	}
 	}
-#	endif // _MONITOR
+#	endif //_MONITOR
 
 
 	base64_encode(b64, (char *) message, messageLength);// max 341
 	base64_encode(b64, (char *) message, messageLength);// max 341
 	// start composing datagram with the header 
 	// start composing datagram with the header 
@@ -480,16 +449,15 @@ int buildPacket(uint8_t *buff_up, struct LoraUp *LoraUp, bool internal)
 #ifdef _JSONENCODE
 #ifdef _JSONENCODE
 //------------------
 //------------------
 	StaticJsonDocument<400> doc;
 	StaticJsonDocument<400> doc;
-	// MMM Get rid of this code when ready
 	
 	
-	//doc["time"] = "";
+	//doc["time"] = ""+now();
 
 
 	doc["chan"] = "0";
 	doc["chan"] = "0";
 	doc["rfch"] = "0";
 	doc["rfch"] = "0";
 	doc["freq"] = "" + (freqs[gwayConfig.ch].upFreq / 1000000);
 	doc["freq"] = "" + (freqs[gwayConfig.ch].upFreq / 1000000);
 	doc["stat"] = "1";
 	doc["stat"] = "1";
 	doc["modu"] = "LORA";
 	doc["modu"] = "LORA";
-	doc["datr"] = "SF" + String(LoraUp->sf) + "BW125";
+	doc["datr"] = "SF" + String(LoraUp->sf) + "BW" + String(freqs[gwayConfig.ch].upBW);
 	doc["rssi"] = "" +(prssi-rssicorr);
 	doc["rssi"] = "" +(prssi-rssicorr);
 	doc["lsnr"] = "" +(long)SNR;
 	doc["lsnr"] = "" +(long)SNR;
 	doc["codr"] = "4/5";
 	doc["codr"] = "4/5";
@@ -506,7 +474,7 @@ int buildPacket(uint8_t *buff_up, struct LoraUp *LoraUp, bool internal)
 	int written = serializeJson(doc, (const char *)p, buff_index+20 );		// size is buff_index + encoded data + some closing chars
 	int written = serializeJson(doc, (const char *)p, buff_index+20 );		// size is buff_index + encoded data + some closing chars
 
 
 
 
-#else // _JSONENCODE undefined or ==0, this is default
+#else //_JSONENCODE undefined, this is default
 // -----------------
 // -----------------
 	ftoa((double)freqs[gwayConfig.ch].upFreq / 1000000, cfreq, 6);		// XXX This can be done better
 	ftoa((double)freqs[gwayConfig.ch].upFreq / 1000000, cfreq, 6);		// XXX This can be done better
 	if ((LoraUp->sf<6) || (LoraUp->sf>12)) { 				// Lora datarate & bandwidth SF6-SF12, 16-19 useful chars */
 	if ((LoraUp->sf<6) || (LoraUp->sf>12)) { 				// Lora datarate & bandwidth SF6-SF12, 16-19 useful chars */
@@ -524,15 +492,15 @@ int buildPacket(uint8_t *buff_up, struct LoraUp *LoraUp, bool internal)
 		0, 0, cfreq);
 		0, 0, cfreq);
 	
 	
 	buff_index += snprintf((char *)(buff_up + buff_index), TX_BUFF_SIZE-buff_index
 	buff_index += snprintf((char *)(buff_up + buff_index), TX_BUFF_SIZE-buff_index
-		, ",\"datr\":\"SF%uBW125\",\"codr\":\"4/5\",\"lsnr\":%li,\"rssi\":%d,\"size\":%u,\"data\":\""
-		, LoraUp->sf, (long)SNR, prssi-rssicorr, messageLength);
+		, ",\"datr\":\"SF%uBW%u\",\"codr\":\"4/5\",\"lsnr\":%li,\"rssi\":%d,\"size\":%u,\"data\":\""
+		, LoraUp->sf, freqs[gwayConfig.ch].upBW, (long)SNR, prssi-rssicorr, messageLength);
 
 
 	// Use gBase64 library to fill in the data string
 	// Use gBase64 library to fill in the data string
 	encodedLen = base64_enc_len(messageLength);				// max 341
 	encodedLen = base64_enc_len(messageLength);				// max 341
 	buff_index += base64_encode((char *)(buff_up + buff_index), (char *) message, messageLength);
 	buff_index += base64_encode((char *)(buff_up + buff_index), (char *) message, messageLength);
 
 
 	
 	
-	LoraUp->tmst = (uint32_t) micros()+ _RXDELAY1; 			// MMM Correct timing with defined number,
+	LoraUp->tmst = (uint32_t) micros()+ _RXDELAY1; 			// Correct timing with defined number,
 															// https://github.com/TheThingsNetwork/lorawan-stack/issues/277
 															// https://github.com/TheThingsNetwork/lorawan-stack/issues/277
 
 
 	// Get rid of this code when ready	
 	// Get rid of this code when ready	
@@ -541,7 +509,7 @@ int buildPacket(uint8_t *buff_up, struct LoraUp *LoraUp, bool internal)
 		TX_BUFF_SIZE-buff_index, "\",\"tmst\":%u", 
 		TX_BUFF_SIZE-buff_index, "\",\"tmst\":%u", 
 		LoraUp->tmst);	
 		LoraUp->tmst);	
 
 
-#endif // _JSONENCODE undefined or ==0
+#endif //_JSONENCODE undefined or ==0
 // ---------------------
 // ---------------------
 
 
 
 
@@ -556,19 +524,18 @@ int buildPacket(uint8_t *buff_up, struct LoraUp *LoraUp, bool internal)
 	// When we have the node address and the SF, fill the listSeen array
 	// When we have the node address and the SF, fill the listSeen array
 	// with the required data. _MAXSEEN must be >0 for this to happen.
 	// with the required data. _MAXSEEN must be >0 for this to happen.
 	// statr[0] contains the statistics of the node last seen.
 	// statr[0] contains the statistics of the node last seen.
-#	if  _MAXSEEN >= 1
-		//yield();										// MMM 200316 Huge influence !!! on timing
+#	if  _MAXSEEN>=1
 		addSeen(listSeen, statr[0]);
 		addSeen(listSeen, statr[0]);
-#	endif
+#	endif //_MAXSEEN
 
 
-#	if _STAT_LOG == 1	
+#	if _STAT_LOG==1	
 		// Do statistics logging. In first version we might only
 		// Do statistics logging. In first version we might only
 		// write part of the record to files, later more
 		// write part of the record to files, later more
 		addLog( (unsigned char *)(buff_up), buff_index );
 		addLog( (unsigned char *)(buff_up), buff_index );
 #	endif //_STAT_LOG
 #	endif //_STAT_LOG
 
 
 #	if _MONITOR>=1
 #	if _MONITOR>=1
-	if ((debug>=2) && (pdebug & P_RX)) {			// debug: display JSON payload
+	if ((debug>=1) && (pdebug & P_RX)) {			// debug: display JSON payload
 		mPrint("UP RXPK:: "+String((char *)(buff_up + 12))+" , length="+String(buff_index));		
 		mPrint("UP RXPK:: "+String((char *)(buff_up + 12))+" , length="+String(buff_index));		
 	}
 	}
 #	endif
 #	endif
@@ -597,25 +564,20 @@ int buildPacket(uint8_t *buff_up, struct LoraUp *LoraUp, bool internal)
 int receivePacket()
 int receivePacket()
 {
 {
 	uint8_t buff_up[TX_BUFF_SIZE]; 						// buffer to compose the upstream packet to backend server
 	uint8_t buff_up[TX_BUFF_SIZE]; 						// buffer to compose the upstream packet to backend server
-	
+
 	// Regular message received, see SX1276 spec table 18
 	// Regular message received, see SX1276 spec table 18
 	// Next statement could also be a "while" to combine several messages received
 	// Next statement could also be a "while" to combine several messages received
 	// in one UDP message as the Semtech Gateway spec does allow this.
 	// in one UDP message as the Semtech Gateway spec does allow this.
 	// XXX Bit ... Not yet supported
 	// XXX Bit ... Not yet supported
 
 
-#ifdef _PROFILER
-	if ((debug>=1) && (pdebug & P_RX)) {
-		String response = "UP receivePacket:: start: micr=";
-			printInt(micros(),response);
-			response += ", tmst=";
-			printInt(LoraUp.tmst,response);
-			mPrint(response);
-	}
-#endif // _PROFILER
-		
+
 		// Handle the physical data read from LoraUp
 		// Handle the physical data read from LoraUp
 		if (LoraUp.payLength > 0) {
 		if (LoraUp.payLength > 0) {
 
 
+#			ifdef _PROFILER
+				int32_t startTime = micros();
+#			endif //_PROFILER
+
 			// externally received packet, so last parameter is false (==LoRa external)
 			// externally received packet, so last parameter is false (==LoRa external)
 			// Make a buffer to transmit later
 			// Make a buffer to transmit later
             int build_index = buildPacket(buff_up, &LoraUp, false);
             int build_index = buildPacket(buff_up, &LoraUp, false);
@@ -642,15 +604,15 @@ int receivePacket()
 			yield();
 			yield();
 			Udp.flush();								// MMM 200419
 			Udp.flush();								// MMM 200419
 
 
-#ifdef _PROFILER
+#			ifdef _PROFILER
 			if ((debug>=1) && (pdebug & P_RX)) {
 			if ((debug>=1) && (pdebug & P_RX)) {
-				String response = "UP receivePacket:: sendUdp: micr=";
-				printInt(micros(),response);
-				response += ", tmst=";
-				printInt(LoraUp.tmst,response);
+				int32_t endTime = micros();
+				String response = "UP receivePacket:: end="; printInt(endTime,response);
+				response += ", start="; printInt(startTime, response);
+				response += ", diff=" +String(endTime-startTime) + " uSec";
 				mPrint(response);
 				mPrint(response);
 			}
 			}
-#endif // _PROFILER
+#			endif //_PROFILER
 
 
 #			ifdef _THINGSERVER
 #			ifdef _THINGSERVER
 			// Use our own defined server or a second well known server
 			// Use our own defined server or a second well known server
@@ -692,9 +654,9 @@ int receivePacket()
 				DevAddr[3]= LoraUp.payLoad[1];
 				DevAddr[3]= LoraUp.payLoad[1];
 				//uint16_t frameCount=LoraUp.payLoad[7]*256 + LoraUp.payLoad[6];
 				//uint16_t frameCount=LoraUp.payLoad[7]*256 + LoraUp.payLoad[6];
 
 
-#if _DUSB>=1
+#if				_DUSB>=1
 				if ((debug>=2) && (pdebug & P_RX)) {
 				if ((debug>=2) && (pdebug & P_RX)) {
-					Serial.print(F("R receivePacket:: Ind="));
+					Serial.print(F("UP receivePacket:: Ind="));
 					Serial.print(index);
 					Serial.print(index);
 					Serial.print(F(", Len="));
 					Serial.print(F(", Len="));
 					Serial.print(LoraUp.payLength);
 					Serial.print(LoraUp.payLength);
@@ -711,27 +673,25 @@ int receivePacket()
 						Serial.print(statr[0].data[i],HEX);
 						Serial.print(statr[0].data[i],HEX);
 						Serial.print(' ');
 						Serial.print(' ');
 					}
 					}
-					Serial.println();
 				}
 				}
-#endif //DUSB
+#				endif //_DUSB
 
 
 			}
 			}
 #			if _MONITOR>=1
 #			if _MONITOR>=1
-			else if (( debug>=2 ) && ( pdebug & P_RX )) {
+			else if ((debug>=2) && (pdebug & P_RX)) {
 					mPrint("receivePacket:: No Index");
 					mPrint("receivePacket:: No Index");
 			}
 			}
 #			endif //_MONITOR
 #			endif //_MONITOR
-#endif // _LOCALSERVER
+#endif //_LOCALSERVER
 
 
 			// Reset the message area
 			// Reset the message area
 			LoraUp.payLength = 0;
 			LoraUp.payLength = 0;
 			LoraUp.payLoad[0] = 0x00;
 			LoraUp.payLoad[0] = 0x00;
-			
-			
+
 			return(build_index);
 			return(build_index);
         }
         }
-		
+
 	return(0);											// failure no message read
 	return(0);											// failure no message read
-	
+
 }//receivePacket
 }//receivePacket
 
 

+ 79 - 64
src/_udpSemtech.ino

@@ -101,7 +101,7 @@ int readUdp(int packetSize)
 	uint8_t buff_down[RX_BUFF_SIZE];		// Buffer for downstream
 	uint8_t buff_down[RX_BUFF_SIZE];		// Buffer for downstream
 
 
 	// Make sure we are connected over WiFI
 	// Make sure we are connected over WiFI
-	if (WlanConnect(10) < 0) {				// MMM 200316 Every call contains yield()
+	if (WlanConnect(10) < 0) {
 #		if _MONITOR>=1
 #		if _MONITOR>=1
 			mPrint("Dwn readUdp:: ERROR connecting to WLAN");
 			mPrint("Dwn readUdp:: ERROR connecting to WLAN");
 #		endif //_MONITOR
 #		endif //_MONITOR
@@ -109,8 +109,6 @@ int readUdp(int packetSize)
 		return(-1);
 		return(-1);
 	}
 	}
 	
 	
-	//yield();								// MMM 200320 Clear buffer in kernel (?)
-	
 	if (packetSize > RX_BUFF_SIZE) {
 	if (packetSize > RX_BUFF_SIZE) {
 #		if _MONITOR>=1
 #		if _MONITOR>=1
 			mPrint("Dwn readUdp:: ERROR package of size: " + String(packetSize));
 			mPrint("Dwn readUdp:: ERROR package of size: " + String(packetSize));
@@ -118,8 +116,6 @@ int readUdp(int packetSize)
 		Udp.flush();
 		Udp.flush();
 		return(-1);
 		return(-1);
 	}
 	}
-
-	//yield();								// MMM 200406
 	
 	
 	// We assume here that we know the originator of the message.
 	// We assume here that we know the originator of the message.
 	// In practice however this can be any sender!
 	// In practice however this can be any sender!
@@ -160,7 +156,7 @@ int readUdp(int packetSize)
 		uint8_t ident= buff_down[3];
 		uint8_t ident= buff_down[3];
 
 
 #		if _MONITOR>=1
 #		if _MONITOR>=1
-		if ((debug>=2) && (pdebug & P_TX)) {
+		if ((debug>=3) && (pdebug & P_TX)) {
 			mPrint("Dwn readUdp:: message ident="+String(ident));
 			mPrint("Dwn readUdp:: message ident="+String(ident));
 		}
 		}
 #		endif //_MONITOR
 #		endif //_MONITOR
@@ -173,23 +169,37 @@ int readUdp(int packetSize)
 		// As this function is used for downstream only, this option
 		// As this function is used for downstream only, this option
 		// will never be selected but is included as a reference only
 		// will never be selected but is included as a reference only
 		// Para 5.2.1, Semtech Gateway to Server Interface document
 		// Para 5.2.1, Semtech Gateway to Server Interface document
+		//	Byte 0:		Version
+		//	byte 1+2:	Token
+		//	byte 3: 	Command code (0x00)
+		//
 		case PKT_PUSH_DATA: 							// 0x00 UP
 		case PKT_PUSH_DATA: 							// 0x00 UP
 #			if _MONITOR>=1
 #			if _MONITOR>=1
 			if (debug>=1) {
 			if (debug>=1) {
 				mPrint("Dwn PKT_PUSH_DATA:: size "+String(packetSize)+" From "+String(remoteIpNo.toString()));
 				mPrint("Dwn PKT_PUSH_DATA:: size "+String(packetSize)+" From "+String(remoteIpNo.toString()));
 			}
 			}
 #			endif //_MONITOR
 #			endif //_MONITOR
-			//Udp.flush();
+			Udp.flush();
 		break;
 		break;
 
 
 
 
 		// This message is sent DOWN by the server to acknowledge receipt of a
 		// This message is sent DOWN by the server to acknowledge receipt of a
 		// (sensor) PKT_PUSH_DATA message sent with the code above.
 		// (sensor) PKT_PUSH_DATA message sent with the code above.
 		// Para 5.2.2, Semtech Gateway to Server Interface document
 		// Para 5.2.2, Semtech Gateway to Server Interface document
+		// The length of this package is 4 bytes:
+		//	byte 0:		Protol version (0x01 or 0x02)
+		//	byte 1+2:	Token copied from requestor
+		//	byte 3:		0x01, ack PKT_PUSH_ACK
+		//
 		case PKT_PUSH_ACK:								// 0x01 DOWN
 		case PKT_PUSH_ACK:								// 0x01 DOWN
 #			if _MONITOR>=1
 #			if _MONITOR>=1
 			if ((debug>=2) && (pdebug & P_TX)) {
 			if ((debug>=2) && (pdebug & P_TX)) {
-				mPrint("Dwn PKT_PUSH_ACK:: size="+String(packetSize)+", From "+String(remoteIpNo.toString())); 
+				char res[128];				
+				sprintf(res, "Dwn PKT_PUSH_ACK:: size=%u, IP=%d.%d.%d.%d, port=%d ", 
+					packetSize, 
+					remoteIpNo[0], remoteIpNo[1], remoteIpNo[2],remoteIpNo[3], 
+					remotePortNo);
+				mPrint(res);
 			}
 			}
 #			endif //_MONITOR
 #			endif //_MONITOR
 			//Udp.flush();
 			//Udp.flush();
@@ -200,13 +210,14 @@ int readUdp(int packetSize)
 		// This is a request/UP message and will not be executed by this function.
 		// This is a request/UP message and will not be executed by this function.
 		// We have it here as a description only. 
 		// We have it here as a description only. 
 		//	Para 5.2.3, Semtech Gateway to Server Interface document
 		//	Para 5.2.3, Semtech Gateway to Server Interface document
+		//
 		case PKT_PULL_DATA:								// 0x02 UP
 		case PKT_PULL_DATA:								// 0x02 UP
 #			if _MONITOR>=1
 #			if _MONITOR>=1
 			if ((debug>=1) && (pdebug & P_RX)) {
 			if ((debug>=1) && (pdebug & P_RX)) {
-				mPrint("Dwn readUdp:: PKT_PULL_DATA");
+				mPrint("Dwn PKT_PULL_DATA");
 			}
 			}
 #			endif //_MONITOR
 #			endif //_MONITOR
-			Udp.flush();					// MMM 200419 Added
+			Udp.flush();								// MMM 200419 Added
 		break;
 		break;
 
 
 
 
@@ -224,24 +235,14 @@ int readUdp(int packetSize)
 		case PKT_PULL_ACK:								// 0x04 DOWN
 		case PKT_PULL_ACK:								// 0x04 DOWN
 #			if _MONITOR>=1
 #			if _MONITOR>=1
 			if ((debug>=2) && (pdebug & P_TX)) {
 			if ((debug>=2) && (pdebug & P_TX)) {
-				String response="Dwn readUdp PKT_PULL_ACK: micr=";
-				printInt(micros(), response);
-				response += ", size="+String(packetSize)+" From ";
-				printIP(remoteIpNo,'.',response);
-				response += ", port " +String(remotePortNo);
-				mPrint(response);
-
-				if (debug>=2) {
-					Serial.print(F(", data: "));
-					for (int i=0; i<packetSize; i++) {
-						Serial.print(buff_down[i],HEX);
-						Serial.print(':');
-					}
-					Serial.println();
-				}
+				char res[128];				
+				sprintf(res, "Dwn PKT_PULL_ACK:: size=%u, IP=%d.%d.%d.%d, port=%d ", 
+					packetSize, 
+					remoteIpNo[0], remoteIpNo[1], remoteIpNo[2],remoteIpNo[3], 
+					remotePortNo);
+				mPrint(res);
 			}
 			}
 #			endif //_MONITOR
 #			endif //_MONITOR
-
 			
 			
 			yield();			
 			yield();			
 			
 			
@@ -258,13 +259,14 @@ int readUdp(int packetSize)
 		//	JOIN_ACCEPT_DELAY1	5 s
 		//	JOIN_ACCEPT_DELAY1	5 s
 		//	JOIN_ACCEPT_DELAY2	6 s
 		//	JOIN_ACCEPT_DELAY2	6 s
 		// Para 5.2.5, Semtech Gateway to Server Interface document
 		// Para 5.2.5, Semtech Gateway to Server Interface document
+		// or https://github.com/Lora-net/packet_forwarder/blob/master/PROTOCOL.TXT
 		//
 		//
 		case PKT_PULL_RESP:								// 0x03 DOWN
 		case PKT_PULL_RESP:								// 0x03 DOWN
 
 
 			// Define when we start with the response to node
 			// Define when we start with the response to node
 #			ifdef _PROFILER
 #			ifdef _PROFILER
-			if ((debug>=1) && (pdebug & P_TX)) {
-				mPrint("Dwn PKT_PULL_RESP:: sendPacket: micros="+String(micros() ));
+			if ((debug>=2) && (pdebug & P_TX)) {
+				mPrint("Dwn PKT_PULL_RESP:: start sendPacket: micros="+String(micros() ));
 			}
 			}
 #			endif //_PROFILER
 #			endif //_PROFILER
 
 
@@ -301,27 +303,14 @@ int readUdp(int packetSize)
 			// (We normally react on ALL interrupts if we are in TX state)
 			// (We normally react on ALL interrupts if we are in TX state)
 			txLoraModem(&LoraDown);
 			txLoraModem(&LoraDown);
 
 
-			// wait extra delay out. The delayMicroseconds timer is accurate until 16383 uSec.
-#			ifdef _PROFILER
-			if ((debug>=1) && (pdebug & P_TX))
-			{
-				String response = "Dwn PKT_PULL_RESP:: txLoraModem done: ";
-				printDwn(&LoraDown, response);
-				mPrint(response);
-			}
-#			endif //_PROFILER
-
 #			if _MONITOR>=1
 #			if _MONITOR>=1
-			if (( debug>=2 ) && ( pdebug & P_TX )) {
+			if ((debug>=2) && (pdebug & P_TX)) {
 				uint8_t flags = readRegister(REG_IRQ_FLAGS);
 				uint8_t flags = readRegister(REG_IRQ_FLAGS);
 				uint8_t mask  = readRegister(REG_IRQ_FLAGS_MASK);
 				uint8_t mask  = readRegister(REG_IRQ_FLAGS_MASK);
 				uint8_t intr  = flags & ( ~ mask );
 				uint8_t intr  = flags & ( ~ mask );
 
 
-				String response="Dwn txLoraModem fini:: ";
-				mStat(intr, response);
-				mPrint(response); 
 
 
-				response = "Dwn readUdp:: PKT_PULL_RESP from IP="+String(remoteIpNo.toString())
+				String response = "Dwn readUdp:: PKT_PULL_RESP from IP="+String(remoteIpNo.toString())
 					+", micros=" + String(micros())
 					+", micros=" + String(micros())
 					+", wait=";
 					+", wait=";
 				if (sendTime < micros()) {
 				if (sendTime < micros()) {
@@ -330,7 +319,12 @@ int readUdp(int packetSize)
 				else {
 				else {
 					response += "-" + String(sendTime - micros()) ;
 					response += "-" + String(sendTime - micros()) ;
 				};
 				};
-				mPrint(response);
+
+
+				response+=", stat:: ";
+				mStat(intr, response);
+				mPrint(response); 
+
 			}
 			}
 #			endif //_MONITOR
 #			endif //_MONITOR
 
 
@@ -338,19 +332,33 @@ int readUdp(int packetSize)
 			// So, more or less start at the "case TXDONE:"  
 			// So, more or less start at the "case TXDONE:"  
 			_state=S_TXDONE;
 			_state=S_TXDONE;
 			_event=1;										// Or remove the break below
 			_event=1;										// Or remove the break below
-			
-			// No break!!
 
 
+//			Udp.flush();									// MMM 200509 flush UDP buffer
+
+			// No break!! so next secton will be executed
+
+#		ifdef _PROFILER
+		// measure the total time for transmissioon here
+			if ((debug>=2) && (pdebug & P_TX)) {
+				mPrint("Dwn PKT_PULL_RESP:: finit: micros="+String(micros() ));
+			}
+#		endif //_PROFILER
 
 
 		// This is the response to the PKT_PULL_RESP message by the sensor device
 		// This is the response to the PKT_PULL_RESP message by the sensor device
 		// it is sent by the gateway UP to the server to confirm the PULL_RESP message.
 		// it is sent by the gateway UP to the server to confirm the PULL_RESP message.
+		//	byte 0:		Protocol version
+		//	byte 1+2:	Port number of originator
+		//	byte 3:		Message ID TX_ACK == 0x06
+		//	byte 4-11:	Gateway ident
+		//	byte 12-:	Optional Error Data
 		//
 		//
 		case PKT_TX_ACK:									// Message id: 0x05 UP
 		case PKT_TX_ACK:									// Message id: 0x05 UP
 
 
 			if (buff_down[0]== 1) {
 			if (buff_down[0]== 1) {
 #				if _MONITOR>=1
 #				if _MONITOR>=1
-				if ((debug>=1) && (pdebug & P_TX)) {
+				if ((debug>=3) && (pdebug & P_TX)) {
 					mPrint("UP readUdp:: PKT_TX_ACK: protocol version 1");
 					mPrint("UP readUdp:: PKT_TX_ACK: protocol version 1");
+					
 					data = buff_down + 4;
 					data = buff_down + 4;
 					data[packetSize] = 0;
 					data[packetSize] = 0;
 				}
 				}
@@ -358,11 +366,11 @@ int readUdp(int packetSize)
 				break;										// return
 				break;										// return
 			}
 			}
 
 
-#			ifdef _PROFILER
-			if ((debug>=1) && (pdebug & P_TX)) {
+#			if _MONITOR>=1
+			if ((debug>=2) && (pdebug & P_TX)) {
 				mPrint("UP readUDP:: TX_ACK protocol version 2+");
 				mPrint("UP readUDP:: TX_ACK protocol version 2+");
 			}
 			}
-#			endif //_PROFILER
+#			endif //_MONITOR
 
 
 
 
 			// Now respond with an PKT_TX_ACK; UP 
 			// Now respond with an PKT_TX_ACK; UP 
@@ -396,7 +404,7 @@ int readUdp(int packetSize)
 			}
 			}
 			else {
 			else {
 #				if _MONITOR>=1
 #				if _MONITOR>=1
-				if ((debug>=0) && (pdebug & P_TX)) {
+				if ((debug>=2) && (pdebug & P_TX)) {
 					mPrint("UP readUdp:: PKT_TX_ACK: micros="+String(micros()));
 					mPrint("UP readUdp:: PKT_TX_ACK: micros="+String(micros()));
 				}
 				}
 #				endif //_MONITOR
 #				endif //_MONITOR
@@ -437,10 +445,18 @@ int readUdp(int packetSize)
 		}
 		}
 		
 		
 #		if _MONITOR>=1
 #		if _MONITOR>=1
-		if (debug>=2) {
-			String response= "Dwn readUdp:: ret="+String(packetSize)+", data=";
-			for (int i=0; i<packetSize; i++) {
-				response+= String(buff_down[i]) + " ";
+		if ((debug>=3) && (pdebug & P_TX)) {
+			String response= "Dwn readUdp:: ident="+String(ident,HEX);
+			response+= ", tmst=" + String(LoraDown.tmst);
+			response+= ", imme=" + String(LoraDown.imme);
+			response+= ", sfTx=" + String(LoraDown.sfTx);
+			response+= ", freq=" + String(LoraDown.freq);
+			if (debug>=3) {
+				if (packetSize > 4) {
+					response+= ", size=" + String(packetSize) + ", data=";
+					buff_down[packetSize] = 0;
+					response+=String((char *)(buff_down+4));
+				}
 			}
 			}
 			mPrint(response); 
 			mPrint(response); 
 		}
 		}
@@ -472,19 +488,18 @@ int sendUdp(IPAddress server, int port, uint8_t *msg, uint16_t length)
 	// Check whether we are conected to Wifi and the internet
 	// Check whether we are conected to Wifi and the internet
 	if (WlanConnect(3) < 0) {
 	if (WlanConnect(3) < 0) {
 #		if _MONITOR>=1
 #		if _MONITOR>=1
-		if ( pdebug & P_MAIN ) {
+		if (pdebug & P_MAIN) {
 			mPrint("sendUdp: ERROR not connected to WiFi");
 			mPrint("sendUdp: ERROR not connected to WiFi");
 		}
 		}
-#		endif //_MONITOR						// MMM 200426 We removed yield() 
+#		endif //_MONITOR
 		Udp.flush();
 		Udp.flush();
 		return(0);
 		return(0);
 	}
 	}
 
 
-	//yield();									// MMM 200327 yield not necessary
 
 
 	//send the update
 	//send the update
 #	if _MONITOR>=1
 #	if _MONITOR>=1
-	if (( debug>=2 ) && ( pdebug & P_MAIN )) {
+	if ((debug>=2) && (pdebug & P_MAIN)) {
 		mPrint("sendUdp: WlanConnect connected to="+WiFi.SSID()+". Server IP="+ String(WiFi.localIP().toString()) );
 		mPrint("sendUdp: WlanConnect connected to="+WiFi.SSID()+". Server IP="+ String(WiFi.localIP().toString()) );
 	}
 	}
 #	endif //_MONITOR
 #	endif //_MONITOR
@@ -526,7 +541,7 @@ int sendUdp(IPAddress server, int port, uint8_t *msg, uint16_t length)
 
 
 
 
 
 
-// ----------------------------------------------------------------------------
+// --------------------------------- UP ---------------------------------------
 // pullData()
 // pullData()
 // Send UDP periodic Pull_DATA message UP to server to keepalive the connection
 // Send UDP periodic Pull_DATA message UP to server to keepalive the connection
 // and to invite the server to send downstream messages when these are available
 // and to invite the server to send downstream messages when these are available
@@ -591,14 +606,14 @@ void pullData()
 		}
 		}
 		Serial.println();
 		Serial.println();
 	}
 	}
-#endif // _MONITOR
+#endif //_MONITOR
 
 
 	return;
 	return;
 	
 	
 } // pullData()
 } // pullData()
 
 
 
 
-// ----------------------------------------------------------------------------
+// ---------------------------------- UP --------------------------------------
 // sendstat()
 // sendstat()
 // Send UP periodic status message to server even when we do not receive any
 // Send UP periodic status message to server even when we do not receive any
 // data. 
 // data. 
@@ -655,8 +670,8 @@ void sendstat()
     status_report[stat_index] = 0; 							// add string terminator, for safety
     status_report[stat_index] = 0; 							// add string terminator, for safety
 
 
 #	if _MONITOR>=1
 #	if _MONITOR>=1
-    if (( debug>=2 ) && ( pdebug & P_MAIN )) {
-		mPrint("M stat update: <"+String(stat_index)+"> "+String((char *)(status_report+12)) );
+    if ((debug>=2) && (pdebug & P_RX)) {
+		mPrint("RX stat update: <"+String(stat_index)+"> "+String((char *)(status_report+12)) );
 	}
 	}
 #	endif //_MONITOR
 #	endif //_MONITOR
 
 

+ 13 - 12
src/_utils.ino

@@ -130,7 +130,7 @@ void printHexDigit(uint8_t digit, String & response)
 
 
 
 
 // ----------------------------------------------------------------------------------------
 // ----------------------------------------------------------------------------------------
-// Print to the monitor console.
+// Print one line to the monitor console array.
 // This function is used all over the gateway code as a substitute for USB debug code.
 // This function is used all over the gateway code as a substitute for USB debug code.
 // It allows webserver users to view printed/debugging code.
 // It allows webserver users to view printed/debugging code.
 // With initMonitor() we init the index iMoni=0;
 // With initMonitor() we init the index iMoni=0;
@@ -142,7 +142,14 @@ void printHexDigit(uint8_t digit, String & response)
 // ----------------------------------------------------------------------------------------
 // ----------------------------------------------------------------------------------------
 void mPrint(String txt) 
 void mPrint(String txt) 
 {
 {
-#	if _MONITOR>=1
+
+#	if _DUSB>=1
+	if (gwayConfig.dusbStat>=1) {
+		Serial.println(txt);								// Copy to serial when configured
+	}
+#	endif //_DUSB
+
+#if _MONITOR>=1
 	time_t tt = now();
 	time_t tt = now();
 	
 	
 	monitor[iMoni].txt = "";
 	monitor[iMoni].txt = "";
@@ -152,18 +159,12 @@ void mPrint(String txt)
 	
 	
 	// Use the circular buffer to increment the index
 	// Use the circular buffer to increment the index
 
 
-#	if _DUSB>=1
-	if (gwayConfig.dusbStat>=1) {
-		Serial.println(monitor[iMoni].txt);			// Copy to serial when configured
-	}
-#	endif //_DUSB
-
-	iMoni = (iMoni+1) % _MAXMONITOR	;				// And goto 0 when skipping over _MAXMONITOR
+	iMoni = (iMoni+1) % gwayConfig.maxMoni	;				// And goto 0 when skipping over _MAXMONITOR
 	
 	
-#	endif //_MONITOR
+#endif //_MONITOR
 
 
 	return;
 	return;
-}
+} //mPrint
 
 
 
 
 // ----------------------------------------------------------------------------
 // ----------------------------------------------------------------------------
@@ -495,7 +496,7 @@ int SerialName(uint32_t a, String & response)
 			return(i);
 			return(i);
 		}
 		}
 	}
 	}
-#endif // _TRUSTED_NODES
+#endif //_TRUSTED_NODES
 
 
 	return(-1);									// If no success OR is TRUSTED NODES not defined
 	return(-1);									// If no success OR is TRUSTED NODES not defined
 } //SerialName
 } //SerialName

+ 295 - 199
src/_wwwServer.ino

@@ -110,21 +110,22 @@ void wwwFile(String fn)
 
 
 	if (!SPIFFS.exists(fn)) {
 	if (!SPIFFS.exists(fn)) {
 #		if _MONITOR>=1
 #		if _MONITOR>=1
-			mPrint("wwwFile:: ERROR: SPIFFS file not found=");
+			mPrint("wwwFile:: ERROR: SPIFFS file not found="+fn);
 #		endif //_MONITOR
 #		endif //_MONITOR
 		return;
 		return;
 	} 
 	} 
-	
 #	if _MONITOR>=1
 #	if _MONITOR>=1
-	else if (debug>=2) {
-		mPrint("wwwFile:: SPIFFS Filesystem existist= " + String(fn));
+	else if (debug>=1) {
+		mPrint("wwwFile:: SPIFFS Filesystem exists= " + String(fn));
 	}
 	}
+	uint16_t readFile = 0;
 #	endif //_MONITOR
 #	endif //_MONITOR
 
 
 #	if _MONITOR>=1
 #	if _MONITOR>=1
+
 	File f = SPIFFS.open(fn, "r");					// Open the file for reading
 	File f = SPIFFS.open(fn, "r");					// Open the file for reading
-	
-	// MMM Change LOGFILEREC to file available
+
+	// If file is available
 	while (f.available()) {
 	while (f.available()) {
 
 
 		String s=f.readStringUntil('\n');
 		String s=f.readStringUntil('\n');
@@ -134,16 +135,20 @@ void wwwFile(String fn)
 		}
 		}
 		server.sendContent(s.substring(12));		// Skip the first 12 Gateway specific binary characters
 		server.sendContent(s.substring(12));		// Skip the first 12 Gateway specific binary characters
 		server.sendContent("\n");
 		server.sendContent("\n");
+
+		readFile++;
+
 		yield();
 		yield();
 	}
 	}
 
 
 	f.close();
 	f.close();
 
 
 #	endif //_MONITOR
 #	endif //_MONITOR
+
 #endif //_STAT_LOG
 #endif //_STAT_LOG
 
 
 	return;
 	return;
-	
+
 }
 }
 
 
 // --------------------------------------------------------------------------------
 // --------------------------------------------------------------------------------
@@ -185,9 +190,15 @@ void buttonDocu()
 void buttonLog() 
 void buttonLog() 
 {
 {
 #if _STAT_LOG == 1	
 #if _STAT_LOG == 1	
+
+	int startFile = (gwayConfig.logFileNo > LOGFILEMAX ? (gwayConfig.logFileNo - LOGFILEMAX) : 0);
 	
 	
-	for (int i=0; i< LOGFILEMAX; i++ ) {
-		String fn = "/log-" + String(gwayConfig.logFileNo - i);
+#	if _MONITOR>=1
+		mPrint("buttonLog:: gwayConfig.logFileNo="+String(gwayConfig.logFileNo)+", LOGFILEMAX="+String(LOGFILEMAX)+", startFile="+String(startFile)+", recs="+String(gwayConfig.logFileRec) );
+#	endif //_MONITOR
+
+	for (int i=startFile; i<= gwayConfig.logFileNo; i++ ) {
+		String fn = "/log-" + String(i);
 		wwwFile(fn);									// Display the file contents in the browser
 		wwwFile(fn);									// Display the file contents in the browser
 	}
 	}
 	
 	
@@ -216,13 +227,15 @@ static void wwwButtons()
 #	if _STAT_LOG == 1
 #	if _STAT_LOG == 1
 	response += "<a href=\"LOG\" download><button type=\"button\">Log Files</button></a>";
 	response += "<a href=\"LOG\" download><button type=\"button\">Log Files</button></a>";
 #	endif //__STAT_LOG
 #	endif //__STAT_LOG
+
 	response += "<a href=\"EXPERT\" download><button type=\"button\">" + mode + "</button></a>";
 	response += "<a href=\"EXPERT\" download><button type=\"button\">" + mode + "</button></a>";
 #	if _MONITOR>=1
 #	if _MONITOR>=1
 	response += "<a href=\"MONITOR\" download><button type=\"button\">" +moni+ "</button></a>";
 	response += "<a href=\"MONITOR\" download><button type=\"button\">" +moni+ "</button></a>";
-#	endif
+#	endif //_MONITOR
+
 #	if _MAXSEEN>=1
 #	if _MAXSEEN>=1
 	response += "<a href=\"SEEN\" download><button type=\"button\">" +seen+ "</button></a>";
 	response += "<a href=\"SEEN\" download><button type=\"button\">" +seen+ "</button></a>";
-#	endif
+#	endif //_MAXSEEN
 	server.sendContent(response);							// Send to the screen
 	server.sendContent(response);							// Send to the screen
 	
 	
 	return;
 	return;
@@ -255,12 +268,12 @@ static void setVariables(const char *cmd, const char *arg)
 		else if (atoi(arg) == -1) {
 		else if (atoi(arg) == -1) {
 			debug = (debug+3)%4;
 			debug = (debug+3)%4;
 		}
 		}
-		writeGwayCfg(CONFIGFILE, &gwayConfig );						// Save configuration to file
+		writeGwayCfg(_CONFIGFILE, &gwayConfig );					// Save configuration to file
 	}
 	}
 	
 	
 	if (strcmp(cmd, "CAD")==0) {									// Set -cad on=1 or off=0
 	if (strcmp(cmd, "CAD")==0) {									// Set -cad on=1 or off=0
 		gwayConfig.cad=(bool)atoi(arg);
 		gwayConfig.cad=(bool)atoi(arg);
-		writeGwayCfg(CONFIGFILE, &gwayConfig );						// Save configuration to file
+		writeGwayCfg(_CONFIGFILE, &gwayConfig );					// Save configuration to file
 	}
 	}
 	
 	
 	if (strcmp(cmd, "HOP")==0) {									// Set -hop on=1 or off=0
 	if (strcmp(cmd, "HOP")==0) {									// Set -hop on=1 or off=0
@@ -271,14 +284,14 @@ static void setVariables(const char *cmd, const char *arg)
 			sf = SF7;
 			sf = SF7;
 			cadScanner();
 			cadScanner();
 		}
 		}
-		writeGwayCfg(CONFIGFILE, &gwayConfig );						// Save configuration to file
+		writeGwayCfg(_CONFIGFILE, &gwayConfig );					// Save configuration to file
 	}
 	}
 	
 	
 	// DELAY, write txDelay for transmissions
 	// DELAY, write txDelay for transmissions
 	//
 	//
 	if (strcmp(cmd, "DELAY")==0) {									// Set delay usecs
 	if (strcmp(cmd, "DELAY")==0) {									// Set delay usecs
 		gwayConfig.txDelay+=atoi(arg)*1000;
 		gwayConfig.txDelay+=atoi(arg)*1000;
-		writeGwayCfg(CONFIGFILE, &gwayConfig );						// Save configuration to file
+		writeGwayCfg(_CONFIGFILE, &gwayConfig );					// Save configuration to file
 	}
 	}
 
 
 	// TRUSTED, write node trusted value 
 	// TRUSTED, write node trusted value 
@@ -291,7 +304,7 @@ static void setVariables(const char *cmd, const char *arg)
 		else if (atoi(arg) == -1) {
 		else if (atoi(arg) == -1) {
 			gwayConfig.trusted = (gwayConfig.trusted -1)%4;
 			gwayConfig.trusted = (gwayConfig.trusted -1)%4;
 		}
 		}
-		writeGwayCfg(CONFIGFILE, &gwayConfig );						// Save configuration to file
+		writeGwayCfg(_CONFIGFILE, &gwayConfig );					// Save configuration to file
 	}
 	}
 	
 	
 	// SF; Handle Spreading Factor Settings
 	// SF; Handle Spreading Factor Settings
@@ -304,7 +317,7 @@ static void setVariables(const char *cmd, const char *arg)
 			if (sf<=SF7) sf=SF12; else sf= (sf_t)((int)sf-1);
 			if (sf<=SF7) sf=SF12; else sf= (sf_t)((int)sf-1);
 		}
 		}
 		rxLoraModem();												// Reset the radio with the new spreading factor
 		rxLoraModem();												// Reset the radio with the new spreading factor
-		writeGwayCfg(CONFIGFILE, &gwayConfig );						// Save configuration to file
+		writeGwayCfg(_CONFIGFILE, &gwayConfig );					// Save configuration to file
 	}
 	}
 	
 	
 	// FREQ; Handle Frequency  Settings
 	// FREQ; Handle Frequency  Settings
@@ -322,7 +335,7 @@ static void setVariables(const char *cmd, const char *arg)
 		}
 		}
 		setFreq(freqs[gwayConfig.ch].upFreq);
 		setFreq(freqs[gwayConfig.ch].upFreq);
 		rxLoraModem();												// Reset the radio with the new frequency
 		rxLoraModem();												// Reset the radio with the new frequency
-		writeGwayCfg(CONFIGFILE, &gwayConfig );						// Save configuration to file
+		writeGwayCfg(_CONFIGFILE, &gwayConfig );						// Save configuration to file
 	}
 	}
 
 
 	if (strcmp(cmd, "GETTIME")==0) { 								// Get the local time
 	if (strcmp(cmd, "GETTIME")==0) { 								// Get the local time
@@ -338,14 +351,14 @@ static void setVariables(const char *cmd, const char *arg)
 #if _GATEWAYNODE==1
 #if _GATEWAYNODE==1
 	if (strcmp(cmd, "NODE")==0) {									// Set node on=1 or off=0
 	if (strcmp(cmd, "NODE")==0) {									// Set node on=1 or off=0
 		gwayConfig.isNode =(bool)atoi(arg);
 		gwayConfig.isNode =(bool)atoi(arg);
-		writeGwayCfg(CONFIGFILE, &gwayConfig );						// Save configuration to file
+		writeGwayCfg(_CONFIGFILE, &gwayConfig );					// Save configuration to file
 	}
 	}
 	
 	
 	// File Counter//
 	// File Counter//
 	if (strcmp(cmd, "FCNT")==0)   { 
 	if (strcmp(cmd, "FCNT")==0)   { 
 		frameCount=0; 
 		frameCount=0; 
 		rxLoraModem();												// Reset the radio with the new frequency
 		rxLoraModem();												// Reset the radio with the new frequency
-		writeGwayCfg(CONFIGFILE, &gwayConfig );
+		writeGwayCfg(_CONFIGFILE, &gwayConfig );
 	}
 	}
 #endif
 #endif
 	
 	
@@ -370,12 +383,12 @@ static void setVariables(const char *cmd, const char *arg)
 		String ssid = String(AP_NAME) + "-" + String(ESP_getChipId(), HEX);
 		String ssid = String(AP_NAME) + "-" + String(ESP_getChipId(), HEX);
 		
 		
 #		if _MONITOR>=1
 #		if _MONITOR>=1
-		if ((debug>=1) && ( pdebug & P_GUI )) {
+		if ((debug>=1) && (pdebug & P_MAIN)) {
 			mPrint("Set Variables:: ssid="+ ssid );
 			mPrint("Set Variables:: ssid="+ ssid );
 		}
 		}
 #		endif //_MONITOR
 #		endif //_MONITOR
 
 
-		// wifiManager.startConfigPortal( ssid.c_str(), AP_PASSWD );		// MMM added 23Feb
+		// wifiManager.startConfigPortal( ssid.c_str(), AP_PASSWD );
 	}
 	}
 #endif //_WIFIMANAGER
 #endif //_WIFIMANAGER
 
 
@@ -384,7 +397,7 @@ static void setVariables(const char *cmd, const char *arg)
 	if (strcmp(cmd, "UPDATE")==0) {
 	if (strcmp(cmd, "UPDATE")==0) {
 		if (atoi(arg) == 1) {
 		if (atoi(arg) == 1) {
 			updateOtaa();
 			updateOtaa();
-			writeGwayCfg(CONFIGFILE, &gwayConfig );
+			writeGwayCfg(_CONFIGFILE, &gwayConfig );
 		}
 		}
 	}
 	}
 #endif
 #endif
@@ -392,7 +405,7 @@ static void setVariables(const char *cmd, const char *arg)
 #if _REFRESH==1
 #if _REFRESH==1
 	if (strcmp(cmd, "REFR")==0) {									// Set refresh on=1 or off=0
 	if (strcmp(cmd, "REFR")==0) {									// Set refresh on=1 or off=0
 		gwayConfig.refresh =(bool)atoi(arg);
 		gwayConfig.refresh =(bool)atoi(arg);
-		writeGwayCfg(CONFIGFILE, &gwayConfig );						// Save configuration to file
+		writeGwayCfg(_CONFIGFILE, &gwayConfig );					// Save configuration to file
 	}
 	}
 #endif
 #endif
 
 
@@ -406,7 +419,7 @@ static void setVariables(const char *cmd, const char *arg)
 // --------------------------------------------------------------------------------
 // --------------------------------------------------------------------------------
 static void openWebPage()
 static void openWebPage()
 {
 {
-	++gwayConfig.views;									// increment number of views
+	++gwayConfig.views;											// increment number of views
 	String response="";	
 	String response="";	
 
 
 	server.sendHeader("Cache-Control", "no-cache, no-store, must-revalidate");
 	server.sendHeader("Cache-Control", "no-cache, no-store, must-revalidate");
@@ -486,7 +499,7 @@ static void gatewaySettings()
 	response +="<tr>";
 	response +="<tr>";
 	response +="<th class=\"thead\">Setting</th>";
 	response +="<th class=\"thead\">Setting</th>";
 	response +="<th colspan=\"2\" style=\"background-color: green; color: white; width:120px;\">Value</th>";
 	response +="<th colspan=\"2\" style=\"background-color: green; color: white; width:120px;\">Value</th>";
-	response +="<th colspan=\"4\" style=\"background-color: green; color: white; width:100px;\">Set</th>";
+	response +="<th colspan=\"2\" style=\"background-color: green; color: white; width:100px;\">Set</th>";
 	response +="</tr>";
 	response +="</tr>";
 	
 	
 	bg = " background-color: ";
 	bg = " background-color: ";
@@ -649,29 +662,6 @@ static void gatewaySettings()
 	response +="</tr>";
 	response +="</tr>";
 #endif
 #endif
 
 
-	// Time Correction DELAY
-	if (gwayConfig.expert) {
-		response +="<tr><td class=\"cell\">Time Correction (uSec)</td><td class=\"cell\" colspan=\"2\">"; 
-		response += gwayConfig.txDelay; 
-		response +="</td>";
-		response +="<td class=\"cell\"><a href=\"DELAY=-1\"><button>-</button></a></td>";
-		response +="<td class=\"cell\"><a href=\"DELAY=1\"><button>+</button></a></td>";
-		response +="</tr>";
-	}
-
-	// Reset Accesspoint
-#if _WIFIMANAGER==1
-	response +="<tr><td><tr><td>";
-	response +="Click <a href=\"/NEWSSID\">here</a> to reset accesspoint<br>";
-	response +="</td><td></td></tr>";
-#endif //_WIFIMANAGER
-
-#if _UPDFIRMWARE==1
-	// Update Firmware
-	response +="<tr><td class=\"cell\">Update Firmware</td><td colspan=\"2\"></td>";
-	response +="<td class=\"cell\" colspan=\"2\" class=\"cell\"><a href=\"/UPDATE=1\"><button>UPDATE</button></a></td></tr>";
-#endif //_UPDFIRMWARE
-
 	// Format the Filesystem
 	// Format the Filesystem
 	response +="<tr><td class=\"cell\">Format SPIFFS</td>";
 	response +="<tr><td class=\"cell\">Format SPIFFS</td>";
 	response +=String() + "<td class=\"cell\" colspan=\"2\" >"+gwayConfig.formatCntr+"</td>";
 	response +=String() + "<td class=\"cell\" colspan=\"2\" >"+gwayConfig.formatCntr+"</td>";
@@ -899,7 +889,7 @@ static void messageHistory()
 	server.sendContent(response);
 	server.sendContent(response);
 
 
 	// PRINT NODE CONTENT
 	// PRINT NODE CONTENT
-	for (int i=0; i< _MAXSTAT; i++) {										// For every Node in the list
+	for (int i=0; i< gwayConfig.maxStat; i++) {								// For every Node in the list
 		if (statr[i].sf == 0) break;
 		if (statr[i].sf == 0) break;
 		
 		
 		response = "";
 		response = "";
@@ -933,9 +923,9 @@ static void messageHistory()
 				break;
 				break;
 		}
 		}
 		
 		
-#else // _TRUSTED_NODES
+#else //_TRUSTED_NODES
 		printHex(statr[i].node,' ',response);
 		printHex(statr[i].node,' ',response);
-#endif // _TRUSTED_NODES
+#endif //_TRUSTED_NODES
 
 
 		response += "</td>";
 		response += "</td>";
 		
 		
@@ -981,7 +971,7 @@ static void messageHistory()
 // --------------------------------------------------------------------------------
 // --------------------------------------------------------------------------------
 static void nodeHistory() 
 static void nodeHistory() 
 {
 {
-#	if _MAXSEEN >= 1
+#	if _MAXSEEN>=1
 	if (gwayConfig.seen) {
 	if (gwayConfig.seen) {
 		// First draw the headers
 		// First draw the headers
 		String response= "";
 		String response= "";
@@ -1000,7 +990,7 @@ static void nodeHistory()
 		
 		
 		// Now start the contents
 		// Now start the contents
 		
 		
-		for (int i=0; i<_MAXSEEN; i++) {
+		for (int i=0; i<gwayConfig.maxSeen; i++) {
 			if (listSeen[i].idSeen == 0)
 			if (listSeen[i].idSeen == 0)
 			{
 			{
 #				if _MONITOR>=1
 #				if _MONITOR>=1
@@ -1046,7 +1036,7 @@ static void nodeHistory()
 				}	
 				}	
 #			else
 #			else
 				printHex(listSeen[i].idSeen,' ',response);
 				printHex(listSeen[i].idSeen,' ',response);
-#			endif // _TRUSTED_NODES
+#			endif //_TRUSTED_NODES
 			
 			
 			response += "</td>";
 			response += "</td>";
 			
 			
@@ -1087,12 +1077,12 @@ void monitorData()
 		response +="<th class=\"thead\">Monitor Console</th>";
 		response +="<th class=\"thead\">Monitor Console</th>";
 		response +="</tr>";
 		response +="</tr>";
 		
 		
-		for (int i= iMoni-1+_MAXMONITOR; i>=iMoni; i--) {
-			if (monitor[i % _MAXMONITOR].txt == "-") {			// If equal to init value '-'
+		for (int i= iMoni-1+gwayConfig.maxMoni; i>=iMoni; i--) {
+			if (monitor[i % gwayConfig.maxMoni].txt == "-") {	// If equal to init value '-'
 				break;
 				break;
 			}
 			}
 			response +="<tr><td class=\"cell\">" ;
 			response +="<tr><td class=\"cell\">" ;
-			response += String(monitor[i % _MAXMONITOR].txt);
+			response += String(monitor[i % gwayConfig.maxMoni].txt);
 			response += "</td></tr>";
 			response += "</td></tr>";
 		}
 		}
 		
 		
@@ -1168,11 +1158,11 @@ static void systemStatus()
 		response +="<table class=\"config_table\">";
 		response +="<table class=\"config_table\">";
 		response +="<tr>";
 		response +="<tr>";
 		response +="<th class=\"thead\">Parameter</th>";
 		response +="<th class=\"thead\">Parameter</th>";
-		response +="<th class=\"thead\">Value</th>";
-		response +="<th colspan=\"2\" class=\"thead\">Set</th>";
+		response +="<th class=\"thead\" style=\"width:120px;\">Value</th>";
+		response +="<th colspan=\"2\" class=\"thead width:120px;\">Set</th>";
 		response +="</tr>";
 		response +="</tr>";
 	
 	
-		response +="<tr><td style=\"border: 1px solid black; width:120px;\">Gateway ID</td>";
+		response +="<tr><td style=\"border: 1px solid black;\">Gateway ID</td>";
 		response +="<td class=\"cell\">";	
 		response +="<td class=\"cell\">";	
 		if (MAC_array[0]< 0x10) response +='0'; response +=String(MAC_array[0],HEX);	// The MAC array is always returned in lowercase
 		if (MAC_array[0]< 0x10) response +='0'; response +=String(MAC_array[0],HEX);	// The MAC array is always returned in lowercase
 		if (MAC_array[1]< 0x10) response +='0'; response +=String(MAC_array[1],HEX);
 		if (MAC_array[1]< 0x10) response +='0'; response +=String(MAC_array[1],HEX);
@@ -1186,19 +1176,56 @@ static void systemStatus()
 
 
 		response +="<tr><td class=\"cell\">Free heap</td><td class=\"cell\">"; response+=ESP.getFreeHeap(); response+="</tr>";
 		response +="<tr><td class=\"cell\">Free heap</td><td class=\"cell\">"; response+=ESP.getFreeHeap(); response+="</tr>";
 // XXX We Should find an ESP32 alternative
 // XXX We Should find an ESP32 alternative
-#if !defined ESP32_ARCH
-		response +="<tr><td class=\"cell\">ESP speed</td><td class=\"cell\">"; response+=ESP.getCpuFreqMHz(); 
-		response +="<td style=\"border: 1px solid black; width:40px;\"><a href=\"SPEED=80\"><button>80</button></a></td>";
-		response +="<td style=\"border: 1px solid black; width:40px;\"><a href=\"SPEED=160\"><button>160</button></a></td>";
-		response+="</tr>";
-		response +="<tr><td class=\"cell\">ESP Chip ID</td><td class=\"cell\">"; response+=ESP.getChipId(); response+="</tr>";
-#endif
+#		if !defined ESP32_ARCH
+			response +="<tr><td class=\"cell\">ESP speed</td><td class=\"cell\">"; response+=ESP.getCpuFreqMHz(); 
+			response +="<td style=\"border: 1px solid black; width:40px;\"><a href=\"SPEED=80\"><button>80</button></a></td>";
+			response +="<td style=\"border: 1px solid black; width:40px;\"><a href=\"SPEED=160\"><button>160</button></a></td>";
+			response+="</tr>";
+			response +="<tr><td class=\"cell\">ESP Chip ID</td><td class=\"cell\">"; response+=ESP.getChipId(); response+="</tr>";
+#		endif
 		response +="<tr><td class=\"cell\">OLED</td><td class=\"cell\">"; response+=_OLED; response+="</tr>";
 		response +="<tr><td class=\"cell\">OLED</td><td class=\"cell\">"; response+=_OLED; response+="</tr>";
 		
 		
-#if _STATISTICS >= 1
-		response +="<tr><td class=\"cell\">WiFi Setups</td><td class=\"cell\">"; response+=gwayConfig.wifis; response+="</tr>";
-		response +="<tr><td class=\"cell\">WWW Views</td><td class=\"cell\">"; response+=gwayConfig.views; response+="</tr>";
-#endif
+#		if _STATISTICS >= 1
+			response +="<tr><td class=\"cell\">WiFi Setups</td><td class=\"cell\">"; response+=gwayConfig.wifis; response+="</tr>";
+			response +="<tr><td class=\"cell\">WWW Views</td><td class=\"cell\">"; response+=gwayConfig.views; response+="</tr>";
+#		endif
+
+		// Time Correction DELAY
+		response +="<tr><td class=\"cell\">Time Correction (uSec)</td><td class=\"cell\">"; 
+		response += gwayConfig.txDelay; 
+		response +="</td>";
+		response +="<td class=\"cell\"><a href=\"DELAY=-1\"><button>-</button></a></td>";
+		response +="<td class=\"cell\"><a href=\"DELAY=1\"><button>+</button></a></td>";
+		response +="</tr>";
+
+		// Package Statistics List
+		response +="<tr><td class=\"cell\">Package Statistics List</td><td class=\"cell\">"; 
+		response += gwayConfig.maxStat; 
+		response +="</td>";
+		response +="<td class=\"cell\"><a href=\"MAXSTAT=-5\"><button>-</button></a></td>";
+		response +="<td class=\"cell\"><a href=\"MAXSTAT=5\"><button>+</button></a></td>";
+		response +="</tr>";
+
+		// Last Seen Statistics
+		response +="<tr><td class=\"cell\">Last Seen List</td><td class=\"cell\">"; 
+		response += gwayConfig.maxSeen; 
+		response +="</td>";
+		response +="<td class=\"cell\"><a href=\"MAXSEEN-5\"><button>-</button></a></td>";
+		response +="<td class=\"cell\"><a href=\"MAXSEEN+5\"><button>+</button></a></td>";
+		response +="</tr>";
+
+		// Reset Accesspoint
+#		if _WIFIMANAGER==1
+			response +="<tr><td><tr><td>";
+			response +="Click <a href=\"/NEWSSID\">here</a> to reset accesspoint<br>";
+			response +="</td><td></td></tr>";
+#		endif //_WIFIMANAGER
+
+#		if _UPDFIRMWARE==1
+			// Update Firmware
+			response +="<tr><td class=\"cell\">Update Firmware</td><td colspan=\"2\"></td>";
+			response +="<td class=\"cell\" colspan=\"2\" class=\"cell\"><a href=\"/UPDATE=1\"><button>UPDATE</button></a></td></tr>";
+#		endif //_UPDFIRMWARE
 
 
 		response +="</table>";
 		response +="</table>";
 		server.sendContent(response);
 		server.sendContent(response);
@@ -1307,16 +1334,44 @@ static void interruptData()
 void setupWWW() 
 void setupWWW() 
 {
 {
 	server.begin();									// Start the webserver
 	server.begin();									// Start the webserver
+
+	server.on("/", []() {
+		sendWebPage("","");							// Send the webPage string
+		server.sendHeader("Location", String("/"), true);
+		server.send( 302, "text/plain", "");
+	});
 	
 	
-	// -----------------
+	// --------------------------------
+	//     BUTTONS PART
+	// --------------------------------
 	// BUTTONS, define what should happen with the buttons we press on the homepage
 	// BUTTONS, define what should happen with the buttons we press on the homepage
 	
 	
-	server.on("/", []() {
-		sendWebPage("","");							// Send the webPage string
+	// Display Expert mode or Simple mode
+	server.on("/EXPERT", []() {
+		server.sendHeader("Location", String("/"), true);
+		gwayConfig.expert = bool(1 - (int) gwayConfig.expert) ;
+		server.send( 302, "text/plain", "");
+	});
+
+#if _MONITOR>=1
+	// Display Monitor Console or not
+	server.on("/MONITOR", []() {
 		server.sendHeader("Location", String("/"), true);
 		server.sendHeader("Location", String("/"), true);
-		server.send ( 302, "text/plain", "");
+		gwayConfig.monitor = bool(1 - (int) gwayConfig.monitor) ;
+		server.send( 302, "text/plain", "");
+	});
+#endif //_MONITOR
+	
+	// Display the SEEN statistics
+	server.on("/SEEN", []() {
+		server.sendHeader("Location", String("/"), true);
+		gwayConfig.seen = bool(1 - (int) gwayConfig.seen) ;
+		server.send( 302, "text/plain", "");
 	});
 	});
 
 
+	// --------------------------------
+	//     GATEWAY SETTINGS PART
+	// --------------------------------
 	
 	
 	server.on("/HELP", []() {
 	server.on("/HELP", []() {
 		sendWebPage("HELP","");					// Send the webPage string
 		sendWebPage("HELP","");					// Send the webPage string
@@ -1324,6 +1379,47 @@ void setupWWW()
 		server.send( 302, "text/plain", "");
 		server.send( 302, "text/plain", "");
 	});
 	});
 
 
+	// Set CAD function off/on
+	server.on("/CAD=1", []() {
+		gwayConfig.cad=(bool)1;
+		writeGwayCfg(_CONFIGFILE, &gwayConfig );	// Save configuration to file
+		server.sendHeader("Location", String("/"), true);
+		server.send( 302, "text/plain", "");
+	});
+	server.on("/CAD=0", []() {
+		gwayConfig.cad=(bool)0;
+		writeGwayCfg(_CONFIGFILE, &gwayConfig );	// Save configuration to file
+		server.sendHeader("Location", String("/"), true);
+		server.send( 302, "text/plain", "");
+	});
+
+
+	// Set debug parameter
+	server.on("/DEBUG=-1", []() {				// Set debug level 0-2. Note: +3 is same as -1					
+		debug = (debug+3)%4;
+		writeGwayCfg(_CONFIGFILE, &gwayConfig );	// Save configuration to file
+#		if _DUSB>=1 || _MONITOR>=1
+		if ((debug>=1) && (pdebug & P_GUI)) {
+			mPrint("DEBUG -1: config written");
+		}
+#		endif //_DUSB _MONITOR
+		server.sendHeader("Location", String("/"), true);
+		server.send( 302, "text/plain", "");
+	});
+	
+	server.on("/DEBUG=1", []() {
+		debug = (debug+1)%4;
+		writeGwayCfg(_CONFIGFILE, &gwayConfig );	// Save configuration to file
+#		if _MONITOR>=1
+		if (pdebug & P_GUI) {
+			mPrint("DEBUG +1: config written");
+		}
+#		endif //_MONITOR
+		server.sendHeader("Location", String("/"), true);
+		server.send( 302, "text/plain", "");
+	});
+
+
 	// Format the filesystem
 	// Format the filesystem
 	server.on("/FORMAT", []() {
 	server.on("/FORMAT", []() {
 		Serial.print(F("FORMAT ..."));
 		Serial.print(F("FORMAT ..."));
@@ -1331,19 +1427,19 @@ void setupWWW()
 		SPIFFS.format();							// Normally not used. Use only when SPIFFS corrupt
 		SPIFFS.format();							// Normally not used. Use only when SPIFFS corrupt
 		initConfig(&gwayConfig);					// Well known values
 		initConfig(&gwayConfig);					// Well known values
 		gwayConfig.formatCntr++;
 		gwayConfig.formatCntr++;
-		writeConfig(CONFIGFILE, &gwayConfig);
+		writeConfig(_CONFIGFILE, &gwayConfig);
 		writeSeen( _SEENFILE, listSeen);			// Write the last time record  is Seen
 		writeSeen( _SEENFILE, listSeen);			// Write the last time record  is Seen
 #		if _MONITOR>=1
 #		if _MONITOR>=1
-		if ((debug>=1) && (pdebug & P_GUI )) {
+		if ((debug>=1) && (pdebug & P_MAIN )) {
 			mPrint("www:: manual Format DONE");
 			mPrint("www:: manual Format DONE");
 		}
 		}
 #		endif //_MONITOR
 #		endif //_MONITOR
 		server.sendHeader("Location", String("/"), true);
 		server.sendHeader("Location", String("/"), true);
-		server.send ( 302, "text/plain", "");
+		server.send( 302, "text/plain", "");
 	});
 	});
 	
 	
 	
 	
-	// Reset the statistics (th egateway function) but not the system specific things
+	// Reset the statistics (the gateway function) but not the system specific things
 	server.on("/RESET", []() {
 	server.on("/RESET", []() {
 		mPrint("RESET");
 		mPrint("RESET");
 		startTime= now() - 1;					// Reset all timers too (-1 to avoid division by 0)
 		startTime= now() - 1;					// Reset all timers too (-1 to avoid division by 0)
@@ -1372,7 +1468,7 @@ void setupWWW()
 #endif
 #endif
 
 
 #	if _STATISTICS >= 1
 #	if _STATISTICS >= 1
-		for (int i=0; i< _MAXSTAT; i++) { statr[i].sf = 0; }
+		for (int i=0; i< gwayConfig.maxStat; i++) { statr[i].sf = 0; }
 #		if _STATISTICS >= 2
 #		if _STATISTICS >= 2
 			statc.sf7 = 0;
 			statc.sf7 = 0;
 			statc.sf8 = 0;
 			statc.sf8 = 0;
@@ -1382,7 +1478,6 @@ void setupWWW()
 			statc.sf12= 0;
 			statc.sf12= 0;
 		
 		
 			statc.resets= 0;
 			statc.resets= 0;
-			writeGwayCfg(CONFIGFILE, &gwayConfig );
 			
 			
 #			if _STATISTICS >= 3
 #			if _STATISTICS >= 3
 				statc.sf7_0 = 0; statc.sf7_1 = 0; statc.sf7_2 = 0;
 				statc.sf7_0 = 0; statc.sf7_1 = 0; statc.sf7_2 = 0;
@@ -1392,14 +1487,15 @@ void setupWWW()
 				statc.sf11_0= 0; statc.sf11_1= 0; statc.sf11_2= 0;
 				statc.sf11_0= 0; statc.sf11_1= 0; statc.sf11_2= 0;
 				statc.sf12_0= 0; statc.sf12_1= 0; statc.sf12_2= 0;
 				statc.sf12_0= 0; statc.sf12_1= 0; statc.sf12_2= 0;
 #			endif //_STATISTICS==3
 #			endif //_STATISTICS==3
-
+			
 #		endif //_STATISTICS==2
 #		endif //_STATISTICS==2
 #	endif //_STATISTICS==1
 #	endif //_STATISTICS==1
-			
+
+		writeGwayCfg(_CONFIGFILE, &gwayConfig );			
 		initSeen(listSeen);						// Clear all Seen records as well.
 		initSeen(listSeen);						// Clear all Seen records as well.
 		
 		
 		server.sendHeader("Location", String("/"), true);
 		server.sendHeader("Location", String("/"), true);
-		server.send ( 302, "text/plain", "");
+		server.send( 302, "text/plain", "");
 	});
 	});
 
 
 	// Reset the boot counter, and other system specific counters
 	// Reset the boot counter, and other system specific counters
@@ -1415,14 +1511,14 @@ void setupWWW()
 		gwayConfig.boots = 0;					//
 		gwayConfig.boots = 0;					//
 		gwayConfig.reents = 0;					// Re-entrance
 		gwayConfig.reents = 0;					// Re-entrance
 		
 		
-		writeGwayCfg(CONFIGFILE, &gwayConfig );
+		writeGwayCfg(_CONFIGFILE, &gwayConfig );
 #if _MONITOR>=1
 #if _MONITOR>=1
 		if ((debug>=2) && (pdebug & P_GUI)) {
 		if ((debug>=2) && (pdebug & P_GUI)) {
 			mPrint("wwwServer:: BOOT: config written");
 			mPrint("wwwServer:: BOOT: config written");
 		}
 		}
 #endif
 #endif
 		server.sendHeader("Location", String("/"), true);
 		server.sendHeader("Location", String("/"), true);
-		server.send ( 302, "text/plain", "");
+		server.send( 302, "text/plain", "");
 	});
 	});
 
 
 	// Reboot the Gateway
 	// Reboot the Gateway
@@ -1430,7 +1526,7 @@ void setupWWW()
 	server.on("/REBOOT", []() {
 	server.on("/REBOOT", []() {
 		sendWebPage("",""); 					// Send the webPage string
 		sendWebPage("",""); 					// Send the webPage string
 		server.sendHeader("Location", String("/"), true);
 		server.sendHeader("Location", String("/"), true);
-		server.send ( 302, "text/plain", "");
+		server.send( 302, "text/plain", "");
 		ESP.restart();
 		ESP.restart();
 	});
 	});
 
 
@@ -1438,140 +1534,117 @@ void setupWWW()
 	server.on("/NEWSSID", []() {
 	server.on("/NEWSSID", []() {
 		sendWebPage("NEWSSID","");				// Send the webPage string
 		sendWebPage("NEWSSID","");				// Send the webPage string
 		server.sendHeader("Location", String("/"), true);
 		server.sendHeader("Location", String("/"), true);
-		server.send ( 302, "text/plain", "");
+		server.send( 302, "text/plain", "");
 	});
 	});
 
 
-	// Set debug parameter
-	server.on("/DEBUG=-1", []() {				// Set debug level 0-2. Note: +3 is same as -1					
-		debug = (debug+3)%4;
-		writeGwayCfg(CONFIGFILE, &gwayConfig );	// Save configuration to file
-#		if _DUSB>=1 || _MONITOR>=1
-		if ((debug>=1) && (pdebug & P_GUI)) {
-			mPrint("DEBUG -1: config written");
-		}
-#		endif // _DUSB _MONITOR
-		server.sendHeader("Location", String("/"), true);
-		server.send ( 302, "text/plain", "");
-	});
-	
-	server.on("/DEBUG=1", []() {
-		debug = (debug+1)%4;
-		writeGwayCfg(CONFIGFILE, &gwayConfig );	// Save configuration to file
-#		if _DUSB>=1 || _MONITOR>=1
-		if ((debug>=1) && (pdebug & P_GUI)) {
-			mPrint("DEBUG +1: config written");
-		}
-#		endif //_DUSB _MONITOR
-		server.sendHeader("Location", String("/"), true);
-		server.send ( 302, "text/plain", "");
-	});
+
 
 
 	// Set PDEBUG parameter
 	// Set PDEBUG parameter
 	//
 	//
 	server.on("/PDEBUG=SCAN", []() {			// Set debug level 0x01						
 	server.on("/PDEBUG=SCAN", []() {			// Set debug level 0x01						
 		pdebug ^= P_SCAN;
 		pdebug ^= P_SCAN;
-		writeGwayCfg(CONFIGFILE, &gwayConfig );	// Save configuration to file
+		writeGwayCfg(_CONFIGFILE, &gwayConfig );	// Save configuration to file
 		server.sendHeader("Location", String("/"), true);
 		server.sendHeader("Location", String("/"), true);
-		server.send ( 302, "text/plain", "");
+		server.send( 302, "text/plain", "");
 	});
 	});
 	server.on("/PDEBUG=CAD", []() {				// Set debug level 0x02						
 	server.on("/PDEBUG=CAD", []() {				// Set debug level 0x02						
 		pdebug ^= P_CAD;
 		pdebug ^= P_CAD;
-		writeGwayCfg(CONFIGFILE, &gwayConfig );	// Save configuration to file
+		writeGwayCfg(_CONFIGFILE, &gwayConfig );	// Save configuration to file
 		server.sendHeader("Location", String("/"), true);
 		server.sendHeader("Location", String("/"), true);
-		server.send ( 302, "text/plain", "");
+		server.send( 302, "text/plain", "");
 	});
 	});
 	server.on("/PDEBUG=RX", []() {				// Set debug level 0x04						
 	server.on("/PDEBUG=RX", []() {				// Set debug level 0x04						
 		pdebug ^= P_RX;
 		pdebug ^= P_RX;
-		writeGwayCfg(CONFIGFILE, &gwayConfig );	// Save configuration to file
+		writeGwayCfg(_CONFIGFILE, &gwayConfig );	// Save configuration to file
 		server.sendHeader("Location", String("/"), true);
 		server.sendHeader("Location", String("/"), true);
-		server.send ( 302, "text/plain", "");
+		server.send( 302, "text/plain", "");
 	});
 	});
 	server.on("/PDEBUG=TX", []() {				// Set debug level 0x08						
 	server.on("/PDEBUG=TX", []() {				// Set debug level 0x08						
 		pdebug ^= P_TX;
 		pdebug ^= P_TX;
-		writeGwayCfg(CONFIGFILE, &gwayConfig );	// Save configuration to file
+		writeGwayCfg(_CONFIGFILE, &gwayConfig );	// Save configuration to file
 		server.sendHeader("Location", String("/"), true);
 		server.sendHeader("Location", String("/"), true);
-		server.send ( 302, "text/plain", "");
+		server.send( 302, "text/plain", "");
 	});
 	});
 	server.on("/PDEBUG=PRE", []() {				// Set debug level 0-2						
 	server.on("/PDEBUG=PRE", []() {				// Set debug level 0-2						
 		pdebug ^= P_PRE;
 		pdebug ^= P_PRE;
-		writeGwayCfg(CONFIGFILE, &gwayConfig );	// Save configuration to file
+		writeGwayCfg(_CONFIGFILE, &gwayConfig );	// Save configuration to file
 		server.sendHeader("Location", String("/"), true);
 		server.sendHeader("Location", String("/"), true);
-		server.send ( 302, "text/plain", "");
+		server.send( 302, "text/plain", "");
 	});
 	});
 	server.on("/PDEBUG=MAIN", []() {				// Set debug level 0-2						
 	server.on("/PDEBUG=MAIN", []() {				// Set debug level 0-2						
 		pdebug ^= P_MAIN;
 		pdebug ^= P_MAIN;
-		writeGwayCfg(CONFIGFILE, &gwayConfig );	// Save configuration to file
+		writeGwayCfg(_CONFIGFILE, &gwayConfig );	// Save configuration to file
 		server.sendHeader("Location", String("/"), true);
 		server.sendHeader("Location", String("/"), true);
-		server.send ( 302, "text/plain", "");
+		server.send( 302, "text/plain", "");
 	});
 	});
 	server.on("/PDEBUG=GUI", []() {				// Set debug level 0-2						
 	server.on("/PDEBUG=GUI", []() {				// Set debug level 0-2						
 		pdebug ^= P_GUI;
 		pdebug ^= P_GUI;
-		writeGwayCfg(CONFIGFILE, &gwayConfig );	// Save configuration to file
+		writeGwayCfg(_CONFIGFILE, &gwayConfig );	// Save configuration to file
 		server.sendHeader("Location", String("/"), true);
 		server.sendHeader("Location", String("/"), true);
-		server.send ( 302, "text/plain", "");
+		server.send( 302, "text/plain", "");
 	});
 	});
 	server.on("/PDEBUG=RADIO", []() {			// Set debug level 0-2						
 	server.on("/PDEBUG=RADIO", []() {			// Set debug level 0-2						
 		pdebug ^= P_RADIO;
 		pdebug ^= P_RADIO;
-		writeGwayCfg(CONFIGFILE, &gwayConfig );	// Save configuration to file
+		writeGwayCfg(_CONFIGFILE, &gwayConfig );	// Save configuration to file
 		server.sendHeader("Location", String("/"), true);
 		server.sendHeader("Location", String("/"), true);
-		server.send ( 302, "text/plain", "");
+		server.send( 302, "text/plain", "");
 	});
 	});
 
 
 	
 	
 	// Set delay in microseconds
 	// Set delay in microseconds
 	server.on("/DELAY=1", []() {
 	server.on("/DELAY=1", []() {
 		gwayConfig.txDelay+=5000;
 		gwayConfig.txDelay+=5000;
-		writeGwayCfg(CONFIGFILE, &gwayConfig );	// Save configuration to file
+		writeGwayCfg(_CONFIGFILE, &gwayConfig );	// Save configuration to file
 #		if _MONITOR>=1
 #		if _MONITOR>=1
 		if ((debug>=1) && (pdebug & P_GUI)) {
 		if ((debug>=1) && (pdebug & P_GUI)) {
 			mPrint("DELAY +, config written");
 			mPrint("DELAY +, config written");
 		}
 		}
 #		endif //_MONITOR
 #		endif //_MONITOR
 		server.sendHeader("Location", String("/"), true);
 		server.sendHeader("Location", String("/"), true);
-		server.send ( 302, "text/plain", "");
+		server.send( 302, "text/plain", "");
 	});
 	});
 	server.on("/DELAY=-1", []() {
 	server.on("/DELAY=-1", []() {
 		gwayConfig.txDelay-=5000;
 		gwayConfig.txDelay-=5000;
-		writeGwayCfg(CONFIGFILE, &gwayConfig );	// Save configuration to file
+		writeGwayCfg(_CONFIGFILE, &gwayConfig );	// Save configuration to file
 #		if _MONITOR>=1
 #		if _MONITOR>=1
 		if ((debug>=1) && (pdebug & P_GUI)) {
 		if ((debug>=1) && (pdebug & P_GUI)) {
 			mPrint("DELAY -, config written");
 			mPrint("DELAY -, config written");
 		}
 		}
 #		endif //_MONITOR
 #		endif //_MONITOR
 		server.sendHeader("Location", String("/"), true);
 		server.sendHeader("Location", String("/"), true);
-		server.send ( 302, "text/plain", "");
+		server.send( 302, "text/plain", "");
 	});
 	});
 
 
 	// Set Trusted Node Parameter
 	// Set Trusted Node Parameter
 	server.on("/TRUSTED=1", []() {
 	server.on("/TRUSTED=1", []() {
 	gwayConfig.trusted = (gwayConfig.trusted +1)%4;
 	gwayConfig.trusted = (gwayConfig.trusted +1)%4;
-		writeGwayCfg(CONFIGFILE, &gwayConfig );	// Save configuration to file
+		writeGwayCfg(_CONFIGFILE, &gwayConfig );	// Save configuration to file
 #		if _MONITOR>=1
 #		if _MONITOR>=1
 			mPrint("TRUSTED +, config written");
 			mPrint("TRUSTED +, config written");
 #		endif //_MONITOR
 #		endif //_MONITOR
 		server.sendHeader("Location", String("/"), true);
 		server.sendHeader("Location", String("/"), true);
-		server.send ( 302, "text/plain", "");
+		server.send( 302, "text/plain", "");
 	});
 	});
 	server.on("/TRUSTED=-1", []() {
 	server.on("/TRUSTED=-1", []() {
 		gwayConfig.trusted = (gwayConfig.trusted -1)%4;
 		gwayConfig.trusted = (gwayConfig.trusted -1)%4;
-		writeGwayCfg(CONFIGFILE, &gwayConfig );	// Save configuration to file
+		writeGwayCfg(_CONFIGFILE, &gwayConfig );	// Save configuration to file
 #		if _MONITOR>=1
 #		if _MONITOR>=1
 			mPrint("TRUSTED -, config written");
 			mPrint("TRUSTED -, config written");
 #		endif //_MONITOR
 #		endif //_MONITOR
 		server.sendHeader("Location", String("/"), true);
 		server.sendHeader("Location", String("/"), true);
-		server.send ( 302, "text/plain", "");
+		server.send( 302, "text/plain", "");
 	});
 	});
 
 
 	// Spreading Factor setting
 	// Spreading Factor setting
 	server.on("/SF=1", []() {
 	server.on("/SF=1", []() {
 		if (sf>=SF12) sf=SF7; else sf= (sf_t)((int)sf+1);
 		if (sf>=SF12) sf=SF7; else sf= (sf_t)((int)sf+1);
 		server.sendHeader("Location", String("/"), true);
 		server.sendHeader("Location", String("/"), true);
-		server.send ( 302, "text/plain", "");
+		server.send( 302, "text/plain", "");
 	});
 	});
 	server.on("/SF=-1", []() {
 	server.on("/SF=-1", []() {
 		if (sf<=SF7) sf=SF12; else sf= (sf_t)((int)sf-1);
 		if (sf<=SF7) sf=SF12; else sf= (sf_t)((int)sf-1);
 		server.sendHeader("Location", String("/"), true);
 		server.sendHeader("Location", String("/"), true);
-		server.send ( 302, "text/plain", "");
+		server.send( 302, "text/plain", "");
 	});
 	});
 
 
 	// Set Frequency of the GateWay node
 	// Set Frequency of the GateWay node
@@ -1584,45 +1657,32 @@ void setupWWW()
 #endif
 #endif
 		if (gwayConfig.ch==(nf-1)) gwayConfig.ch=0; else gwayConfig.ch++;
 		if (gwayConfig.ch==(nf-1)) gwayConfig.ch=0; else gwayConfig.ch++;
 		server.sendHeader("Location", String("/"), true);
 		server.sendHeader("Location", String("/"), true);
-		server.send ( 302, "text/plain", "");
+		server.send( 302, "text/plain", "");
 	});
 	});
 	server.on("/FREQ=-1", []() {
 	server.on("/FREQ=-1", []() {
 		uint8_t nf = sizeof(freqs)/sizeof(freqs[0]);	// Number of elements in array
 		uint8_t nf = sizeof(freqs)/sizeof(freqs[0]);	// Number of elements in array
 		if (gwayConfig.ch==0) gwayConfig.ch=(nf-1); else gwayConfig.ch--;
 		if (gwayConfig.ch==0) gwayConfig.ch=(nf-1); else gwayConfig.ch--;
 		server.sendHeader("Location", String("/"), true);
 		server.sendHeader("Location", String("/"), true);
-		server.send ( 302, "text/plain", "");
+		server.send( 302, "text/plain", "");
 	});
 	});
 
 
-	// Set CAD function off/on
-	server.on("/CAD=1", []() {
-		gwayConfig.cad=(bool)1;
-		writeGwayCfg(CONFIGFILE, &gwayConfig );	// Save configuration to file
-		server.sendHeader("Location", String("/"), true);
-		server.send ( 302, "text/plain", "");
-	});
-	server.on("/CAD=0", []() {
-		gwayConfig.cad=(bool)0;
-		writeGwayCfg(CONFIGFILE, &gwayConfig );	// Save configuration to file
-		server.sendHeader("Location", String("/"), true);
-		server.send ( 302, "text/plain", "");
-	});
 
 
 	// GatewayNode
 	// GatewayNode
 	server.on("/NODE=1", []() {
 	server.on("/NODE=1", []() {
 #if _GATEWAYNODE==1
 #if _GATEWAYNODE==1
 		gwayConfig.isNode =(bool)1;
 		gwayConfig.isNode =(bool)1;
-		writeGwayCfg(CONFIGFILE, &gwayConfig );	// Save configuration to file
+		writeGwayCfg(_CONFIGFILE, &gwayConfig );	// Save configuration to file
 #endif //_GATEWAYNODE
 #endif //_GATEWAYNODE
 		server.sendHeader("Location", String("/"), true);
 		server.sendHeader("Location", String("/"), true);
-		server.send ( 302, "text/plain", "");
+		server.send( 302, "text/plain", "");
 	});
 	});
 	server.on("/NODE=0", []() {
 	server.on("/NODE=0", []() {
 #if _GATEWAYNODE==1
 #if _GATEWAYNODE==1
 		gwayConfig.isNode =(bool)0;
 		gwayConfig.isNode =(bool)0;
-		writeGwayCfg(CONFIGFILE, &gwayConfig );	// Save configuration to file
+		writeGwayCfg(_CONFIGFILE, &gwayConfig );	// Save configuration to file
 #endif //_GATEWAYNODE
 #endif //_GATEWAYNODE
 		server.sendHeader("Location", String("/"), true);
 		server.sendHeader("Location", String("/"), true);
-		server.send ( 302, "text/plain", "");
+		server.send( 302, "text/plain", "");
 	});
 	});
 
 
 #if _GATEWAYNODE==1	
 #if _GATEWAYNODE==1	
@@ -1631,11 +1691,11 @@ void setupWWW()
 
 
 		frameCount=0; 
 		frameCount=0; 
 		rxLoraModem();							// Reset the radio with the new frequency
 		rxLoraModem();							// Reset the radio with the new frequency
-		writeGwayCfg(CONFIGFILE, &gwayConfig );
+		writeGwayCfg(_CONFIGFILE, &gwayConfig );
 
 
 		//sendWebPage("","");						// Send the webPage string
 		//sendWebPage("","");						// Send the webPage string
 		server.sendHeader("Location", String("/"), true);
 		server.sendHeader("Location", String("/"), true);
-		server.send ( 302, "text/plain", "");
+		server.send( 302, "text/plain", "");
 	});
 	});
 #endif
 #endif
 
 
@@ -1643,46 +1703,46 @@ void setupWWW()
 	server.on("/REFR=1", []() {					// WWW page auto refresh ON
 	server.on("/REFR=1", []() {					// WWW page auto refresh ON
 #if _REFRESH==1
 #if _REFRESH==1
 		gwayConfig.refresh =1;
 		gwayConfig.refresh =1;
-		writeGwayCfg(CONFIGFILE, &gwayConfig );	// Save configuration to file
+		writeGwayCfg(_CONFIGFILE, &gwayConfig );	// Save configuration to file
 #endif		
 #endif		
 		server.sendHeader("Location", String("/"), true);
 		server.sendHeader("Location", String("/"), true);
-		server.send ( 302, "text/plain", "");
+		server.send( 302, "text/plain", "");
 	});
 	});
 	server.on("/REFR=0", []() {					// WWW page auto refresh OFF
 	server.on("/REFR=0", []() {					// WWW page auto refresh OFF
 #if _REFRESH==1
 #if _REFRESH==1
 		gwayConfig.refresh =0;
 		gwayConfig.refresh =0;
-		writeGwayCfg(CONFIGFILE, &gwayConfig );	// Save configuration to file
+		writeGwayCfg(_CONFIGFILE, &gwayConfig );	// Save configuration to file
 #endif
 #endif
 		server.sendHeader("Location", String("/"), true);
 		server.sendHeader("Location", String("/"), true);
-		server.send ( 302, "text/plain", "");
+		server.send( 302, "text/plain", "");
 	});
 	});
 
 
 	// WWW Page serial print function
 	// WWW Page serial print function
 	server.on("/DUSB=1", []() {					// WWW page Serial Print ON
 	server.on("/DUSB=1", []() {					// WWW page Serial Print ON
 		gwayConfig.dusbStat =1;
 		gwayConfig.dusbStat =1;
-		writeGwayCfg(CONFIGFILE, &gwayConfig );	// Save configuration to file
+		writeGwayCfg(_CONFIGFILE, &gwayConfig );	// Save configuration to file
 		server.sendHeader("Location", String("/"), true);
 		server.sendHeader("Location", String("/"), true);
-		server.send ( 302, "text/plain", "");
+		server.send( 302, "text/plain", "");
 	});
 	});
 	server.on("/DUSB=0", []() {					// WWW page Serial Print OFF
 	server.on("/DUSB=0", []() {					// WWW page Serial Print OFF
 		gwayConfig.dusbStat =0;
 		gwayConfig.dusbStat =0;
-		writeGwayCfg(CONFIGFILE, &gwayConfig );	// Save configuration to file
+		writeGwayCfg(_CONFIGFILE, &gwayConfig );	// Save configuration to file
 		server.sendHeader("Location", String("/"), true);
 		server.sendHeader("Location", String("/"), true);
-		server.send ( 302, "text/plain", "");
+		server.send( 302, "text/plain", "");
 	});
 	});
 	
 	
 	// Switch off/on the HOP functions
 	// Switch off/on the HOP functions
 	server.on("/HOP=1", []() {
 	server.on("/HOP=1", []() {
 		gwayConfig.hop=true;
 		gwayConfig.hop=true;
 		server.sendHeader("Location", String("/"), true);
 		server.sendHeader("Location", String("/"), true);
-		server.send ( 302, "text/plain", "");
+		server.send( 302, "text/plain", "");
 	});
 	});
 	server.on("/HOP=0", []() {
 	server.on("/HOP=0", []() {
 		gwayConfig.hop=false;
 		gwayConfig.hop=false;
 		setFreq(freqs[gwayConfig.ch].upFreq);
 		setFreq(freqs[gwayConfig.ch].upFreq);
 		rxLoraModem();
 		rxLoraModem();
 		server.sendHeader("Location", String("/"), true);
 		server.sendHeader("Location", String("/"), true);
-		server.send ( 302, "text/plain", "");
+		server.send( 302, "text/plain", "");
 	});
 	});
 
 
 #if !defined ESP32_ARCH
 #if !defined ESP32_ARCH
@@ -1690,12 +1750,12 @@ void setupWWW()
 	server.on("/SPEED=80", []() {
 	server.on("/SPEED=80", []() {
 		system_update_cpu_freq(80);
 		system_update_cpu_freq(80);
 		server.sendHeader("Location", String("/"), true);
 		server.sendHeader("Location", String("/"), true);
-		server.send ( 302, "text/plain", "");
+		server.send( 302, "text/plain", "");
 	});
 	});
 	server.on("/SPEED=160", []() {
 	server.on("/SPEED=160", []() {
 		system_update_cpu_freq(160);
 		system_update_cpu_freq(160);
 		server.sendHeader("Location", String("/"), true);
 		server.sendHeader("Location", String("/"), true);
-		server.send ( 302, "text/plain", "");
+		server.send( 302, "text/plain", "");
 	});
 	});
 #endif
 #endif
 	// Display Documentation pages
 	// Display Documentation pages
@@ -1703,7 +1763,7 @@ void setupWWW()
 
 
 		server.sendHeader("Location", String("/"), true);
 		server.sendHeader("Location", String("/"), true);
 		buttonDocu();
 		buttonDocu();
-		server.send ( 302, "text/plain", "");
+		server.send( 302, "text/plain", "");
 	});
 	});
 
 
 	// Display LOGging information
 	// Display LOGging information
@@ -1713,40 +1773,76 @@ void setupWWW()
 		mPrint("LOG button");
 		mPrint("LOG button");
 #endif //_MONITOR
 #endif //_MONITOR
 		buttonLog();
 		buttonLog();
-		server.send ( 302, "text/plain", "");
+		server.send( 302, "text/plain", "");
 	});
 	});
-	
-	// Display Expert mode or Simple mode
-	server.on("/EXPERT", []() {
+
+
+	// Update the sketch. Not yet implemented
+	server.on("/UPDATE=1", []() {
+		// Future work
 		server.sendHeader("Location", String("/"), true);
 		server.sendHeader("Location", String("/"), true);
-		gwayConfig.expert = bool(1 - (int) gwayConfig.expert) ;
-		server.send ( 302, "text/plain", "");
+		server.send( 302, "text/plain", "");
 	});
 	});
 
 
-#if _MONITOR>=1
-	// Display Monitor Console or not
-	server.on("/MONITOR", []() {
+
+	// ----------------------------
+	//    SYSTEM STATUS PART    
+	// ---------------------------- 
+	server.on("/MAXSTAT=-5", []() {
+		if (gwayConfig.maxStat>5) {
+			struct stat_t * oldStat = statr;
+			gwayConfig.maxStat-=5;
+			statr = (struct stat_t *) malloc(gwayConfig.maxStat * sizeof(struct stat_t));
+			for (int i=0; i<gwayConfig.maxStat; i+=1) {
+				statr[i]=oldStat[i];
+			}
+			free(oldStat);
+		}
 		server.sendHeader("Location", String("/"), true);
 		server.sendHeader("Location", String("/"), true);
-		gwayConfig.monitor = bool(1 - (int) gwayConfig.monitor) ;
-		server.send ( 302, "text/plain", "");
+		server.send( 302, "text/plain", "");
 	});
 	});
-#endif //_MONITOR
-	
-	// Display the SEEN statistics
-	server.on("/SEEN", []() {
+	server.on("/MAXSTAT=5", []() {
+		struct stat_t * oldStat = statr;
+		gwayConfig.maxStat+=5;
+		statr = (struct stat_t *) malloc(gwayConfig.maxStat * sizeof(struct stat_t));
+		for (int i=0; i<gwayConfig.maxStat; i+=1) {
+			if (i<(gwayConfig.maxStat-5)) {
+				statr[i]=oldStat[i];
+			}
+			else {
+				statr[i].sf=0;
+			}
+		}
+		free(oldStat);
 		server.sendHeader("Location", String("/"), true);
 		server.sendHeader("Location", String("/"), true);
-		gwayConfig.seen = bool(1 - (int) gwayConfig.seen) ;
-		server.send ( 302, "text/plain", "");
+		server.send( 302, "text/plain", "");
 	});
 	});
 
 
-	
-	// Update the sketch. Not yet implemented
-	server.on("/UPDATE=1", []() {
-#if _OTA==1
-		updateOtaa();
-#endif
+	server.on("/MAXSEEN-5", []() {
+		if (gwayConfig.maxSeen>5) {
+			struct nodeSeen * oldSeen = listSeen;
+			gwayConfig.maxSeen-=5;
+			listSeen = (struct nodeSeen *) malloc(gwayConfig.maxSeen * sizeof(struct nodeSeen));
+			for (int i=0; i<gwayConfig.maxSeen; i+=1) {
+				listSeen[i]=oldSeen[i];
+			}
+			if (gwayConfig.maxSeen<iSeen) iSeen = gwayConfig.maxSeen;			
+			free(oldSeen);
+		}
 		server.sendHeader("Location", String("/"), true);
 		server.sendHeader("Location", String("/"), true);
-		server.send ( 302, "text/plain", "");
+		server.send( 302, "text/plain", "");
+	});
+	server.on("/MAXSEEN+5", []() {
+		struct nodeSeen * oldSeen = listSeen;
+		gwayConfig.maxSeen+=5;
+		listSeen = (struct nodeSeen *) malloc(gwayConfig.maxSeen * sizeof(struct nodeSeen));
+		for (int i=0; i<gwayConfig.maxSeen; i+=1) {
+			if (i<(gwayConfig.maxSeen-5)) listSeen[i]=oldSeen[i];
+			else listSeen[i].idSeen=0;
+		}
+		free(oldSeen);
+		server.sendHeader("Location", String("/"), true);
+		server.send( 302, "text/plain", "");
 	});
 	});
 
 
 	// -----------
 	// -----------
@@ -1757,7 +1853,7 @@ void setupWWW()
 	// package interrupt arrives at the gateway
 	// package interrupt arrives at the gateway
 #	if _MONITOR>=1
 #	if _MONITOR>=1
 		mPrint("WWW Server started on port " + String(_SERVERPORT) );
 		mPrint("WWW Server started on port " + String(_SERVERPORT) );
-#	endif // _MONITOR
+#	endif //_MONITOR
 
 
 	return;
 	return;
 } // setupWWW
 } // setupWWW
@@ -1811,5 +1907,5 @@ static void websiteFooter()
 }
 }
 
 
 
 
-#endif // _SERVER==1
+#endif //_SERVER==1
 
 

+ 59 - 47
src/configGway.h

@@ -1,7 +1,8 @@
 // 1-channel LoRa Gateway for ESP32 and ESP8266
 // 1-channel LoRa Gateway for ESP32 and ESP8266
 // Copyright (c) Maarten Westenberg 2016-2020 
 // Copyright (c) Maarten Westenberg 2016-2020 
 
 
-#define VERSION "V.6.2.4.EU868; PlatformIO 200428n"
+#define VERSION "V.6.2.5.EU868; PlatformIO 200524i"
+
 //
 //
 // Based on work done by Thomas Telkamp for Raspberry PI 1ch gateway and many others.
 // Based on work done by Thomas Telkamp for Raspberry PI 1ch gateway and many others.
 //
 //
@@ -61,7 +62,7 @@
 // the special screen at the GUI.
 // the special screen at the GUI.
 // If _DUSB is also set to 1 then most messages will also be copied to USB devices.
 // If _DUSB is also set to 1 then most messages will also be copied to USB devices.
 #if !defined _MONITOR
 #if !defined _MONITOR
-#define _MONITOR 1
+#	define _MONITOR 1
 #endif
 #endif
 
 
 
 
@@ -70,8 +71,9 @@
 // 1= Keep track of messages statistics, number determined by _MAXSTAT
 // 1= Keep track of messages statistics, number determined by _MAXSTAT
 // 2= Option 1 + Keep track of messages received PER each SF (default)
 // 2= Option 1 + Keep track of messages received PER each SF (default)
 // 3= See Option 2, but with extra channel info (Not used when Hopping is not selected)
 // 3= See Option 2, but with extra channel info (Not used when Hopping is not selected)
-#define _STATISTICS 3
-
+#if !defined _STATISTICS
+#	define _STATISTICS 3
+#endif
 
 
 // Define the frequency band the gateway will listen on. Valid options are
 // Define the frequency band the gateway will listen on. Valid options are
 // EU863_870	Europe 
 // EU863_870	Europe 
@@ -128,13 +130,14 @@
 // Note: DIO3 must be connected for this to work (Heltec and later Wemos gateways). 
 // Note: DIO3 must be connected for this to work (Heltec and later Wemos gateways). 
 #define _CRCCHECK 1
 #define _CRCCHECK 1
 
 
+
 // Definitions for the admin webserver.
 // Definitions for the admin webserver.
 // _SERVER determines whether or not the admin webpage is included in the sketch.
 // _SERVER determines whether or not the admin webpage is included in the sketch.
 // Normally, leave it in!
 // Normally, leave it in!
 #define _SERVER 1				// Define local WebServer only if this define is set
 #define _SERVER 1				// Define local WebServer only if this define is set
 #define _REFRESH 1				// Allow the webserver refresh or not?
 #define _REFRESH 1				// Allow the webserver refresh or not?
 #define _SERVERPORT 80			// Local webserver port (normally 80)
 #define _SERVERPORT 80			// Local webserver port (normally 80)
-#define _MAXBUFSIZE 192		// Must be larger than 128, but small enough to work
+#define _MAXBUFSIZE 192			// Must be larger than 128, but small enough to work
 
 
 
 
 // Definitions for over the air updates. At the moment we support OTA with IDE
 // Definitions for over the air updates. At the moment we support OTA with IDE
@@ -142,7 +145,9 @@
 // Bonjour is included in iTunes (which is free) and OTA is recommended to install 
 // Bonjour is included in iTunes (which is free) and OTA is recommended to install 
 // the firmware on your router witout having to be really close to the gateway and 
 // the firmware on your router witout having to be really close to the gateway and 
 // connect with USB.
 // connect with USB.
-#define _OTA 1
+#if !defined _OTA
+#	define _OTA 1
+#endif
 
 
 
 
 // We support a few pin-out configurations out-of-the-box: HALLARD, COMPRESULT and 
 // We support a few pin-out configurations out-of-the-box: HALLARD, COMPRESULT and 
@@ -172,7 +177,8 @@
 // NOTE: In all other cases, value 0 works for most gateways with CAD enabled
 // NOTE: In all other cases, value 0 works for most gateways with CAD enabled
 #if !defined _STRICT_1CH
 #if !defined _STRICT_1CH
 #	define _STRICT_1CH 1
 #	define _STRICT_1CH 1
-#endif //_STRICT_1CH
+#endif
+
 
 
 //
 //
 // Also, normally the server will respond with SF12 in the RX2 timeslot.
 // Also, normally the server will respond with SF12 in the RX2 timeslot.
@@ -189,12 +195,9 @@
 // This section defines whether we use the gateway as a repeater
 // This section defines whether we use the gateway as a repeater
 // For his, we use another output channel as the channel (default==0) we are 
 // For his, we use another output channel as the channel (default==0) we are 
 // receiving the messages on.
 // receiving the messages on.
-#define _REPEATER 0
-
-
-// Will we use Mutex or not?
-// +SPI is input for SPI, SPO is output for SPI
-#define _MUTEX 0
+#if !defined _REPEATER
+#	define _REPEATER 0
+#endif
 
 
 
 
 // Define if Oled Display is connected to I2C bus. Note that defining an Oled display does not
 // Define if Oled Display is connected to I2C bus. Note that defining an Oled display does not
@@ -220,42 +223,32 @@
 #define _GATEWAYMGT 0
 #define _GATEWAYMGT 0
 
 
 
 
-// Do extensive logging to file
+// Do extensive logging to file(s)
 // Use the ESP8266 SPIFS filesystem to do extensive logging.
 // Use the ESP8266 SPIFS filesystem to do extensive logging.
 // We must take care that the filesystem never(!) is full, and for that purpose we
 // We must take care that the filesystem never(!) is full, and for that purpose we
 // rather have new records/line of statistics than very old.
 // rather have new records/line of statistics than very old.
 // Of course we must store enough records to make the filesystem work
 // Of course we must store enough records to make the filesystem work
+// NOTE:
+// Please do NOT USE file logging if you are concerned about downstream timing.
+//	The status logging taken about 6 ms (6000 uSec) for each write whereas
+//	normally this is less than 100 uSecs.
 #if !defined _STAT_LOG
 #if !defined _STAT_LOG
 #	define _STAT_LOG 0
 #	define _STAT_LOG 0
-#endif //_STAT_LOG
+#endif
 
 
 
 
 // Set the Server Settings (IMPORTANT)
 // Set the Server Settings (IMPORTANT)
 #define _LOCUDPPORT 1700					// UDP port of gateway! Often 1700 or 1701 is used for upstream comms
 #define _LOCUDPPORT 1700					// UDP port of gateway! Often 1700 or 1701 is used for upstream comms
 
 
-// Timing
-#define _PULL_INTERVAL 20					// PULL_DATA messages to server to get downstream in seconds
-#define _STAT_INTERVAL 120					// Send a 'stat' message to server
-#define _NTP_INTERVAL 3600					// How often do we want time NTP synchronization
-#define _WWW_INTERVAL 60					// Number of seconds before we refresh the WWW page
-#define _FILE_INTERVAL 30					// Number of timer (in secs) before writing to files
-#define _MSG_INTERVAL 31					// Message timeout timer in seconds
-#define _RST_INTERVAL 90					// Reset interval in seconds, total chip reset
+
 
 
 // This defines whether or not we would use the gateway as 
 // This defines whether or not we would use the gateway as 
-// as sort of backend decoding system for local sensors which decodes
+// as sort of backend decoding system for local sensors which decodes (such as TTGO T-Beam)
 // 1: _LOCALSERVER is used
 // 1: _LOCALSERVER is used
 // 0: Do not use _LOCALSERVER 
 // 0: Do not use _LOCALSERVER 
-#define _LOCALSERVER 1						// See server definitions for decodes
-
-
-// Gateway Ident definitions. Where is the gateway located?
-#define _DESCRIPTION "ESP Gateway"			// Name of the gateway
-#define _EMAIL "mw12554@hotmail.com"		// Owner
-#define _PLATFORM "ESP8266"
-#define _LAT 52.237367
-#define _LON 5.978654
-#define _ALT 14								// Altitude
+#if !defined _LOCALSERVER
+#	define _LOCALSERVER 0					// See server definitions for decodes
+#endif
 
 
 
 
 // ntp
 // ntp
@@ -276,11 +269,11 @@
 // NOTE: The node is switched off by default. Switch it on in the GUI
 // NOTE: The node is switched off by default. Switch it on in the GUI
 #if !defined _GATEWAYNODE
 #if !defined _GATEWAYNODE
 #	define _GATEWAYNODE 0
 #	define _GATEWAYNODE 0
-#endif //_GATEWAYNODE
+#endif
 
 
 
 
 // We can put the gateway in such a mode that it will (only) recognize
 // We can put the gateway in such a mode that it will (only) recognize
-// nodes that are put in a list of trusted nodes 
+// nodes that are put in a list of trusted nodes.
 // Values:
 // Values:
 // 0: Do not use names for trusted Nodes
 // 0: Do not use names for trusted Nodes
 // 1: Use the nodes as a translation table for hex codes to names (in TLN)
 // 1: Use the nodes as a translation table for hex codes to names (in TLN)
@@ -290,20 +283,24 @@
 #define _TRUSTED_DECODE 1
 #define _TRUSTED_DECODE 1
 
 
 
 
-
 // ========================================================================
 // ========================================================================
 // DO NOT CHANGE BELOW THIS LINE
 // DO NOT CHANGE BELOW THIS LINE
 // Probably do not change items below this line, only if lists or 
 // Probably do not change items below this line, only if lists or 
 // configurations on configNode.h are not large enough for example.
 // configurations on configNode.h are not large enough for example.
 // ========================================================================
 // ========================================================================
 
 
-// Maximum number of Message History statistics records gathered. 20 is a good maximum 
-// (memory intensive). For ESP32 maybe 30 could be used as well
-#define _MAXSTAT 20
+
+// Name of he configfile in SPIFFs	filesystem
+// In this file we store the configuration and other relevant info that should
+// survive a reboot of the gateway		
+#define _CONFIGFILE "/gwayConfig.txt"
 
 
 
 
-// Define the maximum amount of itemas we monitor on the screen
-#define _MAXMONITOR 20
+// Maximum number of Message History statistics records gathered. 20 is a good maximum 
+// (memory intensive). For ESP32 maybe 30 could be used as well
+#if !defined _MAXSTAT
+#	define _MAXSTAT 20
+#endif
 
 
 
 
 // We will log a list of LoRa nodes that was forwarded using this gateway.
 // We will log a list of LoRa nodes that was forwarded using this gateway.
@@ -316,13 +313,23 @@
 #if !defined _MAXSEEN
 #if !defined _MAXSEEN
 #	define _MAXSEEN 20
 #	define _MAXSEEN 20
 #endif
 #endif
-#define _SEENFILE "/gwayNum.txt"
+#define _SEENFILE "/gwaySeen.txt"
 
 
 
 
-// Name of he configfile in SPIFFs	filesystem
-// In this file we store the configuration and other relevant info that should
-// survive a reboot of the gateway		
-#define CONFIGFILE "/gwayConfig.txt"
+// Define the maximum amount of items we monitor on the screen
+#if !defined _MAXMONITOR
+#	define _MAXMONITOR 20
+#endif
+
+
+// Timing
+#define _PULL_INTERVAL 20					// PULL_DATA messages to server to get downstream in seconds
+#define _STAT_INTERVAL 120					// Send a 'stat' message to server
+#define _NTP_INTERVAL 3600					// How often do we want time NTP synchronization
+#define _WWW_INTERVAL 60					// Number of seconds before we refresh the WWW page
+#define _FILE_INTERVAL 30					// Number of timer (in secs) before writing to files
+#define _MSG_INTERVAL 31					// Message timeout timer in seconds
+#define _RST_INTERVAL 90					// Reset interval in seconds, total chip reset
 
 
 
 
 // Define the correct radio type that you are using
 // Define the correct radio type that you are using
@@ -334,6 +341,11 @@
 #define _BAUDRATE 115200						// Works for debug messages to serial momitor
 #define _BAUDRATE 115200						// Works for debug messages to serial momitor
 
 
 
 
+// Will we use Mutex or not?
+// +SPI is input for SPI, SPO is output for SPI
+#define _MUTEX 0
+
+
 // MQTT definitions, these settings should be standard for TTN
 // MQTT definitions, these settings should be standard for TTN
 // and need no changing
 // and need no changing
 #define _TTNSERVER "router.eu.thethings.network"
 #define _TTNSERVER "router.eu.thethings.network"

+ 9 - 0
src/configNode.h

@@ -132,6 +132,15 @@ wpas wpa[] = {
 //#define AP_PASSWD "ttnAutoPw"
 //#define AP_PASSWD "ttnAutoPw"
 
 
 
 
+// Gateway Ident definitions. Where is the gateway located?
+#define _DESCRIPTION "ESP Gateway"			// Name of the gateway
+#define _EMAIL "mw12554@hotmail.com"		// Owner
+#define _PLATFORM "ESP8266"
+#define _LAT 52.237367
+#define _LON 5.978654
+#define _ALT 14								// Altitude
+
+
 // For asserting and testing the following defines are used.
 // For asserting and testing the following defines are used.
 //
 //
 #if !defined(CFG_noassert)
 #if !defined(CFG_noassert)

+ 6 - 6
src/loraFiles.h

@@ -69,7 +69,6 @@ struct espGwayConfig {
 	uint16_t ntps;
 	uint16_t ntps;
 	uint16_t logFileRec;		// Logging File Record number
 	uint16_t logFileRec;		// Logging File Record number
 	uint16_t logFileNo;			// Logging File Number
 	uint16_t logFileNo;			// Logging File Number
-	uint16_t logFileNum;		// Number of log files max
 	uint16_t formatCntr;		// Count the number of formats
 	uint16_t formatCntr;		// Count the number of formats
 
 
 	uint16_t ntpErr;			// Number of UTP requests that failed
 	uint16_t ntpErr;			// Number of UTP requests that failed
@@ -82,6 +81,10 @@ struct espGwayConfig {
 	uint8_t pdebug;				// pattern debug, 
 	uint8_t pdebug;				// pattern debug, 
 	uint8_t trusted;			// pattern debug,
 	uint8_t trusted;			// pattern debug,
 	
 	
+	uint8_t	maxSeen;			// Max Seen lines on GUI (not saved for reboots)
+	uint8_t maxMoni;			// Max Monitoring lines	(not saved)
+	uint8_t maxStat;			// Max history lines (not saved)
+	
 	bool cad;					// is CAD enabled?
 	bool cad;					// is CAD enabled?
 	bool hop;					// Is HOP enabled (Note: default be disabled)
 	bool hop;					// Is HOP enabled (Note: default be disabled)
 	bool isNode;				// Is gateway node enabled
 	bool isNode;				// Is gateway node enabled
@@ -99,13 +102,10 @@ struct espGwayConfig {
 
 
 // We do keep admin of logfiles by number
 // We do keep admin of logfiles by number
 // 
 // 
-//uint32_t logFileNo = 0;		// Included in struct espGwayConfig LogFile number
-//uint32_t logFileRec = 0;		// Number of records in a single logfile
-//uint32_t logFileNum = 1;		// Number of log files
 #define LOGFILEMAX 10
 #define LOGFILEMAX 10
 #define LOGFILEREC 100
 #define LOGFILEREC 100
 
 
-#endif // _STAT_LOG
+#endif //_STAT_LOG
 
 
 // Define the node list structure
 // Define the node list structure
 //
 //
@@ -126,7 +126,7 @@ struct nodeSeen {
 	uint8_t chnSeen;
 	uint8_t chnSeen;
 	uint8_t sfSeen;				// Encode the SF seen.This might differ per message!
 	uint8_t sfSeen;				// Encode the SF seen.This might differ per message!
 };
 };
-struct nodeSeen listSeen[_MAXSEEN];
+struct nodeSeen * listSeen;
 
 
 
 
 // define the logging structure used for printout of error and warning messages
 // define the logging structure used for printout of error and warning messages

+ 7 - 6
src/loraModem.h

@@ -254,12 +254,11 @@ struct pins {
 #if _GPS==1
 #if _GPS==1
 #define GPS_RX 15
 #define GPS_RX 15
 #define GPS_TX 12
 #define GPS_TX 12
-#endif // _GPS
+#endif //_GPS
 
 
 #elif _PIN_OUT==5
 #elif _PIN_OUT==5
-
 // ----------------------------------------------------------------------------
 // ----------------------------------------------------------------------------
-// For ESP32/Heltec Wifi LoRA 32(V2) board with 0.9" OLED
+// For ESP32/Heltec Wifi LoRA 32(V2) HTIT-WB32LA board with 0.9" OLED
 //
 //
 // SCK  == GPIO5/ PIN5
 // SCK  == GPIO5/ PIN5
 // SS   == GPIO18/PIN18 CS
 // SS   == GPIO18/PIN18 CS
@@ -279,6 +278,7 @@ struct pins {
 #define RST 14				// Check
 #define RST 14				// Check
 #define SS 18
 #define SS 18
 
 
+
 #else
 #else
 // ----------------------------------------------------------------------------
 // ----------------------------------------------------------------------------
 // Use your own pin definitions, and comment #error line below
 // Use your own pin definitions, and comment #error line below
@@ -291,7 +291,7 @@ struct pins {
 
 
 // stat_t contains the statistics that are kept for a message. 
 // stat_t contains the statistics that are kept for a message. 
 // Each time a message is received or sent the statistics are updated.
 // Each time a message is received or sent the statistics are updated.
-// In case _STATISTICS==1 we define the last _MAXSTAT messages as statistics
+// In case _STATISTICS==1 we define the last gwayConfig.maxStat message as statistics
 struct stat_t {
 struct stat_t {
 	uint32_t time;							// Time since 1970 in seconds		
 	uint32_t time;							// Time since 1970 in seconds		
 	uint32_t node;							// 4-byte DEVaddr (the only one known to gateway)
 	uint32_t node;							// 4-byte DEVaddr (the only one known to gateway)
@@ -352,12 +352,12 @@ struct stat_c statc;
 
 
 
 
 // History of received uplink and downlink messages from nodes
 // History of received uplink and downlink messages from nodes
-struct stat_t statr[_MAXSTAT];
+struct stat_t * statr;
 
 
 
 
 
 
 
 
-#else // _STATISTICS==0
+#else //_STATISTICS==0
 struct stat_t	statr[1];					// Always have at least one element to store in
 struct stat_t	statr[1];					// Always have at least one element to store in
 #endif
 #endif
 
 
@@ -372,6 +372,7 @@ struct LoraDown {
 	uint8_t		powe;
 	uint8_t		powe;
 	uint8_t		crc;
 	uint8_t		crc;
 	uint8_t		iiq;
 	uint8_t		iiq;
+	uint8_t		imme;
 	uint8_t	* 	payLoad;
 	uint8_t	* 	payLoad;
 } LoraDown;
 } LoraDown;
 
 

+ 7 - 7
src/oLED.h

@@ -27,7 +27,7 @@
 // 2. 1.3" OLED with much better and larger display
 // 2. 1.3" OLED with much better and larger display
 // 4. TTGO board
 // 4. TTGO board
 
 
-#if _OLED>=1										// If OLED is used
+#if _OLED>=1									// If OLED is used
 
 
 // ----------------------------------------------------------------------------------------
 // ----------------------------------------------------------------------------------------
 // Define the different PIN's used for SCL/SDA for each arch.
 // Define the different PIN's used for SCL/SDA for each arch.
@@ -45,10 +45,10 @@
 #define OLED_SDA 4								// GPIO4 / 
 #define OLED_SDA 4								// GPIO4 / 
 #define OLED_RST 16								// Reset pin (Some OLED displays do not have it)
 #define OLED_RST 16								// Reset pin (Some OLED displays do not have it)
 
 
-#elif _PIN_OUT==5								// Heltec Wifi LoRA 32(V2) onboard OLED
-#define OLED_SCL 15								// GPIO22 / SCL
-#define OLED_SDA 4								// GPIO21 / SDA
-#define OLED_RST 16								// Reset pin
+#elif _PIN_OUT==5								// TTGO with external OLED
+#define OLED_SCL 22								// GPIO22 / SCL
+#define OLED_SDA 21								// GPIO21 / SDA
+#define OLED_RST 16								// Reset pin (Some OLED displays do not have it)
 
 
 #endif
 #endif
 
 
@@ -60,7 +60,7 @@
 #include "SSD1306.h"
 #include "SSD1306.h"
 #define OLED_ADDR 0x3C							// Default 0x3C for 0.9", for 1.3" it is 0x78
 #define OLED_ADDR 0x3C							// Default 0x3C for 0.9", for 1.3" it is 0x78
 SSD1306  display(OLED_ADDR, OLED_SDA, OLED_SCL);// i2c ADDR & SDA, SCL on wemos
 SSD1306  display(OLED_ADDR, OLED_SDA, OLED_SCL);// i2c ADDR & SDA, SCL on wemos
-#endif
+#endif //_OLED
 
 
 // This is an 1.3" OLED display which is running on I2C
 // This is an 1.3" OLED display which is running on I2C
 #if _OLED==2
 #if _OLED==2
@@ -69,4 +69,4 @@ SSD1306  display(OLED_ADDR, OLED_SDA, OLED_SCL);// i2c ADDR & SDA, SCL on wemos
 SH1106  display(OLED_ADDR, OLED_SDA, OLED_SCL);	// i2c ADDR & SDA, SCL on wemos
 SH1106  display(OLED_ADDR, OLED_SDA, OLED_SCL);	// i2c ADDR & SDA, SCL on wemos
 #endif
 #endif
 
 
-#endif// _OLED>=1
+#endif //_OLED>=1