Hi all,

The attached patches add an auth plugin for SipXproxy that adds Alert-Info headers to INVITE messages depending on whether they're internal (i.e. from the local domain) or external. It is configurable via SipXconfig and defaults to tagging only external INVITES, the default header value has been tested with Polycom and Snom phones, the necessary changes to the templates of the former are included.
>From 84e8815f852d96d73c58e8d76fc90c759bd39327 Mon Sep 17 00:00:00 2001
From: David Becker <[email protected]>
Date: Thu, 17 Feb 2011 10:27:10 +0100
Subject: [PATCH] * Added unit tests for CallerAlertInfo
 * Added handling for existing headers

---
 .../neoconf/etc/sipxproxy/sipXproxy-config.vm      |    1 +
 .../neoconf/etc/sipxproxy/sipxproxy.properties     |    5 +
 sipXconfig/neoconf/etc/sipxproxy/sipxproxy.xml     |   12 +
 .../neoconf/etc/sipxproxy/sipxproxy_de.properties  |    5 +
 .../sipxconfig/service/service.beans.xml           |    1 +
 sipXproxy/lib/authplugins/CallerAlertInfo.cpp      |   49 +++--
 sipXproxy/lib/authplugins/CallerAlertInfo.h        |    1 +
 .../lib/authplugins/test/CallerAlertInfoTest.cpp   |  255 ++++++++++++++++++++
 sipXproxy/lib/authplugins/test/Makefile.am         |   14 +
 10 files changed, 329 insertions(+), 17 deletions(-)
 create mode 100644 sipXproxy/lib/authplugins/test/CallerAlertInfoTest.cpp

diff --git a/sipXconfig/neoconf/etc/sipxproxy/sipXproxy-config.vm 
b/sipXconfig/neoconf/etc/sipxproxy/sipXproxy-config.vm
index 211a728..23d65bc 100644
--- a/sipXconfig/neoconf/etc/sipxproxy/sipXproxy-config.vm
+++ b/sipXconfig/neoconf/etc/sipxproxy/sipXproxy-config.vm
@@ -35,6 +35,7 @@ SIPX_PROXY.350_calleralertinfo.EXTERNAL: 
$!{settings.getSetting('alert-info/EXTE
 SIPX_PROXY.350_calleralertinfo.EXTERNAL_ENABLED: 
$!{settings.getSetting('alert-info/EXTERNAL_ENABLED').Value}
 SIPX_PROXY.350_calleralertinfo.INTERNAL: 
$!{settings.getSetting('alert-info/INTERNAL').Value}
 SIPX_PROXY.350_calleralertinfo.INTERNAL_ENABLED: 
$!{settings.getSetting('alert-info/INTERNAL_ENABLED').Value}
+SIPX_PROXY.350_calleralertinfo.ON_EXISTING: 
$!{settings.getSetting('alert-info/ON_EXISTING').Value}
 
 SIPX_PROXY_HOOK_LIBRARY.400_authrules : 
@sipxpbx.lib.dir@/authplugins/libEnforceAuthRules.so
 SIPX_PROXY.400_authrules.RULES        : @sipxpbx.conf.dir@/authrules.xml
diff --git a/sipXconfig/neoconf/etc/sipxproxy/sipxproxy.properties 
b/sipXconfig/neoconf/etc/sipxproxy/sipxproxy.properties
index c20eb48..370f111 100644
--- a/sipXconfig/neoconf/etc/sipxproxy/sipxproxy.properties
+++ b/sipXconfig/neoconf/etc/sipxproxy/sipxproxy.properties
@@ -36,3 +36,8 @@ proxy-configuration.alert-info.INTERNAL_ENABLED.label=Enable 
for internal calls
 proxy-configuration.alert-info.INTERNAL.label=Internal call field value
 proxy-configuration.alert-info.INTERNAL.description=The default value was 
chosen to satisfy the requirements of Snom \
   and Polycom phones and RFC 3261.
+
+proxy-configuration.alert-info.ON_EXISTING.label=When the field already exists:
+proxy-configuration.alert-info.ON_EXISTING.description=Phones can be 
configured to send their own Alert-Info field or other redundant proxies could 
already have inserted the field.
+type.replaceOrKeep.0=Leave it as it is
+type.replaceOrKeep.1=Replace it
diff --git a/sipXconfig/neoconf/etc/sipxproxy/sipxproxy.xml 
b/sipXconfig/neoconf/etc/sipxproxy/sipxproxy.xml
index 38af610..41c60dc 100644
--- a/sipXconfig/neoconf/etc/sipxproxy/sipxproxy.xml
+++ b/sipXconfig/neoconf/etc/sipxproxy/sipxproxy.xml
@@ -30,6 +30,13 @@
       </option>
     </enum>
   </type>
+  <!-- Enum seems more user friendly than boolean -->
+  <type id="replaceOrKeep">
+    <enum>
+      <option><value>0</value></option> <!-- Leave alone -->
+      <option><value>1</value></option> <!-- Replace -->
+    </enum>
+  </type>
   <group name="proxy-configuration">
     <setting name="SIPX_PROXY_DEFAULT_SERIAL_EXPIRES">
       <type>
@@ -86,6 +93,7 @@
       <value>false</value>
     </setting>
     <group name="alert-info">
+      <label>Alert Info</label>
       <setting name="INTERNAL_ENABLED">
         <type><boolean /></type>
         <value>0</value>
@@ -104,6 +112,10 @@
         <type><string /></type>
         
<value>&lt;http://external.call&gt;;info=alert-external;x-line-id=0</value>
       </setting>
+      <setting name="ON_EXISTING" advanced="yes">
+        <type refid="replaceOrKeep" />
+        <value>0</value>
+      </setting>
     </group>
   </group>
 </model>
diff --git a/sipXconfig/neoconf/etc/sipxproxy/sipxproxy_de.properties 
b/sipXconfig/neoconf/etc/sipxproxy/sipxproxy_de.properties
index 1c1de17..8282cb0 100644
--- a/sipXconfig/neoconf/etc/sipxproxy/sipxproxy_de.properties
+++ b/sipXconfig/neoconf/etc/sipxproxy/sipxproxy_de.properties
@@ -37,3 +37,8 @@ proxy-configuration.alert-info.INTERNAL_ENABLED.label=Interne 
Anrufe markieren
 proxy-configuration.alert-info.INTERNAL.label=Wert für interne Anrufe
 proxy-configuration.alert-info.INTERNAL.description=Der Standardwert ist 
f&uuml;r Polycom und Snom Telefone geeignet, \
   f&uuml;r andere Telefone muss der Wert evtl. dem Handbuch entnommen werden.
+
+proxy-configuration.alert-info.ON_EXISTING.label=Wenn das Feld bereits 
existiert:
+proxy-configuration.alert-info.ON_EXISTING.description=Telefone k&ouml;nnen 
eigene Alert-Info Felder einf&uuml;gen und redundante Proxies k&ouml;nnen 
bereits ein Feld eingef&uuml;gt haben.
+type.replaceOrKeep.0=Wert beibehalten
+type.replaceOrKeep.1=Wert ersetzen
diff --git 
a/sipXconfig/neoconf/src/org/sipfoundry/sipxconfig/service/service.beans.xml 
b/sipXconfig/neoconf/src/org/sipfoundry/sipxconfig/service/service.beans.xml
index c40b683..de3b3de 100644
--- a/sipXconfig/neoconf/src/org/sipfoundry/sipxconfig/service/service.beans.xml
+++ b/sipXconfig/neoconf/src/org/sipfoundry/sipxconfig/service/service.beans.xml
@@ -153,6 +153,7 @@
     <property name="sipxProcessContext" ref="sipxProcessContext" />
     <property name="sipxReplicationContext" ref="sipxReplicationContext"/>
     <property name="sbcSipXbridgeConfiguration" 
ref="sbcSipXbridgeConfiguration"/>
+    <property name="groupTitleEnabled" value="true" />
   </bean>
 
   <bean id="sipxProxyConfiguration" 
class="org.sipfoundry.sipxconfig.service.SipxProxyConfiguration" 
scope="prototype"
diff --git a/sipXproxy/lib/authplugins/CallerAlertInfo.cpp 
b/sipXproxy/lib/authplugins/CallerAlertInfo.cpp
index 8f86507..62905a4 100644
--- a/sipXproxy/lib/authplugins/CallerAlertInfo.cpp
+++ b/sipXproxy/lib/authplugins/CallerAlertInfo.cpp
@@ -21,7 +21,10 @@
 #include "CallerAlertInfo.h"
 
 // DEFINES
+#define FIELD_NAME "Alert-Info"
 // CONSTANTS
+const UtlString ONEXIST_DO_NOTHING = UtlString("0");
+const UtlString ONEXIST_REPLACE = UtlString("1");
 // TYPEDEFS
 OsMutex        CallerAlertInfo::sSingletonLock(OsMutex::Q_FIFO);
 CallerAlertInfo*   CallerAlertInfo::spInstance;
@@ -85,6 +88,13 @@ CallerAlertInfo::readConfig( OsConfigDb& configDb /**< a 
subhash of the individu
    configDb.get("EXTERNAL", mExternalText);
    mInternalEnabled = configDb.getBoolean("INTERNAL_ENABLED",false);
    configDb.get("INTERNAL", mInternalText);
+   UtlString _onExisting;
+   configDb.get("ON_EXISTING", _onExisting);
+   if (_onExisting.compareTo(ONEXIST_REPLACE) == 0) {
+      mReplaceExisting = true;
+   } else {
+      mReplaceExisting = false;
+   }
 }
 
 AuthPlugin::AuthResult
@@ -113,23 +123,28 @@ CallerAlertInfo::authorizeAndModify(const UtlString& id,  
  /**< The authenticat
        && (method.compareTo(SIP_INVITE_METHOD) == 0) //We only operate on 
INVITEs
        )   
    {
-      // Check if the SIP message comes from the local domain
-      Url _fromAddress;
-      request.getFromUrl(_fromAddress);
-      if (!mpSipRouter->isLocalDomain(_fromAddress)) {
-         //if not then add Alert-Info External
-         OsReadLock readLock(mConfigLock);
-         OsSysLog::add(FAC_SIP, PRI_DEBUG, 
"CallerAlertInfo[%s]::authorizeAndModify() found external call",
-                       mInstanceName.data()
-                       );
-         if (mExternalEnabled) {              
-            request.addHeaderField("Alert-Info", mExternalText);
-         }
-      } else {
-         //otherwise add Alert-Info Internal
-         OsReadLock readLock(mConfigLock);
-         if (mInternalEnabled) {              
-            request.addHeaderField("Alert-Info", mInternalText);
+      
+      OsReadLock readLock(mConfigLock);
+      //Only checking if the header exists already
+      const char* _existingHeader = request.getHeaderValue(0, FIELD_NAME);
+      //If it exists we will only act if we are instructed to replace it.
+      if (_existingHeader == NULL || mReplaceExisting) {
+         // Check if the SIP message comes from the local domain
+         Url _fromAddress;
+         request.getFromUrl(_fromAddress);
+         if (!mpSipRouter->isLocalDomain(_fromAddress)) {
+            //if not then add Alert-Info External
+            OsSysLog::add(FAC_SIP, PRI_DEBUG, 
"CallerAlertInfo[%s]::authorizeAndModify() found external call",
+                          mInstanceName.data()
+                          );
+            if (mExternalEnabled) {              
+               request.setHeaderValue(FIELD_NAME, mExternalText);
+            }
+         } else {
+            //otherwise add Alert-Info Internal
+            if (mInternalEnabled) {              
+               request.setHeaderValue(FIELD_NAME, mInternalText);
+            }
          }
       }
    }
diff --git a/sipXproxy/lib/authplugins/CallerAlertInfo.h 
b/sipXproxy/lib/authplugins/CallerAlertInfo.h
index 8387091..2112f0b 100644
--- a/sipXproxy/lib/authplugins/CallerAlertInfo.h
+++ b/sipXproxy/lib/authplugins/CallerAlertInfo.h
@@ -93,6 +93,7 @@ class CallerAlertInfo : public AuthPlugin
    bool       mExternalEnabled; ///< Whether Alert-Info should be appended to 
external calls
    UtlString  mInternalText;    ///< Alert-Info value for internal calls
    bool       mInternalEnabled; ///< Whether Alert-Info should be appended to 
internal calls
+   bool       mReplaceExisting; ///< If the SIP request already contains an 
Alert-Info, should we replace it?
 
    SipRouter* mpSipRouter;
 };
diff --git a/sipXproxy/lib/authplugins/test/CallerAlertInfoTest.cpp 
b/sipXproxy/lib/authplugins/test/CallerAlertInfoTest.cpp
new file mode 100644
index 0000000..62c6591
--- /dev/null
+++ b/sipXproxy/lib/authplugins/test/CallerAlertInfoTest.cpp
@@ -0,0 +1,255 @@
+//
+// Copyright (C) 2007 Pingtel Corp., certain elements licensed under a 
Contributor Agreement.
+// Contributors retain copyright to elements licensed under a Contributor 
Agreement.
+// Licensed to the User under the LGPL license.
+//
+// $$
+////////////////////////////////////////////////////////////////////////
+
+#include "cppunit/extensions/HelperMacros.h"
+#include "cppunit/TestCase.h"
+#include "sipxunit/TestUtilities.h"
+#include "testlib/FileTestContext.h"
+#include "testlib/SipDbTestContext.h"
+
+#include "os/OsDefs.h"
+#include "os/OsSysLog.h"
+#include "utl/PluginHooks.h"
+#include "net/SipMessage.h"
+#include "net/SipUserAgent.h"
+
+#include "ForwardRules.h"
+#include "SipRouter.h"
+#include "AuthPlugin.h"
+#include "CallerAlertInfo.h"
+
+#define EXTERNAL_TEXT "<http://external-test-text.example.edu>"
+#define INTERNAL_TEXT "<http://internal-test-text.example.edu>"
+
+class CallerAlertInfoTest : public CppUnit::TestCase
+{
+   CPPUNIT_TEST_SUITE(CallerAlertInfoTest);
+
+   CPPUNIT_TEST(testConstructor); // ! MUST BE FIRST
+
+   CPPUNIT_TEST(testInternal);
+   CPPUNIT_TEST(testExternal);
+   CPPUNIT_TEST(testExisting);
+
+   CPPUNIT_TEST_SUITE_END();
+
+public:
+
+   static CallerAlertInfo*  pluginTestee;
+   static SipUserAgent      testUserAgent;
+   static SipRouter*        testSipRouter;
+
+   void setUp()
+      {
+      }
+
+   void tearDown()
+      {
+      }
+
+   void testConstructor()
+      {
+         /*
+          * This test exists to initialize the singleton plugin.
+          * Doing it as a static ran into ordering problems.
+          */
+         CPPUNIT_ASSERT((pluginTestee = 
dynamic_cast<CallerAlertInfo*>(getAuthPlugin("testee"))));
+
+         testUserAgent.setDnsSrvTimeout(1 /* seconds */);
+         testUserAgent.setMaxSrvRecords(4);
+         testUserAgent.setUserAgentHeaderProperty("sipXecs/sipXproxy");
+
+         testUserAgent.setForking(FALSE);  // Disable forking
+
+         OsConfigDb configDb;
+         configDb.set("SIPX_PROXY_AUTHENTICATE_ALGORITHM", "");
+         configDb.set("SIPX_PROXY_HOSTPORT", "example.edu");
+
+         configDb.set("EXTERNAL", EXTERNAL_TEXT);
+         configDb.set("EXTERNAL_ENABLED", "1");
+         configDb.set("INTERNAL", INTERNAL_TEXT);
+         configDb.set("INTERNAL_ENABLED", "1");
+         configDb.set("ON_EXISTING", "0");
+
+         testSipRouter = new SipRouter(testUserAgent, mForwardingRules, 
configDb);
+         pluginTestee->announceAssociatedSipRouter( testSipRouter );
+         pluginTestee->readConfig(configDb);
+      }
+
+   ///Test an internal call
+   void testInternal()
+      {
+         UtlString identity; // no authenticated identity
+         Url requestUri("sip:[email protected]");
+
+         const char* message =
+            "INVITE sip:[email protected] SIP/2.0\r\n"
+            "Via: SIP/2.0/TCP 10.1.1.3:33855\r\n"
+            "To: sip:[email protected]\r\n"
+            "From: Caller <sip:[email protected]>; 
tag=30543f3483e1cb11ecb40866edd3295b\r\n"
+            "Call-Id: f88dfabce84b6a2787ef024a7dbe8749\r\n"
+            "Cseq: 2 INVITE\r\n"
+            "Max-Forwards: 20\r\n"
+            "Contact: [email protected]\r\n"
+            "Content-Length: 0\r\n"
+            "\r\n";
+         SipMessage testMsg(message, strlen(message));
+
+         UtlSList noRemovedRoutes;
+         UtlString routeName("example.com");
+         RouteState routeState( testMsg, noRemovedRoutes, routeName );
+
+         const char unmodifiedRejectReason[] = "unmodified";
+         UtlString rejectReason(unmodifiedRejectReason);
+
+         UtlString method("INVITE");
+         AuthPlugin::AuthResult priorResult = AuthPlugin::CONTINUE;
+         bool bSpiralingRequest = false;
+
+         CPPUNIT_ASSERT(AuthPlugin::CONTINUE
+                        == pluginTestee->authorizeAndModify(identity,
+                                                            requestUri,
+                                                            routeState,
+                                                            method,
+                                                            priorResult,
+                                                            testMsg,
+                                                            bSpiralingRequest,
+                                                            rejectReason
+                                                            ));
+         ASSERT_STR_EQUAL(unmodifiedRejectReason, rejectReason.data());
+
+         const char* alertInfoValue = testMsg.getHeaderValue(0, "Alert-Info");
+         CPPUNIT_ASSERT(alertInfoValue != NULL);
+         ASSERT_STR_EQUAL(INTERNAL_TEXT, alertInfoValue);
+      }
+
+   ///Test an external call
+   void testExternal()
+      {
+         UtlString identity; // no authenticated identity
+         Url requestUri("sip:[email protected]");
+
+         const char* message =
+            "INVITE sip:[email protected] SIP/2.0\r\n"
+            "Via: SIP/2.0/TCP 10.1.1.3:33855\r\n"
+            "To: sip:[email protected]\r\n"
+            "From: Caller <sip:[email protected]>; 
tag=30543f3483e1cb11ecb40866edd3295b\r\n"
+            "Call-Id: f88dfabce84b6a2787ef024a7dbe8749\r\n"
+            "Cseq: 2 INVITE\r\n"
+            "Max-Forwards: 20\r\n"
+            "Contact: [email protected]\r\n"
+            "Content-Length: 0\r\n"
+            "\r\n";
+         SipMessage testMsg(message, strlen(message));
+
+         UtlSList noRemovedRoutes;
+         UtlString routeName("example.com");
+         RouteState routeState( testMsg, noRemovedRoutes, routeName );
+
+         const char unmodifiedRejectReason[] = "unmodified";
+         UtlString rejectReason(unmodifiedRejectReason);
+
+         UtlString method("INVITE");
+         AuthPlugin::AuthResult priorResult = AuthPlugin::CONTINUE;
+         bool bSpiralingRequest = false;
+
+         CPPUNIT_ASSERT(AuthPlugin::CONTINUE
+                        == pluginTestee->authorizeAndModify(identity,
+                                                            requestUri,
+                                                            routeState,
+                                                            method,
+                                                            priorResult,
+                                                            testMsg,
+                                                            bSpiralingRequest,
+                                                            rejectReason
+                                                            ));
+         ASSERT_STR_EQUAL(unmodifiedRejectReason, rejectReason.data());
+
+         const char* alertInfoValue = testMsg.getHeaderValue(0, "Alert-Info");
+         CPPUNIT_ASSERT(alertInfoValue != NULL);
+         ASSERT_STR_EQUAL(EXTERNAL_TEXT, alertInfoValue);
+      }
+
+   /// Make sure existing fields aren't overwritten
+   void testExisting()
+      {
+         UtlString identity; // no authenticated identity
+         Url requestUri("sip:[email protected]");
+
+         const char* message =
+            "INVITE sip:[email protected] SIP/2.0\r\n"
+            "Via: SIP/2.0/TCP 10.1.1.3:33855\r\n"
+            "To: sip:[email protected]\r\n"
+            "From: Caller <sip:[email protected]>; 
tag=30543f3483e1cb11ecb40866edd3295b\r\n"
+            "Call-Id: f88dfabce84b6a2787ef024a7dbe8749\r\n"
+            "Cseq: 2 INVITE\r\n"
+            "Max-Forwards: 20\r\n"
+            "Alert-Info: <http://www.example.com/sounds/moo.wav>\r\n"
+            "Contact: [email protected]\r\n"
+            "Content-Length: 0\r\n"
+            "\r\n";
+         SipMessage testMsg(message, strlen(message));
+
+         UtlSList noRemovedRoutes;
+         UtlString routeName("example.com");
+         RouteState routeState( testMsg, noRemovedRoutes, routeName );
+
+         const char unmodifiedRejectReason[] = "unmodified";
+         UtlString rejectReason(unmodifiedRejectReason);
+
+         UtlString method("INVITE");
+         AuthPlugin::AuthResult priorResult = AuthPlugin::CONTINUE;
+         bool bSpiralingRequest = false;
+
+         CPPUNIT_ASSERT(AuthPlugin::CONTINUE
+                        == pluginTestee->authorizeAndModify(identity,
+                                                            requestUri,
+                                                            routeState,
+                                                            method,
+                                                            priorResult,
+                                                            testMsg,
+                                                            bSpiralingRequest,
+                                                            rejectReason
+                                                            ));
+         ASSERT_STR_EQUAL(unmodifiedRejectReason, rejectReason.data());
+
+         const char* alertInfoValue = testMsg.getHeaderValue(0, "Alert-Info");
+         CPPUNIT_ASSERT(alertInfoValue != NULL);
+         ASSERT_STR_EQUAL("<http://www.example.com/sounds/moo.wav>", 
alertInfoValue);
+      }
+
+
+private:
+   ForwardRules  mForwardingRules;
+
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION(CallerAlertInfoTest);
+
+CallerAlertInfo*     CallerAlertInfoTest::pluginTestee;
+SipUserAgent     CallerAlertInfoTest::testUserAgent(
+   PORT_NONE,
+   PORT_NONE,
+   PORT_NONE,
+   NULL, // public IP address (not used in proxy)
+   NULL, // default user (not used in proxy)
+   NULL, // default SIP address (not used in proxy)
+   NULL, // outbound proxy
+   NULL, // directory server
+   NULL, // registry server
+   NULL, // auth realm
+   NULL, // auth DB
+   NULL, // auth user IDs
+   NULL, // auth passwords
+   NULL, // line mgr
+   SIP_DEFAULT_RTT, // first resend timeout
+   FALSE, // default to proxy transaction
+   SIPUA_DEFAULT_SERVER_UDP_BUFFER_SIZE, // socket layer read buffer size
+   SIPUA_DEFAULT_SERVER_OSMSG_QUEUE_SIZE // OsServerTask message queue size
+                                                );
+SipRouter* CallerAlertInfoTest::testSipRouter;
diff --git a/sipXproxy/lib/authplugins/test/Makefile.am 
b/sipXproxy/lib/authplugins/test/Makefile.am
index 9b4eefc..96b712c 100644
--- a/sipXproxy/lib/authplugins/test/Makefile.am
+++ b/sipXproxy/lib/authplugins/test/Makefile.am
@@ -2,6 +2,7 @@
 ## and of course require no setup
 TESTS = \
        calleraliastest \
+       calleralertinfotest \
        calldestinationtest \
        enforcerulestest \
        emergencyrulestest \
@@ -15,6 +16,7 @@ TESTS = \
 
 check_PROGRAMS = \
        calleraliastest \
+       calleralertinfotest \
        calldestinationtest \
        enforcerulestest \
        emergencyrulestest \
@@ -80,6 +82,18 @@ calleraliastest_SOURCES = \
 calleraliastest_LDADD = \
        $(COMMON_LIBS)
 
+
+calleralertinfotest_CXXFLAGS = \
+       $(COMMON_CXX_FLAGS)
+
+calleralertinfotest_SOURCES = \
+       $(top_srcdir)/lib/authplugins/CallerAlertInfo.cpp \
+       CallerAlertInfoTest.cpp
+
+calleralertinfotest_LDADD = \
+       $(COMMON_LIBS)
+
+
 calldestinationtest_CXXFLAGS = \
        $(COMMON_CXX_FLAGS)
 
-- 
1.5.5.6

>From 47286eaadc4addc3b8fb8f0714fe959bfba78af6 Mon Sep 17 00:00:00 2001
From: David Becker <[email protected]>
Date: Mon, 24 Jan 2011 11:44:06 +0100
Subject: [PATCH] * Added Authplugin that adds Alert-Info to calls, can be 
configured for external calls, internal calls or both.
 * Added SipXconfig settings for the plugin to the Proxy settings.
 * Added Alert-Info related settings to Snom and Polycom templates.

---
 .../neoconf/etc/sipxproxy/sipXproxy-config.vm      |    6 +
 .../neoconf/etc/sipxproxy/sipxproxy.properties     |   17 ++
 sipXconfig/neoconf/etc/sipxproxy/sipxproxy.xml     |   22 ++-
 .../neoconf/etc/sipxproxy/sipxproxy_de.properties  |   26 ++-
 .../plugins/polycom/etc/polycom/phone.properties   |   35 +++-
 sipXconfig/plugins/polycom/etc/polycom/phone.xml   |   68 +++++-
 sipXproxy/lib/authplugins/CallerAlertInfo.cpp      |  153 +++++++++++
 sipXproxy/lib/authplugins/CallerAlertInfo.h        |  100 +++++++
 sipXproxy/lib/authplugins/Makefile.am              |   16 ++
 11 files changed, 690 insertions(+), 46 deletions(-)
 create mode 100644 sipXproxy/lib/authplugins/CallerAlertInfo.cpp
 create mode 100644 sipXproxy/lib/authplugins/CallerAlertInfo.h

diff --git a/sipXconfig/neoconf/etc/sipxproxy/sipXproxy-config.vm 
b/sipXconfig/neoconf/etc/sipxproxy/sipXproxy-config.vm
index 618a177..211a728 100644
--- a/sipXconfig/neoconf/etc/sipxproxy/sipXproxy-config.vm
+++ b/sipXconfig/neoconf/etc/sipxproxy/sipXproxy-config.vm
@@ -30,6 +30,12 @@ SIPX_PROXY.210_msftxchghack.USERAGENT : ^RTCC/
 
 SIPX_PROXY_HOOK_LIBRARY.300_calldestination: 
@sipxpbx.lib.dir@/authplugins/libCallDestination.so
 
+SIPX_PROXY_HOOK_LIBRARY.350_calleralertinfo: 
@sipxpbx.lib.dir@/authplugins/libCallerAlertInfo.so
+SIPX_PROXY.350_calleralertinfo.EXTERNAL: 
$!{settings.getSetting('alert-info/EXTERNAL').Value}
+SIPX_PROXY.350_calleralertinfo.EXTERNAL_ENABLED: 
$!{settings.getSetting('alert-info/EXTERNAL_ENABLED').Value}
+SIPX_PROXY.350_calleralertinfo.INTERNAL: 
$!{settings.getSetting('alert-info/INTERNAL').Value}
+SIPX_PROXY.350_calleralertinfo.INTERNAL_ENABLED: 
$!{settings.getSetting('alert-info/INTERNAL_ENABLED').Value}
+
 SIPX_PROXY_HOOK_LIBRARY.400_authrules : 
@sipxpbx.lib.dir@/authplugins/libEnforceAuthRules.so
 SIPX_PROXY.400_authrules.RULES        : @sipxpbx.conf.dir@/authrules.xml
 SIPX_PROXY.400_authrules.IDENTITY_VALIDITY_SECONDS : 300
diff --git a/sipXconfig/neoconf/etc/sipxproxy/sipxproxy.properties 
b/sipXconfig/neoconf/etc/sipxproxy/sipxproxy.properties
index b26bfd5..c20eb48 100644
--- a/sipXconfig/neoconf/etc/sipxproxy/sipxproxy.properties
+++ b/sipXconfig/neoconf/etc/sipxproxy/sipxproxy.properties
@@ -19,3 +19,20 @@ 
proxy-configuration.SIPX_PROXY_DIALOG_SUBSCRIBE_AUTHENTICATION.description=Warni
 proxy-configuration.SIP_PORT.label=SIP Port
 proxy-configuration.TLS_SIP_PORT.label=TLS SIP Port
 proxy-configuration.ENABLE_BRIDGE_PROXY_RELAY.label=Enable bridge-proxy relay
+
+proxy-configuration.alert-info.label=Alert-Info
+proxy-configuration.alert-info.description=The Alert-Info header field can 
trigger alternate ringer sounds on many \
+  telephones, it is used to mark external phonecalls as such and trigger a 
different ringer sound if the phone \
+  is configured for it.
+
+proxy-configuration.alert-info.EXTERNAL_ENABLED.label=Enable for external calls
+
+proxy-configuration.alert-info.EXTERNAL.label=External call field value
+proxy-configuration.alert-info.EXTERNAL.description=The default value was 
chosen to satisfy the requirements of Snom \
+  and Polycom phones and RFC 3261.
+
+proxy-configuration.alert-info.INTERNAL_ENABLED.label=Enable for internal calls
+
+proxy-configuration.alert-info.INTERNAL.label=Internal call field value
+proxy-configuration.alert-info.INTERNAL.description=The default value was 
chosen to satisfy the requirements of Snom \
+  and Polycom phones and RFC 3261.
diff --git a/sipXconfig/neoconf/etc/sipxproxy/sipxproxy.xml 
b/sipXconfig/neoconf/etc/sipxproxy/sipxproxy.xml
index f43796b..38af610 100644
--- a/sipXconfig/neoconf/etc/sipxproxy/sipxproxy.xml
+++ b/sipXconfig/neoconf/etc/sipxproxy/sipxproxy.xml
@@ -85,5 +85,25 @@
       </type>
       <value>false</value>
     </setting>
+    <group name="alert-info">
+      <setting name="INTERNAL_ENABLED">
+        <type><boolean /></type>
+        <value>0</value>
+      </setting>
+      <setting name="INTERNAL" advanced="yes">
+        <type><string /></type>
+        <!--Polycom phones interpret only the part in angle brackets, Snom 
phones only the part following info=.
+            alert-internal is a default value for Snom-->
+        
<value>&lt;http://internal.call&gt;;info=alert-internal;x-line-id=0</value>
+      </setting>
+      <setting name="EXTERNAL_ENABLED">
+        <type><boolean /></type>
+        <value>1</value>
+      </setting>
+      <setting name="EXTERNAL" advanced="yes">
+        <type><string /></type>
+        
<value>&lt;http://external.call&gt;;info=alert-external;x-line-id=0</value>
+      </setting>
+    </group>
   </group>
-</model>
\ No newline at end of file
+</model>
diff --git a/sipXconfig/neoconf/etc/sipxproxy/sipxproxy_de.properties 
b/sipXconfig/neoconf/etc/sipxproxy/sipxproxy_de.properties
index f3c7770..1c1de17 100644
--- a/sipXconfig/neoconf/etc/sipxproxy/sipxproxy_de.properties
+++ b/sipXconfig/neoconf/etc/sipxproxy/sipxproxy_de.properties
@@ -1,3 +1,4 @@
+#Make sure to use entities for umlauts
 proxy-configuration.label=sipXproxy Parameters
 
 proxy-configuration.SIPX_PROXY_DEFAULT_SERIAL_EXPIRES.label=Standard Serial 
Fork Ablauf
@@ -11,11 +12,28 @@ 
proxy-configuration.SIPX_PROXY_DEFAULT_EXPIRES.description=Anzahl an Sekunden di
   wenn diese Zeit verstreicht wird die Anrufanfrage mit einem Fehler erwidert.
 
 
proxy-configuration.SIPX_PROXY_DIALOG_SUBSCRIBE_AUTHENTICATION.label=Authentifiziere
 Dialogereigniss-Abonnements
-proxy-configuration.SIPX_PROXY_DIALOG_SUBSCRIBE_AUTHENTICATION.description=Warnung:
 Wenn die Authentifizierung ausgeschaltet wird, \
-  werden externe Benutzer nicht mehr länger auf Berechtigung geprüft wenn 
sie Dialogereignisse abonnieren. Dialog- \
-  ereignisbenachrichtigungen beinhalten private Anruf-/Dialogdaten, die für 
bösartige Zwecke verwendet werden könnten. Das Ausschalten \
-  der Authentifizierung könnte den Datenschutz dieses Systems 
beeinträchtigen.
+proxy-configuration.SIPX_PROXY_DIALOG_SUBSCRIBE_AUTHENTICATION.description=Warnung:
 Wenn die Authentifizierung \
+  ausgeschaltet wird, werden externe Benutzer nicht mehr l&auml;nger auf 
Berechtigung gepr&uuml;ft wenn sie \
+  Dialogereignisse abonnieren. Dialog- ereignisbenachrichtigungen beinhalten 
private Anruf-/Dialogdaten, die f&uuml;r \
+  b&ouml;sartige Zwecke verwendet werden k&ouml;nnten. Das Ausschalten der 
Authentifizierung k&ouml;nnte den Datenschutz \
+  dieses Systems beeintr&auml;chtigen.
 
 proxy-configuration.SIP_PORT.label=SIP Port
 
 proxy-configuration.TLS_SIP_PORT.label=TLS SIP Port
+
+proxy-configuration.alert-info.label=Alert-Info
+proxy-configuration.alert-info.description=Der Proxy kann externe und interne 
Anrufe mit Anweisungen, einen bestimmten \
+  Klingelton zu spielen, ausstatten. Wie dieses Feld von Telefonen 
interpretiert wird ist Modellabh&auml;ngig.
+
+proxy-configuration.alert-info.EXTERNAL_ENABLED.label=Externe Anrufe markieren
+
+proxy-configuration.alert-info.EXTERNAL.label=Wert für externe Anrufe
+proxy-configuration.alert-info.EXTERNAL.description=Der Standardwert ist 
f&uuml;r Polycom und Snom Telefone geeignet, \
+  f&uuml;r andere Telefone muss der Wert evtl. dem Handbuch entnommen werden.
+
+proxy-configuration.alert-info.INTERNAL_ENABLED.label=Interne Anrufe markieren
+
+proxy-configuration.alert-info.INTERNAL.label=Wert für interne Anrufe
+proxy-configuration.alert-info.INTERNAL.description=Der Standardwert ist 
f&uuml;r Polycom und Snom Telefone geeignet, \
+  f&uuml;r andere Telefone muss der Wert evtl. dem Handbuch entnommen werden.
diff --git a/sipXconfig/plugins/polycom/etc/polycom/phone.properties 
b/sipXconfig/plugins/polycom/etc/polycom/phone.properties
index f8e8dcc..1f4e109 100644
--- a/sipXconfig/plugins/polycom/etc/polycom/phone.properties
+++ b/sipXconfig/plugins/polycom/etc/polycom/phone.properties
@@ -319,6 +319,24 @@ se.ringType.RING_ANSWER.callWait.description=Pattern used 
to notify about incomi
 se.ringType.RING_ANSWER.mod.label=Modification allowed
 se.ringType.RING_ANSWER.mod.description=
 
+
+se.ringType.RING_EXTERNAL.label=External call ringtone
+se.ringType.RING_EXTERNAL.description=Ringer settings for external calls
+
+se.ringType.RING_EXTERNAL.ringer.label=Ringer
+
+se.ringType.RING_EXTERNAL.callWait.label=Call waiting
+se.ringType.RING_EXTERNAL.callWait.description=Pattern used to notify about 
incoming call when another call is in progress
+
+se.ringType.RING_INTERNAL.label=Internal call ringtone
+se.ringType.RING_INTERNAL.description=Ringer settings for internal calls
+
+se.ringType.RING_INTERNAL.ringer.label=Ringer
+
+se.ringType.RING_INTERNAL.callWait.label=Call waiting
+se.ringType.RING_INTERNAL.callWait.description=Pattern used to notify about 
incoming call when another call is in progress
+
+
 #se.stutterOnVoiceMail.label=
 se.stutterOnVoiceMail.description=If checked, stuttered dial tone is used in 
place of normal dial tone to  \
  indicate that one or more messages (voice-mail) are waiting at the message  \
@@ -1434,9 +1452,9 @@ 
voIpProt.SIP.protocol.allowTransferOnProceeding.description=If checked, A transf
 
 voIpProt.SIP.alertInfo.label=Alert Information
 voIpProt.SIP.alertInfo.description=Match incoming call's alert information to 
a particular ring response. NOTE:  \
- Currently only 1 alert type is supported
+ Currently only 2 alert types are supported
 
-voIpProt.SIP.alertInfo.1.label=Alert Info Details
+voIpProt.SIP.alertInfo.1.label=Alert Info #1 Details
 voIpProt.SIP.alertInfo.1.description=
 
 #voIpProt.SIP.alertInfo.1.value.label=
@@ -1447,6 +1465,19 @@ voIpProt.SIP.alertInfo.1.value.description=Alert-Info 
fields from INVITE request
 #voIpProt.SIP.alertInfo.1.class.label=
 voIpProt.SIP.alertInfo.1.class.description="Ring class number" that identifies 
a configured ring type
 
+
+voIpProt.SIP.alertInfo.3.label=Alert Info #2 Details
+voIpProt.SIP.alertInfo.3.description=
+
+#voIpProt.SIP.alertInfo.3.value.label=
+voIpProt.SIP.alertInfo.3.value.description=Alert-Info fields from INVITE 
requests will be compared against with  \
+ this value and if a match is found, the behavior described in the 
corresponding  \
+ ring class will be applied.
+
+#voIpProt.SIP.alertInfo.3.class.label=
+voIpProt.SIP.alertInfo.3.class.description="Ring class number" that identifies 
a configured ring type
+
+
 voIpProt.SIP.requestValidation.label=Request Validation
 voIpProt.SIP.requestValidation.description=To guard against unauthorized 
callers or telephony events. NOTE: Currently  \
  only 1 event type is supported
diff --git a/sipXconfig/plugins/polycom/etc/polycom/phone.xml 
b/sipXconfig/plugins/polycom/etc/polycom/phone.xml
index 793af65..d28efc3 100644
--- a/sipXconfig/plugins/polycom/etc/polycom/phone.xml
+++ b/sipXconfig/plugins/polycom/etc/polycom/phone.xml
@@ -266,6 +266,42 @@
           <value>1</value>
         </setting>
       </group>
+      <!--Settings for the external ringtone-->
+      <group name="RING_EXTERNAL">
+        <profileName>8</profileName>
+        <setting name="ringer">
+          <type refid="ringer-pattern" />
+          <value>4</value>
+        </setting>
+        <setting name="callWait">
+          <type refid="call_progress_pattern" />
+          <value>6</value>
+        </setting>
+        <setting name="mod" hidden="yes">
+          <type>
+            <boolean />
+          </type>
+          <value>1</value>
+        </setting>
+      </group>
+      <!--Settings for the internal ringtone-->
+      <group name="RING_INTERNAL">
+        <profileName>9</profileName>
+        <setting name="ringer">
+          <type refid="ringer-pattern" />
+          <value>3</value>
+        </setting>
+        <setting name="callWait">
+          <type refid="call_progress_pattern" />
+          <value>6</value>
+        </setting>
+        <setting name="mod" hidden="yes">
+          <type>
+            <boolean />
+          </type>
+          <value>1</value>
+        </setting>
+      </group>
     </group>
   </group>
   <group name="voice">
@@ -2330,19 +2366,45 @@
       </setting>
     </group>
     <group name="alertInfo">
+      <!--If an INVITE contains at least one Alert-Info field and the value in 
none of them is equal to 
+          <the-values-here>.* the phone will not ring audibly.
+          RFC 3261 requires that only the first value for Alert-Info is in 
angle brackets and that it is a
+          URL. Any following parameters must be in the form of 
parameter-name=parameter-value which this
+          phone will not parse properly. -->
       <group name="1">
         <setting name="value">
           <type>
             <!-- string to compare against the value of Alert-Info headers in 
INVITE requests -->
-            <string />
+            <string/>
           </type>
-          <value />
+          <!-- This checks the URL included in the Alert-Info field, if it 
isn't a bogus URL 
+               other phones (e.g. Snom) will refuse to work and it will 
violate RFC 3261-->
+          <value>http://external.call</value>
         </setting>
         <setting name="class">
           <type>
             <integer min="1" />
           </type>
-          <value />
+          <!--Must be one greater than the corresponding ring-type number-->
+          <value>9</value>
+        </setting>
+      </group>
+      <group name="3">
+        <setting name="value">
+          <type>
+            <!-- string to compare against the value of Alert-Info headers in 
INVITE requests -->
+            <string/>
+          </type>
+          <!-- This checks the URL included in the Alert-Info field, if it 
isn't a bogus URL 
+               other phones (e.g. Snom) will refuse to work and it will 
violate RFC 3261-->
+          <value>http://internal.call</value>
+        </setting>
+        <setting name="class">
+          <type>
+            <integer min="1" />
+          </type>
+          <!--Must be one greater than the corresponding ring-type number-->
+          <value>10</value>
         </setting>
       </group>
       <!-- reserved for sipXpage - call with this value of alert-info will be 
used for paging -->
diff --git a/sipXproxy/lib/authplugins/CallerAlertInfo.cpp 
b/sipXproxy/lib/authplugins/CallerAlertInfo.cpp
new file mode 100644
index 0000000..8f86507
--- /dev/null
+++ b/sipXproxy/lib/authplugins/CallerAlertInfo.cpp
@@ -0,0 +1,153 @@
+// 
+// Copyright (C) 2011 Pingtel Corp., certain elements licensed under a 
Contributor Agreement.  
+// Contributors retain copyright to elements licensed under a Contributor 
Agreement.
+// Licensed to the User under the LGPL license.
+// 
+//////////////////////////////////////////////////////////////////////////////
+
+// SYSTEM INCLUDES
+#include "os/OsLock.h"
+#include "os/OsReadLock.h"
+#include "os/OsWriteLock.h"
+#include "os/OsConfigDb.h"
+#include "os/OsSysLog.h"
+#include "os/OsFS.h"
+#include "net/Url.h"
+
+// APPLICATION INCLUDES
+
+#include "RouteState.h"
+#include "SipRouter.h"
+#include "CallerAlertInfo.h"
+
+// DEFINES
+// CONSTANTS
+// TYPEDEFS
+OsMutex        CallerAlertInfo::sSingletonLock(OsMutex::Q_FIFO);
+CallerAlertInfo*   CallerAlertInfo::spInstance;
+
+/// Factory used by PluginHooks to dynamically link the plugin instance
+extern "C" AuthPlugin* getAuthPlugin(const UtlString& pluginName)
+{
+   OsLock singleton(CallerAlertInfo::sSingletonLock);
+
+   if (!CallerAlertInfo::spInstance)
+   {
+      CallerAlertInfo::spInstance = new CallerAlertInfo(pluginName);
+   }
+   else
+   {
+      OsSysLog::add(FAC_SIP, PRI_CRIT, "CallerAlertInfo[%s]: "
+                    "it is invalid to configure more than one instance of the 
CallerAlertInfo plugin.",
+                    pluginName.data());
+      assert(false);
+   }
+
+   return CallerAlertInfo::spInstance;
+}
+
+/// constructor
+CallerAlertInfo::CallerAlertInfo(const UtlString& pluginName ///< the name for 
this instance
+                         )
+   : AuthPlugin(pluginName),
+     mConfigLock(OsRWMutex::Q_FIFO),
+     mExternalText(""),
+     mExternalEnabled(false),
+     mInternalText(""),
+     mInternalEnabled(false),
+     mpSipRouter( 0 )
+{
+   OsSysLog::add(FAC_SIP, PRI_DEBUG, "CallerAlertInfo[%s] started",
+                 mInstanceName.data()
+                 );
+};
+
+/// Nothing configurable
+void
+CallerAlertInfo::readConfig( OsConfigDb& configDb /**< a subhash of the 
individual configuration
+                                               * parameters for this instance 
of this plugin. */
+                             )
+{
+   /*
+    * @note
+    * The parent service may call the readConfig method at any time to
+    * indicate that the configuration may have changed.  The plugin
+    * should reinitialize itself based on the configuration that exists when
+    * this is called.  The fact that it is a subhash means that whatever prefix
+    * is used to identify the plugin (see PluginHooks) has been removed (see 
the
+    * examples in PluginHooks::readConfig).
+    */
+   OsSysLog::add(FAC_SIP, PRI_DEBUG, "CallerAlertInfo[%s]::readConfig",
+                 mInstanceName.data()
+                 );
+   OsWriteLock writeLock(mConfigLock);
+   mExternalEnabled = configDb.getBoolean("EXTERNAL_ENABLED",false);
+   configDb.get("EXTERNAL", mExternalText);
+   mInternalEnabled = configDb.getBoolean("INTERNAL_ENABLED",false);
+   configDb.get("INTERNAL", mInternalText);
+}
+
+AuthPlugin::AuthResult
+CallerAlertInfo::authorizeAndModify(const UtlString& id,    /**< The 
authenticated identity of the
+                                                             *   request 
originator, if any (the null
+                                                             *   string if 
not).
+                                                             *   This is in 
the form of a SIP uri
+                                                             *   identity 
value as used in the
+                                                             *   credentials 
database (user@domain)
+                                                             *   without the 
scheme or any parameters.
+                                                             */
+                                const Url&  requestUri, ///< parsed target Uri
+                                RouteState& routeState, ///< the state for 
this request.  
+                                const UtlString& method,///< the request method
+                                AuthResult  priorResult,///< results from 
earlier plugins.
+                                SipMessage& request,    ///< see AuthPlugin 
regarding modifying
+                                bool bSpiralingRequest, ///< spiraling 
indication 
+                                UtlString&  reason      ///< rejection reason
+                                )
+{
+   OsSysLog::add(FAC_SIP, PRI_DEBUG, 
"CallerAlertInfo[%s]::authorizeAndModify() begin",
+                 mInstanceName.data()
+                 );
+
+   if (   (priorResult != DENY) // no point in modifying a request that won't 
be sent
+       && (method.compareTo(SIP_INVITE_METHOD) == 0) //We only operate on 
INVITEs
+       )   
+   {
+      // Check if the SIP message comes from the local domain
+      Url _fromAddress;
+      request.getFromUrl(_fromAddress);
+      if (!mpSipRouter->isLocalDomain(_fromAddress)) {
+         //if not then add Alert-Info External
+         OsReadLock readLock(mConfigLock);
+         OsSysLog::add(FAC_SIP, PRI_DEBUG, 
"CallerAlertInfo[%s]::authorizeAndModify() found external call",
+                       mInstanceName.data()
+                       );
+         if (mExternalEnabled) {              
+            request.addHeaderField("Alert-Info", mExternalText);
+         }
+      } else {
+         //otherwise add Alert-Info Internal
+         OsReadLock readLock(mConfigLock);
+         if (mInternalEnabled) {              
+            request.addHeaderField("Alert-Info", mInternalText);
+         }
+      }
+   }
+   OsSysLog::add(FAC_SIP, PRI_DEBUG, 
"CallerAlertInfo[%s]::authorizeAndModify() end",
+                 mInstanceName.data()
+                 );
+   return AuthPlugin::CONTINUE;
+}
+
+void CallerAlertInfo::announceAssociatedSipRouter( SipRouter* sipRouter )
+{
+   mpSipRouter = sipRouter;
+}
+
+/// destructor
+CallerAlertInfo::~CallerAlertInfo()
+{
+   OsSysLog::add(FAC_SIP, PRI_DEBUG, "CallerAlertInfo[%s] stopped",
+                 mInstanceName.data()
+                 );
+}
diff --git a/sipXproxy/lib/authplugins/CallerAlertInfo.h 
b/sipXproxy/lib/authplugins/CallerAlertInfo.h
new file mode 100644
index 0000000..8387091
--- /dev/null
+++ b/sipXproxy/lib/authplugins/CallerAlertInfo.h
@@ -0,0 +1,100 @@
+// 
+// Copyright (C) 2011 Pingtel Corp., certain elements licensed under a 
Contributor Agreement.  
+// Contributors retain copyright to elements licensed under a Contributor 
Agreement.
+// Licensed to the User under the LGPL license.
+// 
+//////////////////////////////////////////////////////////////////////////////
+#ifndef _CALLERALERTINFO_H_
+#define _CALLERALERTINFO_H_
+
+// SYSTEM INCLUDES
+#include "os/OsMutex.h"
+#include "os/OsRWMutex.h"
+
+// APPLICATION INCLUDES
+#include "AuthPlugin.h"
+
+// DEFINES
+// MACROS
+// EXTERNAL FUNCTIONS
+// EXTERNAL VARIABLES
+// CONSTANTS
+// STRUCTS
+// TYPEDEFS
+// FORWARD DECLARATIONS
+class CallerAlertInfo;
+
+extern "C" AuthPlugin* getAuthPlugin(const UtlString& name);
+
+/**
+ * Proxy AuthPlugin CallerAlertInfo
+ * This plug-in adds the Alert-Info header field to all INVITE messages 
passing through.
+ * If the message originates from the local domain the message is marked as 
internal,
+ * otherwise it is marked as external.
+ */
+
+class CallerAlertInfo : public AuthPlugin
+{
+  public:
+
+   virtual ~CallerAlertInfo();
+
+   /// Read (or re-read) the authorization rules.
+   virtual void readConfig( OsConfigDb& configDb /**< a subhash of the 
individual configuration
+                                                  * parameters for this 
instance of this plugin. */
+                           );
+   /**<
+    * @note
+    * The parent service may call the readConfig method at any time to
+    * indicate that the configuration may have changed.  The plugin
+    * should reinitialize itself based on the configuration that exists when
+    * this is called.  The fact that it is a subhash means that whatever prefix
+    * is used to identify the plugin (see PluginHooks) has been removed (see 
the
+    * examples in PluginHooks::readConfig).
+    */
+
+   /// Called for any request
+   virtual
+      AuthResult authorizeAndModify(const UtlString& id,    /**< The 
authenticated identity of the
+                                                             *   request 
originator, if any (the null
+                                                             *   string if 
not).
+                                                             *   This is in 
the form of a SIP uri
+                                                             *   identity 
value as used in the
+                                                             *   credentials 
database (user@domain)
+                                                             *   without the 
scheme or any parameters.
+                                                             */
+                                    const Url&  requestUri, ///< parsed target 
Uri
+                                    RouteState& routeState, ///< the state for 
this request.  
+                                    const UtlString& method,///< the request 
method
+                                    AuthResult  priorResult,///< results from 
earlier plugins.
+                                    SipMessage& request,    ///< see 
AuthPlugin regarding modifying
+                                    bool bSpiralingRequest, ///< request 
spiraling indication 
+                                    UtlString&  reason      ///< rejection 
reason
+                                    );
+   ///< See class description.
+
+   virtual void announceAssociatedSipRouter( SipRouter* sipRouter );
+   
+  protected:
+
+   static OsMutex        sSingletonLock;  ///< lock to protext the spInstance
+   static CallerAlertInfo*   spInstance;  ///< only one CallerAlertInfo may be 
configured
+
+  private:
+   friend AuthPlugin* getAuthPlugin(const UtlString& name);
+
+   CallerAlertInfo(const UtlString& instanceName ///< the configured name for 
this plugin instance
+              );
+
+   OsRWMutex  mConfigLock;      ///< lock to protect the configuration
+   
+   // Plug-in configuration
+   UtlString  mExternalText;    ///< Alert-Info value for external calls
+   bool       mExternalEnabled; ///< Whether Alert-Info should be appended to 
external calls
+   UtlString  mInternalText;    ///< Alert-Info value for internal calls
+   bool       mInternalEnabled; ///< Whether Alert-Info should be appended to 
internal calls
+
+   SipRouter* mpSipRouter;
+};
+
+#endif // _CALLERALERTINFO_H_
diff --git a/sipXproxy/lib/authplugins/Makefile.am 
b/sipXproxy/lib/authplugins/Makefile.am
index f3ad115..1eff089 100644
--- a/sipXproxy/lib/authplugins/Makefile.am
+++ b/sipXproxy/lib/authplugins/Makefile.am
@@ -22,6 +22,7 @@ AUTHPLUGIN_COMMON_LD_FLAGS = \
 
 nobase_lib_LTLIBRARIES = \
     authplugins/libCallerAlias.la \
+    authplugins/libCallerAlertInfo.la \
     authplugins/libTransferControl.la \
     authplugins/libEnforceAuthRules.la \
     authplugins/libEmergencyNotify.la \
@@ -43,6 +44,21 @@ authplugins_libCallerAlias_la_LDFLAGS = \
 authplugins_libCallerAlias_la_LIBADD = \
     @SIPXCOMMSERVER_LIBS@
 
+
+authplugins_libCallerAlertInfo_la_SOURCES = \
+    CallerAlertInfo.h \
+    CallerAlertInfo.cpp
+
+authplugins_libCallerAlertInfo_la_CXXFLAGS = \
+    $(AUTHPLUGIN_COMMON_CXX_FLAGS)
+
+authplugins_libCallerAlertInfo_la_LDFLAGS = \
+    $(AUTHPLUGIN_COMMON_LD_FLAGS)
+
+authplugins_libCallerAlertInfo_la_LIBADD = \
+    @SIPXCOMMSERVER_LIBS@
+
+
 authplugins_libEnforceAuthRules_la_SOURCES = \
     EnforceAuthRules.h \
     EnforceAuthRules.cpp
-- 
1.5.5.6

_______________________________________________
sipx-dev mailing list
[email protected]
List Archive: http://list.sipfoundry.org/archive/sipx-dev/

Reply via email to