[asterisk-scf-commits] asterisk-scf/integration/sip.git branch "master" updated.

Commits to the Asterisk SCF project code repositories asterisk-scf-commits at lists.digium.com
Tue Sep 7 15:36:05 CDT 2010


branch "master" has been updated
       via  4bcab574c90611397c5d9a112f36f4914aeeaef2 (commit)
      from  db8c0d391fc71d23653cc29558a21b6a264c7057 (commit)

Summary of changes:
 src/PJSipSessionModule.cpp |   80 +++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 79 insertions(+), 1 deletions(-)


- Log -----------------------------------------------------------------
commit 4bcab574c90611397c5d9a112f36f4914aeeaef2
Author: Joshua Colp <jcolp at digium.com>
Date:   Tue Sep 7 17:43:32 2010 -0300

    Add code which interprets a pjmedia SDP structure, constructs SDP discovery classes, and finds media formats based on them. This does not yet use those media formats though.

diff --git a/src/PJSipSessionModule.cpp b/src/PJSipSessionModule.cpp
index 9506b07..0319642 100644
--- a/src/PJSipSessionModule.cpp
+++ b/src/PJSipSessionModule.cpp
@@ -10,6 +10,7 @@
 #include <Core/Routing/RoutingIf.h>
 #include <Core/Bridging/BridgeServiceIf.h>
 #include <Session/SessionIf.h>
+#include <Media/MediaIf.h>
 
 #include "PJSipSessionModule.h"
 #include "SipChannelServiceDataModel.h"
@@ -27,6 +28,7 @@ using namespace Hydra::Core::Routing::V1;
 using namespace Hydra::Core::Bridging::V1;
 using namespace Hydra::Core::Endpoint::V1;
 using namespace Hydra::Session::V1;
+using namespace Hydra::Media::V1;
 
 static pj_status_t sessionLoad(pjsip_endpoint *endpt)
 {
@@ -399,11 +401,87 @@ static void invOnMediaUpdate(pjsip_inv_session *inv, pj_status_t status)
    }
 
    const pjmedia_sdp_session *remote_sdp;
-   status = pjmedia_sdp_neg_get_active_remote(inv->neg, &remote_sdp);
+   if ((status = pjmedia_sdp_neg_get_active_remote(inv->neg, &remote_sdp)) != PJ_SUCCESS)
+   {
+      // TODO: What happens if we can't get negotiated SDP?
+      return;
+   }
+
    const pjmedia_sdp_conn *remote_conn = remote_sdp->media[0]->conn ? remote_sdp->media[0]->conn : remote_sdp->conn;
 
    SipEndpointPtr *endpoint = (SipEndpointPtr*)inv->dlg->mod_data[pjsip_ua_instance()->id];
    (*endpoint)->setRemoteDetails(pj_strbuf(&remote_conn->addr), remote_sdp->media[0]->desc.port);
+
+   // Each stream has its own set of formats, so go to that granularity
+   for (unsigned int stream = 0; stream < remote_sdp->media_count; stream++)
+   {
+      // We should have the parsing of the connection information here
+
+      // We should have the parsing of the rtcp attribute here
+
+      FormatSeq formats;
+
+      // Next step is to see what formats exist on this stream
+      for (unsigned int format = 0; format < remote_sdp->media[stream]->desc.fmt_count; format++)
+      {
+	 FormatDiscoverySDPPtr params = new FormatDiscoverySDP();
+	 params->category = "media_format";
+	 params->payload = *remote_sdp->media[stream]->desc.fmt[format].ptr;
+	 params->type = std::string(pj_strbuf(&remote_sdp->media[stream]->desc.media), pj_strlen(&remote_sdp->media[stream]->desc.media));
+
+	 // Some devices rely solely on the payload for known formats (such as PCMU) so the following format parameters are optional
+	 const pjmedia_sdp_attr *attr;
+	 if ((attr = pjmedia_sdp_media_find_attr2(remote_sdp->media[stream], "rtpmap", &remote_sdp->media[stream]->desc.fmt[format])))
+	 {
+	    pjmedia_sdp_rtpmap *rtpmap;
+	    if ((pjmedia_sdp_attr_to_rtpmap(inv->pool_active, attr, &rtpmap)) == PJ_SUCCESS)
+	    {
+	       params->subtype = std::string(pj_strbuf(&rtpmap->enc_name), pj_strlen(&rtpmap->enc_name));
+	       params->samplerate = rtpmap->clock_rate;
+	    }
+	 }
+
+	 // Next we move on to the format specific parameters
+	 if ((attr = pjmedia_sdp_media_find_attr2(remote_sdp->media[stream], "fmtp", &remote_sdp->media[stream]->desc.fmt[format])))
+	 {
+	    pjmedia_sdp_fmtp fmtp;
+	    if ((pjmedia_sdp_attr_get_fmtp(attr, &fmtp)) == PJ_SUCCESS)
+	    {
+	       std::string parameter = std::string(pj_strbuf(&fmtp.fmt_param), pj_strlen(&fmtp.fmt_param));
+	       params->parameters.push_back(parameter);
+	    }
+	 }
+
+	 // Next up are attributes that are not specific to the format, such as ptime
+	 for (unsigned int attribute = 0; attribute < remote_sdp->media[stream]->attr_count; attribute++)
+	 {
+	    // Attributes we already touch above OR know aren't helpful to the media format component don't need to be given to it, obviously
+	    if (!pj_strcmp2(&remote_sdp->media[stream]->attr[attribute]->name, "rtpmap") ||
+		!pj_strcmp2(&remote_sdp->media[stream]->attr[attribute]->name, "fmtp") ||
+		!pj_strcmp2(&remote_sdp->media[stream]->attr[attribute]->name, "rtcp") ||
+		!pj_strcmp2(&remote_sdp->media[stream]->attr[attribute]->name, "sendrecv") ||
+		!pj_strcmp2(&remote_sdp->media[stream]->attr[attribute]->name, "sendonly") ||
+		!pj_strcmp2(&remote_sdp->media[stream]->attr[attribute]->name, "recvonly"))
+	    {
+	       continue;
+	    }
+
+	    std::string parameter = std::string(pj_strbuf(&remote_sdp->media[stream]->attr[attribute]->name), pj_strlen(&remote_sdp->media[stream]->attr[attribute]->name)) + ':' +
+	       std::string(pj_strbuf(&remote_sdp->media[stream]->attr[attribute]->value), pj_strlen(&remote_sdp->media[stream]->attr[attribute]->value));
+	    params->parameters.push_back(parameter);
+	 }
+
+	 SipChannelServiceDataModel &dataModel = SipChannelServiceDataModel::getInstance();
+	 MediaFormatServicePrx service = MediaFormatServicePrx::uncheckedCast(dataModel.getServiceLocator()->locate(params));
+
+	 // It is entirely possible for the service locator to not find a service that knows about this media format
+	 if (service != 0)
+	 {
+	    FormatPtr format = FormatPtr::dynamicCast(service->getFormat(params));
+	    formats.push_back(format);
+	 }
+      }
+   }
 }
 //Comment this out for now so pjsip will send the ACK for us.
 //static void invOnSendAck(pjsip_inv_session *inv, pjsip_rx_data *rdata)

-----------------------------------------------------------------------


-- 
asterisk-scf/integration/sip.git



More information about the asterisk-scf-commits mailing list