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