Module: sems Branch: rco/offer_answer Commit: b5a12f33656505095e637d2d2088ab706db3dcfc URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sems/?a=commit;h=b5a12f33656505095e637d2d2088ab706db3dcfc
Author: Raphael Coeffic <[email protected]> Committer: Raphael Coeffic <[email protected]> Date: Mon Jun 21 10:59:57 2010 +0200 added sdp dialog handler. --- core/AmSession.cpp | 14 ++++++ core/AmSession.h | 6 +++ core/AmSipDialog.cpp | 113 ++++++++++++++++++++++++++++++++----------------- core/AmSipDialog.h | 23 +++++++++- 4 files changed, 115 insertions(+), 41 deletions(-) diff --git a/core/AmSession.cpp b/core/AmSession.cpp index 7c34729..9ea489d 100644 --- a/core/AmSession.cpp +++ b/core/AmSession.cpp @@ -906,6 +906,20 @@ void AmSession::onSendReply(const AmSipRequest& req, unsigned int code, CALL_EVENT_H(onSendReply,req,code,reason,content_type,body,hdrs,flags); } +/** Hook called when an SDP offer is required */ +void AmSession::onSdpOfferNeeded(AmSdp& offer) +{ + // NYI + assert(0); +} + +/** Hook called when an SDP offer is required */ +void AmSession::onSdpAnswerNeeded(const AmSdp& offer, AmSdp& answer) +{ + // NYI + assert(0); +} + void AmSession::onRtpTimeout() { DBG("stopping Session.\n"); diff --git a/core/AmSession.h b/core/AmSession.h index f143185..a331ff9 100644 --- a/core/AmSession.h +++ b/core/AmSession.h @@ -510,6 +510,12 @@ public: string& hdrs, int flags); + /** Hook called when an SDP offer is required */ + virtual void onSdpOfferNeeded(AmSdp& offer); + + /** Hook called when an SDP offer is required */ + virtual void onSdpAnswerNeeded(const AmSdp& offer, AmSdp& answer); + /** * called in the session thread before the session is destroyed, * i.e. after the main event loop has finished diff --git a/core/AmSipDialog.cpp b/core/AmSipDialog.cpp index 1dbdc34..f119604 100644 --- a/core/AmSipDialog.cpp +++ b/core/AmSipDialog.cpp @@ -74,57 +74,92 @@ void AmSipDialog::updateStatus(const AmSipRequest& req) { DBG("AmSipDialog::updateStatus(request)\n"); - if ((req.method == "ACK") || (req.method == "CANCEL")) { - if(hdl) - hdl->onSipRequest(req); - return; - } + if ((req.method != "ACK") || (req.method != "CANCEL")) { + + // Sanity checks + if (r_cseq_i && req.cseq <= r_cseq){ + INFO("remote cseq lower than previous ones - refusing request\n"); + // see 12.2.2 + reply_error(req, 500, "Server Internal Error"); + return; + } - // Sanity checks - if (r_cseq_i && req.cseq <= r_cseq){ - INFO("remote cseq lower than previous ones - refusing request\n"); - // see 12.2.2 - reply_error(req, 500, "Server Internal Error"); - return; + if ((req.method == "INVITE") && pending_invites) { + reply_error(req,500,"Server Internal Error", + "Retry-After: " + int2str(get_random() % 10) + CRLF); + } + else { + pending_invites++; + } + + r_cseq = req.cseq; + r_cseq_i = true; + uas_trans[req.cseq] = AmSipTransaction(req.method,req.cseq,req.tt); + + // target refresh requests + if (req.from_uri.length() && + (req.method == "INVITE" || + req.method == "UPDATE" || + req.method == "SUBSCRIBE" || + req.method == "NOTIFY")) { + + remote_uri = req.from_uri; + } + + if(callid.empty()){ + callid = req.callid; + remote_tag = req.from_tag; + user = req.user; + domain = req.domain; + local_uri = req.r_uri; + remote_party = req.from; + local_party = req.to; + route = req.route; + } } - if ((req.method == "INVITE") && pending_invites) { - reply_error(req,500,"Server Internal Error", - "Retry-After: " + int2str(get_random() % 10) + CRLF); - } - else { - pending_invites++; + if((req.method == "INVITE" || req.method == "UPDATE" || req.method == "ACK") && + !req.body.empty() && + (req.content_type == "application/sdp")) { + + onSdp(req); } + + if(hdl) + hdl->onSipRequest(req); +} - r_cseq = req.cseq; - r_cseq_i = true; - uas_trans[req.cseq] = AmSipTransaction(req.method,req.cseq,req.tt); +void AmSipDialog::onSdp(const AmSipRequest& req) +{ + const char* err_txt = NULL; + int err_code = 0; - // target refresh requests - if (req.from_uri.length() && - (req.method == "INVITE" || - req.method == "UPDATE" || - req.method == "SUBSCRIBE" || - req.method == "NOTIFY")) { + sdp_remote.setBody(req.body.c_str()); - remote_uri = req.from_uri; + if(sdp_remote.parse()){ + err_code = 400; + err_txt = "session description parsing failed"; + } + else if(sdp_remote.media.empty()){ + err_code = 400; + err_txt = "no media line found in SDP message"; } + else { - if(callid.empty()){ - callid = req.callid; - remote_tag = req.from_tag; - user = req.user; - domain = req.domain; - local_uri = req.r_uri; - remote_party = req.from; - local_party = req.to; - route = req.route; + switch(oa_state) { + case OA_None: + case OA_Completed: + oa_state = OA_OfferRecved; + break; + + case OA_OfferRecved: + oa_state = OA_Completed; + break; + } } - - if(hdl) - hdl->onSipRequest(req); } + /** * * update dialog status from UAC Request that we send (e.g. INVITE) diff --git a/core/AmSipDialog.h b/core/AmSipDialog.h index 5d27722..8239c34 100644 --- a/core/AmSipDialog.h +++ b/core/AmSipDialog.h @@ -29,6 +29,7 @@ #define AmSipDialog_h #include "AmSipMsg.h" +#include "AmSdp.h" #include <string> #include <vector> @@ -69,6 +70,7 @@ typedef std::map<int,AmSipTransaction> TransMap; class AmSipDialogEventHandler { public: + virtual ~AmSipDialogEventHandler() {}; /** Hook called when a request has been received */ virtual void onSipRequest(const AmSipRequest& req)=0; @@ -92,7 +94,7 @@ class AmSipDialogEventHandler const string& body, string& hdrs, int flags)=0; - + /** Hook called when a local INVITE request has been replied with 2xx */ virtual void onInvite2xx(const AmSipReply& reply)=0; @@ -102,7 +104,11 @@ class AmSipDialogEventHandler /** Hook called when a UAS INVITE transaction did not receive a non-2xx-ACK */ virtual void onNoErrorACK(unsigned int cseq)=0; - virtual ~AmSipDialogEventHandler() {}; + /** Hook called when an SDP offer is required */ + virtual void onSdpOfferNeeded(AmSdp& offer)=0; + + /** Hook called when an SDP offer is required */ + virtual void onSdpAnswerNeeded(const AmSdp& offer, AmSdp& answer)=0; }; /** @@ -117,11 +123,24 @@ class AmSipDialog unsigned int pending_invites; + enum OAState { + OA_None=0, + OA_OfferRecved, + OA_Completed + }; + + OAState oa_state; + AmSdp sdp_local; + AmSdp sdp_remote; + AmSipDialogEventHandler* hdl; int updateStatusReply(const AmSipRequest& req, unsigned int code); + void onSdp(const AmSipRequest& req); + void onSdp(const AmSipReply& reply); + public: enum Status { _______________________________________________ Semsdev mailing list [email protected] http://lists.iptel.org/mailman/listinfo/semsdev
