/* * $Id: XMLRPC2DI.cpp 145 2006-11-26 00:01:18Z sayer $ * * Copyright (C) 2007 iptego GmbH * * This file is part of sems, a free SIP media server. * * sems 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 2 of the License, or * (at your option) any later version. * * For a license to use the sems software under conditions * other than those described here, or to purchase support for this * software, please contact iptel.org by e-mail at the following addresses: * info@iptel.org * * sems 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 this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "XMLRPC2DI.h" #include "AmSessionContainer.h" #include "AmPlugIn.h" #include "log.h" #include "AmConfigReader.h" #include "AmUtils.h" #include "AmArg.h" #define MOD_NAME "xmlrpc2di" #define XMLRPC_PORT "8090" // default port EXPORT_PLUGIN_CLASS_FACTORY(XMLRPC2DI, MOD_NAME) XMLRPC2DI::XMLRPC2DI(string mod_name) : AmDynInvokeFactory(mod_name) { } int XMLRPC2DI::onLoad() { AmConfigReader cfg; if(cfg.loadFile(AmConfig::ModConfigPath + string(MOD_NAME ".conf"))) return -1; string conf_xmlrpc_port = cfg.getParameter("xmlrpc_port",XMLRPC_PORT); if (conf_xmlrpc_port.empty()) { ERROR("configuration: xmlrpc_port must be defined!\n"); return -1; } if (str2i(conf_xmlrpc_port, XMLRPCPort)) { ERROR("configuration: unable to decode xmlrpc_port value '%s'!\n", conf_xmlrpc_port.c_str()); return -1; } bool export_di = false; string direct_export = cfg.getParameter("direct_export",""); if (direct_export.length()) { DBG("direct_export interfaces: %s\n", direct_export.c_str()); } else { DBG("No direct_export interfaces.\n"); } string export_di_s = cfg.getParameter("export_di","yes"); if (export_di_s == "yes") { export_di = true; } DBG("XMLRPC Server: %snabling builtin method 'di'.\n", export_di?"E":"Not e"); server = new XMLRPC2DIServer(XMLRPCPort, export_di, direct_export); server->start(); return 0; } // XMLRPC server functions XMLRPC2DIServer::XMLRPC2DIServer(unsigned int port, bool di_export, string direct_export) : port(port), // register method 'calls' calls_method(&s), // register method 'get_loglevel' setloglevel_method(&s), // register method 'set_loglevel' getloglevel_method(&s) { DBG(" XMLRPC Server: enabled builtin method 'calls'\n"); DBG("XMLRPC Server: enabled builtin method 'get_loglevel'\n"); DBG("XMLRPC Server: enabled builtin method 'set_loglevel'\n"); // export all methods via 'di' function? if (di_export) { // register method 'di' di_method = new XMLRPC2DIServerDIMethod(&s); } vector export_ifaces = explode(direct_export, ";"); for(vector::iterator it=export_ifaces.begin(); it != export_ifaces.end(); it++) { registerMethods(*it); } DBG("Initialized XMLRPC2DIServer with: \n"); DBG(" port = %u\n", port); } /** register all methods on xmlrpc server listed by the iface * in _list function */ void XMLRPC2DIServer::registerMethods(const std::string& iface) { try { AmDynInvokeFactory* di_f = AmPlugIn::instance()->getFactory4Di(iface); if(NULL == di_f){ ERROR("DI interface '%s' could not be found. Missing load_plugins?\n", iface.c_str()); return; } AmDynInvoke* di = di_f->getInstance(); if(NULL == di){ ERROR("could not get DI instance from '%s'.\n", iface.c_str()); return; } AmArg dummy, fct_list; di->invoke("_list", dummy, fct_list); for (unsigned int i=0;igetSize(); DBG("XMLRPC2DI: calls = %d\n", res); result = res; } void XMLRPC2DIServerGetLoglevelMethod::execute(XmlRpcValue& params, XmlRpcValue& result) { int res = log_level; DBG("XMLRPC2DI: get_loglevel returns %d\n", res); result = res; } void XMLRPC2DIServerSetLoglevelMethod::execute(XmlRpcValue& params, XmlRpcValue& result) { log_level = params[0]; DBG("XMLRPC2DI: set log level to %d.\n", (int)params[0]); result = "200 OK"; } void XMLRPC2DIServerDIMethod::execute(XmlRpcValue& params, XmlRpcValue& result) { try { if (params.size() < 2) { DBG("XMLRPC2DI: ERROR: need at least factory name" " and function name to call\n"); throw XmlRpcException("need at least factory name" " and function name to call", 400); } string fact_name = params[0]; string fct_name = params[1]; DBG("XMLRPC2DI: factory '%s' function '%s'\n", fact_name.c_str(), fct_name.c_str()); // get args AmArg args; XMLRPC2DIServer::xmlrpcval2amarg(params, args, 2); AmDynInvokeFactory* di_f = AmPlugIn::instance()->getFactory4Di(fact_name); if(!di_f){ throw XmlRpcException("could not get factory", 500); } AmDynInvoke* di = di_f->getInstance(); if(!di){ throw XmlRpcException("could not get instance from factory", 500); } AmArg ret; di->invoke(fct_name, args, ret); XMLRPC2DIServer::amarg2xmlrpcval(ret, result); } catch (const XmlRpcException& e) { throw; } catch (const AmDynInvoke::NotImplemented& e) { throw XmlRpcException("Exception: AmDynInvoke::NotImplemented: " + e.what, 504); } catch (const AmArg::OutOfBoundsException& e) { throw XmlRpcException("Exception: AmArg out of bounds - paramter number mismatch.", 300); } catch (const AmArg::TypeMismatchException& e) { throw XmlRpcException("Exception: Type mismatch in arguments.", 300); } catch (const string& e) { throw XmlRpcException("Exception: "+e, 500); } catch (...) { throw XmlRpcException("Exception occured.", 500); } } void XMLRPC2DIServer::xmlrpcval2amarg(XmlRpcValue& v, AmArg& a, unsigned int start_index) { if (v.valid()) { for (int i=start_index; igetInstance(); if(NULL == di){ throw XmlRpcException("could not get instance from factory", 500); } AmArg args, ret; XMLRPC2DIServer::xmlrpcval2amarg(params, args); DBG("XMLRPC2DI '%s': function '%s'\n", server_method_name.c_str(), di_method_name.c_str()); di->invoke(di_method_name, args, ret); XMLRPC2DIServer::amarg2xmlrpcval(ret, result); } catch (const XmlRpcException& e) { throw; } catch (const AmDynInvoke::NotImplemented& e) { throw XmlRpcException("Exception: AmDynInvoke::NotImplemented: " + e.what, 504); } catch (const AmArg::OutOfBoundsException& e) { throw XmlRpcException("Exception: AmArg out of bounds - paramter number mismatch.", 300); } catch (const AmArg::TypeMismatchException& e) { throw XmlRpcException("Exception: Type mismatch in arguments.", 300); } catch (const string& e) { throw XmlRpcException("Exception: "+e, 500); } catch (...) { throw XmlRpcException("Exception occured.", 500); } }