From a9780f0f81f8ae178a3e1be404390096e68a476d Mon Sep 17 00:00:00 2001 From: Stefan Sayer Date: Tue, 3 Mar 2009 21:05:13 +0000 Subject: [PATCH] RIP unixsock. git-svn-id: http://svn.berlios.de/svnroot/repos/sems/trunk@1296 8eb893ce-cfd4-0310-b710-fb5ebe64c474 --- core/plug-in/unixsockctrl/Makefile | 7 - .../unixsockctrl/UnixCtrlInterface.cpp | 257 ------- core/plug-in/unixsockctrl/UnixCtrlInterface.h | 79 -- .../unixsockctrl/UnixSocketAdapter.cpp | 681 ------------------ core/plug-in/unixsockctrl/UnixSocketAdapter.h | 106 --- .../unixsockctrl/etc/unixsockctrl.conf | 19 - 6 files changed, 1149 deletions(-) delete mode 100644 core/plug-in/unixsockctrl/Makefile delete mode 100644 core/plug-in/unixsockctrl/UnixCtrlInterface.cpp delete mode 100644 core/plug-in/unixsockctrl/UnixCtrlInterface.h delete mode 100644 core/plug-in/unixsockctrl/UnixSocketAdapter.cpp delete mode 100644 core/plug-in/unixsockctrl/UnixSocketAdapter.h delete mode 100644 core/plug-in/unixsockctrl/etc/unixsockctrl.conf diff --git a/core/plug-in/unixsockctrl/Makefile b/core/plug-in/unixsockctrl/Makefile deleted file mode 100644 index 2fb589d1..00000000 --- a/core/plug-in/unixsockctrl/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -COREPATH =../.. -plug_in_name = unixsockctrl - -module_ldflags = -module_cflags = -DMOD_NAME=\"$(plug_in_name)\" - -include ../Makefile.app_module diff --git a/core/plug-in/unixsockctrl/UnixCtrlInterface.cpp b/core/plug-in/unixsockctrl/UnixCtrlInterface.cpp deleted file mode 100644 index 11f519b9..00000000 --- a/core/plug-in/unixsockctrl/UnixCtrlInterface.cpp +++ /dev/null @@ -1,257 +0,0 @@ - -#include -#include -#include - -#include "AmUtils.h" -#include "AmConfig.h" -#include "AmSipHeaders.h" -#include "AmConfigReader.h" -#include "AmSession.h" -#include "sems.h" -#include "log.h" - -#include "UnixCtrlInterface.h" - -#ifndef MOD_NAME -#define MOD_NAME "unixsockctrl" -#endif - -EXPORT_CONTROL_INTERFACE_FACTORY(UnixCtrlInterfaceFactory, MOD_NAME); - -/* - * Config paramters names. - */ -#define SOCKET_NAME_PARAM "socket_name" -#define REPLY_SOCKET_NAME_PARAM "reply_socket_name" -#define SER_SOCKET_NAME_PARAM "ser_socket_name" -/* - * Config paramters default values. - */ -#define SOCKET_NAME_DEFAULT "/tmp/sems_sock" -#define REPLY_SOCKET_NAME_DEFAULT "/tmp/sems_rsp_sock" -#define SER_SOCKET_NAME_DEFAULT "/tmp/ser_sock" - -#define SIP_POLL_TIMEOUT 50 /*50 ms*/ -#define MAX_MSG_ERR 5 -#define SND_USOCK_TEMPLATE "/tmp/sems_send_sock_XXXXXX" //TODO: configurable - -//UnixCtrlInterface* UnixCtrlInterface::_instance = 0; - -AmCtrlInterface* UnixCtrlInterfaceFactory::instance() -{ - UnixCtrlInterface* ctrl = new UnixCtrlInterface(reply_socket_name,ser_socket_name); - - if(ctrl->init(socket_name) < 0){ - - delete ctrl; - return NULL; - } - - return ctrl; -} - -int UnixCtrlInterfaceFactory::onLoad() -{ - AmConfigReader cfg; - - if (cfg.loadFile(AmConfig::ModConfigPath + string(MOD_NAME ".conf"))) { - WARN("failed to read/parse config file `%s' - assuming defaults\n", - (AmConfig::ModConfigPath + string(MOD_NAME ".conf")).c_str()); - socket_name = string(SOCKET_NAME_DEFAULT); - reply_socket_name = string(REPLY_SOCKET_NAME_DEFAULT); - ser_socket_name = string(SER_SOCKET_NAME_DEFAULT); - } else { - socket_name = cfg.getParameter(SOCKET_NAME_PARAM, SOCKET_NAME_DEFAULT); - reply_socket_name = cfg.getParameter(REPLY_SOCKET_NAME_PARAM, - REPLY_SOCKET_NAME_DEFAULT); - ser_socket_name = cfg.getParameter(SER_SOCKET_NAME_PARAM, - SER_SOCKET_NAME_DEFAULT); - } - - INFO(SOCKET_NAME_PARAM ": `%s'.\n", socket_name.c_str()); - INFO(REPLY_SOCKET_NAME_PARAM ": `%s'.\n", reply_socket_name.c_str()); - INFO(SER_SOCKET_NAME_PARAM ": `%s'.\n", ser_socket_name.c_str()); - - return 0; -} - - -UnixCtrlInterface::~UnixCtrlInterface() -{ - reqAdapt.close(); - rplAdapt.close(); - sndAdapt.close(); -} - -UnixCtrlInterface::UnixCtrlInterface(const string& reply_socket_name, const string& ser_socket_name) - : reply_socket_name(reply_socket_name), ser_socket_name(ser_socket_name) -{ - sipDispatcher = AmSipDispatcher::instance(); - -} - -int UnixCtrlInterface::init(const string& socket_name) -{ - //initialize the listening adapters - if (! reqAdapt.init(socket_name)) { - ERROR("failed to initialize requests listner.\n"); - return -1; - } - - if (! rplAdapt.init(reply_socket_name)) { - ERROR("failed to initialize replies listner.\n"); - return -1; - } - - int errcnt = -1; - char buff[sizeof(SND_USOCK_TEMPLATE)]; - do { - if (MAX_MSG_ERR < ++errcnt) { - ERROR("failed to create a unix socket as a temproary file with " - "template `%s'.\n",SND_USOCK_TEMPLATE); - - return -1; - } - - //buff will hold the string for a temporary file that we'll than bind the - //sending unix socket to. - //Bind is needed so that replies can be received from SER. - memcpy(buff, SND_USOCK_TEMPLATE, sizeof(SND_USOCK_TEMPLATE)); - int fd = mkstemp(buff); - if (0 <= fd) { - close(fd); - //by unlinking (here or in init(), there's a race created [the one - //mkstemp tries to fix :-) ) => try a bunch of times - unlink(buff); - } - } while (! sndAdapt.init(string(buff))); - - return 0; -} - -int UnixCtrlInterface::send(const AmSipRequest &req, char *, unsigned int &) -{ - return rplAdapt.send(req, reply_socket_name, ser_socket_name); -} - -int UnixCtrlInterface::send(const AmSipReply &rpl) -{ - return sndAdapt.send(rpl, ser_socket_name); -} - -void UnixCtrlInterface::run() -{ - struct pollfd ufds[2]; - AmSipRequest req; - AmSipReply rpl; - - if (! sipDispatcher) { - ERROR("SIP dispacher hook not set.\n"); - return; - } - -#define POS_REQ 0 -#define POS_RPL 1 - ufds[POS_REQ].fd = reqAdapt.getFd(); - ufds[POS_RPL].fd = rplAdapt.getFd(); - ufds[POS_REQ].events = POLLIN; - ufds[POS_RPL].events = POLLIN; - // FIXME: is this really needed?! - ufds[POS_REQ].revents = 0; - ufds[POS_RPL].revents = 0; - -#define SERVICE_EVENT(_adapter, _msg) \ - do { \ - if ((_adapter).receive(_msg)) \ - sipDispatcher->handleSipMsg(_msg); \ - else \ - ERROR("failed to fetch %s.\n", #_msg); \ - } while (0) - -#ifdef OpenSER - DBG("Unix socket control interface built for OpenSER.\n"); -#else - DBG("Unix socket control interface built for SER.\n"); -#endif - - DBG("Running UnixCtrlInterface thread.\n"); - - while (!is_stopped()) { - int ret = poll(ufds,2,/*FIXME: configurable*/SIP_POLL_TIMEOUT); - switch (ret) { - case -1: - ERROR("AmServer: poll: %s\n",strerror(errno)); - continue; - case 0: - continue; //timedout - case 1: - if (ufds[POS_REQ].revents & POLLIN) - SERVICE_EVENT(reqAdapt, req); - else //rpl - SERVICE_EVENT(rplAdapt, rpl); - break; - case 2: - assert(ufds[POS_REQ].revents & POLLIN); - assert(ufds[POS_RPL].revents & POLLIN); - SERVICE_EVENT(reqAdapt, req); - SERVICE_EVENT(rplAdapt, rpl); - break; - default: - ERROR("unexpected poll events count: %i\n", ret); - continue; - } - } - -#undef SERVICE_EVENT -#undef POS_REQ -#undef POS_RPL -} - -string UnixCtrlInterface::getContact(const string &displayName, - const string &userName, const string &hostName, - const string &uriParams, const string &hdrParams) -{ - string localUri; - - if (displayName.length()) { - // quoting is safer (the check for quote need doesn't really pay off) - if (displayName.c_str()[0] == '"') { - assert(displayName.c_str()[displayName.length() - 1] == '"'); - localUri += displayName; - } else { - localUri += '"'; - localUri += displayName; - localUri += '"'; - } - localUri += " "; - } - - // angular brackets not always needed (unless contact) - localUri += "<"; - localUri += SIP_SCHEME_SIP; //TODO: sips|tel|tels - localUri += ":"; - if (userName.length()) { - localUri += userName; - localUri += "@"; - } - if (hostName.length()) - localUri += hostName; - else - localUri += "!!"; // Ser will replace that... - - if (uriParams.length()) { - if (uriParams.c_str()[0] != ';') - localUri += ';'; - localUri += uriParams; - } - localUri += ">"; - - if (hdrParams.length()) { - if (hdrParams.c_str()[0] != ';') - localUri += ';'; - localUri += hdrParams; - } - - return localUri; -} diff --git a/core/plug-in/unixsockctrl/UnixCtrlInterface.h b/core/plug-in/unixsockctrl/UnixCtrlInterface.h deleted file mode 100644 index feed4369..00000000 --- a/core/plug-in/unixsockctrl/UnixCtrlInterface.h +++ /dev/null @@ -1,79 +0,0 @@ - -#ifndef __UNIXCTRLINTERFACE_H__ -#define __UNIXCTRLINTERFACE_H__ - - -#include "AmApi.h" -#include "AmSipDispatcher.h" -#include "UnixSocketAdapter.h" - - -class UnixCtrlInterfaceFactory: public AmCtrlInterfaceFactory -{ - string socket_name; // SEMS listens for SIP requests from SER - string reply_socket_name; // SEMS listens for SIP replies from SER - string ser_socket_name; //SER listens for SIP requests|replies from SEMS - - public: - UnixCtrlInterfaceFactory(const string& name) : AmCtrlInterfaceFactory(name){} - ~UnixCtrlInterfaceFactory() {} - - // AmPluginFactory - int onLoad(); - - AmCtrlInterface* instance(); -}; - -// The SEMS - SER-0.9.6 unix socket message exchange: -// - requests(*) are sent from SER to a well known SEMS socket (sems_sock); -// SER doesn't expect a reply from SEMS, to ack(**). the good receiving. -// - requests and replies are sent from SEMS to a well known SER socket -// (ser_sock). -// If processing the request goes fine, no reply is sent back(***), to -// ack. it; if it goes bad, a "500 Bla" is replied immediately, using the -// same socket that SER received the request on. -// The reply is always ack'ed, also using the same socket. -// - replies (to SEMS requests) are sent from SER to SEMS to another well -// known socket (sems_rsp_sock). SER doesn't expect an ack. -// -// (*) in SIP terms; so, these are unix-socket-interface messages describing -// a SIP message. -// (**) an "ack" here means a one line string of pattern "200 All went fine", -// not an SIP ACK. -// (***) with the notable exception of CANCEL, for which a reply is always -// sent back. -class UnixCtrlInterface : public AmCtrlInterface -{ - private: - string reply_socket_name; // SEMS listens for SIP replies from SER - string ser_socket_name; //SER listens for SIP requests|replies from SEMS - - // listeners for requests from SER, for SIP requests and replies - UnixSocketAdapter reqAdapt, rplAdapt; - // this adapter is only used for sending replies - UnixSocketAdapter sndAdapt; - // handler of requests (SIP request | reply) received from SER - AmSipDispatcher *sipDispatcher; - - protected: - // AmCtrlInterface:AmThread - void run(); - void on_stop() {} - - public: - UnixCtrlInterface(const string& reply_socket_name, const string& ser_socket_name); - ~UnixCtrlInterface(); - - // AmCtrlInterface - int send(const AmSipRequest &, char *, unsigned int &); - int send(const AmSipReply &); - - string getContact(const string &displayName, - const string &userName, const string &hostName, - const string &uriParams, const string &hdrParams); - - // paths to unix sockets where: - int init(const string& socket_name); -}; - -#endif /* __UNIXCTRLINTERFACE_H__ */ diff --git a/core/plug-in/unixsockctrl/UnixSocketAdapter.cpp b/core/plug-in/unixsockctrl/UnixSocketAdapter.cpp deleted file mode 100644 index 6f19ff44..00000000 --- a/core/plug-in/unixsockctrl/UnixSocketAdapter.cpp +++ /dev/null @@ -1,681 +0,0 @@ -#include "AmUtils.h" -#include "AmConfig.h" -#include "AmSession.h" -#include "sems.h" -#include "log.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "UnixSocketAdapter.h" - - -#define MAX_MSG_ERR 5 -#define FIFO_VERSION "0.3" - - -#define NREADY(_msg, _args...) \ - do { \ - ERROR(_msg, ##_args); \ - return false; \ - } while (0) - -#define CHK_MBR(_member) \ - do { \ - if (! _member.size()) \ - NREADY("mandatory member empty: '%s'\n", #_member); \ - } while (0) - - -int UnixSocketAdapter::getLine(string& line) -{ - int err = get_line(buffer,CTRL_MSGBUF_SIZE); - if(err != -1) - line = buffer; - return err; -} - -int UnixSocketAdapter::getLines(string& lines) -{ - int err = get_lines(buffer,CTRL_MSGBUF_SIZE); - if(err != -1) - lines = buffer; - return err; -} - -int UnixSocketAdapter::getParam(string& param) -{ - return get_param(param,buffer,CTRL_MSGBUF_SIZE); -} - - -int UnixSocketAdapter::cacheMsg() -{ - int err_cnt=0; - - msg_c = NULL; - while(true){ - - msg_sz = recv(fd,msg_buf,CTRL_MSGBUF_SIZE,MSG_TRUNC|MSG_DONTWAIT); - if(msg_sz == -1){ - ERROR("recv on unix socket failed: %s\n",strerror(errno)); - if(++err_cnt >= MAX_MSG_ERR){ - ERROR("too many consecutive errors...\n"); - return -1; - } - - continue; - } - - break; - } - - if(msg_sz > CTRL_MSGBUF_SIZE){ - ERROR("unix socket message is too big (size=%i;max=%i): discarding\n", - msg_sz,CTRL_MSGBUF_SIZE); - return -1; - } - - msg_buf[msg_sz-1] = '\0'; - msg_c = msg_buf; - - DBG("recv-ed:\n<<%s>>\n",msg_buf); - - return 0; -} - -int UnixSocketAdapter::get_line(char* lb, unsigned int lbs) -{ - assert(msg_c); - return msg_get_line(msg_c,lb,lbs); -} - -int UnixSocketAdapter::get_lines(char* lb, unsigned int lbs) -{ - assert(msg_c); - return msg_get_lines(msg_c,lb,lbs); -} - -int UnixSocketAdapter::get_param(string& p, char* lb, unsigned int lbs) -{ - assert(msg_c); - return msg_get_param(msg_c,p,lb,lbs); -} - -UnixSocketAdapter::UnixSocketAdapter() - : close_fd(true),msg_c(NULL),msg_sz(0), fd(0) -{ - memset(sock_name,0,UNIX_PATH_MAX); -} - -UnixSocketAdapter::~UnixSocketAdapter() -{ - close(); -} - -bool UnixSocketAdapter::init(const string& addr) -{ - strncpy(sock_name,addr.c_str(),UNIX_PATH_MAX-1); - - ::unlink(sock_name); - fd = create_unix_socket(sock_name); - if(fd == -1){ - ERROR("could not open unix socket '%s'\n",sock_name); - return false; - } - - DBG("UnixSocketAdapter::init @ %s\n", sock_name); - close_fd = true; - return true; -} - -int UnixSocketAdapter::sendto(const string& addr,const char* buf,unsigned int len) -{ - return write_to_socket(fd,addr.c_str(),buf,len); -} - -void UnixSocketAdapter::close() -{ - if((fd != -1) && close_fd){ - ::close(fd); - } - - fd = -1; - - if(sock_name[0] != '\0') - ::unlink(sock_name); -} - -/** - * Return: - * -1 if error. - * 0 if timeout. - * 1 if there some datas ready. - */ -int UnixSocketAdapter::wait4data(int timeout) -{ - struct pollfd pfd = { fd, POLLIN, 0 }; - - int ret = poll(&pfd,1,timeout); - if(ret < 0){ - ERROR("poll: %s\n",strerror(errno)); - return -1; - } - else if(ret == 0){ - WARN("poll timed out\n"); - return -1; - } - - if(pfd.revents & POLLIN) - return 1; - else { - ERROR("poll: revents & POLLIN == 0\n"); - return -1; - } -} - - -#define SAFECTRLCALL1(fct, arg1) \ - do { \ - int ret; \ - if((ret = fct(arg1)) < 0){ \ - ERROR("call %s(%s) failed with %d\n", #fct, #arg1, ret); \ - goto failure; \ - } \ - } while (0) - - -bool UnixSocketAdapter::receive(AmSipRequest &req) -{ - string version; - string fct_name; - string cmd; - string::size_type pos; - string cseq_str; - - if (cacheMsg() < 0) - goto failure; - - // handle API version - SAFECTRLCALL1(getParam, version); - if (version == "") { - // some odd trailer from previous request -- ignore - ERROR("odd trailer\n"); - goto failure; - } - if(version != FIFO_VERSION){ - ERROR("wrong FIFO Interface version: %s\n",version.c_str()); - goto failure; - } - - // handle invoked function - SAFECTRLCALL1(getParam, fct_name); - if((pos = fct_name.find('.')) != string::npos){ - cmd = fct_name.substr(pos+1,string::npos); - fct_name = fct_name.substr(0,pos); - } - if(fct_name != "sip_request") { - ERROR("unexpected request function: '%s'\n",fct_name.c_str()); - goto failure; - } - if(cmd.empty()) { - ERROR("parameter plug-in name missing.\n"); - goto failure; - } - req.cmd = cmd; - -#define READ_PARAMETER(p) \ - do { \ - SAFECTRLCALL1(getParam, p); \ - DBG("%s = <%s>\n",#p,p.c_str()); \ - } while (0) - - READ_PARAMETER(req.method); - READ_PARAMETER(req.user); - READ_PARAMETER(req.domain); - READ_PARAMETER(req.dstip); // will be taken for UDP's local peer IP & Contact - READ_PARAMETER(req.port); // will be taken for Contact - READ_PARAMETER(req.r_uri); // ??? will be taken for the answer's Contact header field ??? - READ_PARAMETER(req.from_uri); // will be taken for subsequent request uri - READ_PARAMETER(req.from); - READ_PARAMETER(req.to); - READ_PARAMETER(req.callid); - READ_PARAMETER(req.from_tag); - READ_PARAMETER(req.to_tag); - - READ_PARAMETER(cseq_str); - - if(sscanf(cseq_str.c_str(),"%u", &req.cseq) != 1){ - ERROR("invalid cseq number '%s'\n",cseq_str.c_str()); - goto failure; - } - DBG("cseq = <%s>(%i)\n",cseq_str.c_str(),req.cseq); - - READ_PARAMETER(req.serKey); - READ_PARAMETER(req.route); - READ_PARAMETER(req.next_hop); - - - SAFECTRLCALL1(getLines,req.hdrs); - DBG("hdrs = <%s>\n",req.hdrs.c_str()); - - SAFECTRLCALL1(getLines,req.body); - DBG("body = <%s>\n",req.body.c_str()); - - if(req.from.empty() || - req.to.empty() || - req.callid.empty() || - req.from_tag.empty()) { - ERROR("%s::%s: empty mandatory parameter (from|to|callid|from_tag)\n", - __FILE__, __FUNCTION__); - goto failure; - } - - return true; - -failure: - return false; - -#undef READ_PARAMETER -} - - -bool UnixSocketAdapter::receive(AmSipReply &reply) -{ - string tmp_str; - string cseq_str; - -#ifdef OpenSER - unsigned int mi_res_code; - string mi_res_msg; -#endif - - if (cacheMsg() < 0) - goto failure; - -#ifdef OpenSER - SAFECTRLCALL1(getParam,tmp_str); - - DBG("MI response from OpenSER: %s\n",tmp_str.c_str()); - if( parse_return_code(tmp_str.c_str(),// res_code_str, - mi_res_code, mi_res_msg) == -1 ){ - ERROR("while parsing MI return code from OpenSER.\n"); - goto failure; - } - - if (mi_res_code != 200) { - ERROR("MI response from OpenSER\n"); - goto failure; - } - - SAFECTRLCALL1(getParam,tmp_str); - DBG("SIP response from OpenSER: %s\n",tmp_str.c_str()); - if( parse_return_code(tmp_str.c_str(),// res_code_str, - reply.code, reply.reason) == -1 ){ - ERROR("while parsing return code from Ser.\n"); - goto failure; - } -#else - SAFECTRLCALL1(getParam,tmp_str); - - DBG("response from Ser: %s\n",tmp_str.c_str()); - if( parse_return_code(tmp_str.c_str(),// res_code_str, - reply.code,reply.reason) == -1 ){ - ERROR("while parsing return code from Ser.\n"); - goto failure; - } -#endif - - /* Parse complete response: - * - * [next_request_uri->cmd.from_uri]CRLF - * [next_hop->cmd.next_hop]CRLF - * [route->cmd.route]CRLF - * ([headers->n_cmd.hdrs]CRLF)* - * CRLF - * ([body->body]CRLF)* - */ - - SAFECTRLCALL1(getParam,reply.next_request_uri); - SAFECTRLCALL1(getParam,reply.next_hop); - SAFECTRLCALL1(getParam,reply.route); - - SAFECTRLCALL1(getLines,reply.hdrs); - SAFECTRLCALL1(getLines,reply.body); - - if(reply.hdrs.empty()){ - ERROR("reply is missing headers: <%i %s>\n", - reply.code,reply.reason.c_str()); - goto failure; - } - - reply.local_tag = getHeader(reply.hdrs,"From"); - reply.local_tag = extract_tag(reply.local_tag); - - reply.remote_tag = getHeader(reply.hdrs,"To"); - reply.remote_tag = extract_tag(reply.remote_tag); - - cseq_str = getHeader(reply.hdrs,"CSeq"); - if(str2i(cseq_str,reply.cseq)){ - ERROR("could not parse CSeq header\n"); - goto failure; - } - - reply.content_type = getHeader(reply.hdrs,"Content-Type"); - - return true; -failure: - //cleanup(ctrl); - return false; -} - - -bool UnixSocketAdapter::isComplete(const AmSipReply &rpl) -{ - if (rpl.code < 100 || 699 < rpl.code) - NREADY("invalid reply code: %d.\n", rpl.code); - - CHK_MBR(rpl.reason); - CHK_MBR(rpl.serKey); - - if (300 <= rpl.code) - return true; - - CHK_MBR(rpl.local_tag); - - if (! rpl.body.empty()) - CHK_MBR(rpl.content_type); - - if ((rpl.method!="CANCEL") && (rpl.method!="BYE")) - CHK_MBR(rpl.contact); - - return true; -} - - -#ifdef OpenSER -/* Escape " chars of argument and return escaped string */ -static inline string escape(string s) -{ - string::size_type pos; - - pos = 0; - while ((pos = s.find("\"", pos)) != string::npos) { - s.insert(pos, "\\"); - pos = pos + 2; - } - return s; -} - -/* Add CR before each LF if not already there */ -static inline string lf2crlf(string s) -{ - string::size_type pos; - - pos = 0; - while ((pos = s.find("\n", pos)) != string::npos) { - if ((pos > 0) && (s[pos - 1] == 13)) { - pos = pos + 1; - } else { - s.insert(pos, "\r"); - pos = pos + 2; - } - } - return s; -} -#endif - -string UnixSocketAdapter::serialize(const AmSipReply &reply, - const string &rplAddr) -{ - string msg; - - msg = ":t_reply:" -#ifndef OpenSER - + rplAddr + -#endif - "\n"; - - msg += int2str(reply.code); - msg += "\n"; - - msg += reply.reason; - msg += "\n"; - - msg += reply.serKey; - msg += "\n"; - - msg += reply.local_tag; - msg += "\n"; - - string extraHdrs, bodyFrame; - - if (! reply.hdrs.empty()) - extraHdrs += reply.hdrs; - - if (reply.code < 300) { - if (! reply.contact.empty()) - extraHdrs += reply.contact; - - if (! reply.body.empty()) - extraHdrs += "Content-Type: " + reply.content_type + "\n"; - -#ifndef OpenSER - bodyFrame += reply.body; - bodyFrame += ".\n\n"; -#else - if (! reply.body.empty()) { - // TODO: body already CRLF'ed? - bodyFrame += "\"" + reply.body + "\"\n"; - } -#endif - } - -#ifndef OpenSER - else { - bodyFrame = ".\n\n"; - } - extraHdrs += ".\n"; -#endif - -#ifdef OpenSER - if (extraHdrs.empty()) { - extraHdrs = ".\n"; - } else { - extraHdrs = "\"" + lf2crlf(escape(extraHdrs)) + "\"\n"; - } -#endif - - msg += extraHdrs + bodyFrame; - return msg; -} - -int UnixSocketAdapter::send_msg(const string &msg, const string &src, - const string &dst, int timeout) -{ - DBG("sending out serialized SER command:\n<<%s>>.\n", msg.c_str()); - - // FIXME: is this init really needed?! - //if(init(src) || sendto(dst, msg.c_str(),msg.length())){ - if(sendto(dst, msg.c_str(),msg.length())){ - ERROR("...while sending request to SER.\n"); - return -1; - } - - if (timeout) { // should it collect the reply? - if(wait4data(timeout) < 1){ - ERROR("while waiting for SER's response\n"); - return -1; - } - - string status_line; - if(cacheMsg() || getParam(status_line)) - return -1; - - unsigned int res_code; - string res_reason; - if(parse_return_code(status_line.c_str(),res_code,res_reason)) - return -1; - - if( (res_code < 200) || - (res_code >= 300) ) { - ERROR("SER answered: %i %s\n", res_code,res_reason.c_str()); - return -1; - } - } - - return 0; - -} - -int UnixSocketAdapter::send(const AmSipReply &reply, const string &dst) -{ - string rplSockAddr, msg; - - if (! isComplete(reply)) { - ERROR("can not send reply: not complete.\n"); - return -1; - } - - rplSockAddr = /*TODO: configurable?!*/"/tmp/" + AmSession::getNewId(); - msg = serialize(reply, rplSockAddr); - return send_msg(msg, rplSockAddr, dst, /*TODO: configurable?!*/500); -} - - - -bool UnixSocketAdapter::isComplete(const AmSipRequest &req) -{ - CHK_MBR(req.method); - CHK_MBR(req.callid); - if (req.method != "CANCEL") { - CHK_MBR(req.r_uri); - CHK_MBR(req.from); - CHK_MBR(req.to); - if (! req.body.empty()) - CHK_MBR(req.content_type); - } - - return true; -} - -string UnixSocketAdapter::serialize(const AmSipRequest& req, - const string &rplAddr) -{ - string msg; - - msg = ":t_uac_dlg:" -#ifndef OpenSER - + rplAddr + -#endif - "\n" - + req.method + "\n" - + req.r_uri + "\n"; - - if(req.next_hop.empty()) - msg += "."; - else - msg += req.next_hop; - - msg += "\n"; - -#ifdef OpenSER - msg += ".\n"; /* socket */ -#endif - - string extraHdrs; - - extraHdrs += req.from; - extraHdrs += "\n"; - - extraHdrs += req.to; - extraHdrs += "\n"; - - extraHdrs += "CSeq: " + int2str(req.cseq) + " " + req.method + "\n" - + "Call-ID: " + req.callid + "\n"; - - if (! req.contact.empty()) - extraHdrs += req.contact; - - if (! req.hdrs.empty()) { - extraHdrs += req.hdrs; - if (req.hdrs[req.hdrs.length() - 1] != '\n') - extraHdrs += "\n"; - } - - if(!req.route.empty()) - extraHdrs += req.route; - - if(!req.body.empty()) - extraHdrs += "Content-Type: " + req.content_type + "\n"; - -#ifdef OpenSER - extraHdrs = "\"" + lf2crlf(escape(extraHdrs)) + "\"\n"; -#endif - - string bodyFrame; -#ifndef OpenSER - bodyFrame = ".\n" // EoH - + req.body + ".\n\n"; -#else - // is lf2crlf() needed?! (see function for replies) - if (!req.body.empty()) - bodyFrame = "\"" + req.body + "\"\n"; -#endif - - msg += extraHdrs + bodyFrame; - - return msg; -} - -string UnixSocketAdapter::serialize_cancel(const AmSipRequest& req, - const string &rplAddr) -{ - string msg; - - msg = ":t_uac_cancel:" -#ifndef OpenSER - + rplAddr + -#endif - "\n" + - req.callid + "\n" + - int2str(req.cseq) + "\n" -#ifndef OpenSER - "\n" -#endif - ; - return msg; -} - -int UnixSocketAdapter::send(const AmSipRequest &req, string &src, string &dst) -{ - if (! isComplete(req)) { - ERROR("can not send request: not complete.\n"); - return -1; - } - - string rplAddr; - string msg; - int timeout; - if (req.method == "CANCEL") { - rplAddr = "/tmp/" + AmSession::getNewId(); - msg = serialize_cancel(req, rplAddr); - timeout = 50000; /*TODO: WTF's with this value?!*/ - } else { - rplAddr = src;//AmConfig::ReplySocketName; - msg = serialize(req, rplAddr); - /* timeout: don't wait for reply [comes through other, - * dedicated socket] */ - timeout = 0; - } - - return send_msg(msg, rplAddr, dst, timeout); -} diff --git a/core/plug-in/unixsockctrl/UnixSocketAdapter.h b/core/plug-in/unixsockctrl/UnixSocketAdapter.h deleted file mode 100644 index d0a7fdf8..00000000 --- a/core/plug-in/unixsockctrl/UnixSocketAdapter.h +++ /dev/null @@ -1,106 +0,0 @@ - -#ifndef __UNIXSOCKETADAPTER_H__ -#define __UNIXSOCKETADAPTER_H__ - -#include - -#ifndef UNIX_PATH_MAX -#include -#define UNIX_PATH_MAX sizeof(((struct sockaddr_un *)0)->sun_path) -#endif -#define CTRL_MSGBUF_SIZE 2048 - -using std::string; - -/** - * \brief UNIX socket control interface - * - * The FIFO / Unix socket Server. - * - * Enables Ser to send request throught FIFO file. - * - * Syntax for FIFO commands:
- *
- *   version  EOL // 'x.x'
- *   command  EOL // fct_name.{plugin_name,'bye'}
- *   method   EOL
- *   user     EOL 
- *   dstip    EOL // important for the RTP connection IP
- *   from     EOL
- *   to       EOL
- *   call-id  EOL
- *   from-tag EOL
- *   [to-tag] EOL
- *   cseq     EOL
- *   transid  EOL // Ser's tranction ID
- *   [body]   EOL
- *   .EOL
- *   EOL
- *   
- */ -class UnixSocketAdapter -{ - int fd; - char buffer[CTRL_MSGBUF_SIZE]; - bool close_fd; - char msg_buf[CTRL_MSGBUF_SIZE]; - char* msg_c; - int msg_sz; - char sock_name[UNIX_PATH_MAX]; - - /** @return -1 on error, 0 if success */ - int getLine(string& line); - int getLines(string& lines); - int getParam(string& param); - - /** @return -1 on error, 0 if success */ - int cacheMsg(); - int get_line(char* lb, unsigned int lbs); - int get_lines(char* lb, unsigned int lbs); - int get_param(string& p, char* lb, unsigned int lbs); - - /* message manipulation methods */ - static bool isComplete(const AmSipReply &rpl); - static bool isComplete(const AmSipRequest &rpl); - static string serialize(const AmSipRequest& req, const string &rplAddr); - static string serialize_cancel(const AmSipRequest &, const string &rplAddr); - static string serialize(const AmSipReply& reply, const string &rplAddr); - - int send_msg(const string &msg, const string &src, const string &dst, - int timeout); - - /** - * Send a message. - * - * @param addr destination address. - * @return -1 on error, 0 if success. - */ - int sendto(const string& addr, - const char* buf, - unsigned int len); - - /** - * Return: - * -1 if error. - * 0 if timeout. - * 1 if there some datas ready. - */ - int wait4data(int timeout); - - public: - UnixSocketAdapter(); - ~UnixSocketAdapter(); - - bool init(const string& addr); - int getFd() { return fd; } - void close(); - - bool receive(AmSipRequest &); - bool receive(AmSipReply &); - - int send(const AmSipRequest &req, string &src, string &dst); - int send(const AmSipReply &reply, const string &dst); -}; - - -#endif /* __UNIXSOCKETADAPTER_H__ */ diff --git a/core/plug-in/unixsockctrl/etc/unixsockctrl.conf b/core/plug-in/unixsockctrl/etc/unixsockctrl.conf deleted file mode 100644 index 316ef105..00000000 --- a/core/plug-in/unixsockctrl/etc/unixsockctrl.conf +++ /dev/null @@ -1,19 +0,0 @@ - -# optional parameter: socket_name= -# -# - path and file name of our unix socket -# (where ser writes messages to) -socket_name=/tmp/sems_sock - -# optional parameter: reply_socket_name= -# -# - path and file name of the unix socket where we -# get replies from ser -reply_socket_name=/tmp/sems_rsp_sock - -# optional parameter: ser_socket_name= -# -# - path and file name of Ser's unix socket -# (where we write messages to) -ser_socket_name=/tmp/ser_sock -