diff options
-rw-r--r-- | CHANGES | 4 | ||||
-rw-r--r-- | apps/app_dial.c | 5 | ||||
-rw-r--r-- | include/asterisk/stasis_app.h | 9 | ||||
-rw-r--r-- | main/manager_channels.c | 10 | ||||
-rw-r--r-- | main/stasis_channels.c | 14 | ||||
-rw-r--r-- | res/ari/resource_channels.c | 39 | ||||
-rw-r--r-- | res/res_pjsip_pubsub.c | 5 | ||||
-rw-r--r-- | res/stasis/app.c | 4 | ||||
-rw-r--r-- | res/stasis/control.c | 28 |
9 files changed, 57 insertions, 61 deletions
@@ -274,6 +274,10 @@ AMI * The AMI action PJSIPShowEndpoint now includes ContactStatusDetail sections that give information on Asterisk's attempts to qualify the endpoint. + * The DialEnd event will now contain a Forward header if the dial is ending + due to the call being forwarded. The contents of the Forward header is the + extension in the number to which the call is being forwarded. + CEL ------------------ * The "bridge_technology" extra field key has been added to BRIDGE_ENTER diff --git a/apps/app_dial.c b/apps/app_dial.c index b48a226c7..7c0cc6299 100644 --- a/apps/app_dial.c +++ b/apps/app_dial.c @@ -895,6 +895,7 @@ static void do_forward(struct chanlist *o, struct cause_args *num, tech, stuff, cause); } if (!c) { + ast_channel_publish_dial(in, original, stuff, "BUSY"); ast_clear_flag64(o, DIAL_STILLGOING); handle_cause(cause, num); ast_hangup(original); @@ -995,16 +996,18 @@ static void do_forward(struct chanlist *o, struct cause_args *num, if (ast_call(c, stuff, 0)) { ast_log(LOG_NOTICE, "Forwarding failed to dial '%s/%s'\n", tech, stuff); + ast_channel_publish_dial(in, original, stuff, "CONGESTION"); ast_clear_flag64(o, DIAL_STILLGOING); ast_hangup(original); ast_hangup(c); c = o->chan = NULL; num->nochan++; } else { - ast_channel_publish_dial(in, c, stuff, NULL); ast_channel_publish_dial_forward(in, original, c, NULL, "CANCEL", ast_channel_call_forward(original)); + ast_channel_publish_dial(in, c, stuff, NULL); + /* Hangup the original channel now, in case we needed it */ ast_hangup(original); } diff --git a/include/asterisk/stasis_app.h b/include/asterisk/stasis_app.h index e06e68ed2..e0a6c60f5 100644 --- a/include/asterisk/stasis_app.h +++ b/include/asterisk/stasis_app.h @@ -554,15 +554,6 @@ int stasis_app_control_unmute(struct stasis_app_control *control, unsigned int d int stasis_app_control_answer(struct stasis_app_control *control); /*! - * \brief Get the value of a variable on the channel associated with this control. - * \param control Control for \c res_stasis. - * \param variable The name of the variable. - * - * \return The value of the variable. The returned variable must be freed. - */ -char *stasis_app_control_get_channel_var(struct stasis_app_control *control, const char *variable); - -/*! * \brief Set a variable on the channel associated with this control to value. * \param control Control for \c res_stasis. * \param variable The name of the variable diff --git a/main/manager_channels.c b/main/manager_channels.c index 9a15353f2..127084161 100644 --- a/main/manager_channels.c +++ b/main/manager_channels.c @@ -185,6 +185,10 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") </enum> </enumlist> </parameter> + <parameter name="Forward" required="false"> + <para>If the call was forwarded, where the call was + forwarded to.</para> + </parameter> </syntax> <see-also> <ref type="application">Dial</ref> @@ -986,6 +990,7 @@ static void channel_dial_cb(void *data, struct stasis_subscription *sub, struct ast_multi_channel_blob *obj = stasis_message_data(message); const char *dialstatus; const char *dialstring; + const char *forward; struct ast_channel_snapshot *caller; struct ast_channel_snapshot *peer; RAII_VAR(struct ast_str *, caller_event_string, NULL, ast_free); @@ -1007,6 +1012,7 @@ static void channel_dial_cb(void *data, struct stasis_subscription *sub, dialstatus = ast_json_string_get(ast_json_object_get(ast_multi_channel_blob_get_json(obj), "dialstatus")); dialstring = ast_json_string_get(ast_json_object_get(ast_multi_channel_blob_get_json(obj), "dialstring")); + forward = ast_json_string_get(ast_json_object_get(ast_multi_channel_blob_get_json(obj), "forward")); if (ast_strlen_zero(dialstatus)) { manager_event(EVENT_FLAG_CALL, "DialBegin", "%s" @@ -1016,12 +1022,16 @@ static void channel_dial_cb(void *data, struct stasis_subscription *sub, ast_str_buffer(peer_event_string), S_OR(dialstring, "unknown")); } else { + int forwarded = !ast_strlen_zero(forward); + manager_event(EVENT_FLAG_CALL, "DialEnd", "%s" "%s" + "%s%s%s" "DialStatus: %s\r\n", caller_event_string ? ast_str_buffer(caller_event_string) : "", ast_str_buffer(peer_event_string), + forwarded ? "Forward: " : "", S_OR(forward, ""), forwarded ? "\r\n" : "", S_OR(dialstatus, "unknown")); } diff --git a/main/stasis_channels.c b/main/stasis_channels.c index d7fbc98ab..d40b5701c 100644 --- a/main/stasis_channels.c +++ b/main/stasis_channels.c @@ -288,11 +288,6 @@ static void channel_blob_dtor(void *obj) ast_json_unref(event->blob); } -/*! \brief Dummy callback for receiving events */ -static void dummy_event_cb(void *data, struct stasis_subscription *sub, struct stasis_message *message) -{ -} - void ast_channel_publish_dial_forward(struct ast_channel *caller, struct ast_channel *peer, struct ast_channel *forwarded, const char *dialstring, const char *dialstatus, const char *forward) @@ -362,14 +357,7 @@ void ast_channel_publish_dial_forward(struct ast_channel *caller, struct ast_cha return; } - if (forwarded) { - struct stasis_subscription *subscription = stasis_subscribe(ast_channel_topic(peer), dummy_event_cb, NULL); - - stasis_publish(ast_channel_topic(peer), msg); - stasis_unsubscribe_and_join(subscription); - } else { - publish_message_for_channel_topics(msg, caller); - } + publish_message_for_channel_topics(msg, caller); } void ast_channel_publish_dial(struct ast_channel *caller, struct ast_channel *peer, diff --git a/res/ari/resource_channels.c b/res/ari/resource_channels.c index d0a1be32e..729eeec67 100644 --- a/res/ari/resource_channels.c +++ b/res/ari/resource_channels.c @@ -929,7 +929,8 @@ void ast_ari_channels_get_channel_var(struct ast_variable *headers, { RAII_VAR(struct ast_json *, json, NULL, ast_json_unref); RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup); - RAII_VAR(char *, value, NULL, ast_free); + RAII_VAR(struct ast_str *, value, ast_str_create(32), ast_free); + RAII_VAR(struct ast_channel *, channel, NULL, ast_channel_cleanup); ast_assert(response != NULL); @@ -940,15 +941,41 @@ void ast_ari_channels_get_channel_var(struct ast_variable *headers, return; } - control = find_control(response, args->channel_id); - if (control == NULL) { - /* response filled in by find_control */ + if (ast_strlen_zero(args->channel_id)) { + ast_ari_response_error( + response, 400, "Bad Request", + "Channel ID is required"); + return; + } + + channel = ast_channel_get_by_name(args->channel_id); + if (!channel) { + ast_ari_response_error( + response, 404, "Channel Not Found", + "Provided channel was not found"); return; } - value = stasis_app_control_get_channel_var(control, args->variable); + /* You may be tempted to lock the channel you're about to read from. You + * would be wrong. Some dialplan functions put the channel into + * autoservice, which deadlocks if the channel is already locked. + * ast_str_retrieve_variable() does its own locking, and the dialplan + * functions need to as well. We should be fine without the lock. + */ + + if (args->variable[strlen(args->variable) - 1] == ')') { + if (ast_func_read2(channel, args->variable, &value, 0)) { + ast_ari_response_alloc_failed(response); + return; + } + } else { + if (!ast_str_retrieve_variable(&value, 0, channel, NULL, args->variable)) { + ast_ari_response_alloc_failed(response); + return; + } + } - if (!(json = ast_json_pack("{s: s}", "value", S_OR(value, "")))) { + if (!(json = ast_json_pack("{s: s}", "value", S_OR(ast_str_buffer(value), "")))) { ast_ari_response_alloc_failed(response); return; } diff --git a/res/res_pjsip_pubsub.c b/res/res_pjsip_pubsub.c index f9b64f85f..90be60d4e 100644 --- a/res/res_pjsip_pubsub.c +++ b/res/res_pjsip_pubsub.c @@ -2032,10 +2032,13 @@ int ast_sip_subscription_notify(struct ast_sip_subscription *sub, void *notify_d if (sub->tree->notification_batch_interval) { return schedule_notification(sub->tree); } else { + int res; /* See the note in pubsub_on_rx_refresh() for why sub->tree is refbumped here */ ao2_ref(sub->tree, +1); - return send_notify(sub->tree, 0); + res = send_notify(sub->tree, 0); ao2_ref(sub->tree, -1); + + return res; } } diff --git a/res/stasis/app.c b/res/stasis/app.c index 745969615..245936734 100644 --- a/res/stasis/app.c +++ b/res/stasis/app.c @@ -1073,9 +1073,7 @@ static int unsubscribe(struct stasis_app *app, const char *kind, const char *id, forwards = ao2_find(app->forwards, id, OBJ_SEARCH_KEY | OBJ_NOLOCK); if (!forwards) { - ast_log(LOG_WARNING, - "App '%s' not subscribed to %s '%s'\n", - app->name, kind, id); + ast_debug(3, "App '%s' not subscribed to %s '%s'\n", app->name, kind, id); return -1; } forwards->interested--; diff --git a/res/stasis/control.c b/res/stasis/control.c index 0a9669d3b..e53d93c06 100644 --- a/res/stasis/control.c +++ b/res/stasis/control.c @@ -565,34 +565,6 @@ int stasis_app_control_unmute(struct stasis_app_control *control, unsigned int d return 0; } -char *stasis_app_control_get_channel_var(struct stasis_app_control *control, const char *variable) -{ - RAII_VAR(struct ast_str *, tmp, ast_str_create(32), ast_free); - - /* You may be tempted to lock the channel you're about to read from. You - * would be wrong. Some dialplan functions put the channel into - * autoservice, which deadlocks if the channel is already locked. - * ast_str_retrieve_variable() does its own locking, and the dialplan - * functions need to as well. We should be fine without the lock. - */ - - if (!tmp) { - return NULL; - } - - if (variable[strlen(variable) - 1] == ')') { - if (ast_func_read2(control->channel, variable, &tmp, 0)) { - return NULL; - } - } else { - if (!ast_str_retrieve_variable(&tmp, 0, control->channel, NULL, variable)) { - return NULL; - } - } - - return ast_strdup(ast_str_buffer(tmp)); -} - int stasis_app_control_set_channel_var(struct stasis_app_control *control, const char *variable, const char *value) { return pbx_builtin_setvar_helper(control->channel, variable, value); |