reorganized session beginning:

- sdp reply generation is now separated from the reply.
  - new onInvite.
corrected a bug in getSession(callid,remote_tag).



git-svn-id: http://svn.berlios.de/svnroot/repos/sems/trunk@22 8eb893ce-cfd4-0310-b710-fb5ebe64c474
sayer/1.4-spce2.6
Raphael Coeffic 21 years ago
parent aae96ca832
commit 555dd79d0a

@ -335,6 +335,11 @@ int AmRtpStream::getRPort()
return r_port;
}
string AmRtpStream::getRHost()
{
return r_host;
}
void AmRtpStream::setRAddr(const string& addr, unsigned short port)
{
DBG("RTP remote address set to %s:%u\n",addr.c_str(),port);

@ -179,7 +179,16 @@ public:
* @return remote RTP port.
*/
int getRPort();
/**
* Gets remote host IP.
* @return remote host IP.
*/
string getRHost();
/**
* Set remote IP & port.
*/
void setRAddr(const string& addr, unsigned short port);
/** Symmetric RTP: passive mode ? */

@ -198,12 +198,14 @@ int AmSession::getRPort()
return rtp_str.getRPort();
}
void AmSession::negotiate(const AmSipRequest& request)
void AmSession::negotiate(const string& sdp_body,
bool force_symmetric_rtp,
string& sdp_reply)
{
string r_host = "";
int r_port = 0;
sdp.setBody(request.body.c_str());
sdp.setBody(sdp_body.c_str());
if(sdp.parse())
throw AmSession::Exception(400,"session description parsing failed");
@ -240,46 +242,22 @@ void AmSession::negotiate(const AmSipRequest& request)
DBG("remote party doesn't support telephone events\n");
}
string str_msg_flags = getHeader(request.hdrs,"P-MsgFlags");
unsigned int msg_flags = 0;
if(reverse_hex2int(str_msg_flags,msg_flags)){
ERROR("while parsing 'P-MsgFlags' header\n");
msg_flags = 0;
}
DBG("msg_flags=%u\n",msg_flags);
bool passive_mode = false;
if( sdp.remote_active
|| (msg_flags & FL_FORCE_ACTIVE) ) {
if( sdp.remote_active || force_symmetric_rtp) {
DBG("The other UA is NATed: switched to passive mode.\n");
DBG("remote_active = %i; msg_flags = %i\n",
sdp.remote_active,msg_flags);
DBG("remote_active = %i; force_symmetric_rtp = %i\n",
sdp.remote_active,force_symmetric_rtp);
passive_mode = true;
}
//TODO: if dialog started
if(first_negotiation)
onBeforeCallAccept(request);
lockAudio();
rtp_str.setLocalIP(AmConfig::LocalIP);
unlockAudio();
string sdp_body;
sdp.genResponse(AmConfig::LocalIP,rtp_str.getLocalPort(),sdp_body);
if( dlg.reply(request,200,"OK",
"application/sdp",sdp_body//, getReplyHeaders(request)
) != 0 )
throw AmSession::Exception(500,"could not send response.");
sdp.genResponse(AmConfig::LocalIP,rtp_str.getLocalPort(),sdp_reply);
lockAudio();
rtp_str.setLocalIP(AmConfig::LocalIP);
rtp_str.setPassiveMode(passive_mode);
rtp_str.setRAddr(r_host, r_port);
unlockAudio();
DBG("Sending Rtp data to %s/%i\n",r_host.c_str(),r_port);
first_negotiation = false;
}
void AmSession::run()
@ -476,7 +454,18 @@ void AmSession::onSipRequest(const AmSipRequest& req)
DBG("onSipRequest: method = %s\n",req.method.c_str());
if(req.method == "INVITE"){
acceptAudio(req);
onInvite(req);
if(detached.get()){
onSessionStart(req);
if(input || output)
AmSessionScheduler::instance()->addSession(this, callgroup);
else {
ERROR("missing audio input and/or ouput.\n");
}
}
}
else if( req.method == "BYE" ){
@ -486,7 +475,10 @@ void AmSession::onSipRequest(const AmSipRequest& req)
else if( req.method == "CANCEL" ){
dlg.reply(req,200,"OK");
onCancel();
} else if( req.method == "INFO" ){
if ((strip_header_params(getHeader(req.hdrs, "Content-Type"))
=="application/dtmf-relay")||
(strip_header_params(getHeader(req.hdrs, "c"))
@ -504,35 +496,50 @@ void AmSession::onSipReply(const AmSipReply& reply)
dlg.updateStatus(reply);
}
void AmSession::onInvite(const AmSipRequest& req)
{
string sdp_reply;
if(acceptAudio(req,sdp_reply)!=0)
return;
if(dlg.reply(req,200,"OK",
"application/sdp",sdp_reply) != 0){
//throw AmSession::Exception(500,"error while sending response");
setStopped();
}
}
void AmSession::onBye(const AmSipRequest& req)
{
setStopped();
}
int AmSession::acceptAudio(const AmSipRequest& req)
int AmSession::acceptAudio(const AmSipRequest& req,
string& sdp_reply)
{
try {
try {
// handle codec and send reply
negotiate(req);
string str_msg_flags = getHeader(req.hdrs,"P-MsgFlags");
unsigned int msg_flags = 0;
if(reverse_hex2int(str_msg_flags,msg_flags)){
ERROR("while parsing 'P-MsgFlags' header\n");
msg_flags = 0;
}
negotiate( req.body,
msg_flags & FL_FORCE_ACTIVE,
sdp_reply);
// enable RTP stream
lockAudio();
rtp_str.init(&payload);
unlockAudio();
if(detached.get()){
onSessionStart(req);
if(input || output)
AmSessionScheduler::instance()->addSession(this, callgroup);
else {
ERROR("missing audio input and/or ouput.\n");
return -1;
}
}
DBG("Sending Rtp data to %s/%i\n",
rtp_str.getRHost().c_str(),rtp_str.getRPort());
return 0;
}
catch(const AmSession::Exception& e){ throw e; }
@ -586,4 +593,3 @@ void AmSession::sendReinvite()
dlg.reinvite("", "application/sdp", sdp_body);
}

@ -182,7 +182,8 @@ public:
* Accept the INVITE proposal
* thus setting up audio stream
*/
int acceptAudio(const AmSipRequest& req);
int acceptAudio(const AmSipRequest& req,
string& sdp_reply);
/**
* Lock and unlock audio input & output
@ -233,7 +234,9 @@ public:
int getRPort();
/** handle SDP negotiation: only for INVITEs & re-INVITEs */
virtual void negotiate(const AmSipRequest& request);
virtual void negotiate(const string& sdp_body,
bool force_symmetric_rtp,
string& sdp_reply);
void sendUpdate();
void sendReinvite();
@ -282,13 +285,24 @@ public:
virtual void onStart(){}
/**
* onBeforeCallAccept will be called on incoming
* request before the call gets definitely established.
*
* Throw AmSession::Exception if you want to
* signal any error.
* onInvite will be called if an INVITE or re-INVITE
* has been received for the session.
*/
virtual void onInvite(const AmSipRequest& req);
/**
* onCancel will be called if a CANCEL for a running
* dialog has been received. At this point, the CANCEL
* transaction has been replied with 200.
*
* A normal plug-in does not have to do anything special,
* as normal dialogs are immediatly replied with 200
* or error code.
*
* Note: You are still responsible for responding the
* initial transaction.
*/
virtual void onBeforeCallAccept(const AmSipRequest& req){}
virtual void onCancel(){}
/**
* onSessionStart will be called after call setup.

@ -142,7 +142,7 @@ AmSession* AmSessionContainer::getSession(const string& callid, const string& re
return NULL;
}
return getSession(it->first);
return getSession(it->second);
}
AmSession* AmSessionContainer::getSession(const string& local_tag)
@ -209,8 +209,8 @@ bool AmSessionContainer::postEvent(const string& callid,
const string& remote_tag,
AmEvent* event)
{
DBG("postEvent: callid = %s; remote_tag = %s\n",
callid.c_str(),remote_tag.c_str());
// DBG("postEvent: callid = %s; remote_tag = %s\n",
// callid.c_str(),remote_tag.c_str());
as_mut.lock();
AmSession* s = getSession(callid,remote_tag);
@ -228,7 +228,7 @@ bool AmSessionContainer::postEvent(const string& callid,
bool AmSessionContainer::postEvent(const string& local_tag,
AmEvent* event)
{
DBG("postEvent: local_tag = %s\n",local_tag.c_str());
// DBG("postEvent: local_tag = %s\n",local_tag.c_str());
as_mut.lock();
AmSession* s = getSession(local_tag);
@ -239,7 +239,7 @@ bool AmSessionContainer::postEvent(const string& local_tag,
return false;
}
DBG("posting...\n");
// DBG("posting...\n");
s->postEvent(event);
return true;
}

Loading…
Cancel
Save