summaryrefslogtreecommitdiff
path: root/main/pbx.c
diff options
context:
space:
mode:
Diffstat (limited to 'main/pbx.c')
-rw-r--r--main/pbx.c69
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);