From 09b6b338e006bf3e92b289d5987bc52ad3a56d98 Mon Sep 17 00:00:00 2001
From: Marco De Marco <demarco@oats.inaf.it>
Date: Fri, 29 Nov 2013 15:54:24 +0100
Subject: [PATCH] Servers, sessions, worker thread, and db manager classes
 added

---
 src/Configuration.h              | 177 ++++++++++
 src/DBManager.cpp                |  80 +++++
 src/DBManager.h                  |  80 +++++
 src/DataExporter.cpp             | 562 +++++++++++++++++++++++++++++--
 src/DataExporter.h               | 107 +++++-
 src/DataExporter.xmi             | 116 ++++++-
 src/DataExporterClass.cpp        | 437 ++++++++++++++++++++++++
 src/DataExporterClass.h          |  66 ++++
 src/DataExporterStateMachine.cpp |  33 ++
 src/PlainServer.cpp              |  52 +++
 src/PlainServer.h                |  42 +++
 src/PlainSession.cpp             | 161 +++++++++
 src/PlainSession.h               |  67 ++++
 src/SSLServer.cpp                |  87 +++++
 src/SSLServer.h                  |  56 +++
 src/SSLSession.cpp               | 196 +++++++++++
 src/SSLSession.h                 |  77 +++++
 src/Server.cpp                   | 197 +++++++++++
 src/Server.h                     | 103 ++++++
 src/Session.cpp                  | 135 ++++++++
 src/Session.h                    |  97 ++++++
 src/WorkerThread.cpp             |  59 ++++
 src/WorkerThread.h               |  37 ++
 23 files changed, 2987 insertions(+), 37 deletions(-)
 create mode 100644 src/Configuration.h
 create mode 100644 src/DBManager.cpp
 create mode 100644 src/DBManager.h
 create mode 100644 src/PlainServer.cpp
 create mode 100644 src/PlainServer.h
 create mode 100644 src/PlainSession.cpp
 create mode 100644 src/PlainSession.h
 create mode 100644 src/SSLServer.cpp
 create mode 100644 src/SSLServer.h
 create mode 100644 src/SSLSession.cpp
 create mode 100644 src/SSLSession.h
 create mode 100644 src/Server.cpp
 create mode 100644 src/Server.h
 create mode 100644 src/Session.cpp
 create mode 100644 src/Session.h
 create mode 100644 src/WorkerThread.cpp
 create mode 100644 src/WorkerThread.h

diff --git a/src/Configuration.h b/src/Configuration.h
new file mode 100644
index 0000000..e25c887
--- /dev/null
+++ b/src/Configuration.h
@@ -0,0 +1,177 @@
+#ifndef CONFIGURATION_H
+#define	CONFIGURATION_H
+
+#include <map>
+#include <string>
+#include <vector>
+
+#include <boost/shared_ptr.hpp>
+
+namespace DataExporter_ns
+{
+
+class Configuration
+{
+public:
+//------------------------------------------------------------------------------
+//	[Public] Shared pointer typedef
+//------------------------------------------------------------------------------
+	typedef boost::shared_ptr<Configuration> SP;
+
+//------------------------------------------------------------------------------
+//	[Public] Map typedef
+//------------------------------------------------------------------------------
+	typedef const std::multimap<const std::string, const std::string> ExportedTablesMap;
+	typedef const std::map<const std::string, const std::string> AuthorisedUsersMap;
+
+protected:
+//------------------------------------------------------------------------------
+//	[Private] Constructor destructor deleter
+//------------------------------------------------------------------------------
+	Configuration(std::string certificateFile, std::string privateKeyFile,
+        std::string dHTempFile, ExportedTablesMap exportedTablesMap,
+        AuthorisedUsersMap authorisedUsersMap, std::string storagePath,
+        std::string localHost, unsigned int localPort, unsigned int workerNumber,
+        std::string databaseHost, unsigned int databasePort,
+        std::string databaseUsername, std::string databasePassword,
+        unsigned int databaseConnectionNumber) :
+        m_certificateFile(certificateFile), m_privateKeyFile(privateKeyFile),
+        m_dHTempFile(dHTempFile), m_exportedTablesMap(exportedTablesMap),
+        m_authorisedUsersMap(authorisedUsersMap), m_storagePath(storagePath),
+         m_localHost(localHost), m_localPort(localPort), m_workerNumber(workerNumber),
+        m_databaseHost(databaseHost), m_databasePort(databasePort),
+        m_databaseUsername(databaseUsername), m_databasePassword(databasePassword),
+        m_databaseConnectionNumber(databaseConnectionNumber) {}
+
+	virtual ~Configuration() {}
+
+	class Deleter;
+	friend class Deleter;
+	class Deleter
+	{
+	public:
+		void operator()(Configuration* c) { delete c; }
+	};
+
+public:
+//------------------------------------------------------------------------------
+//	[Public] Create class method
+//------------------------------------------------------------------------------
+	static Configuration::SP create(std::string certificateFile,
+        std::string privateKeyFile, std::string dHTempFile,
+        ExportedTablesMap exportedTablesMap, AuthorisedUsersMap authorisedUsersMap,
+        std::string storagePath, std::string localHost,
+         unsigned int localPort, unsigned int workerNumber,
+        std::string databaseHost, unsigned int databasePort,
+        std::string databaseUsername, std::string databasePassword,
+        unsigned int databaseConnectionNumber)
+	{
+		Configuration::SP c_sp(new Configuration(certificateFile, privateKeyFile,
+            dHTempFile, exportedTablesMap, authorisedUsersMap, storagePath,
+            localHost, localPort, workerNumber, databaseHost, databasePort,
+            databaseUsername, databasePassword, databaseConnectionNumber),
+            Configuration::Deleter());
+
+		return c_sp;
+	}
+
+//------------------------------------------------------------------------------
+//	[Public] Getter methods
+//------------------------------------------------------------------------------
+	std::string getCertificateFile() const { return m_certificateFile; }
+	std::string getPrivateKeyFile() const { return m_privateKeyFile; }
+	std::string getDHTempFile() const { return m_dHTempFile; }
+    ExportedTablesMap& getExportedTablesMap() const { return m_exportedTablesMap; }
+    AuthorisedUsersMap& getAuthorisedUsersMap() const { return m_authorisedUsersMap; }
+    std::string getStoragePath() const { return m_storagePath; }
+	std::string getLocalHost() const { return m_localHost; }
+	unsigned int getLocalPort() const { return m_localPort; }
+	unsigned int getWorkerNumber() const { return m_workerNumber; }
+	std::string getDatabaseHost() const { return m_databaseHost; }
+	unsigned int getDatabasePort() const { return m_databasePort; }
+	std::string getDatabaseUsername() const { return m_databaseUsername; }
+	std::string getDatabasePassword() const { return m_databasePassword; }
+    unsigned int getDatabaseConnectionNumber() const { return m_databaseConnectionNumber; }
+
+//------------------------------------------------------------------------------
+//	[Public] Utilities methods
+//------------------------------------------------------------------------------
+    bool isTableExported(const std::string schema, const std::string table)
+    {
+        std::pair<ExportedTablesMap::const_iterator, ExportedTablesMap::const_iterator > ret;
+
+        ret = m_exportedTablesMap.equal_range(schema);
+
+        ExportedTablesMap::const_iterator it;
+
+        for(it=ret.first; it!=ret.second; ++it)
+        {
+            if(it->second.compare(table) == 0)
+                return true;
+        }
+
+        return false;
+    }
+
+    bool isUserAuthorized(const std::string username, const std::string password)
+    {
+        AuthorisedUsersMap::const_iterator it = m_authorisedUsersMap.find(username);
+
+        if(it!=m_authorisedUsersMap.end() &&
+            it->second.compare(password)==0)
+            return true;
+
+        return false;
+    }
+
+protected:
+//------------------------------------------------------------------------------
+//	[Private] class variables
+//------------------------------------------------------------------------------
+	//Absolute path to certificate chain file
+	const std::string m_certificateFile;
+
+	//Absolute path to private key file
+	const std::string m_privateKeyFile;
+
+	//Absolute path to Diffie Hellman temporary file
+	const std::string m_dHTempFile;
+
+    //Exported tables multi map [schema table]
+	ExportedTablesMap m_exportedTablesMap;
+
+    //Authorised users map [user password]
+	AuthorisedUsersMap m_authorisedUsersMap;
+
+    //Absolute path to storage
+    const std::string m_storagePath;
+
+	//Local host address for incoming connection
+	const std::string m_localHost;
+
+	//Local port for wait incoming connection
+	const unsigned int m_localPort;
+
+	//Number of threads that call io service run methods
+	const unsigned int m_workerNumber;
+
+	//Metadata database host
+	const std::string m_databaseHost;
+
+	//Metadata database port
+	const unsigned int m_databasePort;
+
+	//Metadata database login username
+	const std::string m_databaseUsername;
+
+	//Metadata database login password
+	const std::string m_databasePassword;
+
+    //Metadata database connections number
+    const unsigned int m_databaseConnectionNumber;
+};
+
+}   //End of namespace
+
+#endif	/* CONFIGURATION_H */
+
diff --git a/src/DBManager.cpp b/src/DBManager.cpp
new file mode 100644
index 0000000..e59e6f8
--- /dev/null
+++ b/src/DBManager.cpp
@@ -0,0 +1,80 @@
+#include <DBManager.h>
+
+#include <boost/date_time.hpp>
+
+#include <soci/mysql/soci-mysql.h>
+#include <soci/use.h>
+
+namespace DataExporter_ns
+{
+
+//==============================================================================
+//      DBManager::DBManager()
+//==============================================================================
+DBManager::DBManager(Tango::DeviceImpl* deviceImpl_p,
+    Configuration::SP configuration_sp) : Tango::LogAdapter(deviceImpl_p),
+    m_configuration_sp(configuration_sp)
+{
+    DEBUG_STREAM << "DBManager::DBManager()" << endl;
+}
+
+//==============================================================================
+//      DBManager::DBManager()
+//==============================================================================
+DBManager::~DBManager()
+{
+    DEBUG_STREAM << "DBManager::~DBManager()" << endl;
+}
+
+//==============================================================================
+//      DBManager::DBManager()
+//==============================================================================
+DBManager::SP DBManager::create(Tango::DeviceImpl* deviceImpl_p,
+    Configuration::SP configuration_sp)
+{
+    DBManager::SP d_sp(new DBManager(deviceImpl_p, configuration_sp),
+        DBManager::Deleter());
+
+    return d_sp;
+}
+
+//==============================================================================
+//      DBManager::connect()
+//==============================================================================
+void DBManager::connect() throw(soci::soci_error)
+{
+    DEBUG_STREAM << "DBManager::connect()" << endl;
+
+    boost::mutex::scoped_lock lock(m_connectionPoolMutex);
+
+    unsigned int connectionNumber = m_configuration_sp->getDatabaseConnectionNumber();
+
+    m_connectionPool_sp.reset(new soci::connection_pool(connectionNumber));
+
+    std::stringstream connection;
+    connection << " host=" << m_configuration_sp->getDatabaseHost();
+    connection << " port=" << m_configuration_sp->getDatabasePort();
+    connection << " user=" << m_configuration_sp->getDatabaseUsername();
+    connection << " password=" << m_configuration_sp->getDatabasePassword();
+
+    #ifdef VERBOSE_DEBUG
+        INFO_STREAM << "DBManager::connect(): " << connection.str() << endl;
+    #endif
+
+    for(unsigned int i=0; i<connectionNumber; ++i)
+        m_connectionPool_sp->at(i).open(soci::mysql, connection.str());
+}
+
+//==============================================================================
+//      DBManager::disconnect()
+//==============================================================================
+void DBManager::disconnect()
+{
+    DEBUG_STREAM << "DBManager::disconnect()" << endl;
+
+    boost::mutex::scoped_lock lock(m_connectionPoolMutex);
+
+    m_connectionPool_sp.reset();
+}
+
+}   //namespace
diff --git a/src/DBManager.h b/src/DBManager.h
new file mode 100644
index 0000000..30c9659
--- /dev/null
+++ b/src/DBManager.h
@@ -0,0 +1,80 @@
+#ifndef DBMANAGER_H
+#define	DBMANAGER_H
+
+#include <Configuration.h>
+
+#include <tango.h>
+
+#include <ctime>
+
+#include <boost/tuple/tuple.hpp>
+#include <boost/optional/optional.hpp>
+#include <boost/scoped_ptr.hpp>
+#include <boost/thread/mutex.hpp>
+
+#include <soci/soci.h>
+#include <soci/error.h>
+#include <soci/row.h>
+#include <soci/rowset.h>
+#include <soci/boost-tuple.h>
+#include <soci/boost-optional.h>
+#include <soci/session.h>
+#include <soci/connection-pool.h>
+
+namespace DataExporter_ns
+{
+
+class DBManager : public Tango::LogAdapter
+{
+public:
+//------------------------------------------------------------------------------
+//  [Public] Shared pointer typedef
+//------------------------------------------------------------------------------
+    typedef boost::shared_ptr<DBManager> SP;
+
+protected:
+//------------------------------------------------------------------------------
+//  [Protected] Constructor destructor deleter
+//------------------------------------------------------------------------------
+    DBManager(Tango::DeviceImpl*, Configuration::SP);
+
+    virtual ~DBManager();
+
+    class Deleter;
+    friend Deleter;
+    class Deleter
+    {
+        public:
+            void operator()(DBManager* d) { delete d; }
+    };
+
+public:
+//------------------------------------------------------------------------------
+//	[Public] Class creation method
+//------------------------------------------------------------------------------
+    static DBManager::SP create(Tango::DeviceImpl*, Configuration::SP);
+
+//------------------------------------------------------------------------------
+//  [Public] Connection management methods
+//------------------------------------------------------------------------------
+    virtual void connect() throw(soci::soci_error);
+
+    virtual void disconnect();
+
+protected:
+//------------------------------------------------------------------------------
+//  [Protected] Class variables
+//------------------------------------------------------------------------------
+    //Configuration shared pointer
+    Configuration::SP m_configuration_sp;
+
+    //Connection pool mutex
+    boost::mutex m_connectionPoolMutex;
+
+    //Database connection pool scoped pointer
+    boost::scoped_ptr<soci::connection_pool> m_connectionPool_sp;
+};
+
+}   //End of namespace
+
+#endif	/* DBMANAGER_H */
diff --git a/src/DataExporter.cpp b/src/DataExporter.cpp
index 12c9b88..594ac45 100644
--- a/src/DataExporter.cpp
+++ b/src/DataExporter.cpp
@@ -13,20 +13,20 @@ static const char *RcsId = "$Id:  $";
 // project :     Data exporter
 //
 // This file is part of Tango device class.
-// 
+//
 // Tango is free software: you can redistribute it and/or modify
 // it under the terms of the GNU General Public License as published by
 // the Free Software Foundation, either version 3 of the License, or
 // (at your option) any later version.
-// 
+//
 // Tango is distributed in the hope that it will be useful,
 // but WITHOUT ANY WARRANTY; without even the implied warranty of
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 // GNU General Public License for more details.
-// 
+//
 // You should have received a copy of the GNU General Public License
 // along with Tango.  If not, see <http://www.gnu.org/licenses/>.
-// 
+//
 // $Author:  $
 //
 // $Revision:  $
@@ -42,12 +42,16 @@ static const char *RcsId = "$Id:  $";
 
 #include <DataExporter.h>
 #include <DataExporterClass.h>
+#include <PlainServer.h>
+#include <SSLServer.h>
+
+#include <boost/filesystem.hpp>
 
 /*----- PROTECTED REGION END -----*/	//	DataExporter.cpp
 
 /**
  *  DataExporter class description:
- *    
+ *
  */
 
 //================================================================
@@ -58,6 +62,8 @@ static const char *RcsId = "$Id:  $";
 //================================================================
 //  State         |  Inherited (no method)
 //  Status        |  Inherited (no method)
+//  On            |  on
+//  Off           |  off
 //================================================================
 
 //================================================================
@@ -85,7 +91,7 @@ DataExporter::DataExporter(Tango::DeviceClass *cl, string &s)
 {
 	/*----- PROTECTED REGION ID(DataExporter::constructor_1) ENABLED START -----*/
 	init_device();
-	
+
 	/*----- PROTECTED REGION END -----*/	//	DataExporter::constructor_1
 }
 //--------------------------------------------------------
@@ -94,7 +100,7 @@ DataExporter::DataExporter(Tango::DeviceClass *cl, const char *s)
 {
 	/*----- PROTECTED REGION ID(DataExporter::constructor_2) ENABLED START -----*/
 	init_device();
-	
+
 	/*----- PROTECTED REGION END -----*/	//	DataExporter::constructor_2
 }
 //--------------------------------------------------------
@@ -103,7 +109,7 @@ DataExporter::DataExporter(Tango::DeviceClass *cl, const char *s, const char *d)
 {
 	/*----- PROTECTED REGION ID(DataExporter::constructor_3) ENABLED START -----*/
 	init_device();
-	
+
 	/*----- PROTECTED REGION END -----*/	//	DataExporter::constructor_3
 }
 
@@ -117,9 +123,9 @@ void DataExporter::delete_device()
 {
 	DEBUG_STREAM << "DataExporter::delete_device() " << device_name << endl;
 	/*----- PROTECTED REGION ID(DataExporter::delete_device) ENABLED START -----*/
-	
+
 	//	Delete device allocated objects
-	
+
 	/*----- PROTECTED REGION END -----*/	//	DataExporter::delete_device
 }
 
@@ -133,21 +139,339 @@ void DataExporter::init_device()
 {
 	DEBUG_STREAM << "DataExporter::init_device() create device " << device_name << endl;
 	/*----- PROTECTED REGION ID(DataExporter::init_device_before) ENABLED START -----*/
-	
-	//	Initialization before get_device_property() call
-	
+
+    set_state(Tango::INIT);
+    set_status("Initializing device");
+
 	/*----- PROTECTED REGION END -----*/	//	DataExporter::init_device_before
-	
-	//	No device property to be read from database
-	
+
+
+	//	Get the device properties from database
+	get_device_property();
+
 
 	/*----- PROTECTED REGION ID(DataExporter::init_device) ENABLED START -----*/
-	
-	//	Initialize device
-	
+
+    if(get_state() != Tango::FAULT)
+    {
+        try
+        {
+            if(enableSSL)
+                m_server_sp = SSLServer::create(this, m_configuration_sp);
+            else
+                m_server_sp = PlainServer::create(this, m_configuration_sp);
+        }
+        catch(std::exception& ex)
+        {
+            set_state(Tango::FAULT);
+            std::stringstream error_stream;
+            error_stream << "DataExporter::init_device() " << ex.what() << std::endl;
+            set_status(error_stream.str());
+        }
+        catch(...)
+        {
+            set_state(Tango::FAULT);
+            set_status("DataExporter::init_device() unknown error");
+        }
+    }
+
 	/*----- PROTECTED REGION END -----*/	//	DataExporter::init_device
 }
 
+//--------------------------------------------------------
+/**
+ *	Method      : DataExporter::get_device_property()
+ *	Description : Read database to initialize property data members.
+ */
+//--------------------------------------------------------
+void DataExporter::get_device_property()
+{
+	/*----- PROTECTED REGION ID(DataExporter::get_device_property_before) ENABLED START -----*/
+
+    //Exported tables multi map [schema table]
+    std::multimap<const std::string, const std::string> exportedTablesMap;
+
+    //Authorised user map [user password]
+    std::map<const std::string, const std::string> authorisedUsersMap;
+
+	/*----- PROTECTED REGION END -----*/	//	DataExporter::get_device_property_before
+
+
+	//	Read device properties from database.
+	Tango::DbData	dev_prop;
+	dev_prop.push_back(Tango::DbDatum("CertificateFile"));
+	dev_prop.push_back(Tango::DbDatum("PrivateKeyFile"));
+	dev_prop.push_back(Tango::DbDatum("DHTempFile"));
+	dev_prop.push_back(Tango::DbDatum("ExportedTables"));
+	dev_prop.push_back(Tango::DbDatum("AuthorisedUsers"));
+	dev_prop.push_back(Tango::DbDatum("StoragePath"));
+	dev_prop.push_back(Tango::DbDatum("LocalHost"));
+	dev_prop.push_back(Tango::DbDatum("LocalPort"));
+	dev_prop.push_back(Tango::DbDatum("WorkerNumber"));
+	dev_prop.push_back(Tango::DbDatum("EnableSSL"));
+	dev_prop.push_back(Tango::DbDatum("DatabaseHost"));
+	dev_prop.push_back(Tango::DbDatum("DatabasePort"));
+	dev_prop.push_back(Tango::DbDatum("DatabaseUsername"));
+	dev_prop.push_back(Tango::DbDatum("DatabasePassword"));
+	dev_prop.push_back(Tango::DbDatum("DatabaseConnectionNumber"));
+
+	//	is there at least one property to be read ?
+	if (dev_prop.size()>0)
+	{
+		//	Call database and extract values
+		if (Tango::Util::instance()->_UseDb==true)
+			get_db_device()->get_property(dev_prop);
+
+		//	get instance on DataExporterClass to get class property
+		Tango::DbDatum	def_prop, cl_prop;
+		DataExporterClass	*ds_class =
+			(static_cast<DataExporterClass *>(get_device_class()));
+		int	i = -1;
+
+		//	Try to initialize CertificateFile from class property
+		cl_prop = ds_class->get_class_property(dev_prop[++i].name);
+		if (cl_prop.is_empty()==false)	cl_prop  >>  certificateFile;
+		else {
+			//	Try to initialize CertificateFile from default device value
+			def_prop = ds_class->get_default_device_property(dev_prop[i].name);
+			if (def_prop.is_empty()==false)	def_prop  >>  certificateFile;
+		}
+		//	And try to extract CertificateFile value from database
+		if (dev_prop[i].is_empty()==false)	dev_prop[i]  >>  certificateFile;
+
+		//	Try to initialize PrivateKeyFile from class property
+		cl_prop = ds_class->get_class_property(dev_prop[++i].name);
+		if (cl_prop.is_empty()==false)	cl_prop  >>  privateKeyFile;
+		else {
+			//	Try to initialize PrivateKeyFile from default device value
+			def_prop = ds_class->get_default_device_property(dev_prop[i].name);
+			if (def_prop.is_empty()==false)	def_prop  >>  privateKeyFile;
+		}
+		//	And try to extract PrivateKeyFile value from database
+		if (dev_prop[i].is_empty()==false)	dev_prop[i]  >>  privateKeyFile;
+
+		//	Try to initialize DHTempFile from class property
+		cl_prop = ds_class->get_class_property(dev_prop[++i].name);
+		if (cl_prop.is_empty()==false)	cl_prop  >>  dHTempFile;
+		else {
+			//	Try to initialize DHTempFile from default device value
+			def_prop = ds_class->get_default_device_property(dev_prop[i].name);
+			if (def_prop.is_empty()==false)	def_prop  >>  dHTempFile;
+		}
+		//	And try to extract DHTempFile value from database
+		if (dev_prop[i].is_empty()==false)	dev_prop[i]  >>  dHTempFile;
+
+		//	Try to initialize ExportedTables from class property
+		cl_prop = ds_class->get_class_property(dev_prop[++i].name);
+		if (cl_prop.is_empty()==false)	cl_prop  >>  exportedTables;
+		else {
+			//	Try to initialize ExportedTables from default device value
+			def_prop = ds_class->get_default_device_property(dev_prop[i].name);
+			if (def_prop.is_empty()==false)	def_prop  >>  exportedTables;
+		}
+		//	And try to extract ExportedTables value from database
+		if (dev_prop[i].is_empty()==false)	dev_prop[i]  >>  exportedTables;
+
+		//	Try to initialize AuthorisedUsers from class property
+		cl_prop = ds_class->get_class_property(dev_prop[++i].name);
+		if (cl_prop.is_empty()==false)	cl_prop  >>  authorisedUsers;
+		else {
+			//	Try to initialize AuthorisedUsers from default device value
+			def_prop = ds_class->get_default_device_property(dev_prop[i].name);
+			if (def_prop.is_empty()==false)	def_prop  >>  authorisedUsers;
+		}
+		//	And try to extract AuthorisedUsers value from database
+		if (dev_prop[i].is_empty()==false)	dev_prop[i]  >>  authorisedUsers;
+
+		//	Try to initialize StoragePath from class property
+		cl_prop = ds_class->get_class_property(dev_prop[++i].name);
+		if (cl_prop.is_empty()==false)	cl_prop  >>  storagePath;
+		else {
+			//	Try to initialize StoragePath from default device value
+			def_prop = ds_class->get_default_device_property(dev_prop[i].name);
+			if (def_prop.is_empty()==false)	def_prop  >>  storagePath;
+		}
+		//	And try to extract StoragePath value from database
+		if (dev_prop[i].is_empty()==false)	dev_prop[i]  >>  storagePath;
+
+		//	Try to initialize LocalHost from class property
+		cl_prop = ds_class->get_class_property(dev_prop[++i].name);
+		if (cl_prop.is_empty()==false)	cl_prop  >>  localHost;
+		else {
+			//	Try to initialize LocalHost from default device value
+			def_prop = ds_class->get_default_device_property(dev_prop[i].name);
+			if (def_prop.is_empty()==false)	def_prop  >>  localHost;
+		}
+		//	And try to extract LocalHost value from database
+		if (dev_prop[i].is_empty()==false)	dev_prop[i]  >>  localHost;
+
+		//	Try to initialize LocalPort from class property
+		cl_prop = ds_class->get_class_property(dev_prop[++i].name);
+		if (cl_prop.is_empty()==false)	cl_prop  >>  localPort;
+		else {
+			//	Try to initialize LocalPort from default device value
+			def_prop = ds_class->get_default_device_property(dev_prop[i].name);
+			if (def_prop.is_empty()==false)	def_prop  >>  localPort;
+		}
+		//	And try to extract LocalPort value from database
+		if (dev_prop[i].is_empty()==false)	dev_prop[i]  >>  localPort;
+
+		//	Try to initialize WorkerNumber from class property
+		cl_prop = ds_class->get_class_property(dev_prop[++i].name);
+		if (cl_prop.is_empty()==false)	cl_prop  >>  workerNumber;
+		else {
+			//	Try to initialize WorkerNumber from default device value
+			def_prop = ds_class->get_default_device_property(dev_prop[i].name);
+			if (def_prop.is_empty()==false)	def_prop  >>  workerNumber;
+		}
+		//	And try to extract WorkerNumber value from database
+		if (dev_prop[i].is_empty()==false)	dev_prop[i]  >>  workerNumber;
+
+		//	Try to initialize EnableSSL from class property
+		cl_prop = ds_class->get_class_property(dev_prop[++i].name);
+		if (cl_prop.is_empty()==false)	cl_prop  >>  enableSSL;
+		else {
+			//	Try to initialize EnableSSL from default device value
+			def_prop = ds_class->get_default_device_property(dev_prop[i].name);
+			if (def_prop.is_empty()==false)	def_prop  >>  enableSSL;
+		}
+		//	And try to extract EnableSSL value from database
+		if (dev_prop[i].is_empty()==false)	dev_prop[i]  >>  enableSSL;
+
+		//	Try to initialize DatabaseHost from class property
+		cl_prop = ds_class->get_class_property(dev_prop[++i].name);
+		if (cl_prop.is_empty()==false)	cl_prop  >>  databaseHost;
+		else {
+			//	Try to initialize DatabaseHost from default device value
+			def_prop = ds_class->get_default_device_property(dev_prop[i].name);
+			if (def_prop.is_empty()==false)	def_prop  >>  databaseHost;
+		}
+		//	And try to extract DatabaseHost value from database
+		if (dev_prop[i].is_empty()==false)	dev_prop[i]  >>  databaseHost;
+
+		//	Try to initialize DatabasePort from class property
+		cl_prop = ds_class->get_class_property(dev_prop[++i].name);
+		if (cl_prop.is_empty()==false)	cl_prop  >>  databasePort;
+		else {
+			//	Try to initialize DatabasePort from default device value
+			def_prop = ds_class->get_default_device_property(dev_prop[i].name);
+			if (def_prop.is_empty()==false)	def_prop  >>  databasePort;
+		}
+		//	And try to extract DatabasePort value from database
+		if (dev_prop[i].is_empty()==false)	dev_prop[i]  >>  databasePort;
+
+		//	Try to initialize DatabaseUsername from class property
+		cl_prop = ds_class->get_class_property(dev_prop[++i].name);
+		if (cl_prop.is_empty()==false)	cl_prop  >>  databaseUsername;
+		else {
+			//	Try to initialize DatabaseUsername from default device value
+			def_prop = ds_class->get_default_device_property(dev_prop[i].name);
+			if (def_prop.is_empty()==false)	def_prop  >>  databaseUsername;
+		}
+		//	And try to extract DatabaseUsername value from database
+		if (dev_prop[i].is_empty()==false)	dev_prop[i]  >>  databaseUsername;
+
+		//	Try to initialize DatabasePassword from class property
+		cl_prop = ds_class->get_class_property(dev_prop[++i].name);
+		if (cl_prop.is_empty()==false)	cl_prop  >>  databasePassword;
+		else {
+			//	Try to initialize DatabasePassword from default device value
+			def_prop = ds_class->get_default_device_property(dev_prop[i].name);
+			if (def_prop.is_empty()==false)	def_prop  >>  databasePassword;
+		}
+		//	And try to extract DatabasePassword value from database
+		if (dev_prop[i].is_empty()==false)	dev_prop[i]  >>  databasePassword;
+
+		//	Try to initialize DatabaseConnectionNumber from class property
+		cl_prop = ds_class->get_class_property(dev_prop[++i].name);
+		if (cl_prop.is_empty()==false)	cl_prop  >>  databaseConnectionNumber;
+		else {
+			//	Try to initialize DatabaseConnectionNumber from default device value
+			def_prop = ds_class->get_default_device_property(dev_prop[i].name);
+			if (def_prop.is_empty()==false)	def_prop  >>  databaseConnectionNumber;
+		}
+		//	And try to extract DatabaseConnectionNumber value from database
+		if (dev_prop[i].is_empty()==false)	dev_prop[i]  >>  databaseConnectionNumber;
+
+	}
+
+	/*----- PROTECTED REGION ID(DataExporter::get_device_property_after) ENABLED START -----*/
+
+    try
+    {
+        if(enableSSL)
+        {
+            if(certificateFile.empty())
+                throw(invalid_argument("CertificateFile property is empty or not defined"));
+
+            checkIfFileExists(certificateFile);
+
+            if(privateKeyFile.empty())
+                throw(invalid_argument("PrivateKeyFile property is empty or not defined"));
+
+            checkIfFileExists(privateKeyFile);
+
+            if(dHTempFile.empty())
+                throw(invalid_argument("DHTempFile property is empty or not defined"));
+
+            checkIfFileExists(dHTempFile);
+        }
+
+        if(exportedTables.empty())
+            throw(invalid_argument("ExportedTables property is empty or not defined"));
+
+        importExportedTables(exportedTables, exportedTablesMap);
+
+        if(authorisedUsers.empty())
+            throw(invalid_argument("AuthorisedUsers property is empty or not defined"));
+
+        importAuthorisedUsers(authorisedUsers, authorisedUsersMap);
+
+        if(storagePath.empty())
+            throw(invalid_argument("StoragePath property is empty or not defined"));
+
+        checkIfDirectoryExists(storagePath);
+
+        if(localHost.empty())
+            throw(invalid_argument("LocalHost property is empty or not defined"));
+
+        if(localPort<1 || localPort>MAX_LOCAL_PORT)
+            throw(invalid_argument("LocalPort property out of range or not defined"));
+
+        if(workerNumber<1 || workerNumber>MAX_WORKER_NUMBER)
+            throw(invalid_argument("WorkerNumber property out of range or not defined"));
+
+        if(databaseHost.empty())
+            throw(invalid_argument("DatabaseHost property is empty or not defined"));
+
+        if(databasePort<1 || databasePort>MAX_DB_PORT)
+            throw(invalid_argument("DatabasePort property out of range or not defined"));
+
+        if(databaseUsername.empty())
+            throw(invalid_argument("DatabaseUsername property is empty or not defined"));
+
+        if(databasePassword.empty())
+            throw(invalid_argument("DatabasePassword property is empty or not defined"));
+
+        if(databaseConnectionNumber<1 || databaseConnectionNumber>MAX_DB_CONNECTION_NUMBER)
+            throw(invalid_argument("DatabaseConnectionNumber property out of range or not defined"));
+
+        m_configuration_sp = Configuration::create(certificateFile,
+            privateKeyFile, dHTempFile, exportedTablesMap, authorisedUsersMap,
+            storagePath, localHost, localPort, workerNumber,
+            databaseHost, databasePort, databaseUsername, databasePassword,
+            databaseConnectionNumber);
+    }
+    catch(invalid_argument& ex)
+    {
+        set_state(Tango::FAULT);
+        stringstream error_stream;
+        error_stream << "DataExporter::get_device_property() " << ex.what() << endl;
+        set_status(error_stream.str());
+    }
+
+	/*----- PROTECTED REGION END -----*/	//	DataExporter::get_device_property_after
+}
 
 //--------------------------------------------------------
 /**
@@ -157,11 +481,19 @@ void DataExporter::init_device()
 //--------------------------------------------------------
 void DataExporter::always_executed_hook()
 {
-	INFO_STREAM << "DataExporter::always_executed_hook()  " << device_name << endl;
+	DEBUG_STREAM << "DataExporter::always_executed_hook()  " << device_name << endl;
 	/*----- PROTECTED REGION ID(DataExporter::always_executed_hook) ENABLED START -----*/
-	
-	//	code always executed before all requests
-	
+
+    if(get_state() != Tango::FAULT)
+    {
+        if(m_server_sp)
+        {
+            set_state(m_server_sp->readState());
+
+            set_status(m_server_sp->readStatus());
+        }
+    }
+
 	/*----- PROTECTED REGION END -----*/	//	DataExporter::always_executed_hook
 }
 
@@ -175,9 +507,9 @@ void DataExporter::read_attr_hardware(TANGO_UNUSED(vector<long> &attr_list))
 {
 	DEBUG_STREAM << "DataExporter::read_attr_hardware(vector<long> &attr_list) entering... " << endl;
 	/*----- PROTECTED REGION ID(DataExporter::read_attr_hardware) ENABLED START -----*/
-	
+
 	//	Add your own code
-	
+
 	/*----- PROTECTED REGION END -----*/	//	DataExporter::read_attr_hardware
 }
 
@@ -192,16 +524,190 @@ void DataExporter::read_attr_hardware(TANGO_UNUSED(vector<long> &attr_list))
 void DataExporter::add_dynamic_attributes()
 {
 	/*----- PROTECTED REGION ID(DataExporter::add_dynamic_attributes) ENABLED START -----*/
-	
+
 	//	Add your own code to create and add dynamic attributes if any
-	
+
 	/*----- PROTECTED REGION END -----*/	//	DataExporter::add_dynamic_attributes
 }
 
+//--------------------------------------------------------
+/**
+ *	Command On related method
+ *	Description: Activate data exporter
+ *
+ */
+//--------------------------------------------------------
+void DataExporter::on()
+{
+	DEBUG_STREAM << "DataExporter::On()  - " << device_name << endl;
+	/*----- PROTECTED REGION ID(DataExporter::on) ENABLED START -----*/
+
+    try
+    {
+        if(m_server_sp)
+            m_server_sp->start();
+    }
+    catch(std::exception& ex)
+    {
+        set_state(Tango::FAULT);
+        std::stringstream error_stream;
+        error_stream << "DataExporter::On() " << ex.what() << std::endl;
+        set_status(error_stream.str());
+    }
+    catch(...)
+    {
+        set_state(Tango::FAULT);
+        set_status("DataExporter::On() unknown error");
+    }
+
+	/*----- PROTECTED REGION END -----*/	//	DataExporter::on
+}
+//--------------------------------------------------------
+/**
+ *	Command Off related method
+ *	Description: Deactivate data exporter
+ *
+ */
+//--------------------------------------------------------
+void DataExporter::off()
+{
+	DEBUG_STREAM << "DataExporter::Off()  - " << device_name << endl;
+	/*----- PROTECTED REGION ID(DataExporter::off) ENABLED START -----*/
+
+    try
+    {
+        if(m_server_sp)
+            m_server_sp->stop();
+    }
+    catch(std::exception& ex)
+    {
+        set_state(Tango::FAULT);
+        std::stringstream error_stream;
+        error_stream << "DataExporter::Off() " << ex.what() << std::endl;
+        set_status(error_stream.str());
+    }
+    catch(...)
+    {
+        set_state(Tango::FAULT);
+        set_status("DataExporter::Off() unknown error");
+    }
+
+	/*----- PROTECTED REGION END -----*/	//	DataExporter::off
+}
 
 /*----- PROTECTED REGION ID(DataExporter::namespace_ending) ENABLED START -----*/
 
-//	Additional Methods
+//==============================================================================
+//      DataExporter::importExportedTables()
+//==============================================================================
+void DataExporter::importExportedTables(std::vector<std::string>& exportedTables,
+    std::multimap<const std::string, const std::string>& exportedTablesMap)
+    throw(std::invalid_argument)
+{
+    DEBUG_STREAM << "DataExporter::importExportedTables()  - " << device_name << endl;
+
+    for(unsigned int i=0; i<exportedTables.size(); ++i)
+    {
+        std::size_t found;
+
+        if((found=exportedTables.at(i).find(' ')) == std::string::npos)
+        {
+            std::stringstream errorStream;
+            errorStream << "ExportedTables property has invalid key at "
+                << i << " position" << std::endl;
+            throw std::invalid_argument(errorStream.str());
+        }
+
+        std::string schema = exportedTables.at(i).substr(0, found);
+        std::string table = exportedTables.at(i).substr(found+1, std::string::npos);
+
+        INFO_STREAM << "DataExporter::importExportedTables() schema "
+            << schema << " table " << table << endl;
+
+        exportedTablesMap.insert(std::pair<const std::string, const std::string> (schema, table));
+    }
+}
+
+//==============================================================================
+//      DataExporter::importAuthorisedUsers()
+//==============================================================================
+void DataExporter::importAuthorisedUsers(std::vector<std::string>& authorisedUsers,
+    std::map<const std::string, const std::string>& authorisedUsersMap)
+    throw(std::invalid_argument)
+{
+    DEBUG_STREAM << "DataExporter::importAuthorisedUsers()  - " << device_name << endl;
+
+    for(unsigned int i=0; i<authorisedUsers.size(); ++i)
+    {
+        std::size_t found;
+
+        if((found=authorisedUsers.at(i).find(' ')) == std::string::npos)
+        {
+            std::stringstream errorStream;
+            errorStream << "AuthorisedUsers property has invalid key at "
+                << i << " position" << std::endl;
+            throw std::invalid_argument(errorStream.str());
+        }
+
+        std::string user = authorisedUsers.at(i).substr(0, found);
+        std::string password = authorisedUsers.at(i).substr(found+1, std::string::npos);
+
+        #ifdef VERBOSE_DEBUG
+            INFO_STREAM << "DataExporter::importAuthorisedUsers() user "
+                << user << " password " << password << endl;
+        #endif
+
+        authorisedUsersMap.insert(std::pair<const std::string,
+            const std::string>(user, password));
+    }
+}
+
+//==============================================================================
+//      DataExporter::checkIfFileExists()
+//==============================================================================
+void DataExporter::checkIfFileExists(std::string fileName)
+    throw(std::invalid_argument)
+{
+    DEBUG_STREAM << "DataExporter::checkIfFileExists()  - " << device_name << endl;
+
+    boost::filesystem::path path(fileName);
+
+    if(!boost::filesystem::exists(path))
+    {
+        std::stringstream errorStream;
+        errorStream << "File " << fileName << " not exists" << std::endl;
+        throw std::invalid_argument(errorStream.str());
+    }
+
+    INFO_STREAM << "DataExporter::checkIfFileExists() " << fileName << endl;
+}
+
+//==============================================================================
+//      DataExporter::checkIfFileExists()
+//==============================================================================
+void DataExporter::checkIfDirectoryExists(std::string directoryName)
+    throw(std::invalid_argument)
+{
+    DEBUG_STREAM << "DataExporter::checkIfFileExists()  - " << device_name << endl;
+
+    boost::filesystem::path path(directoryName);
+
+    if(!boost::filesystem::exists(path))
+    {
+        std::stringstream errorStream;
+        errorStream << "Directory " << directoryName << " not exists" << std::endl;
+        throw std::invalid_argument(errorStream.str());
+    }
+
+    if(!boost::filesystem::is_directory(path))
+    {
+        std::stringstream errorStream;
+        errorStream << directoryName << " is not a directory" << std::endl;
+        throw std::invalid_argument(errorStream.str());
+    }
+
+    INFO_STREAM << "DataExporter::checkIfDirectoryExists() " << directoryName << endl;
+}
 
 /*----- PROTECTED REGION END -----*/	//	DataExporter::namespace_ending
 } //	namespace
diff --git a/src/DataExporter.h b/src/DataExporter.h
index 3bc9b4c..0aaf826 100644
--- a/src/DataExporter.h
+++ b/src/DataExporter.h
@@ -8,20 +8,20 @@
 // project :     Data exporter
 //
 // This file is part of Tango device class.
-// 
+//
 // Tango is free software: you can redistribute it and/or modify
 // it under the terms of the GNU General Public License as published by
 // the Free Software Foundation, either version 3 of the License, or
 // (at your option) any later version.
-// 
+//
 // Tango is distributed in the hope that it will be useful,
 // but WITHOUT ANY WARRANTY; without even the implied warranty of
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 // GNU General Public License for more details.
-// 
+//
 // You should have received a copy of the GNU General Public License
 // along with Tango.  If not, see <http://www.gnu.org/licenses/>.
-// 
+//
 // $Author:  $
 //
 // $Revision:  $
@@ -38,6 +38,9 @@
 #ifndef DataExporter_H
 #define DataExporter_H
 
+#include <Configuration.h>
+#include <Server.h>
+
 #include <tango.h>
 
 
@@ -45,7 +48,7 @@
 
 /**
  *  DataExporter class description:
- *    
+ *
  */
 
 namespace DataExporter_ns
@@ -61,10 +64,64 @@ class DataExporter : public TANGO_BASE_CLASS
 
 /*----- PROTECTED REGION ID(DataExporter::Data Members) ENABLED START -----*/
 
-//	Add your own data members
+//------------------------------------------------------------------------------
+//  [Protected] Class variables
+//------------------------------------------------------------------------------
+    //Configuration class shared pointer
+    Configuration::SP m_configuration_sp;
+
+    //Server base class shared pointer
+    Server::SP m_server_sp;
+
+    //Max local port number allowed value
+    static const unsigned int MAX_LOCAL_PORT = 65535;
+
+    //Max number of worker thread allowed
+    static const unsigned int MAX_WORKER_NUMBER = 100;
+
+    //Max number of database connection allowed
+    static const unsigned int MAX_DB_CONNECTION_NUMBER = 100;
+
+    //Max database port number allowed value
+    static const unsigned int MAX_DB_PORT = 65535;
+
 
 /*----- PROTECTED REGION END -----*/	//	DataExporter::Data Members
 
+//	Device property data members
+public:
+	//	CertificateFile:	Absolute path to certificate chain file
+	string	certificateFile;
+	//	PrivateKeyFile:	Absolute path to private key file
+	string	privateKeyFile;
+	//	DHTempFile:	Absolute path to Diffie Hellman temporary file
+	string	dHTempFile;
+	//	ExportedTables:	Tables exported from database: one table per row
+	//  [schema table]
+	vector<string>	exportedTables;
+	//	AuthorisedUsers:	Authorised user list: one user per row
+	//  [username password]
+	vector<string>	authorisedUsers;
+	//	StoragePath:	Absolute path to storage
+	string	storagePath;
+	//	LocalHost:	Local host address for incoming connection
+	string	localHost;
+	//	LocalPort:	Local port for wait incoming connection
+	Tango::DevULong	localPort;
+	//	WorkerNumber:	Number of threads that call io service run methods
+	Tango::DevUShort	workerNumber;
+	//	EnableSSL:	Enable or disable SSL connections
+	Tango::DevBoolean	enableSSL;
+	//	DatabaseHost:	Metadata database host
+	string	databaseHost;
+	//	DatabasePort:	Metadata database port
+	Tango::DevULong	databasePort;
+	//	DatabaseUsername:	Metadata database login username
+	string	databaseUsername;
+	//	DatabasePassword:	Metadata database login password
+	string	databasePassword;
+	//	DatabaseConnectionNumber:	Number of database connection created
+	Tango::DevUShort	databaseConnectionNumber;
 
 
 //	Constructors and destructors
@@ -93,7 +150,7 @@ public:
 	DataExporter(Tango::DeviceClass *cl,const char *s,const char *d);
 	/**
 	 * The device object destructor.
-	 */	
+	 */
 	~DataExporter() {delete_device();};
 
 
@@ -107,6 +164,10 @@ public:
 	 *	Initialize the device
 	 */
 	virtual void init_device();
+	/*
+	 *	Read the device properties from database
+	 */
+	void get_device_property();
 	/*
 	 *	Always executed method before execution command method.
 	 */
@@ -136,11 +197,41 @@ public:
 
 //	Command related methods
 public:
+	/**
+	 *	Command On related method
+	 *	Description: Activate data exporter
+	 *
+	 */
+	virtual void on();
+	virtual bool is_On_allowed(const CORBA::Any &any);
+	/**
+	 *	Command Off related method
+	 *	Description: Deactivate data exporter
+	 *
+	 */
+	virtual void off();
+	virtual bool is_Off_allowed(const CORBA::Any &any);
 
 
 /*----- PROTECTED REGION ID(DataExporter::Additional Method prototypes) ENABLED START -----*/
 
-//	Additional Method prototypes
+//------------------------------------------------------------------------------
+//  [Protected] Utilities methods
+//------------------------------------------------------------------------------
+    virtual void importExportedTables(std::vector<std::string>&,
+        std::multimap<const std::string, const std::string>&)
+        throw(std::invalid_argument);
+
+    virtual void importAuthorisedUsers(std::vector<std::string>&,
+        std::map<const std::string, const std::string>&)
+        throw(std::invalid_argument);
+
+    virtual void checkIfFileExists(std::string)
+        throw(std::invalid_argument);
+
+    virtual void checkIfDirectoryExists(std::string)
+        throw(std::invalid_argument);
+
 
 /*----- PROTECTED REGION END -----*/	//	DataExporter::Additional Method prototypes
 };
diff --git a/src/DataExporter.xmi b/src/DataExporter.xmi
index af83bb6..6d53e1a 100644
--- a/src/DataExporter.xmi
+++ b/src/DataExporter.xmi
@@ -1,10 +1,97 @@
 <?xml version="1.0" encoding="ASCII"?>
 <pogoDsl:PogoSystem xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:pogoDsl="http://www.esrf.fr/tango/pogo/PogoDsl">
   <classes name="DataExporter" pogoRevision="8.1">
-    <description description="" title="Data exporter" sourcePath="/home/mdm/workspace/nadir/data_exporter/src" language="Cpp" filestogenerate="XMI   file,Code files" license="GPL" hasMandatoryProperty="false" hasConcreteProperty="false" hasAbstractCommand="false" hasAbstractAttribute="false">
+    <description description="" title="Data exporter" sourcePath="/home/mdm/workspace/nadir/data_exporter/src" language="Cpp" filestogenerate="XMI   file,Code files" license="GPL" hasMandatoryProperty="false" hasConcreteProperty="true" hasAbstractCommand="false" hasAbstractAttribute="false">
       <inheritances classname="Device_Impl" sourcePath=""/>
       <identification contact="at oats.inaf.it - demarco" author="demarco" emailDomain="oats.inaf.it" classFamily="Communication" siteSpecific="" platform="Unix Like" bus="TCP/UDP" manufacturer="none" reference=""/>
     </description>
+    <classProperties name="CertificateFile" description="Absolute path to certificate chain file">
+      <type xsi:type="pogoDsl:StringType"/>
+      <status abstract="false" inherited="false" concrete="true" concreteHere="true"/>
+    </classProperties>
+    <classProperties name="PrivateKeyFile" description="Absolute path to private key file">
+      <type xsi:type="pogoDsl:StringType"/>
+      <status abstract="false" inherited="false" concrete="true" concreteHere="true"/>
+    </classProperties>
+    <classProperties name="DHTempFile" description="Absolute path to Diffie Hellman temporary file">
+      <type xsi:type="pogoDsl:StringType"/>
+      <status abstract="false" inherited="false" concrete="true" concreteHere="true"/>
+    </classProperties>
+    <classProperties name="ExportedTables" description="Tables exported from database: one table per row&#xA;[schema table]">
+      <type xsi:type="pogoDsl:StringVectorType"/>
+      <status abstract="false" inherited="false" concrete="true" concreteHere="true"/>
+    </classProperties>
+    <classProperties name="AuthorisedUsers" description="Authorised user list: one user per row&#xA;[username password]">
+      <type xsi:type="pogoDsl:StringVectorType"/>
+      <status abstract="false" inherited="false" concrete="true" concreteHere="true"/>
+    </classProperties>
+    <classProperties name="StoragePath" description="Absolute path to storage">
+      <type xsi:type="pogoDsl:StringType"/>
+      <status abstract="false" inherited="false" concrete="true" concreteHere="true"/>
+    </classProperties>
+    <deviceProperties name="CertificateFile" description="Absolute path to certificate chain file">
+      <type xsi:type="pogoDsl:StringType"/>
+      <status abstract="false" inherited="false" concrete="true" concreteHere="true"/>
+    </deviceProperties>
+    <deviceProperties name="PrivateKeyFile" description="Absolute path to private key file">
+      <type xsi:type="pogoDsl:StringType"/>
+      <status abstract="false" inherited="false" concrete="true" concreteHere="true"/>
+    </deviceProperties>
+    <deviceProperties name="DHTempFile" description="Absolute path to Diffie Hellman temporary file">
+      <type xsi:type="pogoDsl:StringType"/>
+      <status abstract="false" inherited="false" concrete="true" concreteHere="true"/>
+    </deviceProperties>
+    <deviceProperties name="ExportedTables" description="Tables exported from database: one table per row&#xA;[schema table]">
+      <type xsi:type="pogoDsl:StringVectorType"/>
+      <status abstract="false" inherited="false" concrete="true" concreteHere="true"/>
+    </deviceProperties>
+    <deviceProperties name="AuthorisedUsers" description="Authorised user list: one user per row&#xA;[username password]">
+      <type xsi:type="pogoDsl:StringVectorType"/>
+      <status abstract="false" inherited="false" concrete="true" concreteHere="true"/>
+    </deviceProperties>
+    <deviceProperties name="StoragePath" description="Absolute path to storage">
+      <type xsi:type="pogoDsl:StringType"/>
+      <status abstract="false" inherited="false" concrete="true" concreteHere="true"/>
+    </deviceProperties>
+    <deviceProperties name="LocalHost" description="Local host address for incoming connection">
+      <type xsi:type="pogoDsl:StringType"/>
+      <status abstract="false" inherited="false" concrete="true" concreteHere="true"/>
+    </deviceProperties>
+    <deviceProperties name="LocalPort" description="Local port for wait incoming connection">
+      <type xsi:type="pogoDsl:UIntType"/>
+      <status abstract="false" inherited="false" concrete="true" concreteHere="true"/>
+    </deviceProperties>
+    <deviceProperties name="WorkerNumber" description="Number of threads that call io service run methods">
+      <type xsi:type="pogoDsl:UShortType"/>
+      <status abstract="false" inherited="false" concrete="true" concreteHere="true"/>
+      <DefaultPropValue>8</DefaultPropValue>
+    </deviceProperties>
+    <deviceProperties name="EnableSSL" description="Enable or disable SSL connections">
+      <type xsi:type="pogoDsl:BooleanType"/>
+      <status abstract="false" inherited="false" concrete="true" concreteHere="true"/>
+      <DefaultPropValue>0</DefaultPropValue>
+    </deviceProperties>
+    <deviceProperties name="DatabaseHost" description="Metadata database host">
+      <type xsi:type="pogoDsl:StringType"/>
+      <status abstract="false" inherited="false" concrete="true" concreteHere="true"/>
+    </deviceProperties>
+    <deviceProperties name="DatabasePort" description="Metadata database port">
+      <type xsi:type="pogoDsl:UIntType"/>
+      <status abstract="false" inherited="false" concrete="true" concreteHere="true"/>
+    </deviceProperties>
+    <deviceProperties name="DatabaseUsername" description="Metadata database login username">
+      <type xsi:type="pogoDsl:StringType"/>
+      <status abstract="false" inherited="false" concrete="true" concreteHere="true"/>
+    </deviceProperties>
+    <deviceProperties name="DatabasePassword" description="Metadata database login password">
+      <type xsi:type="pogoDsl:StringType"/>
+      <status abstract="false" inherited="false" concrete="true" concreteHere="true"/>
+    </deviceProperties>
+    <deviceProperties name="DatabaseConnectionNumber" description="Number of database connection created">
+      <type xsi:type="pogoDsl:UShortType"/>
+      <status abstract="false" inherited="false" concrete="true" concreteHere="true"/>
+      <DefaultPropValue>2</DefaultPropValue>
+    </deviceProperties>
     <commands name="State" description="This command gets the device state (stored in its device_state data member) and returns it to the caller." execMethod="dev_state" displayLevel="OPERATOR" polledPeriod="0">
       <argin description="none">
         <type xsi:type="pogoDsl:VoidType"/>
@@ -23,6 +110,33 @@
       </argout>
       <status abstract="true" inherited="true" concrete="true"/>
     </commands>
+    <commands name="On" description="Activate data exporter" execMethod="on" displayLevel="OPERATOR" polledPeriod="0">
+      <argin description="">
+        <type xsi:type="pogoDsl:VoidType"/>
+      </argin>
+      <argout description="">
+        <type xsi:type="pogoDsl:VoidType"/>
+      </argout>
+      <status abstract="false" inherited="false" concrete="true" concreteHere="true"/>
+    </commands>
+    <commands name="Off" description="Deactivate data exporter" execMethod="off" displayLevel="OPERATOR" polledPeriod="0">
+      <argin description="">
+        <type xsi:type="pogoDsl:VoidType"/>
+      </argin>
+      <argout description="">
+        <type xsi:type="pogoDsl:VoidType"/>
+      </argout>
+      <status abstract="false" inherited="false" concrete="true" concreteHere="true"/>
+    </commands>
+    <states name="ON" description="Data exporter is in ON state (ready to incoming connections)">
+      <status abstract="false" inherited="false" concrete="true" concreteHere="true"/>
+    </states>
+    <states name="OFF" description="Data exporter is in OFF state (not ready for incoming connections)">
+      <status abstract="false" inherited="false" concrete="true" concreteHere="true"/>
+    </states>
+    <states name="FAULT" description="Data exporter is in FAULT state (an error occurred)">
+      <status abstract="false" inherited="false" concrete="true" concreteHere="true"/>
+    </states>
     <preferences docHome="./doc_html" makefileHome="/usr/local/tango-8.1.2/share/pogo/preferences"/>
   </classes>
 </pogoDsl:PogoSystem>
diff --git a/src/DataExporterClass.cpp b/src/DataExporterClass.cpp
index ab3dbab..76a8754 100644
--- a/src/DataExporterClass.cpp
+++ b/src/DataExporterClass.cpp
@@ -85,6 +85,7 @@ DataExporterClass::DataExporterClass(string &s):Tango::DeviceClass(s)
 {
 	cout2 << "Entering DataExporterClass constructor" << endl;
 	set_default_property();
+	get_class_property();
 	write_class_property();
 
 	/*----- PROTECTED REGION ID(DataExporterClass::constructor) ENABLED START -----*/
@@ -158,6 +159,42 @@ DataExporterClass *DataExporterClass::instance()
 //===================================================================
 //	Command execution method calls
 //===================================================================
+//--------------------------------------------------------
+/**
+ * method : 		OnClass::execute()
+ * description : 	method to trigger the execution of the command.
+ *
+ * @param	device	The device on which the command must be executed
+ * @param	in_any	The command input data
+ *
+ *	returns The command output data (packed in the Any object)
+ */
+//--------------------------------------------------------
+CORBA::Any *OnClass::execute(Tango::DeviceImpl *device, TANGO_UNUSED(const CORBA::Any &in_any))
+{
+	cout2 << "OnClass::execute(): arrived" << endl;
+	((static_cast<DataExporter *>(device))->on());
+	return new CORBA::Any();
+}
+
+//--------------------------------------------------------
+/**
+ * method : 		OffClass::execute()
+ * description : 	method to trigger the execution of the command.
+ *
+ * @param	device	The device on which the command must be executed
+ * @param	in_any	The command input data
+ *
+ *	returns The command output data (packed in the Any object)
+ */
+//--------------------------------------------------------
+CORBA::Any *OffClass::execute(Tango::DeviceImpl *device, TANGO_UNUSED(const CORBA::Any &in_any))
+{
+	cout2 << "OffClass::execute(): arrived" << endl;
+	((static_cast<DataExporter *>(device))->off());
+	return new CORBA::Any();
+}
+
 
 //===================================================================
 //	Properties management
@@ -207,6 +244,112 @@ Tango::DbDatum DataExporterClass::get_default_class_property(string &prop_name)
 	return Tango::DbDatum(prop_name);
 }
 
+//--------------------------------------------------------
+/**
+ *	Method      : DataExporterClass::get_class_property()
+ *	Description : Read database to initialize class property data members.
+ */
+//--------------------------------------------------------
+void DataExporterClass::get_class_property()
+{
+	/*----- PROTECTED REGION ID(DataExporterClass::get_class_property_before) ENABLED START -----*/
+	
+	//	Initialize class property data members
+	
+	/*----- PROTECTED REGION END -----*/	//	DataExporterClass::get_class_property_before
+	//	Read class properties from database.
+	cl_prop.push_back(Tango::DbDatum("CertificateFile"));
+	cl_prop.push_back(Tango::DbDatum("PrivateKeyFile"));
+	cl_prop.push_back(Tango::DbDatum("DHTempFile"));
+	cl_prop.push_back(Tango::DbDatum("ExportedTables"));
+	cl_prop.push_back(Tango::DbDatum("AuthorisedUsers"));
+	cl_prop.push_back(Tango::DbDatum("StoragePath"));
+	
+	//	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;
+
+	//	Try to extract CertificateFile value
+	if (cl_prop[++i].is_empty()==false)	cl_prop[i]  >>  certificateFile;
+	else
+	{
+		//	Check default value for CertificateFile
+		def_prop = get_default_class_property(cl_prop[i].name);
+		if (def_prop.is_empty()==false)
+		{
+			def_prop    >>  certificateFile;
+			cl_prop[i]  <<  certificateFile;
+		}
+	}
+	//	Try to extract PrivateKeyFile value
+	if (cl_prop[++i].is_empty()==false)	cl_prop[i]  >>  privateKeyFile;
+	else
+	{
+		//	Check default value for PrivateKeyFile
+		def_prop = get_default_class_property(cl_prop[i].name);
+		if (def_prop.is_empty()==false)
+		{
+			def_prop    >>  privateKeyFile;
+			cl_prop[i]  <<  privateKeyFile;
+		}
+	}
+	//	Try to extract DHTempFile value
+	if (cl_prop[++i].is_empty()==false)	cl_prop[i]  >>  dHTempFile;
+	else
+	{
+		//	Check default value for DHTempFile
+		def_prop = get_default_class_property(cl_prop[i].name);
+		if (def_prop.is_empty()==false)
+		{
+			def_prop    >>  dHTempFile;
+			cl_prop[i]  <<  dHTempFile;
+		}
+	}
+	//	Try to extract ExportedTables value
+	if (cl_prop[++i].is_empty()==false)	cl_prop[i]  >>  exportedTables;
+	else
+	{
+		//	Check default value for ExportedTables
+		def_prop = get_default_class_property(cl_prop[i].name);
+		if (def_prop.is_empty()==false)
+		{
+			def_prop    >>  exportedTables;
+			cl_prop[i]  <<  exportedTables;
+		}
+	}
+	//	Try to extract AuthorisedUsers value
+	if (cl_prop[++i].is_empty()==false)	cl_prop[i]  >>  authorisedUsers;
+	else
+	{
+		//	Check default value for AuthorisedUsers
+		def_prop = get_default_class_property(cl_prop[i].name);
+		if (def_prop.is_empty()==false)
+		{
+			def_prop    >>  authorisedUsers;
+			cl_prop[i]  <<  authorisedUsers;
+		}
+	}
+	//	Try to extract StoragePath value
+	if (cl_prop[++i].is_empty()==false)	cl_prop[i]  >>  storagePath;
+	else
+	{
+		//	Check default value for StoragePath
+		def_prop = get_default_class_property(cl_prop[i].name);
+		if (def_prop.is_empty()==false)
+		{
+			def_prop    >>  storagePath;
+			cl_prop[i]  <<  storagePath;
+		}
+	}
+	/*----- PROTECTED REGION ID(DataExporterClass::get_class_property_after) ENABLED START -----*/
+	
+	//	Check class property data members init
+	
+	/*----- PROTECTED REGION END -----*/	//	DataExporterClass::get_class_property_after
+
+}
 
 //--------------------------------------------------------
 /**
@@ -225,8 +368,284 @@ void DataExporterClass::set_default_property()
 	vector<string>	vect_data;
 
 	//	Set Default Class Properties
+	prop_name = "CertificateFile";
+	prop_desc = "Absolute path to certificate chain file";
+	prop_def  = "";
+	vect_data.clear();
+	if (prop_def.length()>0)
+	{
+		Tango::DbDatum	data(prop_name);
+		data << vect_data ;
+		cl_def_prop.push_back(data);
+		add_wiz_class_prop(prop_name, prop_desc,  prop_def);
+	}
+	else
+		add_wiz_class_prop(prop_name, prop_desc);
+	prop_name = "PrivateKeyFile";
+	prop_desc = "Absolute path to private key file";
+	prop_def  = "";
+	vect_data.clear();
+	if (prop_def.length()>0)
+	{
+		Tango::DbDatum	data(prop_name);
+		data << vect_data ;
+		cl_def_prop.push_back(data);
+		add_wiz_class_prop(prop_name, prop_desc,  prop_def);
+	}
+	else
+		add_wiz_class_prop(prop_name, prop_desc);
+	prop_name = "DHTempFile";
+	prop_desc = "Absolute path to Diffie Hellman temporary file";
+	prop_def  = "";
+	vect_data.clear();
+	if (prop_def.length()>0)
+	{
+		Tango::DbDatum	data(prop_name);
+		data << vect_data ;
+		cl_def_prop.push_back(data);
+		add_wiz_class_prop(prop_name, prop_desc,  prop_def);
+	}
+	else
+		add_wiz_class_prop(prop_name, prop_desc);
+	prop_name = "ExportedTables";
+	prop_desc = "Tables exported from database: one table per row\n[schema table]";
+	prop_def  = "";
+	vect_data.clear();
+	if (prop_def.length()>0)
+	{
+		Tango::DbDatum	data(prop_name);
+		data << vect_data ;
+		cl_def_prop.push_back(data);
+		add_wiz_class_prop(prop_name, prop_desc,  prop_def);
+	}
+	else
+		add_wiz_class_prop(prop_name, prop_desc);
+	prop_name = "AuthorisedUsers";
+	prop_desc = "Authorised user list: one user per row\n[username password]";
+	prop_def  = "";
+	vect_data.clear();
+	if (prop_def.length()>0)
+	{
+		Tango::DbDatum	data(prop_name);
+		data << vect_data ;
+		cl_def_prop.push_back(data);
+		add_wiz_class_prop(prop_name, prop_desc,  prop_def);
+	}
+	else
+		add_wiz_class_prop(prop_name, prop_desc);
+	prop_name = "StoragePath";
+	prop_desc = "Absolute path to storage";
+	prop_def  = "";
+	vect_data.clear();
+	if (prop_def.length()>0)
+	{
+		Tango::DbDatum	data(prop_name);
+		data << vect_data ;
+		cl_def_prop.push_back(data);
+		add_wiz_class_prop(prop_name, prop_desc,  prop_def);
+	}
+	else
+		add_wiz_class_prop(prop_name, prop_desc);
 
 	//	Set Default device Properties
+	prop_name = "CertificateFile";
+	prop_desc = "Absolute path to certificate chain file";
+	prop_def  = "";
+	vect_data.clear();
+	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);
+	prop_name = "PrivateKeyFile";
+	prop_desc = "Absolute path to private key file";
+	prop_def  = "";
+	vect_data.clear();
+	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);
+	prop_name = "DHTempFile";
+	prop_desc = "Absolute path to Diffie Hellman temporary file";
+	prop_def  = "";
+	vect_data.clear();
+	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);
+	prop_name = "ExportedTables";
+	prop_desc = "Tables exported from database: one table per row\n[schema table]";
+	prop_def  = "";
+	vect_data.clear();
+	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);
+	prop_name = "AuthorisedUsers";
+	prop_desc = "Authorised user list: one user per row\n[username password]";
+	prop_def  = "";
+	vect_data.clear();
+	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);
+	prop_name = "StoragePath";
+	prop_desc = "Absolute path to storage";
+	prop_def  = "";
+	vect_data.clear();
+	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);
+	prop_name = "LocalHost";
+	prop_desc = "Local host address for incoming connection";
+	prop_def  = "";
+	vect_data.clear();
+	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);
+	prop_name = "LocalPort";
+	prop_desc = "Local port for wait incoming connection";
+	prop_def  = "";
+	vect_data.clear();
+	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);
+	prop_name = "WorkerNumber";
+	prop_desc = "Number of threads that call io service run methods";
+	prop_def  = "8";
+	vect_data.clear();
+	vect_data.push_back("8");
+	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);
+	prop_name = "EnableSSL";
+	prop_desc = "Enable or disable SSL connections";
+	prop_def  = "0";
+	vect_data.clear();
+	vect_data.push_back("0");
+	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);
+	prop_name = "DatabaseHost";
+	prop_desc = "Metadata database host";
+	prop_def  = "";
+	vect_data.clear();
+	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);
+	prop_name = "DatabasePort";
+	prop_desc = "Metadata database port";
+	prop_def  = "";
+	vect_data.clear();
+	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);
+	prop_name = "DatabaseUsername";
+	prop_desc = "Metadata database login username";
+	prop_def  = "";
+	vect_data.clear();
+	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);
+	prop_name = "DatabasePassword";
+	prop_desc = "Metadata database login password";
+	prop_def  = "";
+	vect_data.clear();
+	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);
+	prop_name = "DatabaseConnectionNumber";
+	prop_desc = "Number of database connection created";
+	prop_def  = "2";
+	vect_data.clear();
+	vect_data.push_back("2");
+	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);
 }
 
 //--------------------------------------------------------
@@ -455,6 +874,24 @@ void DataExporterClass::command_factory()
 	/*----- PROTECTED REGION END -----*/	//	DataExporterClass::command_factory_before
 
 
+	//	Command On
+	OnClass	*pOnCmd =
+		new OnClass("On",
+			Tango::DEV_VOID, Tango::DEV_VOID,
+			"",
+			"",
+			Tango::OPERATOR);
+	command_list.push_back(pOnCmd);
+
+	//	Command Off
+	OffClass	*pOffCmd =
+		new OffClass("Off",
+			Tango::DEV_VOID, Tango::DEV_VOID,
+			"",
+			"",
+			Tango::OPERATOR);
+	command_list.push_back(pOffCmd);
+
 	/*----- PROTECTED REGION ID(DataExporterClass::command_factory_after) ENABLED START -----*/
 	
 	//	Add your own code
diff --git a/src/DataExporterClass.h b/src/DataExporterClass.h
index eae172a..86bd2c2 100644
--- a/src/DataExporterClass.h
+++ b/src/DataExporterClass.h
@@ -56,6 +56,56 @@ namespace DataExporter_ns
 
 /*----- PROTECTED REGION END -----*/	//	DataExporterClass::classes for dynamic creation
 
+//=========================================
+//	Define classes for commands
+//=========================================
+//	Command On class definition
+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<DataExporter *>(dev))->is_On_allowed(any);}
+};
+
+//	Command Off class definition
+class OffClass : public Tango::Command
+{
+public:
+	OffClass(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)	{};
+
+	OffClass(const char   *name,
+	               Tango::CmdArgType in,
+				   Tango::CmdArgType out)
+	:Command(name,in,out)	{};
+	~OffClass() {};
+	
+	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<DataExporter *>(dev))->is_Off_allowed(any);}
+};
+
+
 /**
  *	The DataExporterClass singleton definition
  */
@@ -71,6 +121,22 @@ class DataExporterClass : public Tango::DeviceClass
 	
 	/*----- PROTECTED REGION END -----*/	//	DataExporterClass::Additionnal DServer data members
 
+	//	Class properties data members
+	public:
+		//	CertificateFile:	Absolute path to certificate chain file
+		string	certificateFile;
+		//	PrivateKeyFile:	Absolute path to private key file
+		string	privateKeyFile;
+		//	DHTempFile:	Absolute path to Diffie Hellman temporary file
+		string	dHTempFile;
+		//	ExportedTables:	Tables exported from database: one table per row
+		//  [schema table]
+		vector<string>	exportedTables;
+		//	AuthorisedUsers:	Authorised user list: one user per row
+		//  [username password]
+		vector<string>	authorisedUsers;
+		//	StoragePath:	Absolute path to storage
+		string	storagePath;
 	public:
 		//	write class properties data members
 		Tango::DbData	cl_prop;
diff --git a/src/DataExporterStateMachine.cpp b/src/DataExporterStateMachine.cpp
index 6029d4e..09afe08 100644
--- a/src/DataExporterStateMachine.cpp
+++ b/src/DataExporterStateMachine.cpp
@@ -42,6 +42,9 @@ static const char *RcsId = "$Id:  $";
 //================================================================
 //  States  |  Description
 //================================================================
+//  ON      |  Data exporter is in ON state (ready to incoming connections)
+//  OFF     |  Data exporter is in OFF state (not ready for incoming connections)
+//  FAULT   |  Data exporter is in FAULT state (an error occurred)
 
 
 namespace DataExporter_ns
@@ -54,4 +57,34 @@ namespace DataExporter_ns
 //		Commands Allowed Methods
 //=================================================
 
+//--------------------------------------------------------
+/**
+ *	Method      : DataExporter::is_On_allowed()
+ *	Description : Execution allowed for On attribute
+ */
+//--------------------------------------------------------
+bool DataExporter::is_On_allowed(TANGO_UNUSED(const CORBA::Any &any))
+{
+	//	Not any excluded states for On command.
+	/*----- PROTECTED REGION ID(DataExporter::OnStateAllowed) ENABLED START -----*/
+	
+	/*----- PROTECTED REGION END -----*/	//	DataExporter::OnStateAllowed
+	return true;
+}
+
+//--------------------------------------------------------
+/**
+ *	Method      : DataExporter::is_Off_allowed()
+ *	Description : Execution allowed for Off attribute
+ */
+//--------------------------------------------------------
+bool DataExporter::is_Off_allowed(TANGO_UNUSED(const CORBA::Any &any))
+{
+	//	Not any excluded states for Off command.
+	/*----- PROTECTED REGION ID(DataExporter::OffStateAllowed) ENABLED START -----*/
+	
+	/*----- PROTECTED REGION END -----*/	//	DataExporter::OffStateAllowed
+	return true;
+}
+
 }	//	End of namespace
diff --git a/src/PlainServer.cpp b/src/PlainServer.cpp
new file mode 100644
index 0000000..22c083e
--- /dev/null
+++ b/src/PlainServer.cpp
@@ -0,0 +1,52 @@
+#include <PlainServer.h>
+#include <PlainSession.h>
+
+namespace DataExporter_ns
+{
+
+//==============================================================================
+//      PlainServer::PlainServer()
+//==============================================================================
+PlainServer::PlainServer(Tango::DeviceImpl* deviceImpl_p,
+    Configuration::SP configuration_sp) :
+    Server::Server(deviceImpl_p, configuration_sp)
+{
+    DEBUG_STREAM << "PlainServer::PlainServer()" << endl;
+}
+
+//==============================================================================
+//      PlainServer::~PlainServer()
+//==============================================================================
+PlainServer::~PlainServer()
+{
+    DEBUG_STREAM << "PlainServer::~PlainServer()" << endl;
+}
+
+//==============================================================================
+//      PlainServer::create()
+//==============================================================================
+Server::SP PlainServer::create(Tango::DeviceImpl* deviceImpl_p,
+    Configuration::SP configuration_sp)
+{
+    Server::SP s_sp(new PlainServer(deviceImpl_p, configuration_sp),
+        PlainServer::Deleter());
+
+    return s_sp;
+}
+
+//==============================================================================
+//      PlainServer::startAccept()
+//==============================================================================
+void PlainServer::startAccept()
+{
+    DEBUG_STREAM << "PlainServer::startAccept()" << endl;
+
+    Session::SP session_sp = PlainSession::create(m_deviceImpl_p,
+        m_configuration_sp, m_dBManager_sp, m_ioService_sp);
+
+    m_acceptor_sp->async_accept(session_sp->getSocket(),
+        boost::bind(&PlainServer::handleAccept, this,
+        session_sp, boost::asio::placeholders::error));
+}
+
+}   //namespace
diff --git a/src/PlainServer.h b/src/PlainServer.h
new file mode 100644
index 0000000..f3655b6
--- /dev/null
+++ b/src/PlainServer.h
@@ -0,0 +1,42 @@
+#ifndef PLAINSERVER_H
+#define	PLAINSERVER_H
+
+#include <Server.h>
+#include <Configuration.h>
+
+namespace DataExporter_ns
+{
+
+class PlainServer : public Server
+{
+//------------------------------------------------------------------------------
+//	[Protected] Constructor destructor deleter
+//------------------------------------------------------------------------------
+    PlainServer(Tango::DeviceImpl*, Configuration::SP);
+
+    virtual ~PlainServer();
+
+    class Deleter;
+    friend Deleter;
+    class Deleter
+    {
+	public:
+		void operator()(PlainServer* d) { delete d; }
+    };
+
+public:
+//------------------------------------------------------------------------------
+//	[Public] Class creation method
+//------------------------------------------------------------------------------
+    static Server::SP create(Tango::DeviceImpl*, Configuration::SP);
+
+//------------------------------------------------------------------------------
+//  [Protected] Incoming connection method
+//------------------------------------------------------------------------------
+    virtual void startAccept();
+};
+
+}   //End of namespace
+
+#endif	/* PLAINSERVER_H */
+
diff --git a/src/PlainSession.cpp b/src/PlainSession.cpp
new file mode 100644
index 0000000..c429da0
--- /dev/null
+++ b/src/PlainSession.cpp
@@ -0,0 +1,161 @@
+#include <PlainSession.h>
+
+#include <boost/bind.hpp>
+#include <boost/lexical_cast.hpp>
+
+namespace DataExporter_ns
+{
+
+//==============================================================================
+//      PlainSession::PlainSession()
+//==============================================================================
+PlainSession::PlainSession(Tango::DeviceImpl* deviceImpl_p,
+    Configuration::SP configuration_sp, DBManager::SP dBManager_sp,
+    boost::shared_ptr<boost::asio::io_service> ioService_sp) :
+    Session::Session(deviceImpl_p,configuration_sp, dBManager_sp, ioService_sp),
+    m_plainSocket(*ioService_sp)
+{
+    DEBUG_STREAM << "PlainSession::PlainSession()" << endl;
+}
+
+//==============================================================================
+//      PlainSession::~PlainSession()
+//==============================================================================
+PlainSession::~PlainSession()
+{
+    DEBUG_STREAM << "PlainSession::~PlainSession()" << endl;
+
+    INFO_STREAM << "PlainSession::~PlainSession() Disconnection from "
+        << m_remoteEndpoint << endl;
+
+    boost::system::error_code errorCode;
+
+    m_plainSocket.shutdown(boost::asio::ip::tcp::socket::shutdown_both, errorCode);
+
+    m_plainSocket.close(errorCode);
+}
+
+//==============================================================================
+//      PlainSession::create()
+//==============================================================================
+Session::SP PlainSession::create(Tango::DeviceImpl* deviceImpl_p,
+    Configuration::SP configuration_sp, DBManager::SP dBManager_sp,
+    boost::shared_ptr<boost::asio::io_service> ioService_sp)
+{
+    Session::SP s_sp(new PlainSession(deviceImpl_p, configuration_sp,
+    dBManager_sp, ioService_sp), PlainSession::Deleter());
+
+    return s_sp;
+}
+
+//==============================================================================
+//      PlainSession::getSocket()
+//==============================================================================
+boost::asio::ip::tcp::socket& PlainSession::getSocket()
+{
+    DEBUG_STREAM << "PlainSession::getSocket()" << endl;
+
+    return m_plainSocket;
+}
+
+//==============================================================================
+//      PlainSession::start()
+//==============================================================================
+void PlainSession::start()
+{
+    DEBUG_STREAM << "PlainSession::start()" << endl;
+
+//    m_remoteEndpoint = boost::lexical_cast<std::string>(
+//        m_plainSocket.remote_endpoint());
+//
+//    INFO_STREAM << "PlainSession::start() Connection from "
+//        << m_remoteEndpoint << endl;
+//
+//    m_protocolManager_sp->setRemoteEndpoint(m_remoteEndpoint);
+//
+//    startReadRequestHeader();
+}
+
+////==============================================================================
+////      PlainSession::startReadRequestHeader()
+////==============================================================================
+//void PlainSession::startReadRequestHeader()
+//{
+//        DEBUG_STREAM << "PlainSession::startReadRequestHeader()" << endl;
+//
+//        m_readBuff.resize(HEADER_SIZE);
+//
+//        boost::asio::async_read(m_plainSocket, boost::asio::buffer(m_readBuff),
+//            m_strand.wrap(boost::bind(&PlainSession::handleReadRequestHeader,
+//            shared_from_this(), boost::asio::placeholders::error)));
+//}
+//
+////==============================================================================
+////      PlainSession::startReadRequestBody()
+////==============================================================================
+//void PlainSession::startReadRequestBody(boost::uint32_t bodySize)
+//{
+//    DEBUG_STREAM << "PlainSession::startReadRequestBody()" << endl;
+//
+//    m_readBuff.resize(HEADER_SIZE + bodySize);
+//
+//    boost::asio::mutable_buffers_1 mutableBuffer =
+//        boost::asio::buffer(&m_readBuff[HEADER_SIZE], bodySize);
+//
+//    #ifdef VERBOSE_DEBUG
+//        INFO_STREAM << "PlainSession::startReadRequestBody() "
+//            << m_remoteEndpoint << " >>>> " << bodySize << " BYTE" << endl;
+//    #endif
+//
+//    boost::asio::async_read(m_plainSocket, mutableBuffer,
+//        m_strand.wrap(boost::bind(&PlainSession::handleReadRequestBody,
+//        shared_from_this(), boost::asio::placeholders::error)));
+//}
+//
+////==============================================================================
+////      PlainSession::startWriteResponse()
+////==============================================================================
+//void PlainSession::startWriteResponse()
+//{
+//    DEBUG_STREAM << "PlainSession::startWriteResponse()" << endl;
+//
+//    try
+//    {
+//        RequestSP request_sp(new Request);
+//
+//        request_sp->ParseFromArray(&m_readBuff[HEADER_SIZE], m_readBuff.size() - HEADER_SIZE);
+//
+//        ResponseSP response_sp = m_protocolManager_sp->prepareResponse(request_sp);
+//
+//        boost::uint32_t bodySize = response_sp->ByteSize();
+//
+//        std::vector<boost::uint8_t> writeBuff;
+//        writeBuff.resize(HEADER_SIZE + bodySize);
+//
+//        encodeHeader(writeBuff, bodySize);
+//
+//        response_sp->SerializeToArray(&writeBuff[HEADER_SIZE], bodySize);
+//
+//        #ifdef VERBOSE_DEBUG
+//            INFO_STREAM << "PlainSession::startWriteResponse() "
+//                << m_remoteEndpoint << " <<<< " << bodySize << " byte" << endl;
+//        #endif
+//
+//        boost::asio::async_write(m_plainSocket, boost::asio::buffer(writeBuff),
+//            m_strand.wrap(boost::bind(&PlainSession::handleWriteResponse,
+//                shared_from_this(), boost::asio::placeholders::error)));
+//    }
+//    catch(std::exception& ec)
+//    {
+//        ERROR_STREAM << "SSLSession::startWriteResponse() "
+//            << ec.what() << " from " << m_remoteEndpoint << endl;
+//    }
+//    catch(...)
+//    {
+//        ERROR_STREAM << "SSLSession::startWriteResponse() unknown error from "
+//            << m_remoteEndpoint << endl;
+//
+//    }
+//}
+
+}   //namespace
\ No newline at end of file
diff --git a/src/PlainSession.h b/src/PlainSession.h
new file mode 100644
index 0000000..ea76008
--- /dev/null
+++ b/src/PlainSession.h
@@ -0,0 +1,67 @@
+#ifndef PLAINSESSION_H
+#define	PLAINSESSION_H
+
+#include <Session.h>
+
+#include <tango.h>
+
+#include <boost/enable_shared_from_this.hpp>
+
+namespace DataExporter_ns
+{
+
+class PlainSession : public Session,
+    public boost::enable_shared_from_this<PlainSession>
+{
+protected:
+//------------------------------------------------------------------------------
+//	[Protected] Constructor destructor deleter
+//------------------------------------------------------------------------------
+    PlainSession(Tango::DeviceImpl*, Configuration::SP, DBManager::SP,
+        boost::shared_ptr<boost::asio::io_service>);
+
+    virtual ~PlainSession();
+
+    class Deleter;
+    friend Deleter;
+    class Deleter
+    {
+	public:
+		void operator()(PlainSession* d) { delete d; }
+    };
+
+public:
+//------------------------------------------------------------------------------
+//	[Public] Class creation method
+//------------------------------------------------------------------------------
+    static Session::SP create(Tango::DeviceImpl*, Configuration::SP,
+        DBManager::SP, boost::shared_ptr<boost::asio::io_service>);
+
+//------------------------------------------------------------------------------
+//	[Public] Incoming connection methods
+//------------------------------------------------------------------------------
+    virtual boost::asio::ip::tcp::socket& getSocket();
+
+    virtual void start();
+
+protected:
+////------------------------------------------------------------------------------
+////  [Protected] Request response methods
+////------------------------------------------------------------------------------
+//    virtual void startReadRequestHeader();
+//
+//    virtual void startReadRequestBody(boost::uint32_t);
+//
+//    virtual void startWriteResponse();
+
+//------------------------------------------------------------------------------
+//	[Protected] Class variables
+//------------------------------------------------------------------------------
+    //TCP socket object
+    boost::asio::ip::tcp::socket m_plainSocket;
+};
+
+}   //End of namespace
+
+#endif	/* PLAINSESSION_H */
+
diff --git a/src/SSLServer.cpp b/src/SSLServer.cpp
new file mode 100644
index 0000000..4bc67ff
--- /dev/null
+++ b/src/SSLServer.cpp
@@ -0,0 +1,87 @@
+#include <SSLServer.h>
+#include <SSLSession.h>
+
+#include <boost/bind.hpp>
+
+namespace DataExporter_ns
+{
+
+//==============================================================================
+//      SSLServer::SSLServer()
+//==============================================================================
+SSLServer::SSLServer(Tango::DeviceImpl* deviceImpl_p,
+    Configuration::SP configuration_sp) :
+    Server::Server(deviceImpl_p, configuration_sp)
+{
+    DEBUG_STREAM << "SSLServer::SSLServer()" << endl;
+
+    m_context_sp.reset(new boost::asio::ssl::context(*m_ioService_sp,
+        boost::asio::ssl::context::sslv23));
+
+    m_context_sp->set_options(boost::asio::ssl::context::default_workarounds |
+        boost::asio::ssl::context::no_sslv2 |
+        boost::asio::ssl::context::single_dh_use);
+
+    //@todo: ssl certificate password
+    m_context_sp->set_password_callback(boost::bind(&SSLServer::getPassword, this));
+
+    std::string certificateFile = m_configuration_sp->getCertificateFile();
+    std::string privateKey = m_configuration_sp->getPrivateKeyFile();
+    std::string dHTempFile = m_configuration_sp->getDHTempFile();
+
+    INFO_STREAM << "SSLServer::SSLServer() Certificate " << certificateFile << endl;
+    INFO_STREAM << "SSLServer::SSLServer() Private key " << privateKey << endl;
+    INFO_STREAM << "SSLServer::SSLServer() DH Temporary " << dHTempFile << endl;
+
+    //@todo: check error_code  use in load file methods
+    m_context_sp->use_certificate_chain_file(certificateFile);
+    m_context_sp->use_private_key_file(privateKey, boost::asio::ssl::context::pem);
+    m_context_sp->use_tmp_dh_file(dHTempFile);
+}
+
+//==============================================================================
+//      SSLServer::~SSLServer()
+//==============================================================================
+SSLServer::~SSLServer()
+{
+    DEBUG_STREAM << "SSLServer::~SSLServer()" << endl;
+}
+
+//==============================================================================
+//      SSLServer::create()
+//==============================================================================
+Server::SP SSLServer::create(Tango::DeviceImpl* deviceImpl_p,
+    Configuration::SP configuration_sp)
+{
+    Server::SP s_sp(new SSLServer(deviceImpl_p, configuration_sp),
+        SSLServer::Deleter());
+
+    return s_sp;
+}
+
+//==============================================================================
+//      SSLServer::startAccept()
+//==============================================================================
+void SSLServer::startAccept()
+{
+    DEBUG_STREAM << "SSLServer::startAccept()" << endl;
+
+    Session::SP session_sp = SSLSession::create(m_deviceImpl_p,
+        m_configuration_sp, m_dBManager_sp, m_ioService_sp, m_context_sp);
+
+    m_acceptor_sp->async_accept(session_sp->getSocket(),
+        boost::bind(&SSLServer::handleAccept, this,
+        session_sp, boost::asio::placeholders::error));
+}
+
+//==============================================================================
+//      SSLServer::startAccept()
+//==============================================================================
+std::string SSLServer::getPassword()
+{
+    DEBUG_STREAM << "SSLServer::getPassword()" << endl;
+
+    return "test";
+}
+
+}   //namespace
diff --git a/src/SSLServer.h b/src/SSLServer.h
new file mode 100644
index 0000000..db74b71
--- /dev/null
+++ b/src/SSLServer.h
@@ -0,0 +1,56 @@
+#ifndef SSLSERVER_H
+#define	SSLSERVER_H
+
+#include <Server.h>
+#include <Configuration.h>
+
+#include <boost/asio/ssl.hpp>
+
+namespace DataExporter_ns
+{
+
+class SSLServer : public Server
+{
+//------------------------------------------------------------------------------
+//	[Protected] Constructor destructor deleter
+//------------------------------------------------------------------------------
+    SSLServer(Tango::DeviceImpl*, Configuration::SP);
+
+    virtual ~SSLServer();
+
+    class Deleter;
+    friend Deleter;
+    class Deleter
+    {
+	public:
+		void operator()(SSLServer* d) { delete d; }
+    };
+
+public:
+//------------------------------------------------------------------------------
+//	[Public] Class creation method
+//------------------------------------------------------------------------------
+    static Server::SP create(Tango::DeviceImpl*, Configuration::SP);
+
+//------------------------------------------------------------------------------
+//  [Protected] Incoming connection method
+//------------------------------------------------------------------------------
+    virtual void startAccept();
+
+protected:
+//------------------------------------------------------------------------------
+//  [Protected] Utilities methods
+//------------------------------------------------------------------------------
+    virtual std::string getPassword();
+
+//------------------------------------------------------------------------------
+//	[Protected] Class variables
+//------------------------------------------------------------------------------
+    //SSL context shared pointer
+    boost::shared_ptr<boost::asio::ssl::context> m_context_sp;
+};
+
+}   //End of namespace
+
+#endif	/* SSLSERVER_H */
+
diff --git a/src/SSLSession.cpp b/src/SSLSession.cpp
new file mode 100644
index 0000000..d971949
--- /dev/null
+++ b/src/SSLSession.cpp
@@ -0,0 +1,196 @@
+#include <SSLSession.h>
+
+#include <boost/bind.hpp>
+#include <boost/lexical_cast.hpp>
+
+namespace DataExporter_ns
+{
+
+//==============================================================================
+//      SSLSession::SSLSession()
+//==============================================================================
+SSLSession::SSLSession(Tango::DeviceImpl* deviceImpl_p,
+    Configuration::SP configuration_sp, DBManager::SP dBManager_sp,
+    boost::shared_ptr<boost::asio::io_service> ioService_sp,
+    boost::shared_ptr<boost::asio::ssl::context> context_sp) :
+    Session::Session(deviceImpl_p, configuration_sp, dBManager_sp, ioService_sp),
+    m_sslSocket(*ioService_sp, *context_sp)
+{
+    DEBUG_STREAM << "SSLSession::SSLSession()" << endl;
+}
+
+//==============================================================================
+//      SSLSession::~SSLSession()
+//==============================================================================
+SSLSession::~SSLSession()
+{
+    DEBUG_STREAM << "SSLSession::~SSLSession()" << endl;
+
+    INFO_STREAM << "SSLSession::~SSLSession() Disconnection from "
+        << m_remoteEndpoint << endl;
+
+    boost::system::error_code errorCode;
+
+    m_sslSocket.shutdown(errorCode);
+
+    m_sslSocket.lowest_layer().shutdown(
+        boost::asio::ip::tcp::socket::shutdown_both, errorCode);
+
+    m_sslSocket.lowest_layer().close(errorCode);
+}
+
+//==============================================================================
+//      SSLSession::create()
+//==============================================================================
+Session::SP SSLSession::create(Tango::DeviceImpl* deviceImpl_p,
+    Configuration::SP configuration_sp, DBManager::SP dBManager_sp,
+    boost::shared_ptr<boost::asio::io_service> ioService_sp,
+    boost::shared_ptr<boost::asio::ssl::context> context_sp)
+{
+    Session::SP s_sp(new SSLSession(deviceImpl_p, configuration_sp,
+        dBManager_sp, ioService_sp, context_sp), SSLSession::Deleter());
+
+    return s_sp;
+}
+
+//==============================================================================
+//      SSLSession::getSocket()
+//==============================================================================
+boost::asio::ip::tcp::socket& SSLSession::getSocket()
+{
+    DEBUG_STREAM << "SSLSession::getSocket()" << endl;
+
+    return m_sslSocket.next_layer();
+}
+
+//==============================================================================
+//      SSLSession::start()
+//==============================================================================
+void SSLSession::start()
+{
+    DEBUG_STREAM << "SSLSession::start()" << endl;
+
+//    m_remoteEndpoint = boost::lexical_cast<std::string>(
+//        m_sslSocket.lowest_layer().remote_endpoint());
+//
+//    INFO_STREAM << "SSLSession::start() Connection from "
+//        << m_remoteEndpoint << endl;
+//
+//    m_protocolManager_sp->setRemoteEndpoint(m_remoteEndpoint);
+//
+//    startHandShake();
+}
+
+////==============================================================================
+////      SSLSession::startHandShake()
+////==============================================================================
+//void SSLSession::startHandShake()
+//{
+//    DEBUG_STREAM << "SSLSession::startHandShake()" << endl;
+//
+//    m_sslSocket.async_handshake(boost::asio::ssl::stream_base::server,
+//        boost::bind(&SSLSession::handleHandShake, shared_from_this(),
+//        boost::asio::placeholders::error));
+//}
+//
+////==============================================================================
+////      SSLSession::handleRequest()
+////==============================================================================
+//void SSLSession::handleHandShake(const boost::system::error_code& errorCode)
+//{
+//        DEBUG_STREAM << "SSLSession::handleHandShake()" << endl;
+//
+//        if(!errorCode)
+//        {
+//            startReadRequestHeader();
+//        }
+//        else
+//        {
+//            ERROR_STREAM << "SSLSession::handleHandShake() error "
+//                << errorCode.message() << " from " << m_remoteEndpoint << endl;
+//        }
+//}
+//
+////==============================================================================
+////      SSLSession::startReadRequestHeader()
+////==============================================================================
+//void SSLSession::startReadRequestHeader()
+//{
+//        DEBUG_STREAM << "SSLSession::startReadRequestHeader()" << endl;
+//
+//        m_readBuff.resize(HEADER_SIZE);
+//
+//        boost::asio::async_read(m_sslSocket, boost::asio::buffer(m_readBuff),
+//            m_strand.wrap(boost::bind(&SSLSession::handleReadRequestHeader,
+//            shared_from_this(), boost::asio::placeholders::error)));
+//}
+//
+////==============================================================================
+////      SSLSession::startReadRequestBody()
+////==============================================================================
+//void SSLSession::startReadRequestBody(boost::uint32_t bodySize)
+//{
+//    DEBUG_STREAM << "SSLSession::startReadRequestBody()" << endl;
+//
+//    m_readBuff.resize(HEADER_SIZE + bodySize);
+//
+//    boost::asio::mutable_buffers_1 mutableBuffer =
+//        boost::asio::buffer(&m_readBuff[HEADER_SIZE], bodySize);
+//
+//    #ifdef VERBOSE_DEBUG
+//        INFO_STREAM << "SSLSession::startReadRequestBody() "
+//            << m_remoteEndpoint << " >>>> " << bodySize << " byte" << endl;
+//    #endif
+//
+//    boost::asio::async_read(m_sslSocket, mutableBuffer,
+//        m_strand.wrap(boost::bind(&SSLSession::handleReadRequestBody,
+//        shared_from_this(), boost::asio::placeholders::error)));
+//}
+//
+////==============================================================================
+////      SSLSession::startWriteResponse()
+////==============================================================================
+//void SSLSession::startWriteResponse()
+//{
+//    DEBUG_STREAM << "SSLSession::startWriteResponse()" << endl;
+//
+//    try
+//    {
+//        RequestSP request_sp(new Request);
+//
+//        request_sp->ParseFromArray(&m_readBuff[HEADER_SIZE],
+//            m_readBuff.size() - HEADER_SIZE);
+//
+//        ResponseSP response_sp = m_protocolManager_sp->prepareResponse(request_sp);
+//
+//        boost::uint32_t bodySize = response_sp->ByteSize();
+//
+//        std::vector<boost::uint8_t> writeBuff;
+//        writeBuff.resize(HEADER_SIZE + bodySize);
+//
+//        encodeHeader(writeBuff, bodySize);
+//
+//        response_sp->SerializeToArray(&writeBuff[HEADER_SIZE], bodySize);
+//
+//        #ifdef VERBOSE_DEBUG
+//            INFO_STREAM << "SSLSession::startWriteResponse() "
+//                << m_remoteEndpoint << " <<<< " << bodySize << " byte" << endl;
+//        #endif
+//
+//        boost::asio::async_write(m_sslSocket, boost::asio::buffer(writeBuff),
+//            m_strand.wrap(boost::bind(&SSLSession::handleWriteResponse,
+//            shared_from_this(), boost::asio::placeholders::error)));
+//    }
+//    catch(std::exception& ec)
+//    {
+//        ERROR_STREAM << "SSLSession::startWriteResponse() "
+//            << ec.what() << " from " << m_remoteEndpoint << endl;
+//    }
+//    catch(...)
+//    {
+//        ERROR_STREAM << "SSLSession::startWriteResponse() unknown error from "
+//            << m_remoteEndpoint <<  endl;
+//    }
+//}
+
+}   //namespace
diff --git a/src/SSLSession.h b/src/SSLSession.h
new file mode 100644
index 0000000..7967c21
--- /dev/null
+++ b/src/SSLSession.h
@@ -0,0 +1,77 @@
+#ifndef SSLSESSION_H
+#define	SSLSESSION_H
+
+#include <Session.h>
+
+#include <tango.h>
+
+#include <boost/enable_shared_from_this.hpp>
+#include <boost/asio/ssl.hpp>
+
+namespace DataExporter_ns
+{
+
+class SSLSession : public Session,
+        public boost::enable_shared_from_this<SSLSession>
+{
+protected:
+//------------------------------------------------------------------------------
+//	[Protected] Constructor destructor deleter
+//------------------------------------------------------------------------------
+    SSLSession(Tango::DeviceImpl*, Configuration::SP, DBManager::SP,
+        boost::shared_ptr<boost::asio::io_service>,
+        boost::shared_ptr<boost::asio::ssl::context>);
+
+    virtual ~SSLSession();
+
+    class Deleter;
+    friend Deleter;
+    class Deleter
+    {
+	public:
+		void operator()(SSLSession* d) { delete d; }
+    };
+
+public:
+//------------------------------------------------------------------------------
+//	[Public] Class creation method
+//------------------------------------------------------------------------------
+    static Session::SP create(Tango::DeviceImpl*, Configuration::SP,
+        DBManager::SP, boost::shared_ptr<boost::asio::io_service>,
+        boost::shared_ptr<boost::asio::ssl::context>);
+
+//------------------------------------------------------------------------------
+//	[Public] Incoming connection methods
+//------------------------------------------------------------------------------
+    virtual boost::asio::ip::tcp::socket& getSocket();
+
+    virtual void start();
+
+protected:
+////------------------------------------------------------------------------------
+////  [Protected] SSL handshake initialization methods
+////------------------------------------------------------------------------------
+//    virtual void startHandShake();
+//
+//    virtual void handleHandShake(const boost::system::error_code&);
+//
+////------------------------------------------------------------------------------
+////  [Protected] Request response methods
+////------------------------------------------------------------------------------
+//    virtual void startReadRequestHeader();
+//
+//    virtual void startReadRequestBody(boost::uint32_t);
+//
+//    virtual void startWriteResponse();
+
+//------------------------------------------------------------------------------
+//	[Protected] Class variables
+//------------------------------------------------------------------------------
+    //SSL socket object
+    boost::asio::ssl::stream<boost::asio::ip::tcp::socket> m_sslSocket;
+};
+
+}   //End of namespace
+
+#endif	/* SSLSESSION_H */
+
diff --git a/src/Server.cpp b/src/Server.cpp
new file mode 100644
index 0000000..b9c7e10
--- /dev/null
+++ b/src/Server.cpp
@@ -0,0 +1,197 @@
+#include <Server.h>
+#include <WorkerThread.h>
+
+#include <boost/lexical_cast.hpp>
+
+namespace DataExporter_ns
+{
+
+//==============================================================================
+//      Server::Server()
+//==============================================================================
+Server::Server(Tango::DeviceImpl* deviceImpl_p, Configuration::SP configuration_sp) :
+    Tango::LogAdapter(deviceImpl_p), m_deviceImpl_p(deviceImpl_p),
+    m_configuration_sp(configuration_sp)
+{
+    DEBUG_STREAM << "Server::Server()" << endl;
+
+    //GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+    m_dBManager_sp = DBManager::create(deviceImpl_p, configuration_sp);
+
+    m_ioService_sp.reset(new boost::asio::io_service);
+
+    m_acceptor_sp.reset(new boost::asio::ip::tcp::acceptor(*m_ioService_sp));
+
+    m_state = Tango::OFF;
+    m_status="Disconnected";
+}
+
+//==============================================================================
+//      Server::Server()
+//==============================================================================
+Server::~Server()
+{
+    DEBUG_STREAM << "Server::~Server()" << endl;
+
+    boost::system::error_code errorCode;
+    m_acceptor_sp->close(errorCode);
+
+    m_work_sp.reset();
+
+    m_ioService_sp->stop();
+
+    if(m_threadGroup_sp)
+    {
+        m_threadGroup_sp->interrupt_all();
+
+        m_threadGroup_sp->join_all();
+    }
+
+    //google::protobuf::ShutdownProtobufLibrary();
+}
+
+//==============================================================================
+//      Server::start()
+//==============================================================================
+void Server::start() throw(std::runtime_error)
+{
+    DEBUG_STREAM << "Server::start()" << endl;
+
+    m_dBManager_sp->connect();
+
+    m_ioService_sp->reset();
+
+    m_work_sp.reset(new boost::asio::io_service::work(*m_ioService_sp));
+
+    std::string localHost = m_configuration_sp->getLocalHost();
+    unsigned int localPort = m_configuration_sp->getLocalPort();
+
+    std::stringstream infoStream;
+    infoStream << "Listening on " << localHost << ":" << localPort << endl;
+
+    INFO_STREAM << "Server::start()" << infoStream.str() << endl;
+
+    writeState(Tango::ON);
+    writeStatus(infoStream.str());
+
+    boost::asio::ip::tcp::resolver::query query(localHost,
+        boost::lexical_cast<std::string>(localPort));
+
+    boost::asio::ip::tcp::resolver resolver(*m_ioService_sp);
+    boost::asio::ip::tcp::endpoint endpoint = *resolver.resolve(query);
+
+    m_acceptor_sp->open(endpoint.protocol());
+    m_acceptor_sp->set_option(boost::asio::ip::tcp::acceptor::reuse_address(true));
+    m_acceptor_sp->bind(endpoint);
+    m_acceptor_sp->listen();
+
+    m_threadGroup_sp.reset(new boost::thread_group);
+
+    unsigned int workerNumber = m_configuration_sp->getWorkerNumber();
+
+    WorkerThread worker(m_deviceImpl_p, m_ioService_sp);
+
+    for(unsigned int i=0; i<workerNumber; ++i)
+        m_threadGroup_sp->add_thread(new boost::thread(&WorkerThread::run, worker));
+
+    startAccept();
+}
+
+//==============================================================================
+//      Server::stop()
+//==============================================================================
+void Server::stop() throw(std::runtime_error)
+{
+    DEBUG_STREAM << "Server::stop()" << endl;
+
+    writeState(Tango::OFF);
+    writeStatus("Disconnected");
+
+    boost::system::error_code errorCode;
+    m_acceptor_sp->close(errorCode);
+
+    m_work_sp.reset();
+
+    m_ioService_sp->stop();
+
+    if(m_threadGroup_sp)
+    {
+        m_threadGroup_sp->interrupt_all();
+
+        m_threadGroup_sp->join_all();
+    }
+
+    m_threadGroup_sp.reset();
+
+    m_dBManager_sp->disconnect();
+}
+//==============================================================================
+//      Server::readState()
+//==============================================================================
+Tango::DevState Server::readState()
+{
+    DEBUG_STREAM << "Server::readState()" << endl;
+
+    boost::mutex::scoped_lock stateLock(m_stateMutex);
+
+    return m_state;
+}
+
+//==============================================================================
+//      Server::readStatus()
+//==============================================================================
+std::string Server::readStatus()
+{
+    DEBUG_STREAM << "Server::readStatus()" << endl;
+
+    boost::mutex::scoped_lock statusLock(m_statusMutex);
+
+    return m_status;
+}
+
+//==============================================================================
+//      Server::writeState()
+//==============================================================================
+void Server::writeState(Tango::DevState state)
+{
+    DEBUG_STREAM << "Server::writeState()" << endl;
+
+    boost::mutex::scoped_lock stateLock(m_stateMutex);
+
+    m_state = state;
+}
+
+//==============================================================================
+//      Server::writeStatus()
+//==============================================================================
+void Server::writeStatus(std::string status)
+{
+    DEBUG_STREAM << "Server::writeStatus()" << endl;
+
+    boost::mutex::scoped_lock statusLock(m_statusMutex);
+
+    m_status = status;
+}
+
+//==============================================================================
+//      Server::handleAccept()
+//==============================================================================
+void Server::handleAccept(Session::SP session_sp,
+    const boost::system::error_code& ec)
+{
+    DEBUG_STREAM << "Server::handleAccept()" << endl;
+
+    if(!ec)
+    {
+        session_sp->start();
+    }
+    else
+    {
+        ERROR_STREAM << "Server::handleAccept() " << ec.message() << endl;
+    }
+
+    startAccept();
+}
+
+}   //namespace
\ No newline at end of file
diff --git a/src/Server.h b/src/Server.h
new file mode 100644
index 0000000..9d030a6
--- /dev/null
+++ b/src/Server.h
@@ -0,0 +1,103 @@
+#ifndef SERVER_H
+#define	SERVER_H
+
+#include <Configuration.h>
+#include <DBManager.h>
+#include <Session.h>
+
+#include <tango.h>
+
+#include <boost/shared_ptr.hpp>
+#include <boost/asio.hpp>
+#include <boost/thread.hpp>
+
+namespace DataExporter_ns
+{
+
+class Server : public Tango::LogAdapter
+{
+public:
+//------------------------------------------------------------------------------
+//  [Public] Shared pointer typedef
+//------------------------------------------------------------------------------
+    typedef boost::shared_ptr<Server> SP;
+
+protected:
+//------------------------------------------------------------------------------
+//	[Protected] Constructor destructor
+//------------------------------------------------------------------------------
+    Server(Tango::DeviceImpl*, Configuration::SP);
+
+    virtual ~Server();
+
+public:
+//------------------------------------------------------------------------------
+//	[Public] Thread management methods
+//------------------------------------------------------------------------------
+    virtual void start() throw(std::runtime_error);
+
+    virtual void stop() throw(std::runtime_error);
+
+//------------------------------------------------------------------------------
+//	[Public] Read state and status methods
+//------------------------------------------------------------------------------
+    virtual Tango::DevState readState();
+
+    virtual std::string readStatus();
+
+protected:
+//------------------------------------------------------------------------------
+//  [Protected] Write state and status methods
+//------------------------------------------------------------------------------
+    virtual void writeState(Tango::DevState);
+
+    virtual void writeStatus(std::string);
+
+//------------------------------------------------------------------------------
+//  [Protected] Incoming connection methods
+//------------------------------------------------------------------------------
+    virtual void startAccept() = 0;
+
+    virtual void handleAccept(Session::SP, const boost::system::error_code&);
+
+//------------------------------------------------------------------------------
+//	[Protected] Class variables
+//------------------------------------------------------------------------------
+    //Device server base class pointer
+    Tango::DeviceImpl* m_deviceImpl_p;
+
+    //Configuration parameters shared pointer
+    Configuration::SP m_configuration_sp;
+
+    //Database data access class
+    DBManager::SP m_dBManager_sp;
+
+    //Io service used for async operations
+    boost::shared_ptr<boost::asio::io_service> m_ioService_sp;
+
+    //Prevents io service to run out of work and return
+    boost::shared_ptr<boost::asio::io_service::work> m_work_sp;
+
+    //Acceptor for incoming connection
+    boost::shared_ptr<boost::asio::ip::tcp::acceptor> m_acceptor_sp;
+
+    //Thread group container shared pointer
+    boost::shared_ptr<boost::thread_group> m_threadGroup_sp;
+
+    //Tango state property mutex
+    boost::mutex m_stateMutex;
+
+    //Tango state property
+    Tango::DevState m_state;
+
+    //Tango status property mutex
+    boost::mutex m_statusMutex;
+
+    //Tango status property
+    std::string m_status;
+};
+
+}   //End of namespace
+
+#endif	/* SERVER_H */
+
diff --git a/src/Session.cpp b/src/Session.cpp
new file mode 100644
index 0000000..a3ca0e5
--- /dev/null
+++ b/src/Session.cpp
@@ -0,0 +1,135 @@
+#include <Session.h>
+
+namespace DataExporter_ns
+{
+
+//==============================================================================
+//      Session::Session()
+//==============================================================================
+Session::Session(Tango::DeviceImpl* deviceImpl_p,  Configuration::SP configuration_sp,
+    DBManager::SP dBManager_sp, boost::shared_ptr<boost::asio::io_service> ioService_sp) :
+    Tango::LogAdapter(deviceImpl_p), m_configuration_sp(configuration_sp),
+    m_strand(*ioService_sp)
+{
+    DEBUG_STREAM << "Session::Session()" << endl;
+
+//    m_protocolManager_sp = ProtocolManager::create(deviceImpl_p,
+//        configuration_sp, dBManager_sp);
+}
+
+//==============================================================================
+//      Session::~Session()
+//==============================================================================
+Session::~Session()
+{
+    DEBUG_STREAM << "Session::~Session()" << endl;
+}
+
+////==============================================================================
+////      Session::handleReadRequestHeader()
+////==============================================================================
+//void Session::handleReadRequestHeader(const boost::system::error_code& errorCode)
+//{
+//    DEBUG_STREAM << "Session::handleReadRequestHeader()" << endl;
+//
+//    if(!errorCode)
+//    {
+//        boost::uint32_t bodySize = decodeHeader(m_readBuff);
+//
+//        startReadRequestBody(bodySize);
+//    }
+//    else if(errorCode == boost::asio::error::eof)
+//    {
+//        DEBUG_STREAM << "Session::handleReadRequestBody() end of file from "
+//            << m_remoteEndpoint << endl;
+//    }
+//    else
+//    {
+//        ERROR_STREAM << "Session::handleReadRequestHeader() "
+//            << errorCode.message() << " from " << m_remoteEndpoint << endl;
+//    }
+//}
+//
+////==============================================================================
+////      Session::handleReadRequestBody()
+////==============================================================================
+//void Session::handleReadRequestBody(const boost::system::error_code& errorCode)
+//{
+//    DEBUG_STREAM << "Session::handleReadRequestBody()" << endl;
+//
+//    if(!errorCode)
+//    {
+//        startWriteResponse();
+//    }
+//    else if(errorCode == boost::asio::error::eof)
+//    {
+//        DEBUG_STREAM << "Session::handleReadRequestBody() end of file from"
+//            << m_remoteEndpoint << endl;
+//    }
+//    else
+//    {
+//        ERROR_STREAM << "Session::handleReadRequestBody() "
+//            << errorCode.message() << " from " << m_remoteEndpoint << endl;
+//    }
+//}
+//
+////==============================================================================
+////      Session::handleWriteResponse()
+////==============================================================================
+//void Session::handleWriteResponse(const boost::system::error_code& errorCode)
+//{
+//    DEBUG_STREAM << "Session::handleWriteResponse()" << endl;
+//
+//    if(!errorCode)
+//    {
+//        startReadRequestHeader();
+//    }
+//    else if(errorCode == boost::asio::error::eof)
+//    {
+//        DEBUG_STREAM << "Session::handleWriteResponse() end of file from "
+//            << m_remoteEndpoint << endl;
+//    }
+//    else
+//    {
+//        ERROR_STREAM << "Session::handleWriteResponse() "
+//            << errorCode.message() << " from " << m_remoteEndpoint << endl;
+//    }
+//}
+//
+////==============================================================================
+////      Session::encodeHeader()
+////==============================================================================
+//void Session::encodeHeader(std::vector<boost::uint8_t>& buf, boost::uint32_t size)
+//    throw(std::runtime_error)
+//{
+//    DEBUG_STREAM << "Session::encodeHeader()" << endl;
+//
+//    if(buf.size() < HEADER_SIZE)
+//        throw std::runtime_error("Buffer to small to contain header!");
+//
+//    buf[0] = static_cast<boost::uint8_t>((size >> 24) & 0xFF);
+//    buf[1] = static_cast<boost::uint8_t>((size >> 16) & 0xFF);
+//    buf[2] = static_cast<boost::uint8_t>((size >> 8) & 0xFF);
+//    buf[3] = static_cast<boost::uint8_t>(size & 0xFF);
+//}
+//
+////==============================================================================
+////      Session::decodeHeader()
+////==============================================================================
+//boost::uint32_t Session::decodeHeader(std::vector<boost::uint8_t>& buf)
+//    throw(std::runtime_error)
+//{
+//    DEBUG_STREAM << "Session::decodeHeader()" << endl;
+//
+//    if(buf.size() < HEADER_SIZE)
+//        throw std::runtime_error("Buffer to small to contain header!");
+//
+//    boost::uint32_t size = 0;
+//
+//    for (unsigned i = 0; i < HEADER_SIZE; ++i)
+//        size = size * 256 + (static_cast<unsigned>(buf[i]) & 0xFF);
+//
+//    return size;
+//}
+
+}   //namespace
diff --git a/src/Session.h b/src/Session.h
new file mode 100644
index 0000000..166e34a
--- /dev/null
+++ b/src/Session.h
@@ -0,0 +1,97 @@
+#ifndef SESSION_H
+#define SESSION_H
+
+#include <Configuration.h>
+#include <DBManager.h>
+
+#include <tango.h>
+
+#include <boost/asio.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/cstdint.hpp>
+
+namespace DataExporter_ns
+{
+
+class Session : public Tango::LogAdapter
+{
+public:
+//------------------------------------------------------------------------------
+//  [Public] Shared pointer typedef
+//------------------------------------------------------------------------------
+    typedef boost::shared_ptr<Session> SP;
+
+protected:
+//------------------------------------------------------------------------------
+//	[Protected] Constructor destructor deleter
+//------------------------------------------------------------------------------
+    Session(Tango::DeviceImpl*, Configuration::SP, DBManager::SP,
+        boost::shared_ptr<boost::asio::io_service>);
+
+    virtual ~Session();
+
+public:
+//------------------------------------------------------------------------------
+//	[Public] Incoming connection methods
+//------------------------------------------------------------------------------
+    virtual boost::asio::ip::tcp::socket& getSocket() = 0;
+
+    virtual void start() = 0;
+
+protected:
+////------------------------------------------------------------------------------
+////  [Protected] Read request header methods
+////------------------------------------------------------------------------------
+//    virtual void startReadRequestHeader() = 0;
+//
+//    virtual void handleReadRequestHeader(const boost::system::error_code&);
+//
+////------------------------------------------------------------------------------
+////  [Protected] Read request body methods
+////------------------------------------------------------------------------------
+//    virtual void startReadRequestBody(boost::uint32_t) = 0;
+//
+//    virtual void handleReadRequestBody(const boost::system::error_code&);
+//
+////------------------------------------------------------------------------------
+////  [Protected] Write response methods
+////------------------------------------------------------------------------------
+//    virtual void startWriteResponse() = 0;
+//
+//    virtual void handleWriteResponse(const boost::system::error_code&);
+//
+////------------------------------------------------------------------------------
+////  [Protected] Encode decode header methods
+////------------------------------------------------------------------------------
+//    virtual void encodeHeader(std::vector<boost::uint8_t>&, boost::uint32_t)
+//        throw(std::runtime_error);
+//
+//    virtual boost::uint32_t decodeHeader(std::vector<boost::uint8_t>&)
+//        throw(std::runtime_error);
+
+//------------------------------------------------------------------------------
+//	[Protected] Class variables
+//------------------------------------------------------------------------------
+    //Configuration parameters shared pointer
+    Configuration::SP m_configuration_sp;
+
+    //Protocol manager class shared pointer
+    //ProtocolManager::SP m_protocolManager_sp;
+
+    //Synchronization mechanism
+    boost::asio::io_service::strand m_strand;
+
+    //Header size written on socket
+    const unsigned int HEADER_SIZE = 4;
+
+    //Binary buffer for read data
+    std::vector<boost::uint8_t> m_readBuff;
+
+    //Address and port of remote endpoint
+    std::string m_remoteEndpoint;
+};
+
+}   //End of namespace
+
+#endif	/* SESSION_H */
+
diff --git a/src/WorkerThread.cpp b/src/WorkerThread.cpp
new file mode 100644
index 0000000..132eb63
--- /dev/null
+++ b/src/WorkerThread.cpp
@@ -0,0 +1,59 @@
+#include <WorkerThread.h>
+#include <boost/thread.hpp>
+
+namespace DataExporter_ns
+{
+
+//==============================================================================
+//	WorkerThread::WorkerThread()
+//==============================================================================
+WorkerThread::WorkerThread(Tango::DeviceImpl* deviceImpl_p,
+    boost::shared_ptr<boost::asio::io_service> ioService_sp) :
+    Tango::LogAdapter(deviceImpl_p), m_ioService_sp(ioService_sp)
+{
+    DEBUG_STREAM << "WorkerThread::WorkerThread()" << endl;
+}
+
+//==============================================================================
+//	WorkerThread::~WorkerThread()
+//==============================================================================
+WorkerThread::~WorkerThread()
+{
+    DEBUG_STREAM << "WorkerThread::~WorkerThread()" << endl;
+}
+
+//==============================================================================
+//	WorkerThread::run()
+//==============================================================================
+void WorkerThread::run()
+{
+    DEBUG_STREAM << "WorkerThread::run() Starting" << endl;
+
+    while(true)
+    {
+        try
+        {
+            boost::system::error_code ec;
+            m_ioService_sp->run(ec);
+
+            if(ec)
+            {
+                ERROR_STREAM << "WorkerThread::run() " << ec.message() << endl;
+            }
+            break;
+        }
+        catch(std::exception& ex)
+        {
+            ERROR_STREAM << "WorkerThread::run() " << ex.what() << endl;
+        }
+        catch(boost::thread_interrupted& ex)
+        {
+            DEBUG_STREAM << "WorkerThread::run() interrupt" << endl;
+            break;
+        }
+    }
+
+    DEBUG_STREAM << "WorkerThread::run() Stopping" << endl;
+}
+
+}
\ No newline at end of file
diff --git a/src/WorkerThread.h b/src/WorkerThread.h
new file mode 100644
index 0000000..9d2f183
--- /dev/null
+++ b/src/WorkerThread.h
@@ -0,0 +1,37 @@
+#ifndef WORKERTHREAD_H
+#define	WORKERTHREAD_H
+
+#include <tango.h>
+
+#include <boost/shared_ptr.hpp>
+#include <boost/asio/io_service.hpp>
+
+namespace DataExporter_ns
+{
+
+class WorkerThread : public Tango::LogAdapter
+{
+public:
+//------------------------------------------------------------------------------
+//	[Public] Constructor destructor
+//------------------------------------------------------------------------------
+	WorkerThread(Tango::DeviceImpl*, boost::shared_ptr<boost::asio::io_service>);
+	virtual ~WorkerThread();
+
+//------------------------------------------------------------------------------
+//	[Public] Users method
+//------------------------------------------------------------------------------
+	virtual void run();
+
+protected:
+//------------------------------------------------------------------------------
+//	[Protected] Class variables
+//------------------------------------------------------------------------------
+    //Io service object common to all threads
+    boost::shared_ptr<boost::asio::io_service> m_ioService_sp;
+};
+
+}   //End of namespace
+
+#endif	/* WORKERTHREAD_H */
+
-- 
GitLab