Module: sip-router
Branch: pd/crocodile
Commit: 4a09b0f8c57f632de5c26c6bc34f5ac32dbe86c2
URL:
http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=4a09b0f…
Author: pd <peter.dunkley(a)crocodile-rcs.com>
Committer: pd <peter.dunkley(a)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@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@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@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;
+}