diff --git a/apps/reg_agent/Makefile b/apps/reg_agent/Makefile new file mode 100644 index 00000000..9d1f13aa --- /dev/null +++ b/apps/reg_agent/Makefile @@ -0,0 +1,7 @@ +plug_in_name = reg_agent + +module_ldflags = +module_cflags = + +COREPATH ?=../../core +include $(COREPATH)/plug-in/Makefile.app_module diff --git a/apps/reg_agent/RegistrationAgent.cpp b/apps/reg_agent/RegistrationAgent.cpp new file mode 100644 index 00000000..84870f2e --- /dev/null +++ b/apps/reg_agent/RegistrationAgent.cpp @@ -0,0 +1,200 @@ +/* + * $Id: RegistrationAgent.cpp,v 1.7.8.4 2005/08/31 13:54:29 rco Exp $ + * + * 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 "RegistrationAgent.h" +#include "AmConfig.h" +#include "AmUtils.h" + +#include "sems.h" +#include "log.h" + +#include "AmPlugIn.h" + +#define MOD_NAME "reg_agent" + +EXPORT_SESSION_FACTORY(RegistrationAgentFactory,MOD_NAME); + +RegistrationAgentFactory::RegistrationAgentFactory(const string& _app_name) + : AmSessionFactory(_app_name) +{ +} + +int RegistrationAgentFactory::onLoad() +{ + AmConfigReader cfg; + if(cfg.loadFile(AmConfig::ModConfigPath + string(MOD_NAME ".conf"))) + return -1; + + // get application specific global parameters + configureModule(cfg); + + // stay backwards compatible + RegInfo ri; + ri.domain = cfg.getParameter("domain",""); + ri.user = cfg.getParameter("user",""); + ri.display_name = cfg.getParameter("display_name",""); + ri.auth_user = cfg.getParameter("auth_user",""); + ri.passwd = cfg.getParameter("pwd",""); + + if (!ri.domain.length() || + !ri.user.length() || + !ri.display_name.length() || + !ri.auth_user.length() || + !ri.passwd.length()) { + ERROR("Account for registration not correctly configured.\n"); + ERROR("RegistrationAgent will not register any accounts.\n"); + return 0; + } + + DBG("Adding registration #%d (%s %s %s %s)\n", 0, + ri.domain.c_str(), ri.user.c_str(), ri.display_name.c_str(), ri.auth_user.c_str()); + + dialer.add_reg(ri); + + unsigned int ri_index = 1; + while (ri_index < 100) { + RegInfo ri; + ri.domain = cfg.getParameter("domain"+int2str(ri_index),""); + ri.user = cfg.getParameter("user"+int2str(ri_index),""); + ri.display_name = cfg.getParameter("display_name"+int2str(ri_index),""); + ri.auth_user = cfg.getParameter("auth_user"+int2str(ri_index),""); + ri.passwd = cfg.getParameter("pwd"+int2str(ri_index),""); + + if (!ri.domain.length() || + !ri.user.length() || + !ri.display_name.length() || + !ri.auth_user.length() || + !ri.passwd.length()) + break; + + DBG("Adding registration #%d (%s %s %s %s)\n", ri_index, + ri.domain.c_str(), ri.user.c_str(), ri.display_name.c_str(), ri.auth_user.c_str()); + dialer.add_reg(ri); + ri_index++; + } + + dialer.start(); + + return 0; +} + +void RegistrationAgentFactory::postEvent(AmEvent* ev) { + dialer.postEvent(ev); +} + +AmSession* RegistrationAgentFactory::onInvite(const AmSipRequest& req) +{ + return NULL; +} + + +void RegThread::add_reg(const RegInfo& ri) { + registrations.push_back(ri); +} + +void RegThread::create_registration(RegInfo& ri) { + AmDynInvokeFactory* di_f = AmPlugIn::instance()->getFactory4Di("registrar_client"); + if (di_f == NULL) { + ERROR("unable to get a registrar_client\n"); + } else { + AmDynInvoke* uac_auth_i = di_f->getInstance(); + if (uac_auth_i!=NULL) { + + DBG("calling createRegistration\n"); + AmArg di_args, reg_handle; + di_args.push(ri.domain.c_str()); + di_args.push(ri.user.c_str()); + di_args.push(ri.display_name.c_str()); // display name + di_args.push(ri.auth_user.c_str()); // auth_user + di_args.push(ri.passwd.c_str()); // pwd + di_args.push("reg_agent"); //sess_link + + uac_auth_i->invoke("createRegistration", di_args, reg_handle); + if (reg_handle.size()) + ri.handle = reg_handle.get(0).asCStr(); + } + } +} + +bool RegThread::check_registration(const RegInfo& ri) { + if (!ri.handle.length()) + return false; + AmDynInvokeFactory* di_f = AmPlugIn::instance()->getFactory4Di("registrar_client"); + if (di_f == NULL) { + ERROR("unable to get a registrar_client\n"); + } else { + AmDynInvoke* uac_auth_i = di_f->getInstance(); + if (uac_auth_i!=NULL) { + + AmArg di_args, res; + di_args.push(ri.handle.c_str()); + uac_auth_i->invoke("getRegistrationState", di_args, res); + if (res.size()) { + if (!res.get(0).asInt()) + return false; // does not exist + int state = res.get(1).asInt(); + int expires = res.get(2).asInt(); + DBG("Got state %ud with expires %ud for registration.\n", state, expires); + if (state == 2) // expired ... FIXME: add values from API here + return false; + // else pending or active + return true; + } + } + } + return false; +} + + +void RegThread::run() { + DBG("registrar client started.\n"); + sleep(2); // wait for sems to completely start up + + while (true) { + for (vector::iterator it = registrations.begin(); + it != registrations.end(); it++) { + if (!check_registration(*it)) { + DBG("Registration %d does not exist or timeout. Creating registration.\n", + it - registrations.begin()); + create_registration(*it); + } + } + sleep(10); // 10 seconds + } + +} + +void RegThread::on_stop() { + DBG("not stopping...\n"); +} + +void RegThread::postEvent(AmEvent* ev) { + DBG("received registration event.\n"); + // TODO: handle events instead of re-try + delete ev; +} + diff --git a/apps/reg_agent/RegistrationAgent.h b/apps/reg_agent/RegistrationAgent.h new file mode 100644 index 00000000..d936af2a --- /dev/null +++ b/apps/reg_agent/RegistrationAgent.h @@ -0,0 +1,78 @@ +/* + * $Id: RegistrationAgent.h,v 1.6.8.1 2005/06/01 12:00:24 rco Exp $ + * + * 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 + */ + +#ifndef _REG_AG_H_ +#define _REG_AG_H_ + +#include "AmSession.h" +#include "AmConfigReader.h" + +#include +using std::string; +#include +using std::vector; + +struct RegInfo { + string domain; + string user; + string display_name; + string auth_user; + string passwd; + + string handle; +}; + +class RegThread : public AmThread { + + vector registrations; + + void create_registration(RegInfo& ri); + bool check_registration(const RegInfo& ri); + + protected: + void run(); + void on_stop(); + public: + void add_reg(const RegInfo& ri); + void postEvent(AmEvent* ev); +}; + +class RegistrationAgentFactory: public AmSessionFactory +{ + RegThread dialer; + AmSessionEventHandlerFactory* uac_auth_f; + + public: + RegistrationAgentFactory(const string& _app_name); + + int onLoad(); + AmSession* onInvite(const AmSipRequest& req); + void postEvent(AmEvent* ev); +}; + +#endif + diff --git a/apps/reg_agent/etc/reg_agent.conf b/apps/reg_agent/etc/reg_agent.conf new file mode 100644 index 00000000..77c8d1ca --- /dev/null +++ b/apps/reg_agent/etc/reg_agent.conf @@ -0,0 +1,22 @@ +# +# +# Registrations at SIP registrar, +# refreshed if necessary. +# +# + +#domain=mydomain.net +#user=myuser +#display_name=myuser +#auth_user=myuser +#pwd=verysecret + +# +# For multiple registrations add more entries +# +#domain1=iptel.org +#user1=xyz +#display_name1=xyz +#auth_user1=xyz +#pwd1=ppp + diff --git a/doc/Readme.reg_agent b/doc/Readme.reg_agent new file mode 100644 index 00000000..331cf039 --- /dev/null +++ b/doc/Readme.reg_agent @@ -0,0 +1,9 @@ +Readme for reg_agent module + +This module uses the registrar_client to register the contact +sems@: at a SIP registrar. The accounts +(identities) are set in the config file. +If the registration is not successful, it tries to +re-register. + +This module depends on the registrar_client module. diff --git a/doc/Readme.registrar_client b/doc/Readme.registrar_client index cb7e4df0..40489169 100644 --- a/doc/Readme.registrar_client +++ b/doc/Readme.registrar_client @@ -4,7 +4,7 @@ This component registers on behalf of some application at a SIP registrar. Registrations are refreshed until they are explicitely removed via "removeRegistration". -It is invoked via DI API. +It is invoked via DI API, or used by the reg_agent module. API functions: ============= diff --git a/doc/doxyref.h b/doc/doxyref.h index 9ac3221f..61cd99b8 100644 --- a/doc/doxyref.h +++ b/doc/doxyref.h @@ -164,6 +164,13 @@ * *
  • \ref ModuleDoc_py_sems
* + * \section Registering SEMS at a SIP registrar + * + * The reg_agent module together with the registar_client module + * can be used to register at a SIP registrar. + * + *
  • \ref ModuleDoc_reg_agent
+ *
  • \ref ModuleDoc_registrar_client
*/ /*! \page AppDocExample Example Applications @@ -322,6 +329,22 @@ * Back to \ref AppDoc, to \ref AppDocExample. */ +/*! \page ModuleDoc_reg_agent Module Documentation: reg_agent Application + * \section Readme_reg_agent Readme file + * \verbinclude Readme.reg_agent + * + * \section Links + * Back to \ref AppDoc, to \ref AppDocExample. + */ + +/*! \page ModuleDoc_registrar_client Module Documentation: registrar_client Application + * \section Readme_registrar_client Readme file + * \verbinclude Readme.registrar_client + * + * \section Links + * Back to \ref AppDoc, to \ref AppDocExample. + */ + /*! \page ModuleDoc_uac_auth Module Documentation: uac_auth component * \section Readme_uac_auth Readme file * \verbinclude Readme.uac_auth