[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