diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..f768f7909ca84a190cd6d52a1522bf55d0a7e55d --- /dev/null +++ b/.gitignore @@ -0,0 +1,19 @@ +.pydevproject +.project +.cproject +.settings +obj +bin +core* +*~ +*.pyc +*.so +*.so* +.pylintrc +.metadata +.idea +.cvsignore +.nse_depinfo +software +oldsrc +CVS diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..65c5ca88a67c30becee01c5a8816d964b03862f9 --- /dev/null +++ b/LICENSE @@ -0,0 +1,165 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..9400b8192d1e09e0eaf95d437991a3eaa677fabd --- /dev/null +++ b/Makefile @@ -0,0 +1,6 @@ +NAME_SRV = snmp-srv + +CXXFLAGS = +LDFLAGS = -lnetsnmp + +include ../makefiles/Make-9.3.3.in diff --git a/README.md b/README.md index 4ee0ed3918ec4f652df32e16c50d9ebb81a8d494..c8ec9afb28c77d212157078674764aa64272d583 100644 --- a/README.md +++ b/README.md @@ -1 +1,32 @@ -# snmp \ No newline at end of file +## Project Name + +snmp + +## Description + +Tango base server for accessing snmp devices + +## Dependencies + +libnetsnmp.so + +## Installation & deployment + +This server is mostly used by other tango devices +See your instiute guidelines + +## History + +2020-04-23 imported from CVS repo fermi/server/snmp release_12 + +## Credits + +developed by Alessio Bogani + +Elettra-Sincrotrone Trieste S.C.p.A. di interesse nazionale +Strada Statale 14 - km 163,5 in AREA Science Park +34149 Basovizza, Trieste ITALY + +## License + +GPL 3 diff --git a/src/ClassFactory.cpp b/src/ClassFactory.cpp new file mode 100644 index 0000000000000000000000000000000000000000..71517836f6624ae1591fb0ad512d5c1d394d77d6 --- /dev/null +++ b/src/ClassFactory.cpp @@ -0,0 +1,56 @@ +/*----- PROTECTED REGION ID(Snmp::ClassFactory.cpp) ENABLED START -----*/ +static const char *RcsId = "$Id: ClassFactory.cpp,v 1.1.1.1 2014-04-15 08:04:23 alessio Exp $"; +//============================================================================= +// +// file : ClassFactory.cpp +// +// description : C++ source for the class_factory method of the DServer +// device class. This method is responsible for the creation of +// all class singleton for a device server. It is called +// at device server startup. +// +// project : +// +// 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: alessio $ +// +// $Revision: 1.1.1.1 $ +// $Date: 2014-04-15 08:04:23 $ +// +// $HeadURL: $ +// +//============================================================================= +// This file is generated by POGO +// (Program Obviously used to Generate tango Object) +//============================================================================= + +#include <tango.h> +#include <SnmpClass.h> + +// Add class header files if needed + + +/** + * Create Snmp Class singleton and store it in DServer object. + */ + +void Tango::DServer::class_factory() +{ + // Add method class init if needed + add_class(Snmp_ns::SnmpClass::init("Snmp")); +} +/*----- PROTECTED REGION END -----*/ // Snmp::ClassFactory.cpp diff --git a/src/Snmp.cpp b/src/Snmp.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c055a8504fbb2f5cce2dee6c7c17a7a234cb5ff6 --- /dev/null +++ b/src/Snmp.cpp @@ -0,0 +1,782 @@ +/*----- PROTECTED REGION ID(Snmp.cpp) ENABLED START -----*/ +static const char *RcsId = "$Id: Snmp.cpp,v 1.14 2017-09-26 09:50:43 alessandro.olivo Exp $"; +//============================================================================= +// +// file : Snmp.cpp +// +// description : C++ source for the Snmp class and its commands. +// The class is derived from Device. It represents the +// CORBA servant object which will be accessed from the +// network. All commands which can be executed on the +// Snmp are implemented in this file. +// +// project : +// +// 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: alessandro.olivo $ +// +// $Revision: 1.14 $ +// $Date: 2017-09-26 09:50:43 $ +// +// $HeadURL: $ +// +//============================================================================= +// This file is generated by POGO +// (Program Obviously used to Generate tango Object) +//============================================================================= + + +#include <Snmp.h> +#include <SnmpClass.h> + +/*----- PROTECTED REGION END -----*/ // Snmp.cpp + +/** + * Snmp class description: + * + */ + +//================================================================ +// The following table gives the correspondence +// between command and method names. +// +// Command name | Method name +//================================================================ +// State | Inherited (no method) +// Status | Inherited (no method) +// Get | get +// Set | set +//================================================================ + +//================================================================ +// Attributes managed is: +//================================================================ +//================================================================ + +namespace Snmp_ns +{ +/*----- PROTECTED REGION ID(Snmp::namespace_starting) ENABLED START -----*/ + +// static initializations + +/*----- PROTECTED REGION END -----*/ // Snmp::namespace_starting + +//-------------------------------------------------------- +/** + * Method : Snmp::Snmp() + * Description : Constructors for a Tango device + * implementing the classSnmp + */ +//-------------------------------------------------------- +Snmp::Snmp(Tango::DeviceClass *cl, string &s) + : TANGO_BASE_CLASS(cl, s.c_str()) +{ + /*----- PROTECTED REGION ID(Snmp::constructor_1) ENABLED START -----*/ + init_device(); + + /*----- PROTECTED REGION END -----*/ // Snmp::constructor_1 +} +//-------------------------------------------------------- +Snmp::Snmp(Tango::DeviceClass *cl, const char *s) + : TANGO_BASE_CLASS(cl, s) +{ + /*----- PROTECTED REGION ID(Snmp::constructor_2) ENABLED START -----*/ + init_device(); + + /*----- PROTECTED REGION END -----*/ // Snmp::constructor_2 +} +//-------------------------------------------------------- +Snmp::Snmp(Tango::DeviceClass *cl, const char *s, const char *d) + : TANGO_BASE_CLASS(cl, s, d) +{ + /*----- PROTECTED REGION ID(Snmp::constructor_3) ENABLED START -----*/ + init_device(); + + /*----- PROTECTED REGION END -----*/ // Snmp::constructor_3 +} + +//-------------------------------------------------------- +/** + * Method : Snmp::delete_device() + * Description : will be called at device destruction or at init command + */ +//-------------------------------------------------------- +void Snmp::delete_device() +{ + DEBUG_STREAM << "Snmp::delete_device() " << device_name << endl; + /*----- PROTECTED REGION ID(Snmp::delete_device) ENABLED START -----*/ + + delete_session(); + + /*----- PROTECTED REGION END -----*/ // Snmp::delete_device +} + +//-------------------------------------------------------- +/** + * Method : Snmp::init_device() + * Description : will be called at device initialization. + */ +//-------------------------------------------------------- +void Snmp::init_device() +{ + DEBUG_STREAM << "Snmp::init_device() create device " << device_name << endl; + /*----- PROTECTED REGION ID(Snmp::init_device_before) ENABLED START -----*/ + + sess_ptr = NULL; + sess_config = NULL; + + /*----- PROTECTED REGION END -----*/ // Snmp::init_device_before + + + // Get the device properties from database + get_device_property(); + + // No longer if mandatory property not set. + if (mandatoryNotDefined) + return; + + /*----- PROTECTED REGION ID(Snmp::init_device) ENABLED START -----*/ + + netsnmp_session ts; + try + { + init_session(ts); + } + catch(Tango::DevFailed &e) + { + set_state(Tango::FAULT); + set_status(string(e.errors[0].desc)); + } + + /*----- PROTECTED REGION END -----*/ // Snmp::init_device +} + +//-------------------------------------------------------- +/** + * Method : Snmp::get_device_property() + * Description : Read database to initialize property data members. + */ +//-------------------------------------------------------- +void Snmp::get_device_property() +{ + /*----- PROTECTED REGION ID(Snmp::get_device_property_before) ENABLED START -----*/ + + // Initialize property data members + + /*----- PROTECTED REGION END -----*/ // Snmp::get_device_property_before + + mandatoryNotDefined = false; + + // Read device properties from database. + Tango::DbData dev_prop; + dev_prop.push_back(Tango::DbDatum("Version")); + dev_prop.push_back(Tango::DbDatum("Hostname")); + dev_prop.push_back(Tango::DbDatum("Community")); + dev_prop.push_back(Tango::DbDatum("Username")); + dev_prop.push_back(Tango::DbDatum("Passphrase")); + + // 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 SnmpClass to get class property + Tango::DbDatum def_prop, cl_prop; + SnmpClass *ds_class = + (static_cast<SnmpClass *>(get_device_class())); + int i = -1; + + // Try to initialize Version from class property + cl_prop = ds_class->get_class_property(dev_prop[++i].name); + if (cl_prop.is_empty()==false) cl_prop >> version; + else { + // Try to initialize Version from default device value + def_prop = ds_class->get_default_device_property(dev_prop[i].name); + if (def_prop.is_empty()==false) def_prop >> version; + } + // And try to extract Version value from database + if (dev_prop[i].is_empty()==false) dev_prop[i] >> version; + // Property StartDsPath is mandatory, check if has been defined in database. + check_mandatory_property(cl_prop, dev_prop[i]); + + // Try to initialize Hostname from class property + cl_prop = ds_class->get_class_property(dev_prop[++i].name); + if (cl_prop.is_empty()==false) cl_prop >> hostname; + else { + // Try to initialize Hostname from default device value + def_prop = ds_class->get_default_device_property(dev_prop[i].name); + if (def_prop.is_empty()==false) def_prop >> hostname; + } + // And try to extract Hostname value from database + if (dev_prop[i].is_empty()==false) dev_prop[i] >> hostname; + // Property StartDsPath is mandatory, check if has been defined in database. + check_mandatory_property(cl_prop, dev_prop[i]); + + // Try to initialize Community from class property + cl_prop = ds_class->get_class_property(dev_prop[++i].name); + if (cl_prop.is_empty()==false) cl_prop >> community; + else { + // Try to initialize Community from default device value + def_prop = ds_class->get_default_device_property(dev_prop[i].name); + if (def_prop.is_empty()==false) def_prop >> community; + } + // And try to extract Community value from database + if (dev_prop[i].is_empty()==false) dev_prop[i] >> community; + + // Try to initialize Username from class property + cl_prop = ds_class->get_class_property(dev_prop[++i].name); + if (cl_prop.is_empty()==false) cl_prop >> username; + else { + // Try to initialize Username from default device value + def_prop = ds_class->get_default_device_property(dev_prop[i].name); + if (def_prop.is_empty()==false) def_prop >> username; + } + // And try to extract Username value from database + if (dev_prop[i].is_empty()==false) dev_prop[i] >> username; + + // Try to initialize Passphrase from class property + cl_prop = ds_class->get_class_property(dev_prop[++i].name); + if (cl_prop.is_empty()==false) cl_prop >> passphrase; + else { + // Try to initialize Passphrase from default device value + def_prop = ds_class->get_default_device_property(dev_prop[i].name); + if (def_prop.is_empty()==false) def_prop >> passphrase; + } + // And try to extract Passphrase value from database + if (dev_prop[i].is_empty()==false) dev_prop[i] >> passphrase; + + } + + /*----- PROTECTED REGION ID(Snmp::get_device_property_after) ENABLED START -----*/ + + if (version != 1 && version != 2 && version != 3) + { + mandatoryNotDefined = true; + set_state(Tango::FAULT); + set_status("SNMP version must be choosen between 1, 2 or 3."); + } + + if ((version == 1 || version == 2) && community.size() == 0) + { + mandatoryNotDefined = true; + set_state(Tango::FAULT); + set_status("Community property is mandatory with SNMP version 1 and 2."); + } + + if (version == 3 && (username.size() == 0 || passphrase.size() == 0)) + { + mandatoryNotDefined = true; + set_state(Tango::FAULT); + set_status("Username and Passphrase properties are mandatory with SNMP version 3."); + } + + /*----- PROTECTED REGION END -----*/ // Snmp::get_device_property_after +} +//-------------------------------------------------------- +/** + * Method : Snmp::check_mandatory_property() + * Description : For mandatory properties check if defined in database. + */ +//-------------------------------------------------------- +void Snmp::check_mandatory_property(Tango::DbDatum &class_prop, Tango::DbDatum &dev_prop) +{ + // Check if all properties are empty + if (class_prop.is_empty() && dev_prop.is_empty()) + { + TangoSys_OMemStream tms; + tms << endl <<"Property \'" << dev_prop.name; + if (Tango::Util::instance()->_UseDb==true) + tms << "\' is mandatory but not defined in database"; + else + tms << "\' is mandatory but cannot be defined without database"; + string status(get_status()); + status += tms.str(); + set_status(status); + mandatoryNotDefined = true; + /*----- PROTECTED REGION ID(Snmp::check_mandatory_property) ENABLED START -----*/ + cerr << tms.str() << " for " << device_name << endl; + + /*----- PROTECTED REGION END -----*/ // Snmp::check_mandatory_property + } +} + + +//-------------------------------------------------------- +/** + * Method : Snmp::always_executed_hook() + * Description : method always executed before any command is executed + */ +//-------------------------------------------------------- +void Snmp::always_executed_hook() +{ + DEBUG_STREAM << "Snmp::always_executed_hook() " << device_name << endl; + if (mandatoryNotDefined) + { + string status(get_status()); + Tango::Except::throw_exception( + (const char *)"PROPERTY_NOT_SET", + status.c_str(), + (const char *)"Snmp::always_executed_hook()"); + } + /*----- PROTECTED REGION ID(Snmp::always_executed_hook) ENABLED START -----*/ + + if (Tango::Util::instance()->is_svr_shutting_down() == false + && Tango::Util::instance()->is_device_restarting(device_name) == false + && Tango::Util::instance()->is_svr_starting() == false) { + if (sess_ptr == NULL) + { + netsnmp_session ts; + try + { + init_session(ts); + } + catch(Tango::DevFailed &e) + { + set_state(Tango::FAULT); + set_status(string(e.errors[0].desc)); + } + } + } + + /*----- PROTECTED REGION END -----*/ // Snmp::always_executed_hook +} + +//-------------------------------------------------------- +/** + * Method : Snmp::read_attr_hardware() + * Description : Hardware acquisition for attributes + */ +//-------------------------------------------------------- +void Snmp::read_attr_hardware(TANGO_UNUSED(vector<long> &attr_list)) +{ + DEBUG_STREAM << "Snmp::read_attr_hardware(vector<long> &attr_list) entering... " << endl; + /*----- PROTECTED REGION ID(Snmp::read_attr_hardware) ENABLED START -----*/ + + // Add your own code + (void)attr_list; + + /*----- PROTECTED REGION END -----*/ // Snmp::read_attr_hardware +} + + +//-------------------------------------------------------- +/** + * Method : Snmp::add_dynamic_attributes() + * Description : Create the dynamic attributes if any + * for specified device. + */ +//-------------------------------------------------------- +void Snmp::add_dynamic_attributes() +{ + /*----- PROTECTED REGION ID(Snmp::add_dynamic_attributes) ENABLED START -----*/ + + // Add your own code to create and add dynamic attributes if any + + /*----- PROTECTED REGION END -----*/ // Snmp::add_dynamic_attributes +} + +//-------------------------------------------------------- +/** + * Command Get related method + * Description: + * + * @param argin + * @returns + */ +//-------------------------------------------------------- +Tango::DevVarStringArray *Snmp::get(const Tango::DevVarLongStringArray *argin) +{ + Tango::DevVarStringArray *argout; + DEBUG_STREAM << "Snmp::Get() - " << device_name << endl; + /*----- PROTECTED REGION ID(Snmp::get) ENABLED START -----*/ + + size_t items = argin->svalue.length(); + + if (argin->lvalue.length() != 1 || items == 0) + Tango::Except::throw_exception( "", + "Invalid input: It requires one only long value " + "and one or more string values", + "Snmp::get()"); + + sess_config = snmp_sess_session(sess_ptr); + sess_config->timeout = argin->lvalue[0] * 1000; + netsnmp_pdu *pdu = snmp_pdu_create(SNMP_MSG_GET); + + for (size_t i=0; i<items; ++i) + { + oid anOID[MAX_OID_LEN]; + size_t anOID_len = MAX_OID_LEN; + DEBUG_STREAM << "Snmp::Get() " + << "Parsing " << string(argin->svalue[i]) << endl; + if (! read_objid(argin->svalue[i], anOID, &anOID_len)) + { + snmp_free_pdu(pdu); + throw_exception("Parsing error","PARSING_ERR"); + } + snmp_add_null_var(pdu, anOID, anOID_len); + } + + netsnmp_pdu *response; + switch (snmp_sess_synch_response(sess_ptr, pdu, &response)) + { + case STAT_SUCCESS: + break; + case STAT_ERROR: + snmp_free_pdu(response); + throw_exception("Error", "STAT_ERR"); + break; + case STAT_TIMEOUT: + snmp_free_pdu(response); + throw_exception("Timeout", "STAT_TIMEOUT" ); + break; + default: + assert(false); + } + + switch (response->errstat) + { + case SNMP_ERR_NOERROR: + break; + case SNMP_ERR_NOTWRITABLE: + snmp_free_pdu(response); + throw_exception("SNMP object isn't writeable", "SNMP_ERR_NOTWRITABLE"); + break; + case SNMP_ERR_TOOBIG: + case SNMP_ERR_NOSUCHNAME: + case SNMP_ERR_BADVALUE: + case SNMP_ERR_READONLY: + case SNMP_ERR_GENERR: + case SNMP_ERR_NOACCESS: + case SNMP_ERR_WRONGTYPE: + case SNMP_ERR_WRONGLENGTH: + case SNMP_ERR_WRONGENCODING: + case SNMP_ERR_WRONGVALUE: + case SNMP_ERR_NOCREATION: + case SNMP_ERR_INCONSISTENTVALUE: + case SNMP_ERR_RESOURCEUNAVAILABLE: + case SNMP_ERR_COMMITFAILED: + case SNMP_ERR_UNDOFAILED: + case SNMP_ERR_AUTHORIZATIONERROR: + case SNMP_ERR_INCONSISTENTNAME: + ERROR_STREAM << "SNMP protocol data unit Error: " << response->errstat << endl; + snmp_free_pdu(response); + throw_exception("Error", "SNMP_ERR"); + break; + default: + assert(false); + } + + argout = new Tango::DevVarStringArray(); + argout->length(items); + int i = 0; + for(variable_list *vars = response->variables; vars; + vars = vars->next_variable) + { + char buff[1024]; + int cp = snprint_value(buff, sizeof(buff), vars->name, + vars->name_length, vars); + + if (cp == -1) + { + delete argout; + snmp_free_pdu(response); + throw_exception("Buffer overflow", "RESPONSE_BUFFOVERFLOW"); + } + + DEBUG_STREAM << "Snmp::get() " + << "Received " << string(buff) << endl; + (*argout)[i++] = CORBA::string_dup(buff); + } + + snmp_free_pdu(response); + + set_state(Tango::ON); + set_status("The device is in ON state."); + + /*----- PROTECTED REGION END -----*/ // Snmp::get + return argout; +} +//-------------------------------------------------------- +/** + * Command Set related method + * Description: + * + * @param argin + * @returns + */ +//-------------------------------------------------------- +Tango::DevVarStringArray *Snmp::set(const Tango::DevVarLongStringArray *argin) +{ + Tango::DevVarStringArray *argout; + DEBUG_STREAM << "Snmp::Set() - " << device_name << endl; + /*----- PROTECTED REGION ID(Snmp::set) ENABLED START -----*/ + + size_t items = argin->svalue.length(); + if (argin->lvalue.length() != 1 || items == 0 || items % 2 != 0) + Tango::Except::throw_exception( "", + "Invalid input: It requires one only long value " + "and one or more pair of string (composed by oid and value)", + "Snmp::set()"); + + sess_config = snmp_sess_session(sess_ptr); + sess_config->timeout = argin->lvalue[0] * 1000; + netsnmp_pdu *pdu = snmp_pdu_create(SNMP_MSG_SET); + + for (size_t i=0; i<items; i+=2) + { + oid anOID[MAX_OID_LEN]; + size_t anOID_len = MAX_OID_LEN; + DEBUG_STREAM << "Snmp::Set() " + << "Parsing " << string(argin->svalue[i]) << endl; + if (! read_objid(argin->svalue[i], anOID, &anOID_len)) + { + snmp_free_pdu(pdu); + throw_exception("Parsing error","PARSING_ERR"); + } + if (snmp_add_var(pdu, anOID, anOID_len, '=', argin->svalue[i+1])) + throw_exception(); + } + + netsnmp_pdu *response; + switch (snmp_sess_synch_response(sess_ptr, pdu, &response)) + { + case STAT_SUCCESS: + break; + case STAT_ERROR: + snmp_free_pdu(response); + throw_exception("Error", "STAT_ERROR"); + break; + case STAT_TIMEOUT: + snmp_free_pdu(response); + throw_exception("Timeout", "STAT_TIMEOUT" ); + break; + default: + assert(false); + } + + switch (response->errstat) + { + case SNMP_ERR_NOERROR: + break; + case SNMP_ERR_NOTWRITABLE: + snmp_free_pdu(response); + throw_exception("SNMP object isn't writeable", "SNMP_ERR_NOTWRITABLE"); + break; + case SNMP_ERR_TOOBIG: + case SNMP_ERR_NOSUCHNAME: + case SNMP_ERR_BADVALUE: + case SNMP_ERR_READONLY: + case SNMP_ERR_GENERR: + case SNMP_ERR_NOACCESS: + case SNMP_ERR_WRONGTYPE: + case SNMP_ERR_WRONGLENGTH: + case SNMP_ERR_WRONGENCODING: + case SNMP_ERR_WRONGVALUE: + case SNMP_ERR_NOCREATION: + case SNMP_ERR_INCONSISTENTVALUE: + case SNMP_ERR_RESOURCEUNAVAILABLE: + case SNMP_ERR_COMMITFAILED: + case SNMP_ERR_UNDOFAILED: + case SNMP_ERR_AUTHORIZATIONERROR: + case SNMP_ERR_INCONSISTENTNAME: + ERROR_STREAM << "SNMP protocol data unit Error: " << response->errstat << endl; + snmp_free_pdu(response); + throw_exception("Error", "SNMP_ERR"); + break; + default: + assert(false); + } + + argout = new Tango::DevVarStringArray(); + argout->length(items); + int i = 0; + for(variable_list *vars = response->variables; vars; + vars = vars->next_variable) + { + char buff[1024]; + int cp = snprint_value(buff, sizeof(buff), vars->name, + vars->name_length, vars); + + if (cp == -1) + { + delete argout; + snmp_free_pdu(response); + throw_exception("Buffer overflow", "RESPONSE_BUFFOVERFLOW"); + } + + DEBUG_STREAM << "Snmp::set() " + << "Received " << string(buff) << endl; + (*argout)[i++] = CORBA::string_dup(buff); + } + + snmp_free_pdu(response); + + set_state(Tango::ON); + set_status("The device is in ON state."); + + /*----- PROTECTED REGION END -----*/ // Snmp::set + return argout; +} +//-------------------------------------------------------- +/** + * Method : Snmp::add_dynamic_commands() + * Description : Create the dynamic commands if any + * for specified device. + */ +//-------------------------------------------------------- +void Snmp::add_dynamic_commands() +{ + /*----- PROTECTED REGION ID(Snmp::add_dynamic_commands) ENABLED START -----*/ + + // Add your own code to create and add dynamic commands if any + + /*----- PROTECTED REGION END -----*/ // Snmp::add_dynamic_commands +} + +/*----- PROTECTED REGION ID(Snmp::namespace_ending) ENABLED START -----*/ + +void Snmp::get_error(netsnmp_session *sess, string &ret) +{ + DEBUG_STREAM << "Snmp::get_error() - " << device_name << endl; + + stringstream mesg; + int pcliberr, psnmperr; + char *pperrstring; + + snmp_error(sess, &pcliberr, &psnmperr, &pperrstring); + mesg << string(pperrstring) << " (" << pcliberr << " " << psnmperr + << ")" << flush; + free(pperrstring); + ret = mesg.str(); +} + +void Snmp::get_sess_error(string &ret) +{ + DEBUG_STREAM << "Snmp::get_sess_error() - " << device_name << endl; + + stringstream mesg; + int pcliberr, psnmperr; + char *pperrstring; + + snmp_sess_error(sess_ptr, &pcliberr, &psnmperr, &pperrstring); + mesg << string(pperrstring) << " (" << pcliberr << " " << psnmperr + << ")" << flush; + free(pperrstring); + ret = mesg.str(); +} + +void Snmp::throw_exception(const string &prepend, const string &reason) +{ + DEBUG_STREAM << "Snmp::throw_exception() - " << device_name << endl; + + string errmesg; + get_sess_error(errmesg); + set_state(Tango::FAULT); + set_status(prepend + " " + errmesg); + delete_session(); + Tango::Except::throw_exception(reason, + prepend + " " + errmesg, + "Snmp::throw_exception()"); +} + +void Snmp::delete_session() +{ + DEBUG_STREAM << "Snmp::delete_session() - " << device_name << endl; + + if (sess_ptr != NULL) + { + if (! snmp_sess_close(sess_ptr)) + { + ERROR_STREAM << "Snmp::delete_session() " + << "Error closing SNMP" << endl; + } + SOCK_CLEANUP; + + sess_ptr = NULL; + } +} + +void Snmp::init_session(netsnmp_session &ts) +{ + DEBUG_STREAM << "Snmp::init_session() - " << device_name << endl; + snmp_sess_init(&ts); + + switch(version) + { + case 1: + ts.peername = (char*)hostname.c_str(); + ts.version = SNMP_VERSION_1; + ts.community = (u_char*)(community.c_str()); + ts.community_len = community.size() ; + break; + case 2: + ts.peername = (char*)hostname.c_str(); + ts.version = SNMP_VERSION_2c; + ts.community = (u_char*)(community.c_str()); + ts.community_len = community.size() ; + break; + case 3: + ts.peername = (char*)hostname.c_str(); + ts.version = SNMP_VERSION_3; + ts.securityName = (char*)username.c_str(); + ts.securityNameLen = username.size(); + ts.securityLevel = SNMP_SEC_LEVEL_AUTHNOPRIV; + ts.securityAuthProto = usmHMACMD5AuthProtocol; + ts.securityAuthProtoLen = + sizeof(usmHMACMD5AuthProtocol)/sizeof(oid); + ts.securityAuthKeyLen = USM_AUTH_KU_LEN; + + if (generate_Ku(ts.securityAuthProto, + ts.securityAuthProtoLen, + (u_char*)passphrase.c_str(), + passphrase.size(), + ts.securityAuthKey, + &ts.securityAuthKeyLen) + != SNMPERR_SUCCESS) + Tango::Except::throw_exception( "", + "Error generating Ku from " + "authentication pass phrase", + "Snmp::init_device()"); + break; + } + + SOCK_STARTUP; + + ts.retries = 0; + + netsnmp_ds_set_int(NETSNMP_DS_LIBRARY_ID, + NETSNMP_DS_LIB_OID_OUTPUT_FORMAT, + NETSNMP_OID_OUTPUT_NUMERIC); + + sess_ptr = snmp_sess_open(&ts); + + if (sess_ptr == NULL) + { + SOCK_CLEANUP; + string errmesg; + get_error(&ts, errmesg); + Tango::Except::throw_exception( + "", + "Error - " + errmesg, + "Snmp::init_session()"); + } +} + +/*----- PROTECTED REGION END -----*/ // Snmp::namespace_ending +} // namespace diff --git a/src/Snmp.h b/src/Snmp.h new file mode 100644 index 0000000000000000000000000000000000000000..3628c2cbc9da219d31d3f3eec53071d6fa4c7dec --- /dev/null +++ b/src/Snmp.h @@ -0,0 +1,212 @@ +/*----- PROTECTED REGION ID(Snmp.h) ENABLED START -----*/ +//============================================================================= +// +// file : Snmp.h +// +// description : Include file for the Snmp class +// +// project : +// +// 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: alessandro.olivo $ +// +// $Revision: 1.7 $ +// $Date: 2017-09-26 09:50:43 $ +// +// $HeadURL: $ +// +//============================================================================= +// This file is generated by POGO +// (Program Obviously used to Generate tango Object) +//============================================================================= + + +#ifndef Snmp_H +#define Snmp_H + +#include <tango.h> +#include <net-snmp/net-snmp-config.h> +#include <net-snmp/net-snmp-includes.h> + +/*----- PROTECTED REGION END -----*/ // Snmp.h + +/** + * Snmp class description: + * + */ + +namespace Snmp_ns +{ +/*----- PROTECTED REGION ID(Snmp::Additional Class Declarations) ENABLED START -----*/ + +// Additional Class Declarations + +/*----- PROTECTED REGION END -----*/ // Snmp::Additional Class Declarations + +class Snmp : public TANGO_BASE_CLASS +{ + +/*----- PROTECTED REGION ID(Snmp::Data Members) ENABLED START -----*/ + + netsnmp_session *sess_config; + void *sess_ptr; + +/*----- PROTECTED REGION END -----*/ // Snmp::Data Members + +// Device property data members +public: + // Version: SNMP`s version used + Tango::DevUShort version; + // Hostname: + string hostname; + // Community: + string community; + // Username: + string username; + // Passphrase: + string passphrase; + + bool mandatoryNotDefined; + + +// Constructors and destructors +public: + /** + * Constructs a newly device object. + * + * @param cl Class. + * @param s Device Name + */ + Snmp(Tango::DeviceClass *cl,string &s); + /** + * Constructs a newly device object. + * + * @param cl Class. + * @param s Device Name + */ + Snmp(Tango::DeviceClass *cl,const char *s); + /** + * Constructs a newly device object. + * + * @param cl Class. + * @param s Device name + * @param d Device description. + */ + Snmp(Tango::DeviceClass *cl,const char *s,const char *d); + /** + * The device object destructor. + */ + ~Snmp() {delete_device();}; + + +// Miscellaneous methods +public: + /* + * will be called at device destruction or at init command. + */ + void delete_device(); + /* + * Initialize the device + */ + virtual void init_device(); + /* + * Read the device properties from database + */ + void get_device_property(); + /* + * Always executed method before execution command method. + */ + virtual void always_executed_hook(); + + /* + * Check if mandatory property has been set + */ + void check_mandatory_property(Tango::DbDatum &class_prop, Tango::DbDatum &dev_prop); + +// Attribute methods +public: + //-------------------------------------------------------- + /* + * Method : Snmp::read_attr_hardware() + * Description : Hardware acquisition for attributes. + */ + //-------------------------------------------------------- + virtual void read_attr_hardware(vector<long> &attr_list); + + + //-------------------------------------------------------- + /** + * Method : Snmp::add_dynamic_attributes() + * Description : Add dynamic attributes if any. + */ + //-------------------------------------------------------- + void add_dynamic_attributes(); + + + + +// Command related methods +public: + /** + * Command Get related method + * Description: + * + * @param argin + * @returns + */ + virtual Tango::DevVarStringArray *get(const Tango::DevVarLongStringArray *argin); + virtual bool is_Get_allowed(const CORBA::Any &any); + /** + * Command Set related method + * Description: + * + * @param argin + * @returns + */ + virtual Tango::DevVarStringArray *set(const Tango::DevVarLongStringArray *argin); + virtual bool is_Set_allowed(const CORBA::Any &any); + + + //-------------------------------------------------------- + /** + * Method : Snmp::add_dynamic_commands() + * Description : Add dynamic commands if any. + */ + //-------------------------------------------------------- + void add_dynamic_commands(); + +/*----- PROTECTED REGION ID(Snmp::Additional Method prototypes) ENABLED START -----*/ + +private: + void get_error(netsnmp_session *sess, string &ret); + void get_sess_error(string &ret); + void throw_exception(const string &prepend = "", const string &reason = ""); + void delete_session(); + void init_session(netsnmp_session &ts); + +/*----- PROTECTED REGION END -----*/ // Snmp::Additional Method prototypes +}; + +/*----- PROTECTED REGION ID(Snmp::Additional Classes Definitions) ENABLED START -----*/ + +// Additional Classes Definitions + +/*----- PROTECTED REGION END -----*/ // Snmp::Additional Classes Definitions + +} // End of namespace + +#endif // Snmp_H diff --git a/src/Snmp.xmi b/src/Snmp.xmi new file mode 100644 index 0000000000000000000000000000000000000000..94f8240e0e1c039f0c9b0ef39b3e8ee36653a0cb --- /dev/null +++ b/src/Snmp.xmi @@ -0,0 +1,66 @@ +<?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="Snmp" pogoRevision="9.1"> + <description description="" title="" sourcePath="/home/alessandro/gitdevel/fermi/servers/snmp/src" language="Cpp" filestogenerate="XMI file,Code files,Protected Regions" license="GPL" hasMandatoryProperty="true" hasConcreteProperty="true" hasAbstractCommand="false" hasAbstractAttribute="false"> + <inheritances classname="Device_Impl" sourcePath=""/> + <identification contact="at elettra.eu> - Alessio Igor Bogani <alessio.bogani" author="Alessio Igor Bogani <alessio.bogani" emailDomain="elettra.eu>" classFamily="Communication" siteSpecific="" platform="Unix Like" bus="Not Applicable" manufacturer="none" reference=""/> + </description> + <deviceProperties name="Version" mandatory="true" description="SNMP`s version used"> + <type xsi:type="pogoDsl:UShortType"/> + <status abstract="false" inherited="false" concrete="true" concreteHere="true"/> + </deviceProperties> + <deviceProperties name="Hostname" mandatory="true" description=""> + <type xsi:type="pogoDsl:StringType"/> + <status abstract="false" inherited="false" concrete="true" concreteHere="true"/> + </deviceProperties> + <deviceProperties name="Community" description=""> + <type xsi:type="pogoDsl:StringType"/> + <status abstract="false" inherited="false" concrete="true" concreteHere="true"/> + </deviceProperties> + <deviceProperties name="Username" description=""> + <type xsi:type="pogoDsl:StringType"/> + <status abstract="false" inherited="false" concrete="true" concreteHere="true"/> + </deviceProperties> + <deviceProperties name="Passphrase" description=""> + <type xsi:type="pogoDsl:StringType"/> + <status abstract="false" inherited="false" concrete="true" concreteHere="true"/> + </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"/> + </argin> + <argout description="Device state"> + <type xsi:type="pogoDsl:StateType"/> + </argout> + <status abstract="true" inherited="true" concrete="true"/> + </commands> + <commands name="Status" description="This command gets the device status (stored in its device_status data member) and returns it to the caller." execMethod="dev_status" displayLevel="OPERATOR" polledPeriod="0"> + <argin description="none"> + <type xsi:type="pogoDsl:VoidType"/> + </argin> + <argout description="Device status"> + <type xsi:type="pogoDsl:ConstStringType"/> + </argout> + <status abstract="true" inherited="true" concrete="true"/> + </commands> + <commands name="Get" description="" execMethod="get" displayLevel="OPERATOR" polledPeriod="0"> + <argin description=""> + <type xsi:type="pogoDsl:LongStringArrayType"/> + </argin> + <argout description=""> + <type xsi:type="pogoDsl:StringArrayType"/> + </argout> + <status abstract="false" inherited="false" concrete="true" concreteHere="true"/> + </commands> + <commands name="Set" description="" execMethod="set" displayLevel="OPERATOR" polledPeriod="0" isDynamic="false"> + <argin description=""> + <type xsi:type="pogoDsl:LongStringArrayType"/> + </argin> + <argout description=""> + <type xsi:type="pogoDsl:StringArrayType"/> + </argout> + <status abstract="false" inherited="false" concrete="true" concreteHere="true"/> + </commands> + <preferences docHome="./doc_html" makefileHome="/usr/local/tango-9.2.2/share/pogo/preferences"/> + </classes> +</pogoDsl:PogoSystem> diff --git a/src/SnmpClass.cpp b/src/SnmpClass.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1101585d04dfb028af32cfc1c18cea62fa2497ec --- /dev/null +++ b/src/SnmpClass.cpp @@ -0,0 +1,707 @@ +/*----- PROTECTED REGION ID(SnmpClass.cpp) ENABLED START -----*/ +static const char *RcsId = "$Id: SnmpClass.cpp,v 1.7 2017-08-07 15:02:23 alessandro.olivo Exp $"; +static const char *TagName = "Snmp $Name: $"; +static const char *CvsPath = "$Source: /home/cvsadm/cvsroot/fermi/servers/snmp/src/SnmpClass.cpp,v $"; +static const char *SvnPath = "$HeadURL: $"; +static const char *HttpServer = "http://www.esrf.eu/computing/cs/tango/tango_doc/ds_doc/"; +//============================================================================= +// +// file : SnmpClass.cpp +// +// description : C++ source for the SnmpClass. +// A singleton class derived from DeviceClass. +// It implements the command and attribute list +// and all properties and methods required +// by the Snmp once per process. +// +// project : +// +// 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: alessandro.olivo $ +// +// $Revision: 1.7 $ +// $Date: 2017-08-07 15:02:23 $ +// +// $HeadURL: $ +// +//============================================================================= +// This file is generated by POGO +// (Program Obviously used to Generate tango Object) +//============================================================================= + + +#include <SnmpClass.h> + +/*----- PROTECTED REGION END -----*/ // SnmpClass.cpp + +//------------------------------------------------------------------- +/** + * Create SnmpClass singleton and + * return it in a C function for Python usage + */ +//------------------------------------------------------------------- +extern "C" { +#ifdef _TG_WINDOWS_ + +__declspec(dllexport) + +#endif + + Tango::DeviceClass *_create_Snmp_class(const char *name) { + return Snmp_ns::SnmpClass::init(name); + } +} + +namespace Snmp_ns +{ +//=================================================================== +// Initialize pointer for singleton pattern +//=================================================================== +SnmpClass *SnmpClass::_instance = NULL; + +//-------------------------------------------------------- +/** + * method : SnmpClass::SnmpClass(string &s) + * description : constructor for the SnmpClass + * + * @param s The class name + */ +//-------------------------------------------------------- +SnmpClass::SnmpClass(string &s):Tango::DeviceClass(s) +{ + cout2 << "Entering SnmpClass constructor" << endl; + set_default_property(); + write_class_property(); + + /*----- PROTECTED REGION ID(SnmpClass::constructor) ENABLED START -----*/ + + netsnmp_ds_toggle_boolean(NETSNMP_DS_LIBRARY_ID, + NETSNMP_DS_LIB_PRINT_BARE_VALUE); + netsnmp_ds_toggle_boolean(NETSNMP_DS_LIBRARY_ID, + NETSNMP_DS_LIB_QUICK_PRINT); + netsnmp_ds_toggle_boolean(NETSNMP_DS_LIBRARY_ID, + NETSNMP_DS_LIB_PRINT_NUMERIC_ENUM); + netsnmp_ds_toggle_boolean(NETSNMP_DS_LIBRARY_ID, + NETSNMP_DS_LIB_NUMERIC_TIMETICKS); + + init_snmp(""); + + /*----- PROTECTED REGION END -----*/ // SnmpClass::constructor + + cout2 << "Leaving SnmpClass constructor" << endl; +} + +//-------------------------------------------------------- +/** + * method : SnmpClass::~SnmpClass() + * description : destructor for the SnmpClass + */ +//-------------------------------------------------------- +SnmpClass::~SnmpClass() +{ + /*----- PROTECTED REGION ID(SnmpClass::destructor) ENABLED START -----*/ + + /*----- PROTECTED REGION END -----*/ // SnmpClass::destructor + + _instance = NULL; +} + + +//-------------------------------------------------------- +/** + * method : SnmpClass::init + * description : Create the object if not already done. + * Otherwise, just return a pointer to the object + * + * @param name The class name + */ +//-------------------------------------------------------- +SnmpClass *SnmpClass::init(const char *name) +{ + if (_instance == NULL) + { + try + { + string s(name); + _instance = new SnmpClass(s); + } + catch (bad_alloc &) + { + throw; + } + } + return _instance; +} + +//-------------------------------------------------------- +/** + * method : SnmpClass::instance + * description : Check if object already created, + * and return a pointer to the object + */ +//-------------------------------------------------------- +SnmpClass *SnmpClass::instance() +{ + if (_instance == NULL) + { + cerr << "Class is not initialised !!" << endl; + exit(-1); + } + return _instance; +} + + + +//=================================================================== +// Command execution method calls +//=================================================================== +//-------------------------------------------------------- +/** + * method : GetClass::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 *GetClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) +{ + cout2 << "GetClass::execute(): arrived" << endl; + const Tango::DevVarLongStringArray *argin; + extract(in_any, argin); + return insert((static_cast<Snmp *>(device))->get(argin)); +} + +//-------------------------------------------------------- +/** + * method : SetClass::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 *SetClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) +{ + cout2 << "SetClass::execute(): arrived" << endl; + const Tango::DevVarLongStringArray *argin; + extract(in_any, argin); + return insert((static_cast<Snmp *>(device))->set(argin)); +} + + +//=================================================================== +// Properties management +//=================================================================== +//-------------------------------------------------------- +/** + * Method : SnmpClass::get_class_property() + * Description : Get the class property for specified name. + */ +//-------------------------------------------------------- +Tango::DbDatum SnmpClass::get_class_property(string &prop_name) +{ + for (unsigned int i=0 ; i<cl_prop.size() ; i++) + if (cl_prop[i].name == prop_name) + return cl_prop[i]; + // if not found, returns an empty DbDatum + return Tango::DbDatum(prop_name); +} + +//-------------------------------------------------------- +/** + * Method : SnmpClass::get_default_device_property() + * Description : Return the default value for device property. + */ +//-------------------------------------------------------- +Tango::DbDatum SnmpClass::get_default_device_property(string &prop_name) +{ + for (unsigned int i=0 ; i<dev_def_prop.size() ; i++) + if (dev_def_prop[i].name == prop_name) + return dev_def_prop[i]; + // if not found, return an empty DbDatum + return Tango::DbDatum(prop_name); +} + +//-------------------------------------------------------- +/** + * Method : SnmpClass::get_default_class_property() + * Description : Return the default value for class property. + */ +//-------------------------------------------------------- +Tango::DbDatum SnmpClass::get_default_class_property(string &prop_name) +{ + for (unsigned int i=0 ; i<cl_def_prop.size() ; i++) + if (cl_def_prop[i].name == prop_name) + return cl_def_prop[i]; + // if not found, return an empty DbDatum + return Tango::DbDatum(prop_name); +} + + +//-------------------------------------------------------- +/** + * Method : SnmpClass::set_default_property() + * Description : Set default property (class and device) for wizard. + * For each property, add to wizard property name and description. + * If default value has been set, add it to wizard property and + * store it in a DbDatum. + */ +//-------------------------------------------------------- +void SnmpClass::set_default_property() +{ + string prop_name; + string prop_desc; + string prop_def; + vector<string> vect_data; + + // Set Default Class Properties + + // Set Default device Properties + prop_name = "Version"; + prop_desc = "SNMP`s version used"; + 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 = "Hostname"; + prop_desc = ""; + 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 = "Community"; + prop_desc = ""; + 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 = "Username"; + prop_desc = ""; + 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 = "Passphrase"; + prop_desc = ""; + 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); +} + +//-------------------------------------------------------- +/** + * Method : SnmpClass::write_class_property() + * Description : Set class description fields as property in database + */ +//-------------------------------------------------------- +void SnmpClass::write_class_property() +{ + // First time, check if database used + if (Tango::Util::_UseDb == false) + return; + + Tango::DbData data; + string classname = get_name(); + string header; + string::size_type start, end; + + // Put title + Tango::DbDatum title("ProjectTitle"); + string str_title(""); + title << str_title; + data.push_back(title); + + // Put Description + Tango::DbDatum description("Description"); + vector<string> str_desc; + str_desc.push_back(""); + description << str_desc; + data.push_back(description); + + // put cvs or svn location + string filename("Snmp"); + filename += "Class.cpp"; + + // check for cvs information + string src_path(CvsPath); + start = src_path.find("/"); + if (start!=string::npos) + { + end = src_path.find(filename); + if (end>start) + { + string strloc = src_path.substr(start, end-start); + // Check if specific repository + start = strloc.find("/cvsroot/"); + if (start!=string::npos && start>0) + { + string repository = strloc.substr(0, start); + if (repository.find("/segfs/")!=string::npos) + strloc = "ESRF:" + strloc.substr(start, strloc.length()-start); + } + Tango::DbDatum cvs_loc("cvs_location"); + cvs_loc << strloc; + data.push_back(cvs_loc); + } + } + + // check for svn information + else + { + string src_path(SvnPath); + start = src_path.find("://"); + if (start!=string::npos) + { + end = src_path.find(filename); + if (end>start) + { + header = "$HeadURL: "; + start = header.length(); + string strloc = src_path.substr(start, (end-start)); + + Tango::DbDatum svn_loc("svn_location"); + svn_loc << strloc; + data.push_back(svn_loc); + } + } + } + + // Get CVS or SVN revision tag + + // CVS tag + string tagname(TagName); + header = "$Name: "; + start = header.length(); + string endstr(" $"); + + end = tagname.find(endstr); + if (end!=string::npos && end>start) + { + string strtag = tagname.substr(start, end-start); + Tango::DbDatum cvs_tag("cvs_tag"); + cvs_tag << strtag; + data.push_back(cvs_tag); + } + + // SVN tag + string svnpath(SvnPath); + header = "$HeadURL: "; + start = header.length(); + + end = svnpath.find(endstr); + if (end!=string::npos && end>start) + { + string strloc = svnpath.substr(start, end-start); + + string tagstr ("/tags/"); + start = strloc.find(tagstr); + if ( start!=string::npos ) + { + start = start + tagstr.length(); + end = strloc.find(filename); + string strtag = strloc.substr(start, end-start-1); + + Tango::DbDatum svn_tag("svn_tag"); + svn_tag << strtag; + data.push_back(svn_tag); + } + } + + // Get URL location + string httpServ(HttpServer); + if (httpServ.length()>0) + { + Tango::DbDatum db_doc_url("doc_url"); + db_doc_url << httpServ; + data.push_back(db_doc_url); + } + + // Put inheritance + Tango::DbDatum inher_datum("InheritedFrom"); + vector<string> inheritance; + inheritance.push_back("TANGO_BASE_CLASS"); + inher_datum << inheritance; + data.push_back(inher_datum); + + // Call database and and values + get_db_class()->put_property(data); +} + +//=================================================================== +// Factory methods +//=================================================================== + +//-------------------------------------------------------- +/** + * Method : SnmpClass::device_factory() + * Description : Create the device object(s) + * and store them in the device list + */ +//-------------------------------------------------------- +void SnmpClass::device_factory(const Tango::DevVarStringArray *devlist_ptr) +{ + /*----- PROTECTED REGION ID(SnmpClass::device_factory_before) ENABLED START -----*/ + + // Add your own code + + /*----- PROTECTED REGION END -----*/ // SnmpClass::device_factory_before + + // Create devices and add it into the device list + for (unsigned long i=0 ; i<devlist_ptr->length() ; i++) + { + cout4 << "Device name : " << (*devlist_ptr)[i].in() << endl; + device_list.push_back(new Snmp(this, (*devlist_ptr)[i])); + } + + // Manage dynamic attributes if any + erase_dynamic_attributes(devlist_ptr, get_class_attr()->get_attr_list()); + + // Export devices to the outside world + for (unsigned long i=1 ; i<=devlist_ptr->length() ; i++) + { + // Add dynamic attributes if any + Snmp *dev = static_cast<Snmp *>(device_list[device_list.size()-i]); + dev->add_dynamic_attributes(); + + // Check before if database used. + if ((Tango::Util::_UseDb == true) && (Tango::Util::_FileDb == false)) + export_device(dev); + else + export_device(dev, dev->get_name().c_str()); + } + + /*----- PROTECTED REGION ID(SnmpClass::device_factory_after) ENABLED START -----*/ + + // Add your own code + + /*----- PROTECTED REGION END -----*/ // SnmpClass::device_factory_after +} +//-------------------------------------------------------- +/** + * Method : SnmpClass::attribute_factory() + * Description : Create the attribute object(s) + * and store them in the attribute list + */ +//-------------------------------------------------------- +void SnmpClass::attribute_factory(vector<Tango::Attr *> &att_list) +{ + /*----- PROTECTED REGION ID(SnmpClass::attribute_factory_before) ENABLED START -----*/ + + // Add your own code + + /*----- PROTECTED REGION END -----*/ // SnmpClass::attribute_factory_before + + // Create a list of static attributes + create_static_attribute_list(get_class_attr()->get_attr_list()); + /*----- PROTECTED REGION ID(SnmpClass::attribute_factory_after) ENABLED START -----*/ + + // Add your own code + + /*----- PROTECTED REGION END -----*/ // SnmpClass::attribute_factory_after +} +//-------------------------------------------------------- +/** + * Method : SnmpClass::pipe_factory() + * Description : Create the pipe object(s) + * and store them in the pipe list + */ +//-------------------------------------------------------- +void SnmpClass::pipe_factory() +{ + /*----- PROTECTED REGION ID(SnmpClass::pipe_factory_before) ENABLED START -----*/ + + // Add your own code + + /*----- PROTECTED REGION END -----*/ // SnmpClass::pipe_factory_before + /*----- PROTECTED REGION ID(SnmpClass::pipe_factory_after) ENABLED START -----*/ + + // Add your own code + + /*----- PROTECTED REGION END -----*/ // SnmpClass::pipe_factory_after +} +//-------------------------------------------------------- +/** + * Method : SnmpClass::command_factory() + * Description : Create the command object(s) + * and store them in the command list + */ +//-------------------------------------------------------- +void SnmpClass::command_factory() +{ + /*----- PROTECTED REGION ID(SnmpClass::command_factory_before) ENABLED START -----*/ + + // Add your own code + + /*----- PROTECTED REGION END -----*/ // SnmpClass::command_factory_before + + + // Command Get + GetClass *pGetCmd = + new GetClass("Get", + Tango::DEVVAR_LONGSTRINGARRAY, Tango::DEVVAR_STRINGARRAY, + "", + "", + Tango::OPERATOR); + command_list.push_back(pGetCmd); + + // Command Set + SetClass *pSetCmd = + new SetClass("Set", + Tango::DEVVAR_LONGSTRINGARRAY, Tango::DEVVAR_STRINGARRAY, + "", + "", + Tango::OPERATOR); + command_list.push_back(pSetCmd); + + /*----- PROTECTED REGION ID(SnmpClass::command_factory_after) ENABLED START -----*/ + + // Add your own code + + /*----- PROTECTED REGION END -----*/ // SnmpClass::command_factory_after +} + +//=================================================================== +// Dynamic attributes related methods +//=================================================================== + +//-------------------------------------------------------- +/** + * method : SnmpClass::create_static_attribute_list + * description : Create the a list of static attributes + * + * @param att_list the ceated attribute list + */ +//-------------------------------------------------------- +void SnmpClass::create_static_attribute_list(vector<Tango::Attr *> &att_list) +{ + for (unsigned long i=0 ; i<att_list.size() ; i++) + { + string att_name(att_list[i]->get_name()); + transform(att_name.begin(), att_name.end(), att_name.begin(), ::tolower); + defaultAttList.push_back(att_name); + } + + cout2 << defaultAttList.size() << " attributes in default list" << endl; + + /*----- PROTECTED REGION ID(SnmpClass::create_static_att_list) ENABLED START -----*/ + + /*----- PROTECTED REGION END -----*/ // SnmpClass::create_static_att_list +} + + +//-------------------------------------------------------- +/** + * method : SnmpClass::erase_dynamic_attributes + * description : delete the dynamic attributes if any. + * + * @param devlist_ptr the device list pointer + * @param list of all attributes + */ +//-------------------------------------------------------- +void SnmpClass::erase_dynamic_attributes(const Tango::DevVarStringArray *devlist_ptr, vector<Tango::Attr *> &att_list) +{ + Tango::Util *tg = Tango::Util::instance(); + + for (unsigned long i=0 ; i<devlist_ptr->length() ; i++) + { + Tango::DeviceImpl *dev_impl = tg->get_device_by_name(((string)(*devlist_ptr)[i]).c_str()); + Snmp *dev = static_cast<Snmp *> (dev_impl); + + vector<Tango::Attribute *> &dev_att_list = dev->get_device_attr()->get_attribute_list(); + vector<Tango::Attribute *>::iterator ite_att; + for (ite_att=dev_att_list.begin() ; ite_att != dev_att_list.end() ; ++ite_att) + { + string att_name((*ite_att)->get_name_lower()); + if ((att_name == "state") || (att_name == "status")) + continue; + vector<string>::iterator ite_str = find(defaultAttList.begin(), defaultAttList.end(), att_name); + if (ite_str == defaultAttList.end()) + { + cout2 << att_name << " is a UNWANTED dynamic attribute for device " << (*devlist_ptr)[i] << endl; + Tango::Attribute &att = dev->get_device_attr()->get_attr_by_name(att_name.c_str()); + dev->remove_attribute(att_list[att.get_attr_idx()], true, false); + --ite_att; + } + } + } + /*----- PROTECTED REGION ID(SnmpClass::erase_dynamic_attributes) ENABLED START -----*/ + + /*----- PROTECTED REGION END -----*/ // SnmpClass::erase_dynamic_attributes +} + +//-------------------------------------------------------- +/** + * Method : SnmpClass::get_attr_by_name() + * Description : returns Tango::Attr * object found by name + */ +//-------------------------------------------------------- +Tango::Attr *SnmpClass::get_attr_object_by_name(vector<Tango::Attr *> &att_list, string attname) +{ + vector<Tango::Attr *>::iterator it; + for (it=att_list.begin() ; it<att_list.end() ; ++it) + if ((*it)->get_name()==attname) + return (*it); + // Attr does not exist + return NULL; +} + + +/*----- PROTECTED REGION ID(SnmpClass::Additional Methods) ENABLED START -----*/ + +/*----- PROTECTED REGION END -----*/ // SnmpClass::Additional Methods +} // namespace diff --git a/src/SnmpClass.h b/src/SnmpClass.h new file mode 100644 index 0000000000000000000000000000000000000000..a2623a8ae311527271e0f5ea872352c39f62eec5 --- /dev/null +++ b/src/SnmpClass.h @@ -0,0 +1,160 @@ +/*----- PROTECTED REGION ID(SnmpClass.h) ENABLED START -----*/ +//============================================================================= +// +// file : SnmpClass.h +// +// description : Include for the Snmp root class. +// This class is the singleton class for +// the Snmp device class. +// It contains all properties and methods which the +// Snmp requires only once e.g. the commands. +// +// project : +// +// 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: alessandro.olivo $ +// +// $Revision: 1.2 $ +// $Date: 2017-08-07 15:02:23 $ +// +// $HeadURL: $ +// +//============================================================================= +// This file is generated by POGO +// (Program Obviously used to Generate tango Object) +//============================================================================= + + +#ifndef SnmpClass_H +#define SnmpClass_H + +#include <tango.h> +#include <Snmp.h> + + +/*----- PROTECTED REGION END -----*/ // SnmpClass.h + + +namespace Snmp_ns +{ +/*----- PROTECTED REGION ID(SnmpClass::classes for dynamic creation) ENABLED START -----*/ + + +/*----- PROTECTED REGION END -----*/ // SnmpClass::classes for dynamic creation + +//========================================= +// Define classes for commands +//========================================= +// Command Get class definition +class GetClass : public Tango::Command +{ +public: + GetClass(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) {}; + + GetClass(const char *name, + Tango::CmdArgType in, + Tango::CmdArgType out) + :Command(name,in,out) {}; + ~GetClass() {}; + + 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<Snmp *>(dev))->is_Get_allowed(any);} +}; + +// Command Set class definition +class SetClass : public Tango::Command +{ +public: + SetClass(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) {}; + + SetClass(const char *name, + Tango::CmdArgType in, + Tango::CmdArgType out) + :Command(name,in,out) {}; + ~SetClass() {}; + + 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<Snmp *>(dev))->is_Set_allowed(any);} +}; + + +/** + * The SnmpClass singleton definition + */ + +#ifdef _TG_WINDOWS_ +class __declspec(dllexport) SnmpClass : public Tango::DeviceClass +#else +class SnmpClass : public Tango::DeviceClass +#endif +{ + /*----- PROTECTED REGION ID(SnmpClass::Additionnal DServer data members) ENABLED START -----*/ + + + /*----- PROTECTED REGION END -----*/ // SnmpClass::Additionnal DServer data members + + public: + // write class properties data members + Tango::DbData cl_prop; + Tango::DbData cl_def_prop; + Tango::DbData dev_def_prop; + + // Method prototypes + static SnmpClass *init(const char *); + static SnmpClass *instance(); + ~SnmpClass(); + Tango::DbDatum get_class_property(string &); + Tango::DbDatum get_default_device_property(string &); + Tango::DbDatum get_default_class_property(string &); + + protected: + SnmpClass(string &); + static SnmpClass *_instance; + void command_factory(); + void attribute_factory(vector<Tango::Attr *> &); + void pipe_factory(); + void write_class_property(); + void set_default_property(); + void get_class_property(); + string get_cvstag(); + string get_cvsroot(); + + private: + void device_factory(const Tango::DevVarStringArray *); + void create_static_attribute_list(vector<Tango::Attr *> &); + void erase_dynamic_attributes(const Tango::DevVarStringArray *,vector<Tango::Attr *> &); + vector<string> defaultAttList; + Tango::Attr *get_attr_object_by_name(vector<Tango::Attr *> &att_list, string attname); +}; + +} // End of namespace + +#endif // Snmp_H diff --git a/src/SnmpClient.cpp b/src/SnmpClient.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e1696737539a50866b161f36650ee323cb0ceecd --- /dev/null +++ b/src/SnmpClient.cpp @@ -0,0 +1,430 @@ +/*----- PROTECTED REGION ID(SnmpClient.cpp) ENABLED START -----*/ +static const char *RcsId = "$Id: SnmpClient.cpp,v 1.3 2018-05-22 12:10:39 alessio Exp $"; +//============================================================================= +// +// file : SnmpClient.cpp +// +// description : C++ source for the SnmpClient class and its commands. +// The class is derived from Device. It represents the +// CORBA servant object which will be accessed from the +// network. All commands which can be executed on the +// SnmpClient are implemented in this file. +// +// project : Snmp proxy interface +// +// 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: alessio $ +// +// $Revision: 1.3 $ +// $Date: 2018-05-22 12:10:39 $ +// +// $HeadURL: $ +// +//============================================================================= +// This file is generated by POGO +// (Program Obviously used to Generate tango Object) +//============================================================================= + + +#include <SnmpClient.h> +#include <SnmpClientClass.h> + +/*----- PROTECTED REGION END -----*/ // SnmpClient.cpp + +/** + * SnmpClient class description: + * + */ + +//================================================================ +// The following table gives the correspondence +// between command and method names. +// +// Command name | Method name +//================================================================ +// State | Inherited (no method) +// Status | Inherited (no method) +//================================================================ + +//================================================================ +// Attributes managed is: +//================================================================ +//================================================================ + +namespace SnmpClient_ns +{ +/*----- PROTECTED REGION ID(SnmpClient::namespace_starting) ENABLED START -----*/ + +// static initializations + +/*----- PROTECTED REGION END -----*/ // SnmpClient::namespace_starting + +//-------------------------------------------------------- +/** + * Method : SnmpClient::SnmpClient() + * Description : Constructors for a Tango device + * implementing the classSnmpClient + */ +//-------------------------------------------------------- +SnmpClient::SnmpClient(Tango::DeviceClass *cl, string &s) + : TANGO_BASE_CLASS(cl, s.c_str()) +{ + /*----- PROTECTED REGION ID(SnmpClient::constructor_1) ENABLED START -----*/ + init_device(); + + /*----- PROTECTED REGION END -----*/ // SnmpClient::constructor_1 +} +//-------------------------------------------------------- +SnmpClient::SnmpClient(Tango::DeviceClass *cl, const char *s) + : TANGO_BASE_CLASS(cl, s) +{ + /*----- PROTECTED REGION ID(SnmpClient::constructor_2) ENABLED START -----*/ + init_device(); + + /*----- PROTECTED REGION END -----*/ // SnmpClient::constructor_2 +} +//-------------------------------------------------------- +SnmpClient::SnmpClient(Tango::DeviceClass *cl, const char *s, const char *d) + : TANGO_BASE_CLASS(cl, s, d) +{ + /*----- PROTECTED REGION ID(SnmpClient::constructor_3) ENABLED START -----*/ + init_device(); + + /*----- PROTECTED REGION END -----*/ // SnmpClient::constructor_3 +} + +//-------------------------------------------------------- +/** + * Method : SnmpClient::delete_device() + * Description : will be called at device destruction or at init command + */ +//-------------------------------------------------------- +void SnmpClient::delete_device() +{ + DEBUG_STREAM << "SnmpClient::delete_device() " << device_name << endl; + /*----- PROTECTED REGION ID(SnmpClient::delete_device) ENABLED START -----*/ + + // Delete device allocated objects + if (device_proxy) + delete device_proxy; + /*----- PROTECTED REGION END -----*/ // SnmpClient::delete_device +} + +//-------------------------------------------------------- +/** + * Method : SnmpClient::init_device() + * Description : will be called at device initialization. + */ +//-------------------------------------------------------- +void SnmpClient::init_device() +{ + DEBUG_STREAM << "SnmpClient::init_device() create device " << device_name << endl; + /*----- PROTECTED REGION ID(SnmpClient::init_device_before) ENABLED START -----*/ + + // Initialization before get_device_property() call + device_proxy = NULL; + /*----- PROTECTED REGION END -----*/ // SnmpClient::init_device_before + + + // Get the device properties from database + get_device_property(); + + // No longer if mandatory property not set. + if (mandatoryNotDefined) + return; + + /*----- PROTECTED REGION ID(SnmpClient::init_device) ENABLED START -----*/ + + // Initialize device + try + { + device_proxy = new Tango::DeviceProxy(deviceName); + + if (Tango::Util::instance()->is_svr_starting() == false && Tango::Util::instance()->is_device_restarting(device_name)==false) + initialize(); + } + catch(...) + {} + /*----- PROTECTED REGION END -----*/ // SnmpClient::init_device +} + +//-------------------------------------------------------- +/** + * Method : SnmpClient::get_device_property() + * Description : Read database to initialize property data members. + */ +//-------------------------------------------------------- +void SnmpClient::get_device_property() +{ + /*----- PROTECTED REGION ID(SnmpClient::get_device_property_before) ENABLED START -----*/ + + // Initialize property data members + + /*----- PROTECTED REGION END -----*/ // SnmpClient::get_device_property_before + + mandatoryNotDefined = false; + + // Read device properties from database. + Tango::DbData dev_prop; + dev_prop.push_back(Tango::DbDatum("DeviceName")); + dev_prop.push_back(Tango::DbDatum("Timeout")); + + // 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 SnmpClientClass to get class property + Tango::DbDatum def_prop, cl_prop; + SnmpClientClass *ds_class = + (static_cast<SnmpClientClass *>(get_device_class())); + int i = -1; + + // Try to initialize DeviceName from class property + cl_prop = ds_class->get_class_property(dev_prop[++i].name); + if (cl_prop.is_empty()==false) cl_prop >> deviceName; + else { + // Try to initialize DeviceName from default device value + def_prop = ds_class->get_default_device_property(dev_prop[i].name); + if (def_prop.is_empty()==false) def_prop >> deviceName; + } + // And try to extract DeviceName value from database + if (dev_prop[i].is_empty()==false) dev_prop[i] >> deviceName; + // Property StartDsPath is mandatory, check if has been defined in database. + check_mandatory_property(cl_prop, dev_prop[i]); + + // Try to initialize Timeout from class property + cl_prop = ds_class->get_class_property(dev_prop[++i].name); + if (cl_prop.is_empty()==false) cl_prop >> timeout; + else { + // Try to initialize Timeout from default device value + def_prop = ds_class->get_default_device_property(dev_prop[i].name); + if (def_prop.is_empty()==false) def_prop >> timeout; + } + // And try to extract Timeout value from database + if (dev_prop[i].is_empty()==false) dev_prop[i] >> timeout; + + } + + /*----- PROTECTED REGION ID(SnmpClient::get_device_property_after) ENABLED START -----*/ + + // Check device property data members init + + /*----- PROTECTED REGION END -----*/ // SnmpClient::get_device_property_after +} +//-------------------------------------------------------- +/** + * Method : SnmpClient::check_mandatory_property() + * Description : For mandatory properties check if defined in database. + */ +//-------------------------------------------------------- +void SnmpClient::check_mandatory_property(Tango::DbDatum &class_prop, Tango::DbDatum &dev_prop) +{ + // Check if all properties are empty + if (class_prop.is_empty() && dev_prop.is_empty()) + { + TangoSys_OMemStream tms; + tms << endl <<"Property \'" << dev_prop.name; + if (Tango::Util::instance()->_UseDb==true) + tms << "\' is mandatory but not defined in database"; + else + tms << "\' is mandatory but cannot be defined without database"; + string status(get_status()); + status += tms.str(); + set_status(status); + mandatoryNotDefined = true; + /*----- PROTECTED REGION ID(SnmpClient::check_mandatory_property) ENABLED START -----*/ + cerr << tms.str() << " for " << device_name << endl; + + /*----- PROTECTED REGION END -----*/ // SnmpClient::check_mandatory_property + } +} + + +//-------------------------------------------------------- +/** + * Method : SnmpClient::always_executed_hook() + * Description : method always executed before any command is executed + */ +//-------------------------------------------------------- +void SnmpClient::always_executed_hook() +{ + DEBUG_STREAM << "SnmpClient::always_executed_hook() " << device_name << endl; + if (mandatoryNotDefined) + { + string status(get_status()); + Tango::Except::throw_exception( + (const char *)"PROPERTY_NOT_SET", + status.c_str(), + (const char *)"SnmpClient::always_executed_hook()"); + } + /*----- PROTECTED REGION ID(SnmpClient::always_executed_hook) ENABLED START -----*/ + + // code always executed before all requests + + /*----- PROTECTED REGION END -----*/ // SnmpClient::always_executed_hook +} + +//-------------------------------------------------------- +/** + * Method : SnmpClient::read_attr_hardware() + * Description : Hardware acquisition for attributes + */ +//-------------------------------------------------------- +void SnmpClient::read_attr_hardware(TANGO_UNUSED(vector<long> &attr_list)) +{ + DEBUG_STREAM << "SnmpClient::read_attr_hardware(vector<long> &attr_list) entering... " << endl; + /*----- PROTECTED REGION ID(SnmpClient::read_attr_hardware) ENABLED START -----*/ + + // Add your own code + + /*----- PROTECTED REGION END -----*/ // SnmpClient::read_attr_hardware +} + + +//-------------------------------------------------------- +/** + * Method : SnmpClient::add_dynamic_attributes() + * Description : Create the dynamic attributes if any + * for specified device. + */ +//-------------------------------------------------------- +void SnmpClient::add_dynamic_attributes() +{ + /*----- PROTECTED REGION ID(SnmpClient::add_dynamic_attributes) ENABLED START -----*/ + + // Add your own code to create and add dynamic attributes if any + + /*----- PROTECTED REGION END -----*/ // SnmpClient::add_dynamic_attributes +} + +//-------------------------------------------------------- +/** + * Method : SnmpClient::add_dynamic_commands() + * Description : Create the dynamic commands if any + * for specified device. + */ +//-------------------------------------------------------- +void SnmpClient::add_dynamic_commands() +{ + /*----- PROTECTED REGION ID(SnmpClient::add_dynamic_commands) ENABLED START -----*/ + + // Add your own code to create and add dynamic commands if any + + /*----- PROTECTED REGION END -----*/ // SnmpClient::add_dynamic_commands +} + +/*----- PROTECTED REGION ID(SnmpClient::namespace_ending) ENABLED START -----*/ + +// Additional Methods +void SnmpClient::initialize() +{ + DEBUG_STREAM << "SnmpClient::initialized() - " << device_name << endl; + + if(!device_proxy) + Tango::Except::throw_exception("device_proxy not initialized", "Snmp \"GET\" request can't be sent", "SnmpClient::initialized()"); + + device_proxy->command_inout("Init"); +} + +void SnmpClient::get(const string &oid, string &reply) +{ + vector<string> vs_oids; + vs_oids.push_back(oid); + vector<string> vs_replies(1); + get(vs_oids, vs_replies); + reply = vs_replies[0]; +} +void SnmpClient::get(vector<string> &oids, vector<string> &replies) +{ + DEBUG_STREAM << "SnmpClient::get() - " << device_name << endl; + + if(!device_proxy) + Tango::Except::throw_exception("device_proxy not initialized", "Snmp \"GET\" request can't be sent", "SnmpClient::get()"); + + Tango::DeviceData ddin, ddout; + Tango::DevVarLongStringArray *dvlsa = new Tango::DevVarLongStringArray(); + size_t oids_num = oids.size(); + dvlsa->lvalue.length(1); + dvlsa->lvalue[0] = timeout; + dvlsa->svalue.length(oids_num); + for(size_t i = 0; i < oids_num; i++) + dvlsa->svalue[i] = CORBA::string_dup(oids[i].c_str()); + ddin << dvlsa; + ddout = device_proxy->command_inout("Get", ddin); + const Tango::DevVarStringArray *dvsa; + ddout >> dvsa; + for(size_t i = 0; i < oids_num; i++) + { + replies[i] = (*dvsa)[i]; + + DEBUG_STREAM << "SnmpClient::get() - oid = <"<< oids[i] << "> - returned value = <"<< replies[i] << ">" << endl; + } +} + +void SnmpClient::set(const string &oid, const string &value, const string &expected_reply) +{ + vector<string> vs_oids; + vs_oids.push_back(oid); + vector<string> vs_values; + vs_values.push_back(value); + vector<string> vs_expected_replies; + vs_expected_replies.push_back(expected_reply); + set(vs_oids, vs_values, vs_expected_replies); +} +void SnmpClient::set(vector<string> &oids, vector<string> &values, vector<string> &expected_replies) +{ + DEBUG_STREAM << "SnmpClient::set() - " << device_name << endl; + + if(!device_proxy) + Tango::Except::throw_exception("device_proxy not initialized", "Snmp \"SET\" request can't be sent", "SnmpClient::set()"); + + Tango::DeviceData ddin, ddout; + Tango::DevVarLongStringArray *dvlsa = new Tango::DevVarLongStringArray(); + size_t oids_num = oids.size(); + dvlsa->lvalue.length(1); + dvlsa->lvalue[0] = timeout; + dvlsa->svalue.length(2 * oids_num); + for (size_t i = 0; i < oids_num; i++ ) + { + dvlsa->svalue[i * 2] = CORBA::string_dup(oids[i].c_str()); + dvlsa->svalue[i * 2 + 1] = CORBA::string_dup(values[i].c_str()); + } + ddin << dvlsa; + ddout = device_proxy->command_inout("Set", ddin); + const Tango::DevVarStringArray *dvsa; + ddout >> dvsa; + string reply; + string mismatch_info(""); + for (size_t i = 0; i < oids_num; i++) + { + reply = (*dvsa)[i]; + if (reply != expected_replies[i]) + mismatch_info += " - " + oids[i] + " (expected reply: " + expected_replies[i] + " but returned: " + reply + ")\n"; + + DEBUG_STREAM << "SnmpClient::set() - oid = <"<< oids[i] << "> returned value = <"<< reply << ">" << endl; + } + if(!mismatch_info.empty()) + Tango::Except::throw_exception("", + "Mismatch between expected reply and actual reply for the following oids: \n" + mismatch_info, + "SnmpClient::set()"); +} + +/*----- PROTECTED REGION END -----*/ // SnmpClient::namespace_ending +} // namespace diff --git a/src/SnmpClient.h b/src/SnmpClient.h new file mode 100644 index 0000000000000000000000000000000000000000..649350e6d71f191e77a7e8690a6bc6ec512fea19 --- /dev/null +++ b/src/SnmpClient.h @@ -0,0 +1,258 @@ +/*----- PROTECTED REGION ID(SnmpClient.h) ENABLED START -----*/ +//============================================================================= +// +// file : SnmpClient.h +// +// description : Include file for the SnmpClient class +// +// project : Snmp proxy interface +// +// 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: alessandro.olivo $ +// +// $Revision: 1.2 $ +// $Date: 2017-10-04 15:23:46 $ +// +// $HeadURL: $ +// +//============================================================================= +// This file is generated by POGO +// (Program Obviously used to Generate tango Object) +//============================================================================= + + +#ifndef SnmpClient_H +#define SnmpClient_H + +#include <tango.h> + + +/*----- PROTECTED REGION END -----*/ // SnmpClient.h + +/** + * SnmpClient class description: + * + */ + +namespace SnmpClient_ns +{ +/*----- PROTECTED REGION ID(SnmpClient::Additional Class Declarations) ENABLED START -----*/ + +// Additional Class Declarations + +/*----- PROTECTED REGION END -----*/ // SnmpClient::Additional Class Declarations + +class SnmpClient : public TANGO_BASE_CLASS +{ + +/*----- PROTECTED REGION ID(SnmpClient::Data Members) ENABLED START -----*/ + +// Add your own data members + Tango::DeviceProxy *device_proxy; + +/*----- PROTECTED REGION END -----*/ // SnmpClient::Data Members + +// Device property data members +public: + // DeviceName: + string deviceName; + // Timeout: Timeout for snmp responses + Tango::DevUShort timeout; + + bool mandatoryNotDefined; + + +// Constructors and destructors +public: + /** + * Constructs a newly device object. + * + * @param cl Class. + * @param s Device Name + */ + SnmpClient(Tango::DeviceClass *cl,string &s); + /** + * Constructs a newly device object. + * + * @param cl Class. + * @param s Device Name + */ + SnmpClient(Tango::DeviceClass *cl,const char *s); + /** + * Constructs a newly device object. + * + * @param cl Class. + * @param s Device name + * @param d Device description. + */ + SnmpClient(Tango::DeviceClass *cl,const char *s,const char *d); + /** + * The device object destructor. + */ + ~SnmpClient() {delete_device();}; + + +// Miscellaneous methods +public: + /* + * will be called at device destruction or at init command. + */ + void delete_device(); + /* + * Initialize the device + */ + virtual void init_device(); + /* + * Read the device properties from database + */ + void get_device_property(); + /* + * Always executed method before execution command method. + */ + virtual void always_executed_hook(); + + /* + * Check if mandatory property has been set + */ + void check_mandatory_property(Tango::DbDatum &class_prop, Tango::DbDatum &dev_prop); + +// Attribute methods +public: + //-------------------------------------------------------- + /* + * Method : SnmpClient::read_attr_hardware() + * Description : Hardware acquisition for attributes. + */ + //-------------------------------------------------------- + virtual void read_attr_hardware(vector<long> &attr_list); + + + //-------------------------------------------------------- + /** + * Method : SnmpClient::add_dynamic_attributes() + * Description : Add dynamic attributes if any. + */ + //-------------------------------------------------------- + void add_dynamic_attributes(); + + + + +// Command related methods +public: + + + //-------------------------------------------------------- + /** + * Method : SnmpClient::add_dynamic_commands() + * Description : Add dynamic commands if any. + */ + //-------------------------------------------------------- + void add_dynamic_commands(); + +/*----- PROTECTED REGION ID(SnmpClient::Additional Method prototypes) ENABLED START -----*/ + +// Additional Method prototypes + +//void get(const string &oids, string &response); +void initialize(); + +void get(vector<string> &oids, vector<string> &replies); +void get(const string &oid, string &reply); + +template<typename T> void get(const string &oid, T &reply) +{ + string str_reply; + get(oid, str_reply); + convert(str_reply, reply); +} +template<typename T> void get(vector<string> &oids, vector<T> &replies) +{ + vector<string> vs_replies(oids.size()); + get(oids, vs_replies); + convert(vs_replies, replies); +} + + +void set(vector<string> &oids, vector<string> &values, vector<string> &expected_replies); +void set(const string &oid, const string &value, const string &expected_reply); + +template<typename F> void set(const string &oid, const F &value) +{ + set(oid, value, value); +} +template<typename F> void set(vector<string> &oids, vector<F> &values) +{ + set(oids, values, values); +} +template<typename F, typename T> void set(const string &oid, const F &value, const T &expected_reply) +{ + string str_value, str_expected_reply; + convert(value, str_value); + convert(expected_reply, str_expected_reply); + set(oid, str_value, str_expected_reply); +} +template<typename F, typename T> void set(vector<string> &oids, vector<F> &values, vector<T> &expected_replies) +{ + vector<string> vs_values(oids.size()); + vector<string> vs_expected_replies(oids.size()); + convert(values, vs_values); + convert(expected_replies, vs_expected_replies); + set(oids, vs_values, vs_expected_replies); +} + + +template<typename F, typename T> void convert(const F &reply, T &reply_converted) +{ + stringstream conv; + conv << reply << flush; + if (conv.fail()) + Tango::Except::throw_exception( + "API_ConverionError", + "Conversion fail " + conv.str(), + "SnmpClient::convert()"); + conv >> reply_converted; +} +template<typename F, typename T> void convert(vector<F> &replies, vector<T> &replies_converted) +{ + for (size_t i = 0; i < replies.size(); i++ ) + convert(replies[i], replies_converted[i]); +} +template<typename F> void convert(const F &reply, string &reply_converted) +{ + stringstream conv; + conv << reply << flush; + if (conv.fail()) + Tango::Except::throw_exception( + "API_ConverionError", + "Conversion fail " + conv.str(), + "SnmpClient::convert()"); + reply_converted = conv.str(); +} + +/*----- PROTECTED REGION END -----*/ // SnmpClient::Additional Method prototypes +}; + +/*----- PROTECTED REGION ID(SnmpClient::Additional Classes Definitions) ENABLED START -----*/ + +// Additional Classes Definitions + +/*----- PROTECTED REGION END -----*/ // SnmpClient::Additional Classes Definitions + +} // End of namespace + +#endif // SnmpClient_H diff --git a/src/SnmpClient.xmi b/src/SnmpClient.xmi new file mode 100644 index 0000000000000000000000000000000000000000..9ea02b600b242b2a843a4b863a043f8698619186 --- /dev/null +++ b/src/SnmpClient.xmi @@ -0,0 +1,37 @@ +<?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="SnmpClient" pogoRevision="9.1"> + <description description="" title="Snmp proxy interface" sourcePath="/home/alessandro/devel/fermi/servers/snmp/src" language="Cpp" filestogenerate="XMI file,Code files,Protected Regions" license="GPL" copyright="" hasMandatoryProperty="true" hasConcreteProperty="true" hasAbstractCommand="false" hasAbstractAttribute="false"> + <inheritances classname="Device_Impl" sourcePath=""/> + <identification contact="at gmail.com - alessandro.olivo89" author="alessandro.olivo89" emailDomain="gmail.com" classFamily="Communication" siteSpecific="" platform="All Platforms" bus="Not Applicable" manufacturer="Elettra Sincrotrone" reference=""/> + </description> + <deviceProperties name="DeviceName" mandatory="true" description=""> + <type xsi:type="pogoDsl:StringType"/> + <status abstract="false" inherited="false" concrete="true" concreteHere="true"/> + </deviceProperties> + <deviceProperties name="Timeout" description="Timeout for snmp responses"> + <type xsi:type="pogoDsl:UShortType"/> + <status abstract="false" inherited="false" concrete="true" concreteHere="true"/> + <DefaultPropValue>1500</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"/> + </argin> + <argout description="Device state"> + <type xsi:type="pogoDsl:StateType"/> + </argout> + <status abstract="true" inherited="true" concrete="true"/> + </commands> + <commands name="Status" description="This command gets the device status (stored in its device_status data member) and returns it to the caller." execMethod="dev_status" displayLevel="OPERATOR" polledPeriod="0"> + <argin description="none"> + <type xsi:type="pogoDsl:VoidType"/> + </argin> + <argout description="Device status"> + <type xsi:type="pogoDsl:ConstStringType"/> + </argout> + <status abstract="true" inherited="true" concrete="true"/> + </commands> + <preferences docHome="./doc_html" makefileHome="/usr/local/tango-9.2.2/share/pogo/preferences"/> + </classes> +</pogoDsl:PogoSystem> diff --git a/src/SnmpClientClass.cpp b/src/SnmpClientClass.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a4cb1fe3caacdb530d627ac0faed72753170f025 --- /dev/null +++ b/src/SnmpClientClass.cpp @@ -0,0 +1,602 @@ +/*----- PROTECTED REGION ID(SnmpClientClass.cpp) ENABLED START -----*/ +static const char *RcsId = "$Id: SnmpClientClass.cpp,v 1.3 2018-05-22 12:29:24 alessio Exp $"; +static const char *TagName = "SnmpClient $Name: $"; +static const char *CvsPath = "$Source: /home/cvsadm/cvsroot/fermi/servers/snmp/src/SnmpClientClass.cpp,v $"; +static const char *SvnPath = "$HeadURL: $"; +static const char *HttpServer = "http://www.esrf.eu/computing/cs/tango/tango_doc/ds_doc/"; +//============================================================================= +// +// file : SnmpClientClass.cpp +// +// description : C++ source for the SnmpClientClass. +// A singleton class derived from DeviceClass. +// It implements the command and attribute list +// and all properties and methods required +// by the SnmpClient once per process. +// +// project : Snmp proxy interface +// +// 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: alessio $ +// +// $Revision: 1.3 $ +// $Date: 2018-05-22 12:29:24 $ +// +// $HeadURL: $ +// +//============================================================================= +// This file is generated by POGO +// (Program Obviously used to Generate tango Object) +//============================================================================= + + +#include <SnmpClientClass.h> + +/*----- PROTECTED REGION END -----*/ // SnmpClientClass.cpp + +//------------------------------------------------------------------- +/** + * Create SnmpClientClass singleton and + * return it in a C function for Python usage + */ +//------------------------------------------------------------------- +extern "C" { +#ifdef _TG_WINDOWS_ + +__declspec(dllexport) + +#endif + + Tango::DeviceClass *_create_SnmpClient_class(const char *name) { + return SnmpClient_ns::SnmpClientClass::init(name); + } +} + +namespace SnmpClient_ns +{ +//=================================================================== +// Initialize pointer for singleton pattern +//=================================================================== +SnmpClientClass *SnmpClientClass::_instance = NULL; + +//-------------------------------------------------------- +/** + * method : SnmpClientClass::SnmpClientClass(string &s) + * description : constructor for the SnmpClientClass + * + * @param s The class name + */ +//-------------------------------------------------------- +SnmpClientClass::SnmpClientClass(string &s):Tango::DeviceClass(s) +{ + cout2 << "Entering SnmpClientClass constructor" << endl; + set_default_property(); + write_class_property(); + + /*----- PROTECTED REGION ID(SnmpClientClass::constructor) ENABLED START -----*/ + + /*----- PROTECTED REGION END -----*/ // SnmpClientClass::constructor + + cout2 << "Leaving SnmpClientClass constructor" << endl; +} + +//-------------------------------------------------------- +/** + * method : SnmpClientClass::~SnmpClientClass() + * description : destructor for the SnmpClientClass + */ +//-------------------------------------------------------- +SnmpClientClass::~SnmpClientClass() +{ + /*----- PROTECTED REGION ID(SnmpClientClass::destructor) ENABLED START -----*/ + + /*----- PROTECTED REGION END -----*/ // SnmpClientClass::destructor + + _instance = NULL; +} + + +//-------------------------------------------------------- +/** + * method : SnmpClientClass::init + * description : Create the object if not already done. + * Otherwise, just return a pointer to the object + * + * @param name The class name + */ +//-------------------------------------------------------- +SnmpClientClass *SnmpClientClass::init(const char *name) +{ + if (_instance == NULL) + { + try + { + string s(name); + _instance = new SnmpClientClass(s); + } + catch (bad_alloc &) + { + throw; + } + } + return _instance; +} + +//-------------------------------------------------------- +/** + * method : SnmpClientClass::instance + * description : Check if object already created, + * and return a pointer to the object + */ +//-------------------------------------------------------- +SnmpClientClass *SnmpClientClass::instance() +{ + if (_instance == NULL) + { + cerr << "Class is not initialised !!" << endl; + exit(-1); + } + return _instance; +} + + + +//=================================================================== +// Command execution method calls +//=================================================================== + +//=================================================================== +// Properties management +//=================================================================== +//-------------------------------------------------------- +/** + * Method : SnmpClientClass::get_class_property() + * Description : Get the class property for specified name. + */ +//-------------------------------------------------------- +Tango::DbDatum SnmpClientClass::get_class_property(string &prop_name) +{ + for (unsigned int i=0 ; i<cl_prop.size() ; i++) + if (cl_prop[i].name == prop_name) + return cl_prop[i]; + // if not found, returns an empty DbDatum + return Tango::DbDatum(prop_name); +} + +//-------------------------------------------------------- +/** + * Method : SnmpClientClass::get_default_device_property() + * Description : Return the default value for device property. + */ +//-------------------------------------------------------- +Tango::DbDatum SnmpClientClass::get_default_device_property(string &prop_name) +{ + for (unsigned int i=0 ; i<dev_def_prop.size() ; i++) + if (dev_def_prop[i].name == prop_name) + return dev_def_prop[i]; + // if not found, return an empty DbDatum + return Tango::DbDatum(prop_name); +} + +//-------------------------------------------------------- +/** + * Method : SnmpClientClass::get_default_class_property() + * Description : Return the default value for class property. + */ +//-------------------------------------------------------- +Tango::DbDatum SnmpClientClass::get_default_class_property(string &prop_name) +{ + for (unsigned int i=0 ; i<cl_def_prop.size() ; i++) + if (cl_def_prop[i].name == prop_name) + return cl_def_prop[i]; + // if not found, return an empty DbDatum + return Tango::DbDatum(prop_name); +} + + +//-------------------------------------------------------- +/** + * Method : SnmpClientClass::set_default_property() + * Description : Set default property (class and device) for wizard. + * For each property, add to wizard property name and description. + * If default value has been set, add it to wizard property and + * store it in a DbDatum. + */ +//-------------------------------------------------------- +void SnmpClientClass::set_default_property() +{ + string prop_name; + string prop_desc; + string prop_def; + vector<string> vect_data; + + // Set Default Class Properties + + // Set Default device Properties + prop_name = "DeviceName"; + prop_desc = ""; + 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 = "Timeout"; + prop_desc = "Timeout for snmp responses"; + prop_def = "1500"; + vect_data.clear(); + vect_data.push_back("1500"); + if (prop_def.length()>0) + { + Tango::DbDatum data(prop_name); + data << vect_data ; + dev_def_prop.push_back(data); + add_wiz_dev_prop(prop_name, prop_desc, prop_def); + } + else + add_wiz_dev_prop(prop_name, prop_desc); +} + +//-------------------------------------------------------- +/** + * Method : SnmpClientClass::write_class_property() + * Description : Set class description fields as property in database + */ +//-------------------------------------------------------- +void SnmpClientClass::write_class_property() +{ + // First time, check if database used + if (Tango::Util::_UseDb == false) + return; + + Tango::DbData data; + string classname = get_name(); + string header; + string::size_type start, end; + + // Put title + Tango::DbDatum title("ProjectTitle"); + string str_title("Snmp proxy interface"); + title << str_title; + data.push_back(title); + + // Put Description + Tango::DbDatum description("Description"); + vector<string> str_desc; + str_desc.push_back(""); + description << str_desc; + data.push_back(description); + + // put cvs or svn location + string filename("SnmpClient"); + filename += "Class.cpp"; + + // check for cvs information + string src_path(CvsPath); + start = src_path.find("/"); + if (start!=string::npos) + { + end = src_path.find(filename); + if (end>start) + { + string strloc = src_path.substr(start, end-start); + // Check if specific repository + start = strloc.find("/cvsroot/"); + if (start!=string::npos && start>0) + { + string repository = strloc.substr(0, start); + if (repository.find("/segfs/")!=string::npos) + strloc = "ESRF:" + strloc.substr(start, strloc.length()-start); + } + Tango::DbDatum cvs_loc("cvs_location"); + cvs_loc << strloc; + data.push_back(cvs_loc); + } + } + + // check for svn information + else + { + string src_path(SvnPath); + start = src_path.find("://"); + if (start!=string::npos) + { + end = src_path.find(filename); + if (end>start) + { + header = "$HeadURL: "; + start = header.length(); + string strloc = src_path.substr(start, (end-start)); + + Tango::DbDatum svn_loc("svn_location"); + svn_loc << strloc; + data.push_back(svn_loc); + } + } + } + + // Get CVS or SVN revision tag + + // CVS tag + string tagname(TagName); + header = "$Name: "; + start = header.length(); + string endstr(" $"); + + end = tagname.find(endstr); + if (end!=string::npos && end>start) + { + string strtag = tagname.substr(start, end-start); + Tango::DbDatum cvs_tag("cvs_tag"); + cvs_tag << strtag; + data.push_back(cvs_tag); + } + + // SVN tag + string svnpath(SvnPath); + header = "$HeadURL: "; + start = header.length(); + + end = svnpath.find(endstr); + if (end!=string::npos && end>start) + { + string strloc = svnpath.substr(start, end-start); + + string tagstr ("/tags/"); + start = strloc.find(tagstr); + if ( start!=string::npos ) + { + start = start + tagstr.length(); + end = strloc.find(filename); + string strtag = strloc.substr(start, end-start-1); + + Tango::DbDatum svn_tag("svn_tag"); + svn_tag << strtag; + data.push_back(svn_tag); + } + } + + // Get URL location + string httpServ(HttpServer); + if (httpServ.length()>0) + { + Tango::DbDatum db_doc_url("doc_url"); + db_doc_url << httpServ; + data.push_back(db_doc_url); + } + + // Put inheritance + Tango::DbDatum inher_datum("InheritedFrom"); + vector<string> inheritance; + inheritance.push_back("TANGO_BASE_CLASS"); + inher_datum << inheritance; + data.push_back(inher_datum); + + // Call database and and values + get_db_class()->put_property(data); +} + +//=================================================================== +// Factory methods +//=================================================================== + +//-------------------------------------------------------- +/** + * Method : SnmpClientClass::device_factory() + * Description : Create the device object(s) + * and store them in the device list + */ +//-------------------------------------------------------- +void SnmpClientClass::device_factory(const Tango::DevVarStringArray *devlist_ptr) +{ + /*----- PROTECTED REGION ID(SnmpClientClass::device_factory_before) ENABLED START -----*/ + + // Add your own code + + /*----- PROTECTED REGION END -----*/ // SnmpClientClass::device_factory_before + + // Create devices and add it into the device list + for (unsigned long i=0 ; i<devlist_ptr->length() ; i++) + { + cout4 << "Device name : " << (*devlist_ptr)[i].in() << endl; + device_list.push_back(new SnmpClient(this, (*devlist_ptr)[i])); + } + + // Manage dynamic attributes if any + erase_dynamic_attributes(devlist_ptr, get_class_attr()->get_attr_list()); + + // Export devices to the outside world + for (unsigned long i=1 ; i<=devlist_ptr->length() ; i++) + { + // Add dynamic attributes if any + SnmpClient *dev = static_cast<SnmpClient *>(device_list[device_list.size()-i]); + dev->add_dynamic_attributes(); + + // Check before if database used. + if ((Tango::Util::_UseDb == true) && (Tango::Util::_FileDb == false)) + export_device(dev); + else + export_device(dev, dev->get_name().c_str()); + } + + /*----- PROTECTED REGION ID(SnmpClientClass::device_factory_after) ENABLED START -----*/ + + // Add your own code + + /*----- PROTECTED REGION END -----*/ // SnmpClientClass::device_factory_after +} +//-------------------------------------------------------- +/** + * Method : SnmpClientClass::attribute_factory() + * Description : Create the attribute object(s) + * and store them in the attribute list + */ +//-------------------------------------------------------- +void SnmpClientClass::attribute_factory(vector<Tango::Attr *> &att_list) +{ + /*----- PROTECTED REGION ID(SnmpClientClass::attribute_factory_before) ENABLED START -----*/ + + // Add your own code + + /*----- PROTECTED REGION END -----*/ // SnmpClientClass::attribute_factory_before + + // Create a list of static attributes + create_static_attribute_list(get_class_attr()->get_attr_list()); + /*----- PROTECTED REGION ID(SnmpClientClass::attribute_factory_after) ENABLED START -----*/ + + // Add your own code + + /*----- PROTECTED REGION END -----*/ // SnmpClientClass::attribute_factory_after +} +//-------------------------------------------------------- +/** + * Method : SnmpClientClass::pipe_factory() + * Description : Create the pipe object(s) + * and store them in the pipe list + */ +//-------------------------------------------------------- +void SnmpClientClass::pipe_factory() +{ + /*----- PROTECTED REGION ID(SnmpClientClass::pipe_factory_before) ENABLED START -----*/ + + // Add your own code + + /*----- PROTECTED REGION END -----*/ // SnmpClientClass::pipe_factory_before + /*----- PROTECTED REGION ID(SnmpClientClass::pipe_factory_after) ENABLED START -----*/ + + // Add your own code + + /*----- PROTECTED REGION END -----*/ // SnmpClientClass::pipe_factory_after +} +//-------------------------------------------------------- +/** + * Method : SnmpClientClass::command_factory() + * Description : Create the command object(s) + * and store them in the command list + */ +//-------------------------------------------------------- +void SnmpClientClass::command_factory() +{ + /*----- PROTECTED REGION ID(SnmpClientClass::command_factory_before) ENABLED START -----*/ + + // Add your own code + + /*----- PROTECTED REGION END -----*/ // SnmpClientClass::command_factory_before + + + /*----- PROTECTED REGION ID(SnmpClientClass::command_factory_after) ENABLED START -----*/ + + // Add your own code + + /*----- PROTECTED REGION END -----*/ // SnmpClientClass::command_factory_after +} + +//=================================================================== +// Dynamic attributes related methods +//=================================================================== + +//-------------------------------------------------------- +/** + * method : SnmpClientClass::create_static_attribute_list + * description : Create the a list of static attributes + * + * @param att_list the ceated attribute list + */ +//-------------------------------------------------------- +void SnmpClientClass::create_static_attribute_list(vector<Tango::Attr *> &att_list) +{ + for (unsigned long i=0 ; i<att_list.size() ; i++) + { + string att_name(att_list[i]->get_name()); + transform(att_name.begin(), att_name.end(), att_name.begin(), ::tolower); + defaultAttList.push_back(att_name); + } + + cout2 << defaultAttList.size() << " attributes in default list" << endl; + + /*----- PROTECTED REGION ID(SnmpClientClass::create_static_att_list) ENABLED START -----*/ + + /*----- PROTECTED REGION END -----*/ // SnmpClientClass::create_static_att_list +} + + +//-------------------------------------------------------- +/** + * method : SnmpClientClass::erase_dynamic_attributes + * description : delete the dynamic attributes if any. + * + * @param devlist_ptr the device list pointer + * @param list of all attributes + */ +//-------------------------------------------------------- +void SnmpClientClass::erase_dynamic_attributes(const Tango::DevVarStringArray *devlist_ptr, vector<Tango::Attr *> &att_list) +{ + Tango::Util *tg = Tango::Util::instance(); + + for (unsigned long i=0 ; i<devlist_ptr->length() ; i++) + { + Tango::DeviceImpl *dev_impl = tg->get_device_by_name(((string)(*devlist_ptr)[i]).c_str()); + SnmpClient *dev = static_cast<SnmpClient *> (dev_impl); + + vector<Tango::Attribute *> &dev_att_list = dev->get_device_attr()->get_attribute_list(); + vector<Tango::Attribute *>::iterator ite_att; + for (ite_att=dev_att_list.begin() ; ite_att != dev_att_list.end() ; ++ite_att) + { + string att_name((*ite_att)->get_name_lower()); + if ((att_name == "state") || (att_name == "status")) + continue; + vector<string>::iterator ite_str = find(defaultAttList.begin(), defaultAttList.end(), att_name); + if (ite_str == defaultAttList.end()) + { + cout2 << att_name << " is a UNWANTED dynamic attribute for device " << (*devlist_ptr)[i] << endl; + Tango::Attribute &att = dev->get_device_attr()->get_attr_by_name(att_name.c_str()); + dev->remove_attribute(att_list[att.get_attr_idx()], true, false); + --ite_att; + } + } + } + /*----- PROTECTED REGION ID(SnmpClientClass::erase_dynamic_attributes) ENABLED START -----*/ + + /*----- PROTECTED REGION END -----*/ // SnmpClientClass::erase_dynamic_attributes +} + +//-------------------------------------------------------- +/** + * Method : SnmpClientClass::get_attr_by_name() + * Description : returns Tango::Attr * object found by name + */ +//-------------------------------------------------------- +Tango::Attr *SnmpClientClass::get_attr_object_by_name(vector<Tango::Attr *> &att_list, string attname) +{ + vector<Tango::Attr *>::iterator it; + for (it=att_list.begin() ; it<att_list.end() ; ++it) + if ((*it)->get_name()==attname) + return (*it); + // Attr does not exist + return NULL; +} + + +/*----- PROTECTED REGION ID(SnmpClientClass::Additional Methods) ENABLED START -----*/ + +/*----- PROTECTED REGION END -----*/ // SnmpClientClass::Additional Methods +} // namespace diff --git a/src/SnmpClientClass.h b/src/SnmpClientClass.h new file mode 100644 index 0000000000000000000000000000000000000000..5bd05868ba5df051e0021304f5081cbc78a1a561 --- /dev/null +++ b/src/SnmpClientClass.h @@ -0,0 +1,110 @@ +/*----- PROTECTED REGION ID(SnmpClientClass.h) ENABLED START -----*/ +//============================================================================= +// +// file : SnmpClientClass.h +// +// description : Include for the SnmpClient root class. +// This class is the singleton class for +// the SnmpClient device class. +// It contains all properties and methods which the +// SnmpClient requires only once e.g. the commands. +// +// project : Snmp proxy interface +// +// 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: alessandro.olivo $ +// +// $Revision: 1.1 $ +// $Date: 2017-08-07 15:04:44 $ +// +// $HeadURL: $ +// +//============================================================================= +// This file is generated by POGO +// (Program Obviously used to Generate tango Object) +//============================================================================= + + +#ifndef SnmpClientClass_H +#define SnmpClientClass_H + +#include <tango.h> +#include <SnmpClient.h> + + +/*----- PROTECTED REGION END -----*/ // SnmpClientClass.h + + +namespace SnmpClient_ns +{ +/*----- PROTECTED REGION ID(SnmpClientClass::classes for dynamic creation) ENABLED START -----*/ + + +/*----- PROTECTED REGION END -----*/ // SnmpClientClass::classes for dynamic creation + +/** + * The SnmpClientClass singleton definition + */ + +#ifdef _TG_WINDOWS_ +class __declspec(dllexport) SnmpClientClass : public Tango::DeviceClass +#else +class SnmpClientClass : public Tango::DeviceClass +#endif +{ + /*----- PROTECTED REGION ID(SnmpClientClass::Additionnal DServer data members) ENABLED START -----*/ + + + /*----- PROTECTED REGION END -----*/ // SnmpClientClass::Additionnal DServer data members + + public: + // write class properties data members + Tango::DbData cl_prop; + Tango::DbData cl_def_prop; + Tango::DbData dev_def_prop; + + // Method prototypes + static SnmpClientClass *init(const char *); + static SnmpClientClass *instance(); + ~SnmpClientClass(); + Tango::DbDatum get_class_property(string &); + Tango::DbDatum get_default_device_property(string &); + Tango::DbDatum get_default_class_property(string &); + + protected: + SnmpClientClass(string &); + static SnmpClientClass *_instance; + void command_factory(); + void attribute_factory(vector<Tango::Attr *> &); + void pipe_factory(); + void write_class_property(); + void set_default_property(); + void get_class_property(); + string get_cvstag(); + string get_cvsroot(); + + private: + void device_factory(const Tango::DevVarStringArray *); + void create_static_attribute_list(vector<Tango::Attr *> &); + void erase_dynamic_attributes(const Tango::DevVarStringArray *,vector<Tango::Attr *> &); + vector<string> defaultAttList; + Tango::Attr *get_attr_object_by_name(vector<Tango::Attr *> &att_list, string attname); +}; + +} // End of namespace + +#endif // SnmpClient_H diff --git a/src/SnmpClientStateMachine.cpp b/src/SnmpClientStateMachine.cpp new file mode 100644 index 0000000000000000000000000000000000000000..95cb5cb5a2847e8c8f5ac7580d9cc78d7742e6f2 --- /dev/null +++ b/src/SnmpClientStateMachine.cpp @@ -0,0 +1,65 @@ +/*----- PROTECTED REGION ID(SnmpClientStateMachine.cpp) ENABLED START -----*/ +static const char *RcsId = "$Id: SnmpClientStateMachine.cpp,v 1.1 2017-08-07 15:04:44 alessandro.olivo Exp $"; +//============================================================================= +// +// file : SnmpClientStateMachine.cpp +// +// description : State machine file for the SnmpClient class +// +// project : Snmp proxy interface +// +// 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: alessandro.olivo $ +// +// $Revision: 1.1 $ +// $Date: 2017-08-07 15:04:44 $ +// +// $HeadURL: $ +// +//============================================================================= +// This file is generated by POGO +// (Program Obviously used to Generate tango Object) +//============================================================================= + +#include <SnmpClient.h> + +/*----- PROTECTED REGION END -----*/ // SnmpClient::SnmpClientStateMachine.cpp + +//================================================================ +// States | Description +//================================================================ + + +namespace SnmpClient_ns +{ +//================================================= +// Attributes Allowed Methods +//================================================= + + +//================================================= +// Commands Allowed Methods +//================================================= + + +/*----- PROTECTED REGION ID(SnmpClient::SnmpClientStateAllowed.AdditionalMethods) ENABLED START -----*/ + +// Additional Methods + +/*----- PROTECTED REGION END -----*/ // SnmpClient::SnmpClientStateAllowed.AdditionalMethods + +} // End of namespace diff --git a/src/SnmpStateMachine.cpp b/src/SnmpStateMachine.cpp new file mode 100644 index 0000000000000000000000000000000000000000..43f7f392befce741b31354960de065908d01beb3 --- /dev/null +++ b/src/SnmpStateMachine.cpp @@ -0,0 +1,99 @@ +/*----- PROTECTED REGION ID(SnmpStateMachine.cpp) ENABLED START -----*/ +static const char *RcsId = "$Id: SnmpStateMachine.cpp,v 1.3 2017-09-26 09:50:43 alessandro.olivo Exp $"; +//============================================================================= +// +// file : SnmpStateMachine.cpp +// +// description : State machine file for the Snmp class +// +// project : +// +// 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: alessandro.olivo $ +// +// $Revision: 1.3 $ +// $Date: 2017-09-26 09:50:43 $ +// +// $HeadURL: $ +// +//============================================================================= +// This file is generated by POGO +// (Program Obviously used to Generate tango Object) +//============================================================================= + +#include <Snmp.h> + +/*----- PROTECTED REGION END -----*/ // Snmp::SnmpStateMachine.cpp + +//================================================================ +// States | Description +//================================================================ + + +namespace Snmp_ns +{ +//================================================= +// Attributes Allowed Methods +//================================================= + + +//================================================= +// Commands Allowed Methods +//================================================= + +//-------------------------------------------------------- +/** + * Method : Snmp::is_Get_allowed() + * Description : Execution allowed for Get attribute + */ +//-------------------------------------------------------- +bool Snmp::is_Get_allowed(TANGO_UNUSED(const CORBA::Any &any)) +{ + // Not any excluded states for Get command. + /*----- PROTECTED REGION ID(Snmp::GetStateAllowed) ENABLED START -----*/ + if(sess_ptr == NULL) + return false; + + /*----- PROTECTED REGION END -----*/ // Snmp::GetStateAllowed + return true; +} + +//-------------------------------------------------------- +/** + * Method : Snmp::is_Set_allowed() + * Description : Execution allowed for Set attribute + */ +//-------------------------------------------------------- +bool Snmp::is_Set_allowed(TANGO_UNUSED(const CORBA::Any &any)) +{ + // Not any excluded states for Set command. + /*----- PROTECTED REGION ID(Snmp::SetStateAllowed) ENABLED START -----*/ + if(sess_ptr == NULL) + return false; + + /*----- PROTECTED REGION END -----*/ // Snmp::SetStateAllowed + return true; +} + + +/*----- PROTECTED REGION ID(Snmp::SnmpStateAllowed.AdditionalMethods) ENABLED START -----*/ + +// Additional Methods + +/*----- PROTECTED REGION END -----*/ // Snmp::SnmpStateAllowed.AdditionalMethods + +} // End of namespace diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b4202373a16112bc439b5a146505df95465bbf12 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,76 @@ +/*----- PROTECTED REGION ID(Snmp::main.cpp) ENABLED START -----*/ +static const char *RcsId = "$Id: main.cpp,v 1.1.1.1 2014-04-15 08:04:23 alessio Exp $"; +//============================================================================= +// +// file : main.cpp +// +// description : C++ source for the Snmp device server main. +// The main rule is to initialise (and create) the Tango +// system and to create the DServerClass singleton. +// The main should be the same for every Tango device server. +// +// project : +// +// 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: alessio $ +// +// $Revision: 1.1.1.1 $ +// $Date: 2014-04-15 08:04:23 $ +// +// $HeadURL: $ +// +//============================================================================= +// This file is generated by POGO +// (Program Obviously used to Generate tango Object) +//============================================================================= +#include <tango.h> + +int main(int argc,char *argv[]) +{ + try + { + // Initialise the device server + //---------------------------------------- + Tango::Util *tg = Tango::Util::init(argc,argv); + + // Create the device server singleton + // which will create everything + //---------------------------------------- + tg->server_init(false); + + // Run the endless loop + //---------------------------------------- + cout << "Ready to accept request" << endl; + tg->server_run(); + } + catch (bad_alloc &) + { + cout << "Can't allocate memory to store device object !!!" << endl; + cout << "Exiting" << endl; + } + catch (CORBA::Exception &e) + { + Tango::Except::print_exception(e); + + cout << "Received a CORBA_Exception" << endl; + cout << "Exiting" << endl; + } + Tango::Util::instance()->server_cleanup(); + return(0); +} + +/*----- PROTECTED REGION END -----*/ // Snmp::main.cpp