The attached patch extends the mappingrules.xml with an optional
<callerMatch><callerPattern /></callerMatch> tag set (child of
userMatch), this takes a reg ex like the userPattern but is applied to
the from address instead of the to address. The intended purpose is to
allow a single number to resolve into different extensions depending on
who is calling it, e.g. in the case of regional offices with one central
contact number that gets routed to different call centers depending on
the caller's area code.
It's a work-in-progress, I'm looking for feedback on what I have so far.
--
-------------------------------------------------------------------
David Becker
IANT- APPLIED NGN-TECHNOLOGIES
Schlüsselfertige VoIP-Lösungen und mehr...
IANT GmbH
Salzdahlumer Straße 46/48
D-38302 Wolfenbüttel
Fon: +49/(0)5331/ 900989-450
Fax: +49/(0)5331/ 900989-499
Internet: www.iant.de
Ust.-IdNr: DE264352710
HRB 201710, Amtsgericht Braunschweig
Geschäftsführer: Prof. Dr.-Ing. Diederich Wermser, Dipl.-Ing. Jan Schumacher
IANT is Member of GROUPLINK
www.grouplink.de
>From 67c33ef0a72c5592c40e63d4fa4b574fbb3adfa1 Mon Sep 17 00:00:00 2001
From: David Becker <[email protected]>
Date: Thu, 7 Jul 2011 13:41:35 +0200
Subject: [PATCH] Mappingrules can now specify a caller pattern that allows
restricting the rule to specific caller IDs.
---
.../include/digitmaps/MappingRulesUrlMapping.h | 1 +
sipXcommserverLib/include/digitmaps/UrlMapping.h | 12 +++-
sipXcommserverLib/meta/urlmap.xsd | 25 ++++++
.../src/digitmaps/MappingRulesUrlMapping.cpp | 11 ++-
sipXcommserverLib/src/digitmaps/UrlMapping.cpp | 82 +++++++++++++++++++-
.../lib/redirect_plugins/SipRedirectorMapping.cpp | 3 +
6 files changed, 124 insertions(+), 10 deletions(-)
diff --git a/sipXcommserverLib/include/digitmaps/MappingRulesUrlMapping.h
b/sipXcommserverLib/include/digitmaps/MappingRulesUrlMapping.h
index 256ac7b..1e7c443 100644
--- a/sipXcommserverLib/include/digitmaps/MappingRulesUrlMapping.h
+++ b/sipXcommserverLib/include/digitmaps/MappingRulesUrlMapping.h
@@ -72,6 +72,7 @@ public:
/// Evaluate a request URI using mapping rules semantics, return contacts
and permissions.
OsStatus getContactList(const Url& requestUri, ///< target to check
+ UtlString& sourceUri, ///< source of this request
ResultSet& rContacts, ///< contacts generated
from first match
ResultSet& rPermissions, ///< permissions that
target must have
UtlString& callTag ///< call tag for contacts.
diff --git a/sipXcommserverLib/include/digitmaps/UrlMapping.h
b/sipXcommserverLib/include/digitmaps/UrlMapping.h
index c8354a9..d3e87c6 100644
--- a/sipXcommserverLib/include/digitmaps/UrlMapping.h
+++ b/sipXcommserverLib/include/digitmaps/UrlMapping.h
@@ -35,6 +35,8 @@
#define XML_TAG_PERMISSION ("permission")
#define XML_ATT_AUTHTYPE ("authType")
+#define XML_TAG_CALLERMATCH ("callerMatch")
+#define XML_TAG_CALLERPATTERN ("callerPattern")
#define XML_TAG_CALLERLOCATIONMATCH ("callerLocationMatch")
#define XML_TAG_CALLERLOCATION ("callerLocation")
@@ -121,7 +123,8 @@ protected:
UtlString& variableDigits,
const TiXmlNode*&
prMatchingUserMatchContainerNode,
const TiXmlNode*&
prMatchingHostMatchContainerNode,
- const char* ruleType =
NULL ///< e.g. Emergency to match only emerg rules
+ const char* ruleType =
NULL, ///< e.g. Emergency to match only emerg rules
+ const Url* sourceUri =
NULL
) const;
OsStatus doTransform(const Url& requestUri,
@@ -142,9 +145,14 @@ private:
OsStatus getUserMatchContainer(const Url& requestUri,
const TiXmlNode* const pHostMatchNode,
UtlString& variableDigits,
- const TiXmlNode*&
prMatchingUserMatchContainerNode
+ const TiXmlNode*&
prMatchingUserMatchContainerNode,
+ const Url* sourceUri = NULL
) const;
+ OsStatus isCallerCovered(const Url* sourceUri,
+ const TiXmlNode* const pUserMatchNode
+ ) const;
+
/// Get the name/value pair from an element; supports two syntaxes.
bool getNamedAttribute(const TiXmlElement* component, ///< the xml element
to interpret
UtlString& name, ///< the content name
diff --git a/sipXcommserverLib/meta/urlmap.xsd
b/sipXcommserverLib/meta/urlmap.xsd
index 97f862a..f3b37a5 100644
--- a/sipXcommserverLib/meta/urlmap.xsd
+++ b/sipXcommserverLib/meta/urlmap.xsd
@@ -117,6 +117,7 @@
<element ref='dmp:description' minOccurs='0' />
<element ref='dmp:callTag' minOccurs='0' />
<element ref='dmp:userPattern' minOccurs='0' maxOccurs='unbounded'/>
+ <element ref='dmp:callerMatch' minOccurs='0' maxOccurs='unbounded'/>
<element ref='dmp:permissionMatch' minOccurs='0'
maxOccurs='unbounded'/>
</sequence>
</complexType>
@@ -131,6 +132,30 @@
</annotation>
</element>
+ <element name='callerMatch'>
+ <annotation>
+ <documentation>
+ Contains a set of match specifiers for the user part of a SIP address
+ and then other rules to be applied to any address that matches at least
+ one of the specified callerPattern specifiers.
+ </documentation>
+ </annotation>
+ <complexType>
+ <sequence>
+ <element ref='dmp:callerPattern' minOccurs='0' maxOccurs='unbounded'/>
+ </sequence>
+ </complexType>
+ </element>
+
+ <element name='callerPattern' type='normalizedString'>
+ <annotation>
+ <documentation>
+ A pattern expression used to match the user part of a SIP URL.
+ The pattern is implicitly anchored at both ends.
+ </documentation>
+ </annotation>
+ </element>
+
<element name='permissionMatch'>
<annotation>
<documentation>
diff --git a/sipXcommserverLib/src/digitmaps/MappingRulesUrlMapping.cpp
b/sipXcommserverLib/src/digitmaps/MappingRulesUrlMapping.cpp
index d444fb3..99116d6 100644
--- a/sipXcommserverLib/src/digitmaps/MappingRulesUrlMapping.cpp
+++ b/sipXcommserverLib/src/digitmaps/MappingRulesUrlMapping.cpp
@@ -58,7 +58,8 @@ MappingRulesUrlMapping::loadMappings(const UtlString&
configFileName,
/* ============================ ACCESSORS ================================= */
OsStatus
-MappingRulesUrlMapping::getContactList(const Url& requestUri,
+MappingRulesUrlMapping::getContactList(const Url& requestUri,
+ UtlString& sourceUri,
ResultSet& rContacts,
ResultSet& rPermissions,
UtlString& callTag
@@ -66,13 +67,16 @@ MappingRulesUrlMapping::getContactList(const Url&
requestUri,
{
OsStatus contactsSet = OS_FAILED;
UtlString variableDigits;
+ Url source(sourceUri);
const TiXmlNode* pMatchingUserMatchContainerNode = 0;
const TiXmlNode* pMatchingHostMatchContainerNode = 0;
if( getUserMatchContainerMatchingRequestURI(requestUri,
variableDigits,
pMatchingUserMatchContainerNode,
- pMatchingHostMatchContainerNode
) == OS_SUCCESS )
+ pMatchingHostMatchContainerNode,
+ NULL,
+ &source ) == OS_SUCCESS )
{
contactsSet = parsePermMatchContainer( requestUri,
variableDigits,
@@ -150,7 +154,7 @@ MappingRulesUrlMapping::parsePermMatchContainer(const Url&
requestUri,
}
//if no permission node - then it means no permission required -
allow all
- if((!bPermNodePresent || bPermissionFound ) )
+ if((!bPermNodePresent || bPermissionFound ))
{
//if the premission matches in the permissions database
//go ahead and get the transform tag
@@ -164,4 +168,3 @@ MappingRulesUrlMapping::parsePermMatchContainer(const Url&
requestUri,
}
return doTransformStatus;
}
-
diff --git a/sipXcommserverLib/src/digitmaps/UrlMapping.cpp
b/sipXcommserverLib/src/digitmaps/UrlMapping.cpp
index 14daf0d..af1f3c6 100644
--- a/sipXcommserverLib/src/digitmaps/UrlMapping.cpp
+++ b/sipXcommserverLib/src/digitmaps/UrlMapping.cpp
@@ -370,7 +370,8 @@ UrlMapping::getUserMatchContainerMatchingRequestURI(const
Url& requestUri,
UtlString& variableDigits,
const TiXmlNode*&
prMatchingUserMatchContainerNode,
const TiXmlNode*&
prMatchingHostMatchContainerNode,
- const char* ruleType
+ const char* ruleType,
+ const Url* sourceUri
) const
{
prMatchingUserMatchContainerNode = 0;
@@ -512,7 +513,8 @@ UrlMapping::getUserMatchContainerMatchingRequestURI(const
Url& requestUri,
userMatchFound = getUserMatchContainer(requestUri,
pHostMatchNode,
variableDigits,
-
prMatchingUserMatchContainerNode);
+
prMatchingUserMatchContainerNode,
+ sourceUri);
}
}
}
@@ -528,7 +530,8 @@ OsStatus
UrlMapping::getUserMatchContainer(const Url& requestUri,
const TiXmlNode* const pHostMatchNode,
UtlString& variableDigits,
- const TiXmlNode*&
prMatchingUserMatchContainerNode ) const
+ const TiXmlNode*&
prMatchingUserMatchContainerNode,
+ const Url* sourceUri) const
{
UtlString testUser;
requestUri.getUserId(testUser);
@@ -568,7 +571,8 @@ UrlMapping::getUserMatchContainer(const Url&
requestUri,
UtlString regStr;
convertRegularExpression(userRE, regStr);
RegEx userExpression(regStr.data());
- if (userExpression.Search(testUser.data(),
testUser.length()))
+ if (userExpression.Search(testUser.data(),
testUser.length())
+ && isCallerCovered(sourceUri, pUserMatchNode) ==
OS_SUCCESS)
{
getVDigits(userExpression, variableDigits);
prMatchingUserMatchContainerNode = pUserMatchNode;
@@ -1069,3 +1073,73 @@ bool UrlMapping::getNamedAttribute(const TiXmlElement*
component,
return foundNameValue;
}
+
+
+OsStatus
+UrlMapping::isCallerCovered(const Url* sourceUri,
+ const TiXmlNode* const pUserMatchNode) const
+{
+ OsStatus isCovered = OS_FAILED;
+ bool usesCallerMapping = false;
+
+ UtlString callerName;
+ if (sourceUri != NULL) {
+ sourceUri->getUserId(callerName);
+ }
+ else {
+ return OS_SUCCESS;
+ }
+ const TiXmlElement* const pUserMatchElement = pUserMatchNode->ToElement();
+
+ const TiXmlNode* pCallerMatchNode = NULL;
+ while ( (pCallerMatchNode = pUserMatchElement->IterateChildren(
pCallerMatchNode ))
+ && (isCovered != OS_SUCCESS) )
+ {
+ if(pCallerMatchNode && pCallerMatchNode->Type() == TiXmlNode::ELEMENT)
+ {
+ UtlString tagValue = pCallerMatchNode->Value();
+ if(tagValue.compareTo(XML_TAG_CALLERMATCH) == 0 )
+ {
+ //found callerPattern tag
+ usesCallerMapping = true;
+ const TiXmlElement* pCallerMatchElement =
pCallerMatchNode->ToElement();
+ const TiXmlNode* pCallerPatternNode = NULL;
+ //get the caller text value from it
+ for( pCallerPatternNode = pCallerMatchElement->FirstChild(
XML_TAG_CALLERPATTERN );
+ pCallerPatternNode && (isCovered != OS_SUCCESS);
+ pCallerPatternNode = pCallerPatternNode->NextSibling(
XML_TAG_CALLERPATTERN ) )
+ {
+ if(pCallerPatternNode && pCallerPatternNode->Type() ==
TiXmlNode::ELEMENT)
+ {
+ const TiXmlElement* pCallerPatternElement =
pCallerPatternNode->ToElement();
+
+ const TiXmlNode* pCallerPatternText =
pCallerPatternElement->FirstChild();
+ if(pCallerPatternText && pCallerPatternText->Type() ==
TiXmlNode::TEXT)
+ {
+ const TiXmlText* pXmlCaller =
pCallerPatternText->ToText();
+ if (pXmlCaller)
+ {
+ UtlString callerRE = pXmlCaller->Value();
+ UtlString regStr;
+ convertRegularExpression(callerRE, regStr);
+ RegEx callerExpression(regStr.data());
+ if (callerExpression.Search(callerName.data(),
callerName.length()))
+ {
+ //getVDigits(userExpression, variableDigits);
+ //prMatchingUserMatchContainerNode =
pUserMatchNode;
+ isCovered = OS_SUCCESS;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ if (usesCallerMapping) {
+ return isCovered;
+ }
+ else {
+ return OS_SUCCESS;
+ }
+}
diff --git a/sipXregistry/lib/redirect_plugins/SipRedirectorMapping.cpp
b/sipXregistry/lib/redirect_plugins/SipRedirectorMapping.cpp
index b4941eb..fee3911 100644
--- a/sipXregistry/lib/redirect_plugins/SipRedirectorMapping.cpp
+++ b/sipXregistry/lib/redirect_plugins/SipRedirectorMapping.cpp
@@ -94,6 +94,8 @@ SipRedirectorMapping::lookUp(
{
UtlString callTag = "UNK";
UtlString permissionName;
+ UtlString sourceUri;
+ message.getFromUri(&sourceUri);
ResultSet urlMappingRegistrations;
ResultSet urlMappingPermissions;
@@ -107,6 +109,7 @@ SipRedirectorMapping::lookUp(
{
mMap.getContactList(
requestUri,
+ sourceUri,
urlMappingRegistrations,
urlMappingPermissions,
callTag);
--
1.5.5.6
_______________________________________________
sipx-dev mailing list
[email protected]
List Archive: http://list.sipfoundry.org/archive/sipx-dev/