diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..f768f7909ca84a190cd6d52a1522bf55d0a7e55d
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,19 @@
+.pydevproject
+.project
+.cproject
+.settings
+obj
+bin
+core*
+*~
+*.pyc
+*.so
+*.so*
+.pylintrc
+.metadata
+.idea
+.cvsignore
+.nse_depinfo
+software
+oldsrc
+CVS
diff --git a/BridgeAttr.cpp b/BridgeAttr.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..b83cd02517c99117d12b80b117b4590ccab71749
--- /dev/null
+++ b/BridgeAttr.cpp
@@ -0,0 +1,162 @@
+#include <BridgeAttr.h>
+#include <RPCHandleSet.h>
+
+namespace RPC2TangoBridge_ns
+{
+
+BridgeAttr::BridgeAttr(const char *name, long data_type,Tango::AttrWriteType w_type) :
+                        Attr(name, data_type, w_type) 
+{
+	wrpch = NULL;
+	rpch = RPCHandleSet::instance()->handleFromList(name);
+	if(!rpch)
+	{
+		rpch = new RPCHandle(name);
+		if(rpch && rpch->connected())
+		{
+			RPCHandleSet::instance()->addHandle(rpch);
+			//printf("\e[1;32m*\e[0m connected to host \"%s\" port %d for attribute \"%s\"", rpch->host().c_str(), rpch->port(), name);
+		}
+		else if(rpch){
+			//printf("\e[1;31m* \e[0merror creating RPC handle for \"%s\": \e[1;4;31mmessage\e[0m: \"%s\"\n", name, rpch->lastRpcError().c_str());
+		}
+	}
+	else{
+		//printf("\e[1;32m* \e[0mread handle for  attribute \"%s\" was already created (host \"%s\":%d\n", name, rpch->host().c_str(), rpch->port());
+	}
+	if(rpch && rpch->connected())
+		d_connected = true;
+	else
+		d_connected = false;
+	if(rpch)
+	{
+		rpch->_refcnt++;
+		rrpch = new RPCReadHandle(rpch);
+	}
+}
+
+/* read write attribute */
+BridgeAttr::BridgeAttr(const char *name, const char *wname, long data_type,Tango::AttrWriteType w_type) :
+                        Attr(name, data_type, w_type) 
+{
+	rpch = RPCHandleSet::instance()->handleFromList(name);
+	if(!rpch)
+	{
+		rpch = new RPCHandle(name);
+		if(rpch && rpch->connected())
+			RPCHandleSet::instance()->addHandle(rpch);
+		else if(rpch){
+			//printf("\e[1;31m* \e[0merror creating RPC handle for \"%s\": \e[1;4;31mmessage\e[0m: \"%s\"\n", 
+					//name, rpch->lastRpcError().c_str());
+		}
+	}
+	else{
+		//printf("\e[1;32m* \e[0mread handle for  attribute \"%s\" was already created (host \"%s\":%d\n", name, rpch->host().c_str(), rpch->port());
+	}
+	
+	if(rpch && rpch->connected())
+		d_connected = true;
+	else
+		d_connected = false;
+	if(rpch)
+	{
+		rpch->_refcnt++;
+		rrpch = new RPCReadHandle(rpch);
+		wrpch = new RPCWriteHandle(rpch);
+	}
+	d_writeName = string(wname);
+}
+
+
+SpectrumBridgeAttr::SpectrumBridgeAttr(const char *name,long data_type,Tango::AttrWriteType w_type, long max_x)
+	: SpectrumAttr(name, data_type, w_type, max_x)
+{
+	rpch = RPCHandleSet::instance()->handleFromList(name);
+	if(!rpch)
+	{
+		rpch = new RPCHandle(name);
+		if(rpch && rpch->connected())
+			RPCHandleSet::instance()->addHandle(rpch);
+		else if(rpch){
+			//printf("\e[1;31m* \e[0merror creating RPC handle for SPECTRUM \"%s\": \e[1;4;31mmessage\e[0m: \"%s\"\n", name, rpch->lastRpcError().c_str());
+		}
+	}
+	else{
+		//printf("\e[1;32m* \e[0mread handle for spectrum attribute \"%s\" was already created (host \"%s\":%d\n", name, rpch->host().c_str(), rpch->port());
+	}
+	if(rpch && rpch->connected())
+		d_connected = true;
+	else
+		d_connected = false;
+	if(rpch)
+	{
+		rpch->_refcnt++;
+		rrpch =new  RPCReadHandle(rpch);
+	}
+}
+
+std::string BridgeAttr::host()
+{
+	if(rpch && rpch->connected())
+		return rpch->host();
+	return string("unconnected");
+}
+
+unsigned short BridgeAttr::port()
+{
+	if(rpch && rpch->connected())
+		return rpch->port();
+	return 0;
+}
+
+string SpectrumBridgeAttr::host()
+{
+	if(rpch && rpch->connected())
+		return rpch->host();
+	return string("unconnected");
+}
+
+unsigned short SpectrumBridgeAttr::port()
+{
+	if(rpch && rpch->connected())
+		return rpch->port();
+	return 0;
+}
+
+
+/* destructors: called by delete_device() */
+SpectrumBridgeAttr::~SpectrumBridgeAttr()
+{
+	if(rpch)
+		rpch->_refcnt--;
+	if(rpch && !rpch->_refcnt)
+	{
+		//printf("\e[1;32m x\e[0m deleting rpc handle linked to spectrum attribute \"%s\"\n", get_name().c_str());
+		RPCHandleSet::instance()->removeHandle(rpch);
+		delete rpch;
+	}
+	else{
+		//printf("\e[1;35m *\e[0m rpc handle linked to \"%s\"  still referenced by %d attributes, not freeing\n", get_name().c_str(), rpch->_refcnt);
+	}
+}
+
+BridgeAttr::~BridgeAttr()
+{
+	if(rpch)
+		rpch->_refcnt--;
+	if(rpch && !rpch->_refcnt)
+	{
+		//printf("\e[1;32m x\e[0m deleting rpc handle linked to scalar attribute \"%s\"\n", get_name().c_str());
+		RPCHandleSet::instance()->removeHandle(rpch);
+		delete rpch;
+	}
+	else{
+		//printf("\e[1;35m *\e[0m rpc handle linked to \"%s\"  still referenced by %d attributes, not freeing\n", get_name().c_str(), rpch->_refcnt);
+	}
+}
+
+} /* namespace ends */
+
+
+
+
diff --git a/BridgeAttr.h b/BridgeAttr.h
new file mode 100644
index 0000000000000000000000000000000000000000..8a7e6bfa46cd2eec44e6c67284e6c4ffe3951ab4
--- /dev/null
+++ b/BridgeAttr.h
@@ -0,0 +1,86 @@
+#ifndef _BRIDGE_ATTR_H
+#define _BRIDGE_ATTR_H
+
+#include <tango.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <RPC2TangoBridge.h>
+#include <RpcReadHandle.h>
+#include <RpcWriteHandle.h>
+
+using namespace Tango;
+
+namespace RPC2TangoBridge_ns
+{
+
+class BridgeAttr : public Tango::Attr
+{
+	public:
+		/** Constructor for Tango::READ attributes (read only )
+		 */
+		BridgeAttr(const char *name,long data_type,Tango::AttrWriteType w_type);
+		
+		/** Constructor for Tango::READ_WRITE attributes (scalar only). Wants a writeName as parameter, 
+		 * that indicates the RPC call to execute when writing attribute.
+		 */
+		BridgeAttr(const char *name, const char* writeName, long data_type,Tango::AttrWriteType w_type);
+
+		~BridgeAttr() ;
+		virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+			{(static_cast<RPC2TangoBridge *>(dev))->read_BridgeAttr(att);}
+		virtual void write(Tango::DeviceImpl *dev,Tango::WAttribute &att)
+			{(static_cast<RPC2TangoBridge *>(dev))->write_BridgeAttr(att);}
+		virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+			{return (static_cast<RPC2TangoBridge *>(dev))->is_BridgeAttr_allowed(ty);}
+
+		RPCHandle *rpcHandle() { return rpch; }
+		
+		std::string host();
+		unsigned short port();
+		
+		bool connected() { return d_connected; }
+		
+		void setRpcWriteHandle(RPCWriteHandle *h) { wrpch = h; }
+		RPCWriteHandle *rpcWriteHandle() { return wrpch; }
+		
+		RPCReadHandle *rpcReadHandle() { return rrpch; }
+		
+		string writeName() { return d_writeName; }
+
+	private:
+		RPCHandle *rpch;
+		RPCWriteHandle *wrpch;
+		RPCReadHandle *rrpch;
+		std::string d_writeName;
+		bool d_connected;
+};
+
+class SpectrumBridgeAttr : public Tango::SpectrumAttr
+{
+	public:
+		SpectrumBridgeAttr(const char *name,long data_type,Tango::AttrWriteType w_type, long max_x);
+		~SpectrumBridgeAttr();
+
+		 virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+                        {(static_cast<RPC2TangoBridge *>(dev))->read_BridgeAttr(att);}
+                virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+                        {return (static_cast<RPC2TangoBridge *>(dev))->is_BridgeAttr_allowed(ty);}
+
+		RPCHandle *rpcHandle() { return rpch; }
+		RPCReadHandle *rpcReadHandle() { return rrpch; }
+		bool connected() { return d_connected; }
+			
+		string host();
+		unsigned short port();
+		
+        private:
+                RPCHandle *rpch;
+		RPCWriteHandle *wrpch;
+		RPCReadHandle *rrpch;
+		bool d_connected;
+};
+
+
+} /* namespace RPC2TangoBridge_ns */
+#endif
+
diff --git a/BridgeAttribute.h b/BridgeAttribute.h
new file mode 100644
index 0000000000000000000000000000000000000000..24512175c4d11c0096dcf2b18fbad87f48761744
--- /dev/null
+++ b/BridgeAttribute.h
@@ -0,0 +1,42 @@
+#ifndef _BRIDGE_ATTR_H
+#define _BRIDGE_ATTR_H
+
+#include <tango.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <RPC2TangoBridge.h>
+
+using namespace Tango;
+
+class BridgeAttr : public Tango::Attr
+{
+	public:
+		BridgeAttr(const char *name,long data_type,Tango::AttrWriteType w_type) :
+			Attr(name, data_type, w_type) {};
+		BridgeAttr(const char *name,long data_type,Tango::AttrWriteType w_type, string host, 
+				unsigned short port) :
+			Attr(name, data_type, w_type), rpchost(host), rpcport(port), rpcname(string(name)) {};
+
+		~BridgeAttr() {};
+		virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+			{(static_cast<RPC2TangoBridge *>(dev))->read_AlarmAttribute(att);}
+		virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+			{return (static_cast<RPC2TangoBridge *>(dev))->is_AlarmAttribute_allowed(ty);}
+
+		string rpcHost() {return rpchost; }
+		unsigned short rpcPort() { return rpcport; }
+		string rpcName() { return rpcname; }
+		bool rpcConnected() { return connected; }
+
+	private:
+		string rpchost;
+		string rpcname;
+		unsigned short rpcport;
+		bool connected;
+};
+
+
+
+
+#endif
+
diff --git a/CHANGELOG b/CHANGELOG
new file mode 100644
index 0000000000000000000000000000000000000000..68d32abea2c361cb98504709a2eb469416ab3a3c
--- /dev/null
+++ b/CHANGELOG
@@ -0,0 +1,9 @@
+2012/03/12 - release_02
+- rimossi tutti i printf, in attesa di usare DEBUG_STREAM
+- compilato con tango 7.2.6
+
+2012/11/30 relase_03
+- risolto ticket 928: must free sequences aftre reading
+
+2013/03/06 release_04
+- compilato con tango-8.0.5
diff --git a/ClassFactory.cpp b/ClassFactory.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..3587dcb13bb6dba1273dc065c9fab50d65c8f219
--- /dev/null
+++ b/ClassFactory.cpp
@@ -0,0 +1,47 @@
+static const char *RcsId = "$Header: /home/cvsadm/cvsroot/elettra/server/RPC2TangoBridge/ClassFactory.cpp,v 1.1.1.1 2008-04-28 09:13:16 giacomo Exp $";
+//+=============================================================================
+//
+// file :        ClassFactory.cpp
+//
+// description : C++ source for the class_factory method of the DServer
+//               device class. This method is responsible to create
+//               all class singletin for a device server. It is called
+//               at device server startup
+//
+// project :     TANGO Device Server
+//
+// $Author: giacomo $
+//
+// $Revision: 1.1.1.1 $
+//
+// $Log: ClassFactory.cpp,v $
+// Revision 1.1.1.1  2008-04-28 09:13:16  giacomo
+// Prima versione di RPC2TangoBridge
+//
+//
+// copyleft :    European Synchrotron Radiation Facility
+//               BP 220, Grenoble 38043
+//               FRANCE
+//
+//-=============================================================================
+//
+//  		This file is generated by POGO
+//	(Program Obviously used to Generate tango Object)
+//
+//         (c) - Software Engineering Group - ESRF
+//=============================================================================
+
+
+#include <tango.h>
+#include <RPC2TangoBridgeClass.h>
+
+/**
+ *	Create RPC2TangoBridgeClass singleton and store it in DServer object.
+ */
+
+void Tango::DServer::class_factory()
+{
+
+	add_class(RPC2TangoBridge_ns::RPC2TangoBridgeClass::init("RPC2TangoBridge"));
+
+}
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..d513ada9ac5c8190e4cd71f6a86790b27c061c9b
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,193 @@
+#=============================================================================
+#
+# file :        Makefile
+#
+# description : Include for the RPC2TangoBridge class.
+#
+# project :     Makefile to generate a Tango server
+#
+# $Author: claudio $
+#
+# $Revision: 1.8 $
+#
+#
+# copyleft :    European Synchrotron Radiation Facility
+#               BP 220, Grenoble 38043
+#               FRANCE
+#
+#=============================================================================
+#  		This file is generated by POGO
+#	(Program Obviously used to Generate tango Object)
+#
+#         (c) - Software Engineering Group - ESRF
+#=============================================================================
+#
+
+CLASS      = RPC2TangoBridge
+MAJOR_VERS = 1
+MINOR_VERS = 1
+RELEASE    = Release_$(MAJOR_VERS)_$(MINOR_VERS)
+
+#-----------------------------------------
+#	Set default home directories
+#-----------------------------------------
+
+TANGO_HOME   =  /usr/local/tango-9.2.5a
+OMNI_HOME = /usr/local/omniorb-4.2.1
+ZMQ_HOME = //usr/local/zeromq-4.0.7
+CPP_SERVERS  =  $(TANGO_HOME)/cppserver
+
+
+
+#ifdef no_debug
+	DEBUG = -O2
+#else
+#	DEBUG = -g
+#endif
+
+CC = c++
+CC_SHLIB = $(CC)  -fPIC
+AR = ar
+
+AR_SL = $(CC) -fPIC -shared 
+SL_EXT = so
+VERS_OPT = -Wl,-soname,
+
+INCLUDE_DIRS =  -I$(TANGO_HOME)/include/tango \
+					 -I$(OMNI_HOME)/include \
+					 -I$(ZMQ_HOME)/include \
+					 -I.	\
+                -I$(CPP_SERVERS)/include -I/runtime/elettra/include
+
+SERVER_DIR  = ./rpcserver
+OBJS_DIR    = obj
+LIB_DIRS    = -L $(TANGO_HOME)/lib -L $(OMNI_HOME)/lib -L$(ZMQ_HOME)/lib -L/runtime/elettra/lib
+
+TARGET_LIB = $(CPP_SERVERS)/lib/libtgclasses.a
+
+
+#-----------------------------------------
+#	Set  CXXFLAGS and LFLAGS
+#-----------------------------------------
+
+
+CXXFLAGS =  -std=c++0x $(DEBUG) -D_REENTRANT $(INCLUDE_DIRS)
+LFLAGS =  $(DEBUG) $(LIB_DIRS)  		\
+				-ltango		\
+				-llog4tango	\
+				-lomniORB4 	\
+				-lomniDynamic4	\
+				-lomnithread	\
+				-lCOS4		\
+				-lzmq		\
+				-ldl -lpthread -llpc -lnc \
+				-lRpcResolver -llpcresolve
+
+
+
+
+#-----------------------------------------
+#	Set  dependences
+#-----------------------------------------
+
+DEPENDPATH += $(SERVER_DIR)
+
+SVC_OBJS = $(OBJS_DIR)/main.o	\
+		$(OBJS_DIR)/ClassFactory.o	\
+		$(OBJS_DIR)/$(CLASS)Class.o	\
+		$(OBJS_DIR)/$(CLASS)StateMachine.o	\
+		$(OBJS_DIR)/$(CLASS).o \
+		$(OBJS_DIR)/RPC2TangoBridgeThread.o	\
+		$(OBJS_DIR)/BridgeAttr.o	\
+		$(OBJS_DIR)/RpcHandle.o	$(OBJS_DIR)/RpcWriteHandle.o	\
+		$(OBJS_DIR)/read_dynamic_attribute.o	\
+		$(OBJS_DIR)/write_dynamic_attribute.o	\
+		$(OBJS_DIR)/attribute_converter.o \
+		$(OBJS_DIR)/RPCHandleSet.o \
+		$(OBJS_DIR)/RpcReadHandle.o
+
+SHLIB_OBJS = 	$(OBJS_DIR)/RPC2TangoBridgeThread.so.o \
+		$(OBJS_DIR)/$(CLASS)Class.so.o	\
+		$(OBJS_DIR)/$(CLASS)StateMachine.so.o	\
+		$(OBJS_DIR)/$(CLASS).so.o
+
+
+SVC_INC = $(CLASS)Class.h \
+		RPC2TangoBridgeThread.h \
+		BridgeAttr.h \
+		RpcHandle.h \
+		RpcWriteHandle.h \
+		attribute_converter.h \
+		RPCHandleSet.h \
+		RpcReadHandle.h \
+		$(CLASS).h
+
+
+$(OBJS_DIR)/%.o: %.cpp $(SVC_INC)
+	$(CC) $(CXXFLAGS) -c $< -o $(OBJS_DIR)/$*.o
+			
+$(OBJS_DIR)/%.so.o: %.cpp $(SVC_INC)
+	$(CC_SHLIB) $(CXXFLAGS) -c $< -o $(OBJS_DIR)/$*.so.o
+
+
+#-----------------------------------------
+#	 Make Entry
+#-----------------------------------------
+all: $(CLASS)
+	
+$(CLASS):	make_obj_dir make_bin_dir $(SVC_OBJS)
+	$(CC) $(SVC_OBJS) -o $(CLASS) $(LFLAGS)
+	@mv $(CLASS) bin/$(CLASS)
+
+shlib:	make_obj_dir make_shlib_dir $(SHLIB_OBJS)
+	$(AR_SL) -o \
+		shlib/$(CLASS).$(SL_EXT).$(MAJOR_VERS).$(MINOR_VERS) \
+		$(VERS_OPT)shlib/$(CLASS).$(SL_EXT).$(MAJOR_VERS) \
+		$(SHLIB_OBJS) $(LFLAGS)
+	@rm -f shlib/$(CLASS).$(SL_EXT)
+	@cd  shlib; \
+		ln -s $(CLASS).$(SL_EXT).$(MAJOR_VERS).$(MINOR_VERS) $(CLASS).$(SL_EXT)
+
+clean:
+	rm -f $(OBJS_DIR)/*.o  \
+	$(OBJS_DIR)/*.so.o \
+	bin/$(CLASS) \
+	core
+
+make_obj_dir:
+	@mkdir -p obj
+
+make_bin_dir:
+	@mkdir -p bin
+
+make_shlib_dir:
+	@mkdir -p shlib
+	
+#-----------------------------------------
+#	 Install binary file
+#-----------------------------------------
+install:
+	cp bin/$(CLASS)  $(TANGO_HOME)/bin
+
+#-----------------------------------------
+#	 Update class library and header files
+#	recompile without debug mode.
+#-----------------------------------------
+lib: clean
+	@make no_debug=1
+	cp *.h $(CPP_SERVERS)/include
+	ar ruv $(TARGET_LIB)/$(CLASS).o
+	ar ruv $(TARGET_LIB)/$(CLASS)Class.o
+	ar ruv $(TARGET_LIB)/$(CLASS)StateMachine.o
+	ident  $(TARGET_LIB)/* | grep $(CLASS)
+
+#----------------------------------------------------
+#	Tag the CVS module corresponding to this class
+#----------------------------------------------------
+tag:
+	@cvstag "$(CLASS)-$(RELEASE)"
+	@make   $(CLASS)
+	@make show_tag
+
+show_tag:
+	@cvstag -d 
diff --git a/README.md b/README.md
index 7c554bdeb84ef360cc3376a0cd2d0906001b3bf8..8d1c3683072083166cad15ae36af2396ea362d46 100644
--- a/README.md
+++ b/README.md
@@ -1 +1,33 @@
-# rpc2tango-bridge
\ No newline at end of file
+## Project
+
+ rpc2tango-bridge
+
+## Description
+
+configurable bridge from Tango to legacy Elettra rpc control system protocol
+
+## Dependencies
+
+leagacy Elettra rpc libraries and services
+
+
+## Installation & deployment
+
+Follow standard C++ Tango device server installation guidelines
+
+## History
+
+2020-03-31 imported from CVS repo elettra/server/RPC2TangoBridge release_06
+
+## Credits
+
+developed by Giacomo Strangolino
+
+Elettra-Sincrotrone Trieste S.C.p.A. di interesse nazionale
+Strada Statale 14 - km 163,5 in AREA Science Park
+34149 Basovizza, Trieste ITALY
+
+## License
+
+GPL 3
+
diff --git a/RPC2TangoBridge.cpp b/RPC2TangoBridge.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..861222a8c7916c0a5491d50fab8bdf7d324c14ae
--- /dev/null
+++ b/RPC2TangoBridge.cpp
@@ -0,0 +1,564 @@
+static const char *RcsId = "$Header: /home/cvsadm/cvsroot/elettra/server/RPC2TangoBridge/RPC2TangoBridge.cpp,v 1.6 2017-03-28 09:39:02 claudio Exp $";
+//+=============================================================================
+//
+// file :         RPC2TangoBridge.cpp
+//
+// description :  C++ source for the RPC2TangoBridge and its commands. 
+//                The class is derived from Device. It represents the
+//                CORBA servant object which will be accessed from the
+//                network. All commands which can be executed on the
+//                RPC2TangoBridge are implemented in this file.
+//
+// project :      TANGO Device Server
+//
+// $Author: claudio $
+//
+// $Revision: 1.6 $
+//
+// $Log: RPC2TangoBridge.cpp,v $
+// Revision 1.6  2017-03-28 09:39:02  claudio
+// ticket 2413: tango-9
+//
+// Revision 1.5  2012-08-09 13:04:39  claudio
+// tango 4 impl
+//
+// Revision 1.4  2012-03-12 11:31:06  claudio
+// tango-7.2.6
+// rimossi "printf" ridondanti
+//
+// Revision 1.3  2009/08/19 07:37:57  giacomo
+// Correzioni al bridge e allineamento set point a read point in ogni
+// read attribute (per gli attributi RW).
+//
+// Revision 1.2  2009/02/26 08:15:45  giacomo
+// Versione di RPC2TangoBridge con supporto ad attributi SCALARI READ WRITE.
+// La parte WRITE va specificata nelle device properties separata da : dalla
+// parte rpc read.
+//
+// Revision 1.1.1.1  2008/04/28 09:13:16  giacomo
+// Prima versione di RPC2TangoBridge
+//
+//
+// copyleft :     European Synchrotron Radiation Facility
+//                BP 220, Grenoble 38043
+//                FRANCE
+//
+//-=============================================================================
+//
+//  		This file is generated by POGO
+//	(Program Obviously used to Generate tango Object)
+//
+//         (c) - Software Engineering Group - ESRF
+//=============================================================================
+
+
+
+//===================================================================
+//
+//	The following table gives the correspondance
+//	between commands and method's name.
+//
+//  Command's name       |  Method's name
+//	----------------------------------------
+//  State                |  dev_state()
+//  Status               |  dev_status()
+//  RPCDataForAttribute  |  rpcdata_for_attribute()
+//  Standby              |  standby()
+//  On                   |  on()
+//
+//===================================================================
+
+
+#include <tango.h>
+#include <RPC2TangoBridge.h>
+#include <RPC2TangoBridgeClass.h>
+#include <RPC2TangoBridgeThread.h>
+#include <BridgeAttr.h>
+#include <RpcHandle.h>
+#include <RPCHandleSet.h>
+#include <attribute_converter.h>
+#include <errno.h>
+
+
+using namespace Tango;
+using namespace std;
+
+namespace RPC2TangoBridge_ns
+{
+
+//+----------------------------------------------------------------------------
+//
+// method : 		RPC2TangoBridge::RPC2TangoBridge(string &s)
+// 
+// description : 	constructor for simulated RPC2TangoBridge
+//
+// in : - cl : Pointer to the DeviceClass object
+//      - s : Device name 
+//
+//-----------------------------------------------------------------------------
+RPC2TangoBridge::RPC2TangoBridge(Tango::DeviceClass *cl,string &s)
+:TANGO_BASE_CLASS(cl,s.c_str())
+{
+	init_device();
+}
+
+RPC2TangoBridge::RPC2TangoBridge(Tango::DeviceClass *cl,const char *s)
+:TANGO_BASE_CLASS(cl,s)
+{
+	init_device();
+}
+
+RPC2TangoBridge::RPC2TangoBridge(Tango::DeviceClass *cl,const char *s,const char *d)
+:TANGO_BASE_CLASS(cl,s,d)
+{
+	init_device();
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		RPC2TangoBridge::delete_device()
+// 
+// description : 	will be called at device destruction or at init command.
+//
+//-----------------------------------------------------------------------------
+
+void RPC2TangoBridge::delete_device()
+{
+	//	Delete device's allocated object
+	int cnt = 0, handlecnt = 0;
+	int totatt;
+	set_state(Tango::CLOSE);
+	set_status("deallocating attributes and freeing resources");
+
+	//printf("\e[1;32m*\e[0m freeing RPC resources and deleting dynamic attributes...\n");
+
+	totatt = namesMap.size() + spectrumNamesMap.size();
+
+	map<string, BridgeAttr* >::iterator mapiter;
+	/* NOTE: tango: device.c if  an attribute already exists, the new attribute is deleted!
+	 * So: remove all attributes in delete device.
+	 */
+	for(mapiter = namesMap.begin(); mapiter != namesMap.end(); mapiter++)
+	{
+		//printf("\e[1;32mx\e[0m removing scalar dynamic attribute \"%s\"\n", (*mapiter).second->get_name().c_str());
+		try{
+			remove_attribute((*mapiter).second, true);
+		}
+		catch(Tango::DevFailed &e)
+		{
+			//printf("\e[1;31m*\e[0m error removing attribute: \"%s\"", (*mapiter).second->get_name().c_str());
+			Tango::Except::print_exception(e);
+		}
+	}
+ 	namesMap.erase(namesMap.begin(), namesMap.end());
+	
+	map<string, SpectrumBridgeAttr* >::iterator spmapiter;
+	for(spmapiter = spectrumNamesMap.begin(); spmapiter != spectrumNamesMap.end(); spmapiter++)
+	{
+		//printf("\e[1;32mx\e[0m removing spectrum dynamic attribute \"%s\"\n", (*spmapiter).second->get_name().c_str());
+		try{
+			remove_attribute((*spmapiter).second, true);	
+		}
+		catch(Tango::DevFailed &e)
+		{
+			//printf("\e[1;31m* \e[0merror removing attribute: \"%s\"", (*mapiter).second->get_name().c_str());
+			Tango::Except::print_exception(e);
+		}
+	}
+	spectrumNamesMap.erase(spectrumNamesMap.begin(), spectrumNamesMap.end());
+	
+	/* do not clear() RPCHandleSet here: if we restart device the order of  attribute re-creation and destruction would 
+	 * make the server crash. Indeed, the reference count of the handle would be 0 and so freed in an unappropriate 
+	 * instant. On the other hand, if the server is restarted, we do not exit and the set remains alive and initialized.
+	*/
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		RPC2TangoBridge::init_device()
+// 
+// description : 	will be called at device initialization.
+//
+//-----------------------------------------------------------------------------
+void RPC2TangoBridge::init_device()
+{
+	set_state(Tango::INIT);
+	INFO_STREAM << "RPC2TangoBridge::RPC2TangoBridge() create device " << device_name << endl;
+
+	// Initialise variables to default values
+	//--------------------------------------------
+	set_state(Tango::INIT);
+	set_status("Reading device properties");
+	get_device_property();
+
+	/* Now let's allocate the dynamic attributes whose name 
+	 * is taken from the configuration file.
+	 */
+	set_status("Allocating dynamic attributes");
+
+	AllocateAttributes();
+	set_state(Tango::ON);
+	set_status("ON");
+}
+
+
+//+----------------------------------------------------------------------------
+//
+// method : 		RPC2TangoBridge::get_device_property()
+// 
+// description : 	Read the device properties from database.
+//
+//-----------------------------------------------------------------------------
+void RPC2TangoBridge::get_device_property()
+{
+	//	Initialize your default values here (if not done with  POGO).
+	//------------------------------------------------------------------
+
+	//	Read device properties from database.(Automatic code generation)
+	//------------------------------------------------------------------
+	Tango::DbData	dev_prop;
+	dev_prop.push_back(Tango::DbDatum("Rpc_items"));
+
+	//	Call database and extract values
+	//--------------------------------------------
+	if (Tango::Util::instance()->_UseDb==true)
+		get_db_device()->get_property(dev_prop);
+	Tango::DbDatum	def_prop, cl_prop;
+	RPC2TangoBridgeClass	*ds_class =
+		(static_cast<RPC2TangoBridgeClass *>(get_device_class()));
+	int	i = -1;
+
+	//	Try to initialize Rpc_items from class property
+	cl_prop = ds_class->get_class_property(dev_prop[++i].name);
+	if (cl_prop.is_empty()==false)	cl_prop  >>  rpc_items;
+	//	Try to initialize Rpc_items from default device value
+	def_prop = ds_class->get_default_device_property(dev_prop[i].name);
+	if (def_prop.is_empty()==false)	def_prop  >>  rpc_items;
+	//	And try to extract Rpc_items value from database
+	if (dev_prop[i].is_empty()==false)	dev_prop[i]  >>  rpc_items;
+
+
+
+	//	End of Automatic code generation
+	//------------------------------------------------------------------
+	DEBUG_STREAM << rpc_items.size() << "rpc items " <<  endl;
+
+}
+
+/* NOTE: careful: add_attribute deletes an attribute with the same name if it was 
+ * already created!
+ */
+void RPC2TangoBridge::AllocateAttributes()
+{
+	int i = 0, totatt = 0, j;
+	char rpcentity[MAXLEN];
+
+	UserDefaultAttrProp default_att_prop;
+	
+// 	printf("\e[1;32m* \e[0mCreating dynamic attributes...\n");
+// 	printf("\e[1;33m*\e[0m If you want to remove an attribute from the\n"
+// 		"\e[1;33m*\e[0m list in the \e[1;4;37mdevice properties\e[0m, remember\n"
+// 		"\e[1;33m*\e[0m first to \e[1;4;37mdisable polling\e[0m and to restore\n"
+// 		"\e[1;33m*\e[0m any modified attribute property to its default.\n"
+// 		"\e[1;33m*\e[0m Otherwise you will not be able to start this server\n"
+// 		"\e[1;33m*\e[0m until references to no more existing attributes remain\n"
+// 		"\e[1;33m*\e[0m on the \e[1;4;37mtango database\e[0m.\n\n");
+
+	/* rpc_items is a vector of strings, got from init_device and loaded
+	 * from the DeviceProperties.
+	 */
+// 	totatt = rpc_items.size();
+// 
+// 	if(totatt == 0)
+// 	{
+// // 		printf("\e[1;31mNo RPC entities specified as device properties\n\e[0m");
+// // 		printf("\e[1;32mhint\e[0m: Define some entries and restart the device server\n\n");
+// 		//exit(EXIT_SUCCESS);
+// 	}
+
+	for(i = 0; i < rpc_items.size(); i++)
+	{
+// 		printf("\n- rpc_items %d:\"%s\"\n", i, rpc_items[i].c_str());
+		memset(rpcentity, 0, MAXLEN);
+		strncpy(rpcentity, rpc_items[i].c_str(), MAXLEN - 1);
+// 		print_progress(totatt, i);
+
+		bool force_is_spectrum = force_spectrum(rpcentity);
+		map<string, BridgeAttr*> ::iterator scalarMapIter = namesMap.find(string(rpcentity));
+		map<string, SpectrumBridgeAttr*> ::iterator spectrumMapIter = spectrumNamesMap.find(string(rpcentity));
+		if( scalarMapIter != namesMap.end() || spectrumMapIter != spectrumNamesMap.end() )
+		{
+			/* WARNING: do not add_attribute() two times with the same NAME! */
+			//printf("\e[1;31m* \e[0mthe element \"\e[1;31m%s\e[0m\" is duplicated: not adding it again\n", rpcentity);
+		}
+		else
+		{
+			try
+			{
+				AttributeConverter tangoAttr(rpcentity);
+				if(tangoAttr.isSpectrum())
+				{
+					SpectrumBridgeAttr* spattr = tangoAttr.spectrumAttribute();
+					string name(spattr->get_name());
+					if(spattr != NULL && spattr->connected())
+					{
+						DEBUG_STREAM << "Aggiunto alla mappa con nome " << name << " e " << spattr->get_name() << " 0x" << spattr << endl;
+						spectrumNamesMap[name] = spattr;
+						add_attribute(spattr);
+					}
+					
+				}
+				else
+				{
+					BridgeAttr * att = tangoAttr.scalarAttribute();
+					string name(att->get_name());
+					if(att != NULL && att->connected())
+					{
+						/* insert the couple attribute name/BridgeAttr* into the names map */
+						namesMap[name] = att; 
+						add_attribute(att);
+					}
+					
+				}
+			}
+			catch(Tango::DevFailed &e)
+			{
+				printException("Error creating attribute", e);	
+			}
+		} /* else: element not already present in the map */
+	}
+	RPCHandleSet::instance()->handleCount();
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		RPC2TangoBridge::always_executed_hook()
+// 
+// description : 	method always executed before any command is executed
+//
+//-----------------------------------------------------------------------------
+void RPC2TangoBridge::always_executed_hook()
+{
+	
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		RPC2TangoBridge::read_attr_hardware
+// 
+// description : 	Hardware acquisition for attributes.
+//
+//-----------------------------------------------------------------------------
+void RPC2TangoBridge::read_attr_hardware(vector<long> &attr_list)
+{
+	DEBUG_STREAM << "RPC2TangoBridge::read_attr_hardware(vector<long> &attr_list) entering... "<< endl;
+
+//	Add your own code here
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		RPC2TangoBridge::read_AlarmAttribute
+// 
+// description : 	Extract real attribute values for AlarmAttribute acquisition result.
+//
+//-----------------------------------------------------------------------------
+void RPC2TangoBridge::read_BridgeAttr(Tango::Attribute &attr)
+{
+	DEBUG_STREAM << "RPC2TangoBridge::read_AlarmAttribute(Tango::Attribute &attr) entering... "<< endl;
+
+	read_dynamic_attribute(attr);
+}
+
+void RPC2TangoBridge::write_BridgeAttr(Tango::WAttribute &attr)
+{
+	bool res;
+	DEBUG_STREAM<<"write_BridgeAttr()" << endl;
+	res = write_dynamic_attribute(attr);
+	if(!res)
+		Except::throw_exception("Error writing attribute " + attr.get_name(),
+				"Probably the format is not supported.\nSupported formats: long, double, short, boolean - SCALARS -",
+				"RPC2TangoBridge::write_BridgeAttr()");
+}
+
+void RPC2TangoBridge::print_progress(int tot, int part)
+{
+        return;
+//         const int numbars_tot = 20;
+//         int current_bar = part * 20 / tot;
+//         int i = 0;
+//         int percent = part * 100 / tot;
+//         printf("\r             \r");
+//         //printf("\r\b\b\b\b\b\b\b\b\b\b\b\b\r");
+//         fflush(stdout);
+//         if(part < tot)
+//         {
+//                 if(part % 4 == 0)
+//                         printf("|");
+//                 else if(part % 4 == 1)
+//                         printf( "\\");
+//                 else if(part % 4 == 2)
+//                         printf("-");
+//                 else if(part % 4 == 3)
+//                         printf("/");
+//                 fflush(stdout);
+//                 printf("\t[%d%%]", percent);
+//         }
+//         fflush(stdout);
+}
+
+void RPC2TangoBridge::printException(const char* msg, Tango::DevFailed &e)
+{
+	string err, descr, orig;
+        int i;
+        for(i = e.errors.length() - 1; i >= 0;  i--)
+        {
+                err = e.errors[i].reason;
+                descr = e.errors[i].desc;
+                orig = e.errors[i].origin;
+	}
+// 	printf("\n* \e[1;31m%s:\e[0m\n\t%s\n\t%s\n\t%s\n\e[0m", msg, err.c_str(), 
+// 		descr.c_str(), orig.c_str());
+}
+
+//+------------------------------------------------------------------
+/**
+ *	method:	RPC2TangoBridge::rpcdata_for_attribute
+ *
+ *	description:	method to execute "RPCDataForAttribute"
+ *	[3]the connection state (connected,disconnected)
+ *
+ * @param	argin	The name of an attribute representing an RPC call, such as SIP120_S2.1_PRES_RR
+ * @return	Three values: [1]the RPC host name; [2]the RPC port; [3]the connection state (connected,disconnected)
+ *
+ */
+//+------------------------------------------------------------------
+Tango::DevVarStringArray *RPC2TangoBridge::rpcdata_for_attribute(Tango::DevString argin)
+{
+	//	POGO has generated a method core with argout allocation.
+	//	If you would like to use a static reference without copying,
+	//	See "TANGO Device Server Programmer's Manual"
+	//		(chapter : Writing a TANGO DS / Exchanging data)
+	//------------------------------------------------------------
+	Tango::DevVarStringArray	*argout  = new Tango::DevVarStringArray();
+	DEBUG_STREAM << "RPC2TangoBridge::rpcdata_for_attribute(): entering... !" << endl;
+
+	//	Add your own code to control device here
+	bool found = true;
+	map<string, BridgeAttr*>::iterator smapiter;
+	RPCHandle *handle = NULL;
+	map<string, SpectrumBridgeAttr*>::iterator spmapiter;
+	char port[8];
+
+	for(smapiter= namesMap.begin(); smapiter != namesMap.end(); smapiter++)
+	{
+		if(!strcmp(smapiter->first.c_str(), argin))
+		{
+			handle = smapiter->second->rpcHandle();
+			break;
+		}
+	}
+	for(spmapiter= spectrumNamesMap.begin(); spmapiter != spectrumNamesMap.end(); spmapiter++)
+	{
+		if(!strcmp(spmapiter->first.c_str(), argin))
+		{
+			handle = spmapiter->second->rpcHandle();
+			break;
+		}
+	}
+	if(smapiter == namesMap.end() && spmapiter == spectrumNamesMap.end())
+		found = false;
+
+	/* could avoid found variable and test for NULL, but this gives the possibility
+	 * to have an attribute with a handle NULL
+	 */
+	if(!found)
+	{
+		argout->length(1);
+		(*argout)[0] = CORBA::string_dup("No attribute with that name!");
+	}
+	else if(handle == NULL)
+	{
+		argout->length(1);
+		(*argout)[0] = CORBA::string_dup("invalid handle: this won't work");
+	}
+	else
+	{
+		argout->length(3);
+		(*argout)[0] = CORBA::string_dup(handle->host().c_str());
+		snprintf(port, 8, "%d", handle->port());
+		(*argout)[1] = CORBA::string_dup(port);
+		if(handle->connected())
+			(*argout)[2] = CORBA::string_dup("connected");
+		else
+			(*argout)[2] = CORBA::string_dup("disconnected");
+	}		
+	
+	return argout;
+}
+
+//+------------------------------------------------------------------
+/**
+ *	method:	RPC2TangoBridge::standby
+ *
+ *	description:	method to execute "Standby"
+ *	Puts the server in Standby mode: RPC calls are disabled.
+ *
+ *
+ */
+//+------------------------------------------------------------------
+void RPC2TangoBridge::standby()
+{
+	DEBUG_STREAM << "RPC2TangoBridge::standby(): entering... !" << endl;
+
+	//	Add your own code to control device here
+	set_state(Tango::STANDBY);
+	set_status("Standby mode: no RPC calls will be made");
+
+}
+
+bool RPC2TangoBridge::is_BridgeAttr_allowed(Tango::AttReqType type)
+{
+	if(get_state() != Tango::ON)
+		return false;
+	else 
+		return true;
+}
+
+//+------------------------------------------------------------------
+/**
+ *	method:	RPC2TangoBridge::on
+ *
+ *	description:	method to execute "On"
+ *	From the Standby state, the command On enables the RPC calls again.
+ *
+ *
+ */
+//+------------------------------------------------------------------
+void RPC2TangoBridge::on()
+{
+	DEBUG_STREAM << "RPC2TangoBridge::on(): entering... !" << endl;
+
+	//	Add your own code to control device here
+	set_state(Tango::ON);
+	set_status("On: RPC calls enabled");
+}
+
+
+
+bool RPC2TangoBridge::force_spectrum(char *s)
+{
+	int i;
+	for(i = 0; i < strlen(s); i++)
+		if(s[i] == ',')
+			break;
+	if(i == strlen(s))
+		return false;
+	if(strncmp(s + i + 1, "spectrum", strlen("spectrum")) == 0)
+	{
+		s[i] = '\0'; /* remove the spectrum force keyword */
+		return true;
+	}
+	return false;
+
+}
+
+}	//	namespace
diff --git a/RPC2TangoBridge.h b/RPC2TangoBridge.h
new file mode 100644
index 0000000000000000000000000000000000000000..870ff365c79bf676f4796d5929c9dabb1edb9fdc
--- /dev/null
+++ b/RPC2TangoBridge.h
@@ -0,0 +1,271 @@
+//=============================================================================
+//
+// file :        RPC2TangoBridge.h
+//
+// description : Include for the RPC2TangoBridge class.
+//
+// project :	Provides a conversion from RPC alarms to Tango alarm attributes.
+//
+// $Author: claudio $
+//
+// $Revision: 1.4 $
+//
+// $Log: RPC2TangoBridge.h,v $
+// Revision 1.4  2017-03-28 09:39:02  claudio
+// ticket 2413: tango-9
+//
+// Revision 1.3  2012-08-09 13:04:39  claudio
+// tango 4 impl
+//
+// Revision 1.2  2009/02/26 08:15:45  giacomo
+// Versione di RPC2TangoBridge con supporto ad attributi SCALARI READ WRITE.
+// La parte WRITE va specificata nelle device properties separata da : dalla
+// parte rpc read.
+//
+// Revision 1.1.1.1  2008/04/28 09:13:16  giacomo
+// Prima versione di RPC2TangoBridge
+//
+//
+// copyleft :    European Synchrotron Radiation Facility
+//               BP 220, Grenoble 38043
+//               FRANCE
+//
+//=============================================================================
+//
+//  		This file is generated by POGO
+//	(Program Obviously used to Generate tango Object)
+//
+//         (c) - Software Engineering Group - ESRF
+//=============================================================================
+#ifndef _RPCALARMTANGO_H
+#define _RPCALARMTANGO_H
+
+#include <tango.h>
+#include <map>
+//#include "RPC2TangoBridgeThread.h"
+
+
+using namespace Tango;
+using namespace std;
+
+/**
+ * @author	$Author: claudio $
+ * @version	$Revision: 1.4 $
+ */
+
+ //	Add your own constants definitions here.
+ //-----------------------------------------------
+
+
+namespace RPC2TangoBridge_ns
+{
+
+class RPC2TangoBridgeThread;
+class BridgeAttr;
+class SpectrumBridgeAttr;
+class RPCHandle;
+
+/**
+ * Class Description:
+ * Every RPC client who emits alarms will send them to this server.
+ *	RPCAlarmTAngo will then map every alarm into a specific Tango attribute, so
+ *	that it can be notified to the Tango Alarm System.
+ *	The Tango Alarm System has to subscribe to all the attributes managed by this
+ *	RPC2TangoBridge.
+ */
+
+/*
+ *	Device States Description:
+*  Tango::ON :       The device is in on state: the dynamic attributes have been allocated and
+ *                    the server is ready for read operations on the RPC handles.
+*  Tango::INIT :     The server is allocating the dynamic attributes.
+ *                    The server is reading the device property named Rpc_items and for each line
+ *                    is allocating a new dynamic attribute that maps the RPC call into a READ ONLY
+ *                    tango attribute.
+*  Tango::FAULT :    A read attribute failed.
+ *                    This can be a transitional state, when an RPC call fails for instance, and so
+ *                    it can appear for a short time and then resolve to the ON state when the next
+ *                    read ends successfully.
+ *                    Anyway, a persistent state of FAULT can indicate network problems or
+ *                    continuous failures in reads.
+*  Tango::CLOSE :    Deallocating dynamic attributes and exiting
+*  Tango::STANDBY :  In this state the RPC calls are disabled.
+ */
+
+
+class RPC2TangoBridge: public TANGO_BASE_CLASS
+{
+public :
+	//	Add your own data members here
+	//----------------------------------------
+//	void read_AlarmAttribute(Attribute attr);
+//	void write_AlarmAttribute(WAttribute &att);
+//	bool is_AlarmAttribute_allowed(Tango::AttReqType ty);
+	//	Here is the Start of the automatic code generation part
+	//-------------------------------------------------------------	
+/**
+ *	@name attributes
+ *	Attributs member data.
+ */
+//@{
+//@}
+
+/**
+ *	@name Device properties
+ *	Device properties member data.
+ */
+//@{
+/**
+ *	Here you have to put the list of rpc items.
+ *	An RPC item is made up of RPCNAME:RPCHOST:RPCPORT, for instance:
+ *	PSB_T2.2_STAT_RF:rpcpsb.domain.com:9100
+ */
+	vector<string>	rpc_items;
+//@}
+
+/**@name Constructors
+ * Miscellaneous constructors */
+//@{
+/**
+ * Constructs a newly allocated Command object.
+ *
+ *	@param cl	Class.
+ *	@param s 	Device Name
+ */
+	RPC2TangoBridge(Tango::DeviceClass *cl,string &s);
+/**
+ * Constructs a newly allocated Command object.
+ *
+ *	@param cl	Class.
+ *	@param s 	Device Name
+ */
+	RPC2TangoBridge(Tango::DeviceClass *cl,const char *s);
+/**
+ * Constructs a newly allocated Command object.
+ *
+ *	@param cl	Class.
+ *	@param s 	Device name
+ *	@param d	Device description.
+ */
+	RPC2TangoBridge(Tango::DeviceClass *cl,const char *s,const char *d);
+//@}
+
+/**@name Destructor
+ * Only one desctructor is defined for this class */
+//@{
+/**
+ * The object desctructor.
+ */	
+	~RPC2TangoBridge() {delete_device();};
+/**
+ *	will be called at device destruction or at init command.
+ */
+	void delete_device();
+//@}
+
+	
+/**@name Miscellaneous methods */
+//@{
+/**
+ *	Initialize the device
+ */
+	virtual void init_device();
+/**
+ *	Always executed method befor execution command method.
+ */
+	virtual void always_executed_hook();
+
+//@}
+
+/**
+ * @name RPC2TangoBridge methods prototypes
+ */
+
+//@{
+/**
+ *	Execution allowed for RPCDataForAttribute command.
+ */
+	virtual bool is_RPCDataForAttribute_allowed(const CORBA::Any &any);
+/**
+ *	Execution allowed for Standby command.
+ */
+	virtual bool is_Standby_allowed(const CORBA::Any &any);
+/**
+ *	Execution allowed for On command.
+ */
+	virtual bool is_On_allowed(const CORBA::Any &any);
+/**
+ * [3]the connection state (connected,disconnected)
+ *	@param	argin	The name of an attribute representing an RPC call, such as SIP120_S2.1_PRES_RR
+ *	@return	Three values: [1]the RPC host name; [2]the RPC port; [3]the connection state (connected,disconnected)
+ *	@exception DevFailed
+ */
+	Tango::DevVarStringArray	*rpcdata_for_attribute(Tango::DevString);
+/**
+ * Puts the server in Standby mode: RPC calls are disabled.
+ *	@exception DevFailed
+ */
+	void	standby();
+/**
+ * From the Standby state, the command On enables the RPC calls again.
+ *	@exception DevFailed
+ */
+	void	on();
+
+/**
+ *	Read the device properties from database
+ */
+	 void get_device_property();
+//@}
+
+	//	Here is the end of the automatic code generation part
+	//-------------------------------------------------------------	
+	/* Returns the configuration */
+////	map<const char*, struct alarm_tango_info*>  *TangoAlarmMap() { return &tangoalmap; }
+
+	 /**
+	 *	Read/Write allowed for BridgeAttr attribute.
+	 */
+	virtual bool is_BridgeAttr_allowed(Tango::AttReqType type);
+
+	/**
+	 *	Extract real attribute values for BridgeAttr acquisition result.
+	 */
+	virtual void read_BridgeAttr(Tango::Attribute &attr);
+	
+	/**
+ 	*      Write attribute values to hardware.
+ 	*/
+        virtual void write_BridgeAttr(Tango::WAttribute &attr);
+
+
+	void read_attr_hardware(std::vector<long int, std::allocator<long int> >&);
+
+protected :	
+	//	Add your own data members here
+	//-----------------------------------------
+	
+		
+	Tango::DevShort btest1, btest2;		
+	RPC2TangoBridgeThread *rpcthread;
+private:
+	void AllocateAttributes();
+
+	void print_progress(int tot, int part);
+	
+	map<string, BridgeAttr*> namesMap;
+	map<string, SpectrumBridgeAttr*> spectrumNamesMap;
+
+	map<BridgeAttr*, const char*> lpcHostsMap;
+	
+	void read_dynamic_attribute(Tango::Attribute &attr);
+	bool write_dynamic_attribute(Tango::WAttribute &w);
+	void printException(const char* msg, Tango::DevFailed &e);
+	bool force_spectrum(char* device_property);
+	
+//	Tango::DevShort *attr_AlarmAttribute_read;
+};
+
+}	// namespace_ns
+
+#endif	// _RPCALARMTANGO_H
diff --git a/RPC2TangoBridgeClass.cpp b/RPC2TangoBridgeClass.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..ca87e868ca5a7bd05a27a4696f13859599548046
--- /dev/null
+++ b/RPC2TangoBridgeClass.cpp
@@ -0,0 +1,501 @@
+static const char *RcsId     = "$Header: /home/cvsadm/cvsroot/elettra/server/RPC2TangoBridge/RPC2TangoBridgeClass.cpp,v 1.1.1.1 2008-04-28 09:13:16 giacomo Exp $";
+static const char *TagName   = "$Name:  $";
+static const char *HttpServer= "http://www.esrf.fr/computing/cs/tango/tango_doc/ds_doc/";
+//+=============================================================================
+//
+// file :        RPC2TangoBridgeClass.cpp
+//
+// description : C++ source for the RPC2TangoBridgeClass. A singleton
+//               class derived from DeviceClass. It implements the
+//               command list and all properties and methods required
+//               by the RPC2TangoBridge once per process.
+//
+// project :     TANGO Device Server
+//
+// $Author: giacomo $
+//
+// $Revision: 1.1.1.1 $
+//
+// $Log: RPC2TangoBridgeClass.cpp,v $
+// Revision 1.1.1.1  2008-04-28 09:13:16  giacomo
+// Prima versione di RPC2TangoBridge
+//
+//
+// copyleft :   European Synchrotron Radiation Facility
+//              BP 220, Grenoble 38043
+//              FRANCE
+//
+//-=============================================================================
+//
+//  		This file is generated by POGO
+//	(Program Obviously used to Generate tango Object)
+//
+//         (c) - Software Engineering Group - ESRF
+//=============================================================================
+
+
+#include <tango.h>
+
+#include <RPC2TangoBridge.h>
+#include <RPC2TangoBridgeClass.h>
+
+
+//+----------------------------------------------------------------------------
+/**
+ *	Create RPC2TangoBridgeClass singleton and return it in a C function for Python usage
+ */
+//+----------------------------------------------------------------------------
+extern "C" {
+#ifdef WIN32
+
+__declspec(dllexport)
+
+#endif
+
+	Tango::DeviceClass *_create_RPC2TangoBridge_class(const char *name) {
+		return RPC2TangoBridge_ns::RPC2TangoBridgeClass::init(name);
+	}
+}
+
+
+namespace RPC2TangoBridge_ns
+{
+//+----------------------------------------------------------------------------
+//
+// method : 		OnClass::execute()
+// 
+// description : 	method to trigger the execution of the command.
+//                PLEASE DO NOT MODIFY this method core without pogo   
+//
+// in : - device : The device on which the command must be excuted
+//		- in_any : The command input data
+//
+// returns : The command output data (packed in the Any object)
+//
+//-----------------------------------------------------------------------------
+CORBA::Any *OnClass::execute(Tango::DeviceImpl *device,const CORBA::Any &in_any)
+{
+
+	cout2 << "OnClass::execute(): arrived" << endl;
+
+	((static_cast<RPC2TangoBridge *>(device))->on());
+	return new CORBA::Any();
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		StandbyClass::execute()
+// 
+// description : 	method to trigger the execution of the command.
+//                PLEASE DO NOT MODIFY this method core without pogo   
+//
+// in : - device : The device on which the command must be excuted
+//		- in_any : The command input data
+//
+// returns : The command output data (packed in the Any object)
+//
+//-----------------------------------------------------------------------------
+CORBA::Any *StandbyClass::execute(Tango::DeviceImpl *device,const CORBA::Any &in_any)
+{
+
+	cout2 << "StandbyClass::execute(): arrived" << endl;
+
+	((static_cast<RPC2TangoBridge *>(device))->standby());
+	return new CORBA::Any();
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		RPCDataForAttributeCmd::execute()
+// 
+// description : 	method to trigger the execution of the command.
+//                PLEASE DO NOT MODIFY this method core without pogo   
+//
+// in : - device : The device on which the command must be excuted
+//		- in_any : The command input data
+//
+// returns : The command output data (packed in the Any object)
+//
+//-----------------------------------------------------------------------------
+CORBA::Any *RPCDataForAttributeCmd::execute(Tango::DeviceImpl *device,const CORBA::Any &in_any)
+{
+
+	cout2 << "RPCDataForAttributeCmd::execute(): arrived" << endl;
+
+	Tango::DevString	argin;
+	extract(in_any, argin);
+
+	return insert((static_cast<RPC2TangoBridge *>(device))->rpcdata_for_attribute(argin));
+}
+
+
+
+
+
+
+
+//
+//----------------------------------------------------------------
+//	Initialize pointer for singleton pattern
+//----------------------------------------------------------------
+//
+RPC2TangoBridgeClass *RPC2TangoBridgeClass::_instance = NULL;
+
+//+----------------------------------------------------------------------------
+//
+// method : 		RPC2TangoBridgeClass::RPC2TangoBridgeClass(string &s)
+// 
+// description : 	constructor for the RPC2TangoBridgeClass
+//
+// in : - s : The class name
+//
+//-----------------------------------------------------------------------------
+RPC2TangoBridgeClass::RPC2TangoBridgeClass(string &s):DeviceClass(s)
+{
+
+	cout2 << "Entering RPC2TangoBridgeClass constructor" << endl;
+	set_default_property();
+	write_class_property();
+	get_class_property();
+	
+	cout2 << "Leaving RPC2TangoBridgeClass constructor" << endl;
+
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		RPC2TangoBridgeClass::~RPC2TangoBridgeClass()
+// 
+// description : 	destructor for the RPC2TangoBridgeClass
+//
+//-----------------------------------------------------------------------------
+RPC2TangoBridgeClass::~RPC2TangoBridgeClass()
+{
+	_instance = NULL;
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		RPC2TangoBridgeClass::instance
+// 
+// description : 	Create the object if not already done. Otherwise, just
+//			return a pointer to the object
+//
+// in : - name : The class name
+//
+//-----------------------------------------------------------------------------
+RPC2TangoBridgeClass *RPC2TangoBridgeClass::init(const char *name)
+{
+	if (_instance == NULL)
+	{
+		try
+		{
+			string s(name);
+			_instance = new RPC2TangoBridgeClass(s);
+		}
+		catch (bad_alloc)
+		{
+			throw;
+		}		
+	}		
+	return _instance;
+}
+
+RPC2TangoBridgeClass *RPC2TangoBridgeClass::instance()
+{
+	if (_instance == NULL)
+	{
+		cerr << "Class is not initialised !!" << endl;
+		exit(-1);
+	}
+	return _instance;
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		RPC2TangoBridgeClass::command_factory
+// 
+// description : 	Create the command object(s) and store them in the 
+//			command list
+//
+//-----------------------------------------------------------------------------
+void RPC2TangoBridgeClass::command_factory()
+{
+	command_list.push_back(new RPCDataForAttributeCmd("RPCDataForAttribute",
+		Tango::DEV_STRING, Tango::DEVVAR_STRINGARRAY,
+		"The name of an attribute representing an RPC call, such as SIP120_S2.1_PRES_RR",
+		"Three values: [1]the RPC host name; [2]the RPC port; [3]the connection state (connected,disconnected)",
+		Tango::OPERATOR));
+	command_list.push_back(new StandbyClass("Standby",
+		Tango::DEV_VOID, Tango::DEV_VOID,
+		"",
+		"",
+		Tango::OPERATOR));
+	command_list.push_back(new OnClass("On",
+		Tango::DEV_VOID, Tango::DEV_VOID,
+		"",
+		"",
+		Tango::OPERATOR));
+
+	//	add polling if any
+	for (unsigned int i=0 ; i<command_list.size(); i++)
+	{
+	}
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		RPC2TangoBridgeClass::get_class_property
+// 
+// description : 	Get the class property for specified name.
+//
+// in :		string	name : The property name
+//
+//+----------------------------------------------------------------------------
+Tango::DbDatum RPC2TangoBridgeClass::get_class_property(string &prop_name)
+{
+	for (unsigned int i=0 ; i<cl_prop.size() ; i++)
+		if (cl_prop[i].name == prop_name)
+			return cl_prop[i];
+	//	if not found, return  an empty DbDatum
+	return Tango::DbDatum(prop_name);
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		RPC2TangoBridgeClass::get_default_device_property()
+// 
+// description : 	Return the default value for device property.
+//
+//-----------------------------------------------------------------------------
+Tango::DbDatum RPC2TangoBridgeClass::get_default_device_property(string &prop_name)
+{
+	for (unsigned int i=0 ; i<dev_def_prop.size() ; i++)
+		if (dev_def_prop[i].name == prop_name)
+			return dev_def_prop[i];
+	//	if not found, return  an empty DbDatum
+	return Tango::DbDatum(prop_name);
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		RPC2TangoBridgeClass::get_default_class_property()
+// 
+// description : 	Return the default value for class property.
+//
+//-----------------------------------------------------------------------------
+Tango::DbDatum RPC2TangoBridgeClass::get_default_class_property(string &prop_name)
+{
+	for (unsigned int i=0 ; i<cl_def_prop.size() ; i++)
+		if (cl_def_prop[i].name == prop_name)
+			return cl_def_prop[i];
+	//	if not found, return  an empty DbDatum
+	return Tango::DbDatum(prop_name);
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		RPC2TangoBridgeClass::device_factory
+// 
+// description : 	Create the device object(s) and store them in the 
+//			device list
+//
+// in :		Tango::DevVarStringArray *devlist_ptr : The device name list
+//
+//-----------------------------------------------------------------------------
+void RPC2TangoBridgeClass::device_factory(const Tango::DevVarStringArray *devlist_ptr)
+{
+
+	//	Create all devices.(Automatic code generation)
+	//-------------------------------------------------------------
+	for (unsigned long i=0 ; i < devlist_ptr->length() ; i++)
+	{
+		cout4 << "Device name : " << (*devlist_ptr)[i].in() << endl;
+						
+		// Create devices and add it into the device list
+		//----------------------------------------------------
+		device_list.push_back(new RPC2TangoBridge(this, (*devlist_ptr)[i]));							 
+
+		// Export device to the outside world
+		// Check before if database used.
+		//---------------------------------------------
+		if ((Tango::Util::_UseDb == true) && (Tango::Util::_FileDb == false))
+			export_device(device_list.back());
+		else
+			export_device(device_list.back(), (*devlist_ptr)[i]);
+	}
+	//	End of Automatic code generation
+	//-------------------------------------------------------------
+
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+//+----------------------------------------------------------------------------
+//
+// method : 		RPC2TangoBridgeClass::get_class_property()
+// 
+// description : 	Read the class properties from database.
+//
+//-----------------------------------------------------------------------------
+void RPC2TangoBridgeClass::get_class_property()
+{
+	//	Initialize your default values here (if not done with  POGO).
+	//------------------------------------------------------------------
+
+	//	Read class properties from database.(Automatic code generation)
+	//------------------------------------------------------------------
+
+	//	Call database and extract values
+	//--------------------------------------------
+	if (Tango::Util::instance()->_UseDb==true)
+		get_db_class()->get_property(cl_prop);
+	Tango::DbDatum	def_prop;
+	int	i = -1;
+
+
+	//	End of Automatic code generation
+	//------------------------------------------------------------------
+
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 	RPC2TangoBridgeClass::set_default_property
+// 
+// description: Set default property (class and device) for wizard.
+//              For each property, add to wizard property name and description
+//              If default value has been set, add it to wizard property and
+//              store it in a DbDatum.
+//
+//-----------------------------------------------------------------------------
+void RPC2TangoBridgeClass::set_default_property()
+{
+	string	prop_name;
+	string	prop_desc;
+	string	prop_def;
+
+	vector<string>	vect_data;
+	//	Set Default Class Properties
+	//	Set Default Device Properties
+	prop_name = "Rpc_items";
+	prop_desc = "Here you have to put the list of rpc items.\nAn RPC item is made up of RPCNAME:RPCHOST:RPCPORT, for instance:\nPSB_T2.2_STAT_RF:rpcpsb.domain.com:9100";
+	prop_def  = "";
+	if (prop_def.length()>0)
+	{
+		Tango::DbDatum	data(prop_name);
+		data << vect_data ;
+		dev_def_prop.push_back(data);
+		add_wiz_dev_prop(prop_name, prop_desc,  prop_def);
+	}
+	else
+		add_wiz_dev_prop(prop_name, prop_desc);
+
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		RPC2TangoBridgeClass::write_class_property
+// 
+// description : 	Set class description as property in database
+//
+//-----------------------------------------------------------------------------
+void RPC2TangoBridgeClass::write_class_property()
+{
+	//	First time, check if database used
+	//--------------------------------------------
+	if (Tango::Util::_UseDb == false)
+		return;
+
+	Tango::DbData	data;
+	string	classname = get_name();
+	string	header;
+	string::size_type	start, end;
+
+	//	Put title
+	Tango::DbDatum	title("ProjectTitle");
+	string	str_title("Provides a conversion from RPC alarms to Tango alarm attributes.");
+	title << str_title;
+	data.push_back(title);
+
+	//	Put Description
+	Tango::DbDatum	description("Description");
+	vector<string>	str_desc;
+	str_desc.push_back("Every RPC client who emits alarms will send them to this server.");
+	str_desc.push_back("RPCAlarmTAngo will then map every alarm into a specific Tango attribute, so");
+	str_desc.push_back("that it can be notified to the Tango Alarm System.");
+	str_desc.push_back("The Tango Alarm System has to subscribe to all the attributes managed by this");
+	str_desc.push_back("RPC2TangoBridge.");
+	description << str_desc;
+	data.push_back(description);
+		
+	//	put cvs location
+	string	rcsId(RcsId);
+	string	filename(classname);
+	start = rcsId.find("/");
+	if (start!=string::npos)
+	{
+		filename += "Class.cpp";
+		end   = rcsId.find(filename);
+		if (end>start)
+		{
+			string	strloc = rcsId.substr(start, end-start);
+			//	Check if specific repository
+			start = strloc.find("/cvsroot/");
+			if (start!=string::npos && start>0)
+			{
+				string	repository = strloc.substr(0, start);
+				if (repository.find("/segfs/")!=string::npos)
+					strloc = "ESRF:" + strloc.substr(start, strloc.length()-start);
+			}
+			Tango::DbDatum	cvs_loc("cvs_location");
+			cvs_loc << strloc;
+			data.push_back(cvs_loc);
+		}
+	}
+
+	//	Get CVS tag revision
+	string	tagname(TagName);
+	header = "$Name: ";
+	start = header.length();
+	string	endstr(" $");
+	end   = tagname.find(endstr);
+	if (end!=string::npos && end>start)
+	{
+		string	strtag = tagname.substr(start, end-start);
+		Tango::DbDatum	cvs_tag("cvs_tag");
+		cvs_tag << strtag;
+		data.push_back(cvs_tag);
+	}
+
+	//	Get URL location
+	string	httpServ(HttpServer);
+	if (httpServ.length()>0)
+	{
+		Tango::DbDatum	db_doc_url("doc_url");
+		db_doc_url << httpServ;
+		data.push_back(db_doc_url);
+	}
+
+	//  Put inheritance
+	Tango::DbDatum	inher_datum("InheritedFrom");
+	vector<string> inheritance;
+	inheritance.push_back("Device_3Impl");
+	inher_datum << inheritance;
+	data.push_back(inher_datum);
+
+	//	Call database and and values
+	//--------------------------------------------
+	get_db_class()->put_property(data);
+}
+
+}	// namespace
diff --git a/RPC2TangoBridgeClass.h b/RPC2TangoBridgeClass.h
new file mode 100644
index 0000000000000000000000000000000000000000..57b1406ebe3ab811083d9bba26954d04950b7e61
--- /dev/null
+++ b/RPC2TangoBridgeClass.h
@@ -0,0 +1,161 @@
+//=============================================================================
+//
+// file :         RPC2TangoBridgeClass.h
+//
+// description :  Include for the RPC2TangoBridgeClass root class.
+//                This class is represents the singleton class for
+//                the RPC2TangoBridge device class.
+//                It contains all properties and methods which the 
+//                RPC2TangoBridge requires only once e.g. the commands.
+//			
+// project :      TANGO Device Server
+//
+// $Author: giacomo $
+//
+// $Revision: 1.1.1.1 $
+//
+// $Log: RPC2TangoBridgeClass.h,v $
+// Revision 1.1.1.1  2008-04-28 09:13:16  giacomo
+// Prima versione di RPC2TangoBridge
+//
+//
+// copyleft :     European Synchrotron Radiation Facility
+//                BP 220, Grenoble 38043
+//                FRANCE
+//
+//=============================================================================
+//
+//  		This file is generated by POGO
+//	(Program Obviously used to Generate tango Object)
+//
+//         (c) - Software Engineering Group - ESRF
+//=============================================================================
+
+#ifndef _RPCALARMTANGOCLASS_H
+#define _RPCALARMTANGOCLASS_H
+
+#include <tango.h>
+#include <RPC2TangoBridge.h>
+
+
+namespace RPC2TangoBridge_ns
+{
+//=====================================
+//	Define classes for attributes
+//=====================================
+//=========================================
+//	Define classes for commands
+//=========================================
+class OnClass : public Tango::Command
+{
+public:
+	OnClass(const char   *name,
+	               Tango::CmdArgType in,
+				   Tango::CmdArgType out,
+				   const char        *in_desc,
+				   const char        *out_desc,
+				   Tango::DispLevel  level)
+	:Command(name,in,out,in_desc,out_desc, level)	{};
+
+	OnClass(const char   *name,
+	               Tango::CmdArgType in,
+				   Tango::CmdArgType out)
+	:Command(name,in,out)	{};
+	~OnClass() {};
+	
+	virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any);
+	virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any)
+	{return (static_cast<RPC2TangoBridge *>(dev))->is_On_allowed(any);}
+};
+
+
+
+class StandbyClass : public Tango::Command
+{
+public:
+	StandbyClass(const char   *name,
+	               Tango::CmdArgType in,
+				   Tango::CmdArgType out,
+				   const char        *in_desc,
+				   const char        *out_desc,
+				   Tango::DispLevel  level)
+	:Command(name,in,out,in_desc,out_desc, level)	{};
+
+	StandbyClass(const char   *name,
+	               Tango::CmdArgType in,
+				   Tango::CmdArgType out)
+	:Command(name,in,out)	{};
+	~StandbyClass() {};
+	
+	virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any);
+	virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any)
+	{return (static_cast<RPC2TangoBridge *>(dev))->is_Standby_allowed(any);}
+};
+
+
+
+class RPCDataForAttributeCmd : public Tango::Command
+{
+public:
+	RPCDataForAttributeCmd(const char   *name,
+	               Tango::CmdArgType in,
+				   Tango::CmdArgType out,
+				   const char        *in_desc,
+				   const char        *out_desc,
+				   Tango::DispLevel  level)
+	:Command(name,in,out,in_desc,out_desc, level)	{};
+
+	RPCDataForAttributeCmd(const char   *name,
+	               Tango::CmdArgType in,
+				   Tango::CmdArgType out)
+	:Command(name,in,out)	{};
+	~RPCDataForAttributeCmd() {};
+	
+	virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any);
+	virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any)
+	{return (static_cast<RPC2TangoBridge *>(dev))->is_RPCDataForAttribute_allowed(any);}
+};
+
+
+
+//
+// The RPC2TangoBridgeClass singleton definition
+//
+
+class RPC2TangoBridgeClass : public Tango::DeviceClass
+{
+public:
+//	properties member data
+
+//	add your own data members here
+//------------------------------------
+
+public:
+	Tango::DbData	cl_prop;
+	Tango::DbData	cl_def_prop;
+	Tango::DbData	dev_def_prop;
+
+//	Method prototypes
+	static RPC2TangoBridgeClass *init(const char *);
+	static RPC2TangoBridgeClass *instance();
+	~RPC2TangoBridgeClass();
+	Tango::DbDatum	get_class_property(string &);
+	Tango::DbDatum	get_default_device_property(string &);
+	Tango::DbDatum	get_default_class_property(string &);
+	
+protected:
+	RPC2TangoBridgeClass(string &);
+	static RPC2TangoBridgeClass *_instance;
+	void command_factory();
+	void get_class_property();
+	void write_class_property();
+	void set_default_property();
+
+private:
+	void device_factory(const Tango::DevVarStringArray *);
+};
+
+
+}	//	namespace RPC2TangoBridge_ns
+
+#endif // _RPC2TANGOBRIDGECLASS_H
diff --git a/RPC2TangoBridgeStateMachine.cpp b/RPC2TangoBridgeStateMachine.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..8cd9e8a6a9c15c0bbdd1d28dfa9e1bb227b85bf0
--- /dev/null
+++ b/RPC2TangoBridgeStateMachine.cpp
@@ -0,0 +1,116 @@
+static const char *RcsId = "$Header: /home/cvsadm/cvsroot/elettra/server/RPC2TangoBridge/RPC2TangoBridgeStateMachine.cpp,v 1.1.1.1 2008-04-28 09:13:16 giacomo Exp $";
+//+=============================================================================
+//
+// file :         RPC2TangoBridgeStateMachine.cpp
+//
+// description :  C++ source for the RPC2TangoBridge and its alowed. 
+//                method for commands and attributes
+//
+// project :      TANGO Device Server
+//
+// $Author: giacomo $
+//
+// $Revision: 1.1.1.1 $
+//
+// $Log: RPC2TangoBridgeStateMachine.cpp,v $
+// Revision 1.1.1.1  2008-04-28 09:13:16  giacomo
+// Prima versione di RPC2TangoBridge
+//
+//
+// copyleft :     European Synchrotron Radiation Facility
+//                BP 220, Grenoble 38043
+//                FRANCE
+//
+//-=============================================================================
+//
+//  		This file is generated by POGO
+//	(Program Obviously used to Generate tango Object)
+//
+//         (c) - Software Engineering Group - ESRF
+//=============================================================================
+
+#include <tango.h>
+#include <RPC2TangoBridge.h>
+#include <RPC2TangoBridgeClass.h>
+
+/*====================================================================
+ *	This file contains the methods to allow commands and attributes
+ * read or write execution.
+ *
+ * If you wand to add your own code, add it between 
+ * the "End/Re-Start of Generated Code" comments.
+ *
+ * If you want, you can also add your own methods.
+ *====================================================================
+ */
+
+namespace RPC2TangoBridge_ns
+{
+
+//=================================================
+//		Attributes Allowed Methods
+//=================================================
+
+
+//=================================================
+//		Commands Allowed Methods
+//=================================================
+
+//+----------------------------------------------------------------------------
+//
+// method : 		RPC2TangoBridge::is_RPCDataForAttribute_allowed
+// 
+// description : 	Execution allowed for RPCDataForAttribute command.
+//
+//-----------------------------------------------------------------------------
+bool RPC2TangoBridge::is_RPCDataForAttribute_allowed(const CORBA::Any &any)
+{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		RPC2TangoBridge::is_Standby_allowed
+// 
+// description : 	Execution allowed for Standby command.
+//
+//-----------------------------------------------------------------------------
+bool RPC2TangoBridge::is_Standby_allowed(const CORBA::Any &any)
+{
+	if (get_state() == Tango::INIT	||
+		get_state() == Tango::FAULT	||
+		get_state() == Tango::CLOSE	||
+		get_state() == Tango::STANDBY)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		RPC2TangoBridge::is_On_allowed
+// 
+// description : 	Execution allowed for On command.
+//
+//-----------------------------------------------------------------------------
+bool RPC2TangoBridge::is_On_allowed(const CORBA::Any &any)
+{
+	if (get_state() == Tango::ON	||
+		get_state() == Tango::INIT	||
+		get_state() == Tango::FAULT	||
+		get_state() == Tango::CLOSE)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+
+}	// namespace RPC2TangoBridge_ns
diff --git a/RPC2TangoBridgeThread.cpp b/RPC2TangoBridgeThread.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..b9c307b1a88f660c1fe8493ddaa3b230c0eccdee
--- /dev/null
+++ b/RPC2TangoBridgeThread.cpp
@@ -0,0 +1,32 @@
+#include "RPC2TangoBridge.h"
+#include <iostream>
+#include "RPC2TangoBridgeThread.h"
+
+class RPC2TangoBridge;
+
+namespace RPC2TangoBridge_ns
+{
+
+RPC2TangoBridgeThread::RPC2TangoBridgeThread(RPC2TangoBridge* parent)
+{
+	tango_server = parent;
+	
+}
+
+RPC2TangoBridgeThread::~RPC2TangoBridgeThread()
+{
+
+}
+
+/* Calling this makes the server loop break */
+void RPC2TangoBridgeThread::stop_loop()
+{
+}
+
+void *RPC2TangoBridgeThread::RPC2TangoBridgeThread::run_undetached(void *data)
+{
+	return NULL;
+}
+
+}
+
diff --git a/RPC2TangoBridgeThread.h b/RPC2TangoBridgeThread.h
new file mode 100644
index 0000000000000000000000000000000000000000..1f34698211ea2134813d66fb79fa6b4786c9462e
--- /dev/null
+++ b/RPC2TangoBridgeThread.h
@@ -0,0 +1,28 @@
+#ifndef RPCALARM_THREAD_H
+#define RPCALARM_THREAD_H
+
+#include <omnithread.h>
+#include "RPC2TangoBridge.h"
+
+class RPC2TangoBridge;
+
+namespace RPC2TangoBridge_ns
+{
+
+class RPC2TangoBridgeThread : public omni_thread
+{
+	public:
+	  	RPC2TangoBridgeThread(RPC2TangoBridge* parent);
+		void StartUndetached() { start_undetached(); }
+		void stop_loop();
+		~RPC2TangoBridgeThread();
+	
+	private:
+		void* run_undetached(void *arg);
+		RPC2TangoBridge *tango_server;
+		
+};
+
+};
+
+#endif
diff --git a/RPCHandleSet.cpp b/RPCHandleSet.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..06d111eb8ee2d378dd217e42ae5dfd0fb81f9c31
--- /dev/null
+++ b/RPCHandleSet.cpp
@@ -0,0 +1,124 @@
+#include "RPCHandleSet.h"
+namespace RPC2TangoBridge_ns
+{
+
+RPCHandleSet* RPCHandleSet::_instance = NULL;
+
+RPCHandleSet::RPCHandleSet()
+{
+	
+}
+
+RPCHandleSet *RPCHandleSet::instance()
+{
+	if(_instance == NULL)
+		_instance = new RPCHandleSet();
+	return _instance;
+}
+	
+
+RPCReadHandle *RPCHandleSet::readHandleFromList(const char *rpc_call)
+{
+	int i, res;
+	RPCReadHandle *han;
+	char *host;
+	short int port;
+	res = RPCHandle::resolve_rpc(rpc_call, &host, &port);
+	if(host != NULL && res >= 0)
+	{
+		/* in host and port we have the host and port of the rpc service for that call */
+		for(i = 0; i < rpcRHandles.size(); i++)
+		{
+			han = rpcRHandles[i];
+			/* we must exclude the handles with host and port uninitialized */
+			if(han != NULL && han->host() != "" && han->port() != 0 &&
+					han->host() == string(host) && han->port() == port)
+				return han;
+		}
+	}
+	return NULL;
+}
+
+RPCWriteHandle *RPCHandleSet::writeHandleFromList(const char *rpc_call)
+{
+	int i, res;
+	RPCWriteHandle *han;
+	char *host;
+	short int port;
+	res = RPCHandle::resolve_rpc(rpc_call, &host, &port);
+	if(host != NULL && res >= 0)
+	{
+		/* in host and port we have the host and port of the rpc service for that call */
+		for(i = 0; i < rpcWHandles.size(); i++)
+		{
+			han = rpcWHandles[i];
+			/* we must exclude the handles with host and port uninitialized */
+			if(han != NULL && han->host() != "" && han->port() != 0 &&
+					han->host() == string(host) && han->port() == port)
+				return han;
+		}
+	}
+	return NULL;
+}
+
+void RPCHandleSet::removeHandle(RPCHandle *h)
+{
+	int i;
+	for(i = 0; i < rpcHandles.size(); i++)
+	{
+		if(rpcHandles[i] == h)
+			break;
+	}
+	if(i < rpcHandles.size())
+	{
+		//printf(" - removing handle \"%s\":%d from list\n", rpcHandles[i]->host().c_str(), rpcHandles[i]->port());
+		rpcHandles.erase(rpcHandles.begin() + i);
+	}
+	else{
+		//printf("\e[1;31m *\e[0m error: handle  \"%s\":%d  not found in list!\n", rpcHandles[i]->host().c_str(), rpcHandles[i]->port());
+	}
+}
+
+RPCHandle *RPCHandleSet::handleFromList(const char *rpc_call)
+{
+	int i, res;
+	RPCHandle *han;
+	char *host;
+	short int port;
+	res = RPCHandle::resolve_rpc(rpc_call, &host, &port);
+	if(host != NULL && res >= 0)
+	{
+		/* in host and port we have the host and port of the rpc service for that call */
+		for(i = 0; i < rpcHandles.size(); i++)
+		{
+			han = rpcHandles[i];
+			/* we must exclude the handles with host and port uninitialized */
+			if(han != NULL && han->host() != "" && han->port() != 0 &&
+					han->host() == string(host) && han->port() == port)
+				return han;
+		}
+	}
+	return NULL;
+}
+
+void RPCHandleSet::addReadHandle(RPCReadHandle* h)
+{
+	rpcRHandles.push_back(h);
+}
+
+void RPCHandleSet::addWriteHandle(RPCWriteHandle* h)
+{
+	rpcWHandles.push_back(h);
+}
+
+
+}
+
+
+
+
+
+
+
+
+
diff --git a/RPCHandleSet.h b/RPCHandleSet.h
new file mode 100644
index 0000000000000000000000000000000000000000..21b30945bc54b858c2f9ab1af7971c7d807ca723
--- /dev/null
+++ b/RPCHandleSet.h
@@ -0,0 +1,43 @@
+#ifndef RPC_HANDLE_SET_H
+#define RPC_HANDLE_SET_H
+
+#include <vector>
+#include "RpcReadHandle.h"
+#include "RpcWriteHandle.h"
+namespace RPC2TangoBridge_ns
+{
+
+class RPCHandleSet
+{
+	public:
+		static RPCHandleSet *instance();
+		RPCReadHandle *readHandleFromList(const char *rpcname);
+		RPCWriteHandle *writeHandleFromList(const char *rpcname);
+		
+		RPCHandle *handleFromList(const char* rpcname);
+		
+		void addReadHandle(RPCReadHandle* h);
+		void addWriteHandle(RPCWriteHandle *h);
+		
+		void addHandle(RPCHandle* h) { rpcHandles.push_back(h); }
+		void removeHandle(RPCHandle *h);
+		
+		unsigned handleCount() { return rpcHandles.size(); }
+		
+		void clear() { rpcRHandles.clear(); rpcWHandles.clear();  rpcHandles.clear();  }
+		
+	private:
+		
+		RPCHandleSet();
+		static RPCHandleSet *_instance;
+		
+		vector<RPCReadHandle* > rpcRHandles;
+		vector<RPCWriteHandle* > rpcWHandles;
+
+		vector<RPCHandle* > rpcHandles;
+};
+
+}
+
+#endif
+
diff --git a/RpcHandle.cpp b/RpcHandle.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..01fdd610e7070a8864499a3874bc98c03992cad0
--- /dev/null
+++ b/RpcHandle.cpp
@@ -0,0 +1,159 @@
+#include <RpcHandle.h>
+#include <omnithread.h>
+#include <RpcResolver.h>
+#include <errtype.h>
+#include <cstdlib>
+
+#define MAXERRLEN	512
+
+using namespace std;
+
+namespace RPC2TangoBridge_ns
+{
+
+static omni_mutex rpcMutex;
+
+RPCHandle::RPCHandle(RPCHandle *other)
+{
+	_host = other->host();
+	_port = other->port();
+	_sid = other->sid();
+	_refcnt = other->_refcnt;
+	_lastRpcErr = lastRpcError();
+	
+}
+
+RPCHandle::RPCHandle(string rpccall)
+{
+	char *host = 0;
+	short int port = 0;
+	_host = "";
+	_port = 0;
+	_sid = -1;
+	_refcnt = 0;
+	if(resolve_rpc(rpccall.c_str(), &host, &port))	
+	{
+		_host = string(host);
+		free(host);
+		_port = (unsigned short) port;
+		if(!connect())
+			_lastRpcErr = "Connection error to host " + _host;
+		else
+			_lastRpcErr = std::string("No error");
+	}
+	else /* do not connect(): this will leave _sid to -1 */
+		_lastRpcErr = "failed resolving call " + rpccall;
+	 
+}
+
+bool RPCHandle::resolve_rpc(const char *call, char** host, short int *port)
+{
+	int res;
+	char fam[RPCSPLITLEN], mem[RPCSPLITLEN], act[RPCSPLITLEN], mode[RPCSPLITLEN];
+
+	RpcResolver resolver;
+	if(split_rpccall(call, fam, mem, act, mode) >= 0)
+	{
+		res = resolver.resolve(fam, mem, act, mode, host, port);
+		if(res >= 0 && host != NULL)
+			return true;
+	}
+	return false;
+}
+
+RPCHandle::~RPCHandle()
+{
+	if(_sid >= 0)
+	{
+		//printf("\e[1;32m x\e[0m freeing RPC resource associated with host \"%s\" and port %d\n",_host.c_str(), _port);
+		free_lpc(_sid);
+		_sid = -1;
+	}
+	else{
+		//printf("\e[1;31m !\e[0m not freeing RPC resource associated with host \"%s\" and port %d\n",_host.c_str(), _port);
+	}
+}
+
+bool RPCHandle::lockRpc()
+{
+	rpcMutex.acquire();
+	return 1;
+}
+
+bool RPCHandle::unlockRpc()
+{
+	rpcMutex.release();
+	return 1;
+}
+
+/* this is private */
+bool RPCHandle::connect()
+{
+	if((_sid = import_lpc(_host.c_str(), _port)) >= 0)
+		return true;
+	else
+		return false;
+}
+
+bool RPCHandle::connected()
+{
+	if(_sid >= 0)
+		return true;
+	else
+		return false;
+}
+
+int RPCHandle::split_rpccall(const char *call, char* fam, char *mem, char* act, char* mode)
+{
+	int i = 0, delim1, delim2, delim3;
+	int underline_cnt = 0;
+	int calllen = strlen(call);
+
+	delim1 = delim2 = delim3 = -1;
+	memset(fam, 0, RPCSPLITLEN);
+	memset(mem, 0, RPCSPLITLEN);
+	memset(act, 0, RPCSPLITLEN);
+	memset(mode, 0, RPCSPLITLEN);
+
+	for(i = 0; i < strlen(call) && i < MAXLEN; i++)
+		if(call[i] == '_')
+			underline_cnt++;
+
+	if(underline_cnt != 3)
+	{
+		//printf("\e[1;31m*\e[0m Bad name  \"%s\"\n""  RPC calls must be in the form FAMILY_MEMBER_ACTION_MODE,\n""  separated by underline (\"_\")", call);
+		return -1;
+	}
+
+	for(i = 0; i < strlen(call) && i < MAXLEN; i++)
+	{
+		if(call[i] == '_')
+		{
+			if(delim1 < 0)
+				delim1 = i;
+			else if(delim2 < 0)
+				delim2 = i;
+			else if(delim3 < 0)
+				delim3 = i;
+		}
+	}
+	if(delim2 - delim1 >= RPCSPLITLEN || delim3 - delim2 >= RPCSPLITLEN || calllen - delim3 >= RPCSPLITLEN ||
+		delim1 >= RPCSPLITLEN)
+	{
+		//printf("\t\e[1;31m* \e[0mRPC call subparts too long in \"%s\"\n\t""  \e[1;4;35minfo\e[0m: maximum length: %d\n",call, RPCSPLITLEN);
+		return -1;
+	}
+
+	/* should be alright here: */
+	strncpy(fam, call, delim1);
+	strncpy(mem, call + delim1 + 1, delim2 - delim1 - 1);
+	strncpy(act, call + delim2 + 1, delim3 - delim2 - 1);
+	strncpy(mode, call + delim3 + 1, calllen - delim3 - 1);
+
+	return 0;
+}
+
+
+
+}
+
diff --git a/RpcHandle.h b/RpcHandle.h
new file mode 100644
index 0000000000000000000000000000000000000000..c7f68bb22ddfd4c2f6310373d25818ae2404cd95
--- /dev/null
+++ b/RpcHandle.h
@@ -0,0 +1,64 @@
+#ifndef RPC_HANDLE_H
+#define RPC_HANDLE_H
+
+#include <iostream>
+#include <omnithread.h>
+#include <tango.h>
+#include <vector>
+#include <lpc.h>
+
+#define RPCSPLITLEN     32
+#define MAXLEN 256
+
+using namespace std;
+
+namespace RPC2TangoBridge_ns
+{
+class RPCHandle/*: public Tango::LogAdapter*/
+{
+	public: 
+		RPCHandle(string call);
+		RPCHandle(RPCHandle *other);
+		~RPCHandle();
+
+		std::string host() { return _host; }
+		unsigned short port() { return _port; }
+		int sid() { return _sid; }
+
+		bool connected(); 
+
+		bool operator==(const  RPCHandle &other) const  
+			{ return _host == other._host && _port == other._port; }
+	
+		bool lockRpc();
+		bool unlockRpc();
+
+		std::string lastRpcError() { return _lastRpcErr; } 
+		
+		static int split_rpccall(const char *call, char* fam, char *mem, char* act, char* mode);
+		/* returns true if resolve takes place */
+		static bool resolve_rpc(const char *call, char** host, short int *port);
+		
+		unsigned _refcnt;
+		
+	protected:
+		std::string _lastRpcErr;
+		int _sid;
+		
+	private:
+		std::string _host;
+		unsigned short _port;
+
+		bool connect();
+
+
+};
+
+
+
+} /* namespace RPC2TangoBridge_ns ends */
+
+
+#endif
+
+
diff --git a/RpcReadHandle.cpp b/RpcReadHandle.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..3d2312bb74d35e07e7a4502f8b2dd979dc9ab9ae
--- /dev/null
+++ b/RpcReadHandle.cpp
@@ -0,0 +1,464 @@
+#include "RpcReadHandle.h"
+
+using namespace std;
+
+namespace RPC2TangoBridge_ns
+{
+
+RPCReadHandle::RPCReadHandle(RPCHandle* h) : RPCHandle(h)
+{
+	
+}
+
+long int RPCReadHandle::read_long(const char *callname, int* ok)
+{
+	long int ret;
+	char error[MAXERRLEN];
+	long res = -1;
+	char fam[RPCSPLITLEN], mem[RPCSPLITLEN], act[RPCSPLITLEN], mode[RPCSPLITLEN];
+	*ok = 1;
+	/* acquire lock! */
+	// lockRpc();
+	if(split_rpccall(callname, fam, mem, act, mode) < 0)
+	{
+		*ok = 0;
+		_lastRpcErr = string("Failed to split ")  + string(callname) + " into family, member, action, mode";
+	}
+	else
+	{
+		if(!strcmp(mode, "RI") || !strcmp(mode, "RII"))
+			bind_lpc(_sid);
+		if(!strcmp(mode, "RI"))
+			res = lpc_RI(fam, mem, act, mode, &ret);
+		else if(!strcmp(mode, "RII"))
+				res = lpc_RII(fam, mem, act, mode, &ret);
+		
+		if(res < 0)
+		{
+			snprintf(error, MAXERRLEN, "Error reading rpc \"%s\": errno: %d, errtype: %d, errstring: %s",
+				callname, errno, errtype, errstring);
+			 _lastRpcErr = string(error);
+			 *ok = 0;
+		}
+	}
+	/* release lock */
+	// unlockRpc();
+        return ret;
+
+}
+
+double RPCReadHandle::read_double(const char *callname, int* ok)
+{
+	double ret;
+	long res = -1;
+	char error[MAXERRLEN];
+	char fam[RPCSPLITLEN], mem[RPCSPLITLEN], act[RPCSPLITLEN], mode[RPCSPLITLEN];
+	*ok = 1;
+	/* acquire lock! */
+	// lockRpc();
+	if(split_rpccall(callname, fam, mem, act, mode) < 0)
+	{
+		*ok = 0;
+		_lastRpcErr = string("Failed to split ")  + string(callname) + " into family, member, action, mode";
+	}
+	else
+	{
+		if(!strcmp(mode, "RR") || !strcmp(mode, "RRI"))
+			bind_lpc(_sid);
+		if(!strcmp(mode, "RR"))
+			res = lpc_RR(fam, mem, act, mode, &ret);
+		else if(!strcmp(mode, "RRI"))
+				res = lpc_RRI(fam, mem, act, mode, &ret);
+		
+		if(res < 0)
+		{
+			snprintf(error, MAXERRLEN, "Error reading rpc \"%s\": errno: %d, errtype: %d, errstring: %s",
+				callname, errno, errtype, errstring);
+			 _lastRpcErr = string(error);
+			 *ok = 0;
+		}
+	}
+	/* release lock */
+	// unlockRpc();
+        return ret;
+
+}
+
+unsigned char RPCReadHandle::read_uchar(const char *callname, int* ok)
+{
+	unsigned char ret;
+	long res = -1;
+	char error[MAXERRLEN];
+	char fam[RPCSPLITLEN], mem[RPCSPLITLEN], act[RPCSPLITLEN], mode[RPCSPLITLEN];
+	*ok = 1;
+	/* acquire lock! */
+	// lockRpc();
+	if(split_rpccall(callname, fam, mem, act, mode) < 0)
+	{
+		*ok = 0;
+		_lastRpcErr = string("Failed to split ")  + string(callname) + " into family, member, action, mode";
+	}
+	else
+	{
+		if(!strcmp(mode, "RE") || !strcmp(mode, "REI"))
+			bind_lpc(_sid);
+		if(!strcmp(mode, "RE"))
+			res = lpc_RE(fam, mem, act, mode, &ret);
+		else if(!strcmp(mode, "REI"))
+			res = lpc_REI(fam, mem, act, mode, &ret);
+		
+		if(res < 0)
+		{
+			snprintf(error, MAXERRLEN, "Error reading rpc \"%s\": errno: %d, errtype: %d, errstring: %s",
+				callname, errno, errtype, errstring);
+			 _lastRpcErr = string(error);
+			 *ok = 0;
+		}
+	}
+	/* release lock */
+	// unlockRpc();
+        return ret;
+
+}
+
+short int RPCReadHandle::read_short(const char *callname, int* ok)
+{
+	short ret;
+	long res = -1;
+	char error[MAXERRLEN];
+	char fam[RPCSPLITLEN], mem[RPCSPLITLEN], act[RPCSPLITLEN], mode[RPCSPLITLEN];
+	*ok = 1;
+	/* acquire lock! */
+	// lockRpc();
+	if(split_rpccall(callname, fam, mem, act, mode) < 0)
+	{
+		*ok = 0;
+		_lastRpcErr = string("Failed to split ")  + string(callname) + " into family, member, action, mode";
+	}
+	else
+	{
+		if(!strcmp(mode, "RS") || !strcmp(mode, "RSI"))
+			bind_lpc(_sid);
+		if(!strcmp(mode, "RS"))
+			res = lpc_RS(fam, mem, act, mode, &ret);
+		else if(!strcmp(mode, "RSI"))
+			res = lpc_RSI(fam, mem, act, mode, &ret);
+		
+		if(res < 0)
+		{
+			snprintf(error, MAXERRLEN, "Error reading rpc \"%s\": errno: %d, errtype: %d, errstring: %s",
+				callname, errno, errtype, errstring);
+			 _lastRpcErr = string(error);
+			 *ok = 0;
+		}
+	}
+	/* release lock */
+	// unlockRpc();
+        return ret;
+
+}
+
+string RPCReadHandle::read_string(const char *callname, int* ok)
+{
+	string ret;
+	long res = -1;
+	char fam[RPCSPLITLEN], mem[RPCSPLITLEN], act[RPCSPLITLEN], mode[RPCSPLITLEN];
+	char error[MAXERRLEN];
+	*ok = 1;
+	/* acquire lock! */
+	// lockRpc();
+        char* strdata;
+        //idata.length = 0;
+        //idata.sequence = NULL;
+	if(split_rpccall(callname, fam, mem, act, mode) < 0)
+	{
+		*ok = 0;
+		_lastRpcErr = string("Failed to split ")  + string(callname) + " into family, member, action, mode";
+	}
+	else
+	{
+		if(!strcmp(mode, "RM") || !strcmp(mode, "RMI"))
+			bind_lpc(_sid);
+		if(!strcmp(mode, "RM"))
+			res = lpc_RM(fam, mem, act, mode, &strdata);
+		else if(!strcmp(mode, "RMI"))
+			res = lpc_RMI(fam, mem, act, mode, &strdata);
+		/* else: res remains initialized to -1 and will fail */
+		
+		if(res < 0)
+		{
+			snprintf(error, MAXERRLEN, "Error reading rpc \"%s\": errno: %d, errtype: %d, errstring: %s",
+				callname, errno, errtype, errstring);
+			 _lastRpcErr = string(error);
+			 *ok = 0;
+			 ret = "There was an error reading the value";
+		}
+	}
+	/* release lock */
+	// unlockRpc();
+	ret = string(strdata);
+        return ret;
+
+}
+
+unsigned char RPCReadHandle::read_boolean(const char *callname, int* ok)
+{
+	unsigned char ret;
+	long res = -1;
+	char error[MAXERRLEN];
+	char fam[RPCSPLITLEN], mem[RPCSPLITLEN], act[RPCSPLITLEN], mode[RPCSPLITLEN];
+	*ok = 1;
+	/* acquire lock! */
+	// lockRpc();
+	if(split_rpccall(callname, fam, mem, act, mode) < 0)
+	{
+		*ok = 0;
+		_lastRpcErr = string("Failed to split ")  + string(callname) + " into family, member, action, mode";
+	}
+	else
+	{
+		if(!strcmp(mode, "RB") || !strcmp(mode, "RBI"))
+			bind_lpc(_sid);
+		if(!strcmp(mode, "RB"))
+			res = lpc_RB(fam, mem, act, mode, &ret);
+		else if(!strcmp(mode, "RBI"))
+			res = lpc_RBI(fam, mem, act, mode, &ret);
+		if(res < 0)
+		{
+			snprintf(error, MAXERRLEN, "Error reading rpc \"%s\": errno: %d, errtype: %d, errstring: %s",
+				callname, errno, errtype, errstring);
+			 _lastRpcErr = string(error);
+			 *ok = 0;
+		}
+	}
+	/* release lock */
+	// unlockRpc();
+        return ret;
+
+}
+
+intArray RPCReadHandle::read_slong(const char *callname, int* ok)
+{
+	char fam[RPCSPLITLEN], mem[RPCSPLITLEN], act[RPCSPLITLEN], mode[RPCSPLITLEN];
+	char error[MAXERRLEN];
+	*ok = 1;
+	/* acquire lock! */
+	// lockRpc();
+	long res = -1;
+        intArray idata;
+        idata.length = 0;
+        idata.sequence = NULL;
+	if(split_rpccall(callname, fam, mem, act, mode) < 0)
+	{
+		*ok = 0;
+		_lastRpcErr = string("Failed to split ")  + string(callname) + " into family, member, action, mode";
+	}
+	else
+	{
+		if(!strcmp(mode, "RAI") || !strcmp(mode, "RAII"))
+			bind_lpc(_sid);
+		if(!strcmp(mode, "RAI"))
+			res = lpc_RAI(fam, mem, act, mode, &idata);
+		else if(!strcmp(mode, "RAII"))
+			res = lpc_RAII(fam, mem, act, mode, &idata);
+		/* else: res remains initialized to -1 and will fail */
+		
+		if(res < 0)
+		{
+			snprintf(error, MAXERRLEN, "Error reading rpc \"%s\": errno: %d, errtype: %d, errstring: %s",
+				callname, errno, errtype, errstring);
+			 _lastRpcErr = string(error);
+			 *ok = 0;
+		}
+	}
+	/* release lock */
+	// unlockRpc();
+        return idata;
+}
+
+realArray RPCReadHandle::read_sdouble(const char *callname, int* ok)
+{
+	char fam[RPCSPLITLEN], mem[RPCSPLITLEN], act[RPCSPLITLEN], mode[RPCSPLITLEN];
+	char error[MAXERRLEN];
+	*ok = 1;
+	/* acquire lock! */
+	// lockRpc();
+	long res = -1;
+        realArray rdata;
+        rdata.length = 0;
+        rdata.sequence = NULL;
+	if(split_rpccall(callname, fam, mem, act, mode) < 0)
+	{
+		*ok = 0;
+		_lastRpcErr = string("Failed to split ")  + string(callname) + " into family, member, action, mode";
+	}
+	else
+	{
+		if(!strcmp(mode, "RAR") || !strcmp(mode, "RAIR"))
+			bind_lpc(_sid);
+		if(!strcmp(mode, "RAR"))
+			res = lpc_RAR(fam, mem, act, mode, &rdata);
+		else if(!strcmp(mode, "RAIR"))
+			res = lpc_RAIR(fam, mem, act, mode, &rdata);
+		/* else: res remains initialized to -1 and will fail */
+		
+		if(res < 0)
+		{
+			snprintf(error, MAXERRLEN, "Error reading rpc \"%s\": errno: %d, errtype: %d, errstring: %s",
+				callname, errno, errtype, errstring);
+			 _lastRpcErr = string(error);
+			 *ok = 0;
+		}
+	}
+	/* release lock */
+	// unlockRpc();
+        return rdata;
+
+}
+
+shortArray RPCReadHandle::read_sshort(const char *callname, int* ok)
+{
+	char fam[RPCSPLITLEN], mem[RPCSPLITLEN], act[RPCSPLITLEN], mode[RPCSPLITLEN];
+	char error[MAXERRLEN];
+	*ok = 1;
+	/* acquire lock! */
+	// lockRpc();
+	long res = -1;
+        shortArray rdata;
+        rdata.length = 0;
+        rdata.sequence = NULL;
+	if(split_rpccall(callname, fam, mem, act, mode) < 0)
+	{
+		*ok = 0;
+		_lastRpcErr = string("Failed to split ")  + string(callname) + " into family, member, action, mode";
+	}
+	else
+	{
+		if(!strcmp(mode, "RAS") || !strcmp(mode, "RAIS"))
+			bind_lpc(_sid);
+		if(!strcmp(mode, "RAS"))
+			res = lpc_RAS(fam, mem, act, mode, &rdata);
+		else if(!strcmp(mode, "RAIS"))
+			res = lpc_RAIS(fam, mem, act, mode, &rdata);
+		/* else res remains initialized to -1 and will fail */
+		if(res < 0)
+		{
+			snprintf(error, MAXERRLEN, "Error reading rpc \"%s\": errno: %d, errtype: %d, errstring: %s",
+				callname, errno, errtype, errstring);
+			 _lastRpcErr = string(error);
+			 *ok = 0;
+		}
+	}
+	/* release lock */
+	// unlockRpc();
+        return rdata;
+
+}
+
+charArray RPCReadHandle::read_schar(const char *callname, int* ok)
+{
+	char fam[RPCSPLITLEN], mem[RPCSPLITLEN], act[RPCSPLITLEN], mode[RPCSPLITLEN];
+	char error[MAXERRLEN];
+	*ok = 1;
+	/* acquire lock! */
+	// lockRpc();
+	long res = -1;
+        charArray rdata;
+        rdata.length = 0;
+        rdata.sequence = NULL;
+	if(split_rpccall(callname, fam, mem, act, mode) < 0)
+	{
+		*ok = 0;
+		_lastRpcErr = string("Failed to split ")  + string(callname) + " into family, member, action, mode";
+	}
+	else
+	{
+		if(!strcmp(mode, "RAC") || !strcmp(mode, "RAIC"))
+			bind_lpc(_sid);
+		if(!strcmp(mode, "RAC"))
+			res = lpc_RAC(fam, mem, act, mode, &rdata);
+		else if(!strcmp(mode, "RAIC"))
+			res = lpc_RAIC(fam, mem, act, mode, &rdata);
+		/* else: res remains initialized to -1 and this will fail */	
+		if(res < 0)
+		{
+			snprintf(error, MAXERRLEN, "Error reading rpc \"%s\": errno: %d, errtype: %d, errstring: %s",
+				callname, errno, errtype, errstring);
+			 _lastRpcErr = string(error);
+			 *ok = 0;
+		}
+	}
+	/* release lock */
+	// unlockRpc();
+        return rdata;
+
+}
+
+booleanArray RPCReadHandle::read_sboolean(const char *callname, int* ok)
+{
+	char fam[RPCSPLITLEN], mem[RPCSPLITLEN], act[RPCSPLITLEN], mode[RPCSPLITLEN];
+	char error[MAXERRLEN];
+	*ok = 1;
+	/* acquire lock! */
+	// lockRpc();
+	long res = -1;
+        booleanArray rdata;
+        rdata.length = 0;
+        rdata.sequence = NULL;
+	long rfLong;
+	
+	if(split_rpccall(callname, fam, mem, act, mode) < 0)
+	{
+		*ok = 0;
+		_lastRpcErr = string("Failed to split ")  + string(callname) + " into family, member, action, mode";
+	}
+	else
+	{
+		if(!strcmp(mode, "RF") || !strcmp(mode, "RFI"))
+		{
+			bind_lpc(_sid);
+			//printf("_sid: %d\n", _sid);
+			/* long int interpreted as array of 32 booleans */
+			if(!strcmp(mode, "RF"))
+				res = lpc_RF(fam, mem, act, mode, &rfLong);
+			else if(!strcmp(mode, "RFI"))
+				res = lpc_RFI(fam, mem, act, mode, &rfLong);
+			if(res >= 0) /* convert a long of 32 bit into a booleanArray */
+			{
+				rdata.length = 32;
+				rdata.sequence = (idl_boolean *)malloc(sizeof(idl_boolean) * 32);
+				for(int i = 0; i < 32; i++)
+					rdata.sequence[i] = (rfLong >> i) & 1;
+			}
+			else
+				_lastRpcErr = string("failed lpc_RF or lpc_RFI");
+		}
+		else if(!strcmp(mode, "RAB"))
+		{
+			bind_lpc(_sid);
+			res = lpc_RAB(fam, mem, act, mode, &rdata);
+		}
+		else if(!strcmp(mode, "RAIB"))
+		{
+			bind_lpc(_sid);
+			res = lpc_RAIB(fam, mem, act, mode, &rdata);
+		}
+		
+		if(res < 0)
+		{
+			snprintf(error, MAXERRLEN, "Error reading rpc \"%s\": errno: %d, errtype: %d, errstring: %s",
+				callname, errno, errtype, errstring);
+			 _lastRpcErr = string(error);
+			 *ok = 0;
+		}
+	}
+	/* release lock */
+	// unlockRpc();
+        return rdata;
+}
+
+
+
+} /* namespace */
+
+
diff --git a/RpcReadHandle.h b/RpcReadHandle.h
new file mode 100644
index 0000000000000000000000000000000000000000..923db3247c7af4a37ddf2ffdcd80cb49dbb19861
--- /dev/null
+++ b/RpcReadHandle.h
@@ -0,0 +1,37 @@
+#ifndef RPC_READ_HANDLE_H
+#define RPC_READ_HANDLE_H
+
+#include <string>
+#include <omnithread.h>
+#include <RpcResolver.h>
+#include "RpcHandle.h"
+#include <errtype.h>
+
+#define MAXERRLEN	512
+
+namespace RPC2TangoBridge_ns
+{
+	
+class RPCReadHandle : public RPCHandle
+{
+	public:
+		RPCReadHandle(RPCHandle *h);
+		
+		long int read_long(const char *callname, int* ok);
+		double read_double(const char *callname, int* ok);
+		short int read_short(const char *callname, int* ok);
+		unsigned char read_uchar(const char *callname, int* ok);
+		unsigned char read_boolean(const char *callname, int* ok);
+		string read_string(const char *callname, int* ok);
+
+		intArray read_slong(const char *callname, int* ok);
+		charArray read_schar(const char *callname, int* ok);
+		realArray read_sdouble(const char *callname, int* ok);
+		shortArray read_sshort(const char *callname, int* ok);
+		booleanArray read_sboolean(const char *callname, int* ok);
+	
+};
+
+}
+
+#endif
diff --git a/RpcWriteHandle.cpp b/RpcWriteHandle.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..f31c8414cc38fc65e72be4395d7e5bd9c9c0b178
--- /dev/null
+++ b/RpcWriteHandle.cpp
@@ -0,0 +1,274 @@
+#include <RpcWriteHandle.h>
+#include <RpcResolver.h>
+#include <errtype.h>
+
+#define MAXERRLEN	512
+
+using namespace std;
+
+namespace RPC2TangoBridge_ns
+{
+
+static omni_mutex rpcMutex;
+
+RPCWriteHandle::RPCWriteHandle(RPCHandle *h) : RPCHandle(h)
+{
+	
+}
+
+RPCWriteHandle::~RPCWriteHandle()
+{
+	
+}
+
+bool RPCWriteHandle::write_long(const char *callname, long lvalue)
+{
+	bool ret;
+	char error[MAXERRLEN];
+	long res = -1;
+	char fam[RPCSPLITLEN], mem[RPCSPLITLEN], act[RPCSPLITLEN], mode[RPCSPLITLEN];
+
+	if(split_rpccall(callname, fam, mem, act, mode) < 0)
+	{
+		_lastRpcErr = string("Failed to split ")  + string(callname) + " into family, member, action, mode";
+		return false;
+	}
+//	printf("\e[1;32mWRITE\e[0m scrivo %ld su %s %s %s %s\n",lvalue,  fam, mem, act, mode);
+	
+	/* acquire lock! */
+	lockRpc();
+	if(split_rpccall(callname, fam, mem, act, mode) < 0)
+	{
+		_lastRpcErr = string("Failed to split ")  + string(callname) + " into family, member, action, mode";
+	}
+	else
+	{
+		if(!strcmp(mode, "WI") || !strcmp(mode, "WII"))
+			bind_lpc(_sid);
+		if(!strcmp(mode, "WI"))
+			res = lpc_WI(fam, mem, act, mode, &lvalue);
+		else if(!strcmp(mode, "WII"))
+				res = lpc_WII(fam, mem, act, mode, &lvalue);
+		if(res < 0)
+		{
+			snprintf(error, MAXERRLEN, "Error writeing rpc \"%s\": errno: %d, errtype: %d, errstring: %s",
+				callname, errno, errtype, errstring);
+			 _lastRpcErr = string(error);
+		}
+	}
+	/* release lock */
+	unlockRpc();
+        return ret;
+
+}
+
+bool RPCWriteHandle::write_double(const char *callname,  double dvalue)
+{
+	bool ret;
+	long res = -1;
+	char error[MAXERRLEN];
+	char fam[RPCSPLITLEN], mem[RPCSPLITLEN], act[RPCSPLITLEN], mode[RPCSPLITLEN];
+
+	if(split_rpccall(callname, fam, mem, act, mode) < 0)
+	{
+		_lastRpcErr = string("Failed to split ")  + string(callname) + " into family, member, action, mode";
+		return false;
+	}
+//	printf("\e[1;32mWRITE\e[0m scrivo double %lf su %s %s %s %s\n",dvalue,  fam, mem, act, mode);
+
+	/* acquire lock! */
+	lockRpc();
+	if(split_rpccall(callname, fam, mem, act, mode) < 0)
+	{
+		ret = false;
+		_lastRpcErr = string("Failed to split ")  + string(callname) + " into family, member, action, mode";
+	}
+	else
+	{
+		if(!strcmp(mode, "WR") || !strcmp(mode, "WRI"))
+			bind_lpc(_sid);
+		if(!strcmp(mode, "WR"))
+			res = lpc_WR(fam, mem, act, mode, &dvalue);
+		else if(!strcmp(mode, "WRI"))
+				res = lpc_WRI(fam, mem, act, mode, &dvalue);
+		
+		if(res < 0)
+		{
+			snprintf(error, MAXERRLEN, "Error writing rpc \"%s\": errno: %d, errtype: %d, errstring: %s",
+				callname, errno, errtype, errstring);
+			 _lastRpcErr = string(error);
+			 ret = false;
+		}
+		else 
+			ret = true;
+	}
+	/* release lock */
+	unlockRpc();
+        return ret;
+}
+
+bool RPCWriteHandle::write_short(const char *callname, short svalue)
+{
+	bool ret;
+	long res = -1;
+	char error[MAXERRLEN];
+	char fam[RPCSPLITLEN], mem[RPCSPLITLEN], act[RPCSPLITLEN], mode[RPCSPLITLEN];
+	
+	/* acquire lock! */
+	lockRpc();
+	if(split_rpccall(callname, fam, mem, act, mode) < 0)
+	{
+		ret = false;
+		_lastRpcErr = string("Failed to split ")  + string(callname) + " into family, member, action, mode";
+	}
+	else
+	{
+	//	printf("\e[1;32mWRITE\e[0m scrivo SHORT %d su %s %s %s %s\n", svalue,  fam, mem, act, mode);
+		if(!strcmp(mode, "WS") || !strcmp(mode, "WSI"))
+			bind_lpc(_sid);
+		if(!strcmp(mode, "WS"))
+			res = lpc_WS(fam, mem, act, mode, &svalue);
+		else if(!strcmp(mode, "WSI"))
+				res = lpc_WSI(fam, mem, act, mode, &svalue);
+		
+		if(res < 0)
+		{
+			snprintf(error, MAXERRLEN, "Error writing rpc \"%s\": errno: %d, errtype: %d, errstring: %s",
+				callname, errno, errtype, errstring);
+			 _lastRpcErr = string(error);
+			 ret = false;
+		}
+		else 
+			ret = true;
+	}
+	/* release lock */
+	unlockRpc();
+        return ret;
+}
+
+bool RPCWriteHandle::write_string(const char *callname, char **s)
+{
+	bool ret;
+// 	long res = -1;
+// 	char error[MAXERRLEN];
+// 	char fam[RPCSPLITLEN], mem[RPCSPLITLEN], act[RPCSPLITLEN], mode[RPCSPLITLEN];
+// 
+// 	/* acquire lock! */
+// 	lockRpc();
+// 	if(split_rpccall(callname, fam, mem, act, mode) < 0)
+// 	{
+// 		ret = false;
+// 		_lastRpcErr = string("Failed to split ")  + string(callname) + " into family, member, action, mode";
+// 	}
+// 	else
+// 	{
+// 		if(!strcmp(mode, "WR") || !strcmp(mode, "WRI"))
+// 			bind_lpc(_sid);
+// 		if(!strcmp(mode, "WR"))
+// 			res = lpc_WR(fam, mem, act, mode, &dvalue);
+// 		else if(!strcmp(mode, "WRI"))
+// 				res = lpc_WRI(fam, mem, act, mode, &dvalue);
+// 		
+// 		if(res < 0)
+// 		{
+// 			snprintf(error, MAXERRLEN, "Error writing rpc \"%s\": errno: %d, errtype: %d, errstring: %s",
+// 				callname, errno, errtype, errstring);
+// 			 _lastRpcErr = string(error);
+// 			 ret = false;
+// 		}
+// 		else 
+// 			ret = true;
+// 	}
+// 	/* release lock */
+// 	unlockRpc();
+	//printf("\e[1;35m;4minfo\e[0m write_string not implemented yet\n");
+	ret  = -1;
+        return false;
+
+}
+
+bool RPCWriteHandle::write_boolean(const char *callname, bool bvalue)
+{
+	bool ret;
+	long res = -1;
+	char error[MAXERRLEN];
+	char fam[RPCSPLITLEN], mem[RPCSPLITLEN], act[RPCSPLITLEN], mode[RPCSPLITLEN];
+	unsigned char boolval;
+	if(bvalue)
+		boolval = 1;
+	else
+		boolval = 0;
+
+	/* acquire lock! */
+	lockRpc();
+	if(split_rpccall(callname, fam, mem, act, mode) < 0)
+	{
+		ret = false;
+		_lastRpcErr = string("Failed to split ")  + string(callname) + " into family, member, action, mode";
+	}
+	else
+	{
+		if(!strcmp(mode, "WB") || !strcmp(mode, "WBI"))
+			bind_lpc(_sid);
+		if(!strcmp(mode, "WB"))
+			res = lpc_WB(fam, mem, act, mode, &boolval);
+		else if(!strcmp(mode, "WBI"))
+				res = lpc_WBI(fam, mem, act, mode, &boolval);
+		
+		if(res < 0)
+		{
+			snprintf(error, MAXERRLEN, "Error writing rpc \"%s\": errno: %d, errtype: %d, errstring: %s",
+				callname, errno, errtype, errstring);
+			 _lastRpcErr = string(error);
+			 ret = false;
+		}
+		else 
+			ret = true;
+	}
+	/* release lock */
+	unlockRpc();
+        return ret;
+}
+
+
+bool RPCWriteHandle::write_void(const char *callname)
+{
+	bool ret;
+	long res = -1;
+	char error[MAXERRLEN];
+	char fam[RPCSPLITLEN], mem[RPCSPLITLEN], act[RPCSPLITLEN], mode[RPCSPLITLEN];
+	unsigned char dummy;
+
+	/* acquire lock! */
+	lockRpc();
+	if(split_rpccall(callname, fam, mem, act, mode) < 0)
+	{
+		ret = false;
+		_lastRpcErr = string("Failed to split ")  + string(callname) + " into family, member, action, mode";
+	}
+	else
+	{
+		if(!strcmp(mode, "WP") || !strcmp(mode, "WPI"))
+			bind_lpc(_sid);
+		if(!strcmp(mode, "WP"))
+			res = lpc_WP(fam, mem, act, mode, &dummy);
+		else if(!strcmp(mode, "WBI"))
+				res = lpc_WPI(fam, mem, act, mode, &dummy);
+		
+		if(res < 0)
+		{
+			snprintf(error, MAXERRLEN, "Error writing rpc \"%s\": errno: %d, errtype: %d, errstring: %s",
+				callname, errno, errtype, errstring);
+			 _lastRpcErr = string(error);
+			 ret = false;
+		}
+		else 
+			ret = true;
+	}
+	/* release lock */
+	unlockRpc();
+        return ret;
+}
+
+}
+
diff --git a/RpcWriteHandle.h b/RpcWriteHandle.h
new file mode 100644
index 0000000000000000000000000000000000000000..71797153375a0def42369f0ed631bb23d480cc4c
--- /dev/null
+++ b/RpcWriteHandle.h
@@ -0,0 +1,43 @@
+#ifndef RPC_WHANDLE_H
+#define RPC_WHANDLE_H
+
+#include <iostream>
+#include <omnithread.h>
+#include <vector>
+#include <lpc.h>
+#include "RpcHandle.h"
+
+#define RPCSPLITLEN     32
+
+using namespace std;
+
+namespace RPC2TangoBridge_ns
+{
+
+
+class RPCWriteHandle : public RPCHandle
+{
+	public: 
+		RPCWriteHandle(RPCHandle *h);
+		~RPCWriteHandle();
+
+		bool write_long(const char *callname, long lvalue);
+		bool  write_double(const char *callname, double dvalue);
+		bool  write_short(const char *callname, short svalue);
+		bool  write_boolean(const char *callname, bool bval);
+		bool  write_string(const char *callname, char **string);
+                bool  write_void(const char *callname);
+
+	
+	private:
+
+};
+
+
+
+} /* namespace RPC2TangoBridge_ns ends */
+
+
+#endif
+
+
diff --git a/attribute_converter.cpp b/attribute_converter.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..0b2974bd04994285cc71880badc1d62af8b8db69
--- /dev/null
+++ b/attribute_converter.cpp
@@ -0,0 +1,290 @@
+#include <attribute_converter.h>
+#include <RpcHandle.h>
+#include <tango.h>
+
+#define MAX_X  512
+
+/* RPCSPLITLEN and MAXLEN defined in RpcHandle.h */
+
+using namespace std;
+using namespace Tango;
+
+namespace RPC2TangoBridge_ns
+{
+
+
+AttributeConverter::AttributeConverter(char *propertyName, bool force_spectrum)
+{
+	sc_attr = NULL;
+	sp_attr = NULL;
+	spectrum = false;
+	bool readWrite;
+	int data_type;
+	char res[256];
+	
+	/* RPCSPLITLEN and MAXLEN defined in RpcHandle.h */
+	char writeCall[MAXLEN];
+	char readCall[MAXLEN];
+	char fam[RPCSPLITLEN], mem[RPCSPLITLEN], act[RPCSPLITLEN], mode[RPCSPLITLEN];
+	UserDefaultAttrProp default_att_prop;
+	
+	Database *db = new Database();
+	DbData data;
+	
+	memset(fam, 0, RPCSPLITLEN);
+	memset(mem, 0, RPCSPLITLEN);
+	memset(act, 0, RPCSPLITLEN);
+	memset(mode, 0, RPCSPLITLEN);
+	
+	/* isReadWrite() always copies _read_ RPC call in readCall.
+	* If read write, copies in writeCall the write RPC call and returns true, otherwise it 
+	* returns false and strlen(writeCall) is 0.
+	*/
+	readWrite = isReadWrite(propertyName, readCall, writeCall);
+	printf ("AttributeConverter %s readWrite: %d\n",propertyName,readWrite);
+	/* used to determine data_type below. We refer to read name, we are not
+	 * interested in write_name. The configuration of the device properties must
+	 * be consistent, but we do not check it.
+	 */
+	if(RPCHandle::split_rpccall(readCall, fam, mem, act, mode) < 0)
+	{
+		//printf("\e[1;31m*\e[0m Error in RPC split: \"%s\"\n", propertyName);
+		exit(EXIT_FAILURE);
+	}
+	
+	data_type = data_type_for_mode(mode);
+        printf("creating in converter attribute for \"%s\": data type: \"%s\"\n", propertyName, dataType(data_type).c_str());
+	if(data_type >= 0 && (is_spectrum(mode) ||  force_spectrum))
+	{	
+		spectrum = true;
+		sp_attr = createSpectrumAttribute(propertyName, data_type);
+	}
+	else if(data_type >= 0)
+	{
+		spectrum = false;
+		if(!readWrite)
+			sc_attr = createScalarAttribute(readCall, data_type);
+		else
+			sc_attr = createScalarAttribute(readCall, writeCall, data_type);
+	}
+	else if(data_type < 0)
+	{
+		snprintf(res, 256, "\e[1;31m* \e[0merror creating \"%s\""
+			"\e[0;37m [\e[1;31munrecognized data type \e[0;37m]\e[0m", propertyName);
+		result = string(res);
+	}
+}
+
+bool AttributeConverter::isSpectrum()
+{
+	return spectrum;
+}
+
+bool AttributeConverter::string1_contains2(const char* s1, const char* s2)
+{
+	int len1 = strlen(s1);
+	int len2 = strlen(s2);
+	int i;
+
+	for(i = 0; i <= len1 - len2; i++)
+	{
+		if(strncmp(s1 + i, s2, len2) == 0)
+			return true;
+	}
+	return false;
+}
+
+/* detects if the entry read from the tango attribute properties contains a ':' separator
+* and, if so, extracts and saves in rwname the Write part (the RPC WRITE call.
+* rwname must be a pointer to a MAXLEN char vector.
+* Always copies read RPC call in rname.
+* If read write, copies in rwname the write RPC call and returns true, otherwise it 
+* returns false and strlen(rwname) is 0
+*/
+bool AttributeConverter::isReadWrite(char* entry, char * rname, char *rwname)
+{
+	int i;
+	memset(rname, 0, MAXLEN);
+	memset(rwname, 0, MAXLEN);
+	for(i = 0; i< MAXLEN - 1 && i < strlen(entry); i++)
+		if(entry[i] == ':')
+			break;
+	if(i == strlen(entry))
+	{
+		strncpy(rname, entry, MAXLEN - 1);
+		return false;
+	}
+	else
+	{
+		strncpy(rname, entry , i );
+// 		printf("AttributeConverter::isReadWrite read part: %s\n", rname);
+		memset(rwname, 0, MAXLEN);
+		strncpy(rwname, entry + i + 1, MAXLEN - 1);
+// 		printf("AttributeConverter::isReadWrite write part: %s\n", rwname);
+		return true;
+	}
+}
+
+bool AttributeConverter::is_spectrum(const char *mode)
+{
+	/* Read Array (RA) or Read Flags (RF) means a spectrum */
+	if(string1_contains2(mode, "RA") || string1_contains2(mode, "RF"))
+		return true;
+	else
+		return false;
+}
+
+long int AttributeConverter::data_type_for_mode(const char *mode)
+{
+	if(!strcasecmp(mode, "RB") || !strcasecmp(mode, "RBI") ||
+		!strcasecmp(mode, "RAB") || !strcasecmp(mode, "RAIB"))
+		return Tango::DEV_BOOLEAN;
+	
+	/* flags type, is dev Boolean */
+	else if(!strcasecmp(mode, "RF") || !strcasecmp(mode, "RFI"))
+		return Tango::DEV_BOOLEAN;
+	
+	else if(!strcasecmp(mode, "RI") || !strcasecmp(mode, "RII") ||
+		!strcasecmp(mode, "RAI") || !strcasecmp(mode, "RAII"))
+		return Tango::DEV_LONG;
+	
+	else if(!strcasecmp(mode, "RR") || !strcasecmp(mode, "RRI") ||
+		!strcasecmp(mode, "RAR") || !strcasecmp(mode, "RAIR"))
+		return Tango::DEV_DOUBLE;
+	
+	else if(!strcasecmp(mode, "RE") || !strcasecmp(mode, "REI"))
+		return Tango::DEV_DOUBLE;
+	else if(!strcasecmp(mode, "RM") || !strcasecmp(mode, "RMI"))
+		return Tango::DEV_STRING;
+	else if(!strcasecmp(mode, "RS") || !strcasecmp(mode, "RSI") ||
+		!strcasecmp(mode, "RAS") || !strcasecmp(mode, "RAIS"))
+		return Tango::DEV_SHORT;
+        else if(!strcasecmp(mode, "WP") || !strcasecmp(mode, "WPI"))
+		return Tango::DEV_VOID;
+	else
+		return -1;
+ }
+
+SpectrumBridgeAttr* AttributeConverter::createSpectrumAttribute(const char* name, 
+	long int data_type)
+{
+		
+	UserDefaultAttrProp default_att_prop;
+	SpectrumBridgeAttr *spattr;
+	char desc[256];
+	char res[256];
+	char fam[RPCSPLITLEN], mem[RPCSPLITLEN], act[RPCSPLITLEN], mode[RPCSPLITLEN];
+	int max_x = MAX_X;
+
+	snprintf(desc, 255, "This attribute maps the RPC call \"%s\" in a tango "
+		"READ ONLY spectrum attribute with the same name", name);
+	
+	if(RPCHandle::split_rpccall(name, fam, mem, act, mode) < 0)
+	{
+	        //printf("\e[1;31m*\e[0m Error in RPC data_type: \"%s\"\n", name);
+	        exit(EXIT_FAILURE);
+	}
+	/* particular case in which we know that the RF is long 32 */
+	if(strcmp(mode, "RF") == 0)
+		max_x = 32;
+	
+	spattr = new SpectrumBridgeAttr(name, data_type, Tango::READ, max_x);
+
+	if(spattr != NULL)
+	{
+		snprintf(res, 256, "\e[1;32m* \e[0mcreated \"%s\"\t\e[0;37m[\e[0;32mspectrum"
+		"\e[0;37m, \e[0;32m%s\e[0;37m, \e[0;32mRO\e[0;37m]\e[0m",
+  		name, dataType(data_type).c_str());
+		result = string(res);
+	
+		default_att_prop.set_description(desc);
+		spattr->set_default_properties(default_att_prop);
+	}
+	return spattr;
+}
+
+BridgeAttr* AttributeConverter::createScalarAttribute(const char* name, long int data_type)          
+{
+
+        printf("createScalarAttribute %s\n",name);
+        char desc[256];
+	char res[256];
+	UserDefaultAttrProp default_att_prop;
+	BridgeAttr* attr;
+	snprintf(desc, 255, "This attribute maps the RPC call \"%s\" in a tango "
+		"READ ONLY scalar attribute with the same name", name);
+	attr = new BridgeAttr(name, data_type, Tango::READ);
+	
+	if(attr != NULL)
+	{
+		snprintf(res, 256, "\e[1;32m* \e[0mcreated \"%s\"\t\e[0;37m[\e[0;32mscalar"
+		"\e[0;37m, \e[0;32m%s\e[0;37m, \e[0;32mRO\e[0;37m]\e[0m",
+  		name, dataType(data_type).c_str());
+		result = string(res);
+		default_att_prop.set_description(desc);
+		attr->set_default_properties(default_att_prop);
+	}
+	return attr;	
+}
+
+BridgeAttr* AttributeConverter::createScalarAttribute(const char* name, const char* writeName, long int data_type)
+{
+        printf("createScalarAttribute_write %s\n",name);
+        char desc[256];
+	char res[256];
+	UserDefaultAttrProp default_att_prop;
+	BridgeAttr* attr;
+	snprintf(desc, 255, "This attribute maps the RPC call \"%s\" in a tango "
+		"READ WRITE scalar attribute. RPC read call: \"%s\" write call: \"%s\"", name, name, writeName);
+        printf("createScalarAttribute_write %s %s...\n",name,writeName);
+	attr = new BridgeAttr(name, writeName, data_type, Tango::READ_WRITE);
+	printf(".....createScalarAttribute_write %s %s\n",name,writeName);
+	if(attr != NULL)
+	{
+		snprintf(res, 256, "\e[1;32m* \e[0mcreated \"%s\"\t\e[0;37m[\e[0;32mscalar"
+		"\e[0;37m, \e[0;32m%s\e[0;37m, \e[0;32mRW\e[0;37m]\e[0m",
+  		name, dataType(data_type).c_str());
+		default_att_prop.set_description(desc);
+		attr->set_default_properties(default_att_prop);
+	}
+	return attr;	
+}
+
+string AttributeConverter::dataType(long int dt)
+{
+	string s = "";
+	switch(dt)
+	{
+		case Tango::DEV_DOUBLE:
+			s += "double";
+			break;
+		case Tango::DEV_SHORT:
+			s += "short";
+			break;
+		case Tango::DEV_LONG:
+			s += "(long) int";
+			break;
+		case Tango::DEV_STRING:
+			s += "string";
+			break;
+		case Tango::DEV_BOOLEAN:
+			s += "boolean";
+			break;
+		case Tango::DEV_UCHAR:
+			s += "unsigned char";
+			break;
+		case Tango::DEV_USHORT:
+			s += "unsigned short";
+			break;
+                case Tango::DEV_VOID:
+			s += "void";
+			break;
+		default:
+			s += "unrecognized";
+			break;
+	}
+	return s;
+}
+
+} /* end namespace */
+
diff --git a/attribute_converter.h b/attribute_converter.h
new file mode 100644
index 0000000000000000000000000000000000000000..80369a4ae1b33f3b2db2df41b63b5fd076526358
--- /dev/null
+++ b/attribute_converter.h
@@ -0,0 +1,53 @@
+#ifndef _ATTRIBUTE_CONVERTER_H
+
+#define ATTRIBUTE_CONVERTER_H
+
+#include <BridgeAttr.h>
+
+namespace RPC2TangoBridge_ns
+{
+
+class AttributeConverter
+{
+	public:
+		AttributeConverter(char *rpc_call, bool force_spectrum = false);
+		
+		bool isSpectrum();
+		
+		BridgeAttr* scalarAttribute() { return sc_attr; }
+		SpectrumBridgeAttr *spectrumAttribute() { return sp_attr; }
+		string info() { return result; }
+		
+	private:
+		BridgeAttr *sc_attr;
+		SpectrumBridgeAttr* sp_attr;
+		
+		bool string1_contains2(const char* s1, const char* s2);
+		bool is_spectrum(const char *call);
+		long int data_type_for_mode(const char *mode);
+
+		BridgeAttr* createScalarAttribute(const char* name, long int data_type);
+		BridgeAttr* createScalarAttribute(const char* name, const char* writeName, long int data_type);
+		SpectrumBridgeAttr* createSpectrumAttribute(const char* name, 
+			long int data_type);
+		
+		/* detects if the entry read from the tango attribute properties contains a ':' separator
+	 	* and, if so, extracts and saves in rwname the Write part (the RPC WRITE call.
+	 	* rwname must be a pointer to a MAXLEN char vector.
+		* Always copies read RPC call in rname.
+		* If read write, copies in rwname the write RPC call and returns true, otherwise it 
+		* returns false and strlen(rwname) is 0
+		*/
+		bool isReadWrite(char* entry, char *rname, char *rwname);
+		string dataType(long int dt);
+		
+		bool spectrum;
+		string result;
+};
+
+} /* namespace */
+
+
+#endif
+
+
diff --git a/etc/fixsipformat.py b/etc/fixsipformat.py
new file mode 100644
index 0000000000000000000000000000000000000000..c17fd06793fd0be9914f1eeb492caa17fd4d2507
--- /dev/null
+++ b/etc/fixsipformat.py
@@ -0,0 +1,28 @@
+#fix format fro SIP devices
+from PyTango import *
+
+
+sip120 = DeviceProxy('rpcbridge/rpc2tangobridge/sip120')
+sip400 = DeviceProxy('rpcbridge/rpc2tangobridge/sip400')
+
+
+
+sip120attrlist = sip120.get_attribute_list()
+
+for att in sip120attrlist:
+    atconf=sip120.get_attribute_config(att)
+    atconf.format='%6.2e'
+    try:
+        sip120.set_attribute_config(atconf)
+    except:
+        pass
+    
+sip400attrlist = sip400.get_attribute_list()
+
+for att in sip400attrlist:
+    atconf=sip400.get_attribute_config(att)
+    atconf.format='%6.2e'
+    try:
+        sip400.set_attribute_config(atconf)
+    except:
+        pass
\ No newline at end of file
diff --git a/main.cpp b/main.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..797873b6b167602c98444a3bb8ec2b49c9958186
--- /dev/null
+++ b/main.cpp
@@ -0,0 +1,71 @@
+static const char *RcsId = "$Header: /home/cvsadm/cvsroot/elettra/server/RPC2TangoBridge/main.cpp,v 1.1.1.1 2008-04-28 09:13:16 giacomo Exp $";
+//+=============================================================================
+//
+// file :        main.cpp
+//
+// description : C++ source for a TANGO device server main.
+//               The main rule is to initialise (and create) the Tango
+//               system and to create the DServerClass singleton.
+//               The main should be the same for every Tango device server.
+//
+// project :     TANGO Device Server
+//
+// $Author: giacomo $
+//
+// $Revision: 1.1.1.1 $ $
+//
+// $Log: main.cpp,v $
+// Revision 1.1.1.1  2008-04-28 09:13:16  giacomo
+// Prima versione di RPC2TangoBridge
+//
+//
+// copyleft :    European Synchrotron Radiation Facility
+//               BP 220, Grenoble 38043
+//               FRANCE
+//
+//-=============================================================================
+//
+//  		This file is generated by POGO
+//	(Program Obviously used to Generate tango Object)
+//
+//         (c) - Software Engineering Group - ESRF
+//=============================================================================
+
+#include <tango.h>
+
+
+int main(int argc,char *argv[])
+{
+
+	Tango::Util *tg;
+	try
+	{
+		// Initialise the device server
+		//----------------------------------------
+		tg = Tango::Util::init(argc,argv);
+
+		// Create the device server singleton 
+		//	which will create everything
+		//----------------------------------------
+		tg->server_init(false);
+
+		// Run the endless loop
+		//----------------------------------------
+		cout << "Ready to accept request" << endl;
+		tg->server_run();
+	}
+	catch (bad_alloc)
+	{
+		cout << "Can't allocate memory to store device object !!!" << endl;
+		cout << "Exiting" << endl;
+	}
+	catch (CORBA::Exception &e)
+	{
+		Tango::Except::print_exception(e);
+		
+		cout << "Received a CORBA_Exception" << endl;
+		cout << "Exiting" << endl;
+	}
+	tg->server_cleanup();
+	return(0);
+}
diff --git a/read_dynamic_attribute.cpp b/read_dynamic_attribute.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..50fc9d0a6475b2d14516538b454bc0bbe2ee6f9e
--- /dev/null
+++ b/read_dynamic_attribute.cpp
@@ -0,0 +1,311 @@
+#include <tango.h>
+#include <lpc.h>
+#include <RPC2TangoBridge.h>
+#include <BridgeAttr.h>
+#include <RpcHandle.h>
+
+using namespace Tango;
+using namespace std;
+
+namespace RPC2TangoBridge_ns
+{
+
+void RPC2TangoBridge::read_dynamic_attribute(Tango::Attribute &attr)
+{
+//  	 printf("\r                                                                    ");
+//  	 fflush(stdout);
+// 	 printf("\r                                                                  \r");
+//  	 printf("\e[1;32m* \e[1;37mreading \e[0m%s\e[0m", attr.get_name().c_str() );
+//  	 fflush(stdout);
+	
+	/* lpc arrays */
+	 intArray vresi;
+	realArray vresd;
+	shortArray sa;
+	booleanArray sb;
+	charArray sc;
+	unsigned char rpcBool;
+
+	long int resi;
+	double resd;
+	short s;
+	unsigned char uc;
+	string ress;
+
+	int i;
+	int ok;
+
+	bool release = true; /* tells Attribute::set_value to free memory after usage */
+	char error[256];
+
+	/* search name in scalars map first */
+ 	map<string, BridgeAttr*>::iterator mapiter;
+	mapiter = namesMap.find(attr.get_name());
+
+	if(mapiter != namesMap.end())
+ 	{
+		BridgeAttr *brattr = (*mapiter).second;
+		fflush(stdout);
+// 		printf("read_dynamic_attribute: name %s\n", brattr->get_name().c_str());
+		RPCReadHandle *rpch = brattr->rpcReadHandle();
+// 		printf("read_dynamic_attribute: name %s\n", brattr->get_name().c_str());
+		if(rpch)
+		{
+			rpch->lockRpc();
+			Tango::WAttribute *attr_set;
+			try{
+			        Tango::MultiAttribute *attr_list = get_device_attr();
+				attr_set = &(attr_list->get_w_attr_by_name(attr.get_name().c_str()));
+			}
+			catch(DevFailed &e)
+			{
+				//printf("\e[1;31mfailed to find attribute with name \"%s\"\e[0m\n", 
+				//	attr.get_name().c_str());
+				attr_set = NULL;
+			}
+			switch(brattr->get_type())
+			{
+				case Tango::DEV_LONG:
+				resi = rpch->read_long(attr.get_name().c_str(), &ok);
+				if(ok)
+				{
+					DevLong *readVal = new DevLong;
+					*readVal = resi;
+					attr.set_value(readVal, 1, 0, true);
+					if(attr_set)
+						attr_set->set_write_value(readVal);
+				}
+				break;
+				case Tango::DEV_DOUBLE:
+					resd = rpch->read_double(attr.get_name().c_str(), &ok);
+					if(ok)
+					{
+						DevDouble *readVald = new DevDouble;
+						*readVald = resd;
+
+						if(attr_set)
+						{
+						//	printf("\e[1;32msetto write value a %f\e[0m\n",
+						//		*readVald);
+							attr_set->set_write_value(readVald);
+						}
+						attr.set_value(readVald, 1, 0, true);
+
+					}
+					break;
+				
+				case Tango::DEV_SHORT:
+					s =  rpch->read_short(attr.get_name().c_str(), &ok);
+					if(ok)
+					{
+						DevShort *readVals = new DevShort;
+						*readVals = s;
+						attr.set_value(readVals, 1, 0, true);
+						if(attr_set)
+							attr_set->set_write_value(readVals);
+
+					}
+				break;
+				
+				case Tango::DEV_UCHAR:
+					uc =  rpch->read_uchar(attr.get_name().c_str(), &ok);
+					if(ok)
+					{
+						DevUChar *readValc = new DevUChar;
+						*readValc =uc;
+						attr.set_value(readValc, 1, 0, true);
+						if(attr_set)
+							attr_set->set_write_value(readValc);
+
+					}
+				break;
+				
+				case Tango::DEV_STRING:
+					ress =  rpch->read_string(attr.get_name().c_str(), &ok);
+					if(ok)
+					{
+						DevString *readVals = new DevString;
+						*readVals = new char[ress.length() + 1];
+						/* be sure it is null terminated */
+						memset(*readVals, 0, ress.length() + 1);
+						strncpy(*readVals, ress.c_str(), ress.length());
+						attr.set_value(readVals, 1, 0, true);
+						if(attr_set)
+							attr_set->set_write_value(readVals);
+
+					}
+				break;
+				
+				case Tango::DEV_BOOLEAN:
+					rpcBool = rpch->read_boolean(attr.get_name().c_str(), &ok);
+					if(ok)
+					{
+						DevBoolean *db = new DevBoolean;
+						if(rpcBool == 0)
+							*db = false;
+						else
+							*db = true;
+						attr.set_value(db, sb.length, 0, true);
+						if(attr_set)
+							attr_set->set_write_value(db);
+
+					}
+					break;
+				case Tango::DEV_VOID:
+					rpcBool = true;
+                                        ok = true; //all dummies
+					if(ok)
+					{
+						DevBoolean *db = new DevBoolean;
+						if(rpcBool == 0)
+							*db = false;
+						else
+							*db = true;
+						attr.set_value(db, sb.length, 0, true);
+						if(attr_set)
+							attr_set->set_write_value(db);
+
+					}
+					break;
+				default:
+					
+					//printf("\t[\e[1;31mfailed\e[0m] (format not supported - %d)\n", brattr->get_type());
+					Except::throw_exception("Error reading scalar attribute " + attr.get_name(),
+						"The format is not supported.\nSupported formats: long, double",
+						"RPC2TangoBridge::read_BridgeAttr()");
+					break;
+			}
+			rpch->unlockRpc();
+
+			if(!ok)
+			{
+// 				 printf("\r                                                                  \r");
+//  				 printf("\e[1;31m* \e[1;37mreading \e[0m%s\e[0m", attr.get_name().c_str() );
+// 				printf("\t[\e[1;31mfailed\e[0m]\n\t{%s\n\t\t[host: %s:%d]}\n", rpch->lastRpcError().c_str(), rpch->host().c_str(), rpch->port());
+
+				snprintf(error, 256, "Error reading scalar attribute \"%s\". Error: %s", attr.get_name().c_str(),
+						rpch->lastRpcError().c_str());
+			//	set_state(Tango::FAULT);
+				set_status(error);
+				Except::throw_exception("Error reading scalar attribute " + attr.get_name(),
+						"RPC call failed: " + rpch->lastRpcError() ,
+						"RPC2TangoBridge::read_BridgeAttr()");
+				
+			}
+		}
+ 	}
+	
+	/* look among spectrum */
+	map<string, SpectrumBridgeAttr*>::iterator spmapiter;
+	
+	spmapiter = spectrumNamesMap.find(attr.get_name());
+
+	if(spmapiter != spectrumNamesMap.end())
+	{
+		SpectrumBridgeAttr *spbrattr = (*spmapiter).second;
+ 		RPCReadHandle *rpch = spbrattr->rpcReadHandle();
+		if(rpch)
+		{
+			rpch->lockRpc();
+			switch(spbrattr->get_type())
+			{
+				case Tango::DEV_LONG:
+					vresi = rpch->read_slong(attr.get_name().c_str(), &ok);
+					if(ok && vresi.sequence != NULL)
+					{
+						DevLong *readVal = new DevLong[vresi.length];
+						for(i = 0; i < vresi.length; i++)
+							readVal[i] = vresi.sequence[i];
+						attr.set_value(readVal, vresi.length, 0, true);
+						free (vresi.sequence);
+					}
+					break;
+				case Tango::DEV_DOUBLE:
+					vresd = rpch->read_sdouble(attr.get_name().c_str(), &ok);
+					if(ok && vresd.sequence != NULL)
+					{
+						DevDouble *readVald = new DevDouble[vresd.length];
+						for(i = 0; i < vresd.length; i++)
+							readVald[i] = vresd.sequence[i];
+						attr.set_value(readVald, vresd.length, 0, true);
+						free (vresd.sequence);
+					}
+					break;
+				case Tango::DEV_SHORT:
+					sa = rpch->read_sshort(attr.get_name().c_str(), &ok);
+					if(ok && sa.sequence != NULL)
+					{
+						DevShort *ds = new DevShort[sa.length];
+						for(i = 0; i < sa.length; i++)
+							ds[i] = sa.sequence[i];
+						attr.set_value(ds, sa.length, 0, true);
+						free (sa.sequence);
+					}
+					break;
+				
+				case Tango::DEV_UCHAR:
+					sc = rpch->read_schar(attr.get_name().c_str(), &ok);
+					if(ok && sc.sequence != NULL)
+					{
+						DevUChar *dc = new DevUChar[sc.length];
+						for(i = 0; i < sc.length; i++)
+							dc[i] = sc.sequence[i];
+						attr.set_value(dc, sc.length, 0, true);
+						free (sc.sequence);
+					}
+					break;
+
+				case Tango::DEV_BOOLEAN:
+					sb = rpch->read_sboolean(attr.get_name().c_str(), &ok);
+					if(ok && sb.sequence != NULL)
+					{
+						DevBoolean *db = new DevBoolean[sb.length];
+						for(i = 0; i < sb.length; i++)
+							db[i] = sb.sequence[i];
+						attr.set_value(db, sb.length, 0, true);
+						free (sb.sequence);
+					}
+					else{
+						//printf("\e[1;31m*\e[0m error reading boolean array for \"%s\" : %s\n", attr.get_name().c_str(), rpch->lastRpcError().c_str());
+					}
+					break;
+
+				default:
+					//printf("\t[\e[1;31mfailed\e[0m] (format not supported)\n");
+					Except::throw_exception("Error reading spectrum attribute " + attr.get_name(),
+						"The format is not supported.\nSupported formats: long, double, uchar, boolean, short",
+						"RPC2TangoBridge::read_BridgeAttr()");
+					
+					break;
+			}
+			rpch->unlockRpc();
+
+			if(!ok)
+			{
+// 				 printf("\r                                                                  \r");
+//  				 printf("\e[1;31m* \e[1;37mreading \e[0m%s\e[0m", attr.get_name().c_str() );
+// 				printf("\t[\e[1;31mfailed\e[0m]\n\t{%s\n\t\t[host: %s:%d]}\n", rpch->lastRpcError().c_str(), rpch->host().c_str(), rpch->port());
+				snprintf(error, 256, "Error reading scalar attribute \"%s\". Error: %s", attr.get_name().c_str(),
+						rpch->lastRpcError().c_str());
+//				set_state(Tango::FAULT);
+				set_status(error);
+
+				Except::throw_exception("Error reading spectrum attribute " + attr.get_name(),
+					string("RPC call failed: ")  + rpch->lastRpcError(),
+					"RPC2TangoBridge::read_BridgeAttr()");
+				
+			}
+			else
+			{
+				set_state(Tango::ON);
+				set_status("server running");
+			}
+ 		}
+ 	}
+
+}
+
+
+} /* namespace ends here */
+
+
diff --git a/write_dynamic_attribute.cpp b/write_dynamic_attribute.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..c4753a2aa19e84b33feec190c665e0f66b419319
--- /dev/null
+++ b/write_dynamic_attribute.cpp
@@ -0,0 +1,105 @@
+#include <tango.h>
+#include <lpc.h>
+#include <RPC2TangoBridge.h>
+#include <BridgeAttr.h>
+#include <RpcHandle.h>
+
+using namespace Tango;
+using namespace std;
+
+namespace RPC2TangoBridge_ns
+{
+
+bool RPC2TangoBridge::write_dynamic_attribute(Tango::WAttribute &attr)
+{
+//  	 printf("\r                                                                    ");
+//  	 fflush(stdout);
+// 	 printf("\r                                                                  \r");
+//  	 printf("\e[1;32m* \e[1;37mwriting \e[0m%s\e[0m\n", attr.get_name().c_str() );
+//  	 fflush(stdout);
+
+	DevLong dl;
+	DevShort ds;
+	DevDouble dd;
+	DevBoolean db;
+
+	long int l;
+	double d;
+	short s;
+	unsigned char uc;
+	string ress;
+	bool b;
+
+	int i;
+
+	bool release = true; /* tells Attribute::set_value to free memory after usage */
+	char error[256];
+
+	/* search name in scalars map first */
+ 	map<string, BridgeAttr*>::iterator mapiter;
+	mapiter = namesMap.find(attr.get_name());
+
+	if(mapiter != namesMap.end())
+ 	{
+		BridgeAttr *brattr = (*mapiter).second;
+		if(brattr->get_writable() != Tango::READ_WRITE)
+		{
+			//printf("\e[1;31m*\e[0m error: writable is not READ_WRITE\n");
+			return false;
+		}
+		fflush(stdout);
+// 		printf("read_dynamic_attribute: name %s\n", brattr->writeName().c_str());
+		RPCWriteHandle *rpch = brattr->rpcWriteHandle();
+// 		printf("read_dynamic_attribute: name %s\n", brattr->writeName().c_str());
+		if(rpch)
+		{
+			switch(brattr->get_type())
+			{
+				case Tango::DEV_LONG:
+					attr.get_write_value(dl);
+					l = (long) dl;
+					return rpch->write_long(brattr->writeName().c_str(), l);
+
+				case Tango::DEV_DOUBLE:
+					attr.get_write_value(dd);
+					d = (double) dd;
+					return rpch->write_double(brattr->writeName().c_str(), d);
+				
+				case Tango::DEV_SHORT:
+					attr.get_write_value(ds);
+					s = (short) ds;
+					return rpch->write_short(brattr->writeName().c_str(), s);
+// 				case Tango::DEV_STRING:
+// 					
+				
+				case Tango::DEV_BOOLEAN:
+					attr.get_write_value(db);
+					b = (bool) db;
+					return  rpch->write_boolean(brattr->writeName().c_str(), b);
+                                case Tango::DEV_VOID:
+					attr.get_write_value(db);
+					b = (bool) db; //dummy
+					return  rpch->write_void(brattr->writeName().c_str());
+				default:
+					
+					//printf("\t[\e[1;31mfailed\e[0m] (format not supported - %d)\n", brattr->get_type());
+					Except::throw_exception("Error reading scalar attribute " + brattr->writeName(),
+						"The format is not supported.\nSupported formats: long, double",
+						"RPC2TangoBridge::read_BridgeAttr()");
+					break;
+			}
+
+		}
+		else{
+			//printf("\e[1;31m*\e[0m error: rpc write handle not initialized\n");
+		}
+		
+		
+ 	}
+	return false;
+}
+
+
+} /* namespace ends here */
+
+