diff --git a/CSCE838-Lab4-Node/CSCE838-Lab4-Node.ino b/CSCE838-Lab4-Node/CSCE838-Lab4-Node.ino
index 0fc788dd0a518e1495b82cd46a4fa696514b2850..21b6812fe9acf2e45a2063c1df8ed88e4c24de03 100644
--- a/CSCE838-Lab4-Node/CSCE838-Lab4-Node.ino
+++ b/CSCE838-Lab4-Node/CSCE838-Lab4-Node.ino
@@ -66,7 +66,8 @@ static volatile unsigned int counterISR = 1;
 // this interval should not also be increased.
 // See this spreadsheet for an easy airtime and duty cycle calculator:
 // https://docs.google.com/spreadsheets/d/1voGAtQAjC1qBmaVuP1ApNKs1ekgUjavHuVQIXyYSvNc
-#define TX_INTERVAL 5000 //Delay between each message in millisecond.
+#define TX_INTERVAL 60000 //Delay between each message in millisecond.
+#define INTERVAL_NODE 1000
 
 // Pin mapping for SAMD21
 const lmic_pinmap lmic_pins = {
@@ -143,7 +144,7 @@ static void rx_func (osjob_t* job)
   // Timeout RX (i.e. update led status) after 3 periods without RX
   os_setTimedCallback(&timeoutjob, os_getTime() + ms2osticks(3*TX_INTERVAL), rxtimeout_func);
   // Reschedule TX so that it should not collide with the other side's next TX
-  os_setTimedCallback(&txjob, os_getTime() + ms2osticks(TX_INTERVAL / 2), tx_func);
+  //os_setTimedCallback(&txjob, os_getTime() + ms2osticks(TX_INTERVAL / 2), tx_func);
 
   // Print the received output
   if (LMIC.dataLen != sizeof(Lab3Packet_t))
diff --git a/ESP-1ch-Gateway-v5.0-master/ESP-sc-gway/ESP-sc-gway.ino b/ESP-1ch-Gateway-v5.0-master/ESP-sc-gway/ESP-sc-gway.ino
index 015e77aaf34d8bea96c1e5aca3e3f148bf76952b..e2580ada94205d14e531e413141277d7cd157441 100644
--- a/ESP-1ch-Gateway-v5.0-master/ESP-sc-gway/ESP-sc-gway.ino
+++ b/ESP-1ch-Gateway-v5.0-master/ESP-sc-gway/ESP-sc-gway.ino
@@ -1,9 +1,3 @@
-#include "Esp32MQTTClient.h"
-#include <HTTPClient.h>
-#include <Arduino.h>
-
-static const char* connectionString = "HostName=RezoanAhmedNazibHub.azure-devices.net;DeviceId=Node1;SharedAccessKey=+PgtmvZu5RYDc/n/1hCoGzj7i7JyXkBwbDE+rtaBrbk=";
-
 // 1-channel LoRa Gateway for ESP8266
 // Copyright (c) 2016, 2017, 2018 Maarten Westenberg version for ESP8266
 // Version 5.3.3
@@ -33,7 +27,9 @@ static const char* connectionString = "HostName=RezoanAhmedNazibHub.azure-device
 // ----------------------------------------------------------------------------------------
 
 #include "ESP-sc-gway.h"						// This file contains configuration of GWay
-
+#include "Esp32MQTTClient.h"
+#include <HTTPClient.h>
+#include <Arduino.h>
 #if defined (ARDUINO_ARCH_ESP32) || defined(ESP32)
 #define ESP32_ARCH 1
 #endif
@@ -115,6 +111,13 @@ extern "C" {
 #endif//ESP_ARCH
 
 // ----------- Declaration of vars --------------
+#define SEP_CONNECTION_STRING "HostName=SepIoTHub.azure-devices.net;DeviceId=Node1;SharedAccessKey=dZfUU6HJc+TCioN8sbiCgSb/zVK0bgEOiTLKryj6lPA="
+#define SAM_CONNECTION_STRING "HostName=Sam-Murray-Student-IoT-Hub.azure-devices.net;DeviceId=CSCE838-IoT-Sam-Murray;SharedAccessKey=QakoDPCyhIYVOGhf0vcwS+DrHq8rMRWLyS0JmUK8ak0="
+#define MARCUS_CONNECTION_STRING "HostName=CSCE838-IoT.azure-devices.net;DeviceId=Gateway;SharedAccessKey=45a4Yyi98WLO2d7Dudf+jR5r05T063sLWd1UpyCYsAI="
+#define RODOSHI_CONNECTION_STRING "HostName=RodoshiIoTLab.azure-devices.net;DeviceId=IoTGateway;SharedAccessKey=ov2AI0BC/DWDfcCfXCoUfPvh191g0Trm+C6o19pu3yY="
+#define NAZIB_CONNECTION_STRING "HostName=RezoanAhmedNazibHub.azure-devices.net;DeviceId=Node1;SharedAccessKey=+PgtmvZu5RYDc/n/1hCoGzj7i7JyXkBwbDE+rtaBrbk="
+
+static const char* connectionString = NAZIB_CONNECTION_STRING;
 uint8_t debug=1;								// Debug level! 0 is no msgs, 1 normal, 2 extensive
 uint8_t pdebug=0xFF;							// Allow all atterns (departments)
 
@@ -996,22 +999,21 @@ void sendstat() {
 // _state is S_INIT
 // ----------------------------------------------------------------------------
 void setup() {
+
 	char MAC_char[19];								// XXX Unbelievable
 	MAC_char[18] = 0;
 
-	Serial.begin(_BAUDRATE);						// As fast as possible for bus
+	Serial.begin(115200);						// As fast as possible for bus
 	delay(100);	
-  Serial.println("Line number 1004");
+
 #if _GPS==1
 	// Pins are define in LoRaModem.h together with other pins
-	Serial1.begin(115200, SERIAL_8N1, GPS_TX, GPS_RX);// PIN 12-TX 15-RX
-  Serial.begin("Line number 1008");
+	Serial1.begin(9600, SERIAL_8N1, GPS_TX, GPS_RX);// PIN 12-TX 15-RX
 #endif
 
 #ifdef ESP32
-Serial.println("Line number 1012");
 #if DUSB>=1
-	Serial.println(F("ESP32 defined, freq="));
+	Serial.print(F("ESP32 defined, freq="));
 #if _LFREQ==433
 	Serial.print(freqs[0]);
 	Serial.print(F(" EU433"));
@@ -1023,12 +1025,11 @@ Serial.println("Line number 1012");
 #endif
 #endif
 #ifdef ARDUINO_ARCH_ESP32
-
 #if DUSB>=1
 	Serial.println(F("ARDUINO_ARCH_ESP32 defined"));
 #endif
 #endif
-Serial.println("Line number 1031");
+
 
 #if DUSB>=1
 	Serial.flush();
@@ -1075,15 +1076,15 @@ Serial.println("Line number 1031");
 		yield();
 	}
 #endif
-  Serial.println("Line number 1078");
+
 	WiFi.mode(WIFI_STA);
 	WiFi.setAutoConnect(true);
 	//WiFi.begin();
-  Serial.println("Line number 1082");
+	
 	WlanReadWpa();								// Read the last Wifi settings from SPIFFS into memory
 
 	WiFi.macAddress(MAC_array);
- Serial.println("Line number 1086");
+	
     sprintf(MAC_char,"%02x:%02x:%02x:%02x:%02x:%02x",
 		MAC_array[0],MAC_array[1],MAC_array[2],MAC_array[3],MAC_array[4],MAC_array[5]);
 	Serial.print("MAC: ");
@@ -1269,15 +1270,12 @@ Serial.println("Line number 1031");
 	addr_oLED();
 #endif
 
+if (!Esp32MQTTClient_Init((const uint8_t*)connectionString)){
+Serial.println("Initializing IoT hub failed.");
+return;}
+else{
+Serial.println("Initializing IoT hub success.");}
 	Serial.println(F("--------------------------------------"));
-
-  if (!Esp32MQTTClient_Init((const uint8_t*)connectionString)){
-    Serial.println("Initializing IoT hub failed.");
-    return;
-  }
-  else{
-    Serial.println("Initializing IoT hub success.");
-  }
 }//setup
 
 
@@ -1299,15 +1297,195 @@ Serial.println("Line number 1031");
 // ----------------------------------------------------------------------------
 void loop ()
 {
+	uint32_t uSeconds;									// micro seconds
+	int packetSize;
+	uint32_t nowSeconds = now();
+	
+	// check for event value, which means that an interrupt has arrived.
+	// In this case we handle the interrupt ( e.g. message received)
+	// in userspace in loop().
+	//
+	stateMachine();									// do the state machine
+	
+	// After a quiet period, make sure we reinit the modem and state machine.
+	// The interval is in seconds (about 15 seconds) as this re-init
+	// is a heavy operation. 
+	// 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.
+	//
+	if ( ((nowSeconds - statr[0].tmst) > _MSG_INTERVAL ) &&
+		(msgTime <= statr[0].tmst) ) 
+	{
+#if DUSB>=1
+		if (( debug>=1 ) && ( pdebug & P_MAIN )) {
+			Serial.print("M REINIT:: ");
+			Serial.print( _MSG_INTERVAL );
+			Serial.print(F(" "));
+			SerialStat(0);
+		}
+#endif
 
-  uint32_t uSeconds; // micro seconds
-  int packetSize;
-  uint32_t nowSeconds = now();
-  // check for event value, which means that an interrupt has arrived.
-  // In this case we handle the interrupt ( e.g. message received)
-  // in userspace in loop().
-  //
-  stateMachine();
+		// startReceiver() ??
+		if ((_cad) || (_hop)) {
+			_state = S_SCAN;
+			sf = SF7;
+			cadScanner();
+		}
+		else {
+			_state = S_RX;
+			rxLoraModem();
+		}
+		writeRegister(REG_IRQ_FLAGS_MASK, (uint8_t) 0x00);
+		writeRegister(REG_IRQ_FLAGS, (uint8_t) 0xFF);			// Reset all interrupt flags
+		msgTime = nowSeconds;
+	}
+
+#if A_SERVER==1
+	// Handle the Web server part of this sketch. Mainly used for administration 
+	// and monitoring of the node. This function is important so it is called at the
+	// start of the loop() function.
+	yield();
+	server.handleClient();
+#endif
+
+#if A_OTA==1
+	// Perform Over the Air (OTA) update if enabled and requested by user.
+	// It is important to put this function early in loop() as it is
+	// not called frequently but it should always run when called.
+	//
+	yield();
+	ArduinoOTA.handle();
+#endif
+
+	// I event is set, we know that we have a (soft) interrupt.
+	// After all necessary web/OTA services are scanned, we will
+	// reloop here for timing purposes. 
+	// Do as less yield() as possible.
+	// XXX 180326
+	if (_event == 1) {
+		return;
+	}
+	else yield();
+
+	
+	// If we are not connected, try to connect.
+	// We will not read Udp in this loop cycle then
+	if (WlanConnect(1) < 0) {
+#if DUSB>=1
+		if (( debug >= 0 ) && ( pdebug & P_MAIN ))
+			Serial.println(F("M ERROR reconnect WLAN"));
+#endif
+		yield();
+		return;										// Exit loop if no WLAN connected
+	}
+	
+	// So if we are connected 
+	// Receive UDP PUSH_ACK messages from server. (*2, par. 3.3)
+	// This is important since the TTN broker will return confirmation
+	// messages on UDP for every message sent by the gateway. So we have to consume them.
+	// As we do not know when the server will respond, we test in every loop.
+	//
+	else {
+		while( (packetSize = Udp.parsePacket()) > 0) {
+#if DUSB>=2
+			Serial.println(F("loop:: readUdp calling"));
+#endif
+			// DOWNSTREAM
+			// Packet may be PKT_PUSH_ACK (0x01), PKT_PULL_ACK (0x03) or PKT_PULL_RESP (0x04)
+			// This command is found in byte 4 (buffer[3])
+			if (readUdp(packetSize) <= 0) {
+#if DUSB>=1
+				if (( debug>0 ) && ( pdebug & P_MAIN ))
+					Serial.println(F("M readUDP error"));
+#endif
+				break;
+			}
+			// Now we know we succesfully received message from host
+			else {
+				//_event=1;								// Could be done double if more messages received
+			}
+		}
+	}
+	
+	yield();					// XXX 26/12/2017
+
+	// stat PUSH_DATA message (*2, par. 4)
+	//	
+
+    if ((nowSeconds - statTime) >= _STAT_INTERVAL) {	// Wake up every xx seconds
+#if DUSB>=1
+		if (( debug>=1 ) && ( pdebug & P_MAIN )) {
+			Serial.print(F("M STAT:: ..."));
+			Serial.flush();
+		}
+#endif
+        sendstat();										// Show the status message and send to server
+#if DUSB>=1
+		if (( debug>=1 ) && ( pdebug & P_MAIN )) {
+			Serial.println(F(" done"));
+			if (debug>=2) Serial.flush();
+		}
+#endif	
+
+		// If the gateway behaves like a node, we do from time to time
+		// send a node message to the backend server.
+		// The Gateway nod emessage has nothing to do with the STAT_INTERVAL
+		// message but we schedule it in the same frequency.
+		//
+#if GATEWAYNODE==1
+		if (gwayConfig.isNode) {
+			// Give way to internal some Admin if necessary
+			yield();
+			
+			// If the 1ch gateway is a sensor itself, send the sensor values
+			// could be battery but also other status info or sensor info
+		
+			if (sensorPacket() < 0) {
+#if DUSB>=1
+				Serial.println(F("sensorPacket: Error"));
+#endif
+			}
+		}
+#endif
+		statTime = nowSeconds;
+    }
+	
+	yield();
+
+	
+	// send PULL_DATA message (*2, par. 4)
+	//
+	nowSeconds = now();
+    if ((nowSeconds - pulltime) >= _PULL_INTERVAL) {	// Wake up every xx seconds
+#if DUSB>=1
+		if (( debug>=2) && ( pdebug & P_MAIN )) {
+			Serial.println(F("M PULL"));
+			if (debug>=1) Serial.flush();
+		}
+#endif
+//        pullData();										// Send PULL_DATA message to server
+		startReceiver();
+	
+		pulltime = nowSeconds;
+    }
+
+	
+	// If we do our own NTP handling (advisable)
+	// We do not use the timer interrupt but use the timing
+	// of the loop() itself which is better for SPI
+#if NTP_INTR==0
+	// Set the time in a manual way. Do not use setSyncProvider
+	// as this function may collide with SPI and other interrupts
+	yield();											// 26/12/2017
+	nowSeconds = now();
+	if (nowSeconds - ntptimer >= _NTP_INTERVAL) {
+		yield();
+		time_t newTime;
+		newTime = (time_t)getNtpTime();
+		if (newTime != 0) setTime(newTime);
+		ntptimer = nowSeconds;
+	}
+#endif
 	
 
 }//loop