From 98aa637d27b5ac36a35fc85b596f00d1104398e3 Mon Sep 17 00:00:00 2001 From: markster Date: Thu, 17 Mar 2005 21:05:10 +0000 Subject: Add comments for hints (bug #3783) git-svn-id: http://svn.digium.com/svn/asterisk/trunk@5191 f38db490-d61c-443f-a65b-d21fe96a405b --- pbx.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 48 insertions(+), 21 deletions(-) diff --git a/pbx.c b/pbx.c index 2b4078fb5..64a2e7dfa 100755 --- a/pbx.c +++ b/pbx.c @@ -141,7 +141,7 @@ struct ast_state_cb { struct ast_state_cb *next; }; -/* ast_state_cb: An extension state notify */ +/* ast_devstate_cb: An extension state notify */ struct ast_devstate_cb { void *data; ast_devstate_cb_type callback; @@ -150,11 +150,12 @@ struct ast_devstate_cb { static struct ast_devstate_cb *devcbs; +/* Hints are pointers from an extension in the dialplan to one or more devices (tech/name) */ struct ast_hint { - struct ast_exten *exten; - int laststate; - struct ast_state_cb *callbacks; - struct ast_hint *next; + struct ast_exten *exten; /* Extension */ + int laststate; /* Last known state */ + struct ast_state_cb *callbacks; /* Callback list for this extension */ + struct ast_hint *next; /* Pointer to next hint in list */ }; int ast_pbx_outgoing_cdr_failed(void); @@ -464,13 +465,13 @@ static struct pbx_builtin { }; -AST_MUTEX_DEFINE_STATIC(applock); /* Lock for the application list */ static struct ast_context *contexts = NULL; AST_MUTEX_DEFINE_STATIC(conlock); /* Lock for the ast_context list */ static struct ast_app *apps = NULL; +AST_MUTEX_DEFINE_STATIC(applock); /* Lock for the application list */ -AST_MUTEX_DEFINE_STATIC(switchlock); /* Lock for switches */ struct ast_switch *switches = NULL; +AST_MUTEX_DEFINE_STATIC(switchlock); /* Lock for switches */ AST_MUTEX_DEFINE_STATIC(hintlock); /* Lock for extension state notifys */ static int stateid = 1; @@ -1673,6 +1674,7 @@ static struct ast_exten *ast_hint_extension(struct ast_channel *c, const char *c return e; } +/*--- ast_extensions_state2: Check state of extension by using hints */ static int ast_extension_state2(struct ast_exten *e) { char hint[AST_MAX_EXTENSION] = ""; @@ -1681,9 +1683,12 @@ static int ast_extension_state2(struct ast_exten *e) int allunavailable = 1, allbusy = 1, allfree = 1; int busy = 0; + if (!e) + return -1; + strncpy(hint, ast_get_extension_app(e), sizeof(hint)-1); - cur = hint; + cur = hint; /* On or more devices separated with a & character */ do { rest = strchr(cur, '&'); if (rest) { @@ -1717,9 +1722,9 @@ static int ast_extension_state2(struct ast_exten *e) cur = rest; } while (cur); - if (allfree) + if (allfree) return AST_EXTENSION_NOT_INUSE; - if (allbusy) + if (allbusy) return AST_EXTENSION_BUSY; if (allunavailable) return AST_EXTENSION_UNAVAILABLE; @@ -1730,17 +1735,19 @@ static int ast_extension_state2(struct ast_exten *e) } +/*--- ast_extension_state: Check extension state for an extension by using hint */ int ast_extension_state(struct ast_channel *c, char *context, char *exten) { struct ast_exten *e; - e = ast_hint_extension(c, context, exten); + e = ast_hint_extension(c, context, exten); /* Do we have a hint for this extension ? */ if (!e) - return -1; + return -1; /* No hint, return -1 */ - return ast_extension_state2(e); + return ast_extension_state2(e); /* Check all devices in the hint */ } +/*--- ast_device_state_changed: If device state in cblist is changed - then notify callback function */ int ast_device_state_changed(const char *fmt, ...) { struct ast_hint *list; @@ -1748,6 +1755,7 @@ int ast_device_state_changed(const char *fmt, ...) struct ast_devstate_cb *devcb; char hint[AST_MAX_EXTENSION] = ""; char device[AST_MAX_EXTENSION]; + char *cur, *rest; int state; @@ -1762,16 +1770,24 @@ int ast_device_state_changed(const char *fmt, ...) *rest = 0; } + if (option_debug > 2) + ast_log(LOG_DEBUG, "Changing state for %s\n", device); + + + state = ast_device_state(device); ast_mutex_lock(&hintlock); + /* First check device callbacks */ devcb = devcbs; while(devcb) { if (devcb->callback) devcb->callback(device, state, devcb->data); devcb = devcb->next; } + + /* Then check callbacks in hints */ list = hints; while (list) { @@ -1785,10 +1801,14 @@ int ast_device_state_changed(const char *fmt, ...) rest++; } - if (!strcmp(cur, device)) { - /* Found extension execute callbacks */ + if (!strcmp(cur, device)) { /* Is this device referred to in this hint? */ + + /* Get device state for this hint */ state = ast_extension_state2(list->exten); + if ((state != -1) && (state != list->laststate)) { + /* Device state changed since last check - notify the watcher */ + /* For general callbacks */ cblist = statecbs; while (cblist) { @@ -1815,6 +1835,7 @@ int ast_device_state_changed(const char *fmt, ...) return 1; } +/*--- ast_devstate_add: Add device state watcher */ int ast_devstate_add(ast_devstate_cb_type callback, void *data) { struct ast_devstate_cb *devcb; @@ -1831,6 +1852,7 @@ int ast_devstate_add(ast_devstate_cb_type callback, void *data) return 0; } +/*--- ast_devstate_del: Remove device state watcher */ void ast_devstate_del(ast_devstate_cb_type callback, void *data) { struct ast_devstate_cb *devcb, *prev = NULL, *next; @@ -1851,6 +1873,7 @@ void ast_devstate_del(ast_devstate_cb_type callback, void *data) ast_mutex_unlock(&hintlock); } +/*--- ast_extension_state_add: Add watcher for extension states */ int ast_extension_state_add(const char *context, const char *exten, ast_state_cb_type callback, void *data) { @@ -1858,7 +1881,7 @@ int ast_extension_state_add(const char *context, const char *exten, struct ast_state_cb *cblist; struct ast_exten *e; - /* No context and extension add callback to statecbs list */ + /* If there's no context and extension: add callback to statecbs list */ if (!context && !exten) { ast_mutex_lock(&hintlock); @@ -1892,12 +1915,13 @@ int ast_extension_state_add(const char *context, const char *exten, if (!context || !exten) return -1; - /* This callback type is for only one hint */ + /* This callback type is for only one hint, so get the hint */ e = ast_hint_extension(NULL, context, exten); if (!e) { return -1; } + /* Find the hint in the list of hints */ ast_mutex_lock(&hintlock); list = hints; @@ -1908,20 +1932,21 @@ int ast_extension_state_add(const char *context, const char *exten, } if (!list) { + /* We have no hint, sorry */ ast_mutex_unlock(&hintlock); return -1; } - /* Now inserts the callback */ + /* Now insert the callback in the callback list */ cblist = malloc(sizeof(struct ast_state_cb)); if (!cblist) { ast_mutex_unlock(&hintlock); return -1; } memset(cblist, 0, sizeof(struct ast_state_cb)); - cblist->id = stateid++; - cblist->callback = callback; - cblist->data = data; + cblist->id = stateid++; /* Unique ID for this callback */ + cblist->callback = callback; /* Pointer to callback routine */ + cblist->data = data; /* Data for the callback */ cblist->next = list->callbacks; list->callbacks = cblist; @@ -1930,6 +1955,7 @@ int ast_extension_state_add(const char *context, const char *exten, return cblist->id; } +/*--- ast_extension_state_del: Remove a watcher from the callback list */ int ast_extension_state_del(int id, ast_state_cb_type callback) { struct ast_hint *list; @@ -1965,6 +1991,7 @@ int ast_extension_state_del(int id, ast_state_cb_type callback) } /* id greater than zero is a callback with extension */ + /* Find the callback based on ID */ list = hints; while (list) { cblist = list->callbacks; -- cgit v1.2.3