diff options
Diffstat (limited to 'main/pbx.c')
-rw-r--r-- | main/pbx.c | 69 |
1 files changed, 43 insertions, 26 deletions
diff --git a/main/pbx.c b/main/pbx.c index b605a9143..267717e48 100644 --- a/main/pbx.c +++ b/main/pbx.c @@ -1157,10 +1157,14 @@ static int add_hintdevice(struct ast_hint *hint, const char *devicelist) return -1; } ast_str_set(&str, 0, "%s", devicelist); - parse = parse_hint_device(str); + parse = ast_str_buffer(str); - while ((cur = strsep(&parse, "&"))) { + /* Spit on '&' and ',' to handle presence hints as well */ + while ((cur = strsep(&parse, "&,"))) { devicelength = strlen(cur); + if (!devicelength) { + continue; + } device = ao2_t_alloc(sizeof(*device) + devicelength, hintdevice_destroy, "allocating a hintdevice structure"); if (!device) { @@ -11828,10 +11832,12 @@ static int pbx_builtin_sayphonetic(struct ast_channel *chan, const char *data) static void presence_state_cb(void *unused, struct stasis_subscription *sub, struct stasis_message *msg) { - struct ast_presence_state_message *presence_state = stasis_message_data(msg); + struct ast_presence_state_message *presence_state; struct ast_hint *hint; struct ast_str *hint_app = NULL; - struct ao2_iterator hint_iter; + struct ast_hintdevice *device; + struct ast_hintdevice *cmpdevice; + struct ao2_iterator *dev_iter; struct ao2_iterator cb_iter; char context_name[AST_MAX_CONTEXT]; char exten_name[AST_MAX_EXTENSION]; @@ -11840,38 +11846,48 @@ static void presence_state_cb(void *unused, struct stasis_subscription *sub, str return; } + presence_state = stasis_message_data(msg); + + if (ao2_container_count(hintdevices) == 0) { + /* There are no hints monitoring devices. */ + return; + } + hint_app = ast_str_create(1024); if (!hint_app) { return; } ast_mutex_lock(&context_merge_lock);/* Hold off ast_merge_contexts_and_delete */ - hint_iter = ao2_iterator_init(hints, 0); - for (; (hint = ao2_iterator_next(&hint_iter)); ao2_cleanup(hint)) { - struct ast_state_cb *state_cb; - const char *app; - char *parse; - SCOPED_AO2LOCK(lock, hint); - if (!hint->exten) { - /* The extension has already been destroyed */ - continue; - } + cmpdevice = ast_alloca(sizeof(*cmpdevice) + strlen(presence_state->provider)); + strcpy(cmpdevice->hintdevice, presence_state->provider); - /* Does this hint monitor the device that changed state? */ - app = ast_get_extension_app(hint->exten); - if (ast_strlen_zero(app)) { - /* The hint does not monitor presence at all. */ - continue; - } + ast_mutex_lock(&context_merge_lock);/* Hold off ast_merge_contexts_and_delete */ + dev_iter = ao2_t_callback(hintdevices, + OBJ_POINTER | OBJ_MULTIPLE, + hintdevice_cmp_multiple, + cmpdevice, + "find devices in container"); + if (!dev_iter) { + ast_mutex_unlock(&context_merge_lock); + ast_free(hint_app); + return; + } + + for (; (device = ao2_iterator_next(dev_iter)); ao2_t_ref(device, -1, "Next device")) { + struct ast_state_cb *state_cb; - ast_str_set(&hint_app, 0, "%s", app); - parse = parse_hint_presence(hint_app); - if (ast_strlen_zero(parse)) { + if (!device->hint) { + /* Should never happen. */ continue; } - if (strcasecmp(parse, presence_state->provider)) { - /* The hint does not monitor the presence provider. */ + hint = device->hint; + + ao2_lock(hint); + if (!hint->exten) { + /* The extension has already been destroyed */ + ao2_unlock(hint); continue; } @@ -11885,6 +11901,7 @@ static void presence_state_cb(void *unused, struct stasis_subscription *sub, str ast_copy_string(exten_name, ast_get_extension_name(hint->exten), sizeof(exten_name)); ast_str_set(&hint_app, 0, "%s", ast_get_extension_app(hint->exten)); + ao2_unlock(hint); /* Check to see if update is necessary */ if ((hint->last_presence_state == presence_state->state) && @@ -11928,7 +11945,7 @@ static void presence_state_cb(void *unused, struct stasis_subscription *sub, str } ao2_iterator_destroy(&cb_iter); } - ao2_iterator_destroy(&hint_iter); + ao2_iterator_destroy(dev_iter); ast_mutex_unlock(&context_merge_lock); ast_free(hint_app); |