size_t ArduinoiDigiInterfaceClass::network_send(idigi_network_handle_t *handle, char *buffer, size_t length)
{
  EthernetClient *client = (EthernetClient *) handle;
  AR_DEBUG_PRINTF("network_send: len = %d\r\n", length);
  size_t sent = client->write((const uint8_t *) buffer, length);
  return sent;
}
示例#2
0
static void printP(EthernetClient client, const prog_uchar *str) 
{
    uint8_t pgmChar;
    while(pgmChar = pgm_read_byte(str++))
    {
      client.write(pgmChar);
    }
}
示例#3
0
static int flush_sendbuf(EthernetClient & client)
{
	int ret = 0;
	if (sendbufptr > sendbuf)
	{
		ret = client.write((uint8_t*)sendbuf, sendbufptr-sendbuf);
		setup_sendbuf();
	}
	return ret;
}
示例#4
0
Weather::ReturnVals Weather::GetVals(const char * key, uint32_t zip, const char * pws, bool usePws) const
{
	ReturnVals vals = {0};
	EthernetClient client;
	if (client.connect(m_wundergroundAPIHost, 80))
	{
		char getstring[255];
		trace(F("Connected\n"));
		if (usePws)
			snprintf(getstring, sizeof(getstring), "GET http://%s/api/%s/yesterday/conditions/q/pws:%s.json HTTP/1.1\r\n",m_wundergroundAPIHost, key, pws);
		else
			snprintf(getstring, sizeof(getstring), "GET http://%s/api/%s/yesterday/conditions/q/%ld.json HTTP/1.1\r\n",m_wundergroundAPIHost, key, (long) zip);

		//trace("GetString:%s\n",getstring);
		client.write((uint8_t*) getstring, strlen(getstring));
		
		//send host header
		snprintf(getstring, sizeof(getstring), "Host: %s\r\nConnection: close\r\n\r\n",m_wundergroundAPIHost);
		//trace("GetString:%s\n",getstring);
		client.write((uint8_t*) getstring, strlen(getstring));

		ParseResponse(client, &vals);
		vals.resolvedIP=client.GetIpAddress();

		client.stop();
		if (!vals.valid)
		{
			if (vals.keynotfound)
				trace("Invalid WUnderground Key\n");
			else
				trace("Bad WUnderground Response\n");
		}
	}
	else
	{
		trace(F("connection failed\n"));
		client.stop();
	}
	return vals;
}
示例#5
0
void SendFrame(uint8_t fr_nr)
{
	// init frame to send
	memcpy_P(&frame[0], &ec_frames[fr_nr], sizeof(modbus_head_t));
	CalculateCRC(6);  // add crc bytes to the end of frame starting form byte position 6
#if _DEBUG_>1
	Serial.print(F("Sending EnergyCam frame:"));
	for (byte i=0; i<8; i++) {
		Serial.print(' ');
		byte tmp = frame[i];
		if ( tmp<16 ) Serial.print(0);
		Serial.print(tmp, HEX);
	}
	Serial.println();
#endif
	while ( (millis()-startDelay)<2 ) WDG_RST;	// wait for frame delay
	// prepare to send
#ifdef USE_RS485
	RS485_ENABLE_TX;
	delayMicroseconds(100);
	// write RS485 header
	Serial1.write(EC_ID);
	Serial1.write(0xFF^EC_ID);
	Serial1.write(frame, 8);
	// prepare to receive the answer
	Serial1.flush();	// wait till all data was sent
	delayMicroseconds(300);
	RS485_ENABLE_RX;
#else
	ec_client.write((byte)0);	// wake-up from sleep mode
	delay(2);	// frame delay
	//frameSize = 8;
	ec_client.write(frame, 8);
	// wait till last byte was sent
	//	delayMicroseconds(frameDelay);
	delay(2);	// frame delay
#endif
	Modbus_WaitForReply();	// wait one second long till complete reply frame is received
//	return error_code;
}
示例#6
0
void api_call_http_register_self(byte amsg_server[]) {


	char path[ 30 ];
	char host[ 30 ];
	strcpy_P(path, msg_server_path);
	strcpy_P(host, msg_server_host);

	EthernetClient client;


	Serial.print("HTTP opening connection to ");
	Serial.println(host);
	/*
	if (!ether.dnsLookup(website))
		  Serial.println("DNS failed");
	else
		  Serial.println("DNS resolution done");
	ether.printIp("SRV IP:\t", ether.hisip);
	*/

	if (!client.connect(amsg_server, pgm_read_word(&msg_server_port))) {
		Serial.println("HTTP failed");
		return;
	}

	char d;
	String netbuf = "GET ";
	netbuf += path;
	netbuf += " HTTP/1.0\nHost: ";
	netbuf += host;
	netbuf += "\nConnection: close\n\n\n";

	Serial.print("HTTP connected to ... ");

	char sockbuf[ netbuf.length() ];
	netbuf.toCharArray(sockbuf, netbuf.length());
	client.write(sockbuf);
	delay(100);
	while(client.connected()) {
		while(client.available())   {
			d = client.read();
			if (d == '\n')
				Serial.print("\r\n");
			else
				Serial.print(d);
		}
	}	  
	client.stop();
	Serial.println();
}
示例#7
0
void ModbusIP::task() {
    EthernetClient client = _server.available();

    if (client) {
        if (client.connected()) {
            int i = 0;
            while (client.available()){
                _MBAP[i] = client.read();
                i++;
                if (i==7) break;  //MBAP length has 7 bytes size
            }
            _len = _MBAP[4] << 8 | _MBAP[5];
            _len--;  // Do not count with last byte from MBAP

            if (_MBAP[2] !=0 || _MBAP[3] !=0) return;   //Not a MODBUSIP packet
            if (_len > MODBUSIP_MAXFRAME) return;      //Length is over MODBUSIP_MAXFRAME

            _frame = (byte*) malloc(_len);
            i = 0;
            while (client.available()){
                _frame[i] = client.read();
                i++;
                if (i==_len) break;
            }

            this->receivePDU(_frame);
            if (_reply != MB_REPLY_OFF) {
                //MBAP
                _MBAP[4] = (_len+1) >> 8;     //_len+1 for last byte from MBAP
                _MBAP[5] = (_len+1) & 0x00FF;

                byte sendbuffer[7 + _len];

                for (i = 0 ; i < 7 ; i++) {
                    sendbuffer[i] = _MBAP[i];
                }
                //PDU Frame
                for (i = 0 ; i < _len ; i++) {
                    sendbuffer[i+7] = _frame[i];
                }
                client.write(sendbuffer, _len + 7);
            }

#ifndef TCP_KEEP_ALIVE
            client.stop();
#endif
            free(_frame);
            _len = 0;
        }
示例#8
0
static void ServeFile(FILE * stream_file, const char * fname, SdFile & theFile, EthernetClient & client)
{
	freeMemory();
	const char * ext;
	for (ext=fname + strlen(fname); ext>fname; ext--)
		if (*ext == '.')
		{
			ext++;
			break;
		}
	if (ext > fname)
	{
		if (strcmp(ext, "jpg") == 0)
			ServeHeader(stream_file, 200, "OK", true, "image/jpeg");
		else if (strcmp(ext, "gif") == 0)
			ServeHeader(stream_file, 200, "OK", true, "image/gif");
		else if (strcmp(ext, "css") == 0)
			ServeHeader(stream_file, 200, "OK", true, "text/css");
		else if (strcmp(ext, "js") == 0)
			ServeHeader(stream_file, 200, "OK", true, "application/javascript");
		else if (strcmp(ext, "ico") == 0)
			ServeHeader(stream_file, 200, "OK", true, "image/x-icon");
		else
			ServeHeader(stream_file, 200, "OK", true);
	}
	else
		ServeHeader(stream_file, 200, "OK", true);


#ifdef ARDUINO
	flush_sendbuf(client);
#else
	fflush(stream_file);
#endif
	while (theFile.available())
	{
		int bytes = theFile.read(sendbuf, 512);
		if (bytes <= 0)
			break;
		client.write((uint8_t*) sendbuf, bytes);
	}
}
示例#9
0
void networkManage() {
	uint16_t size;

	if (sendClient.available()) {
//		int size = sendClient.read((uint8_t *) buf2, BUFFER_SIZE);
		size = readHttpFrame(sendClient);
#ifdef HMAC
		if (!isTimeReady()) {
			uint16_t endPos = strstrpos_P((char *) buf, DOUBLE_ENDL);
			receiveTime((char *) &buf[endPos + 4]);
		}
#endif
	}

#ifdef HMAC
	if (!isTimeReady() && sendClient.status() == SnSR::CLOSED && (lastFailTime == 0 || millis() - lastFailTime > dateFailRetryWait)) {
		if (sendClient.connect(NotifyDstIp, notifyDstPort)) {
			int len = clientBuildTimeQuery((char *) buf);
			sendClient.write(buf, len);
		} else {
			lastFailTime = millis();
			sendClient.stop();
		}
	}
#endif

	if (!sendClient.connected()) {
		sendClient.stop();
	}

	if (notification != 0 && sendClient.status() == SnSR::CLOSED) {
		// there is a notif and we are not handling another one
		if (lastFailTime == 0 || millis() - lastFailTime > notifFailRetryWait) {
			if (sendClient.connect(NotifyDstIp, notifyDstPort)) {
				int len = clientBuildNextQuery((char *) buf);
				sendClient.write(buf, len);
			} else {
				lastFailTime = millis();
				sendClient.stop();
			}
		}
	}

	EthernetClient client = server.available();
    if (client) {
        while (client.connected()) {
            if (client.available()) {
                size = readHttpFrame(client);

                if (size > 0) {
                    buf[size] = 0;
                    size = handleWebRequest((char *) buf, 0, size);
                    buf[size] = 0;
                    client.println((const char *) buf);
                }

                delay(1);
                client.stop();
            }
        }
    }
	if (needReboot) {
		resetFunc();
	}
}
示例#10
0
void runExternalCommandsPersistent(EthernetServer* _server, systemState* _state) 
{
	// local variables
	int i, buffer_ptr;
	int room, radiatorState, automaticMode;
	float temperature;
	int commandError = 0;
	
	
	EthernetClient client = _server->available(); // is non-blocking
	if(client.available() > 2)
	{
		#ifdef DEBUG
		Serial.println("Connection established");
		Serial.print("Available: ");
		Serial.println(client.available());
		#endif
		
		char buffer[32];
		
		// read command field
		if( readParam(buffer, 3, client) < 0 ) {commandError = 1; goto errorHandler;}
		
		// switch case on commands
		if(strcmp(buffer, "STM") == 0) // set temperature
		{
			#ifdef DEBUG
			Serial.println("Set temperature command received");
			#endif
			
			// read fisrt param: room number (one digit)
			if( readParam(buffer, 1, client) < 0 ) {commandError = 1; goto errorHandler;}
			room = atoi(buffer);
			
			// read second param: temperature (format xx.y)
			if( readParam(buffer, 4, client) < 0 ) {commandError = 1; goto errorHandler;}
			temperature = atof(buffer);
			
			_state->desiredTemp[room] = temperature;
			
			client.write((unsigned char*)"STM", 3);
			client.write((unsigned char*)"OOK", 3);
		}
		else if(strcmp(buffer, "RTM") == 0) // read temperature
		{
			#ifdef DEBUG
			Serial.println("Read temperature command received");
			#endif
			// read fisrt param: room number (one digit)
			if( readParam(buffer, 1, client) < 0 ) {commandError = 1; goto errorHandler;}
			
			room = atoi(buffer);
			
			temperature = _state->actualTemp[room];
			//buffer_ptr = sprintf(buffer, "%4.1f", temperature);
			ttoa(buffer, temperature);
			
			client.write((unsigned char*)"RTM", 3);
			client.write((unsigned char*)"OOK", 3);
			client.write((unsigned char*)buffer, 4);
		}
		else if(strcmp(buffer, "SRD") == 0) // set radiator
		{
			#ifdef DEBUG
			Serial.println("Set radiator command received");
			#endif
			// read fisrt param: room number (one digit)
			if( readParam(buffer, 1, client) < 0 ) {commandError = 1; goto errorHandler;}
			room = atoi(buffer);
			
			// read second param: radiator state (one digit)
			if( readParam(buffer, 1, client) < 0 ) {commandError = 1; goto errorHandler;}
			radiatorState = atoi(buffer);
			
			_state->radiatorState[room] = radiatorState;
			digitalWrite(radiatorPinByRoom(room), (radiatorState == 1) ? LOW : HIGH);
			
			// set zone valve
			int someoneIsOn = 0;
			for(room = 0; room < 6; room++) 
			{
				if(_state->radiatorState[room] == ON) someoneIsOn = 1;
			}
			digitalWrite(ZONE_VALVE_NO1, someoneIsOn ? LOW : HIGH);
			
			client.write((unsigned char*)"SRD", 3);
			client.write((unsigned char*)"OOK", 3);
		}
		else if(strcmp(buffer, "RRD") == 0) // read radiator
		{
			#ifdef DEBUG
			Serial.println("Read radiator command received");
			#endif
			// read fisrt param: room number (one digit)
			if( readParam(buffer, 1, client) < 0 ) {commandError = 1; goto errorHandler;}
			room = atoi(buffer);

			radiatorState = _state->radiatorState[room];
			sprintf(buffer, "%d", radiatorState);
			
			client.write((unsigned char*)"RRD", 3);
			client.write((unsigned char*)"OOK", 3);
			client.write((unsigned char*)buffer, 1);
		}
		else if(strcmp(buffer, "SAM") == 0) // set automatic mode
		{
			#ifdef DEBUG
			Serial.println("Set automatic mode command received");
			#endif
			// read second param: radiator state (one digit)
			if( readParam(buffer, 1, client) < 0 ) {commandError = 1; goto errorHandler;}
			automaticMode = atoi(buffer);
			
			_state->automaticMode = automaticMode;
			
			client.write((unsigned char*)"SAM", 3);
			client.write((unsigned char*)"OOK", 3);
		}
		else if(strcmp(buffer, "RAM") == 0) // read automatic mode
		{
			#ifdef DEBUG
			Serial.println("Read automatic mode command received");
			#endif
			automaticMode = _state->automaticMode;
			
			sprintf(buffer, "%d", automaticMode);
			
			client.write((unsigned char*)"RAM", 3);
			client.write((unsigned char*)"OOK", 3);
			client.write((unsigned char*)buffer, 1);
		}
		else if(strcmp(buffer, "RDT") == 0) // read desired temperature
		{
			#ifdef DEBUG
			Serial.println("Read desired temperature command received");
			#endif
			// read fisrt param: room number (one digit)
			if( readParam(buffer, 1, client) < 0 ) {commandError = 1; goto errorHandler;}
			room = atoi(buffer);
			
			temperature = _state->desiredTemp[room];
			//buffer_ptr = sprintf(buffer, "%4.1f", temperature);
			ttoa(buffer, temperature);
			
			client.write((unsigned char*)"RDT", 3);
			client.write((unsigned char*)"OOK", 3);
			client.write((unsigned char*)buffer, 4);
		}
		else if(strcmp(buffer, "CLS") == 0) // Close connection
		{
			#ifdef DEBUG
			Serial.println("Close connection command received");
			#endif
			
			client.write((unsigned char*)"CLS", 3);
			client.write((unsigned char*)"OOK", 3);
			
			client.flush(); // NEW to verify ---> it seems not working
			delay(2000);
			while(client.connected())
			{
				client.stop();
				delay(2000);
			}
		}
		else
		{
			#ifdef DEBUG
			Serial.print("Invalid command received: ");
			Serial.print(buffer[0]);
			Serial.print(buffer[1]);
			Serial.print(buffer[2]);
			Serial.println();
			#endif
			client.write((unsigned char*)"ERR", 3);
			client.write((unsigned char*)"INV", 3);
		}
		
		// =============================================
		errorHandler:
		if(commandError)
		{
			
			#ifdef DEBUG
			Serial.print("Invalid command received: ");
			Serial.print(buffer[0]);
			Serial.print(buffer[1]);
			Serial.print(buffer[2]);
			Serial.println();
			#endif
			client.write((unsigned char*)"ERR", 3);
			client.write((unsigned char*)"GEN", 3);
		}
		// =============================================
	}
	
}
示例#11
0
void api_call_http(byte amsg_server[], char body[]) {

	char path[ 30 ];
	char host[ 30 ];
	strcpy_P(path, msg_server_path);
	strcpy_P(host, msg_server_host);

	EthernetClient client;


	if (!client) {
		Serial.println("Ethernet client not available!");
		return;
	}

	Serial.print("HTTP opening connection to ");
	Serial.println(host);
	/*
	if (!ether.dnsLookup(website))
		  Serial.println("DNS failed");
	else
		  Serial.println("DNS resolution done");
	ether.printIp("SRV IP:\t", ether.hisip);
	*/

	if (!client.connect(amsg_server, pgm_read_word(&msg_server_port))) {
		Serial.println("HTTP failed");
		return;
	}

	char d;
	//TODO: add serial number, hash message, JSON
	String postbuf = body;
	String netbuf = "POST ";
	netbuf += path;
	netbuf += " HTTP/1.0\nHost: ";
	netbuf += host;
	netbuf += "\nContent-Type: application/x-www-form-urlencoded\nContent-length:";
	netbuf += postbuf.length();
	netbuf += "\nConnection: close\n\n";
	netbuf += postbuf;
  //compile error on arduino 1.6.2
  //it's just a memory optimization
	//postbuf = NULL;

	Serial.println("HTTP connected");
	Serial.print(netbuf);

	char sockbuf[ netbuf.length() +1];
	netbuf.toCharArray(sockbuf, netbuf.length()+1);
	client.write(sockbuf);
	delay(300);
	while(client.connected()) {
		while(client.available())   {
			d = client.read();
			if (d == '\n')
				Serial.print("\r\n");
			else
				Serial.print(d);
		}
	}
	client.stop();
	Serial.println();
}
示例#12
0
void GetWeather() {
  EthernetClient client;

  static struct hostent *server = NULL;
  if (!server) {
    strcpy(tmp_buffer, WEATHER_SCRIPT_HOST);
    server = gethostbyname(tmp_buffer);
    if (!server) {
      DEBUG_PRINTLN("can't resolve weather server");
      return;    
    }
    DEBUG_PRINT("weather server ip:");
    DEBUG_PRINT(((uint8_t*)server->h_addr)[0]);
    DEBUG_PRINT(":");
    DEBUG_PRINT(((uint8_t*)server->h_addr)[1]);
    DEBUG_PRINT(":");
    DEBUG_PRINT(((uint8_t*)server->h_addr)[2]);
    DEBUG_PRINT(":");
    DEBUG_PRINTLN(((uint8_t*)server->h_addr)[3]);
  }

  if (!client.connect((uint8_t*)server->h_addr, 80)) {
    DEBUG_PRINTLN("failed to connect to weather server");
    client.stop();
    return;
  }

  BufferFiller bf = tmp_buffer;
  char tmp[100];
  read_from_file(wtopts_name, tmp, 100);
  bf.emit_p(PSTR("$D.py?loc=$E&key=$E&fwv=$D&wto=$S"),
                (int) os.options[OPTION_USE_WEATHER].value,
                ADDR_NVM_LOCATION,
                ADDR_NVM_WEATHER_KEY,
                (int)os.options[OPTION_FW_VERSION].value,
                tmp);    

  char *src=tmp_buffer+strlen(tmp_buffer);
  char *dst=tmp_buffer+TMP_BUFFER_SIZE-1;
  
  char c;
  // url encode. convert SPACE to %20
  // copy reversely from the end because we are potentially expanding
  // the string size 
  while(src!=tmp_buffer) {
    c = *src--;
    if(c==' ') {
      *dst-- = '0';
      *dst-- = '2';
      *dst-- = '%';
    } else {
      *dst-- = c;
    }
  };
  *dst = *src;

  char urlBuffer[255];
  strcpy(urlBuffer, "GET /weather");
  strcat(urlBuffer, dst);
  strcat(urlBuffer, " HTTP/1.0\r\nHOST: weather.opensprinkler.com\r\n\r\n");
  
  client.write((uint8_t *)urlBuffer, strlen(urlBuffer));
  
  bzero(ether_buffer, ETHER_BUFFER_SIZE);
  
  time_t timeout = os.now_tz() + 5; // 5 seconds timeout
  while(os.now_tz() < timeout) {
    int len=client.read((uint8_t *)ether_buffer, ETHER_BUFFER_SIZE);
    if (len<=0) {
      if(!client.connected())
        break;
      else 
        continue;
    }
    peel_http_header();
    getweather_callback(0, 0, ETHER_BUFFER_SIZE);
  }
  client.stop();
}
/**
 *
 * @brief MQTT Paho client write interface
 *
 * @param n             pointer to the Network stucture
 * @param buffer        buffer to write out 
 * @param length        number of bytes to write out
 * @timeout timeout_ms  timeout
 *
 * @return Number of by bytes written out 
 *
 * \NOMANUAL
 */
int mqtt_write(Network* n, unsigned char* buffer, int length, int timeout_ms) {
    EthernetClient* client = (EthernetClient*)n->client;
    
    return(client->write((char*)buffer, length));
}
示例#14
0
void ModbusTCP::run(void){

  int16_t i, iStart, iQty;
  int16_t iTXLen = 0;       // response packet length
  uint8_t *ptr, iFC = MB_FC_NONE, iEC = MB_EC_NONE;
  //  
  // Initialize and check for a request from a MODBUS master
  //
#ifdef MB_ETHERNET
  EthernetClient clientrequest = mb_server.available();
#endif
#ifdef MB_CC3000
  Adafruit_CC3000_ClientRef clientrequest = mb_server.available();
#endif
#ifdef ARDUINO_AMEBA
  if (!clientrequest.connected()) {
    clientrequest = mb_server.available();
  }
#endif

#ifdef MODBUSTCP_PCN001_USE_WIFI
  if(clientrequest.available()) {
    int len = clientrequest.read(mb_adu, sizeof(mb_adu));
    if (len > 0) {
      iFC = mb_adu[MB_TCP_FUNC];
    }
  } else {
    delay(10);
  }

#else
  if(clientrequest.available()) {
    //
    // Retrieve request
    //
    for (i = 0 ; clientrequest.available() ; i++) 
      mb_adu[i] = clientrequest.read();
#ifdef MB_DEBUG   
    printMB("RX: ", word(mb_adu[MB_TCP_LEN],mb_adu[MB_TCP_LEN+1])+6);  
#endif    
    //
    // Unpack the function code
    //
    iFC = mb_adu[MB_TCP_FUNC];
  }
#endif // end of #ifdef ARDUINO_AMEBA
  //
  // Handle request
  //
  switch(iFC) {
  case MB_FC_NONE:
    break;
  case MB_FC_READ_REGISTERS: 
    //
    // 03 (0x03) Read Holding Registers
    //
    // modpoll -m tcp -t 4:float -r 40001 -c 1 -1 192.168.x.x
    //
    //     [TransID] [ProtID-] [Length-] [Un] [FC] [Start--] [Qty----] 
    // RX: 0x00 0x01 0x00 0x00 0x00 0x06 0x01 0x03 0x9C 0x40 0x00 0x02 
    //
    //     [TransID] [ProtID-] [Length-] [Un] [FC] [Bc] [float------------] 
    // TX: 0x00 0x01 0x00 0x00 0x00 0x07 0x01 0x03 0x04 0x20 0x00 0x47 0xF1
    //
    // 123456.0 = 0x00 0x20 0xF1 0x47 (IEEE 754)
    //
    // Unpack the start and length
    //
    ptr = mb_adu + MB_TCP_DATA;
    iStart = word(*ptr++, *ptr++) - 40000;
    iQty = 2*word(*ptr++, *ptr);
    //
    // check for valid register addresses     
    //
    if (iStart < 0 || (iStart + iQty/2 - 1) > MB_REGISTERS_MAX) {
      iEC = MB_EC_ILLEGAL_DATA_ADDRESS;
      break;
    }
    //
    // Write data length
    //
    ptr = mb_adu + MB_TCP_DATA;
    *ptr++ = iQty;
    //
    // Write data
    //
    for (i = 0 ; i < iQty/2 ; i++) {
      *ptr++ = highByte(mb_reg[iStart + i]);
      *ptr++ =  lowByte(mb_reg[iStart + i]);
    }
    iTXLen = iQty + 9;
    break;

  case MB_FC_WRITE_REGISTER:
    //
    // 06 (0x06) Write register 
    //
    ptr = mb_adu + MB_TCP_DATA;   
    iStart = word(*ptr++, *ptr++) - 40000;
    //
    // check for valid register addresses     
    //   
    if (iStart < 0 || (iStart - 1) > MB_REGISTERS_MAX) {
      iEC = MB_EC_ILLEGAL_DATA_ADDRESS;
      break;
    }      
    // Unpack and store data
    //
    mb_reg[iStart] = word(*ptr++, *ptr);
    //
    // Build a response 
    //
    iTXLen = 12;             
    break;

  case MB_FC_WRITE_MULTIPLE_REGISTERS: 
    //
    // 16 (0x10) Write Multiple registers
    //
    // modpoll -m tcp -t 4:float -r 40001 -c 1 -1 192.168.x.x 123456.0
    //
    //     [TransID] [ProtID-] [Length-] [Un] [FC] [Start--] [Qty----] [Bc] [float------------] 
    // RX: 0x00 0x01 0x00 0x00 0x00 0x0B 0x01 0x10 0x9C 0x40 0x00 0x02 0x04 0x20 0x00 0x47 0xF1
    //
    // 123456.0 = 0x00 0x20 0xF1 0x47 (IEEE 754)
    //
    // Unpack the start and length
    //
    ptr = mb_adu + MB_TCP_DATA;   
    iStart = word(*ptr++, *ptr++) - 40000;
    iQty = 2*word(*ptr++, *ptr);      
    //
    // check for valid register addresses     
    //   
    if (iStart < 0 || (iStart + iQty/2 - 1) > MB_REGISTERS_MAX) {
      iEC = MB_EC_ILLEGAL_DATA_ADDRESS;
      break;
    }
    //
    // Unpack and store data
    //
    ptr = mb_adu + MB_TCP_DATA+5;
    // todo: check for valid length
    for (i = 0 ; i < iQty/2 ; i++) {
      mb_reg[iStart + i] = word(*ptr++, *ptr++);
    }
    //
    // Build a response 
    //
    iTXLen = 12;
    break;

  default:
    iEC = MB_EC_ILLEGAL_FUNCTION;
    break;    
  }
  //
  // Build exception response if necessary because we were too
  // lazy to do it earlier. Other responses should already be
  // built.
  //
  if (iEC) {
    ptr = mb_adu + MB_TCP_FUNC;
    *ptr = *ptr++ | 0x80;        // flag the function code
    *ptr = iEC;                  // write the exception code
    iTXLen = 9;
  }
  //
  // If there's a response, transmit it
  //
  if (iFC) {
    ptr = mb_adu + MB_TCP_LEN;    // write the header length
    *ptr++ = 0x00;
    *ptr = iTXLen - MB_TCP_UID;  
    clientrequest.write(mb_adu, iTXLen); // send it        
#ifdef MB_DEBUG   
    printMB("TX: ", word(mb_adu[MB_TCP_LEN], mb_adu[MB_TCP_LEN+1]) + MB_TCP_UID);  
#endif                                                
  }
}
示例#15
0
void loop() {
	// try to get client
	EthernetClient client = server.available();
	String getStr;
	
	if (client) {
		digitalWrite(greLed,HIGH);
		boolean currentLineIsBlank = true;
		boolean indice = false;
		while (client.connected()) {
			if (client.available()) {	// client data available to read
				char c = client.read();	// read 1 byte (character) from client
				// filter GET request
				// GET /index.html HTTP/1.1
				if (c == 'G') {
					c = client.read();
					if (c == 'E') {
						c = client.read();
						if (c == 'T') {
							Serial.print("GET=");
							c = client.read(); // space
							while (true) {
								c = client.read();
								if (c == ' ') {
									break;
								}
								//Serial.println(c);
								getRequest[getIndi] = c;
								getIndi++;
							}
							Serial.print(getRequest);
							Serial.println("@");
						}
					}
				}
				if (c == '\n' && currentLineIsBlank) {
					// convert to string and clear char array
					String getStr(getRequest);
					Clear();

					// if check
					// first page
					if (getStr == "/" || getStr == "/index.html") {
						indice = true;
					}

					// ajax GET info
					else if (getStr.startsWith("/Set?")) {
						indice = true;
						int getRequestStart = getStr.indexOf('?' );
						int getRequestFirst = getStr.indexOf('=' );
						int getRequestFinal = getStr.indexOf('/',2);
						int getRequestDuall = getStr.indexOf('&' );	// 2 GET
						if (getRequestDuall>0) {	// /index.html?X=20&Y=30
							int getRequestSecon = getStr.indexOf('=', getRequestFirst+1);
							String inputFirst_1 = getStr.substring(getRequestStart+1, getRequestFirst);	// X
							String valueFirst_1 = getStr.substring(getRequestFirst+1, getRequestDuall);	// 20
							String inputFirst_2 = getStr.substring(getRequestDuall+1, getRequestSecon);	// Y
							String valueFirst_2 = getStr.substring(getRequestSecon+1, getRequestFinal);	// 30
							if (inputFirst_1 == "X") {
								Update('X',valueFirst_1.toInt());
								Update('Y',valueFirst_2.toInt());
							}
							// reverse
							else if (inputFirst_1 == "Y") {
								Update('Y',valueFirst_1.toInt());
								Update('X',valueFirst_2.toInt());
							}
						}
						else {						// /index.html?Y=50 or X=50
							String inputFirst = getStr.substring(getRequestStart+1, getRequestFirst);	// Y
							String valueFirst = getStr.substring(getRequestFirst+1, getRequestFinal);	// 50
							if (inputFirst == "X") {
								Update('X',valueFirst.toInt());
							}
							else if (inputFirst == "Y") {
								Update('Y',valueFirst.toInt());
							}
						}
					}

					//ajax SAVE info
					else if (getStr.startsWith("/Save/")) {
						digitalWrite(redLed,HIGH);
						client.println("HTTP/1.1 200 OK");
						client.println("Connection: close");
						Serial.println("SAVE");
						Serial.println("");
						SD.remove(LOG);
						dataFile = SD.open(LOG, FILE_WRITE);
						if(dataFile) {				// X=123-Y=45-
							dataFile.print("X=");
							dataFile.print(X);
							dataFile.print("-Y=");
							dataFile.print(Y);
							dataFile.print("-");
							dataFile.close();
						}
						digitalWrite(redLed,LOW);
					}

					//ajax RESET info
					else if (getStr.startsWith("/Reset/")) {
						digitalWrite(redLed,HIGH);
						client.println("HTTP/1.1 200 OK");
						client.println("Connection: close");
						Serial.println("RESET");
						Serial.println("");
						delay(1);
						servoX.detach();
						servoY.detach();
						digitalWrite(redLed,LOW);
						digitalWrite(resetPin, LOW);
					}
					// ajax SET info
					else if (getStr.startsWith("/Coordinate/")) {
						digitalWrite(redLed,HIGH);
						GetValue();
						double temp = analogRead(thermRes);
						int phot = analogRead(photoRes);
						client.println("HTTP/1.1 200 OK");
						client.println("Connection: close");
						client.println();
						// JSON
						client.print("{\"coordinate\":{\"X\":");
						client.print(X);
						client.print(",\"Y\":");
						client.print(Y);
						client.print("},\"temp\":");
						client.print(GetTemp(temp),1);
						client.print(",\"light\":");
						client.print(phot);
						client.print(",\"network\":\"");
						client.print(Ethernet.localIP());
						client.print("\",\"file\":[");
						for (int i=0; i<HTTP_FILE; i++) {
							File dFile = SD.open(GET[i]);
							if (dFile) {
								if(i>0) {
									client.print(",");
								}
								client.print("{");
								client.print("\"name\":\"");
								client.print(GET[i]);
								client.print("\",\"size\":");
								client.print(dFile.size());
								client.print("}");
							}
						}
						client.println("]}");
						digitalWrite(redLed,LOW);
					}

					// print other file
					else {
						for(int i=1; i<HTTP_FILE; i++) {
							if (getStr == TYP[0][i]) {
								webFile = SD.open(GET[i]);
								if (webFile) {
									client.println("HTTP/1.1 200 OK");
									client.println(TYP[1][i]);
									if(TYP[2][i] == "1") {
										client.println("Content-Encoding: gzip");
									}
									client.print("Content-Length: ");
									client.println(webFile.size());
									client.println("Cache-Control: max-age=302400, public");
									client.println("Connection: close");
									client.println();
								}
								break;
							}
						}
					}
					// endif check

					// print index.html
					if (indice) {
						webFile = SD.open(GET[0]);
						if (webFile) {
							client.println("HTTP/1.1 200 OK");
							client.println(TYP[1][0]);
							client.print("Content-Length: ");
							client.println(webFile.size());
							client.println("Connection: close");
							client.println();
						}
					}
					// read file and write into web client
					if (webFile) {
						while(webFile.available()) {
							client.write(webFile.read());
						}
						webFile.close();
					}
					
					break;
				}

				if (c == '\n') {
					// last character on line of received text. Starting new line with next character read
					currentLineIsBlank = true;
				} 
				else if (c != '\r') {
					// you've gotten a character on the current line
					currentLineIsBlank = false;
				}
			}
		}
		//delay(1);		// give the web browser time to receive the data
		client.stop();	// close the connection
		digitalWrite(greLed,LOW);
	}
}
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;
}
示例#17
0
void PLabFileServer::cWrite(char chr, EthernetClient &c) {
	if (out)
		out->write(chr);
	c.write(chr);
}
示例#18
0
文件: Twitter.cpp 项目: 0x27/mrw-code
bool
Twitter::post_status(const char *message)
{
  char *cp;
  int i;

  timestamp = get_time();
  create_nonce();

  compute_authorization(message);

  /* Post message to twitter. */

  EthernetClient http;

  if (!http.connect(ip, port))
    {
      println(PSTR("Could not connect to server"));
      return false;
    }

  http_print(&http, PSTR("POST "));

  if (proxy)
    {
      http_print(&http, PSTR("http://"));
      http_print(&http, server);
    }

  http_print(&http, uri);
  http_println(&http, PSTR(" HTTP/1.1"));

  http_print(&http, PSTR("Host: "));
  http_print(&http, server);
  http_newline(&http);

  http_println(&http,
               PSTR("Content-Type: application/x-www-form-urlencoded"));
  http_println(&http, PSTR("Connection: close"));

  /* Authorization header. */
  http_print(&http, PSTR("Authorization: OAuth oauth_consumer_key=\""));

  url_encode_pgm(buffer, consumer_key);
  http.write(buffer);

  http_print(&http, PSTR("\",oauth_signature_method=\"HMAC-SHA1"));
  http_print(&http, PSTR("\",oauth_timestamp=\""));

  sprintf(buffer, "%ld", timestamp);
  http.write(buffer);

  http_print(&http, PSTR("\",oauth_nonce=\""));

  hex_encode(buffer, nonce, sizeof(nonce));
  http.write(buffer);

  http_print(&http, PSTR("\",oauth_version=\"1.0\",oauth_token=\""));

  if (access_token_pgm)
    url_encode_pgm(buffer, access_token.pgm);
  else
    url_encode_eeprom(buffer, access_token.eeprom);

  http.write(buffer);

  http_print(&http, PSTR("\",oauth_signature=\""));

  cp = base64_encode(buffer, signature, HASH_LENGTH);
  url_encode(cp + 1, buffer);

  http.write(cp + 1);

  http_println(&http, PSTR("\""));

  /* Encode content. */
  cp = url_encode(buffer, "status");
  *cp++ = '=';
  cp = url_encode(cp, message);

  int content_length = cp - buffer;
  sprintf(cp + 1, "%d", content_length);

  http_print(&http, PSTR("Content-Length: "));
  http.write(cp + 1);
  http_newline(&http);

  /* Header-body separator. */
  http_newline(&http);

  /* And finally content. */
  http.write(buffer);

  /* Read response status line. */
  if (!read_line(&http, buffer, buffer_len) || buffer[0] == '\0')
    {
      http.stop();
      return false;
    }

  int response_code;

  /* HTTP/1.1 200 Success */
  for (i = 0; buffer[i] && buffer[i] != ' '; i++)
    ;
  if (buffer[i])
    response_code = atoi(buffer + i + 1);
  else
    response_code = 0;

  bool success = (200 <= response_code && response_code < 300);

  if (!success)
    Serial.println(buffer);

  /* Skip header. */
  while (true)
    {
      if (!read_line(&http, buffer, buffer_len))
        {
          http.stop();
          return false;
        }

      if (buffer[0] == '\0')
        break;

      /* Update our system basetime from the response `Date'
         header. */
      process_date_header(buffer);
    }

  /* Handle content. */
  while (http.connected())
    {
      while (http.available() > 0)
        {
          uint8_t byte = http.read();

          if (!success)
            Serial.write(byte);
        }
      delay(100);
    }

  http.stop();

  if (!success)
    println(PSTR(""));

  return success;
}
void Mudbus::Run()
{  
  Runs = 1 + Runs * (Runs < 999);

  //****************** Read from socket ****************
 
  EthernetClient client = MbServer.available();
  if(client.available())
  {
    Reads = 1 + Reads * (Reads < 999);
    int i = 0;
    while(client.available())
    {
      ByteArray[i] = client.read();
      i++;
    }
    SetFC(ByteArray[7]);  //Byte 7 of request is FC
    if(!Active)
    {
      Active = true;
      PreviousActivityTime = millis();
      #ifdef MbDebug
        Serial.println("Mb active");
      #endif
    }
  }
  if(millis() > (PreviousActivityTime + 60000))
  {
    if(Active)
    {
      Active = false;
      #ifdef MbDebug
        Serial.println("Mb not active");
      #endif
    }
  }

  int Start, WordDataLength, ByteDataLength, CoilDataLength, MessageLength;

  //****************** Read Coils **********************
  if(FC == MB_FC_READ_COILS)
  {
    Start = word(ByteArray[8],ByteArray[9]);
    CoilDataLength = word(ByteArray[10],ByteArray[11]);
    ByteDataLength = CoilDataLength / 8;
    if(ByteDataLength * 8 < CoilDataLength) ByteDataLength++;      
    CoilDataLength = ByteDataLength * 8;
    #ifdef MbDebug
      Serial.print(" MB_FC_READ_COILS S=");
      Serial.print(Start);
      Serial.print(" L=");
      Serial.println(CoilDataLength);
    #endif
    ByteArray[5] = ByteDataLength + 3; //Number of bytes after this one.
    ByteArray[8] = ByteDataLength;     //Number of bytes after this one (or number of bytes of data).
    for(int i = 0; i < ByteDataLength ; i++)
    {
      for(int j = 0; j < 8; j++)
      {
        bitWrite(ByteArray[9 + i], j, C[Start + i * 8 + j]);
      }
    }
    MessageLength = ByteDataLength + 9;
    client.write(ByteArray, MessageLength);
    Writes = 1 + Writes * (Writes < 999);
    FC = MB_FC_NONE;
  }

  //****************** Read Registers ******************
  if(FC == MB_FC_READ_REGISTERS)
  {
    Start = word(ByteArray[8],ByteArray[9]);
    WordDataLength = word(ByteArray[10],ByteArray[11]);
    ByteDataLength = WordDataLength * 2;
    #ifdef MbDebug
      Serial.print(" MB_FC_READ_REGISTERS S=");
      Serial.print(Start);
      Serial.print(" L=");
      Serial.println(WordDataLength);
    #endif
    ByteArray[5] = ByteDataLength + 3; //Number of bytes after this one.
    ByteArray[8] = ByteDataLength;     //Number of bytes after this one (or number of bytes of data).
    for(int i = 0; i < WordDataLength; i++)
    {
      ByteArray[ 9 + i * 2] = highByte(R[Start + i]);
      ByteArray[10 + i * 2] =  lowByte(R[Start + i]);
    }
    MessageLength = ByteDataLength + 9;
    client.write(ByteArray, MessageLength);
    Writes = 1 + Writes * (Writes < 999);
    FC = MB_FC_NONE;
  }

  //****************** Write Coil **********************
  if(FC == MB_FC_WRITE_COIL)
  {
    Start = word(ByteArray[8],ByteArray[9]);
    C[Start] = word(ByteArray[10],ByteArray[11]) > 0;
    #ifdef MbDebug
      Serial.print(" MB_FC_WRITE_COIL C");
      Serial.print(Start);
      Serial.print("=");
      Serial.println(C[Start]);
    #endif
    ByteArray[5] = 2; //Number of bytes after this one.
    MessageLength = 8;
    client.write(ByteArray, MessageLength);
    Writes = 1 + Writes * (Writes < 999);
    FC = MB_FC_NONE;
  } 

  //****************** Write Register ******************
  if(FC == MB_FC_WRITE_REGISTER)
  {
    Start = word(ByteArray[8],ByteArray[9]);
    R[Start] = word(ByteArray[10],ByteArray[11]);
    #ifdef MbDebug
      Serial.print(" MB_FC_WRITE_REGISTER R");
      Serial.print(Start);
      Serial.print("=");
      Serial.println(R[Start]);
    #endif
    ByteArray[5] = 6; //Number of bytes after this one.
    MessageLength = 12;
    client.write(ByteArray, MessageLength);
    Writes = 1 + Writes * (Writes < 999);
    FC = MB_FC_NONE;
  }


  //****************** Write Multiple Coils **********************
  //Function codes 15 & 16 by Martin Pettersson http://siamect.com
  if(FC == MB_FC_WRITE_MULTIPLE_COILS)
  {
    Start = word(ByteArray[8],ByteArray[9]);
    CoilDataLength = word(ByteArray[10],ByteArray[11]);
    ByteDataLength = CoilDataLength / 8;
    if(ByteDataLength * 8 < CoilDataLength) ByteDataLength++;
    CoilDataLength = ByteDataLength * 8;
    #ifdef MbDebug
      Serial.print(" MB_FC_WRITE_MULTIPLE_COILS S=");
      Serial.print(Start);
      Serial.print(" L=");
      Serial.println(CoilDataLength);
    #endif
    ByteArray[5] = ByteDataLength + 5; //Number of bytes after this one.
    for(int i = 0; i < ByteDataLength ; i++)
    {
      for(int j = 0; j < 8; j++)
      {
        C[Start + i * 8 + j] = bitRead( ByteArray[13 + i], j);
      }
    }
    MessageLength = 12;
    client.write(ByteArray, MessageLength);
    Writes = 1 + Writes * (Writes < 999);
    FC = MB_FC_NONE;
  }


  //****************** Write Multiple Registers ******************
  //Function codes 15 & 16 by Martin Pettersson http://siamect.com
  if(FC == MB_FC_WRITE_MULTIPLE_REGISTERS)
  {
    Start = word(ByteArray[8],ByteArray[9]);
    WordDataLength = word(ByteArray[10],ByteArray[11]);
    ByteDataLength = WordDataLength * 2;
    #ifdef MbDebug
      Serial.print(" MB_FC_READ_REGISTERS S=");
      Serial.print(Start);
      Serial.print(" L=");
      Serial.println(WordDataLength);
    #endif
    ByteArray[5] = ByteDataLength + 3; //Number of bytes after this one.
    for(int i = 0; i < WordDataLength; i++)
    {
      R[Start + i] =  word(ByteArray[ 13 + i * 2],ByteArray[14 + i * 2]);
    }
    MessageLength = 12;
    client.write(ByteArray, MessageLength);
    Writes = 1 + Writes * (Writes < 999);
    FC = MB_FC_NONE;
  }

  #ifdef MbDebug
    Serial.print("Mb runs: ");
    Serial.print(Runs);
    Serial.print("  reads: ");
    Serial.print(Reads);
    Serial.print("  writes: ");
    Serial.print(Writes);
    Serial.println();
  #endif
}