From c3a345d3bfa8ce8a728e9c933a94304551c43a1c Mon Sep 17 00:00:00 2001
From: Jade PHAM <jade.pham@synchrotron-soleil.fr>
Date: Mon, 22 Jul 2024 11:29:31 +0200
Subject: [PATCH] TANGODEVIC-2411 add Ethernet communication mode

---
 include/N_PhotoConducteur.h |   2 +-
 include/N_PhotoVoltaique.h  |   2 +-
 include/NovelecProtocol.h   |  19 +--
 include/Novelec_MCCE2.h     |   4 +-
 include/TangoEthernetLink.h |  80 +++++++++++
 include/TangoSerialLink.h   | 185 +++++++++++++-------------
 src/N_PhotoConducteur.cpp   |   4 +-
 src/N_PhotoVoltaique.cpp    |   4 +-
 src/NovelecProtocol.cpp     |  32 ++---
 src/Novelec_MCCE2.cpp       |   8 +-
 src/TangoEthernetLink.cpp   | 258 ++++++++++++++++++++++++++++++++++++
 src/TangoSerialLink.cpp     |  58 ++++----
 12 files changed, 498 insertions(+), 158 deletions(-)
 create mode 100644 include/TangoEthernetLink.h
 mode change 100644 => 100755 include/TangoSerialLink.h
 create mode 100644 src/TangoEthernetLink.cpp
 mode change 100644 => 100755 src/TangoSerialLink.cpp

diff --git a/include/N_PhotoConducteur.h b/include/N_PhotoConducteur.h
index 14b2183..9605e6b 100755
--- a/include/N_PhotoConducteur.h
+++ b/include/N_PhotoConducteur.h
@@ -36,7 +36,7 @@ public:
 	*  \brief Initialization.
 	*/
 //	N_PhotoConducteur (std::string& comLink_device_name, short channel_address, short electroType);
-	N_PhotoConducteur (std::string& comLink_device_name, short channel_address);
+	N_PhotoConducteur (std::string& comLink_device_name, short channel_address, std::string comProtocol);
 
 	/**
 	*  \brief Release resources.
diff --git a/include/N_PhotoVoltaique.h b/include/N_PhotoVoltaique.h
index 39f215e..9e1e6d7 100755
--- a/include/N_PhotoVoltaique.h
+++ b/include/N_PhotoVoltaique.h
@@ -36,7 +36,7 @@ public:
 	*  \brief Initialization.
 	*/
 //	N_PhotoVoltaique (std::string comLink_device_name, short channel_address, short electroType);
-	N_PhotoVoltaique (std::string comLink_device_name, short channel_address);
+	N_PhotoVoltaique (std::string comLink_device_name, short channel_address, std::string comProtocol);
 
 	/**
 	*  \brief Release resources.
diff --git a/include/NovelecProtocol.h b/include/NovelecProtocol.h
index 6b518c4..39b2a45 100644
--- a/include/NovelecProtocol.h
+++ b/include/NovelecProtocol.h
@@ -17,6 +17,7 @@
 #include "ElectrometerProtocol.h"
 #include "ElectrometerException.h"
 #include "TangoSerialLink.h"
+#include "TangoEthernetLink.h"
 
 /**
  *  \addtogroup Standard Commands Protocol
@@ -38,7 +39,7 @@ public:
 	*  \brief Initialization.
 	*/
 	//NovelecProtocol (std::string& communication_device_name, unsigned short channel_address, unsigned short electroTypeNumber);
-	NovelecProtocol (std::string& communication_device_name, unsigned short channel_address);
+	NovelecProtocol (std::string& communication_device_name, unsigned short channel_address, std::string comProtocol);
 
 	/**
 	*  \brief Release resources.
@@ -89,17 +90,17 @@ public:
 	std::string get_frequency	(void);
 	std::string get_gain		  (void);
 	std::string get_errors		(void);
-	short get_electrometerType(void) {
-	  return this->_novType;
+	short get_electrometerType(void) {
+	  return this->_novType;
 	}
 	void set_polarity	  (std::string pola);
 	void set_frequency	(std::string freq);
 	void set_gain		    (std::string gain);
-	void set_electrometer_active_channel(unsigned short channel_add) {
-	  this->_devAdd = channel_add;
+	void set_electrometer_active_channel(unsigned short channel_add) {
+	  this->_devAdd = channel_add;
   }
-	unsigned short get_electrometer_active_channel(void) {
-	  return this->_devAdd;
+	unsigned short get_electrometer_active_channel(void) {
+	  return this->_devAdd;
   }
 
 	/**
@@ -109,7 +110,7 @@ public:
 	*        - clear error(s)
 	*/
 	void init_MCCE2_for_communication(void);
-  std::string check_electrotype (void);
+  std::string check_electrotype (void);
 
 protected :
 	short _devAdd;								//- novelec active channel address
@@ -129,6 +130,8 @@ private :
 	void is_allowed();
 
 	CommunicationLink* _communication_link;
+	//communication protocol ETHERNET/SERIAL
+	std::string _comProtocol;
 
 	//- if true, parameters cannot be changed !
 	bool	_is_measure_mode_on;
diff --git a/include/Novelec_MCCE2.h b/include/Novelec_MCCE2.h
index e491201..d18957b 100755
--- a/include/Novelec_MCCE2.h
+++ b/include/Novelec_MCCE2.h
@@ -36,7 +36,7 @@ public:
 	*  \brief Initialization.
 	*/
 //	Novelec_MCCE2 (std::string& comLink_device_name, unsigned short channel_address, unsigned short electroType);
-	Novelec_MCCE2 (std::string& comLink_device_name, unsigned short channel_address);
+	Novelec_MCCE2 (std::string& comLink_device_name, unsigned short channel_address, std::string comProtocol);
 
 	/**
 	*  \brief Release resources.
@@ -100,6 +100,8 @@ protected :
 	*	\brief Checks the new range value
 	*/
 	short check_range_value(const std::string& rgToCheck, const std::vector<std::string>	 electroRangeList);
+private:
+	std::string _comProtocol;
 
 };
 
diff --git a/include/TangoEthernetLink.h b/include/TangoEthernetLink.h
new file mode 100644
index 0000000..c8f34cb
--- /dev/null
+++ b/include/TangoEthernetLink.h
@@ -0,0 +1,80 @@
+// ============================================================================
+//
+// = CONTEXT
+//    TANGO Project - Keithley Electrometer Support Library
+//
+// = FILENAME
+//    TangoEthernetLink.h
+//
+// = AUTHOR
+//    X. Elattaoui
+//
+// ============================================================================
+
+#ifndef _TANGO_ETHERNET_LINK_H_
+#define _TANGO_ETHERNET_LINK_H_
+
+// ============================================================================
+// DEPENDENCIES
+// ============================================================================
+#include <tango.h>
+#include "CommunicationLink.h"
+
+/**
+ *  \addtogroup Communication Management
+ *  @{
+ */
+
+/**
+ *  \brief This class manage the ETHERNET communication bus
+ *
+ *  \author
+ *  \date
+ */
+
+class TangoEthernetLink : public CommunicationLink
+{
+
+public :
+ 	/**
+	* \brief Initialization.
+	*/
+	TangoEthernetLink (std::string& serial_device_name);
+
+	/**
+	* \brief Release resources.
+	*/
+	~TangoEthernetLink ();
+
+	/**
+	*  \brief Send command (data) as string to hardware.
+	*
+	*  \throws Tango::DevFailed
+	*/
+	void write(std::string cmd)	 throw (Tango::DevFailed);
+
+	std::string read(void) throw (Tango::DevFailed);
+
+	/**
+	*  \brief Performs a write read operation as string. (read nb char)
+	*
+	*  \throws Tango::DevFailed
+	*/
+	std::string write_read(std::string cmd, size_t nbChar)  throw (Tango::DevFailed);
+
+private :
+
+  /**
+	* Creates a proxy on the specified Serial Device.
+	*/
+	void check_proxy(void) throw (Tango::DevFailed);
+
+	Tango::DeviceProxy* _ethernet_proxy;
+
+	bool _is_ethernet_proxy_ok;
+
+};
+
+/** @} */	//- end addtogroup
+
+#endif // _TANGO_ETHERNET_LINK_H_
diff --git a/include/TangoSerialLink.h b/include/TangoSerialLink.h
old mode 100644
new mode 100755
index 0c7c518..9af3863
--- a/include/TangoSerialLink.h
+++ b/include/TangoSerialLink.h
@@ -1,93 +1,92 @@
-// ============================================================================
-//
-// = CONTEXT
-//    TANGO Project - Keithley Electrometer Support Library
-//
-// = FILENAME
-//    TangoSerialLink.h
-//
-// = AUTHOR
-//    X. Elattaoui
-//
-// ============================================================================
-
-#ifndef _TANGO_SERIAL_LINK_H_
-#define _TANGO_SERIAL_LINK_H_
-
-// ============================================================================
-// DEPENDENCIES
-// ============================================================================
-#include <tango.h>
-#include "CommunicationLink.h"
-
-/**
- *  \addtogroup Communication Management
- *  @{
- */
-
-/**
- *  \brief This class manage the SERIAL communication bus
- *
- *  \author Xavier Elattaoui
- *  \date 11-2006
- */
-
-class TangoSerialLink : public CommunicationLink
-{
-
-public :
- 	/**
-	* \brief Initialization.
-	*/
-	TangoSerialLink (std::string& serial_device_name);
-
-	/**
-	* \brief Release resources.
-	*/
-	~TangoSerialLink ();
-
-	/**
-	*  \brief Send command (data) as string to hardware.
-	*
-	*  \throws Tango::DevFailed
-	*/
-	void write(std::string cmd)	 throw (Tango::DevFailed);
-
-	/**
-	*  \brief Gets hardware response as string. (mode LINE)
-	*
-	*  \throws Tango::DevFailed
-	*/
-	std::string read(void)		 throw (Tango::DevFailed);
-
-	/**
-	*  \brief Gets hardware response as string. (read nbCharToRead)
-	*
-	*  \throws Tango::DevFailed
-	*/
-	std::string read(long nbCharToRead)		 throw (Tango::DevFailed);
-
-	/**
-	*  \brief Performs a write read operation as string. (read nb char)
-	*
-	*  \throws Tango::DevFailed
-	*/
-	std::string write_read(std::string cmd, size_t nbChar)  throw (Tango::DevFailed);
-
-private :
-
-  /**
-	* Creates a proxy on the specified Serial Device.
-	*/
-	void create_serial_proxy(void) throw (Tango::DevFailed);
-
-	//Tango::DeviceProxyHelper* _serial_proxy;
-	Tango::DeviceProxy* _serial_proxy;
-
-	bool _is_serial_proxy_created;
-
-};
-
-/** @} */	//- end addtogroup
-
-#endif // _TANGO_SERIAL_LINK_H_
+// ============================================================================
+//
+// = CONTEXT
+//    TANGO Project - Keithley Electrometer Support Library
+//
+// = FILENAME
+//    TangoSerialLink.h.h
+//
+// = AUTHOR
+//    X. Elattaoui
+//
+// ============================================================================
+
+#ifndef _TANGO_SERIAL_LINK_H_
+#define _TANGO_SERIAL_LINK_H_
+
+// ============================================================================
+// DEPENDENCIES
+// ============================================================================
+#include <tango.h>
+#include "CommunicationLink.h"
+
+/**
+ *  \addtogroup Communication Management
+ *  @{
+ */
+
+/**
+ *  \brief This class manage the SERIAL communication bus
+ *
+ *  \author Xavier Elattaoui
+ *  \date 11-2006
+ */
+
+class TangoSerialLink : public CommunicationLink
+{
+
+public :
+ 	/**
+	* \brief Initialization.
+	*/
+	TangoSerialLink (std::string& serial_device_name);
+
+	/**
+	* \brief Release resources.
+	*/
+	~TangoSerialLink ();
+
+	/**
+	*  \brief Send command (data) as string to hardware.
+	*
+	*  \throws Tango::DevFailed
+	*/
+	void write(std::string cmd)	 throw (Tango::DevFailed);
+
+	/**
+	*  \brief Gets hardware response as string. (mode LINE)
+	*
+	*  \throws Tango::DevFailed
+	*/
+	std::string read(void)		 throw (Tango::DevFailed);
+
+	/**
+	*  \brief Gets hardware response as string. (read nbCharToRead)
+	*
+	*  \throws Tango::DevFailed
+	*/
+	std::string read(long nbCharToRead)		 throw (Tango::DevFailed);
+
+	/**
+	*  \brief Performs a write read operation as string. (read nb char)
+	*
+	*  \throws Tango::DevFailed
+	*/
+	std::string write_read(std::string cmd, size_t nbChar)  throw (Tango::DevFailed);
+
+private :
+
+  /**
+	* Creates a proxy on the specified Serial Device.
+	*/
+	void check_proxy(void) throw (Tango::DevFailed);
+
+	Tango::DeviceProxy* _serial_proxy;
+
+	bool _is_serial_proxy_ok;
+
+};
+
+/** @} */	//- end addtogroup
+
+#endif // _TANGO_SERIAL_LINK_H_
diff --git a/src/N_PhotoConducteur.cpp b/src/N_PhotoConducteur.cpp
index f11be52..fbd1789 100755
--- a/src/N_PhotoConducteur.cpp
+++ b/src/N_PhotoConducteur.cpp
@@ -31,8 +31,8 @@ static const std::vector<std::string> NType5_rangeValue {"1000","300","100","30"
 // ============================================================================
 // N_PhotoConducteur::N_PhotoConducteur
 // ============================================================================
-N_PhotoConducteur::N_PhotoConducteur (std::string& comLink_device_name, short address)
-:	Novelec_MCCE2(comLink_device_name, address)
+N_PhotoConducteur::N_PhotoConducteur (std::string& comLink_device_name, short address, std::string comProtocol)
+:	Novelec_MCCE2(comLink_device_name, address, comProtocol)
 {
 	//std::cout << "N_PhotoConducteur::N_PhotoConducteur <-" << std::endl;
 
diff --git a/src/N_PhotoVoltaique.cpp b/src/N_PhotoVoltaique.cpp
index fe1b6c6..af47e60 100755
--- a/src/N_PhotoVoltaique.cpp
+++ b/src/N_PhotoVoltaique.cpp
@@ -32,8 +32,8 @@ static const std::vector<std::string> NType3_rangeValue {"1E-08AcC","3E-08AcC","
 // ============================================================================
 // N_PhotoVoltaique::N_PhotoVoltaique
 // ============================================================================
-N_PhotoVoltaique::N_PhotoVoltaique (std::string comLink_device_name, short address)
-:	Novelec_MCCE2(comLink_device_name, address)
+N_PhotoVoltaique::N_PhotoVoltaique (std::string comLink_device_name, short address, std::string comProtocol)
+:	Novelec_MCCE2(comLink_device_name, address, comProtocol)
 {
 	//std::cout << "N_PhotoVoltaique::N_PhotoVoltaique <-" << std::endl;
 
diff --git a/src/NovelecProtocol.cpp b/src/NovelecProtocol.cpp
index 60529a5..6bf5776 100644
--- a/src/NovelecProtocol.cpp
+++ b/src/NovelecProtocol.cpp
@@ -54,36 +54,21 @@ static const std::string range_str[5][8] = {
 static const std::string frequency_str[]= {"3 Hz","10 Hz","100 Hz","1000 Hz"};
 static const std::string gain_str[]   = {"1","10","100"};
 
-/*
-// ============================================================================
-// NovelecProtocol::NovelecProtocol
-// ============================================================================
-NovelecProtocol::NovelecProtocol (std::string& serial_device_name, unsigned short devAddress, unsigned short novelecType)
-  : ElectrometerProtocol(),
-    _devAdd(devAddress),
-    _novType(novelecType),
-    _rangeParameterNum(0),
-    _communication_link(0),
-    _is_measure_mode_on(false),
-    _is_explicite_resp_enabled(false)
-{
-  _commDevName = serial_device_name;
-  _function = "Not updated";
-}
-*/
+
 // ============================================================================
 // NovelecProtocol::NovelecProtocol
 // ============================================================================
-NovelecProtocol::NovelecProtocol (std::string& serial_device_name, unsigned short devAddress)
+NovelecProtocol::NovelecProtocol (std::string& communication_device_name, unsigned short devAddress, std::string comProtocol)
   : ElectrometerProtocol(),
     _devAdd(devAddress),
     _novType(0),
     _rangeParameterNum(0),
     _communication_link(0),
+    _comProtocol(comProtocol),
     _is_measure_mode_on(false),
     _is_explicite_resp_enabled(false)
 {
-  _commDevName = serial_device_name;
+  _commDevName = communication_device_name;
   _function = "Not updated";
 }
 
@@ -109,7 +94,14 @@ bool NovelecProtocol::build_communicationLink()
   if (_commDevName.empty())
     return false;
 
-  _communication_link = new TangoSerialLink(_commDevName);
+  if (_comProtocol=="SERIAL")
+  {
+    _communication_link = new TangoSerialLink(_commDevName);
+  }
+  else if (_comProtocol=="ETHERNET")
+  {
+    _communication_link = new TangoEthernetLink(_commDevName);
+  }
 
   if (!_communication_link)
     return false;
diff --git a/src/Novelec_MCCE2.cpp b/src/Novelec_MCCE2.cpp
index bba1fac..6a7fc45 100755
--- a/src/Novelec_MCCE2.cpp
+++ b/src/Novelec_MCCE2.cpp
@@ -39,12 +39,13 @@
 // ============================================================================
 // Novelec_MCCE2::Novelec_MCCE2
 // ============================================================================
-Novelec_MCCE2::Novelec_MCCE2 (std::string& comLink_device_name, unsigned short address)
+Novelec_MCCE2::Novelec_MCCE2 (std::string& comLink_device_name, unsigned short address, std::string comProtocol)
 :	AbstractElectrometerClass(comLink_device_name),
 	_rangeLimit(0),
   _address(address),
 	_MCCE2electroTypeNumber(0),
-	_MCCE2electroTypeStr("Unknown type")
+	_MCCE2electroTypeStr("Unknown type"),
+	_comProtocol(comProtocol)
 {
 	std::cout << "\t\tNovelec_MCCE2::Novelec_MCCE2 <-" << std::endl;
 
@@ -58,7 +59,6 @@ Novelec_MCCE2::~Novelec_MCCE2 (void)
 {
 	//std::cout << "Novelec_MCCE2::~Novelec_MCCE2 <-" << std::endl;
 
-	//std::cout << "Novelec_MCCE2::~Novelec_MCCE2 ->" << std::endl;
 }
 
 // ============================================================================
@@ -71,7 +71,7 @@ bool Novelec_MCCE2::init_protocol (void)
   try
   {
 	  //- build the keithley Electrometer protocol obj
-	_electrometerProtocol = new NovelecProtocol(_device_proxy_name, _address);
+	  _electrometerProtocol = new NovelecProtocol(_device_proxy_name, _address,_comProtocol);
 
     if(_electrometerProtocol)
       success = _electrometerProtocol->build_communicationLink();
diff --git a/src/TangoEthernetLink.cpp b/src/TangoEthernetLink.cpp
new file mode 100644
index 0000000..034ab9f
--- /dev/null
+++ b/src/TangoEthernetLink.cpp
@@ -0,0 +1,258 @@
+// ============================================================================
+//
+// = CONTEXT
+//    TANGO Project - Keithley Electrometer Support Library
+//
+// = FILENAME
+//    TangoEthernetLink.cpp
+//
+// = AUTHOR
+//    X. Elattaoui
+//
+// ============================================================================
+
+// ============================================================================
+// DEPENDENCIES
+// ============================================================================
+#include <string>
+#include <iostream>
+#include "TangoEthernetLink.h"
+
+
+
+// ============================================================================
+// TangoEthernetLink::TangoEthernetLink
+// ============================================================================
+TangoEthernetLink::TangoEthernetLink (std::string& serial_device_name)
+:	CommunicationLink(serial_device_name),
+	_ethernet_proxy (0),
+	_is_ethernet_proxy_ok (false)
+{
+}
+
+// ============================================================================
+// TangoEthernetLink::~TangoEthernetLink
+// ============================================================================
+TangoEthernetLink::~TangoEthernetLink (void)
+{
+
+	if(_ethernet_proxy)
+	{
+		delete _ethernet_proxy;
+		_ethernet_proxy = 0;
+		_is_ethernet_proxy_ok = false;
+	}
+
+}
+
+
+// ============================================================================
+// TangoEthernetLink::create_ethernet_proxy
+// ============================================================================
+void TangoEthernetLink::check_proxy (void)  throw (Tango::DevFailed)
+{
+  std::string description("");
+
+	try
+	{
+		//- try
+		this->_ethernet_proxy = new Tango::DeviceProxy(_communication_Device_name.c_str());
+		_ethernet_proxy->ping();
+		_is_ethernet_proxy_ok = true;
+	}
+	catch(Tango::DevFailed& df )
+	{
+		if( this->_ethernet_proxy )
+		{
+			delete this->_ethernet_proxy;
+			this->_ethernet_proxy = 0;
+		}
+		_is_ethernet_proxy_ok = false;
+		description = "Unable to create proxy on : " + _communication_Device_name;
+		Tango::Except::re_throw_exception (df,
+										(const char*)"ALLOCATION_ERROR",
+										description.c_str(),
+										(const char*)"TangoEthernetLink::create_ethernet_proxy");
+
+	}
+	catch(...)
+	{
+		if( this->_ethernet_proxy )
+		{
+			delete this->_ethernet_proxy;
+			this->_ethernet_proxy = 0;
+		}
+		_is_ethernet_proxy_ok = false;
+		description = "Unable to create proxy on : " + _communication_Device_name + "\nmemory allocation failed.";
+		Tango::Except::throw_exception (
+										(const char*)"ALLOCATION_ERROR",
+										description.c_str(),
+										(const char*)"TangoEthernetLink::write");
+	}
+}
+
+// ============================================================================
+// TangoEthernetLink::write
+// ============================================================================
+void TangoEthernetLink::write (std::string command_to_send)  throw (Tango::DevFailed)
+{
+  std::string description("");
+
+	check_proxy();
+	if (!_is_ethernet_proxy_ok)
+		return;
+
+	Tango::DeviceData dd_in;
+	Tango::DevString argin = 0;
+
+	try
+	{
+		argin = new char [command_to_send.size() + 1];
+		strcpy(argin, command_to_send.c_str());
+	}
+	catch(Tango::DevFailed& df )
+	{
+		if( argin )
+		{
+			delete [] argin;
+			argin = 0;
+		}
+		description = "Unable to write command : " + command_to_send +  + "\nmemory allocation failed.";
+		Tango::Except::re_throw_exception (df,
+										(const char*)"ALLOCATION_ERROR",
+										description.c_str(),
+										(const char*)"TangoEthernetLink::write");
+	}
+	catch(...)
+	{
+		description = "Unable to write command : " + command_to_send + "\nmemory allocation failed.";
+		Tango::Except::throw_exception (
+										(const char*)"ALLOCATION_ERROR",
+										description.c_str(),
+										(const char*)"TangoEthernetLink::write");
+	}
+
+	try
+	{
+		//- try
+		dd_in << argin;
+		_ethernet_proxy->command_inout("Write", dd_in);
+		if( argin )
+		{
+			delete [] argin;
+			argin = 0;
+		}
+		//std::cout << "TangoEthernetLink::write -> argin = *\"" << argin << "\"*" << std::endl;
+	}
+	catch(Tango::DevFailed& df )
+	{
+		if( argin )
+		{
+			delete [] argin;
+			argin = 0;
+		}
+		description = "Unable to write command : " + command_to_send;
+		Tango::Except::re_throw_exception (df,
+										(const char*)"COMMUNICATION_ERROR",
+										description.c_str(),
+										(const char*)"TangoEthernetLink::write");
+
+	}
+	catch(...)
+	{
+		if( argin )
+		{
+			delete [] argin;
+			argin = 0;
+		}
+		description = "Unable to write command : " + command_to_send;
+		Tango::Except::throw_exception (
+										(const char*)"COMMUNICATION_ERROR",
+										description.c_str(),
+										(const char*)"TangoEthernetLink::write");
+	}
+}
+
+
+// ============================================================================
+// TangoEthernetLink::read
+// ============================================================================
+std::string TangoEthernetLink::read (void) throw (Tango::DevFailed)
+{
+
+	check_proxy();
+	if(!_is_ethernet_proxy_ok)
+		return "";
+
+	Tango::DeviceData dd_out;
+	std::string response("");
+
+	try
+	{
+
+		dd_out = _ethernet_proxy->command_inout("Read");
+		dd_out >> response;
+	}
+	catch(Tango::DevFailed& df )
+	{
+		Tango::Except::re_throw_exception (df,
+										(const char*)"COMMUNICATION_ERROR",
+										(const char*)"Unable to perform a read operation",
+										(const char*)"TangoEthernetLink::read");
+	}
+	catch(...)
+	{
+		Tango::Except::throw_exception (
+										(const char*)"COMMUNICATION_ERROR",
+										(const char*)"Unable to perform a read operation",
+										(const char*)"TangoEthernetLink::read");
+	}
+
+	return response ;
+}
+
+// ============================================================================
+// TangoEthernetLink::write_read : read N char
+// ============================================================================
+std::string TangoEthernetLink::write_read (std::string command_to_send, size_t nbChar) throw (Tango::DevFailed)
+{
+	std::string resp;
+
+	check_proxy();
+	if(!_is_ethernet_proxy_ok)
+		return "";
+
+	Tango::DeviceData dd_in;
+	Tango::DevString argin = 0;
+
+	Tango::DeviceData dd_out;
+	std::string response("");
+
+	try
+	{
+		argin = new char [command_to_send.size() + 1];
+		strcpy(argin, command_to_send.c_str());
+		dd_in << argin;
+		dd_out = _ethernet_proxy->command_inout("WriteRead", dd_in);
+		dd_out >> response;
+	}
+	catch(Tango::DevFailed& df )
+	{
+		Tango::Except::re_throw_exception (df,
+										(const char*)"COMMUNICATION_ERROR",
+										(const char*)"Unable to perform a read operation",
+										(const char*)"TangoSerialLink::read");
+	}
+	catch(...)
+	{
+		Tango::Except::throw_exception (
+										(const char*)"COMMUNICATION_ERROR",
+										(const char*)"Unable to perform a read operation",
+										(const char*)"TangoSerialLink::read");
+	}
+
+	return response ;
+
+
+}
+
diff --git a/src/TangoSerialLink.cpp b/src/TangoSerialLink.cpp
old mode 100644
new mode 100755
index fb7e2b3..12b130e
--- a/src/TangoSerialLink.cpp
+++ b/src/TangoSerialLink.cpp
@@ -28,11 +28,10 @@ static const long MODE_LINE = 2;
 TangoSerialLink::TangoSerialLink (std::string& serial_device_name)
 :	CommunicationLink(serial_device_name),
 	_serial_proxy (0),
-	_is_serial_proxy_created (false)
+	_is_serial_proxy_ok (false)
 {
-//	//std::cout << "TangoSerialLink::TangoSerialLink <-" << std::endl;
+	//std::cout << "TangoSerialLink::TangoSerialLink <-" << std::endl;
 
-//	//std::cout << "TangoSerialLink::TangoSerialLink ->" << std::endl;
 }
 
 // ============================================================================
@@ -46,7 +45,7 @@ TangoSerialLink::~TangoSerialLink (void)
 	{
 		delete _serial_proxy;
 		_serial_proxy = 0;
-		_is_serial_proxy_created = false;
+		_is_serial_proxy_ok = false;
 	}
 
 	std::cout << "TangoSerialLink::~TangoSerialLink ->" << std::endl;
@@ -56,16 +55,19 @@ TangoSerialLink::~TangoSerialLink (void)
 // ============================================================================
 // TangoSerialLink::create_serial_proxy
 // ============================================================================
-void TangoSerialLink::create_serial_proxy (void)  throw (Tango::DevFailed)
+void TangoSerialLink::check_proxy (void)  throw (Tango::DevFailed)
 {
   std::string description("");
 
 	try
 	{
-		//- try
-		this->_serial_proxy = new Tango::DeviceProxy(_communication_Device_name.c_str());
-		//(*_serial_proxy)->ping();
-		_is_serial_proxy_created = true;
+		if (_serial_proxy==0)
+		{
+			_serial_proxy = new Tango::DeviceProxy(_communication_Device_name.c_str());
+		}
+
+		_serial_proxy->ping();
+		_is_serial_proxy_ok = true;
 	}
 	catch(Tango::DevFailed& df )
 	{
@@ -74,13 +76,12 @@ void TangoSerialLink::create_serial_proxy (void)  throw (Tango::DevFailed)
 			delete this->_serial_proxy;
 			this->_serial_proxy = 0;
 		}
-		_is_serial_proxy_created = false;
-		description = "Unable to create proxy on : " + _communication_Device_name;
+		_is_serial_proxy_ok = false;
+		description = "Cannot connect to : " + _communication_Device_name;
 		Tango::Except::re_throw_exception (df,
 										(const char*)"ALLOCATION_ERROR",
 										description.c_str(),
-										(const char*)"TangoSerialLink::create_serial_proxy");
-
+										(const char*)"TangoSerialLink::check_proxy");
 	}
 	catch(...)
 	{
@@ -89,12 +90,12 @@ void TangoSerialLink::create_serial_proxy (void)  throw (Tango::DevFailed)
 			delete this->_serial_proxy;
 			this->_serial_proxy = 0;
 		}
-		_is_serial_proxy_created = false;
+		_is_serial_proxy_ok = false;
 		description = "Unable to create proxy on : " + _communication_Device_name + "\nmemory allocation failed.";
 		Tango::Except::throw_exception (
 										(const char*)"ALLOCATION_ERROR",
 										description.c_str(),
-										(const char*)"TangoSerialLink::write");
+										(const char*)"TangoSerialLink::check_proxy");
 	}
 }
 
@@ -105,8 +106,9 @@ void TangoSerialLink::write (std::string command_to_send)  throw (Tango::DevFail
 {
   std::string description("");
 
+  check_proxy();
 	if(!_serial_proxy)
-		create_serial_proxy();
+		return ;
 	Tango::DeviceData dd_in;
 	Tango::DevString argin = 0;
 
@@ -185,9 +187,10 @@ void TangoSerialLink::write (std::string command_to_send)  throw (Tango::DevFail
 std::string TangoSerialLink::read (void) throw (Tango::DevFailed)
 {
 
+  check_proxy();
 	if(!_serial_proxy)
-		create_serial_proxy();
-	Tango::DeviceData dd_out;
+		return "";
+	Tango::DeviceData dd_out;
 	std::string response("");
 
 	try
@@ -220,8 +223,10 @@ std::string TangoSerialLink::read (void) throw (Tango::DevFailed)
 std::string TangoSerialLink::read (long nbCharToRead) throw (Tango::DevFailed)
 {
 
+  check_proxy();
 	if(!_serial_proxy)
-		create_serial_proxy();
+		return "";
+
 	Tango::DeviceData dd_in;
 	Tango::DeviceData dd_out;
 	std::string response("");
@@ -252,9 +257,10 @@ std::string TangoSerialLink::write_read (std::string command_to_send, size_t nbC
 {
 	Tango::DeviceData dd_in;
 	Tango::DeviceData dd_out;
-
-	if( !_serial_proxy )
-		create_serial_proxy();
+
+  check_proxy();
+	if(!_serial_proxy)
+		return "";
 
 	long flush_in_out = 2;
 	dd_in << flush_in_out;
@@ -272,16 +278,16 @@ std::string TangoSerialLink::write_read (std::string command_to_send, size_t nbC
 	//size_t nbRetries = 0;
 	Tango::DevLong nbCharReceived = 0;
 	dd_out = this->_serial_proxy->command_inout("DevSerGetNChar");
-	dd_out >> nbCharReceived;
+	dd_out >> nbCharReceived;
 	//- if no response throw !
 	if ( !nbCharReceived )
 	{
 //		dd_out = this->_serial_proxy->command_inout("DevSerGetNChar");
 //		dd_out >> nbCharReceived;
 //		nbRetries++;
-//std::cout << "TangoSerialLink::write_read -> nbRetries = " << nbRetries << " & nbCharReceived = " << nbCharReceived << std::endl;
-    std::string desc("");
-    desc = "No response received from the hardware for command : " + command_to_send;
+//std::cout << "TangoSerialLink::write_read -> nbRetries = " << nbRetries << " & nbCharReceived = " << nbCharReceived << std::endl;
+    std::string desc("");
+    desc = "No response received from the hardware for command : " + command_to_send;
 		Tango::Except::throw_exception (
 										"COMMUNICATION_ERROR",
 										desc,
-- 
GitLab