Author: rco
Date: 2010-04-09 14:19:28 +0200 (Fri, 09 Apr 2010)
New Revision: 1778
Modified:
trunk/core/AmB2BSession.cpp
trunk/core/AmSipDialog.cpp
trunk/core/AmSipDialog.h
trunk/core/AmSipMsg.cpp
trunk/core/AmSipMsg.h
trunk/core/SipCtrlInterface.cpp
trunk/core/SipCtrlInterface.h
trunk/core/sip/sip_ua.h
trunk/core/sip/trans_layer.cpp
trunk/core/sip/trans_layer.h
Log:
the old serKey has been replaced by a proper transaction ticket specific to the
internal SIP stack.
Modified: trunk/core/AmB2BSession.cpp
===================================================================
--- trunk/core/AmB2BSession.cpp 2010-04-09 10:26:56 UTC (rev 1777)
+++ trunk/core/AmB2BSession.cpp 2010-04-09 12:19:28 UTC (rev 1778)
@@ -224,7 +224,7 @@
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 @@
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 @@
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);
Modified: trunk/core/AmSipDialog.cpp
===================================================================
--- trunk/core/AmSipDialog.cpp 2010-04-09 10:26:56 UTC (rev 1777)
+++ trunk/core/AmSipDialog.cpp 2010-04-09 12:19:28 UTC (rev 1778)
@@ -72,8 +72,10 @@
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 @@
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 @@
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::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::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 @@
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 @@
req.body = body;
}
- if (SipCtrlInterface::send(req, serKey, serKeyLen))
+ if (SipCtrlInterface::send(req))
return -1;
return 0;
Modified: trunk/core/AmSipDialog.h
===================================================================
--- trunk/core/AmSipDialog.h 2010-04-09 10:26:56 UTC (rev 1777)
+++ trunk/core/AmSipDialog.h 2010-04-09 12:19:28 UTC (rev 1778)
@@ -45,16 +45,18 @@
/** \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()
Modified: trunk/core/AmSipMsg.cpp
===================================================================
--- trunk/core/AmSipMsg.cpp 2010-04-09 10:26:56 UTC (rev 1777)
+++ trunk/core/AmSipMsg.cpp 2010-04-09 12:19:28 UTC (rev 1778)
@@ -133,8 +133,6 @@
{
string buf;
- _PM(serKey, "serkey");
-
_PM(r_uri, "r-uri");
_PM(callid, "i");
_PM(int2str(cseq), "cseq");
@@ -166,8 +164,6 @@
{
string buf;
- _PM(serKey, "serkey");
-
_PM(int2str(code), "code");
_PMB(reason, "phrase");
_PM(callid, "i");
Modified: trunk/core/AmSipMsg.h
===================================================================
--- trunk/core/AmSipMsg.h 2010-04-09 10:26:56 UTC (rev 1777)
+++ trunk/core/AmSipMsg.h 2010-04-09 12:19:28 UTC (rev 1778)
@@ -4,6 +4,8 @@
#include <string>
using std::string;
+#include "sip/trans_layer.h"
+
/* enforce common naming in Req&Rpl */
class _AmSipMsgInDlg
{
@@ -23,7 +25,8 @@
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() { };
Modified: trunk/core/SipCtrlInterface.cpp
===================================================================
--- trunk/core/SipCtrlInterface.cpp 2010-04-09 10:26:56 UTC (rev 1777)
+++ trunk/core/SipCtrlInterface.cpp 2010-04-09 12:19:28 UTC (rev 1778)
@@ -116,25 +116,14 @@
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 @@
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 @@
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 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 @@
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 @@
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 @@
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);
Modified: trunk/core/SipCtrlInterface.h
===================================================================
--- trunk/core/SipCtrlInterface.h 2010-04-09 10:26:56 UTC (rev 1777)
+++ trunk/core/SipCtrlInterface.h 2010-04-09 12:19:28 UTC (rev 1778)
@@ -52,8 +52,9 @@
void prepare_routes_uac(const list<sip_header*>& routes, string&
route_field);
void prepare_routes_uas(const list<sip_header*>& 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 @@
/**
* 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 @@
/**
* 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);
};
Modified: trunk/core/sip/sip_ua.h
===================================================================
--- trunk/core/sip/sip_ua.h 2010-04-09 10:26:56 UTC (rev 1777)
+++ trunk/core/sip/sip_ua.h 2010-04-09 12:19:28 UTC (rev 1778)
@@ -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;
};
Modified: trunk/core/sip/trans_layer.cpp
===================================================================
--- trunk/core/sip/trans_layer.cpp 2010-04-09 10:26:56 UTC (rev 1777)
+++ trunk/core/sip/trans_layer.cpp 2010-04-09 12:19:28 UTC (rev 1778)
@@ -89,7 +89,7 @@
-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,8 +114,12 @@
// 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)){
bucket->unlock();
@@ -710,7 +714,7 @@
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 @@
// 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 @@
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 @@
}
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 @@
// 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
Modified: trunk/core/sip/trans_layer.h
===================================================================
--- trunk/core/sip/trans_layer.h 2010-04-09 10:26:56 UTC (rev 1777)
+++ trunk/core/sip/trans_layer.h 2010-04-09 12:19:28 UTC (rev 1778)
@@ -40,13 +40,30 @@
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 @@
* 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 @@
* 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);
/**
_______________________________________________
Semsdev mailing list
[email protected]
http://lists.iptel.org/mailman/listinfo/semsdev