[asterisk-commits] dvossel: branch dvossel/sip_resource_list_trunk r186718 - /team/dvossel/sip_r...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Tue Apr 7 12:15:09 CDT 2009
Author: dvossel
Date: Tue Apr 7 12:15:05 2009
New Revision: 186718
URL: http://svn.digium.com/svn-view/asterisk?view=rev&rev=186718
Log:
Added callback for exten state changes. callback returns pointer to rlist so all watchers can be updated. Stuff left to do, add locking for rlist, add transmit_rlist_notify function to create and send NOTIFY to every watcher on update.
Modified:
team/dvossel/sip_resource_list_trunk/channels/chan_sip.c
Modified: team/dvossel/sip_resource_list_trunk/channels/chan_sip.c
URL: http://svn.digium.com/svn-view/asterisk/team/dvossel/sip_resource_list_trunk/channels/chan_sip.c?view=diff&rev=186718&r1=186717&r2=186718
==============================================================================
--- team/dvossel/sip_resource_list_trunk/channels/chan_sip.c (original)
+++ team/dvossel/sip_resource_list_trunk/channels/chan_sip.c Tue Apr 7 12:15:05 2009
@@ -1901,6 +1901,7 @@
int version;
int the_mark;
int num_watchers;
+ int startmonitor;
AST_LIST_HEAD_NOLOCK(, sip_pvt) watchers;
AST_LIST_HEAD_NOLOCK(, sip_rlist_resource) resources;
};
@@ -2450,6 +2451,8 @@
/* add and remove resource list watchers */
static int rlist_add_watcher(struct sip_pvt *p);
static int rlist_remove_watcher(struct sip_pvt *p);
+static int rlist_start_monitor(struct sip_rlist *rlist);
+static int rlist_stop_monitor(struct sip_rlist *rlist);
/*!
* \brief generic function for determining if a correct transport is being
@@ -4341,7 +4344,8 @@
static void destroy_rlist_resources(struct sip_rlist *rlist) {
struct sip_rlist_resource *resource = NULL;
-
+ /*since resources are being removed, make sure to del exten state callback. */
+ rlist_stop_monitor(rlist);
while ((resource = AST_LIST_REMOVE_HEAD(&rlist->resources, entry))) {
ast_string_field_free_memory(resource);
}
@@ -12179,6 +12183,44 @@
ao2_lock(peer);
sip_send_mwi_to_peer(peer, event, 0);
ao2_unlock(peer);
+}
+
+static int cb_rlist_extensionstate(char *context, char* exten, int state, void *data)
+{
+ struct sip_rlist *rlist = data;
+ struct sip_rlist_resource *resource;
+ int found = 0;
+
+
+ ast_log(LOG_NOTICE, "CALLED BACK!!! exten: %s, state:%d, rlist_name:%s", exten, state, rlist->name); //todohere remove
+ /* check to see if there are any watchers for this list, if not stop monitoring */
+ if (!rlist->num_watchers) {
+ rlist_stop_monitor(rlist);
+ return 0;
+ }
+ AST_LIST_TRAVERSE(&rlist->resources, resource, entry) {
+ if (!strcmp(resource->exten, exten)) {
+ found = 1;
+ break;
+ }
+ }
+
+ if (!found) {
+ return -1;
+ }
+
+ switch(state) {
+ case AST_EXTENSION_DEACTIVATED: /* Retry after a while */
+ case AST_EXTENSION_REMOVED: /* Extension is gone */
+ resource->stateid = -1;
+ break;
+ default: /* Tell user */
+ resource->laststate = state;
+ break;
+ }
+
+//todohere transmit notify to all rlist watchers, something like this transmit_rlist_state_notify(p, state, 1, FALSE);
+ return 0;
}
/*! \brief Callback for the devicestate notification (SUBSCRIBE) support subsystem
@@ -21119,7 +21161,7 @@
ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED);
transmit_response(p, "200 OK", req);
ast_string_field_build(p, subscribeuri, "%s@%s", p->exten, p->context);
- //todohere force first notify
+ //todohere force first notify and delete any matching old subscriptions (they will time out, but why wait
} else {
transmit_response(p, "404 Not found", req);
pvt_set_needdestroy(p, "no extension for SUBSCRIBE");
@@ -23275,6 +23317,47 @@
}
}
+static int rlist_start_monitor(struct sip_rlist *rlist)
+{
+ struct sip_rlist_resource *resource;
+
+ if (!rlist->num_watchers) {
+ if (rlist->startmonitor) {
+ rlist_stop_monitor(rlist); /* no watchers, no need to monitor */
+ }
+ return 0;
+ } else if (rlist->startmonitor) { /* monitor already started */
+ return 0;
+ }
+ AST_LIST_TRAVERSE(&rlist->resources, resource, entry) {
+ if (resource->stateid > -1) {
+ ast_extension_state_del(resource->stateid, cb_rlist_extensionstate);
+ resource->stateid = -1;
+ }
+ resource->stateid = ast_extension_state_add(rlist->context, resource->exten, cb_rlist_extensionstate, rlist);
+ if (resource->stateid > -1) {
+ ao2_t_ref(rlist, 1, "monitoring new extension");
+ }
+ }
+ rlist->startmonitor = 1;
+ return 1;
+}
+
+static int rlist_stop_monitor(struct sip_rlist *rlist)
+{
+ struct sip_rlist_resource *resource;
+
+ AST_LIST_TRAVERSE(&rlist->resources, resource, entry) {
+ if (resource->stateid > -1) {
+ ast_extension_state_del(resource->stateid, cb_rlist_extensionstate);
+ resource->stateid = -1;
+ ao2_t_ref(rlist, -1, "stopped monitoring extension");
+ }
+ }
+ rlist->startmonitor = 0;
+ return 1;
+}
+
static int rlist_add_watcher(struct sip_pvt *p)
{
if (p) {
@@ -23283,10 +23366,8 @@
if (p->rlist) {
dialog_ref(p, "add sip_pvt watcher to resource list notifications");
AST_LIST_INSERT_TAIL(&p->rlist->watchers, p, rlist_entry);
- if (!p->rlist->num_watchers) { /* num_watchers is zero, meaning this is the first watcher so start monitoring */
- // todohere add logic to start monitoring extensions since we have a watcher
- }
p->rlist->num_watchers++;
+ rlist_start_monitor(p->rlist);
return 1;
}
} else {
@@ -23305,7 +23386,7 @@
AST_LIST_REMOVE(&p->rlist->watchers, p, rlist_entry);
p->rlist->num_watchers--;
if (!p->rlist->num_watchers) { /* num_watchers is decremented to zero, stop monitoring extensions. */
- //todohere add logic to stop monitoring extensions since nothing is watching
+ rlist_stop_monitor(p->rlist);
}
ao2_t_ref(p->rlist, -1, "remove dialog's ref to resource list");
p->rlist = NULL;
@@ -23324,6 +23405,7 @@
}
ast_string_field_init(resource, 128);
ast_string_field_set(resource, exten, monitorexten);
+ resource->stateid = -1;
AST_LIST_INSERT_TAIL(&rlist->resources, resource, entry);
return 0;
@@ -23353,7 +23435,7 @@
ao2_t_ref(rlist, -1, "rlist failed to init string field");
return NULL;
}
-
+ rlist->startmonitor = 0;
ast_copy_string(rlist->name, name, sizeof(rlist->name));
}
@@ -23367,6 +23449,8 @@
rlist->the_mark = 0; /* unmark this resource list for deletion */
if (found) {
+ /* monitor was stopped when resources were destroyed. now that they are added back, restart monitor. this only takes affect if rlist has watchers. */
+ rlist_start_monitor(rlist);
ao2_t_ref(rlist, -1, "rlist found and updated, decrement ref and return NULL");
return NULL;
}
More information about the asterisk-commits
mailing list