void SkaarhojSerialClient::runLoop(uint16_t delayTime) {

	unsigned long enterTime = millis();

	do {
		_runSubLoop();
		
		if (_HardSerial.available())	{
			_readFromClient();
		}

			// Requesting status of the device:
		if (_statusRequestInterval>0 && !_pendingAnswer && hasTimedOut(_lastStatusRequest,_statusRequestInterval))	{
			if (_serialOutput>1)	Serial.println(F("Pulling status."));
			_lastStatusRequest = millis();

			_sendStatus();
		}
		
			// Send a ping / reconnect:
		if (_ackMsgInterval>0 && !_pendingAnswer && hasTimedOut(_lastIncomingMsg,_ackMsgInterval))	{
			if (_serialOutput>1)	Serial.println(F("Sending Ping."));
			_lastReconnectAttempt = millis();
			_pendingAnswer = true;

			_sendPing();
		}
		
    		// Trying to connect, if not:
		if (!isConnected()) {
			if (_reconnectInterval>0 && hasTimedOut(_lastReconnectAttempt,_reconnectInterval))	{
				connect();
			}
		} else {
			if (_ackMsgInterval>0 && hasTimedOut(_lastIncomingMsg,_ackMsgInterval+2000))	{
				if (_serialOutput)	Serial.println(F("Disconnected."));
				_isConnected = false;
			}
		}
	} while (delayTime>0 && !hasTimedOut(enterTime,delayTime));
}
bool gatewayTransportSend(MyMessage &message)
{
	bool ret = true;
	char *_ethernetMsg = protocolFormat(message);

    setIndication(INDICATION_GW_TX);

	_w5100_spi_en(true);
	#if defined(MY_CONTROLLER_IP_ADDRESS)
		#if defined(MY_USE_UDP)
			_ethernetServer.beginPacket(_ethernetControllerIP, MY_PORT);
			_ethernetServer.write(_ethernetMsg, strlen(_ethernetMsg));
			// returns 1 if the packet was sent successfully
			ret = _ethernetServer.endPacket();
		#else
			EthernetClient client;
			#if defined(MY_CONTROLLER_URL_ADDRESS)
	                	if (client.connected() || client.connect(MY_CONTROLLER_URL_ADDRESS, MY_PORT)) {
	        	#else
	                	if (client.connected() || client.connect(_ethernetControllerIP, MY_PORT)) {
	        	#endif
	                	client.write(_ethernetMsg, strlen(_ethernetMsg));
	                }
	                else {
	                	// connecting to the server failed!
	                	ret = false;
	                }
		#endif
	#else
		// Send message to connected clients
		#if defined(MY_GATEWAY_ESP8266)
			for (uint8_t i = 0; i < ARRAY_SIZE(clients); i++)
			{
				if (clients[i] && clients[i].connected())
				{
					clients[i].write((uint8_t*)_ethernetMsg, strlen(_ethernetMsg));
				}
			}
		#else
			_ethernetServer.write(_ethernetMsg);
		#endif
	#endif
	_w5100_spi_en(false);
	return ret;

}


#if defined(MY_GATEWAY_ESP8266)
	bool _readFromClient(uint8_t i) {
		while (clients[i].connected() && clients[i].available()) {
			char inChar = clients[i].read();
			if (inputString[i].idx < MY_GATEWAY_MAX_RECEIVE_LENGTH - 1) {
				// if newline then command is complete
				if (inChar == '\n' || inChar == '\r') {
					// Add string terminator and prepare for the next message
					inputString[i].string[inputString[i].idx] = 0;
					debug(PSTR("Client %d: %s\n"), i, inputString[i].string);
					inputString[i].idx = 0;
					if (protocolParse(_ethernetMsg, inputString[i].string)) {
						return true;
					}

				} else {
					// add it to the inputString:
					inputString[i].string[inputString[i].idx++] = inChar;
				}
			} else {
				// Incoming message too long. Throw away
				debug(PSTR("Client %d: Message too long\n"), i);
				inputString[i].idx = 0;
				// Finished with this client's message. Next loop() we'll see if there's more to read.
				break;
			}
		}
		return false;
	}
#else
	bool _readFromClient() {
		while (client.connected() && client.available()) {
			char inChar = client.read();
			if (inputString.idx < MY_GATEWAY_MAX_RECEIVE_LENGTH - 1) {
				// if newline then command is complete
				if (inChar == '\n' || inChar == '\r') {
					// Add string terminator and prepare for the next message
					inputString.string[inputString.idx] = 0;
					debug(PSTR("Eth: %s\n"), inputString.string);
					inputString.idx = 0;
					if (protocolParse(_ethernetMsg, inputString.string)) {
						return true;
					}

				} else {
					// add it to the inputString:
					inputString.string[inputString.idx++] = inChar;
				}
			} else {
				// Incoming message too long. Throw away
				debug(PSTR("Eth: Message too long\n"));
				inputString.idx = 0;
				// Finished with this client's message. Next loop() we'll see if there's more to read.
				break;
			}
		}
		return false;
	}
#endif


bool gatewayTransportAvailable()
{
	_w5100_spi_en(true);
	#if !defined(MY_IP_ADDRESS) && defined(MY_GATEWAY_W5100)
		// renew IP address using DHCP
		gatewayTransportRenewIP();
	#endif

	#ifdef MY_USE_UDP

		int packet_size = _ethernetServer.parsePacket();

		if (packet_size) {
			//debug(PSTR("UDP packet available. Size:%d\n"), packet_size);
            setIndication(INDICATION_GW_RX);
			#if defined(MY_GATEWAY_ESP8266)
				_ethernetServer.read(inputString[0].string, MY_GATEWAY_MAX_RECEIVE_LENGTH);
				inputString[0].string[packet_size] = 0;
				debug(PSTR("UDP packet received: %s\n"), inputString[0].string);
				return protocolParse(_ethernetMsg, inputString[0].string);
			#else
				_ethernetServer.read(inputString.string, MY_GATEWAY_MAX_RECEIVE_LENGTH);
				inputString.string[packet_size] = 0;
				debug(PSTR("UDP packet received: %s\n"), inputString.string);
				_w5100_spi_en(false);
				return protocolParse(_ethernetMsg, inputString.string);
			#endif
		}
	#else
		#if defined(MY_GATEWAY_ESP8266)
			// ESP8266: Go over list of clients and stop any that are no longer connected.
			// If the server has a new client connection it will be assigned to a free slot.
			bool allSlotsOccupied = true;
			for (uint8_t i = 0; i < ARRAY_SIZE(clients); i++) {
				if (!clients[i].connected()) {
					if (clientsConnected[i]) {
						debug(PSTR("Client %d disconnected\n"), i);
						clients[i].stop();
					}
					//check if there are any new clients
					if (_ethernetServer.hasClient()) {
						clients[i] = _ethernetServer.available();
						inputString[i].idx = 0;
						debug(PSTR("Client %d connected\n"), i);
						gatewayTransportSend(buildGw(_msg, I_GATEWAY_READY).set("Gateway startup complete."));
						if (presentation)
							presentation();
					}
				}
				bool connected = clients[i].connected();
				clientsConnected[i] = connected;
				allSlotsOccupied &= connected;
			}
			if (allSlotsOccupied && _ethernetServer.hasClient()) {
				//no free/disconnected spot so reject
				debug(PSTR("No free slot available\n"));
				EthernetClient c = _ethernetServer.available();
				c.stop();
			}
				// Loop over clients connect and read available data
			for (uint8_t i = 0; i < ARRAY_SIZE(clients); i++) {
				if (_readFromClient(i)) {
                    setIndication(INDICATION_GW_RX);
					_w5100_spi_en(false);
					return true;
				}
			}
		#else
			// W5100/ENC module does not have hasClient-method. We can only serve one client at the time.
			EthernetClient newclient = _ethernetServer.available();
			// if a new client connects make sure to dispose any previous existing sockets
			if (newclient) {
				if (client != newclient) {
					client.stop();
					client = newclient;
					debug(PSTR("Eth: connect\n"));
					_w5100_spi_en(false);
					gatewayTransportSend(buildGw(_msg, I_GATEWAY_READY).set("Gateway startup complete."));
					_w5100_spi_en(true);
					if (presentation)
						presentation();
				}
			}
			if (client) {
				if (!client.connected()) {
					debug(PSTR("Eth: disconnect\n"));
					client.stop();
				} else {
					if (_readFromClient()) {
                        setIndication(INDICATION_GW_RX);
						_w5100_spi_en(false);
						return true;
					}
				}
			}
		#endif
	#endif
	_w5100_spi_en(false);
	return false;
}