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

Reply via email to