From 778da1ad578498b848545f2ec203cc0d331ec6d5 Mon Sep 17 00:00:00 2001 From: Raphael Coeffic Date: Fri, 9 Apr 2010 12:19:28 +0000 Subject: [PATCH] the old serKey has been replaced by a proper transaction ticket specific to the internal SIP stack. git-svn-id: http://svn.berlios.de/svnroot/repos/sems/trunk@1778 8eb893ce-cfd4-0310-b710-fb5ebe64c474 --- core/AmB2BSession.cpp | 6 +-- core/AmSipDialog.cpp | 102 ++++++++++++++++++-------------------- core/AmSipDialog.h | 10 ++-- core/AmSipMsg.cpp | 4 -- core/AmSipMsg.h | 5 +- core/SipCtrlInterface.cpp | 38 ++++---------- core/SipCtrlInterface.h | 13 ++--- core/sip/sip_ua.h | 4 +- core/sip/trans_layer.cpp | 46 +++++++++-------- core/sip/trans_layer.h | 31 +++++++++--- 10 files changed, 129 insertions(+), 130 deletions(-) diff --git a/core/AmB2BSession.cpp b/core/AmB2BSession.cpp index cf821912..333835ad 100644 --- a/core/AmB2BSession.cpp +++ b/core/AmB2BSession.cpp @@ -224,7 +224,7 @@ void AmB2BSession::terminateOtherLeg() void AmB2BSession::relaySip(const AmSipRequest& req) { if (req.method != "ACK") { - relayed_req[dlg.cseq] = AmSipTransaction(req.method,req.cseq); + relayed_req[dlg.cseq] = AmSipTransaction(req.method,req.cseq,req.tt); dlg.sendRequest(req.method,"application/sdp",req.body,req.hdrs,SIP_FLAGS_VERBATIM); } else { // its a (200) ACK @@ -240,7 +240,7 @@ void AmB2BSession::relaySip(const AmSipRequest& req) return; } DBG("sending relayed ACK\n"); - dlg.send_200_ack(AmSipTransaction(t->second.method, t->first), + dlg.send_200_ack(AmSipTransaction(t->second.method, t->first,t->second.tt), req.content_type, req.body, req.hdrs, SIP_FLAGS_VERBATIM); relayed_req.erase(t); } @@ -459,7 +459,7 @@ void AmB2BCalleeSession::onB2BEvent(B2BEvent* ev) dlg.remote_uri = co_ev->remote_uri; if (co_ev->relayed_invite) { - relayed_req[dlg.cseq] = AmSipTransaction("INVITE", co_ev->r_cseq); + relayed_req[dlg.cseq] = AmSipTransaction("INVITE", co_ev->r_cseq, trans_ticket()); } dlg.sendRequest("INVITE",co_ev->content_type,co_ev->body,co_ev->hdrs,SIP_FLAGS_VERBATIM); diff --git a/core/AmSipDialog.cpp b/core/AmSipDialog.cpp index 3437acfe..70c85833 100644 --- a/core/AmSipDialog.cpp +++ b/core/AmSipDialog.cpp @@ -72,8 +72,10 @@ void AmSipDialog::updateStatus(const AmSipRequest& req) if (req.method == "ACK") return; - if(uas_trans.find(req.cseq) == uas_trans.end()) - uas_trans[req.cseq] = AmSipTransaction(req.method,req.cseq); + if(uas_trans.find(req.cseq) == uas_trans.end()){ + DBG("req.tt = {0x%X,0x%X}\n",req.tt._bucket, req.tt._t); + uas_trans[req.cseq] = AmSipTransaction(req.method,req.cseq,req.tt); + } // target refresh requests if (req.from_uri.length() && @@ -312,7 +314,7 @@ int AmSipDialog::reply(const AmSipRequest& req, reply.method = req.method; reply.code = code; reply.reason = reason; - reply.serKey = req.serKey; + reply.tt = req.tt; reply.local_tag = local_tag; reply.hdrs = m_hdrs; @@ -344,7 +346,7 @@ int AmSipDialog::reply_error(const AmSipRequest& req, unsigned int code, reply.method = req.method; reply.code = code; reply.reason = reason; - reply.serKey = req.serKey; + reply.tt = req.tt; reply.hdrs = hdrs; reply.local_tag = AmSession::getNewId(); @@ -357,31 +359,31 @@ int AmSipDialog::reply_error(const AmSipRequest& req, unsigned int code, int AmSipDialog::bye(const string& hdrs) { - switch(status){ - case Disconnecting: - case Connected: - status = Disconnected; - return sendRequest("BYE", "", "", hdrs); - case Pending: - status = Disconnecting; - if(getUACTransPending()) - return cancel(); - else { - // missing AmSipRequest to be able - // to send the reply on behalf of the app. - DBG("ignoring bye() in Pending state: " - "no UAC transaction to cancel.\n"); - } - return 0; - default: - if(getUACTransPending()) - return cancel(); - else { - DBG("bye(): we are not connected " - "(status=%i). do nothing!\n",status); - } - return 0; - } + switch(status){ + case Disconnecting: + case Connected: + status = Disconnected; + return sendRequest("BYE", "", "", hdrs); + case Pending: + status = Disconnecting; + if(getUACTransPending()) + return cancel(); + else { + // missing AmSipRequest to be able + // to send the reply on behalf of the app. + DBG("ignoring bye() in Pending state: " + "no UAC transaction to cancel.\n"); + } + return 0; + default: + if(getUACTransPending()) + return cancel(); + else { + DBG("bye(): we are not connected " + "(status=%i). do nothing!\n",status); + } + return 0; + } } int AmSipDialog::reinvite(const string& hdrs, @@ -520,33 +522,27 @@ int AmSipDialog::transfer(const string& target) int AmSipDialog::cancel() { - int cancel_cseq = -1; - TransMap::reverse_iterator t; + + + for(TransMap::reverse_iterator t = uac_trans.rbegin(); + t != uac_trans.rend(); t++) { + + if(t->second.method == "INVITE"){ + + AmSipRequest req; + + req.method = "CANCEL"; + req.callid = callid; + req.cseq = t->second.cseq; - for(t = uac_trans.rbegin(); - t != uac_trans.rend(); t++) { + req.tt = t->second.tt; - if(t->second.method == "INVITE"){ - cancel_cseq = t->second.cseq; - break; + return SipCtrlInterface::send(req) ? 0 : -1; + } } - } - if(t == uac_trans.rend()){ ERROR("could not find INVITE transaction to cancel\n"); return -1; - } - - AmSipRequest req; - req.method = "CANCEL"; - //useful for SER-0.9.6/Open~ - req.callid = callid; - req.cseq = cancel_cseq; - //useful for SER-2.0.0 - req.serKey = string(serKey, serKeyLen); - char empty[MAX_SER_KEY_LEN]; - unsigned int unused = 0; - return SipCtrlInterface::send(req, empty, unused) ? 0 : -1; } int AmSipDialog::sendRequest(const string& method, @@ -601,10 +597,10 @@ int AmSipDialog::sendRequest(const string& method, req.body = body; } - if (SipCtrlInterface::send(req, serKey, serKeyLen)) + if (SipCtrlInterface::send(req)) return -1; - uac_trans[cseq] = AmSipTransaction(method,cseq); + uac_trans[cseq] = AmSipTransaction(method,cseq,req.tt); // increment for next request cseq++; @@ -728,7 +724,7 @@ int AmSipDialog::send_200_ack(const AmSipTransaction& t, req.body = body; } - if (SipCtrlInterface::send(req, serKey, serKeyLen)) + if (SipCtrlInterface::send(req)) return -1; return 0; diff --git a/core/AmSipDialog.h b/core/AmSipDialog.h index 5eb60e57..b87a1728 100644 --- a/core/AmSipDialog.h +++ b/core/AmSipDialog.h @@ -45,16 +45,18 @@ using std::string; /** \brief SIP transaction representation */ struct AmSipTransaction { - string method; - unsigned int cseq; + string method; + unsigned int cseq; + trans_ticket tt; // last reply code // (sent or received) //int reply_code; - AmSipTransaction(const string& method, unsigned int cseq) + AmSipTransaction(const string& method, unsigned int cseq, const trans_ticket& tt) : method(method), - cseq(cseq) + cseq(cseq), + tt(tt) {} AmSipTransaction() diff --git a/core/AmSipMsg.cpp b/core/AmSipMsg.cpp index b8a610bd..9432c3a2 100644 --- a/core/AmSipMsg.cpp +++ b/core/AmSipMsg.cpp @@ -133,8 +133,6 @@ string AmSipRequest::print() { string buf; - _PM(serKey, "serkey"); - _PM(r_uri, "r-uri"); _PM(callid, "i"); _PM(int2str(cseq), "cseq"); @@ -166,8 +164,6 @@ string AmSipReply::print() { string buf; - _PM(serKey, "serkey"); - _PM(int2str(code), "code"); _PMB(reason, "phrase"); _PM(callid, "i"); diff --git a/core/AmSipMsg.h b/core/AmSipMsg.h index 5eae3a51..5b959db4 100644 --- a/core/AmSipMsg.h +++ b/core/AmSipMsg.h @@ -4,6 +4,8 @@ #include using std::string; +#include "sip/trans_layer.h" + /* enforce common naming in Req&Rpl */ class _AmSipMsgInDlg { @@ -23,7 +25,8 @@ class _AmSipMsgInDlg string dstip; // IP where Ser received the message string port; // Ser's SIP port - string serKey; + // transaction ticket from sip stack + trans_ticket tt; _AmSipMsgInDlg() : cseq(0) { } virtual ~_AmSipMsgInDlg() { }; diff --git a/core/SipCtrlInterface.cpp b/core/SipCtrlInterface.cpp index e15f65db..16832565 100644 --- a/core/SipCtrlInterface.cpp +++ b/core/SipCtrlInterface.cpp @@ -116,25 +116,14 @@ SipCtrlInterface::SipCtrlInterface() trans_layer::instance()->register_ua(this); } -int SipCtrlInterface::cancel(const AmSipRequest& req) +int SipCtrlInterface::cancel(AmSipRequest& req) { - unsigned int h=0; - unsigned long t=0; - - if((sscanf(req.serKey.c_str(),"%x:%lx",&h,&t) != 2) || - (h >= H_TABLE_ENTRIES)){ - ERROR("Invalid transaction key: invalid bucket ID (key=%s)\n",req.serKey.c_str()); - return -1; - } - - return trans_layer::instance()->cancel(get_trans_bucket(h),(sip_trans*)t); + return trans_layer::instance()->cancel(&req.tt); } -int SipCtrlInterface::send(const AmSipRequest &req, char* serKey, unsigned int& serKeyLen) +int SipCtrlInterface::send(AmSipRequest &req) { - serKeyLen = 0; - if(req.method == "CANCEL") return cancel(req); @@ -278,7 +267,7 @@ int SipCtrlInterface::send(const AmSipRequest &req, char* serKey, unsigned int& return -1; } - int res = trans_layer::instance()->send_request(msg,serKey,serKeyLen); + int res = trans_layer::instance()->send_request(msg,&req.tt); delete msg; return res; @@ -301,15 +290,6 @@ void SipCtrlInterface::run(const string& bind_addr, unsigned short bind_port) int SipCtrlInterface::send(const AmSipReply &rep) { - unsigned int h=0; - unsigned long t=0; - - if((sscanf(rep.serKey.c_str(),"%x:%lx",&h,&t) != 2) || - (h >= H_TABLE_ENTRIES)){ - ERROR("Invalid transaction key: invalid bucket ID\n"); - return -1; - } - sip_msg msg; if(!rep.hdrs.empty()) { @@ -360,7 +340,7 @@ int SipCtrlInterface::send(const AmSipReply &rep) } } - int ret = trans_layer::instance()->send_reply(get_trans_bucket(h),(sip_trans*)t, + int ret = trans_layer::instance()->send_reply((trans_ticket*)&rep.tt, rep.code,stl2cstr(rep.reason), stl2cstr(rep.local_tag), cstring(hdrs_buf,hdrs_len), stl2cstr(rep.body)); @@ -391,7 +371,6 @@ void SipCtrlInterface::handleSipMsg(AmSipRequest &req) DBG_PARAM(req.from_tag); DBG_PARAM(req.to_tag); DBG("cseq = <%i>\n",req.cseq); - DBG_PARAM(req.serKey); DBG_PARAM(req.route); DBG_PARAM(req.next_hop); DBG("hdrs = <%s>\n",req.hdrs.c_str()); @@ -412,10 +391,12 @@ void SipCtrlInterface::handleSipMsg(AmSipReply &rep) AmSipDispatcher::instance()->handleSipMsg(rep); } -void SipCtrlInterface::handle_sip_request(const char* tid, sip_msg* msg) +void SipCtrlInterface::handle_sip_request(trans_ticket* tt, sip_msg* msg) { + assert(msg); assert(msg->from && msg->from->p); assert(msg->to && msg->to->p); + assert(tt); AmSipRequest req; @@ -472,8 +453,7 @@ void SipCtrlInterface::handle_sip_request(const char* tid, sip_msg* msg) req.cseq = get_cseq(msg)->num; req.body = c2stlstr(msg->body); - if(tid != NULL) - req.serKey = tid; + req.tt = *tt; if (msg->content_type) req.content_type = c2stlstr(msg->content_type->value); diff --git a/core/SipCtrlInterface.h b/core/SipCtrlInterface.h index 99d53710..fe693223 100644 --- a/core/SipCtrlInterface.h +++ b/core/SipCtrlInterface.h @@ -52,8 +52,9 @@ class SipCtrlInterface: void prepare_routes_uac(const list& routes, string& route_field); void prepare_routes_uas(const list& routes, string& route_field); - static int cancel(const AmSipRequest& req); + static int cancel(AmSipRequest& req); + friend class udp_trsp; public: static string outbound_host; @@ -72,12 +73,12 @@ public: /** * From AmCtrlInterface */ - static int send(const AmSipRequest &req, char* serKey, unsigned int& serKeyLen); + static int send(AmSipRequest &req); static int send(const AmSipReply &rep); - string getContact(const string &displayName, - const string &userName, const string &hostName, - const string &uriParams, const string &hdrParams); +// string getContact(const string &displayName, +// const string &userName, const string &hostName, +// const string &uriParams, const string &hdrParams); void handleSipMsg(AmSipRequest &req); void handleSipMsg(AmSipReply &rep); @@ -85,7 +86,7 @@ public: /** * From sip_ua */ - void handle_sip_request(const char* tid, sip_msg* msg); + void handle_sip_request(trans_ticket* tt, sip_msg* msg); void handle_sip_reply(sip_msg* msg); }; diff --git a/core/sip/sip_ua.h b/core/sip/sip_ua.h index f555ccc5..ea8c18af 100644 --- a/core/sip/sip_ua.h +++ b/core/sip/sip_ua.h @@ -27,14 +27,14 @@ #ifndef _sip_ua_h_ #define _sip_ua_h_ -class trans_bucket; +class trans_ticket; struct sip_msg; class sip_ua { public: virtual ~sip_ua() {} - virtual void handle_sip_request(const char* tid, sip_msg* msg)=0; + virtual void handle_sip_request(trans_ticket* tt, sip_msg* msg)=0; virtual void handle_sip_reply(sip_msg* msg)=0; }; diff --git a/core/sip/trans_layer.cpp b/core/sip/trans_layer.cpp index 2a4efd1b..ea635a43 100644 --- a/core/sip/trans_layer.cpp +++ b/core/sip/trans_layer.cpp @@ -89,7 +89,7 @@ void trans_layer::register_transport(udp_trsp* trsp) -int trans_layer::send_reply(trans_bucket* bucket, sip_trans* t, +int trans_layer::send_reply(trans_ticket* tt, int reply_code, const cstring& reason, const cstring& to_tag, const cstring& hdrs, const cstring& body) @@ -114,7 +114,11 @@ int trans_layer::send_reply(trans_bucket* bucket, sip_trans* t, // MAY be contained: // - Accept - assert(bucket && t); + assert(tt); + assert(tt->_bucket && tt->_t); + + trans_bucket* bucket = tt->_bucket; + sip_trans* t = tt->_t; bucket->lock(); if(!bucket->exist(t)){ @@ -710,7 +714,7 @@ void trans_layer::timeout(trans_bucket* bucket, sip_trans* t) bucket->remove_trans(t); } -int trans_layer::send_request(sip_msg* msg, char* tid, unsigned int& tid_len) +int trans_layer::send_request(sip_msg* msg, trans_ticket* tt) { // Request-URI // To @@ -724,8 +728,11 @@ int trans_layer::send_request(sip_msg* msg, char* tid, unsigned int& tid_len) // Content-Length / Content-Type assert(transport); + assert(msg); + assert(tt); - tid_len = 0; + tt->_bucket = 0; + tt->_t = 0; // assume that msg->route headers are not in msg->hdrs msg->hdrs.insert(msg->hdrs.begin(),msg->route.begin(),msg->route.end()); @@ -796,10 +803,10 @@ int trans_layer::send_request(sip_msg* msg, char* tid, unsigned int& tid_len) ntohs(((sockaddr_in*)&p_msg->remote_ip)->sin_port), p_msg->len,p_msg->buf); - trans_bucket* bucket = get_trans_bucket(p_msg->callid->value, + tt->_bucket = get_trans_bucket(p_msg->callid->value, get_cseq(p_msg)->num_str); - bucket->lock(); - + tt->_bucket->lock(); + int send_err = transport->send(&p_msg->remote_ip,p_msg->buf,p_msg->len); if(send_err < 0){ ERROR("Error from transport layer\n"); @@ -807,24 +814,24 @@ int trans_layer::send_request(sip_msg* msg, char* tid, unsigned int& tid_len) } else { - sip_trans* t = 0; - if(update_uac_request(bucket,t,p_msg) < 0){ + if(update_uac_request(tt->_bucket,tt->_t,p_msg) < 0){ ERROR("Could not update UAC state for request.\n"); } - - string t_id = int2hex(bucket->get_id()).substr(5,string::npos) - + ":" + long2hex((unsigned long)t); - memcpy(tid,t_id.c_str(),t_id.length()); - tid_len = t_id.length(); } - bucket->unlock(); + tt->_bucket->unlock(); return send_err; } -int trans_layer::cancel(trans_bucket* bucket, sip_trans* t) +int trans_layer::cancel(trans_ticket* tt) { + assert(tt); + assert(tt->_bucket && tt->_t); + + trans_bucket* bucket = tt->_bucket; + sip_trans* t = tt->_t; + bucket->lock(); if(!bucket->exist(t)){ DBG("No transaction to cancel: wrong key or finally replied\n"); @@ -1039,15 +1046,14 @@ void trans_layer::received_msg(sip_msg* msg) // New transaction t = bucket->add_trans(msg, TT_UAS); - t_id = int2hex(h).substr(5,string::npos) - + ":" + long2hex((unsigned long)t); - bucket->unlock(); // let's pass the request to // the UA. assert(ua); - ua->handle_sip_request(t_id.c_str(),msg); + + trans_ticket tt(t,bucket); + ua->handle_sip_request(&tt,msg); // forget the msg: it will be // owned by the new transaction diff --git a/core/sip/trans_layer.h b/core/sip/trans_layer.h index 2e2a7a10..ba61e306 100644 --- a/core/sip/trans_layer.h +++ b/core/sip/trans_layer.h @@ -40,12 +40,29 @@ struct sip_trans; struct sip_header; struct sockaddr_storage; -class MyCtrlInterface; class trans_bucket; class udp_trsp; class sip_ua; class timer; +class trans_ticket +{ + sip_trans* _t; + trans_bucket* _bucket; + + friend class trans_layer; + friend class AmSipDialog; + +public: + trans_ticket() + : _t(0), _bucket(0) {} + + trans_ticket(sip_trans* t, trans_bucket* bucket) + : _t(t), _bucket(bucket) {} + + trans_ticket(const trans_ticket& ticket) + : _t(ticket._t), _bucket(ticket._bucket) {} +}; class trans_layer { @@ -134,7 +151,7 @@ class trans_layer * include a well-formed 'Content-Type', but no * 'Content-Length' header. */ - int send_reply(trans_bucket* bucket, sip_trans* t, + int send_reply(trans_ticket* tt, int reply_code, const cstring& reason, const cstring& to_tag, const cstring& hdrs, const cstring& body); @@ -144,18 +161,16 @@ class trans_layer * Caution: Route headers should not be added to the * general header list (msg->hdrs). * @param [in] msg Pre-built message. - * @param [out] tid buffer for the transaction key (char*) - * @param [out] length of transaction key + * @param [out] tt transaction ticket (needed for replies & CANCEL) */ - int send_request(sip_msg* msg, char* tid, unsigned int& tid_len); + int send_request(sip_msg* msg, trans_ticket* tt); /** * Cancels a request. * A CANCEL request is sent if necessary. - * @param bucket bucket of the original request. - * @param t transaction of the original request. + * @param tt transaction ticket from the original INVITE. */ - int cancel(trans_bucket* bucket, sip_trans* t); + int cancel(trans_ticket* tt); /**