Commit 903de34f authored by Marco De Marco's avatar Marco De Marco
Browse files

Worker thread and configuration classes added

parent 21e63fa8
Loading
Loading
Loading
Loading

src/Configuration.h

0 → 100644
+91 −0
Original line number Diff line number Diff line
#ifndef CONFIGURATION_H
#define	CONFIGURATION_H

#include <boost/shared_ptr.hpp>

namespace MetadataExporter_ns
{

class Configuration
{
public:
//------------------------------------------------------------------------------
//	[Public] Shared pointer typedef	
//------------------------------------------------------------------------------
	typedef boost::shared_ptr<Configuration> SP;
	typedef std::vector< SP > SPVector;

private:
//------------------------------------------------------------------------------
//	[Private] Constructor destructor deleter
//------------------------------------------------------------------------------
	Configuration(std::string address, unsigned int port, unsigned int workerNumber,
        bool enableSSL, std::string certificateFile, std::string privateKeyFile,
        std::string dHTempFile) : m_address(address), m_port(port), 
        m_workerNumber(workerNumber), m_enableSSL(enableSSL),
        m_certificateFile(certificateFile), m_privateKeyFile(privateKeyFile),
        m_dHTempFile(dHTempFile) {}
	virtual ~Configuration() {}

	class Deleter;
	friend class Deleter;
	class Deleter
	{
	public:
		void operator()(Configuration* c) { delete c; }
	};

public:
//------------------------------------------------------------------------------
//	[Public] User methods
//------------------------------------------------------------------------------
	static Configuration::SP create(std::string address, unsigned int port,
        unsigned int workerNumber, bool enableSSL, std::string certificateFile,
        std::string privateKeyFile, std::string dHTempFile)
	{
		Configuration::SP c_sp(new Configuration(address, port, workerNumber, 
            enableSSL, certificateFile, privateKeyFile, dHTempFile), 
            Configuration::Deleter());
			 
		return c_sp;
	}			

	std::string getAddress() const { return m_address; }
    unsigned int getPort() const { return m_port; }
    unsigned short getWorkerNumber() const { return m_workerNumber; }
    bool isSSLEnbled() const { return m_enableSSL; }
    std::string getCertificateFile() const { return m_certificateFile; }
    std::string getPrivateKeyFile() const { return m_privateKeyFile; }
    std::string getDHTempFile() const { return m_dHTempFile; }

private:
//------------------------------------------------------------------------------
//	[Private] class variables
//------------------------------------------------------------------------------
	//Address used for wait incoming connection
    const std::string m_address;

	//Port used for wait incoming connection
    const unsigned int m_port;
    
    //Number of threads that call io service run methods
    const unsigned short m_workerNumber;
    
    //Enable or disable SSL connections
    const bool m_enableSSL;
    
    //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;
    
};

}   //End of namespace

#endif	/* CONFIGURATION_H */
+173 −10
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@

#include <MetadataExporter.h>
#include <MetadataExporterClass.h>
#include <Configuration.h>
#include <PlainServer.h>
#include <SSLServer.h>

@@ -135,25 +136,184 @@ void MetadataExporter::init_device()
	DEBUG_STREAM << "MetadataExporter::init_device() create device " << device_name << endl;
	/*----- PROTECTED REGION ID(MetadataExporter::init_device_before) ENABLED START -----*/
	
	//	Initialization before get_device_property() call
    set_state(Tango::INIT);
    set_status("Initializing device");
	
	/*----- PROTECTED REGION END -----*/	//	MetadataExporter::init_device_before
	
	//	No device property to be read from database

	//	Get the device properties from database
	get_device_property();
	

	/*----- PROTECTED REGION ID(MetadataExporter::init_device) ENABLED START -----*/
	
    bool useSSL = true;
    if(get_state() != Tango::FAULT)
    {
        Configuration::SP configuration_sp = Configuration::create(address, port, 
            workerNumber, enableSSL, certificateFile, privateKeyFile, dHTempFile);
        
    if(useSSL)
        m_server_sp = SSLServer::create(this);
        if(enableSSL)
            m_server_sp = SSLServer::create(this, configuration_sp);
        else
        m_server_sp = PlainServer::create(this);        
            m_server_sp = PlainServer::create(this, configuration_sp);
    }
        
	/*----- PROTECTED REGION END -----*/	//	MetadataExporter::init_device
}

//--------------------------------------------------------
/**
 *	Method      : MetadataExporter::get_device_property()
 *	Description : Read database to initialize property data members.
 */
//--------------------------------------------------------
void MetadataExporter::get_device_property()
{
	/*----- PROTECTED REGION ID(MetadataExporter::get_device_property_before) ENABLED START -----*/
	
	//	Initialize property data members
	
	/*----- PROTECTED REGION END -----*/	//	MetadataExporter::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("Address"));
	dev_prop.push_back(Tango::DbDatum("Port"));
	dev_prop.push_back(Tango::DbDatum("WorkerNumber"));
	dev_prop.push_back(Tango::DbDatum("EnableSSL"));

	//	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 MetadataExporterClass to get class property
		Tango::DbDatum	def_prop, cl_prop;
		MetadataExporterClass	*ds_class =
			(static_cast<MetadataExporterClass *>(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 Address from class property
		cl_prop = ds_class->get_class_property(dev_prop[++i].name);
		if (cl_prop.is_empty()==false)	cl_prop  >>  address;
		else {
			//	Try to initialize Address from default device value
			def_prop = ds_class->get_default_device_property(dev_prop[i].name);
			if (def_prop.is_empty()==false)	def_prop  >>  address;
		}
		//	And try to extract Address value from database
		if (dev_prop[i].is_empty()==false)	dev_prop[i]  >>  address;

		//	Try to initialize Port from class property
		cl_prop = ds_class->get_class_property(dev_prop[++i].name);
		if (cl_prop.is_empty()==false)	cl_prop  >>  port;
		else {
			//	Try to initialize Port from default device value
			def_prop = ds_class->get_default_device_property(dev_prop[i].name);
			if (def_prop.is_empty()==false)	def_prop  >>  port;
		}
		//	And try to extract Port value from database
		if (dev_prop[i].is_empty()==false)	dev_prop[i]  >>  port;

		//	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;

	}

	/*----- PROTECTED REGION ID(MetadataExporter::get_device_property_after) ENABLED START -----*/
	
    try
    {  	
        if(address.empty())
            throw(invalid_argument("Address property is empty or not defined"));

        if(port<1 || port>MAX_DMDB_PORT)
            throw(invalid_argument("Port property out of range or not defined"));

        if(workerNumber<MIN_WORKER_NUMBER || workerNumber>MAX_WORKER_NUMBER)
            throw(invalid_argument("WorkerNumber property out of range or not defined"));

        if(enableSSL)
        {    
            if(certificateFile.empty())
                throw(invalid_argument("CertificateFile property is empty or not defined"));

            if(privateKeyFile.empty())
                throw(invalid_argument("PrivateKeyFile property is empty or not defined"));

            if(dHTempFile.empty())
                throw(invalid_argument("DHTempFile property is empty or not defined"));
        }
    }
    catch(invalid_argument& ex)
    {
        set_state(Tango::FAULT);
        stringstream error_stream;
        error_stream << "FitsImporter::get_device_property() " << ex.what() << endl;
        set_status(error_stream.str());
    }	
	
	/*----- PROTECTED REGION END -----*/	//	MetadataExporter::get_device_property_after
}

//--------------------------------------------------------
/**
@@ -166,7 +326,10 @@ void MetadataExporter::always_executed_hook()
	INFO_STREAM << "MetadataExporter::always_executed_hook()  " << device_name << endl;
	/*----- PROTECTED REGION ID(MetadataExporter::always_executed_hook) ENABLED START -----*/
	
	//	code always executed before all requests
    if(get_state() != Tango::FAULT)
    {
        
    }
	
	/*----- PROTECTED REGION END -----*/	//	MetadataExporter::always_executed_hook
}
+29 −1
Original line number Diff line number Diff line
@@ -42,7 +42,6 @@

#include <tango.h>


/*----- PROTECTED REGION END -----*/	//	MetadataExporter.h

/**
@@ -68,8 +67,33 @@ class MetadataExporter : public TANGO_BASE_CLASS
//------------------------------------------------------------------------------    
    Server::SP m_server_sp;

    //Max port number allowed value
    static const unsigned int MAX_DMDB_PORT = 65535;    
    
    //Min number of worker thread allowed    
    static const unsigned int MIN_WORKER_NUMBER = 1;    
    
    //Max number of worker thread allowed    
    static const unsigned int MAX_WORKER_NUMBER = 100;
      
/*----- PROTECTED REGION END -----*/	//	MetadataExporter::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;
	//	Address:	Address used for wait incoming connection
	string	address;
	//	Port:	Port used for wait incoming connection
	Tango::DevULong	port;
	//	WorkerNumber:	Number of threads that call io service run methods
	Tango::DevUShort	workerNumber;
	//	EnableSSL:	Enable or disable SSL connections
	Tango::DevBoolean	enableSSL;


//	Constructors and destructors
@@ -112,6 +136,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.
	 */
+43 −1
Original line number Diff line number Diff line
<?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="MetadataExporter" pogoRevision="8.1">
    <description description="Metadata exporter device server" title="Metadata exporter device server" sourcePath="/home/mdm/workspace/nadir/metadata_exporter/src" language="Cpp" filestogenerate="XMI   file,Code files" license="LGPL" hasMandatoryProperty="false" hasConcreteProperty="false" hasAbstractCommand="false" hasAbstractAttribute="false">
    <description description="Metadata exporter device server" title="Metadata exporter device server" sourcePath="/home/mdm/workspace/nadir/metadata_exporter/src" language="Cpp" filestogenerate="XMI   file,Code files" license="LGPL" 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="Not Applicable" 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>
    <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="Address" description="Address used for wait incoming connection">
      <type xsi:type="pogoDsl:StringType"/>
      <status abstract="false" inherited="false" concrete="true" concreteHere="true"/>
    </deviceProperties>
    <deviceProperties name="Port" description="Port used 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>
    <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"/>
+200 −0
Original line number Diff line number Diff line
@@ -84,6 +84,7 @@ MetadataExporterClass::MetadataExporterClass(string &s):Tango::DeviceClass(s)
{
	cout2 << "Entering MetadataExporterClass constructor" << endl;
	set_default_property();
	get_class_property();
	write_class_property();

	/*----- PROTECTED REGION ID(MetadataExporterClass::constructor) ENABLED START -----*/
@@ -206,6 +207,73 @@ Tango::DbDatum MetadataExporterClass::get_default_class_property(string &prop_na
	return Tango::DbDatum(prop_name);
}

//--------------------------------------------------------
/**
 *	Method      : MetadataExporterClass::get_class_property()
 *	Description : Read database to initialize class property data members.
 */
//--------------------------------------------------------
void MetadataExporterClass::get_class_property()
{
	/*----- PROTECTED REGION ID(MetadataExporterClass::get_class_property_before) ENABLED START -----*/
	
	//	Initialize class property data members
	
	/*----- PROTECTED REGION END -----*/	//	MetadataExporterClass::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"));
	
	//	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;
		}
	}
	/*----- PROTECTED REGION ID(MetadataExporterClass::get_class_property_after) ENABLED START -----*/
	
	//	Check class property data members init
	
	/*----- PROTECTED REGION END -----*/	//	MetadataExporterClass::get_class_property_after

}

//--------------------------------------------------------
/**
@@ -224,8 +292,140 @@ void MetadataExporterClass::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);

	//	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 = "Address";
	prop_desc = "Address used 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 = "Port";
	prop_desc = "Port used 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);
}

//--------------------------------------------------------
Loading