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
sayer/1.4-spce2.6
Raphael Coeffic 16 years ago
parent 7cc53db7a3
commit 778da1ad57

@ -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);

@ -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;

@ -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()

@ -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");

@ -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 @@ 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() { };

@ -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);

@ -52,8 +52,9 @@ class SipCtrlInterface:
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 @@ 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);
};

@ -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;
};

@ -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

@ -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);
/**

Loading…
Cancel
Save