From b280576c5ca786a74ef6afec3dc1791893cfa7b4 Mon Sep 17 00:00:00 2001 From: Juha Heinanen Date: Wed, 4 Jul 2007 08:33:06 +0000 Subject: [PATCH] * Added conditional support for OpenSER 1.3. git-svn-id: http://svn.berlios.de/svnroot/repos/sems/trunk@375 8eb893ce-cfd4-0310-b710-fb5ebe64c474 --- Makefile.defs | 2 + core/AmInterfaceHandler.cpp | 30 ++++++ core/AmSipDialog.cpp | 180 +++++++++++++++++++++++++++++++ doc/Configure-Sems-OpenSER-HOWTO | 35 ++++++ 4 files changed, 247 insertions(+) create mode 100644 doc/Configure-Sems-OpenSER-HOWTO diff --git a/Makefile.defs b/Makefile.defs index 4c202ef7..e9718d78 100644 --- a/Makefile.defs +++ b/Makefile.defs @@ -38,6 +38,7 @@ CXX_FLAGS ?= -Wall -Wno-reorder -fPIC -g \ -D_THREAD_SAFE -D_REENTRANT \ -DVERSION='"$(RELEASE)"' -DARCH='"$(ARCH)"'\ -DOS='"$(OS)"' \ +# -DOpenSER \ # -DSUPPORT_IPV6 C_FLAGS ?= -Wall -fPIC -g \ @@ -46,6 +47,7 @@ C_FLAGS ?= -Wall -fPIC -g \ -D_THREAD_SAFE -D_REENTRANT \ -DVERSION='"$(RELEASE)"' -DARCH='"$(ARCH)"'\ -DOS='"$(OS)"' \ +# -DOpenSER \ # -DSUPPORT_IPV6 ifeq ($(DEBUG_PLAYOUT), yes) diff --git a/core/AmInterfaceHandler.cpp b/core/AmInterfaceHandler.cpp index 64389a48..b1026c72 100644 --- a/core/AmInterfaceHandler.cpp +++ b/core/AmInterfaceHandler.cpp @@ -210,6 +210,35 @@ int AmReplyHandler::handleRequest(AmCtrlInterface* ctrl) AmSipReply reply; string tmp_str; + +#ifdef OpenSER + unsigned int mi_res_code; + string mi_res_msg; + + 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"); + //cleanup(ctrl); + return -1; + } + + if (mi_res_code != 200) { + ERROR("MI response from OpenSER\n"); + return -1; + } + + 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"); + //cleanup(ctrl); + return -1; + } +#else SAFECTRLCALL1(getParam,tmp_str); DBG("response from Ser: %s\n",tmp_str.c_str()); @@ -219,6 +248,7 @@ int AmReplyHandler::handleRequest(AmCtrlInterface* ctrl) //cleanup(ctrl); return -1; } +#endif /* Parse complete response: * diff --git a/core/AmSipDialog.cpp b/core/AmSipDialog.cpp index aa9142fe..7bf8af73 100644 --- a/core/AmSipDialog.cpp +++ b/core/AmSipDialog.cpp @@ -278,6 +278,103 @@ string AmSipDialog::getContactHdr() return res; } +#ifdef OpenSER + +/* Escape " chars of argument and return escaped string */ +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; +} + +int AmSipDialog::reply(const AmSipRequest& req, + unsigned int code, + const string& reason, + const string& content_type, + const string& body, + const string& hdrs) +{ + string m_hdrs = hdrs; + int headers; + + if(hdl) + hdl->onSendReply(req,code,reason, + content_type,body,m_hdrs); + + string reply_sock = "/tmp/" + AmSession::getNewId(); + string code_str = int2str(code); + + string msg = ":t_reply:\n"; + + msg += code_str; + msg += "\n"; + + msg += reason; + msg += "\n"; + + msg += req.key; + msg += "\n"; + + msg += local_tag; + msg += "\n"; + + headers = 0; + + if(!m_hdrs.empty()) { + msg += "\"" + escape(m_hdrs); + headers = 1; + } + + if ((req.method!="CANCEL")&& + !((req.method=="BYE")&&(code<300))) { + if (headers == 1) { + msg += escape(getContactHdr()); + } else { + msg += "\"" + escape(getContactHdr()); + headers = 1; + } + } + + if(!body.empty()) { + if (headers == 1) { + msg += "Content-Type: " + content_type + "\n"; + } else { + msg += "\"Content-Type: " + content_type + "\n"; + headers = 1; + } + } + + if (AmConfig::Signature.length()) { + if (headers == 1) { + msg += "Server: " + AmConfig::Signature + "\n"; + } else { + msg += "\"Server: " + AmConfig::Signature + "\n"; + } + } + + if (headers == 1) { + msg += "\"\n"; + } else { + msg += ".\n"; + } + + if(!body.empty()) + msg += "\"" + body + "\"\n"; + + if(updateStatusReply(req,code)) + return -1; + + return AmServer::send_msg(msg,reply_sock, 500); +} + +#else /* Ser */ + int AmSipDialog::reply(const AmSipRequest& req, unsigned int code, const string& reason, @@ -336,6 +433,8 @@ int AmSipDialog::reply(const AmSipRequest& req, return AmServer::send_msg(msg,reply_sock, 500); } +#endif + /* static */ int AmSipDialog::reply_error(const AmSipRequest& req, unsigned int code, const string& reason, const string& hdrs) @@ -543,6 +642,85 @@ int AmSipDialog::cancel() return AmServer::send_msg(msg, reply_sock, 50000); } +#ifdef OpenSER + +int AmSipDialog::sendRequest(const string& method, + const string& content_type, + const string& body, + const string& hdrs) +{ + string msg,ser_cmd; + string m_hdrs = hdrs; + + if(hdl) + hdl->onSendRequest(method,content_type,body,m_hdrs,cseq); + + msg = ":t_uac_dlg:\n" + + method + "\n" + + remote_uri + "\n"; + + if(next_hop.empty()) + msg += "."; + else + msg += next_hop; + + msg += "\n"; + + msg += ".\n"; /* socket */ + + msg += "\"From: " + escape(local_party); + if(!local_tag.empty()) + msg += ";tag=" + local_tag; + + msg += "\n"; + + msg += "To: " + escape(remote_party); + if(!remote_tag.empty()) + msg += ";tag=" + remote_tag; + + msg += "\n"; + + msg += "CSeq: " + int2str(cseq) + " " + method + "\n" + + "Call-ID: " + callid + "\n"; + + if((method!="BYE")&&(method!="CANCEL")) + msg += escape(getContactHdr()); + + if(!m_hdrs.empty()){ + msg += escape(m_hdrs); + if(m_hdrs[m_hdrs.length()-1] != '\n') + msg += "\n"; + } + + if(!route.empty()) + msg += getRoute(); + + if(!body.empty()) + msg += "Content-Type: " + content_type + "\n"; + + msg += "Max-Forwards: " MAX_FORWARDS "\n"; + + if (AmConfig::Signature.length()) + msg += "User-Agent: " + AmConfig::Signature + "\n"; + + msg += "\"\n"; + + if (!body.empty()) + + "\"" + body + "\"\n"; + + if (AmServer::send_msg_replyhandler(msg)) + return -1; + + uac_trans[cseq] = AmSipTransaction(method,cseq); + + // increment for next request + cseq++; + + return 0; +} + +#else /* Ser */ + int AmSipDialog::sendRequest(const string& method, const string& content_type, const string& body, @@ -614,6 +792,8 @@ int AmSipDialog::sendRequest(const string& method, return 0; } +#endif + bool AmSipDialog::match_cancel(const AmSipRequest& cancel_req) { TransMap::iterator t = uas_trans.find(cancel_req.cseq); diff --git a/doc/Configure-Sems-OpenSER-HOWTO b/doc/Configure-Sems-OpenSER-HOWTO new file mode 100644 index 00000000..21628afb --- /dev/null +++ b/doc/Configure-Sems-OpenSER-HOWTO @@ -0,0 +1,35 @@ +******************************* +* Sems + OpenSER mini-HOWTO * +******************************* + +1. Introduction + +This document applies to OpenSER version 1.3 or higher. For earlier +versions, refer to Sems + Ser mini-HOWTO. + +2. Compilation + +Before compiling Sems for OpenSER, uncomment + +# -DOpenSER + +lines in Makefile.defs. + +3. OpenSER Configuration + +In openser.cfg, load module mi_datafgram.so, for example: + +mpath="/usr/lib/openser/modules" +loadmodule "mi_datagram.so" + +Define mi_datagram module parameters, for example: + +# -- mi_datagram params +modparam("mi_datagram", "socket_name", "/tmp/sems_openser_sock") +modparam("mi_datagram", "unix_socket_mode", 0600) +modparam("mi_datagram", "unix_socket_user", "root") +modparam("mi_datagram", "unix_socket_group", "root") + +4. Other Instructions + +Refer to Sems + Ser mini-HOWTO.