diff --git a/silecs-communication-cpp/Makefile b/silecs-communication-cpp/Makefile
index 52cd4841a476a55b1363e6582998bdf224a29307..aae655d2fe51bd0923ad68a194c2f4479ffd6a73 100644
--- a/silecs-communication-cpp/Makefile
+++ b/silecs-communication-cpp/Makefile
@@ -33,5 +33,8 @@ COMPILER_FLAGS = -DMAJOR=$(MAJOR) -DMINOR=$(MINOR) -DPATCH=$(PATCH)
 # Comment IN/Out to enable NI-Support
 #COMPILER_FLAGS += -DNI_SUPPORT_ENABLED=TRUE
 
+# Comment IN/Out to enable Modbus-Support
+#COMPILER_FLAGS += -DMODBUS_SUPPORT_ENABLED=TRUE
+
 # Include the generic make file
 include $(COMMON_MAKE_PATH)/Make.generic
\ No newline at end of file
diff --git a/silecs-communication-cpp/Makefile.dep b/silecs-communication-cpp/Makefile.dep
index a0318fd8395f20d30bc860118669f08b8872dc1d..580e172e750328698c70864072fff0d9652f2886 100644
--- a/silecs-communication-cpp/Makefile.dep
+++ b/silecs-communication-cpp/Makefile.dep
@@ -4,6 +4,17 @@ LIBXML_PATH ?= /usr/include/libxml2/
 SNAP7_BASE ?= ../snap7/snap7-full
 BOOST_HOME ?= /opt/gsi/3rdparty/boost/$(BOOST_VERSION)
 
+ifdef MODBUS_SUPPORT_ENABLED
+	MODBUS_VERSION = 3.0.6
+	MODBUS_ROOT=$(RELEASE_LOCATION)/$(CPU)/3rdparty/libmodbus-$(MODBUS_VERSION)
+	MODBUS_SRC=$(MODBUS_ROOT)/src
+	MODBUS_LIB=$(MODBUS_SRC)/.libs
+	MODBUS_RPATH=$(RELEASE_LOCATION)/$(CPU)/3rdparty/libmodbus-$(MODBUS_VERSION)/src/.libs
+endif
+
+ifdef MODBUS_SUPPORT_ENABLED
+	DEPENDENT_COMPILER_OPTIONS += -I$(MODBUS_SRC)
+endif
 DEPENDENT_COMPILER_OPTIONS += -I$(LIBXML_PATH)
 DEPENDENT_COMPILER_OPTIONS += -I$(SNAP7_BASE)/release/Wrappers/c-cpp
 DEPENDENT_COMPILER_OPTIONS += -I$(BOOST_HOME)/include
\ No newline at end of file
diff --git a/silecs-communication-cpp/src/silecs-communication/interface/communication/MBConnection.cpp b/silecs-communication-cpp/src/silecs-communication/interface/communication/MBConnection.cpp
index 5bf337428165e9bdf54137aac98b0d2d703f19a9..1711dfee6a0ef9aad69bd2624ce42bbf4e6cf68a 100644
--- a/silecs-communication-cpp/src/silecs-communication/interface/communication/MBConnection.cpp
+++ b/silecs-communication-cpp/src/silecs-communication/interface/communication/MBConnection.cpp
@@ -12,7 +12,7 @@
 //
 // You should have received a copy of the GNU General Public License
 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
+#ifdef MODBUS_SUPPORT_ENABLED
 #include <silecs-communication/interface/utility/SilecsLog.h>
 #include <silecs-communication/interface/utility/StringUtilities.h>
 #include <silecs-communication/interface/communication/SilecsConnection.h>
@@ -26,6 +26,7 @@ namespace Silecs
 	MBConnection::MBConnection(PLC* thePLC) : Connection(thePLC)
 	{
 		LOG(ALLOC) << "MBConnection (create): " << thePLC->getName();
+		readCtx_ = writeCtx_ = NULL;
 	}
 
 
@@ -39,18 +40,19 @@ namespace Silecs
 	bool MBConnection::open(PLC* thePLC)
 	{
 		//Open read and write Modbus channels (using IP address to limit the naming-server accesses)
-		readCh_  = IeMdbOpen(0, (char *) thePLC->getIPAddress().c_str(), (int)thePLC->getBaseAddress());
-		writeCh_ = IeMdbOpen(0, (char *) thePLC->getIPAddress().c_str(), (int)thePLC->getBaseAddress());
-		return ((readCh_ >= 0) && (writeCh_ >= 0));
+        int readErr  = IeMdbOpen(&readCtx_, NULL, (char *) thePLC->getIPAddress().c_str(), (int)thePLC->getBaseAddress());
+        int writeErr = IeMdbOpen(&writeCtx_, NULL, (char *) thePLC->getIPAddress().c_str(), (int)thePLC->getBaseAddress());
+        return ((readErr == 0) && (writeErr == 0));
 	}
 
 
 	bool MBConnection::close(PLC* thePLC)
 	{
-		int err = 0;
-		err |= IeMdbClose(readCh_);
-		err |= IeMdbClose(writeCh_);
-		return (err == 0);
+        int err = 0;
+        err |= IeMdbClose(readCtx_);
+        err |= IeMdbClose(writeCtx_);
+        readCtx_ = writeCtx_ = NULL;
+        return (err == 0);
 	}
 
 
@@ -78,7 +80,7 @@ namespace Silecs
 			//DATA topic makes sense with RECV one
 			if (RECV & Log::topics_) LOG(DATA) << "Read data, address: %MW" << addr << ", byte-size: " << size;
 
-			int error = IeMBreadData(readCh_, addr, (unsigned short)size, pBuffer);
+            int err = IeMBreadData(readCtx_, addr, (unsigned short)size, pBuffer);
 	        if(error)
 	        	throw SilecsException(__FILE__, __LINE__, UNEXPECTED_ERROR," ModBus Error: " + string(IeGetErrorMessage(error)));
 		}
@@ -111,7 +113,7 @@ namespace Silecs
 			//DATA topic makes sense with SEND one
 			if (SEND & Log::topics_) LOG(DATA) << "Write data, address: %MW" << addr << ", byte-size: " << size;
 
-			int error = IeMBwriteData(writeCh_, (unsigned short)addr, (unsigned short)size, pBuffer);
+			int error = IeMBwriteData(writeCtx_, (unsigned short)addr, (unsigned short)size, pBuffer);
 	        if(error)
 	        	throw SilecsException(__FILE__, __LINE__, UNEXPECTED_ERROR," ModBus Error: " + string(IeGetErrorMessage(error)));
 		}
@@ -119,3 +121,4 @@ namespace Silecs
 	}
 
 } // namespace
+#endif //MODBUS_SUPPORT_ENABLED
diff --git a/silecs-communication-cpp/src/silecs-communication/interface/communication/MBConnection.h b/silecs-communication-cpp/src/silecs-communication/interface/communication/MBConnection.h
index 953cdd8d4c6b86d9bd6fd6bfd6f246fbe94c1900..9ea7f9cf8bebe1ea075d11259121a2cf0112bd8e 100644
--- a/silecs-communication-cpp/src/silecs-communication/interface/communication/MBConnection.h
+++ b/silecs-communication-cpp/src/silecs-communication/interface/communication/MBConnection.h
@@ -12,7 +12,7 @@
 //
 // You should have received a copy of the GNU General Public License
 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
+#ifdef MODBUS_SUPPORT_ENABLED
 #ifndef _MB_CONNECTION_H_
 #define _MB_CONNECTION_H_
 
@@ -22,7 +22,6 @@
 namespace Silecs
 {
 	class PLC;
-	class Connection;
 
 	/*!
 	 * \class MBConnection
@@ -39,6 +38,8 @@ namespace Silecs
  		int writeData(PLC* thePLC, unsigned long address, unsigned long offset, unsigned long size, unsigned char* pBuffer);
 
 	private:
+        modbus_t* readCtx_;
+        modbus_t* writeCtx_;
 		bool open(PLC* thePLC);
 		bool close(PLC* thePLC);
 
@@ -48,3 +49,4 @@ namespace Silecs
 
 #endif // _MB_CONNECTION_H_
 
+#endif //MODBUS_SUPPORT_ENABLED
diff --git a/silecs-communication-cpp/src/silecs-communication/interface/communication/SNAP7Connection.h b/silecs-communication-cpp/src/silecs-communication/interface/communication/SNAP7Connection.h
index 1a86cc943d4a36b6bc29807a24309c38cc409d78..6e156f7cca3a93c330c5bae0126b341ae1c6dcb4 100644
--- a/silecs-communication-cpp/src/silecs-communication/interface/communication/SNAP7Connection.h
+++ b/silecs-communication-cpp/src/silecs-communication/interface/communication/SNAP7Connection.h
@@ -17,12 +17,12 @@
 #define _SNAP7_CONNECTION_H_
 
 #include <silecs-communication/protocol/core/silecs.h>
+#include <silecs-communication/interface/communication/SilecsConnection.h>
 #include <snap7.h>
 
 namespace Silecs
 {
 	class PLC;
-	class Connection;
 
 	/*!
 	 * \class SNAP7Connection
diff --git a/silecs-communication-cpp/src/silecs-communication/interface/communication/SilecsConnection.cpp b/silecs-communication-cpp/src/silecs-communication/interface/communication/SilecsConnection.cpp
index 1cf18425468f6c6b07af9e89784d0896bff537dd..2ba89446a5c4d1e1c54c18f3cff4e565de920cda 100644
--- a/silecs-communication-cpp/src/silecs-communication/interface/communication/SilecsConnection.cpp
+++ b/silecs-communication-cpp/src/silecs-communication/interface/communication/SilecsConnection.cpp
@@ -22,7 +22,6 @@ namespace Silecs
 {
 
 	// static definition
-	bool Connection::isInit_ = false;
 	bool Connection::isAlive_ = false;
 	const unsigned int Connection::numberConn_ = 3;
 
@@ -42,12 +41,6 @@ namespace Silecs
 		timeConn_ = NULL;
 		delayConn_ = UrgentConnection;   //initial reconnection delay
 		remainConn_ = numberConn_; 		 //initial number of attempt
-
-		// Silecs initialization has to be invoked only once per process
-		if (isInit_== false)
-		{	IeInit();
-			isInit_ = true;
-		}
 	}
 
 
@@ -191,7 +184,6 @@ namespace Silecs
 		{
 			if (close(thePLC))
 			{
-			  readCh_ = writeCh_ = 0;
 			  isConnected_ = false;
 
 			  //Connection status has changed: update the diagnostic variables
diff --git a/silecs-communication-cpp/src/silecs-communication/interface/communication/SilecsConnection.h b/silecs-communication-cpp/src/silecs-communication/interface/communication/SilecsConnection.h
index 0cc27ee12f37d9da1e33e31172d4ef4f14200e7c..3c6d04ccb9ec92b839f3c528cdc2f012c7539d71 100644
--- a/silecs-communication-cpp/src/silecs-communication/interface/communication/SilecsConnection.h
+++ b/silecs-communication-cpp/src/silecs-communication/interface/communication/SilecsConnection.h
@@ -147,10 +147,6 @@ namespace Silecs
 	 	// flag used to enable/disable the transactions independently from the scheduling
 		bool isEnabled_;
 
-		// Silecs descriptor for send/recv channels
-		ChannelID readCh_;
-		ChannelID writeCh_;
-
 		/* . read-channel and write channel are independent and can be accessed in parallel.
 		 * . Each channel must be protected against respective concurrent access.
 		 * . The global action (open,close,etc.) must be protected from any concurrent access.
@@ -169,9 +165,6 @@ namespace Silecs
 		static bool isAlive_; // PLC has repliyed to the ping: true/false
 		bool isConnected_; // State of this particular connection: FEC/PLC/Class
 
-		// Silecs initialization has to be invoked only once per process
-		static bool isInit_;
-
 		// not copyable object
 		Connection(const Connection&);
 		Connection& operator=(const Connection&);
diff --git a/silecs-communication-cpp/src/silecs-communication/interface/equipment/PLCRegister.cpp b/silecs-communication-cpp/src/silecs-communication/interface/equipment/PLCRegister.cpp
index d4773eb52c16d1fb381327cbb42aca53b7d035f3..e94d7956bd781dbe3c1d8e3b57d5c46811b31db8 100644
--- a/silecs-communication-cpp/src/silecs-communication/interface/equipment/PLCRegister.cpp
+++ b/silecs-communication-cpp/src/silecs-communication/interface/equipment/PLCRegister.cpp
@@ -294,7 +294,9 @@ namespace Silecs
                                 break;
                             case Schneider:
                             case Digi:
+#ifdef MODBUS_SUPPORT_ENABLED
                                 ((double *)pRecvValue_)[i*dimension2_+j] = IeMdbGetTime(pData);
+#endif //MODBUS_SUPPORT_ENABLED
                                 break;
                             case Ni:
                                 //TODO
@@ -372,7 +374,9 @@ namespace Silecs
                             break;
                         case Schneider:
                         case Digi:
+#ifdef MODBUS_SUPPORT_ENABLED
                             IeMdbSetTime(pData, epoch);
+#endif //MODBUS_SUPPORT_ENABLED
                             break;
                         case Ni:
                             //TODO
diff --git a/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsPLC.cpp b/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsPLC.cpp
index d7808c453ae07b04a76ad7d10b3a09cf086b77b0..acd4e217c7650ddad5de5edbf6348b0392486be6 100644
--- a/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsPLC.cpp
+++ b/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsPLC.cpp
@@ -450,7 +450,9 @@ namespace Silecs
                     case S7Protocol:
                         theConn = new SNAP7Connection(this); break;
                     case MBProtocol:
+#ifdef MODBUS_SUPPORT_ENABLED
                         theConn = new MBConnection(this); break;
+#endif
                     case CNVProtocol:
 #ifdef NI_SUPPORT_ENABLED
                     	theConn = new CNVConnection(this);break;
diff --git a/silecs-communication-cpp/src/silecs-communication/protocol/core/silecs.cpp b/silecs-communication-cpp/src/silecs-communication/protocol/core/silecs.cpp
index def46b4105ec9ae7d223b18e473354dbc523544d..bf98923c37f4825e417fb27987c2911226cb3ebe 100644
--- a/silecs-communication-cpp/src/silecs-communication/protocol/core/silecs.cpp
+++ b/silecs-communication-cpp/src/silecs-communication/protocol/core/silecs.cpp
@@ -39,10 +39,6 @@
 
 #include <silecs-communication/protocol/core/silecs.h>
 
-#ifdef __cplusplus
-extern "C" {
-#endif
-
 /* ---------------------------------------------------------*/
 /* MACRO DEFINITION																				  */
 /* ---------------------------------------------------------*/
@@ -321,40 +317,3 @@ char *IeGetErrorMessage(int err)
 
   return ("Unknown IE error");
 }
-
-/*----------------------------------------------------------*/
-/* This function initializes the DSC-PLC communication.
- * return 0 or <0 on error (see constant error)
- *
- * Details:
- * Must be executed at first.
- */
-int IeInit (void)
-{
-  int err=0;
-
-  err |= IeMdbInit();
-
-  return (err);
-}
-
-/*----------------------------------------------------------*/
-/* This function de-initializes the DSC-PLC communication.
- * return 0 or <0 on error (see constant error)
- *
- * Details:
- * Must be executed at end.
- */
-int IeExit (void)
-{
-  int err=0;
-
-  err |= IeMdbExit();
-
-  return (err);
-}
-
-#ifdef __cplusplus
-}
-#endif
-
diff --git a/silecs-communication-cpp/src/silecs-communication/protocol/core/silecs.h b/silecs-communication-cpp/src/silecs-communication/protocol/core/silecs.h
index 782495b2baea04d37276163140d6428c6daad085..2edf5b1665b94f81189b7c03384814c6d9fdd14c 100644
--- a/silecs-communication-cpp/src/silecs-communication/protocol/core/silecs.h
+++ b/silecs-communication-cpp/src/silecs-communication/protocol/core/silecs.h
@@ -33,10 +33,6 @@
  *
  */
 
-#ifdef __cplusplus
-extern "C" {
-#endif
-
 /* ---------------------------------------------------------*/
 /* INCLUDE FILES																						*/
 /* ---------------------------------------------------------*/
@@ -45,7 +41,7 @@ extern "C" {
 /* ---------------------------------------------------------*/
 /* PROTOTYPE DEFINITIONS                                    */
 /* ---------------------------------------------------------*/
-#include <silecs-communication/protocol/modbus/iemdb.h>  /* modbus interface  */
+#include <silecs-communication/protocol/modbus/iemdb.h>
 
 /*----------------------------------------------------------*/
 /* Time funtion
@@ -89,26 +85,4 @@ int IeRfcPing (char *hostName, char *plcIP);
  */
 char *IeGetErrorMessage(int err);
 
-/*----------------------------------------------------------*/
-/* This function initializes the DSC-PLC communication.
- * return 0 or <0 on error (see constant error)
- *
- * Details:
- * Must be executed at first.
- */
-int IeInit (void);
-
-/*----------------------------------------------------------*/
-/* This function initializes the DSC-PLC communication.
- * return 0 or <0 on error (see constant error)
- *
- * Details:
- * Must be executed at end.
- */
-int IeExit (void);
-
-#ifdef __cplusplus
-}
-#endif
-
 #endif /* _SILECS_H_ */
diff --git a/silecs-communication-cpp/src/silecs-communication/protocol/modbus/iemdb.cpp b/silecs-communication-cpp/src/silecs-communication/protocol/modbus/iemdb.cpp
index 94a55b1c559895c45034b8bbaec2001c330a616d..0ae7c925704e420522bcefe7366986a4355b2ea8 100644
--- a/silecs-communication-cpp/src/silecs-communication/protocol/modbus/iemdb.cpp
+++ b/silecs-communication-cpp/src/silecs-communication/protocol/modbus/iemdb.cpp
@@ -1,128 +1,12 @@
-// Copyright 2016 CERN and GSI
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-/*
- * Revision : v1.0
- * Date     : 08/2003 - F.Locci
- * Objet    : original version for PS7-SCHNEIDER PLC
- * Action   :
- *
- * Revision : v1.1
- * Date     : 05/2004 - F.Locci
- * Objet    : .remove when data size = 0
- *			  .set err on read/write error
- *            Look at v1.1 comments
- *
- * Revision : v1.2
- * Date     : 11/2004 - F.Locci
- * Objet    : .move mb_master_init() call to IeMdbInit() function
- *            to make modbus code reentrant.
- *            Look at v1.2 comments
- *
- * Revision : v1.3
- * Date     : 10/2004 - F.Locci
- * Objet    : .Allow absolute offset for read/write action
- *			  .Allow variable size for read/write action
- *            => use offset sign convention for absolute/relative
- *            => use application size instead of config.table one
- *            Look at v1.3 comments
- *
- * Revision : v1.4
- * Date     : 03/2006 - F.Locci
- * Objet    : .Extend the number of possible connection (7 --> 32)
- *			  in order to allow more than 7 connections with
- *            DIFFERENT PLC (SPS/EA project in particular).
- *            We keep 7 connection  for SIEMENS (F/W) protocole
- *            to respect material constraint (14 ISO-ON-TCP max.)
- *
- * Revision : v1.5
- * Date     : 01/2007 - F.Locci
- * Objet    : implement BLOCK mode
- * Action   : .Add IeMdbGetBlock() and IeMdbSetBlock() function
- *            .Upgrade mdbFindEqp() function
- *            Look at v1.5 comments
- *
- * Revision : v1.6
- * Date     : 03/2007 - F.Locci
- * Objet    : Protect Get data buffer overflow
- *            Look at v1.5 comments
- *
- * Revision : v1.7
- * Date     : 04/2007 - F.Locci
- * Objet    : Direct byte swapping into MdbSetTime function
- *            Look at v1.5 comments
- */
-
-/*
- * This library was developped to provide communication between
- * Linux/LynxOS active host (client) and a PLC passive server.
- * Based on MODBUS std. protocole, it defines generic
- * set and get functions to read and write data into/from PLC
- * memory.
- */
-
-/* ---------------------------------------------------------*/
-/* INCLUDE FILES																						*/
-/* ---------------------------------------------------------*/
-#include <silecs-communication/protocol/core/ietype.h>
-#include "mb_addr.h"
-#include "mb_master.h"
+#ifdef MODBUS_SUPPORT_ENABLED
+#include "iemdb.h"
 
-#ifdef __cplusplus
-extern "C" {
-#endif
+//Modbus max data size definition (byte counting)
+#define MAX_WRITE_DATA_SIZE MODBUS_MAX_WRITE_REGISTERS*2
+#define MAX_READ_DATA_SIZE  MODBUS_MAX_READ_REGISTERS*2
 
 /* ---------------------------------------------------------*/
-/* LOCAL CONSTANT DEFINITIONS																*/
-/* ---------------------------------------------------------*/
-
-/* For Modbus protocol */
-#define MODBUS_MAX_CONNECTION    64 /*v1.4*/
-#define MODBUS_SENDRETRIES_DEF   1
-#define MODBUS_TIMEOUT_DEF       2    /* in seconds */
-
-/*Config.Table entries offset - SCHNEIDER memory implementation - word alignment*/
-#define FEC_CMD_OFS	      0    	/* Command from FEC: first entry of cfg.table*/
-#define PARAMS_CMD_OFS	  2/2   /* Params of FEC command 		*/
-#define CURRENT_DATE_OFS  10/2  /* PLC current dat&time */
-#define SYS_INFO_OFS	  18/2  /* HW/SW info variables */
-#define DIAG_INFO_OFS     78/2  /* PLC SW/HW diagnostic */
-#define NB_EQP_OFS  	  132/2  /*nb table row */
-#define ADDR_TBL_OFS  	  134/2  /*table data (addr/size)*/
-
-#define swap16(w) ((((unsigned short)w & 0x00ff)<<8)+(((unsigned short)w & 0xff00)>>8))
-
-/* ---------------------------------------------------------*/
-/* TYPE DEFINITIONS					  															*/
-/* ---------------------------------------------------------*/
-/* an entry in the network array */
-typedef struct
-{
-	const char      *name;
-	node_addr_t     addr;
-	int             nd; /* the node descriptor... */
-	struct timespec timeout;
-	u32				send_retries;
-} network_t;
-
-/* ---------------------------------------------------------*/
-/* GLOBAL DECLARATIONS																			*/
-/* ---------------------------------------------------------*/
-
-/* ---------------------------------------------------------*/
-/* FUNCTIONS CODE																						*/
+/* FUNCTIONS CODE											*/
 /* ---------------------------------------------------------*/
 
 /*----------------------------------------------------------*/
@@ -225,41 +109,6 @@ double IeMdbGetTime(unsigned char *dt) // from PLC
   return((double)plctm + ms);
 }
 
-/*----------------------------------------------------------*/
-/* This function initializes the DSC-PLC communication.
- * return 0 or <0 on error (see constant error)
- *
- * Details:
- * Must be executed at first.
- */
-int IeMdbInit (void)
-{
-  /*v1.2*/
-  if (mb_master_init(MODBUS_MAX_CONNECTION) < 0)
-  {
-  #ifdef DEBUG
-    /* could not init network! */
-  	printf("\n#Error: mb_master_init() failed");
-  #endif
-    return (IE_SYS_ERROR);
-  }
-
-  return 0;
-}
-
-/*----------------------------------------------------------*/
-/* This function de-initializes the DSC-PLC communication.
- * return 0 or <0 on error (see constant error)
- *
- * Details:
- * Must be executed at end.
- */
-int IeMdbExit (void)
-{
-  mb_master_done();
-  return 0;
-}
-
 /*----------------------------------------------------------*/
 /* This function creates a synchronous OSI-ON-TCP socket
  * channel used for sending/receiving communication with PLC.
@@ -272,150 +121,20 @@ int IeMdbExit (void)
  * Only one synchronous channel per PLC at the same time
  * supported in that version.
  */
-int IeMdbOpen (char *hostName, char *plcIP, int baseAddress)
+int IeMdbOpen (modbus_t** ctx, char *hostName, char *plcIP, int baseAddress)
 {
-  network_t net;
-  char *ipstr = plcIP;
-  _WORD dummy;
-
-  // use hostName reference in priority else plcIP
-  if (hostName) ipstr = hostName;
+  *ctx = modbus_new_tcp(plcIP, MODBUS_TCP_DEFAULT_PORT /*=502*/);
+  //modbus_set_debug(*ctx, TRUE);
 
-  if (ipstr == NULL)
+  if (modbus_connect(*ctx) == -1)
   {
-    printf("#Error: ipstr NULL\n");
-	return(IE_PARAM_ERROR);
+      modbus_free(*ctx);
+      return IE_CONNECT_ERROR;
   }
 
-  /* init network .........................................*/
-  /*net.name				= not used here*/
-  net.addr.naf 				= naf_tcp;
-  net.addr.addr.tcp.host	= ipstr;
-  net.addr.addr.tcp.service = "502";       //specific modbus
-  net.addr.addr.tcp.close_on_silence = 1;  // TRUE
-  net.timeout       		= d_to_timespec(MODBUS_TIMEOUT_DEF);
-  net.send_retries  		= MODBUS_SENDRETRIES_DEF;
-
-  /* connection ......................................*/
-  if ( (net.nd = mb_master_connect(net.addr)) >= 0)
-  {
-	  /*Try to access PLC memory, just to confirm modbus connection (for example,
-		read config. table address.
-	  */
-  	  if (read_bdata(
-					1,					/*int slave,*/
-					baseAddress/2,	    /*int start_addr (/2 is used to convert the byte alignment to 16bit alignment) */
-					sizeof(dummy),		/*int byte count,*/
-					(_BYTE *)&dummy,	/*uchar *dest,*/
-					net.nd,				/*int ttyfd,*/
-					net.send_retries,	/*int send_retries,*/
-					&net.timeout		/*const struct timespec *response_timeout*/
-				) >= 0)
-	  {
-    	/* node opened successfully! */
-		#ifdef DEBUG
-    	printf("Connecting to network %s: OK\n", net.addr.addr.tcp.host);
-		#endif
-
-		return (net.nd);
-	  }
-	  #ifdef DEBUG
-	  else
-	  {
-    	/* could not read registers from slave! */
-    	printf("#Error: could not establish connection to %s\n", net.addr.addr.tcp.host);
-	  }
-	  #endif
-
-  	  mb_master_close(net.nd);
-  }
-  #ifdef DEBUG
-  else
-  {
-    /* could not connect to slave! */
-    printf("#Error: could not establish connection to %s\n", net.addr.addr.tcp.host);
-  }
-  #endif
-
-  return(IE_CONNECT_ERROR);
+  return 0;
 }
 
-/*----------------------------------------------------------*/
-int IeMBwriteData(int cid, _WORD dataOfs, _WORD dataSize, _BYTE* dataBuffer)
-{
-  int err;
-  network_t net;
-
-  /* init network .........................................*/
-  net.timeout       = d_to_timespec(MODBUS_TIMEOUT_DEF);
-  net.send_retries  = MODBUS_SENDRETRIES_DEF;
-
-  /*then SET&DATE cmd into command word*/
-  if (write_bdata(1,				/*int slave,*/
-				  dataOfs,			/*int start_addr (!16 bits alignment)*/
-				  dataSize,	        /*int byte count */
-				  dataBuffer,	    /*uchar *src */
-				  cid,	    		/*int connection id */
-				  net.send_retries,	/*int send_retries,*/
-				  &net.timeout		/*const struct timespec *response_timeout*/
-				  ) >= 0)
-  {
-	#ifdef DEBUG
-	printf("IeMBwriteData has been done successfully\n");
-	#endif
-	err = 0; /*no problem*/
-  }
-  else
-  {
-	#ifdef DEBUG
-	  printf("#Error on IeMBwriteData\n");
-	#endif
-	err = IE_EPIPE_ERROR;
-  }
-
-  return err;
-}
-
-/*----------------------------------------------------------*/
-int IeMBreadData(int cid, _WORD dataOfs, _WORD dataSize, _BYTE* dataBuffer)
-{
-  int err;
-  network_t net;
-
-  /* init network .........................................*/
-  net.timeout       = d_to_timespec(MODBUS_TIMEOUT_DEF);
-  net.send_retries  = MODBUS_SENDRETRIES_DEF;
-
-  /*unusefull to read empty data buffer*/
-  if (dataSize > 0)
-  {
-	 err = read_bdata(1,				/*int slave,*/
-					  dataOfs,			/*int start_addr (!16 bits alignment)*/
-					  dataSize,	        /*int byte count */
-					  dataBuffer,	    /*uchar *src */
-					  cid,	    		/*int connection id */
-				      net.send_retries,	/*int send_retries,*/
-				      &net.timeout		/*const struct timespec *response_timeout*/
-				      );
-  }
-
-  if ((dataSize == 0) || (err >= 0))
-  {
-	#ifdef DEBUG
-	printf("IeMBreadData has been done successfully\n");
-	#endif
-	err = 0; /*no problem*/
-  }
-  else
-  {
-	#ifdef DEBUG
-	  printf("#Error on IeMBreadData\n");
-	#endif
-	err = IE_EPIPE_ERROR;
-  }
-
-  return err;
-}
 
 /*----------------------------------------------------------*/
 /* This function closes the synchronous OSI-ON-TCP socket
@@ -425,17 +144,72 @@ int IeMBreadData(int cid, _WORD dataOfs, _WORD dataSize, _BYTE* dataBuffer)
  *
  * Details:
  */
-int IeMdbClose(int cid)
+int IeMdbClose(modbus_t* ctx)
 {
-  int err = 0;
+  /* Close the connection */
+  modbus_close(ctx);
+  modbus_free(ctx);
 
-  err |= mb_master_close(cid);
-
-  if (err != 0) err = IE_DISCONNECT_ERROR;
-  return(err);
+  return 0;
 }
 
-#ifdef __cplusplus
+/*----------------------------------------------------------*/
+int IeMBwriteData(modbus_t* ctx, uint16_t start_addr, uint16_t count, uint8_t* data)
+{
+    uint16_t *srcp = (uint16_t*)data;
+    int word_count, byte_count;
+
+    while(count)
+    {
+        word_count = (count > MAX_WRITE_DATA_SIZE) ? MAX_WRITE_DATA_SIZE/2 : (count/2)+(count%2);
+        byte_count = (word_count * 2);
+
+        if (modbus_write_registers(ctx, start_addr, word_count, srcp) != word_count)
+        {
+            return IE_EPIPE_ERROR;
+        }
+
+        //srcp += byte_count-(count%2);
+        srcp += word_count;
+        start_addr += word_count;
+        count -= (byte_count - (count%2));
+    }
+
+    return 0;
 }
-#endif
 
+/*----------------------------------------------------------*/
+int IeMBreadData(modbus_t* ctx, uint16_t start_addr, uint16_t count, uint8_t* data)
+{
+  uint16_t *destp = (uint16_t*)data;
+  int word_count, byte_count;
+
+  while(count) {
+
+      if (count > MAX_READ_DATA_SIZE)
+      {
+         /*'word_count' is a word counter*/
+         word_count = MAX_READ_DATA_SIZE/2;
+      }
+      else
+      {
+        /*'word_count' is a word counter*/
+        word_count = (count/2) + (count%2);
+      }
+
+      byte_count = (word_count * 2);
+
+      if (modbus_read_registers(ctx, start_addr, word_count, destp) != word_count)
+      {
+          return IE_EPIPE_ERROR;
+      }
+
+      //destp += (byte_count-(count%2));
+      destp += word_count;
+      start_addr += word_count;
+      count -= (byte_count - (count%2));
+  }
+
+  return 0;
+}
+#endif //MODBUS_SUPPORT_ENABLED
diff --git a/silecs-communication-cpp/src/silecs-communication/protocol/modbus/iemdb.h b/silecs-communication-cpp/src/silecs-communication/protocol/modbus/iemdb.h
index 8a055c727d0b3eb87ff1f8bd142658c962c8f2bc..6fcc3cea5e933a835e83bb2b1e47dbb57807bb47 100644
--- a/silecs-communication-cpp/src/silecs-communication/protocol/modbus/iemdb.h
+++ b/silecs-communication-cpp/src/silecs-communication/protocol/modbus/iemdb.h
@@ -1,58 +1,9 @@
-// Copyright 2016 CERN and GSI
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-/*
- * Revision : v1.0
- * Date     : 08/2003 - F.Locci
- * Objet    : original version for PS7-SCHNEIDER PLC
- * Action   : 
- *
- * Revision : v1.5
- * Date     : 01/2007 - F.Locci
- * Objet    : implement BLOCK mode
- * Action   : Add IeMdbGetBlock() and IeMdbSetBlock() function 
- *            Look at v1.5 comments
- *
- */
-
+#ifdef MODBUS_SUPPORT_ENABLED
 #ifndef _IEMDB_H_
 #define _IEMDB_H_
 
-/*
- * This library was developped to provide communication between 
- * Linux/LynxOS active host (client) and a PLC passive server. 
- * Based on MODBUS std. protocole, it defines generic
- * set and get functions to read and write data into/from PLC 
- * memory.
-  */
-
-/* ---------------------------------------------------------*/
-/* LOCAL CONSTANT DEFINITIONS                               */
-/* ---------------------------------------------------------*/
-
-/* ---------------------------------------------------------*/
-/* TYPE DEFINITIONS                                         */
-/* ---------------------------------------------------------*/
-
-/* ---------------------------------------------------------*/
-/* PROTOTYPE DEFINITIONS                                    */
-/* ---------------------------------------------------------*/
-
-#ifdef __cplusplus
-extern "C" {
-#endif
+#include <silecs-communication/protocol/core/ietype.h>
+#include <modbus.h>
 
 /*----------------------------------------------------------*/
 /* Time funtion
@@ -64,7 +15,7 @@ extern "C" {
  * format:
  *
  *  0      1      2      3      4      5     6     7 
- *  SC     --     HH     MN     MM     DD    YY	   YY
+ *  SC     --     HH     MN     MM     DD    YY    YY
  *
  *  byte 1 is used by gateway to synchronize time setting.
  */
@@ -80,29 +31,11 @@ void IeMdbSetTime(unsigned char *dt, time_t epoch);  // to PLC
  * format:
  *
  *  0      1        2      3      4      5     6     7 
- *  SC     SC/100   HH     MN     MM     DD    YY	 YY
+ *  SC     SC/100   HH     MN     MM     DD    YY    YY
  *
  */
 double IeMdbGetTime(unsigned char *dt); // from PLC
 
-/*----------------------------------------------------------*/
-/* This function initializes the DSC-PLC communication.
- * return 0 or <0 on error (see constant error)
- *
- * Details:
- * Must be executed at first.
- */
-int IeMdbInit (void);
-
-/*----------------------------------------------------------*/
-/* This function initializes the DSC-PLC communication.
- * return 0 or <0 on error (see constant error)
- *
- * Details:
- * Must be executed at end.
- */
-int IeMdbExit (void);
-
 /*----------------------------------------------------------*/
 /* This function creates a synchronous OSI-ON-TCP socket 
  * channel used for sending/receiving communication with PLC.
@@ -115,29 +48,29 @@ int IeMdbExit (void);
  * Only one synchronous channel per PLC at the same time 
  * supported in that version.
  */
-int IeMdbOpen (char *hostName, char *plcIP, int baseAddress);
+int IeMdbOpen (modbus_t** ctx, char *hostName, char *plcIP, int baseAddress);
 
 /*----------------------------------------------------------*/
 /* This function send a data segment to the PLC using the
  * MODBUS protocole.
- * 'cid': write channel id of the MB connection
- * 'dataOfs': target adress of the data segment within the PLC memory
+ * 'ctx': write channel id of the MB connection
+ * 'dataAddr': target address of the data segment within the PLC memory
  * 'dataSize': byte size of the data segment to be sent
  * 'dataBuffer': buffer of the data to be sent
  * return 0 or <0 on error (see constant error)
  */
-int IeMBwriteData(int cid, _WORD dataOfs, _WORD dataSize, _BYTE* dataBuffer);
+int IeMBwriteData(modbus_t* ctx, uint16_t dataAddr, uint16_t dataSize, uint8_t* dataBuffer);
 
 /*----------------------------------------------------------*/
 /* This function read a data segment from the PLC using the
  * MODBUS protocole.
- * 'cid': read channel id of the MB connection
- * 'dataOfs': adress of the data segment within the PLC memory
+ * 'ctx': read channel id of the MB connection
+ * 'dataAddr': address of the data segment within the PLC memory
  * 'dataSize': byte size of the data segment to be read
  * 'dataBuffer': buffer to store the data
  * return 0 or <0 on error (see constant error)
  */
-int IeMBreadData(int cid, _WORD dataOfs, _WORD dataSize, _BYTE* dataBuffer);
+int IeMBreadData(modbus_t* ctx, uint16_t dataAddr, uint16_t dataSize, uint8_t* dataBuffer);
 
 /*----------------------------------------------------------*/
 /* This function closes the synchronous OSI-ON-TCP socket 
@@ -147,10 +80,7 @@ int IeMBreadData(int cid, _WORD dataOfs, _WORD dataSize, _BYTE* dataBuffer);
  *
  * Details:
  */
-int IeMdbClose(int cid);
-
-#ifdef __cplusplus
-}
-#endif
+int IeMdbClose(modbus_t* ctx);
 
 #endif /* _IEMDB_H_ */
+#endif //MODBUS_SUPPORT_ENABLED
diff --git a/silecs-communication-cpp/src/silecs-communication/protocol/modbus/mb_addr.h b/silecs-communication-cpp/src/silecs-communication/protocol/modbus/mb_addr.h
deleted file mode 100644
index 353639638d859a159680a1a6dcdc310c448b9dec..0000000000000000000000000000000000000000
--- a/silecs-communication-cpp/src/silecs-communication/protocol/modbus/mb_addr.h
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * (c) 2002 Mario de Sousa
- *
- * Offered to the public under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
- * Public License for more details.
- *
- * This code is made available on the understanding that it will not be
- * used in safety-critical situations without a full and competent review.
- */
-
-
-#ifndef MODBUS_LAYER2_H
-#define MODBUS_LAYER2_H
-
-/*F.Locci #include <plc.h>*/  /* get the plc data types */
-#include <time.h> /* struct timespec data type */
-
-/*F.Locci - 28/10/2003*/
-/*types only defined with linux version: <asm/types.h>*/
-#ifndef __Lynx__
-#include <asm/types.h>
-
-typedef unsigned char u8;
-typedef unsigned short u16;
-typedef unsigned int u32;
-
-#else
-
-typedef unsigned char u8;
-typedef unsigned short u16;
-typedef unsigned int u32;
-
-#ifndef __ppc4__ /*new <socket.h> with ppc4 environment*/
-/*F.Locci - 03/11/2004, add x86 platform support*/
-#ifndef __x86__
-typedef unsigned short int sa_family_t;
-
-/* The following constants should be used for the second parameter of
-   `shutdown'.  */
-enum
-{
-  SHUT_RD = 0,		/* No more receptions.  */
-#define SHUT_RD		SHUT_RD
-  SHUT_WR,		/* No more transmissions.  */
-#define SHUT_WR		SHUT_WR
-  SHUT_RDWR		/* No more receptions or transmissions.  */
-#define SHUT_RDWR	SHUT_RDWR
-};
-#endif
-#endif
-
-/*constant conversion for LynxOS*/
-#define AF_ROSE 11
-#define AF_X25  9
-#define AF_AX25 3
-#define SOL_TCP 6
-#define SOL_IP  0
-#endif
-
-typedef enum {optimize_speed, optimize_size} optimization_t;
-
-
-typedef enum {
-        naf_ascii,
-        naf_rtu,
-        naf_tcp,
-  } node_addr_family_t;
-
-typedef struct {
-        const char *host;
-        const char *service;
-        int         close_on_silence;  
-  } node_addr_tcp_t;
-
-typedef struct {
-        const char *device;
-        int         baud;       /* plain baud rate, eg 2400; zero for the default 9600 */
-        int         parity;     /* 0 for none, 1 for odd, 2 for even                   */
-        int         data_bits;
-        int         stop_bits;
-        int         ignore_echo; /* 1 => ignore echo; 0 => do not ignore echo */
-  } node_addr_rtu_t;
-
-typedef node_addr_rtu_t node_addr_ascii_t;
-
-typedef union {
-        node_addr_ascii_t ascii;
-        node_addr_rtu_t   rtu;
-        node_addr_tcp_t   tcp;
-  } node_addr_common_t;
-
-typedef struct {
-        node_addr_family_t  naf;
-        node_addr_common_t  addr;
-  } node_addr_t;
-
-#endif  /* MODBUS_LAYER2_H */
-
-
-
-
-
-
-
-
diff --git a/silecs-communication-cpp/src/silecs-communication/protocol/modbus/mb_layer1.h b/silecs-communication-cpp/src/silecs-communication/protocol/modbus/mb_layer1.h
deleted file mode 100644
index 9a335086ee36b44c6dc794a06c0608d095d66722..0000000000000000000000000000000000000000
--- a/silecs-communication-cpp/src/silecs-communication/protocol/modbus/mb_layer1.h
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * (c) 2001 Mario de Sousa
- *
- * Offered to the public under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
- * Public License for more details.
- *
- * This code is made available on the understanding that it will not be
- * used in safety-critical situations without a full and competent review.
- *
- * Revision : v1.0
- * Date     : 11/2004 - F.Locci
- * Objet    : move global recv_buf_ to local one into read/write_bdata()
- *            to make module reentrant.
- *            Look at v1.0 comment
- */
-
-
-#ifndef MODBUS_LAYER1_H
-#define MODBUS_LAYER1_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*F.Locci #include <plc.h>*/  /* get the plc data types */
-#include <time.h> /* struct timespec data type */
-
-#include "mb_addr.h" /* get definitions of common variable types */
-
-
- /* write a modbus frame */
- /* WARNING: when calling this functio, the *frame_data buffer
-  *          must be allocated with an extra *extra_bytes
-  *          beyond those required for the frame_length.
-  *          This is because the extra bytes will be used
-  *          to store the crc before sending the frame.
-  *
-  *          The *extra_bytes value will be returned by the
-  *          modbus_init() function call.
-  */
- /* NOTE: calling this function will flush the input stream,
-  *       which means any frames that may have arrived
-  *       but have not yet been read using modbus_read()
-  *       will be permanently lost...
-  */
-int modbus_write(int    nd,
-                 u8    *frame_data,
-                 size_t frame_length,
-                 u16    transaction_id);
-
- /* read a modbus frame */
- /* NOTE: calling modbus_write() will flush the input stream,
-  *       which means any frames that may have arrived
-  *       but have not yet been read using modbus_read()
-  *       will be permanently lost...
-  *
-  * NOTE: Ususal select semantics for (a: recv_timeout == NULL) and
-  *       (b: *recv_timeout == 0) also apply.
-  *
-  *       (a) Indefinite timeout
-  *       (b) Try once, and and quit if no data available.
-  */
-int modbus_read(int *nd,                /* node descriptor */
-                u8 *recv_data_ptr/*v1.0*/,
-                u16 *transaction_id,
-                u8 *send_data,         /* ignored ! */
-                int send_length,       /* ignored ! */
-                const struct timespec *recv_timeout);
-
-
- /* init the library */
-int modbus_init(int nd_count,        /* maximum number of nodes... */
-                optimization_t opt,
-                int *extra_bytes);
-
- /* shutdown the library...*/
-int modbus_done(void);
-
-
-/* Open a node for master / slave operation.
- * Returns the node descriptor, or -1 on error.
- */
-int modbus_connect(node_addr_t node_addr);
-int modbus_listen(node_addr_t node_addr);
-
-/* Close a node, needs a node descriptor as argument... */
-int modbus_close(int nd);
-
-/* Tell the library that the user will probably not be communicating
- * for some time...
- * This will allow the library to release any resources it will not
- * be needing during the silence.
- * NOTE: This is onlyused by the TCP version to close down tcp connections
- *       when the silence will going to be longer than  second.
- */
-int modbus_silence_init(void);
-
- /* determine the minmum acceptable timeout... */
- /* NOTE: timeout values passed to modbus_read() lower than the value returned
-  *       by this function may result in frames being aborted midway, since they
-  *       take at least modbus_get_min_timeout() seconds to transmit.
-  */
-double modbus_get_min_timeout(int baud,
-                              int parity,
-                              int data_bits,
-                              int stop_bits);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif  /* MODBUS_LAYER1_H */
-
-
-
-
-
-
-
-
diff --git a/silecs-communication-cpp/src/silecs-communication/protocol/modbus/mb_master.cpp b/silecs-communication-cpp/src/silecs-communication/protocol/modbus/mb_master.cpp
deleted file mode 100644
index e4436018cebf12f1ccd478f9aef63cfc5a3e501b..0000000000000000000000000000000000000000
--- a/silecs-communication-cpp/src/silecs-communication/protocol/modbus/mb_master.cpp
+++ /dev/null
@@ -1,483 +0,0 @@
-/* mb_master.c
-
-   By P.Costigan email: phil@pcscada.com.au http://pcscada.com.au
-
-   These library of functions are designed to enable a program send and
-   receive data from a device that communicates using the Modbus protocol.
-
-   Copyright (C) 2000 Philip Costigan  P.C. SCADA LINK PTY. LTD.
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
-   (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-
-   The functions included here have been derived from the
-   Modicon Modbus Protocol Reference Guide
-   which can be obtained from Schneider at www.schneiderautomation.com.
-
-   This code has its origins with
-   paul@pmcrae.freeserve.co.uk (http://www.pmcrae.freeserve.co.uk)
-   who wrote a small program to read 100 registers from a modbus slave.
-
-   I have used his code as a catalist to produce this more functional set
-   of functions. Thanks paul.
-
-
-
-   10/2001 - Mario de Sousa
-		Slightly re-organized the code.
-                Miscelaneous cleanups
-                Removed layer1 functions (i.e. write and read to /dev/ttySx)
-                Added support for transaction id
-
-                TODO
-                add retries at layer2 (i.e. in this file)
-                check response frame for correctness
-*
-*
-* Revision : v1.0
-* Date     : 11/2004 - F.Locci
-* Objet    : .remove static prefix into modbus_tcp_write() declaration 
-*            to make code reentrant.
-*           .move global recv_buf_ to local one into read/write_bdata()
-*            Look at v1.0 comments
-*
-* Revision : v2.0
-* Date     : 11/2006 - F.Locci
-* Objet    : swap16 bits from SILECS client instead of application level
-*            Look at v2.0 comments
-*/
-
-#include <fcntl.h>	/* File control definitions */
-#include <stdio.h>	/* Standard input/output */
-#include <string.h>
-#include <stdlib.h>
-#include <termio.h>	/* POSIX terminal control definitions */
-#include <time.h>	/* Time structures for select() */
-#include <unistd.h>	/* POSIX Symbolic Constants */
-#include <errno.h>	/* Error definitions */
-
-#include <netinet/in.h> /* required for htons() and ntohs() */
-#include "mb_layer1.h"
-#include "mb_master.h"
-#include "mb_master_private.h"
-/*v1.0*/
-#include "mb_tcp_private.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* #define DEBUG */		/* uncomment to see the data sent and received */
-
-
-#ifndef TRUE
-#define TRUE  1
-#endif
-
-#ifndef FALSE
-#define FALSE 0
-#endif
-
-
-/******************************************/
-/******************************************/
-/**                                      **/
-/**         Global Variables...          **/
-/**                                      **/
-/******************************************/
-/******************************************/
-
-/*v1.0
-static u8 *query_buffer_ = NULL;
-*/
-#ifndef __Lynx__ 
-#if RECV_BUFFER_SIZE < 5 //TCP_HEADER_LENGTH
-#error The receive buffer is smaller than the frame header length.
-#endif
-#endif
-/**/
-
-/******************************************/
-/******************************************/
-/**                                      **/
-/**       Local Utility functions...     **/
-/**                                      **/
-/******************************************/
-/******************************************/
-
-
-/*
- * Function to determine next transaction id.
- *
- * We use a library wide transaction id, which means that we
- * use a new transaction id no matter what slave to which we will
- * be sending the request...
- */
-static inline u16 next_transaction_id(void) {
-
-  static u16 next_id = 0;
-
-  return next_id++;
-}
-
-
-/*
- * Functions to convert u16 variables
- * between network and host byte order
- *
- * NOTE: Modbus uses MSByte first, just like
- *       tcp/ip, so we use the htons() and
- *       ntoh() functions to guarantee
- *       code portability.
- */
-
-static inline u16 mb_hton(u16 h_value) {
-/*  return h_value; */
-  return htons(h_value);
-}
-
-static inline u16 mb_ntoh(u16 m_value) {
-/*  return m_value; */
-  return ntohs(m_value);
-}
-
-
-
-static inline u8 msb(u16 value) {
-/*  return Most Significant Byte of value; */
-  return (value >> 8) & 0xFF;
-}
-
-static inline u8 lsb(u16 value) {
-/*  return Least Significant Byte of value; */
-  return value & 0xFF;
-}
-
-#define u16_v(char_ptr)  (*((u16 *)(&(char_ptr))))
-
-
-/***********************************************************************
-
-	The following functions construct the required query into
-	a modbus query packet.
-
-***********************************************************************/
-
-static inline int build_query_packet(u8  slave,
-                                     u8  function,
-                                     u16 start_addr,
-                                     u16 count,
-                                     u8 *packet)
-{
-        packet[ 0 ] = slave,
-        packet[ 1 ] = function;
-          /* NOTE:
-           *  Modbus uses high level addressing starting off from 1, but
-           *  this is sent as 0 on the wire!
-           */
-        u16_v(packet[2]) = mb_hton(start_addr - 1);
-        u16_v(packet[4]) = mb_hton(count);
-
-        return 6;
-}
-
-
-/************************************************************************
-
-	read_bdata
-
-    F.Locci: just read raw byte array. Take care of frame which exceeds 
-    modbus frame std. length.
-
-*************************************************************************/
-/*v2.0*/
-#define swap16(w) ((((unsigned short)w & 0x00ff)<<8)+(((unsigned short)w & 0xff00)>>8))
-
-int read_bdata(int slave,    /* slave id */
-             int start_addr, /* word pointer addr. */
-             int count,      /* byte count to read */
-             u8 *dest,       /* byte array */
-             int ttyfd,      /* connection id */
-             int send_retries, /* number of request retries */
-             const struct timespec *response_timeout) /* timeout value */
-{
-	/*v1.0*/
-    u8 data[RECV_BUFFER_SIZE];
-	u8 packet[QUERY_BUFFER_SIZE];
-	/**/
-	int rl, response_length=0;
-    int query_length;
-    u16 send_transaction_id, recv_transaction_id;
-	u8  *destp  = dest;
-	int global_length, length;            /* word count for read     */
-
-    /*Attention! ModBus travaille sur une zone memoire [1..n] tandis que l'espace memoire
-	  du PLC est definie [0..n-1] => start_addr = start_addr +1
-	  start_addr est exprime en word pour le PLC (alignement 16bits).
-	*/
-	start_addr+=1;
-
-
-	/*'global_length' is a word counter*/
-	global_length = (count/2) + (count%2);
-		  
-    while(count) {
-
-		if (count > MAX_READ_BDATA)
-		   /*'length' is a word counter*/
-		   length = MAX_READ_BDATA/2;
-		else
-		  /*'length' is a word counter*/
-		  length = (count/2) + (count%2);
-		  
-        /* We must also initialize the recv_transaction_id with the same value,
-         * since some layer 1 protocols do not support transaction id's, so
-         * simply return the recv_transaction_id variable without any changes...
-         */
-        send_transaction_id = recv_transaction_id = next_transaction_id();
-
-        query_length = build_query_packet(slave, 0x03, /*function*/
-                                          start_addr, length,
-                                          packet);
-        if (query_length < 0)
-          return -1;
-
-		if (modbus_write(ttyfd, packet, query_length, send_transaction_id) < 0 )
-        	  return PORT_FAILURE;
-
-		rl = modbus_read(&ttyfd, data/*v1.0*/, &recv_transaction_id,
-                         packet, query_length,
-                         response_timeout);
-
-		if( rl <= 0 )  return PORT_FAILURE;
-
-        /* first check whther we have correct transaction id */
-        if (send_transaction_id != recv_transaction_id)
-          return PORT_FAILURE;
-
-        if( rl > 0 )  
-		{ rl -= 3; /*F.Locci, bug: 2->3*/
-		  if (count<MAX_READ_BDATA)
-		    rl -= (count%2);
-		}
-
-        if( rl > 0 ) {
-		   memcpy(destp, (u8 *)&(data[3]), rl);
-		   destp += rl;
-		   start_addr += length; /*F.Locci, bug if rl = 0 */
-		}
-		
-		/* start_addr += length;  F.Locci, bug if rl = 0 */
-		response_length += rl;
-		count -= rl;
-	}
-
-	/*v2.0:
-	  Independamment de son mapping memoire (Little-endian), le PLC SCHNEIDER
-	  swap chaque mot de 16bits qu'il transmet. Cette ligne permet de redresser
-	  les donnees pour transmettre l'image exacte du mapping memoire. Charge 
-	  a l'application ensuite d'appliquer le swapping necessaire relatif a son 
-	  "Endianness".
-	*/
-	{
-	int j;
-	u16 *wdestp = (u16 *)dest; /* for swapping 16bit  */
-	for(j=0; j<global_length; j++){ wdestp[j] = swap16(wdestp[j]); }
-	}
-	/**/
-
-    #ifdef DEBUG
-    { int i;
-	printf("read_bdata: ");
-	for(i=0; i<response_length; printf("%02x ", dest[i++]));
-	printf("\n");
-	}
-	#endif
-	
-	return response_length;
-}
-
-/*************************************************************************
-
-	write_bdata
-
-    F.Locci: just write raw byte array. Take care of frame which exceeds 
-    modbus frame std. length.
-	!!byte count MUST be even value - 16 bits alignment in that PLC
-
-***************************************************************************/
-
-int write_bdata(int slave,   /* slave id */
-             int start_addr, /* word pointer addr.  */
-             int count,      /* byte count to write - MUST be even value */
-             u8 *data,       /* byte array */
-             int ttyfd,      /* connection id */
-             int send_retries, /* number of request retries */
-             const struct timespec *response_timeout) /* timeout value */
-{
-	int byte_count;
-	int i, rl, response_length=0;
-    int query_length;
-	/*v1.0*/
-    u8 rdata[RECV_BUFFER_SIZE];
-	u8 packet[QUERY_BUFFER_SIZE];
-    u16 send_transaction_id, recv_transaction_id;
-	int length;        /* word count */
-	u8 *destp, *srcp = data;
-
-    /*Attention! ModBus travaille sur une zone memoire [1..n] tandis que l'espace memoire
-	  du PLC est definie [0..n-1] => start_addr = start_addr +1
-	  start_addr est exprime en word pour le PLC (alignement 16bits).
-	*/
-	start_addr+=1;
-	
-    while(count) {
-
-		if (count > MAX_WRITE_BDATA) 
-		{
-		   /*'length' is a word counter*/
-		   length = MAX_WRITE_BDATA/2;
-		}
-		else
-		{
-		  /*'length' is a word counter*/
-		  length = (count/2) + (count%2);
-		}
-
-        /* We must also initialize the recv_transaction_id with the same value,
-         * since some layer 1 protocols do not support transaction id's, so
-         * simply return the recv_transaction_id variable without any changes...
-         */
-        send_transaction_id = recv_transaction_id = next_transaction_id();
-
-        query_length = build_query_packet(slave, 0x10 /* function */,
-                                          start_addr, length,
-                                          packet);
-        if (query_length < 0)
-          return -1;
-
-		byte_count = (length * 2);
-		packet[ query_length ] = byte_count;
-
-        destp = &(packet[ ++query_length ]);
-		memcpy(destp, srcp, byte_count-(count%2));
-		
-		/*v2.0:
-		  Independamment de son mapping memoire (Little-endian), le PLC SCHNEIDER
-		  swap chaque mot de 16bits qu'il transmet. Cette ligne permet de redresser
-		  les donnees pour transmettre l'image exacte du mapping memoire. Charge 
-		  a l'application ensuite d'appliquer le swapping necessaire relatif a son 
-		  "Endianness".
-		*/
-		{
-		u16 *wdestp = (u16 *)destp;
-		for(i=0; i<length; i++){ wdestp[i] = swap16(wdestp[i]); }
-		}
-		/**/
-
-		srcp += byte_count-(count%2);
-		query_length += byte_count;
-
-		if( modbus_write( ttyfd, packet, query_length, send_transaction_id) < 0 )
-		  return PORT_FAILURE;
-
-		rl = modbus_read(&ttyfd, rdata/*v1.0*/, &recv_transaction_id,
-                         packet, query_length, response_timeout);
-
-        if( rl <= 0 ) return PORT_FAILURE;
-
-        /* first check whther we have correct transaction id */
-        if (send_transaction_id != recv_transaction_id)
-          return PORT_FAILURE;
-		  
-		start_addr += length;
-		response_length += byte_count;
-		count -= (byte_count - (count%2));
-    }
-
-    return response_length;
-}
-
-/************************************************************************
-
-	initialise / shutdown the library
-
-	These functions sets up/shut down the library state
-        (allocate memory for buffers, initialise data strcutures, etc)
-
-**************************************************************************/
-
-int mb_master_init(int nd_count) {
-        int extra_bytes;
-
-#ifdef DEBUG
-	fprintf( stderr, "mb_master_init()\n");
-	fprintf( stderr, "creating %d nodes\n", nd_count);
-#endif
-
-            /* initialise layer 1 library */
-        if (modbus_init(nd_count, DEF_OPTIMIZATION, &extra_bytes)
-            < 0)
-          goto error_exit_0;
-
-        /*v1.0 initialise send buffer
-        query_buffer_ = (u8 *)malloc(QUERY_BUFFER_SIZE + extra_bytes);
-        if (query_buffer_ == NULL)
-          goto error_exit_1;
-		*/  
-
-        return 0;
-
-error_exit_0:
-        return -1;
-}
-
-
-int mb_master_done(void) {
-/*v1.0
-        free(query_buffer_);
-        query_buffer_ = NULL;
-*/
-        return modbus_done();
-}
-
-/************************************************************************
-
-	open/close master connection
-
-	This function opens/closes a connection to the remote slave.
-
-**************************************************************************/
-
-int mb_master_connect(node_addr_t node_addr) {
-#ifdef DEBUG
-	fprintf( stderr, "mb_master_connect()\n");
-#endif
-          /* call layer 1 library */
-        return modbus_connect(node_addr);
-}
-
-
-int mb_master_close(int nd) {
-#ifdef DEBUG
-	fprintf( stderr, "mb_master_close(): nd = %d\n", nd);
-#endif
-          /* call layer 1 library */
-        return modbus_close(nd);
-}
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/silecs-communication-cpp/src/silecs-communication/protocol/modbus/mb_master.h b/silecs-communication-cpp/src/silecs-communication/protocol/modbus/mb_master.h
deleted file mode 100644
index 774598539ed57421c7a5f035cd0ac7350cd8eee1..0000000000000000000000000000000000000000
--- a/silecs-communication-cpp/src/silecs-communication/protocol/modbus/mb_master.h
+++ /dev/null
@@ -1,157 +0,0 @@
-/* 		modbus_rtu.h
-
-   By P.Costigan email: phil@pcscada.com.au http://pcscada.com.au
-
-   These library of functions are designed to enable a program send and
-   receive data from a device that communicates using the Modbus protocol.
-
-   Copyright (C) 2000 Philip Costigan  P.C. SCADA LINK PTY. LTD.
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
-   (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-
-
-
-   The functions included here have been derived from the
-   Modicon Modbus Protocol Reference Guide
-   which can be obtained from Schneider at www.schneiderautomation.com.
-
-   This code has its origins with
-   paul@pmcrae.freeserve.co.uk (http://www.pmcrae.freeserve.co.uk)
-   who wrote a small program to read 100 registers from a modbus slave.
-
-   I have used his code as a catalist to produce this more functional set
-   of functions. Thanks paul.
-
-
- */
-
-
-#ifndef MODBUS_MASTER_H
-#define MODBUS_MASTER_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*F.Locci #include <plc.h>*/  /* get the plc data types */
-#include <time.h> /* struct timespec data structure */
-
-#include "mb_addr.h"  /* get definition of common variable types */
-
-
-
-/***********************************************************************
-
-	 Note: All functions used for sending or receiving data via
-	       modbus return these return values.
-
-
-	Returns:	string_length if OK
-			0 if failed
-			Less than 0 for exception errors
-
-***********************************************************************/
-
-
-/*F.Locci: error constants adjustement to be SILECS conformed
-#define COMMS_FAILURE 0
-#define ILLEGAL_FUNCTION -1
-#define ILLEGAL_DATA_ADDRESS -2
-#define ILLEGAL_DATA_VALUE -3
-#define SLAVE_DEVICE_FAILURE -4
-#define ACKNOWLEDGE -5
-#define SLAVE_DEVICE_BUSY -6
-#define NEGATIVE_ACKNOWLEDGE -7
-#define MEMORY_PARITY_ERROR -8
-
-#define PORT_FAILURE -11
-*/
-#define PORT_FAILURE -3
-
-
-/************************************************************************
-
-	read_bdata
-
-    F.Locci: just read raw byte array. Take care of frame longer than 
-	125 words.
-
-*************************************************************************/
-
-#define MAX_READ_BDATA  200
-
-int read_bdata(int slave,    /* slave id */
-             int start_addr, /* word pointer addr. */
-             int count,      /* byte count to read */
-             u8 *dest,       /* byte array */
-             int ttyfd,      /* connection id */
-             int send_retries, /* number of request retries */
-             const struct timespec *response_timeout); /* timeout value */
-
-
-/*************************************************************************
-
-	write_bdata
-
-    F.Locci: just write raw byte array. Take care of frame which exceeds 
-    modbus frame std. length.
-	!!byte count MUST be even value - 16 bits alignment in that PLC
-
-***************************************************************************/
-
-#define MAX_WRITE_BDATA  200
-
-int write_bdata(int slave,   /* slave id */
-             int start_addr, /* word pointer addr.  */
-             int count,      /* byte count to write - MUST be even value */
-             u8 *data,       /* byte array */
-             int ttyfd,      /* connection id */
-             int send_retries, /* number of request retries */
-             const struct timespec *response_timeout); /* timeout value */
-
-
-/************************************************************************
-
-	initialise
-
-	This function sets up the libraries
-        (allocate memory for buffers, initialise data strcutures, etc)
-
-**************************************************************************/
-int mb_master_init(int nd_count);
-
-int mb_master_done(void);
-
-
-/***************************************************************************
-
-	set_up_comms
-
-	This function sets up (closes) a connection to a remote modbus
-	slave.
-
-
-***************************************************************************/
-int mb_master_connect(node_addr_t node_addr);
-
-int mb_master_close(int nd);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif  /* MODBUS_MASTER_H */
-
diff --git a/silecs-communication-cpp/src/silecs-communication/protocol/modbus/mb_master_private.h b/silecs-communication-cpp/src/silecs-communication/protocol/modbus/mb_master_private.h
deleted file mode 100644
index 5f9d4b7f63fa40160e90ad9597ab0fbddf8c6366..0000000000000000000000000000000000000000
--- a/silecs-communication-cpp/src/silecs-communication/protocol/modbus/mb_master_private.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * (c) 2002 Mario de Sousa
- *
- * Offered to the public under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
- * Public License for more details.
- *
- * This code is made available on the understanding that it will not be
- * used in safety-critical situations without a full and competent review.
- */
-
-
-#ifndef MODBUS_MASTER_PRIVATE_H
-#define MODBUS_MASTER_PRIVATE_H
-
-/*F.Locci #include <plc.h>*/  /* get the plc data types */
-#include "mb_util.h"
-#include "mb_master.h"
-
-
-#define QUERY_BUFFER_SIZE       MAX_L2_FRAME_LENGTH
-
-#define DEF_LAYER2_SEND_RETRIES 1
-
-#define DEF_IGNORE_ECHO         0
-
-#define DEF_OPTIMIZATION        optimize_speed
-
-
-#endif  /* MODBUS_MASTER_PRIVATE_H */
-
-
-
-
-
-
-
-
diff --git a/silecs-communication-cpp/src/silecs-communication/protocol/modbus/mb_tcp.cpp b/silecs-communication-cpp/src/silecs-communication/protocol/modbus/mb_tcp.cpp
deleted file mode 100644
index f918409981c6121c59e24e1c930489b3b755c63d..0000000000000000000000000000000000000000
--- a/silecs-communication-cpp/src/silecs-communication/protocol/modbus/mb_tcp.cpp
+++ /dev/null
@@ -1,1407 +0,0 @@
-/*
- * (c) 2002 Mario de Sousa
- *
- * Offered to the public under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
- * Public License for more details.
- *
- * This code is made available on the understanding that it will not be
- * used in safety-critical situations without a full and competent review.
- *
- *
- * Revision : v1.0
- * Date     : 11/2004 - F.Locci
- * Objet    : .remove static prefix into modbus_tcp_write() declaration 
- *            to make code reentrant.
- *            .move global recv_buf_ to local one into read/write_bdata()
- *            Look at v1.0 comments
- *
- * Revision : v1.1
- * Date     : 12/2006 - F.Locci
- * Objet    : .modify code (pointing things) to be Lces platform compatible      
- *            Look at v1.1 comments
- */
-
-
-/* TODO:
- *       - clean up the code (access to nw_array_, etc...)
- *       - closing sockets that will be idle for more than 1 second...
- */
-
-
-#include <fcntl.h>      /* File control definitions */
-#include <stdio.h>      /* Standard input/output */
-#include <string.h>
-#include <stdlib.h>
-#include <termio.h>     /* POSIX terminal control definitions */
-#include <unistd.h>     /* POSIX Symbolic Constants */
-#include <assert.h>
-#include <errno.h>      /* Error definitions */
-#include <time.h>       /* clock_gettime()   */
-#include <sys/types.h>
-#ifdef __Lynx__
-#include <bsd/in_systm.h>
-#include <uio.h>
-#endif
-#include <sys/socket.h>
-#include <netinet/in.h>  /* required for htons() and ntohs() */
-#include <netinet/tcp.h> /* TCP level socket options */
-#include <netinet/ip.h>  /* IP  level socket options */
-
-/*F.Locci, 
-#include <plc.h>
-#include <misc/sin_util.h>
-*/
-#include <silecs-communication/protocol/core/ietype.h>
-
-#include "sin_util.h"
-/*F.Locci end*/
-
-#include "mb_layer1.h"  /* The public interface this file implements... */
-#include "mb_tcp_private.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* #define DEBUG */       /* uncomment to see the data sent and received */
-
-
-#define modbus_tcp_write           modbus_write
-#define modbus_tcp_read            modbus_read
-#define modbus_tcp_init            modbus_init
-#define modbus_tcp_done            modbus_done
-#define modbus_tcp_connect         modbus_connect
-#define modbus_tcp_listen          modbus_listen
-#define modbus_tcp_close           modbus_close
-#define modbus_tcp_silence_init    modbus_silence_init
-#define modbus_tcp_get_min_timeout modbus_get_min_timeout
-
-
-
-
-/************************************/
-/**                                **/
-/** Include common code...         **/
-/**                                **/
-/************************************/
-
-#include "mb_time_util.h"
-
-
-
-
-/**************************************************************/
-/**************************************************************/
-/****                                                      ****/
-/****                                                      ****/
-/****                Forward Declarations                  ****/
-/****                    and Defaults                      ****/
-/****                                                      ****/
-/**************************************************************/
-/**************************************************************/
-
-
-  /* A Node Descriptor metadata,
-   *   Due to the fact that modbus TCP is connection oriented,
-   *   and that if the client detects an error the connection
-   *   must be shut down and re-established automatically,
-   *   the modbus TCP layer needs to keep the address of the remote server.
-   *
-   * We do this by implementing a node descriptor table, in which each
-   *   entry will have the remote address, and the file descriptor
-   *   of the socket currently in use.
-   *
-   * We do not pass the file descriptor up to the next higher layer. We
-   *   send them the node descriptor instead...
-   */
-#define MB_MASTER_NODE AF_INET  /* This MUST be set to AF_INET !! */
-#define MB_LISTEN_NODE AF_AX25  /* actually any value will do, as long as it is != AF_INET */
-#define MB_SLAVE_NODE  AF_X25   /* actually any value will do, as long as it is != AF_INET */
-#define MB_FREE_NODE   AF_ROSE  /* actually any value will do, as long as it is != AF_INET */
-typedef sa_family_t nd_type_t;
-
-typedef struct {
-    int    fd;                 /* socket descriptor == file descriptor */
-                               /* NOTE:
-                                *   Modbus TCP says that on error, we should close
-                                *   a connection and retry with a new connection.
-                                *   Since it takes time for a socket to close
-                                *   a connection if the remote server is down,
-                                *   we close the connection on the socket, close the
-                                *   socket itself, and create a new one for the new
-                                *   connection. There will be times when the node will
-                                *   not have any valid socket, and it will have to
-                                *   be created on the fly.
-                                *   When the node does not have a valid socket,
-                                *   fd will be set to -1
-                                */
-    struct sockaddr_in addr;   /* NOTE:
-                                *   We re-use the addr.sin_family member to define the
-                                *   state of the node descriptor.
-                                *   If addr.sin_family == MB_MASTER_NODE
-                                *      The node descriptor was initialised by the
-                                *      modbus_connect() function.
-                                *      The node descriptor is being used by a master
-                                *      device, and the addr contains the address of the slave.
-                                *      Remember that in this case fd may be >= 0 while
-                                *      we have a valid connection, or it may be < 0 when
-                                *      the connection needs to be reset.
-                                *   If addr.sin_family == MB_LISTEN_NODE
-                                *      The node descriptor was initialised by the
-                                *      modbus_listen() function.
-                                *      The node is merely used to accept() new connection
-                                *      requests. The new slave connections will use another
-                                *      node to transfer data.
-                                *      In this case fd must be >= 0.
-                                *      fd < 0 is an ilegal state and should never occur.
-                                *   If addr.sin_family == MB_SLAVE_NODE
-                                *      The node descriptor was initialised when a new
-                                *      connection request arrived on a MB_LISTEN type node.
-                                *      The node descriptor is being used by a slave device,
-                                *      and is currently being used to connect to a master.
-                                *      In this case fd must be >= 0.
-                                *      fd < 0 is an ilegal state and should never occur.
-                                *   If addr.sin_family == FREE_ND
-                                *      The node descriptor is currently not being used.
-                                *      In this case fd is set to -1, but is really irrelevant.
-                                */
-    int close_on_silence;      /* A flag used only by Master Nodes.
-                                * When (close_on_silence > 0), then the connection to the
-                                * slave device will be shut down whenever the
-                                * modbus_tcp_silence_init() function is called.
-                                * Remember that the connection will be automatically
-                                * re-established the next time the user wishes to communicate
-                                * with the same slave (using this same node descripto).
-                                * If the user wishes to comply with the sugestion
-                                * in the OpenModbus Spec, (s)he should set this flag
-                                * if a silence interval longer than 1 second is expected.
-                                */
-} nd_entry_t;
-
-
-static void nd_entry_init(nd_entry_t *nde) {
-  nde->addr.sin_family = MB_FREE_NODE;
-  nde->fd = -1; /* not currently connected... */
-}
-
-
-
-
-typedef struct {
-      /* the array of node descriptors, and current size... */
-    nd_entry_t *node;
-    int        node_count;      /* total number of nodes in the node[] array */
-    int        free_node_count; /*  number of free nodes in the node[] array */
-      /* fd set with all the fd in the node array already set
-       * This saves time in not having to re-initialize a fd_set every time
-       * the modbus_read() function is called...
-       */
-    fd_set     all_fds;
-      /* the highest fd in the fds set... This is used for the select() call */
-    int        all_fd_high;
-      /* fd set with all the fd belonging to MB_MASTER_NODE and MB_SLAVE_NODE
-       * type nodes already set.
-       * This saves time in not having to re-initialize a fd_set every time
-       * the modbus_read() function is called...
-       */
-    fd_set     ms_fds;
-      /* the highest fd in the fds set... This is used for the select() call */
-    int        ms_fd_high;
-} nd_table_t;
-
-
-/*F.Locci, add connection timeout - look at <rfcsock.c> file*/
-extern int connect_nonb(int sockfd, struct sockaddr *saptr, socklen_t salen, int nsec);
-
-
-static int nd_table_init(nd_table_t *ndt, int nd_count) {
-  int count;
-
-  /* initialise the node table with default values... */
-  ndt->node  = NULL;
-  ndt->node_count = 0;
-  ndt->free_node_count = 0;
-  FD_ZERO(&(ndt->all_fds));
-  ndt->all_fd_high = -1;
-  FD_ZERO(&(ndt->ms_fds));
-  ndt->ms_fd_high  = -1;
-
-  /* initialise the node descriptor metadata array... */
-  ndt->node = (nd_entry_t*) malloc(sizeof(nd_entry_t) * nd_count);
-  if (ndt->node == NULL) {
-    /*F.Locci 
-	plc_log_errmsg(1, "Out of memory: error initializing node address buffer");
-	*/
-	printf("\nOut of memory: error initializing node address buffer\n");
-    return -1;
-  }
-  ndt->node_count = nd_count;
-  ndt->free_node_count = nd_count;
-
-    /* initialise the state of each node in the array... */
-  for (count = 0; count < nd_count; count++) {
-    nd_entry_init(&ndt->node[count]);
-  } /* for() */
-
-  return nd_count; /* number of succesfully created nodes! */
-}
-
-
-
-static int nd_table_get_free_node(nd_table_t *ndt, nd_type_t nd_type) {
-  int count;
-
-  /* check for free nodes... */
-  if (ndt->free_node_count <= 0)
-    /* no free nodes... */
-    return -1;
-
-  /* Decrement the free node counter...*/
-  ndt->free_node_count--;
-
-  /* search for a free node... */
-  for (count = 0; count < ndt->node_count; count++) {
-    if(ndt->node[count].addr.sin_family == MB_FREE_NODE) {
-      /* found one!! */
-      ndt->node[count].addr.sin_family = nd_type;
-      return count;
-    }
-  } /* for() */
-
-  /* Strange... We should have free nodes, but we didn't finda any! */
-  /* Let's try to get into a consistent state, and return an error! */
-  ndt->free_node_count = 0;
-  return -1;
-}
-
-
-
-static void nd_table_close_node(nd_table_t *ndt, int nd) {
-
-  if(ndt->node[nd].addr.sin_family == MB_FREE_NODE)
-    /* Node already free... */
-    return;
-
-  /* Increment the free node counter...*/
-  ndt->free_node_count++;
-  /* Mark the node as being free. */
-  ndt->node[nd].addr.sin_family = MB_FREE_NODE;
-
-  return;
-}
-
-
-
-/**************************************************************/
-/**************************************************************/
-/****                                                      ****/
-/****                                                      ****/
-/****                Global Library State                  ****/
-/****                                                      ****/
-/****                                                      ****/
-/**************************************************************/
-/**************************************************************/
-
- /* The receive buffer... */
- /* NOTE: The library supports multiple simultaneous connections,
-  *       but will only read a message from one at a time.
-  *       (i.e. once it starts receiving a message from one node, it
-  *       will read that message to the end, even though another message
-  *       may start arriving later on another node, but finish arriving
-  *       earlier than the first. The second message will be ignored until
-  *       the first has been completely received, or a timeout occurs...)
-  *       This means we can re-use the same buffer for all the nodes.
-  *       It doesn't seem to be worth the hassle and increased memory
-  *       use to implement it properly with one buffer per node...
-  v1.0
-static u8 *recv_buf_ = NULL;
-*/
-
- /* The node descriptor table... */
- /* NOTE: This variable is also used to check whether the library
-  *       has been previously initialised.
-  *       If == NULL, �> library not yet initialised...
-  */
-static nd_table_t *nd_table_ = NULL;
-
-
-
-/**************************************************************/
-/**************************************************************/
-/****                                                      ****/
-/****                                                      ****/
-/****              Local Utility functions...              ****/
-/****                                                      ****/
-/****                                                      ****/
-/**************************************************************/
-/**************************************************************/
-
-
-#define min(a,b) ((a<b)?a:b)
-#define max(a,b) ((a>b)?a:b)
-
-/************************************/
-/**                                **/
-/**  Configure socket for Modbus   **/
-/**                                **/
-/************************************/
-
-
-static int configure_socket(int socket_id) {
-
-  /* configure the socket */
-    /* set the TCP no delay flag. */
-  {int bool_opt = 1;
-  if (setsockopt(socket_id, SOL_TCP, TCP_NODELAY,
-                 (const void *)&bool_opt, sizeof(bool_opt))
-      < 0)
-    return -1;
-  }
-
-    /* set the IP low delay option. */
-  {int priority_opt = IPTOS_LOWDELAY;
-  if (setsockopt(socket_id, SOL_IP, IP_TOS,
-                 (const void *)&priority_opt, sizeof(priority_opt))
-      < 0)
-    return -1;
-  }
-
-#if 0
-    /* send buffer */
-    /* NOTE: For slave devices, that may be receiving multiple
-     *       requests before they have a chance to reply to the first,
-     *       it probably is a good idea to have a larger receive buffer.
-     *
-     *       For the send buffer, it probably does not make sense to
-     *       waste time asking for a smaller buffer, since the larger
-     *       default buffer has already been allocated (the socket has already
-     *       been created!)
-     *
-     *       We might just as well leave out the configuration of the socket
-     *       buffer size...
-     */
-#define SOCK_BUF_SIZE 300 /* The size proposed in the Modbus TCP spec. */
-  {int sock_buf_size;
-  sock_buf_size = SOCK_BUF_SIZE;
-  if (setsockopt(socket_id, SOL_SOCKET, SO_SNDBUF,
-                 (const void *)&sock_buf_size, sizeof(sock_buf_size))
-      < 0)
-    return -1;
-    /* recv buffer */
-  sock_buf_size = SOCK_BUF_SIZE;
-  if (setsockopt(socket_id, SOL_SOCKET, SO_RCVBUF,
-             (const void *)&sock_buf_size, sizeof(sock_buf_size))
-      < 0)
-    return -1;
-  }
-#endif
-
-  return 0;
-}
-
-
-/************************************/
-/**                                **/
-/** Connect socket to remote host  **/
-/**                                **/
-/************************************/
-
-/* This function will create a new socket, and connect it to a remote host... */
-static inline int open_connection(int nd) {
-  int socket_id;
-
-  if (nd_table_->node[nd].fd >= 0)
-    /* nd already connected) */
-    return nd_table_->node[nd].fd;
-
-  if (nd_table_->node[nd].addr.sin_family != AF_INET)
-    /* invalid remote address, or invalid nd */
-    return -1;
-
-  /* lets try to connect... */
-    /* create the socket */
-  if ((socket_id = socket(PF_INET, DEF_TYPE, 0 /* protocol_num */)) < 0)
-    return -1;
-
-  /* configure the socket */
-  if (configure_socket(socket_id) < 0) {
-    close(socket_id);
-    return -1;
-  };
-
-    /* establish the connection to remote host */
-  if (connect_nonb(socket_id,
-      (struct sockaddr *)&(nd_table_->node[nd].addr),
-      sizeof(nd_table_->node[nd].addr), MAX_CONNECT_TIMEOUT) < 0) {
-    close(socket_id);
-    return -1;
-  }
-
-  nd_table_->node[nd].fd = socket_id;
-  FD_SET(socket_id, &(nd_table_->all_fds));
-  nd_table_->all_fd_high = max(nd_table_->all_fd_high, socket_id);
-  FD_SET(socket_id, &(nd_table_->ms_fds));
-  nd_table_->ms_fd_high = max(nd_table_->ms_fd_high, socket_id);
-
-  return socket_id;
-}
-
-
-/* This function will accept a new connection request, and attribute it to a new node... */
-static inline int accept_connection(int nd) {
-  int socket_id, new_nd;
-
-  if ((new_nd = nd_table_get_free_node(nd_table_, MB_SLAVE_NODE)) < 0)
-    /* no available free nodes for the new connection... */
-    return -1;
-
-  /* lets accept new connection request... */
-  if ((socket_id = accept(nd_table_->node[nd].fd, NULL, NULL)) < 0) {
-    /* error establishing new connection... */
-    nd_table_close_node(nd_table_, new_nd);  /* first free up the un-used node. */
-    return -1;
-  }
-
-  /* configure the socket */
-  if (configure_socket(socket_id) < 0) {
-    nd_table_close_node(nd_table_, new_nd);  /* first free up the un-used node. */
-    close(socket_id);
-    return -1;
-  };
-
-  /* set up the node entry and update the fd sets */
-  nd_table_->node[new_nd].fd = socket_id;
-  FD_SET(socket_id, &(nd_table_->all_fds));
-  nd_table_->all_fd_high = max(nd_table_->all_fd_high, socket_id);
-  FD_SET(socket_id, &(nd_table_->ms_fds));
-  nd_table_->ms_fd_high = max(nd_table_->ms_fd_high, socket_id);
-
-  return new_nd;
-}
-
-
-static inline void close_connection(int nd) {
-  if (nd_table_->node[nd].fd < 0)
-    /* nd already disconnected */
-    return;
-
-  int res = shutdown(nd_table_->node[nd].fd, SHUT_RDWR);
-#ifdef DEBUG
-{
-	/* could not read registers from slave! */
-	printf("shutdown()  returned %d\n",res);
-}
-#endif
-
-  close(nd_table_->node[nd].fd);
-  FD_CLR(nd_table_->node[nd].fd, &nd_table_->all_fds);
-  FD_CLR(nd_table_->node[nd].fd, &nd_table_->ms_fds);
-  nd_table_->node[nd].fd = -1;
-}
-
-
-
-/************************************/
-/**                                **/
-/**     Data format conversion     **/
-/**                                **/
-/************************************/
-
-/*
- * Functions to convert u16 variables
- * between network and host byte order
- *
- * NOTE: Modbus uses MSByte first, just like
- *       tcp/ip, so we use the htons() and
- *       ntoh() functions to guarantee
- *       code portability.
- */
-
-static inline u16 mb_hton(u16 h_value) {
-/*  return h_value; */
-  return htons(h_value);
-}
-
-static inline u16 mb_ntoh(u16 m_value) {
-/*  return m_value; */
-  return ntohs(m_value);
-}
-
-static inline u8 msb(u16 value) {
-/*  return Most Significant Byte of value; */
-  return (value >> 8) & 0xFF;
-}
-
-static inline u8 lsb(u16 value) {
-/*  return Least Significant Byte of value; */
-  return value & 0xFF;
-}
-
-#define u16_v(char_ptr)  (*((u16 *)(&(char_ptr))))
-
-
-/************************************/
-/**                                **/
-/**   Build/Check a frame header   **/
-/**                                **/
-/************************************/
-
-/* A modbus TCP frame header has 6 bytes...
- *   header[0-1] -> transaction id
- *   header[2-3] -> must be 0
- *   header[4-5] -> frame data length (must be <= 255)
- */
-#if TCP_HEADER_LENGTH < 6
-#error This code assumes a header size of 6 bytes, but TCP_HEADER_LENGTH < 6
-#endif
-
-static inline void build_header(u8 *header,
-                                u16 transaction_id,
-                                u16 byte_count)
-{
-  u16_v(header[0]) = mb_hton(transaction_id);
-  header[2] = 0;
-  header[3] = 0;
-  u16_v(header[4]) = mb_hton(byte_count);
-}
-
-
-static inline int check_header(u8  *header,
-                               u16 *transaction_id,
-                               u16 *byte_count)
-{
-  if ((header[2] != 0) || (header[3] != 0))
-    return -1;
-
-  *transaction_id = mb_ntoh(*(u16 *)(header + 0));
-  *byte_count     = mb_ntoh(*(u16 *)(header + 4));
-
-  if (*byte_count > MAX_L2_FRAME_LENGTH)
-    return -1;
-
-  return 0;
-}
-
-
-
-
-
-/**************************************************************/
-/**************************************************************/
-/****                                                      ****/
-/****                                                      ****/
-/****              Sending of Modbus TCP Frames            ****/
-/****                                                      ****/
-/****                                                      ****/
-/**************************************************************/
-/**************************************************************/
-
-int modbus_tcp_write(int nd,  /* node descriptor */
-                     u8 *data,
-                     size_t data_length,
-                     u16 transaction_id)
-{
-#define data_vector_size 2
-
-  /* NOTE: The following variables do not have to be static for the code to work
-   *       correctly. It simply does not make sense to re-initialize these
-   *       structures with the same values every time the function is called.
-   */
-  /*v1.0*/
-  u8            header[TCP_HEADER_LENGTH], *ptriovec/*v1.1*/;
-  struct iovec  data_vector[data_vector_size] = {{(void *)header, TCP_HEADER_LENGTH},{NULL, 0}};
-  struct msghdr msg = {NULL, 0, data_vector, data_vector_size, NULL, 0, 0};
-  int res, bytes_sent;
-
-#ifdef DEBUG
-  printf("modbus_tcp_write(): called...  nd=%d\n", nd);
-#endif
-
-  if ((nd >= nd_table_->node_count) || (nd < 0))
-    /* invalid node descriptor... */
-    return -1;
-
-  /*************************
-  * prepare the header...  *
-  *************************/
-  build_header(header, transaction_id, data_length);
-#ifdef DEBUG
-/* Print the hex value of each character that is about to be
- * sent over the bus.
- */
-  { int i;
-    printf("modbus_tcp_write(): sending data...\n");
-    for(i = 0; i < TCP_HEADER_LENGTH; i++)
-      printf("[0x%2X]", header[i]);
-    for(i = 0; i < data_length; i++)
-      printf("[0x%2X]", data[i]);
-    printf("\n");
-  }
-#endif
-
-  /******************************************
-   * do we need to re-establish connection? *
-   ******************************************/
-  if (open_connection(nd) < 0) {
-#ifdef DEBUG
-    printf("modbus_tcp_write(): could not establish connection...\n");
-#endif
-    return -1;
-  }
-
-  /**********************
-   * write to output... *
-   **********************/
-  /* We are optimising for the most likely case, and in doing that
-   * we are making the least likely case have worse behaviour!
-   * Read on for an explanation...
-   *
-   * - The optimised behaviour for the most likely case:
-   * We have set the NO_DELAY flag on the socket, so the IP datagram
-   * is not delayed and is therefore sent as soon as any data is written to
-   * the socket.
-   * In order to send the whole message in a single IP datagram, we have to
-   * write both the the header and the data with a single call to write()
-   * In order to not to have to copy the data around just to add the
-   * message header, we use sendmsg() instead of write()!
-   *
-   * - The worse behaviour for the least likely case:
-   * If for some reason only part of the data is sent with the first call to
-   * write(), a datagram is sent right away, and the subsequent data will
-   * be sent in another datagram. :-(
-   */
-  data_vector[data_vector_size - 1].iov_base = data;
-  data_vector[data_vector_size - 1].iov_len  = data_length;
-  bytes_sent = 0;
-  while (1) {
-     /* Please see the comment just above the main loop!! */
-    res = sendmsg(nd_table_->node[nd].fd, &msg, 0);
-    if (res < 0) {
-      if ((errno != EAGAIN ) && (errno != EINTR )) {
-        /* error sending message... */
-        close_connection(nd);
-        return -1;
-      } else {
-        continue;
-      }
-    } else {
-      /* res >= 0 */
-      bytes_sent += res;
-      if (bytes_sent >= data_length + TCP_HEADER_LENGTH) {
-        /* query succesfully sent! */
-#ifdef DEBUG
-        printf("modbus_tcp_write(): sent %d bytes\n", bytes_sent);
-#endif
-        return data_length;
-      }
-
-      /* adjust the data_vector... */
-	  /*v1.1*/
-      if (res < data_vector[0].iov_len) {
-        data_vector[0].iov_len -= res;
-		ptriovec = (u8 *)data_vector[0].iov_base;
-		ptriovec += res;
-        data_vector[0].iov_base = (void *)ptriovec;
-      } else {
-        res -= data_vector[0].iov_len;
-        data_vector[0].iov_len  = 0;
-        data_vector[1].iov_len -= res;
-		ptriovec = (u8 *)data_vector[1].iov_base;
-		ptriovec += res;
-        data_vector[1].iov_base = (void *)ptriovec;
-      }
-    }
-  } /* while (1) */
-
-  /* humour the compiler... */
-  return -1;
-}
-
-
-
-/**************************************************************/
-/**************************************************************/
-/****                                                      ****/
-/****                                                      ****/
-/****              Receiving Modbus TCP Frames             ****/
-/****                                                      ****/
-/****                                                      ****/
-/**************************************************************/
-/**************************************************************/
-
-
-/* A helper function to modbus_tcp_read()
- *
- * WARNING: The semantics of this function are not what you would expect!
- *
- *          if (data_already_available != 0)
- *          It assumes that select() has already been called before
- *          this function got called, and we are therefore guaranteed
- *          to have at least one byte to read off the socket (the fd).
- *
- *          if (data_already_available == 0)
- *          it starts off by calling select()!
- *
- *
- * NOTE: Ususal select semantics for (a: end_time == NULL) and
- *       (b: *end_time == 0) also apply.
- *
- *       (a) Indefinite timeout
- *       (b) Try once, and and quit if no data available.
- */
-static int read_bytes(int fd,
-                      u8 *data,
-                      int max_data_count,
-                      const struct timespec *end_time,
-                      int data_already_available)
-{
-  fd_set rfds;
-  int res, data_count;
-
-  data_count = 0;
-  while (data_count < max_data_count) {
-    /*============================*
-     * wait for data availability *
-     *============================*/
-    if (data_already_available == 0) {
-      FD_ZERO(&rfds);
-      FD_SET(fd, &rfds);
-      if (my_select(fd + 1, &rfds, end_time) < 0)
-        return -1;
-    }
-
-    /*============================*
-     * read the available data... *
-     *============================*/
-    res = read(fd, data + data_count, max_data_count - data_count);
-    if (res == 0) {
-      /* We are guaranteed to have data to read off the fd since we called
-       * select(), but read() returned 0 bytes.
-       * This means that the remote process has closed down the connection,
-       * so we return 0.
-       */
-      return 0;
-    }
-
-    if (res < 0) {
-      if (errno != EINTR)
-        return -1;
-      else
-        res = 0;
-    }
-	#ifdef DEBUG
-    {/* display the hex code of each character received */
-      int i;
-      for (i=0; i < res; i++)
-        printf("%2X ", *(data + data_count + i));
-    }
-	#endif
-    data_count += res;
-    data_already_available = 0;
-  } /* while ()*/
-
-  /* data read succesfully... */
-  return data_count;
-}
-
-
-
-
-/************************************/
-/**                                **/
-/**    Read a Modbus TCP frame     **/
-/**                                **/
-/************************************/
-
-/* The public function that reads a valid modbus frame.
- * The frame is read from:
- *   -  the node descriptor nd, if nd >= 0
- *   -  any valid and initialised node descriptor, if nd = -1
- *      In this case, the node where the data is eventually read from
- *      is returned in *nd.
- *
- * The send_data and send_length parameters are ignored...
- *
- * return value: The length (in bytes) of the valid frame,
- *               -1 on error
- *
- * NOTE: Ususal select semantics for (a: recv_timeout == NULL) and
- *       (b: *recv_timeout == 0) also apply.
- *
- *       (a) Indefinite timeout
- *       (b) Try once, and and quit if no data available.
- */
-
-/* NOTES:
- *  - We re-use the recv_buf_ to load the frame header, so we have to make
- *    sure that the buffer is large enough to take it...
- */
-/*v1.0 
-#ifndef __Lynx__ 
-#if RECV_BUFFER_SIZE < 5 //TCP_HEADER_LENGTH
-#error The receive buffer is smaller than the frame header length.
-#endif
-#endif
-*/
-
-int modbus_tcp_read(int *nd,                /* node descriptor */
-                    u8 *recv_data_ptr/*v1.0*/,
-                    u16 *transaction_id,
-                    u8 *send_data,         /* ignored ! */
-                    int send_length,       /* ignored ! */
-                    const struct timespec *recv_timeout) {
-
-  struct timespec cur_time, end_time, *ts_ptr;
-  /*v1.0
-  u8 *local_recv_data_ptr;
-  */
-  u16 local_transaction_id = 0;
-  u16 frame_length;
-  int orig_nd, fd, fd_high, data_already_available;
-
-#ifdef DEBUG
-  printf("modbus_tcp_read(): called...  nd=%d\n", *nd);
-#endif
-
-  if (nd == NULL)
-    return -1;
-
-  if (*nd >= nd_table_->node_count)
-    /* invalid *nd                      */
-    /* remember that *nd < 0 is valid!! */
-    return -1;
-
-  /*v1.0
-  if (recv_data_ptr == NULL)
-    recv_data_ptr = &local_recv_data_ptr;
-  */	
-  if (transaction_id == NULL)
-    transaction_id = &local_transaction_id;
-
-  /* We will potentially call read() multiple times to read in a single frame.
-   * We therefore determine the absolute time_out, and use this as a parameter
-   * for each call to read_bytes() instead of using a relative timeout.
-   *
-   * NOTE: see also the timeout related comment in the read_bytes() function!
-   *
-   * NOTE: clock_gettime() is rather expensive, between 7000 and 7500 clock
-   *       cycles (measured with rdtsc on an Intel Pentium)
-   *       gettimeofday() is half as expensive (3000 to 3500 clock cycles),
-   *       but is not POSIX compliant... :-(
-   *       Nevertheless this is peanuts (20 us on a 350 MHz cpu) compared to
-   *       the timescales required to read a modbus frame over a serial bus
-   *       (aprox. 10 ms for a 10 byte frame on a 9600 baud bus!)
-   */
-  /* get the current time... */
-  if (recv_timeout == NULL) {
-    ts_ptr = NULL;
-  } else {
-    ts_ptr = &end_time;
-    if ((recv_timeout->tv_sec == 0) && (recv_timeout->tv_nsec == 0)) {
-      end_time = *recv_timeout;
-    } else {
-      if (clock_gettime(CLOCK_REALTIME, &cur_time) < 0)
-        return -1;
-      end_time = timespec_add(cur_time, *recv_timeout);
-    }
-  }
-
-  /* We will loop forever...
-   * We jump out of the loop and return from the function as soon as:
-   *  - we receive a valid modbus message;
-   *    OR
-   *  - we time out.
-   */
-  orig_nd = *nd;
-  while(1) {
-    *nd = orig_nd;
-
-    /* If we must read off a single node... */
-    if (*nd >= 0)
-      /* but the node does not have a valid fd */
-      if ((nd_table_->node[*nd].addr.sin_family == MB_FREE_NODE) ||
-          (nd_table_->node[*nd].fd < 0))
-        /* then we return an error... */
-        return -1;
-
-    /* We want to call the read_bytes() function only after we are sure there
-     * is data waiting to be read on the socket, so we call select here.
-     *
-     * We only call select() here for the case when (*nd >= 0),
-     * since for the other case select() will be called later on...
-     */
-    data_already_available = 1;
-    if (*nd >= 0)
-      data_already_available = 0;
-
-    /* if *nd < 0, we will be:
-     *  - reading off any valid node descriptor!!
-     *  - and accepting new connection requests, if we have free nodes available!!
-     */
-    while (*nd < 0) {
-      int nd_count;
-      fd_set rfds;
-
-      if (nd_table_->free_node_count > 0) {
-        /* We have free nodes, so we will also listen on nodes
-         * that will accept new connections requests...
-         */
-        rfds = nd_table_->all_fds;
-        fd_high = nd_table_->all_fd_high;
-      } else {
-        /* We do not have free nodes, so we will only listen on nodes
-         * that do not accept new connections requests...
-         */
-        rfds = nd_table_->ms_fds;
-        fd_high = nd_table_->ms_fd_high;
-      }
-
-      if (my_select(fd_high + 1, &rfds, ts_ptr) < 0)
-        return -1;
-
-      /* figure out which nd is ready to be read... */
-      for (nd_count = 0; nd_count < nd_table_->node_count; nd_count++) {
-        if (nd_table_->node[nd_count].addr.sin_family != MB_FREE_NODE) {
-          if (FD_ISSET(nd_table_->node[nd_count].fd, &rfds)) {
-            /* Found the node descriptor... */
-            if (nd_table_->node[nd_count].addr.sin_family == MB_LISTEN_NODE) {
-              /* We must accept a new connection...
-               * No need to check for errors.
-               * If one occurs, there is nothing we can do...
-               */
-              *nd = accept_connection(nd_count);
-#ifdef DEBUG
-              printf("modbus_tcp_read(): new connection request on nd=%d\n", nd_count);
-              printf("modbus_tcp_read(): new connection accepted on nd=%d", *nd);
-#endif
-              *nd = -1; /* this will keep us in the while loop */
-            } else {
-              /* We will read a frame off this nd */
-              *nd = nd_count; /* this will get us out of the while loop later on. */
-            }
-            /* we have found the node descriptor, so let's jump out of the for(;;) loop */
-            break;
-          }
-        }
-      } /* for(;;) */
-    } /* while (*nd < 0) */
-
-    /* Just a consistency check... */
-    if (*nd < 0)
-      /* If the code is correct, this should never occur... */
-      return -1;
-
-#ifdef DEBUG
-    printf("modbus_tcp_read(): reading off nd=%d\n", *nd);
-#endif
-    /*=========================*
-     * read a Modbus TCP frame *
-     *=========================*/
-    /* assume error... */
-    fd = nd_table_->node[*nd].fd;
-	/*v1.0
-    *recv_data_ptr = NULL;
-	*/
-
-    /*-------------*
-     * read header *
-     *-------------*/
-    if (read_bytes(fd, recv_data_ptr/*v1.0*/, TCP_HEADER_LENGTH, ts_ptr, data_already_available)
-        == TCP_HEADER_LENGTH) {
-      /* let's check for header consistency... */
-      if (check_header(recv_data_ptr/*v1.0*/, transaction_id, &frame_length) < 0) {
-#ifdef DEBUG
-        printf("modbus_tcp_read(): frame with non valid header...\n");
-#endif
-        /* We let the code fall through to the error handler, that will
-         * close the connection!
-         * This is exactly what the modbus TCP protocol specifies!
-         */
-      } else {
-        /*-----------*
-         * read data *
-         *-----------*/
-        /* NOTE: the function read_bytes() assumes that there is data ready to be
-         *       read off the socket, so we have to call select() ourselves
-         *       before calling it.
-         */
-
-        data_already_available = 0;
-        if (read_bytes(fd, recv_data_ptr/*v1.0*/, frame_length, ts_ptr, data_already_available)
-            == frame_length) {
-          /* frame received succesfully... */
-#ifdef DEBUG
-          printf("\n");
-#endif
-		  /*v1.0
-          *recv_data_ptr = recv_buf_;
-		  */
-          return frame_length;
-        }
-      }
-    }
-
-    /* We had an error reading the frame...
-     * We handle it by closing the connection, as specified by
-     * the modbus TCP protocol!
-     */
-
-#ifdef DEBUG
-    printf("modbus_tcp_read(): error reading frame. Closing connection...\n");
-#endif
-    /* We close the socket... */
-    close_connection(*nd);
-
-    /* If it is a slave, we free the node... */
-    if(nd_table_->node[*nd].addr.sin_family == MB_SLAVE_NODE)
-        nd_table_close_node(nd_table_, *nd);
-
-    /* We try to read another frame... */
-  } /* while(1) */
-
-  /* humour the compiler... */
-  return -1;
-}
-
-
-
-
-
-
-/**************************************************************/
-/**************************************************************/
-/****                                                      ****/
-/****                                                      ****/
-/****        Initialising and Shutting Down Library        ****/
-/****                                                      ****/
-/****                                                      ****/
-/**************************************************************/
-/**************************************************************/
-
-
-/******************************/
-/**                          **/
-/**   Load Default Values    **/
-/**                          **/
-/******************************/
-
-static void set_defaults(const char **service) {
-  /* Set the default values, if required... */
-  if (*service == NULL)
-    *service = DEF_SERVICE;
-}
-
-
-/******************************/
-/**                          **/
-/**    Initialise Library    **/
-/**                          **/
-/******************************/
-/* returns the number of nodes succesfully initialised...
- * returns -1 on error.
- */
-int modbus_tcp_init(int nd_count,
-                    optimization_t opt /* ignored... */,
-                    int *extra_bytes) {
-#ifdef DEBUG
-  printf("modbus_tcp_init(): called...\n");
-  printf("creating %d nodes:\n", nd_count);
-#endif
-
-  if (nd_table_ != NULL)
-    /* library already previously initialised! */
-    return -1;
-
-  if (nd_count <= 0)
-    /* invalid node count... */
-    goto error_exit_0;
-
-    /* set the extra_bytes value... */
-    /* Please see note before the modbus_rtu_write() function for a
-     * better understanding of this extremely ugly hack... This will be
-     * in the mb_rtu.c file!!
-     *
-     * The number of extra bytes that must be allocated to the data buffer
-     * before calling modbus_tcp_write()
-     */
-  if (extra_bytes != NULL)
-    *extra_bytes = 0;
-
-  /* V1.0:  initialise recv buffer
-  recv_buf_ = malloc(sizeof(u8) * RECV_BUFFER_SIZE);
-  if (recv_buf_ == NULL) {
-    //plc_log_errmsg(1, "Out of memory: error initializing receive buffer");
-	printf("\nOut of memory: error initializing receive buffer\n");
-    goto error_exit_0;
-  }
-  */
-
-  /* create the node table structure... */
-  nd_table_ = (nd_table_t*) malloc(sizeof(nd_table_t));
-  if (nd_table_ == NULL) {
-    /*F.Locci 
-    plc_log_errmsg(1, "Out of memory: error initializing node table");
-	*/
-	printf("\nOut of memory: error initializing node table\n");
-    goto error_exit_1;
-  }
-
-  /* initialise the node table... */
-  if (nd_table_init(nd_table_, nd_count) < 0)
-    goto error_exit_2;
-
-#ifdef DEBUG
-  printf("modbus_tcp_init(): %d node(s) opened succesfully\n", nd_count);
-#endif
-  return nd_count; /* number of succesfully created nodes! */
-
-/*
-error_exit_3:
-  free(nd_table_->node);
-  nd_table_->node = NULL;
-  nd_table_->count = 0;
-*/
-error_exit_2:
-  free(nd_table_); nd_table_ = NULL;
-error_exit_1:
-  /*V1.0
-  free(recv_buf_); recv_buf_ = NULL;
-  */
-error_exit_0:
-  return -1;
-}
-
-
-
-
-
-
-/******************************/
-/**                          **/
-/**    Open a Master Node    **/
-/**                          **/
-/******************************/
-
-int modbus_tcp_connect(node_addr_t node_addr) {
-  int node_descriptor;
-  struct sockaddr_in tmp_addr;
-
-#ifdef DEBUG
-  printf("modbus_tcp_connect(): called...\n");
-  printf("        %s:%s\n",
-         node_addr.addr.tcp.host,
-         node_addr.addr.tcp.service);
-#endif
-
-  /* Check for valid address family */
-  if (node_addr.naf != naf_tcp)
-    /* wrong address type... */
-    return -1;
-
-  /* set the default values... */
-  set_defaults(&(node_addr.addr.tcp.service));
-
-  /* Check the parameters we were passed... */
-  if(sin_init_addr(&tmp_addr,
-                   node_addr.addr.tcp.host,
-                   node_addr.addr.tcp.service,
-                   DEF_PROTOCOL)
-       < 0) {
-    /*
-    plc_log_wrnmsg(1, "Error parsing/resolving address %s:%s",
-                   node_addr.addr.tcp.host,
-                   node_addr.addr.tcp.service);
-    */
-    return -1;
-  }
-
-  /* find a free node descriptor */
-    /* NOTE: The following code line works beacuse MB_MASTER_NODE is set to AF_INET! */
-#if MB_MASTER_NODE != AF_INET
-#error The code only works if MB_MASTER_NODE == AF_INET, which they are not!
-#endif
-  if ((node_descriptor = nd_table_get_free_node(nd_table_, MB_MASTER_NODE)) < 0)
-    /* if no free nodes to initialize, then we are finished... */
-    return -1;
-
-  nd_table_->node[node_descriptor].addr = tmp_addr;
-  nd_table_->node[node_descriptor].fd   = -1; /* not currently connected... */
-  nd_table_->node[node_descriptor].close_on_silence = node_addr.addr.tcp.close_on_silence;
-
-  if (nd_table_->node[node_descriptor].close_on_silence < 0)
-    nd_table_->node[node_descriptor].close_on_silence = DEF_CLOSE_ON_SILENCE;
-
-#ifdef DEBUG
-  printf("modbus_tcp_connect(): returning nd=%d\n", node_descriptor);
-#endif
-  return node_descriptor;
-}
-
-
-
-
-/******************************/
-/**                          **/
-/**    Open a Slave Node     **/
-/**                          **/
-/******************************/
-
-int modbus_tcp_listen(node_addr_t node_addr) {
-  int fd, nd;
-
-#ifdef DEBUG
-  printf("modbus_tcp_listen(): called...\n");
-  printf("        %s:%s\n",
-         node_addr.addr.tcp.host,
-         node_addr.addr.tcp.service);
-#endif
-
-  /* Check for valid address family */
-  if (node_addr.naf != naf_tcp)
-    /* wrong address type... */
-    goto error_exit_0;
-
-  /* set the default values... */
-  set_defaults(&(node_addr.addr.tcp.service));
-
-  /* create a socket and bind it to the appropriate port... */
-  fd = bind_socket(node_addr.addr.tcp.host,
-                   node_addr.addr.tcp.service,
-                   DEF_PROTOCOL);
-  if (fd < 0)
-    goto error_exit_0;
-  if (listen(fd, DEF_MAX_PENDING_CONNECTION_REQUESTS) < 0)
-    goto error_exit_0;
-
-  /* find a free node descriptor */
-  if ((nd = nd_table_get_free_node(nd_table_, MB_LISTEN_NODE)) < 0) {
-    /* if no free nodes to initialize, then we are finished... */
-    goto error_exit_1;
-  }
-
-  /* nd_table_->node[nd].addr = tmp_addr; */ /* does not apply for MB_LISTEN_NODE */
-  nd_table_->node[nd].fd = fd; /* not currently connected... */
-
-  /* update the fd sets...*/
-  FD_SET(fd, &(nd_table_->all_fds));
-  nd_table_->all_fd_high = max(nd_table_->all_fd_high, fd);
-
-#ifdef DEBUG
-  printf("modbus_tcp_listen(): returning nd=%d\n", nd);
-#endif
-  return nd;
-
-error_exit_1:
-  close(fd);
-error_exit_0:
-  return -1;
-}
-
-
-
-/******************************/
-/**                          **/
-/**       Close a node       **/
-/**                          **/
-/******************************/
-
-int modbus_tcp_close(int nd) {
-#ifdef DEBUG
-  printf("modbus_tcp_close(): called... nd=%d\n", nd);
-#endif
-
-/*F.Locci*/
-  if (nd_table_ == NULL) return -1;
-/**/  
-  
-  if ((nd < 0) || (nd >= nd_table_->node_count))
-   	/* invalid nd */
-   	return -1;
-
-  if (nd_table_->node[nd].addr.sin_family == MB_FREE_NODE)
-    /* already free node */
-    return 0;
-
-  close_connection(nd);
-
-  nd_table_->node[nd].addr.sin_family = MB_FREE_NODE;
-  nd_table_->free_node_count++;
-
-  return 0;
-}
-
-
-
-/**********************************/
-/**                              **/
-/**  Close all open connections  **/
-/**                              **/
-/**********************************/
-
-int modbus_tcp_silence_init(void) {
-  int nd;
-
-#ifdef DEBUG
-  printf("modbus_tcp_silence_init(): called...\n");
-#endif
-
-  /* close all master connections that remain open... */
-  for (nd = 0; nd < nd_table_->node_count; nd++)
-    if (nd_table_->node[nd].addr.sin_family == MB_MASTER_NODE)
-      if (nd_table_->node[nd].close_on_silence > 0)
-        /* node is is being used for a master device,
-         * and wishes to be closed...   ...so we close it!
-         */
-         close_connection(nd);
-
-  return 0;
-}
-
-
-
-/******************************/
-/**                          **/
-/**   Shutdown the Library   **/
-/**                          **/
-/******************************/
-
-int modbus_tcp_done(void) {
-  int i;
-
-/*F.Locci*/
-  if (nd_table_ == NULL) return -1;
-/**/  
-
-    /* close all the connections... */
-  for (i = 0; i < nd_table_->node_count; i++)
-    modbus_tcp_close(i);
-
-  /* Free memory... */
-  free(nd_table_->node);
-  /*V1.0
-  free(recv_buf_); recv_buf_ = NULL;
-  */
-  free(nd_table_); nd_table_ = NULL;
-
-  return 0;
-}
-
-
-
-
-double modbus_tcp_get_min_timeout(int baud,
-                                  int parity,
-                                  int data_bits,
-                                  int stop_bits) {
-  return 0;
-}
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/silecs-communication-cpp/src/silecs-communication/protocol/modbus/mb_tcp_private.h b/silecs-communication-cpp/src/silecs-communication/protocol/modbus/mb_tcp_private.h
deleted file mode 100644
index b05ca22cc8800608d9d67ab8d3c43a6beea0fb26..0000000000000000000000000000000000000000
--- a/silecs-communication-cpp/src/silecs-communication/protocol/modbus/mb_tcp_private.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * (c) 2002 Mario de Sousa
- *
- * Offered to the public under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
- * Public License for more details.
- *
- * This code is made available on the understanding that it will not be
- * used in safety-critical situations without a full and competent review.
- */
-
-
-#ifndef MODBUS_TCP_PRIVATE_H
-#define MODBUS_TCP_PRIVATE_H
-
-/*F.Locci #include <plc.h>*/  /* get the plc data types */
-#include "mb_util.h"
-
-
-/* tcp port default configuration... */
-#define DEF_SERVICE  "502"        /* port used by modbus */
-#define DEF_PROTOCOL "tcp"        /* protocol used by modbus tcp */
-#define DEF_TYPE     SOCK_STREAM  /* Quality of service required of the socket... */
-#define DEF_MAX_PENDING_CONNECTION_REQUESTS 5
-                                  /* maximum number of pending connection requests
-                                   * that have not yet been accept()'ed
-                                   */
-#define DEF_CLOSE_ON_SILENCE 1    /* Used only by master nodes.
-                                   * Flag indicating whether, by default, the connection
-                                   * to the slave device should be closed whenever the
-                                   * modbus_tcp_silence_init() function is called.
-                                   *
-                                   * 0  -> do not close connection
-                                   * >0 -> close connection
-                                   *
-                                   * The spec sugests that connections that will not
-                                   * be used for longer than 1 second should be closed.
-                                   * Even though we expect most connections to have
-                                   * silence intervals much shorted than 1 second, we
-                                   * decide to use the default of shuting down the
-                                   * connections because it is safer, and most other
-                                   * implementations seem to do the same.
-                                   * If we do not close we risk using up all the possible
-                                   * connections that the slave can simultaneouly handle,
-                                   * effectively locking out every other master that
-                                   * wishes to communicate with that same slave.
-                                   */
-
- /* Since the receive buffer is also re-used to store the frame header,
-  * we set it to the larger of the two.
-  */
-#ifndef __Lynx__
-
-#if     TCP_HEADER_LENGTH > MAX_L2_FRAME_LENGTH
-#define RECV_BUFFER_SIZE    TCP_HEADER_LENGTH
-#else
-#define RECV_BUFFER_SIZE    MAX_L2_FRAME_LENGTH
-#endif
-
-#else  
-
-#if     defined(TCP_HEADER_LENGTH) > defined(MAX_L2_FRAME_LENGTH)
-#define RECV_BUFFER_SIZE    TCP_HEADER_LENGTH
-#else
-#define RECV_BUFFER_SIZE    MAX_L2_FRAME_LENGTH
-#endif
-
-#endif  
-
-
-#endif  /* MODBUS_TCP_PRIVATE_H */
-
-
-
-
-
-
-
-
diff --git a/silecs-communication-cpp/src/silecs-communication/protocol/modbus/mb_time_util.h b/silecs-communication-cpp/src/silecs-communication/protocol/modbus/mb_time_util.h
deleted file mode 100644
index e17dc5291874284712bbac99529a309af53c88da..0000000000000000000000000000000000000000
--- a/silecs-communication-cpp/src/silecs-communication/protocol/modbus/mb_time_util.h
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * (c) 2002 Mario de Sousa
- *
- * Offered to the public under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
- * Public License for more details.
- *
- * This code is made available on the understanding that it will not be
- * used in safety-critical situations without a full and competent review.
- */
-
-
- /* Time handling functions used by the modbus protocols... */
-#include <time.h>
-
-#ifndef __MODBUS_TIME_UTIL_H
-#define __MODBUS_TIME_UTIL_H
-
-
-/************************************/
-/**                                **/
-/**     Time format conversion     **/
-/**                                **/
-/************************************/
-
-/* Function to load a struct timeval correctly
- * from a double.
- */
-static inline struct timeval d_to_timeval(double time) {
-  struct timeval tmp;
-
-  tmp.tv_sec  = time;
-  tmp.tv_usec = 1e6*(time - tmp.tv_sec);
-  return tmp;
-}
-
-/* Function to ... */
-static inline struct timespec timespec_dif(struct timespec ts1, struct timespec ts2) {
-  struct timespec ts;
-
-  ts.tv_sec  = ts1.tv_sec  - ts2.tv_sec;
-  if(ts1.tv_nsec > ts2.tv_nsec) {
-    ts.tv_nsec = ts1.tv_nsec - ts2.tv_nsec;
-  } else {
-    ts.tv_nsec = 1000000000 + ts1.tv_nsec - ts2.tv_nsec;
-    ts.tv_sec--;
-  }
-
-  if (ts.tv_sec < 0)
-    ts.tv_sec = ts.tv_nsec = 0;
-
-  return ts;
-}
-
-/* Function to ... */
-static inline struct timespec timespec_add(struct timespec ts1, struct timespec ts2) {
-  struct timespec ts;
-
-  ts.tv_sec  = ts1.tv_sec  + ts2.tv_sec;
-  ts.tv_nsec = ts1.tv_nsec + ts2.tv_nsec;
-  ts.tv_sec += ts.tv_nsec / 1000000000;
-  ts.tv_nsec = ts.tv_nsec % 1000000000;
-  return ts;
-}
-
-/* Function to convert a struct timespec to a struct timeval. */
-static inline struct timeval timespec_to_timeval(struct timespec ts) {
-  struct timeval tv;
-
-  tv.tv_sec  = ts.tv_sec;
-  tv.tv_usec = ts.tv_nsec/1000;
-  return tv;
-}
-
-
-
-/************************************/
-/**                                **/
-/** select() with absolute timeout **/
-/**                                **/
-/************************************/
-
-
-/* My private version of select using an absolute timeout, instead of the
- * usual relative timeout.
- *
- * NOTE: Ususal select semantics for (a: end_time == NULL) and
- *       (b: *end_time == 0) also apply.
- *
- *       (a) Indefinite timeout
- *       (b) Try once, and and quit if no data available.
- */
-static int my_select(int fd, fd_set *rfds, const struct timespec *end_time) {
-
-  int res;
-  struct timespec cur_time;
-  struct timeval timeout, *tv_ptr;
-  fd_set tmp_fds;
-
-  /*============================*
-   * wait for data availability *
-   *============================*/
-  do {
-    tmp_fds = *rfds;
-      /* NOTE: To do the timeout correctly we would have to revert to timers
-       *       and asociated signals. That is not very thread friendly, and is
-       *       probably too much of a hassle trying to figure out which signal
-       *       to use. What if we don't have any free signals?
-       *
-       *       The following solution is not correct, as it includes a race
-       *       condition. The following five lines of code should really
-       *       be atomic!
-       *
-       * NOTE: see also the timeout related comment in the
-       *       modbus_tcp_read() function!
-       */
-    if (end_time == NULL) {
-      tv_ptr = NULL;
-    } else {
-      tv_ptr = &timeout;
-      if ((end_time->tv_sec == 0) && (end_time->tv_nsec == 0)) {
-        timeout.tv_sec = timeout.tv_usec = 0;
-      } else {
-        /* ATOMIC - start */
-        if (clock_gettime(CLOCK_REALTIME, &cur_time) < 0)
-          return -1;
-        timeout = timespec_to_timeval(timespec_dif(*end_time, cur_time));
-      }
-    }
-
-    res = select(fd, &tmp_fds, NULL, NULL, tv_ptr);
-  /* ATOMIC - end */
-
-    if (res == 0) {
-#ifdef DEBUG
-      printf("Comms time out\n");
-#endif
-      return -1;
-    }
-    if ((res < 0) && (errno != EINTR)) {
-      return -1;
-    }
-  } while (res <= 0);
-
-  *rfds = tmp_fds;
-  return res;
-}
-
-
-
-
-
-
-#endif  /* __MODBUS_TIME_UTIL_H */
diff --git a/silecs-communication-cpp/src/silecs-communication/protocol/modbus/mb_util.h b/silecs-communication-cpp/src/silecs-communication/protocol/modbus/mb_util.h
deleted file mode 100644
index 9d8ea0868bf986eeeb164985cefb0208aafac55a..0000000000000000000000000000000000000000
--- a/silecs-communication-cpp/src/silecs-communication/protocol/modbus/mb_util.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * (c) 2002 Mario de Sousa
- *
- * Offered to the public under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
- * Public License for more details.
- *
- * This code is made available on the understanding that it will not be
- * used in safety-critical situations without a full and competent review.
- */
-
-
-#ifndef MB_UTIL_H
-#define MB_UTIL_H
-
-/* This file has constants related to the modbus protocol */
-/*
- * Some of these constants are specific to the layer two protocols
- * (i.e. master and slave), while others are specific of the
- * layer one protocols (i.e. rtu, ascii, tcp).
- *
- * a) Unfortunately, due to the nature of the modbus protocol, that does not
- * include a frame size field in the layer 1 frame (see note 1), and the
- * fact that we are implementing it at the user level, the implementation
- * of some layer 1 protocols need to know the content of the layer 2 protocol
- * in order to determine the size of the frame.
- *
- * b) The layer two message formats are in fact the same, just reversing the role
- * being played (master or slave).
- *
- * Bothe a) and b) mean we need the same modbus protocol constants in several files.
- * It ends up making more sense to put them all together in a single file, which
- * makes updating easier, even though we are trying to strictly seperate the layer 1
- * and layer 2 protocols.
- *
- *
- *
- * Notes:
- *  (1) There is no layer 1 field with the frame size, nevertheless this
- *      size can be determined indirectly due to timing restrictions on the rtu
- *      protocol. Unfortunately, due to the fact that we are implementing
- *      it at the user level, we are not guaranteed to detect these timings
- *      correctly, and therefore have to rely on layer 2 protocol info to
- *      determine the frame size.
- *      For the ascii protocol, the frame size is determined indirectly by
- *      a frame header and tail, so we do not use layer 2 protocol info.
- */
-
-
- /* Layer 2 Frame Structure...                */
- /* Valid for both master and slave protocols */
-#define L2_FRAME_HEADER_LENGTH    6
-#define L2_FRAME_BYTECOUNT_LENGTH 1
-#define L2_FRAME_DATABYTES_LENGTH 255
-#define MAX_L2_FRAME_LENGTH (L2_FRAME_HEADER_LENGTH + L2_FRAME_BYTECOUNT_LENGTH + L2_FRAME_DATABYTES_LENGTH)
-
-#define L2_FRAME_SLAVEID_OFS    0
-#define L2_FRAME_FUNCTION_OFS   1
-
- /* Layer 1 - Ascii Frame sizes... */
-#define L2_TO_ASC_CODING        2 /* number of ascii bytes used to code a Layer 2 frame byte */
-#define ASC_FRAME_HEADER_LENGTH 1
-#define ASC_FRAME_HEADER        ':'
-#define ASC_FRAME_TAIL_LENGTH   2
-#define ASC_FRAME_TAIL_0        '\13' /* 'CR' */
-#define ASC_FRAME_TAIL_1        '\10' /* 'LF' */
-#define ASC_FRAME_LRC_LENGTH    2
-
- /* Layer 1 - RTU Frame sizes... */
-#define RTU_FRAME_CRC_LENGTH    2
-
- /* Layer 1 - TCP Frame sizes... */
-#define TCP_HEADER_LENGTH       6
-
- /* Global Frame sizes */
-#define MAX_RTU_FRAME_LENGTH MAX_L2_FRAME_LENGTH + RTU_FRAME_CRC_LENGTH
-#define MAX_ASC_FRAME_LENGTH ((MAX_L2_FRAME_LENGTH * L2_TO_ASC_CODING) + ASC_FRAME_HEADER_LENGTH + ASC_FRAME_TAIL_LENGTH + ASC_FRAME_LRC_LENGTH)
-
-#endif  /* MB_UTIL_H */
-
-
-
-
-
-
-
-
diff --git a/silecs-communication-cpp/src/silecs-communication/protocol/modbus/sin_util.cpp b/silecs-communication-cpp/src/silecs-communication/protocol/modbus/sin_util.cpp
deleted file mode 100644
index 682f4bbc2679bfd2f311b60fb9d9416b18c799db..0000000000000000000000000000000000000000
--- a/silecs-communication-cpp/src/silecs-communication/protocol/modbus/sin_util.cpp
+++ /dev/null
@@ -1,229 +0,0 @@
-/*
- * (c) 2000 Jiri Baum
- *          Mario de Sousa
- *
- * Offered to the public under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
- * Public License for more details.
- *
- * This code is made available on the understanding that it will not be
- * used in safety-critical situations without a full and competent review.
- */
-
-
-/*
- * Socket INET utility routines
- *
- * This file implements the routines in sin_util.h
- *
- * These routines merely make life simpler when working with
- * internet protocol sockets
- */
-#include "sin_util.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <string.h>
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-#define ERR_EXIT(mesg, err_num) {perror(mesg);return err_num;}
-#define MSG_EXIT(mesg, err_num) {fprintf(stderr, "%s\n", mesg);return err_num;}
-
-
-int sin_init_dot_addr(struct sockaddr_in *sad_in,
-                  char *dot_addr,
-                  unsigned short int port)
-{
-sad_in->sin_family = AF_INET;
-
-if( inet_aton(dot_addr, &(sad_in->sin_addr)) == 0 )
-   ERR_EXIT("inet_aton", -1);
-
-sad_in->sin_port = htons(port);
-
-return 1;
-}  /* sin_init_dot_addr */
-
-
-
-
-
-int sin_init_addr(struct sockaddr_in *addr,
-                  const char *host,
-                  const char *service,
-                  const char *protocol)
-/* initialize an address structure */
-{
-int port_flag;
-long int tmp_numb;
-long long int lli = 1;
-char *error_char;
-
-struct servent *serv_entry_ptr;
-struct hostent *host_entry_ptr;
-
-bzero ((char *)addr, sizeof(*addr));
-addr->sin_family = AF_INET;
-
-/* Map service name to port number */
-port_flag = 0;
-if (port_flag == 0)
- if ((service == NULL) || (strcmp(service, "") == 0))
-   {addr->sin_port = htons(0); /* OS will sugest a port when binding */
-    port_flag = 1;
-   }
-
-if (port_flag == 0)
-   if ((serv_entry_ptr = getservbyname ((char *)service, (char *)protocol)) )
-      {addr->sin_port = serv_entry_ptr->s_port;
-       port_flag = 1;
-      }
-
-if (port_flag == 0)
-   {tmp_numb = strtol(service, &error_char, 0);
-    if ((*error_char == '\0') && (error_char != service) && 
-        (tmp_numb >= 0) && (tmp_numb < (lli << (8*sizeof(addr->sin_port)))))
-       {addr->sin_port = htons(tmp_numb);
-        port_flag = 1;
-       }
-   }
-
-if (port_flag == 0)
-   MSG_EXIT("sin_init_addr: Could not determine the port number.", -1);
- 
-/* Map host name to IP address, allowing dotted decimal */
-addr->sin_addr.s_addr = INADDR_NONE;
- 
-if (addr->sin_addr.s_addr == INADDR_NONE)
-   if ( (host_entry_ptr = gethostbyname ((char *)host)) )
-      bcopy (host_entry_ptr->h_addr, 
-             (char *)&(addr->sin_addr), 
-             host_entry_ptr->h_length);
-
-if (addr->sin_addr.s_addr == INADDR_NONE)
-   inet_aton (host, (struct in_addr *)addr);  
-
-if (addr->sin_addr.s_addr == INADDR_NONE)
-   MSG_EXIT("sin_init_addr: Could not determine the host IP address.", -1);
-
-return 1;
-} /* sin_init_addr(...) */
-
-
-
-
-int sin_init_proto(int *type,
-                   int *protocol_num,
-                   const char *protocol)
-{
-struct protoent *proto_entry_ptr;
-
-/* determine the protocol */
-*type = SOCK_RDM;
-if (strcasecmp (protocol, "udp") == 0) *type = SOCK_DGRAM;
-if (strcasecmp (protocol, "tcp") == 0) *type = SOCK_STREAM;
-if (strcasecmp (protocol, "raw") == 0) *type = SOCK_RAW;
-if (*type == SOCK_RDM)
-   MSG_EXIT ("sin_init_proto: protocol not supported.", -1);
-
-/* map protocol name to protocol number */
-if ( (proto_entry_ptr = getprotobyname ((char *)protocol)) == NULL )
-   MSG_EXIT ("sin_init_proto: can't get protocol number.", -1);
-*protocol_num = proto_entry_ptr->p_proto;
-
-return 1;
-} /* sin_init_proto(...) */
-
-
-int bind_socket(const char *host,
-                const char *service,
-                const char *protocol)
-/* create a socket and bind to a local port */
-{
-struct sockaddr_in sock_addr;
-int socket_id, type, protocol_num;
-
-/* initialize the sock_addr sturcture */
-if ( (sin_init_addr (&sock_addr, host, service, protocol)) < 0)
-   MSG_EXIT ("bind_socket: wrong address format", -1);
-
-/* determine the protocol */
-if ( (sin_init_proto (&type, &protocol_num, protocol)) < 0)
-   MSG_EXIT ("bind_socket: wrong protocol format", -1);
-
-/* create the socket */
-if ( (socket_id = socket (PF_INET, type, protocol_num)) < 0)
-   ERR_EXIT ("socket", -1);
-
-/* bind the socket */
-if ( bind (socket_id, (struct sockaddr *)&sock_addr, sizeof (sock_addr)) < 0)
-   ERR_EXIT ("bind", -1);
-
-return socket_id;
-} /* bind_socket(...) */
-
-
-
-int connect_socket(const char *host,
-                   const char *service,
-                   const char *protocol)
-/* create a socket and connect to a remote host */
-{
-struct sockaddr_in sock_addr;
-int socket_id, type, protocol_num;
-
-/* initialize the sock_addr sturcture */
-if ( (sin_init_addr (&sock_addr, host, service, protocol)) < 0)
-   MSG_EXIT ("bind_socket: wrong address format", -1);
-
-/* determine the protocol */
-if ( (sin_init_proto (&type, &protocol_num, protocol)) < 0)
-   MSG_EXIT ("bind_socket: wrong protocol format", -1);
-
-/* create the socket */
-if ( (socket_id = socket (PF_INET, type, protocol_num)) < 0)
-   ERR_EXIT ("socket", -1);
-
-/* bind the socket */
-if ( connect(socket_id, (struct sockaddr *)&sock_addr, sizeof (sock_addr)) < 0)
-   ERR_EXIT ("bind", -1);
-
-return socket_id;
-} /* connect_socket(...) */
-
-
-
-int get_socket_port(int sock)
-/* returns the port to which the socket is bound */ 
-{
- int length;
- struct sockaddr_in srv_addr;  
-
- length = sizeof(srv_addr);
- if (getsockname(sock, (struct sockaddr *)&srv_addr, (socklen_t *)&length) < 0)
-   return -1;
-
- if (srv_addr.sin_family == AF_INET)
-   return ntohs(srv_addr.sin_port);
-
- return -1; /* not INET socket... */
-} /* get_socket_port(...) */
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/silecs-communication-cpp/src/silecs-communication/protocol/modbus/sin_util.h b/silecs-communication-cpp/src/silecs-communication/protocol/modbus/sin_util.h
deleted file mode 100644
index 5e6a6b6499532c60288bc7a463aee775fb51310c..0000000000000000000000000000000000000000
--- a/silecs-communication-cpp/src/silecs-communication/protocol/modbus/sin_util.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * (c) 2000 Jiri Baum
- *          Mario de Sousa
- *
- * Offered to the public under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
- * Public License for more details.
- *
- * This code is made available on the understanding that it will not be
- * used in safety-critical situations without a full and competent review.
- */
-
-
-#ifndef SIN_UTIL_H
-#define SIN_UTIL_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-
-
-
-int sin_init_addr(struct sockaddr_in *addr,
-                  const char *host,
-                  const char *service,
-                  const char *protocol);
-/* initialize an address structure */
-
-
-int bind_socket(const char *host,
-                const char *service,
-                const char *protocol);
-/* create a socket and bind to a local port */
-
-
-int connect_socket(const char *host,
-                   const char *service,
-                   const char *protocol);
-/* create a socket and connect to a remote host */
-
-
-int get_socket_port(int sock);
-/* returns the port to which the socket is bound */
-
-#ifdef __cplusplus
-}
-#endif
-#endif