[sr-dev] git:master: modules_k/rls: Added a new exported function: rls_update_subs()

Peter Dunkley peter.dunkley at crocodile-rcs.com
Fri Jul 29 14:23:55 CEST 2011


Module: sip-router
Branch: master
Commit: 4a09b0f8c57f632de5c26c6bc34f5ac32dbe86c2
URL:    http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=4a09b0f8c57f632de5c26c6bc34f5ac32dbe86c2

Author: pd <peter.dunkley at crocodile-rcs.com>
Committer: pd <peter.dunkley at crocodile-rcs.com>
Date:   Thu Jul 28 12:41:07 2011 +0100

modules_k/rls: Added a new exported function: rls_update_subs()

- This new function can be called from the Kamailio configuration file
  to force the RLS module to refresh its back-end subscriptions.

  This is particularly useful when the resource list has changed (for
  example, a new contact has been added) as it will create a new back-
  end subscriptions when required.

  This means that when you add a new contact in a client the uses RLS
  the added contact can be immediately subscribed to and will get an
  authorisation request.
- Sample usage:

  case "PUT":
    xcaps_put("$var(uri)", "$var(doc_uri)", "$rb");
    if($xcapuri(u=>auid)=~"pres-rules") {
      pres_update_watchers("$var(uri)", "presence");
      pres_refresh_watchers("$var(uri)", "presence", 1);
    } else if ($xcapuri(u=>auid)=~"resource-lists"
               || $xcapuri(u=>auid)=~"rls-services") {
      rls_update_subs("$var(uri)", "presence");
    }
    exit;
  break;

---

 modules_k/rls/README            |   22 ++++++
 modules_k/rls/doc/rls_admin.xml |   34 ++++++++++
 modules_k/rls/rls.c             |    4 +
 modules_k/rls/subscribe.c       |  136 +++++++++++++++++++++++++++++++++++++++
 4 files changed, 196 insertions(+), 0 deletions(-)

diff --git a/modules_k/rls/README b/modules_k/rls/README
index 41588ef..b23953f 100644
--- a/modules_k/rls/README
+++ b/modules_k/rls/README
@@ -42,6 +42,7 @@ Anca-Maria Vamanu
 
               4.1. rls_handle_subscribe()
               4.2. rls_handle_notify()
+              4.3. rls_update_subs(uri, event)
 
         5. Installation
 
@@ -65,6 +66,7 @@ Anca-Maria Vamanu
    1.14. Set server_address parameter
    1.15. rls_handle_subscribe usage
    1.16. rls_handle_notify usage
+   1.17. rls_update_subs usage
 
 Chapter 1. Admin Guide
 
@@ -97,6 +99,7 @@ Chapter 1. Admin Guide
 
         4.1. rls_handle_subscribe()
         4.2. rls_handle_notify()
+        4.3. rls_update_subs(uri, event)
 
    5. Installation
 
@@ -339,6 +342,7 @@ modparam("rls", "server_address", "sip:rls at ip.address.ofyour.proxy:5060")
 
    4.1. rls_handle_subscribe()
    4.2. rls_handle_notify()
+   4.3. rls_update_subs(uri, event)
 
 4.1.  rls_handle_subscribe()
 
@@ -383,6 +387,24 @@ if(method=="NOTIFY")
     rls_handle_notify();
 ...
 
+4.3.  rls_update_subs(uri, event)
+
+   This function can be used in configuration to trigger updates to
+   resource list subscriptions (for example, after the contents of a
+   resource list has changes).
+
+   Parameters:
+     * uri - the uri of the user who made the change and whose resource
+       list subscriptions should be updated
+     * event - the event package (e.g. presence).
+
+   This function can be used from ANY_ROUTE.
+
+   Example 1.17. rls_update_subs usage
+...
+rls_update_subs("sip:test at kamailio.org", "presence");
+...
+
 5. Installation
 
    The module requires 2 tables in Kamailio database: rls_presentity and
diff --git a/modules_k/rls/doc/rls_admin.xml b/modules_k/rls/doc/rls_admin.xml
index 351deb6..bba428c 100644
--- a/modules_k/rls/doc/rls_admin.xml
+++ b/modules_k/rls/doc/rls_admin.xml
@@ -444,6 +444,40 @@ if(method=="NOTIFY")
 </programlisting>
 		</example>
 	</section>
+
+	<section>
+		<title>
+		<function moreinfo="none">rls_update_subs(uri, event)</function>
+		</title>
+		<para>
+		This function can be used in configuration to trigger updates to
+		resource list subscriptions (for example, after the contents of a
+		resource list has changes).
+		</para>
+		<para>Parameters:</para>
+		<itemizedlist>
+			<listitem>
+				<para>uri - the uri of the user who made the change
+				and whose resource list subscriptions should be
+				updated</para>
+			</listitem>
+			<listitem>
+				<para>event - the event package (e.g. presence).
+				</para>
+			</listitem>
+		</itemizedlist>
+		<para>
+		This function can be used from ANY_ROUTE.
+		</para>
+		<example>
+		<title><function>rls_update_subs</function> usage</title>
+		<programlisting format="linespecific">
+...
+rls_update_subs("sip:test at kamailio.org", "presence");
+...
+</programlisting>
+		</example>
+	</section>
 </section>
 
 <section>
diff --git a/modules_k/rls/rls.c b/modules_k/rls/rls.c
index 368f815..b69cea7 100644
--- a/modules_k/rls/rls.c
+++ b/modules_k/rls/rls.c
@@ -164,6 +164,8 @@ static void destroy(void);
 int rlsubs_table_restore();
 void rlsubs_table_update(unsigned int ticks,void *param);
 int add_rls_event(modparam_t type, void* val);
+int rls_update_subs(struct sip_msg *msg, char *puri, char *pevent);
+int fixup_update_subs(void** param, int param_no);
 
 static cmd_export_t cmds[]=
 {
@@ -171,6 +173,8 @@ static cmd_export_t cmds[]=
 			0, 0, REQUEST_ROUTE},
 	{"rls_handle_notify",     (cmd_function)rls_handle_notify,      0,
 			0, 0, REQUEST_ROUTE},
+	{"rls_update_subs",       (cmd_function)rls_update_subs,	2,
+			fixup_update_subs, 0, ANY_ROUTE},
 	{0, 0, 0, 0, 0, 0 }
 };
 
diff --git a/modules_k/rls/subscribe.c b/modules_k/rls/subscribe.c
index 205ecb5..ed6366b 100644
--- a/modules_k/rls/subscribe.c
+++ b/modules_k/rls/subscribe.c
@@ -50,6 +50,7 @@
 #include "subscribe.h"
 #include "notify.h"
 #include "rls.h"
+#include "../../mod_fix.h"
 
 int counter= 0;
 
@@ -876,3 +877,138 @@ error:
 
 }
 
+int fixup_update_subs(void** param, int param_no)
+{
+	if (param_no == 1) {
+		return fixup_spve_null(param, 1);
+	} else if (param_no == 2) {
+		return fixup_spve_null(param, 1);
+	}
+	return 0;
+}
+
+int rls_update_subs(struct sip_msg *msg, char *puri, char *pevent)
+{
+	str uri;
+	str event;
+	struct sip_uri parsed_uri;
+	event_t e;
+	int i;
+	
+	if (fixup_get_svalue(msg, (gparam_p)puri, &uri) != 0)
+	{
+		LM_ERR("invalid uri parameter\n");
+		return -1;
+	}
+
+	if (fixup_get_svalue(msg, (gparam_p)pevent, &event) != 0)
+	{
+		LM_ERR("invalid event parameter\n");
+		return -1;
+	}
+
+	if (event_parser(event.s, event.len, &e) < 0)
+	{
+		LM_ERR("while parsing event: %.*s\n", event.len, event.s);
+		return -1;
+	}
+
+	if (e.type & EVENT_OTHER)
+	{
+		LM_ERR("unrecognised event: %.*s\n", event.len, event.s);
+		return -1;
+	}
+
+	if (!(e.type & rls_events))
+	{
+		LM_ERR("event not supported by RLS: %.*s\n", event.len,
+			event.s);
+		return -1;
+	}
+
+	if (parse_uri(uri.s, uri.len, &parsed_uri) < 0)
+	{
+		LM_ERR("bad uri: %.*s\n", uri.len, uri.s);
+		return -1;
+	}
+
+	LM_DBG("watcher username: %.*s, watcher domain: %.*s\n",
+		parsed_uri.user.len, parsed_uri.user.s,
+		parsed_uri.host.len, parsed_uri.host.s);
+
+	if (rls_table == NULL)
+	{
+		LM_ERR("rls_table is NULL\n");
+		return -1;
+	}
+
+	/* Search through the entire subscription table for matches... */
+	for (i = 0; i < hash_size; i++)
+	{
+		subs_t *subs;
+
+		lock_get(&rls_table[i].lock);
+
+		subs = rls_table[i].entries->next;
+
+		while (subs != NULL)
+		{
+			if (subs->from_user.len == parsed_uri.user.len &&
+				strncmp(subs->from_user.s, parsed_uri.user.s, parsed_uri.user.len) == 0 &&
+			    subs->from_domain.len == parsed_uri.host.len &&
+				strncmp(subs->from_domain.s, parsed_uri.host.s, parsed_uri.host.len) == 0 &&
+				subs->event->evp->type == e.type)
+			{
+				subs_t *subs_copy = NULL;
+				xmlDocPtr doc = NULL;
+				xmlNodePtr service_node = NULL;
+	
+				LM_DBG("found matching RLS subscription for: %.*s\n",
+					subs->pres_uri.len, subs->pres_uri.s);
+
+				if ((subs_copy = pres_copy_subs(subs, PKG_MEM_TYPE)) == NULL)
+				{
+					LM_ERR("subs_t copy failed\n");
+					lock_release(&rls_table[i].lock);
+					return -1;
+				}
+
+				if ((subs_copy->expires -= (int)time(NULL)) <= 0)
+				{
+					LM_WARN("found expired subscription for: %.*s\n",
+						subs_copy->pres_uri.len, subs_copy->pres_uri.s);
+					goto loop_done;
+				}
+
+				if(rls_get_service_list(&subs_copy->pres_uri, &subs_copy->from_user,
+							&subs_copy->from_domain, &service_node, &doc)<0)
+				{
+					LM_ERR("failed getting resource list for: %.*s\n",
+						subs_copy->pres_uri.len, subs_copy->pres_uri.s);
+					goto loop_done;
+				}
+				if(doc==NULL)
+				{
+					LM_WARN("no document returned for: %.*s\n",
+						subs_copy->pres_uri.len, subs_copy->pres_uri.s);
+					goto loop_done;
+				}
+
+				if(resource_subscriptions(subs_copy, service_node)< 0)
+				{
+					LM_ERR("failed sending subscribe requests to resources in list\n");
+					goto loop_done;
+				}
+
+loop_done:
+				if (doc != NULL)
+					xmlFreeDoc(doc);
+				pkg_free(subs_copy);
+			}
+			subs = subs->next;
+		}		
+		lock_release(&rls_table[i].lock);
+	}
+
+	return 1;
+}




More information about the sr-dev mailing list