diff options
author | Mark Michelson <mmichelson@digium.com> | 2016-05-09 15:00:56 -0500 |
---|---|---|
committer | Mark Michelson <mmichelson@digium.com> | 2016-05-31 11:43:24 -0500 |
commit | 205a31f86c4ceec4966492363fb9ac674c990235 (patch) | |
tree | 425d8f23f52900292cd7aad1e1f7f75bdd5a55d3 /main | |
parent | 88d997913faabe81f8b9e7bdaa56742be0d669b9 (diff) |
Expand the scope of Dial Events
Dial events up to this point have come in two flavors
* A Dial event with no status to indicate that dialing has begun
* A Dial event with a status to indicate that dialing has ended
With this change, Dial events have been expanded to also give
intermediate events, such as "RINGING", "PROCEEDING", and "PROGRESS".
This is especially useful for ARI dialing, as it gives the application
writer the opportunity to place a channel into an early bridge when
early media is detected.
AMI handles these in-progress dial events by sending a new event called
"DialState" that simply indicates that dial state has changed but has
not ended. ARI never distinguished between DialBegin and DialEnd, so no
change was made to the event itself.
Another change here relates to dial forwards. A forward-related event
was previously only sent when a channel was successfully able to forward
a call to a new channel. With this set of changes, if forwarding is
blocked, we send a Dial event with a forwarding destination but no
forwarding channel, since we were prevented from creating one. This is
again useful for ARI since application writers can now handle call
forward attempts from within their own application.
ASTERISK-25925 #close
Reported by Mark Michelson
Change-Id: I42cbec7730d84640a434d143a0d172a740995543
Diffstat (limited to 'main')
-rw-r--r-- | main/bridge_channel.c | 29 | ||||
-rw-r--r-- | main/cdr.c | 9 | ||||
-rw-r--r-- | main/dial.c | 3 | ||||
-rw-r--r-- | main/manager_channels.c | 36 | ||||
-rw-r--r-- | main/stasis_channels.c | 2 |
5 files changed, 76 insertions, 3 deletions
diff --git a/main/bridge_channel.c b/main/bridge_channel.c index db4ecfe57..6766dff8e 100644 --- a/main/bridge_channel.c +++ b/main/bridge_channel.c @@ -2393,6 +2393,14 @@ static struct ast_frame *bridge_handle_dtmf(struct ast_bridge_channel *bridge_ch return frame; } +static const char *controls[] = { + [AST_CONTROL_RINGING] = "RINGING", + [AST_CONTROL_PROCEEDING] = "PROCEEDING", + [AST_CONTROL_PROGRESS] = "PROGRESS", + [AST_CONTROL_BUSY] = "BUSY", + [AST_CONTROL_CONGESTION] = "CONGESTION", + [AST_CONTROL_ANSWER] = "ANSWER", +}; /*! * \internal @@ -2404,6 +2412,17 @@ static void bridge_handle_trip(struct ast_bridge_channel *bridge_channel) { struct ast_frame *frame; + if (!ast_strlen_zero(ast_channel_call_forward(bridge_channel->chan))) { + /* TODO If early bridging is ever used by anything other than ARI, + * it's important that we actually attempt to handle the call forward + * attempt, as well as expand features on a bridge channel to allow/disallow + * call forwarding. For now, all we do is raise an event, showing that + * a call forward is being attempted. + */ + ast_channel_publish_dial_forward(NULL, bridge_channel->chan, NULL, NULL, "CANCEL", + ast_channel_call_forward(bridge_channel->chan)); + } + if (bridge_channel->features->mute) { frame = ast_read_noaudio(bridge_channel->chan); } else { @@ -2417,10 +2436,20 @@ static void bridge_handle_trip(struct ast_bridge_channel *bridge_channel) switch (frame->frametype) { case AST_FRAME_CONTROL: switch (frame->subclass.integer) { + case AST_CONTROL_CONGESTION: + case AST_CONTROL_BUSY: + ast_channel_publish_dial(NULL, bridge_channel->chan, NULL, controls[frame->subclass.integer]); + break; case AST_CONTROL_HANGUP: ast_bridge_channel_kick(bridge_channel, 0); bridge_frame_free(frame); return; + case AST_CONTROL_RINGING: + case AST_CONTROL_PROGRESS: + case AST_CONTROL_PROCEEDING: + case AST_CONTROL_ANSWER: + ast_channel_publish_dial(NULL, bridge_channel->chan, NULL, controls[frame->subclass.integer]); + break; default: break; } diff --git a/main/cdr.c b/main/cdr.c index b6a0b428c..b43e3610c 100644 --- a/main/cdr.c +++ b/main/cdr.c @@ -1902,6 +1902,13 @@ static int filter_channel_cache_message(struct ast_channel_snapshot *old_snapsho return ret; } +static int dial_status_end(const char *dialstatus) +{ + return (strcmp(dialstatus, "RINGING") && + strcmp(dialstatus, "PROCEEDING") && + strcmp(dialstatus, "PROGRESS")); +} + /* TOPIC ROUTER CALLBACKS */ /*! @@ -1970,7 +1977,7 @@ static void handle_dial_message(void *data, struct stasis_subscription *sub, str res &= it_cdr->fn_table->process_dial_begin(it_cdr, caller, peer); - } else { + } else if (dial_status_end(dial_status)) { if (!it_cdr->fn_table->process_dial_end) { continue; } diff --git a/main/dial.c b/main/dial.c index fc66af5a7..bac191e06 100644 --- a/main/dial.c +++ b/main/dial.c @@ -627,11 +627,13 @@ static void handle_frame(struct ast_dial *dial, struct ast_dial_channel *channel break; case AST_CONTROL_RINGING: ast_verb(3, "%s is ringing\n", ast_channel_name(channel->owner)); + ast_channel_publish_dial(chan, channel->owner, channel->device, "RINGING"); if (chan && !dial->options[AST_DIAL_OPTION_MUSIC]) ast_indicate(chan, AST_CONTROL_RINGING); set_state(dial, AST_DIAL_RESULT_RINGING); break; case AST_CONTROL_PROGRESS: + ast_channel_publish_dial(chan, channel->owner, channel->device, "PROGRESS"); if (chan) { ast_verb(3, "%s is making progress, passing it to %s\n", ast_channel_name(channel->owner), ast_channel_name(chan)); ast_indicate(chan, AST_CONTROL_PROGRESS); @@ -675,6 +677,7 @@ static void handle_frame(struct ast_dial *dial, struct ast_dial_channel *channel } break; case AST_CONTROL_PROCEEDING: + ast_channel_publish_dial(chan, channel->owner, channel->device, "PROCEEDING"); if (chan) { ast_verb(3, "%s is proceeding, passing it to %s\n", ast_channel_name(channel->owner), ast_channel_name(chan)); ast_indicate(chan, AST_CONTROL_PROCEEDING); diff --git a/main/manager_channels.c b/main/manager_channels.c index c395708cc..ec1f807dc 100644 --- a/main/manager_channels.c +++ b/main/manager_channels.c @@ -142,6 +142,33 @@ ASTERISK_REGISTER_FILE() </see-also> </managerEventInstance> </managerEvent> + <managerEvent language="en_US" name="DialState"> + <managerEventInstance class="EVENT_FLAG_CALL"> + <synopsis>Raised when dial status has changed.</synopsis> + <syntax> + <channel_snapshot/> + <channel_snapshot prefix="Dest"/> + <parameter name="DialStatus"> + <para> The new state of the outbound dial attempt.</para> + <enumlist> + <enum name="RINGING"> + <para>The outbound channel is ringing.</para> + </enum> + <enum name="PROCEEDING"> + <para>The call to the outbound channel is proceeding.</para> + </enum> + <enum name="PROGRESS"> + <para>Progress has been received on the outbound channel.</para> + </enum> + </enumlist> + </parameter> + <parameter name="Forward" required="false"> + <para>If the call was forwarded, where the call was + forwarded to.</para> + </parameter> + </syntax> + </managerEventInstance> + </managerEvent> <managerEvent language="en_US" name="DialEnd"> <managerEventInstance class="EVENT_FLAG_CALL"> <synopsis>Raised when a dial action has completed.</synopsis> @@ -1034,6 +1061,13 @@ static void channel_monitor_stop_cb(void *data, struct stasis_subscription *sub, publish_basic_channel_event("MonitorStop", EVENT_FLAG_CALL, payload->snapshot); } +static int dial_status_end(const char *dialstatus) +{ + return (strcmp(dialstatus, "RINGING") && + strcmp(dialstatus, "PROCEEDING") && + strcmp(dialstatus, "PROGRESS")); +} + /*! * \brief Callback processing messages for channel dialing */ @@ -1077,7 +1111,7 @@ static void channel_dial_cb(void *data, struct stasis_subscription *sub, } else { int forwarded = !ast_strlen_zero(forward); - manager_event(EVENT_FLAG_CALL, "DialEnd", + manager_event(EVENT_FLAG_CALL, dial_status_end(dialstatus) ? "DialEnd" : "DialState", "%s" "%s" "%s%s%s" diff --git a/main/stasis_channels.c b/main/stasis_channels.c index e56d1b928..e1c50c6d0 100644 --- a/main/stasis_channels.c +++ b/main/stasis_channels.c @@ -362,7 +362,7 @@ static void ast_channel_publish_dial_internal(struct ast_channel *caller, return; } - publish_message_for_channel_topics(msg, caller); + publish_message_for_channel_topics(msg, caller ?: peer); } static void remove_dial_masquerade(struct ast_channel *peer); |