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

Commits to the Asterisk SCF project code repositories asterisk-scf-commits at lists.digium.com
Fri Oct 14 15:52:07 CDT 2011


branch "party-id" has been updated
       via  acc52bcd5208a0f34d86da53f78194cd5b19dd31 (commit)
      from  d03e55a9a03a9fd63ac7a236859552ab215af8a7 (commit)

Summary of changes:
 src/PJSipSessionModule.cpp |  160 +++++++++++++++++++++++++++++++++++++++++---
 src/PJSipSessionModule.h   |   12 +++
 src/SipSession.cpp         |   45 ++++++++++--
 3 files changed, 200 insertions(+), 17 deletions(-)


- Log -----------------------------------------------------------------
commit acc52bcd5208a0f34d86da53f78194cd5b19dd31
Author: Mark Michelson <mmichelson at digium.com>
Date:   Fri Oct 14 15:21:19 2011 -0500

    Add reason and privacy parsing.

diff --git a/src/PJSipSessionModule.cpp b/src/PJSipSessionModule.cpp
index ff0ed75..721f9ce 100644
--- a/src/PJSipSessionModule.cpp
+++ b/src/PJSipSessionModule.cpp
@@ -26,6 +26,7 @@
 
 #include <IceUtil/UUID.h>
 #include <boost/lexical_cast.hpp>
+#include <boost/algorithm/string.hpp>
 
 #include <AsteriskSCF/Core/Endpoint/EndpointIf.h>
 #include <AsteriskSCF/Core/Routing/RoutingIf.h>
@@ -630,18 +631,123 @@ CallerPtr PJSipSessionModule::getCallerID(pjsip_rx_data *rdata)
     return caller;
 }
 
+std::string PJSipSessionModule::getParam(const std::string& headerVal, const char *paramName)
+{
+    std::vector<std::string> params;
+    boost::split(params, headerVal, boost::is_any_of(";"));
+    std::string paramValue;
+    for (std::vector<std::string>::iterator paramsIter = params.begin();
+            paramsIter != params.end(); ++paramsIter)
+    {
+        if (paramsIter->substr(0, sizeof(paramName)) == paramName)
+        {
+            paramValue = paramsIter->substr(sizeof(paramName));
+        }
+    }
+    return paramValue;
+}
+
+Reason PJSipSessionModule::translateReason(const std::string& reason)
+{
+    if (reason == "unknown")
+    {
+        return Unknown;
+    }
+    else if (reason == "user-busy")
+    {
+        return UserBusy;
+    }
+    else if (reason == "no-answer")
+    {
+        return NoAnswer;
+    }
+    else if (reason == "unavailable")
+    {
+        return Unavailable;
+    }
+    else if (reason == "unconditional")
+    {
+        return Unconditional;
+    }
+    else if (reason == "time-of-day")
+    {
+        return TimeOfDay;
+    }
+    else if (reason == "do-not-disturb")
+    {
+        return DoNotDisturb;
+    }
+    else if (reason == "deflection")
+    {
+        return Deflection;
+    }
+    else if (reason == "follow-me")
+    {
+        return FollowMe;
+    }
+    else if (reason == "out-of-service")
+    {
+        return OutOfService;
+    }
+    else if (reason == "away")
+    {
+        return Away;
+    }
+    else
+    {
+        return Unknown;
+    }
+}
+
+void PJSipSessionModule::getRedirectionIds(pjsip_rx_data *rdata,
+        bool privacySet,
+        ReasonIdSeq& ids)
+{
+    pj_str_t hdrName;
+    pj_cstr(&hdrName, "Diversion");
+
+    pjsip_generic_string_hdr *hdr = (pjsip_generic_string_hdr *) &rdata->msg_info.msg->hdr;
+    while ((hdr = (pjsip_generic_string_hdr *) pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &hdrName, hdr->next)))
+    { 
+        //With diversion headers, we want to get the reason parameter.
+        std::string headerVal(pj_strbuf(&hdr->hvalue), pj_strlen(&hdr->hvalue));
+        std::string reasonStr = getParam(headerVal, "reason=");
+        Reason reason = translateReason(reasonStr);
+
+        pjsip_name_addr *idNameAddr;
+        //pjsip_parse_uri is incredibly clear that the input string must be
+        //null-terminated. The header we have grabbed is NOT null-terminated,
+        //so we need to create a null-terminated copy.
+        //
+        //Furthermore, I can't use a std::string here because std::string::c_str()
+        //returns a const char *, and pjsip_parse_uri takes a non-const char * as
+        //its second parameter.
+        pj_str_t strCopy;
+        pj_strdup_with_null(rdata->tp_info.pool, &strCopy, &hdr->hvalue);
+        idNameAddr = (pjsip_name_addr*) pjsip_parse_uri(rdata->tp_info.pool, strCopy.ptr, strCopy.slen, PJSIP_PARSE_URI_AS_NAMEADDR);
+
+        NamePtr name(new Name(std::string(pj_strbuf(&idNameAddr->display), pj_strlen(&idNameAddr->display))));
+
+        pjsip_sip_uri *idURI = (pjsip_sip_uri *) pjsip_uri_get_uri(idNameAddr);
+        NumberPtr number (new Number(std::string(pj_strbuf(&idURI->user), pj_strlen(&idURI->user))));
+
+        IdPtr id(new Id(name, number, new Privacy(privacySet)));
+        ids.push_back(std::make_pair(reason, id));
+    }
+}
+
 RedirectionsPtr PJSipSessionModule::getRedirections(pjsip_rx_data *rdata, pjsip_sip_uri *ruri)
 {
     RedirectionsPtr redirections(new Redirections);
-    IdSeq ids;
+    ReasonIdSeq ids;
     bool privacySet = getPrivacy(rdata);
-    getIds("Diversion", rdata, privacySet, ids);
+    getRedirectionIds(rdata, privacySet, ids);
     
     NamePtr rURIName(new Name(std::string(pj_strbuf(&ruri->user), pj_strlen(&ruri->user))));
     NumberPtr rURINumber(new Number(std::string(pj_strbuf(&ruri->user), pj_strlen(&ruri->user))));
     PrivacyPtr rURIPrivacy(new Privacy(false));
     IdPtr rURIId(new Id(rURIName, rURINumber, rURIPrivacy));
-    for (IdSeq::iterator id = ids.begin(); id != ids.end(); ++id)
+    for (ReasonIdSeq::iterator id = ids.begin(); id != ids.end(); ++id)
     {
         //Each ID we've read indicates a redirection *from* something,
         //so we'll fill in the redirecting from information based on it.
@@ -649,7 +755,7 @@ RedirectionsPtr PJSipSessionModule::getRedirections(pjsip_rx_data *rdata, pjsip_
         //targets, so we will just have to fill in the to information with
         //the data from the next diversion if it is present or from the
         //RURI if we've reached the end of the list.
-        IdSeq::iterator nextId = id + 1;
+        ReasonIdSeq::iterator nextId = id + 1;
         IdPtr toId;
         if (nextId == ids.end())
         {
@@ -658,16 +764,52 @@ RedirectionsPtr PJSipSessionModule::getRedirections(pjsip_rx_data *rdata, pjsip_
         }
         else
         {
-            toId = *nextId;
+            toId = nextId->second;
         }
-        //XXX TODO get the reason from the Diversion headah!
-        RedirectionReasonPtr reason(new RedirectionReason(Unknown));
-        RedirectionPtr redirect(new Redirection(*id, toId, reason));
+        RedirectionPtr redirect(new Redirection(id->second, toId, new RedirectionReason(id->first)));
         redirections->redirects.push_back(redirect);
     }
     return redirections;
 }
 
+void PJSipSessionModule::getRemotePartyIds(pjsip_rx_data *rdata, bool privacySet, IdSeq& ids)
+{
+    pj_str_t hdrName;
+    pj_cstr(&hdrName, "Remote-Party-ID");
+
+    pjsip_generic_string_hdr *hdr = (pjsip_generic_string_hdr *) &rdata->msg_info.msg->hdr;
+    while ((hdr = (pjsip_generic_string_hdr *) pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &hdrName, hdr->next)))
+    { 
+        //With Remote-Party-ID headers, we want to get the privacy and screen parameters.
+        std::string headerVal(pj_strbuf(&hdr->hvalue), pj_strlen(&hdr->hvalue));
+        std::string privacy = getParam(headerVal, "privacy=");
+        std::string screen = getParam(headerVal, "screen=");
+
+        PrivacyPtr userPrivacy = new UserNumberPrivacy(privacy == "full" || privacySet, screen == "yes");
+
+        pjsip_name_addr *idNameAddr;
+        //pjsip_parse_uri is incredibly clear that the input string must be
+        //null-terminated. The header we have grabbed is NOT null-terminated,
+        //so we need to create a null-terminated copy.
+        //
+        //Furthermore, I can't use a std::string here because std::string::c_str()
+        //returns a const char *, and pjsip_parse_uri takes a non-const char * as
+        //its second parameter.
+        pj_str_t strCopy;
+        pj_strdup_with_null(rdata->tp_info.pool, &strCopy, &hdr->hvalue);
+        idNameAddr = (pjsip_name_addr*) pjsip_parse_uri(rdata->tp_info.pool, strCopy.ptr, strCopy.slen, PJSIP_PARSE_URI_AS_NAMEADDR);
+
+        NamePtr name(new Name(std::string(pj_strbuf(&idNameAddr->display), pj_strlen(&idNameAddr->display))));
+
+        pjsip_sip_uri *idURI = (pjsip_sip_uri *) pjsip_uri_get_uri(idNameAddr);
+        NumberPtr number (new Number(std::string(pj_strbuf(&idURI->user), pj_strlen(&idURI->user))));
+
+        IdPtr id(new Id(name, number, userPrivacy));
+        ids.push_back(id);
+    }
+
+}
+
 ConnectedLinePtr PJSipSessionModule::getConnectedID(pjsip_rx_data *rdata)
 {
     ConnectedLinePtr connected(new ConnectedLine);
@@ -680,7 +822,7 @@ ConnectedLinePtr PJSipSessionModule::getConnectedID(pjsip_rx_data *rdata)
 
     //There were no P-Asserted-Identity headers present. Maybe
     //they've used Remote-Party-ID instead...
-    getIds("Remote-Party-ID", rdata, privacySet, connected->ids);
+    getRemotePartyIds(rdata, privacySet, connected->ids);
     return connected;
 }
 
diff --git a/src/PJSipSessionModule.h b/src/PJSipSessionModule.h
index cefb899..56c5ed6 100644
--- a/src/PJSipSessionModule.h
+++ b/src/PJSipSessionModule.h
@@ -96,6 +96,10 @@ private:
 
 typedef IceUtil::Handle<SipSessionCreationExtensionPoint> SipSessionCreationExtensionPointPtr;
 
+typedef std::pair<AsteriskSCF::SessionCommunications::PartyIdentification::V1::Reason,
+        AsteriskSCF::SessionCommunications::PartyIdentification::V1::IdPtr> ReasonId;
+typedef std::vector<ReasonId> ReasonIdSeq;
+
 class PJSipSessionModule : public PJSipModule
 {
 public:
@@ -145,6 +149,14 @@ private:
             pjsip_rx_data *rdata,
             bool privacySet,
             AsteriskSCF::SessionCommunications::PartyIdentification::V1::IdSeq& ids);
+    void getRedirectionIds(pjsip_rx_data *rdata,
+            bool privacySet,
+            ReasonIdSeq& ids);
+    void getRemotePartyIds(pjsip_rx_data *rdata,
+            bool privacySet,
+            AsteriskSCF::SessionCommunications::PartyIdentification::V1::IdSeq& ids);
+    std::string getParam(const std::string& headerVal, const char *paramName);
+    AsteriskSCF::SessionCommunications::PartyIdentification::V1::Reason translateReason(const std::string& reason);
     AsteriskSCF::SessionCommunications::PartyIdentification::V1::CallerPtr getCallerID(pjsip_rx_data *rdata);
     AsteriskSCF::SessionCommunications::PartyIdentification::V1::ConnectedLinePtr getConnectedID(pjsip_rx_data *rdata);
     AsteriskSCF::SessionCommunications::PartyIdentification::V1::RedirectionsPtr getRedirections(pjsip_rx_data *rdata, pjsip_sip_uri *ruri);
diff --git a/src/SipSession.cpp b/src/SipSession.cpp
index 6b3daaa..2357091 100755
--- a/src/SipSession.cpp
+++ b/src/SipSession.cpp
@@ -1576,11 +1576,9 @@ private:
                 connectedName = connectedNumber;
             }
             pj_str_t paiValue;
-            std::stringstream ss;
-
             SipEndpointConfig &config = mSession->getEndpoint()->getConfig();
-            ss << "\"" << connectedName << "\" <" << connectedNumber << "@" << config.sessionConfig.sourceAddress << ">;party=called";
-            pj_cstr(&paiValue, ss.str().c_str());
+            std::string ss = "\"" + connectedName + "\" <" + connectedNumber + "@" + config.sessionConfig.sourceAddress + ">;party=called";
+            pj_strset(&paiValue, (char *) ss.c_str(), ss.length());
 
             pjsip_generic_string_hdr *hdr =
                 pjsip_generic_string_hdr_create(packet->pool, &paiHeader, &paiValue);
@@ -2098,10 +2096,9 @@ private:
                 callerName = callerNumber;
             }
             pj_str_t paiValue;
-            std::stringstream ss;
             SipEndpointConfig &config = mSession->getEndpoint()->getConfig();
-            ss << "\"" << callerName << "\" <" << callerNumber << "@" << config.sessionConfig.sourceAddress << ">;party=calling";
-            pj_strset(&paiValue, (char *) ss.str().c_str(), ss.str().length());
+            std::string ss = "\"" + callerName + "\" <" + callerNumber + "@" + config.sessionConfig.sourceAddress + ">;party=calling";
+            pj_strset(&paiValue, (char *) ss.c_str(), ss.length());
 
             pjsip_generic_string_hdr *hdr =
                 pjsip_generic_string_hdr_create(packet->pool, &paiHeader, &paiValue);
@@ -2136,7 +2133,8 @@ private:
             pj_str_t diversionValue;
             std::stringstream ss;
             SipEndpointConfig &config = mSession->getEndpoint()->getConfig();
-            ss << "\"" << fromName << "\" <" << fromNumber << "@" << config.sessionConfig.sourceAddress << ">;reason=unconditional;counter=1";
+            std::string reason = getReason(*redirects);
+            ss << "\"" << fromName << "\" <" << fromNumber << "@" << config.sessionConfig.sourceAddress << ">;reason=" << reason << ";counter=1";
             pj_strset(&diversionValue, (char *) ss.str().c_str(), ss.str().length());
 
             pjsip_generic_string_hdr *hdr =
@@ -2145,6 +2143,37 @@ private:
             pjsip_msg_add_hdr(packet->msg, (pjsip_hdr*) hdr);
         }
     }
+
+    std::string getReason(const RedirectionPtr& redirection)
+    {
+        switch (redirection->reason->why)
+        {
+            case AsteriskSCF::SessionCommunications::PartyIdentification::V1::Unknown:
+                return "unknown";
+            case AsteriskSCF::SessionCommunications::PartyIdentification::V1::UserBusy:
+                return "user-busy";
+            case AsteriskSCF::SessionCommunications::PartyIdentification::V1::NoAnswer:
+                return "no-answer";
+            case AsteriskSCF::SessionCommunications::PartyIdentification::V1::Unavailable:
+                return "unavailable";
+            case AsteriskSCF::SessionCommunications::PartyIdentification::V1::Unconditional:
+                return "unconditional";
+            case AsteriskSCF::SessionCommunications::PartyIdentification::V1::TimeOfDay:
+                return "time-of-day";
+            case AsteriskSCF::SessionCommunications::PartyIdentification::V1::DoNotDisturb:
+                return "do-not-disturb";
+            case AsteriskSCF::SessionCommunications::PartyIdentification::V1::Deflection:
+                return "deflection";
+            case AsteriskSCF::SessionCommunications::PartyIdentification::V1::FollowMe:
+                return "follow-me";
+            case AsteriskSCF::SessionCommunications::PartyIdentification::V1::OutOfService:
+                return "out-of-service";
+            case AsteriskSCF::SessionCommunications::PartyIdentification::V1::Away:
+                return "away";
+            default:
+                return "unknown";
+        }
+    }
     SipSessionPtr mSession;
     boost::shared_ptr<SipSessionPriv> mImplPriv;
 };

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


-- 
asterisk-scf/integration/sip.git



More information about the asterisk-scf-commits mailing list