mirror of
https://github.com/asterisk/asterisk.git
synced 2025-10-12 15:45:18 +00:00
ARI: Re-implement the ARI dial command, allowing for early bridging.
ARI dial had been implemented using the Dial API. This made great sense when dialing was 100% separate from bridging. However, if a channel were to be added to a bridge during the dial attempt, there would be a conflict between the dialing thread and the bridging thread. Each would be attempting to read frames from the dialed channel and act on them. The initial attempt to make the two play nice was to have the Dial API suspend the channel in the bridge and stay in charge of the channel until the dial was complete. The problem with this was that it was riddled with potential race conditions. It also was not well-suited for the case where the channel changed which bridge it was in during the dial. This new approach removes the use of the Dial API altogether. Instead, the channel we are dialing is placed into an invisible ARI dialing bridge. The bridge channel thread handles incoming frames from the channel. If the channel is added to a real bridge, it is departed from the invisible bridge and then added to the real bridge. Similarly, if the channel is removed from the real bridge, it is automatically added back to the invisible bridge if the dial attempt is still active. This approach keeps the threading simple by always having the channel being handled by bridge channel threads. ASTERISK-25925 Change-Id: I7750359ddf45fcd45eaec749c5b3822de4a8ddbb
This commit is contained in:
@@ -749,7 +749,7 @@ static void control_unlink(struct stasis_app_control *control)
|
||||
ao2_cleanup(control);
|
||||
}
|
||||
|
||||
struct ast_bridge *stasis_app_bridge_create(const char *type, const char *name, const char *id)
|
||||
static struct ast_bridge *bridge_create_common(const char *type, const char *name, const char *id, int invisible)
|
||||
{
|
||||
struct ast_bridge *bridge;
|
||||
char *requested_type, *requested_types = ast_strdupa(S_OR(type, "mixing"));
|
||||
@@ -758,6 +758,10 @@ struct ast_bridge *stasis_app_bridge_create(const char *type, const char *name,
|
||||
| AST_BRIDGE_FLAG_SWAP_INHIBIT_FROM | AST_BRIDGE_FLAG_SWAP_INHIBIT_TO
|
||||
| AST_BRIDGE_FLAG_TRANSFER_BRIDGE_ONLY;
|
||||
|
||||
if (invisible) {
|
||||
flags |= AST_BRIDGE_FLAG_INVISIBLE;
|
||||
}
|
||||
|
||||
while ((requested_type = strsep(&requested_types, ","))) {
|
||||
requested_type = ast_strip(requested_type);
|
||||
|
||||
@@ -789,6 +793,16 @@ struct ast_bridge *stasis_app_bridge_create(const char *type, const char *name,
|
||||
return bridge;
|
||||
}
|
||||
|
||||
struct ast_bridge *stasis_app_bridge_create(const char *type, const char *name, const char *id)
|
||||
{
|
||||
return bridge_create_common(type, name, id, 0);
|
||||
}
|
||||
|
||||
struct ast_bridge *stasis_app_bridge_create_invisible(const char *type, const char *name, const char *id)
|
||||
{
|
||||
return bridge_create_common(type, name, id, 1);
|
||||
}
|
||||
|
||||
void stasis_app_bridge_destroy(const char *bridge_id)
|
||||
{
|
||||
struct ast_bridge *bridge = stasis_app_bridge_find_by_id(bridge_id);
|
||||
@@ -1287,7 +1301,6 @@ int stasis_app_exec(struct ast_channel *chan, const char *app_name, int argc,
|
||||
int r;
|
||||
int command_count;
|
||||
RAII_VAR(struct ast_bridge *, last_bridge, NULL, ao2_cleanup);
|
||||
struct ast_dial *dial;
|
||||
|
||||
/* Check to see if a bridge absorbed our hangup frame */
|
||||
if (ast_check_hangup_locked(chan)) {
|
||||
@@ -1297,7 +1310,6 @@ int stasis_app_exec(struct ast_channel *chan, const char *app_name, int argc,
|
||||
|
||||
last_bridge = bridge;
|
||||
bridge = ao2_bump(stasis_app_get_bridge(control));
|
||||
dial = stasis_app_get_dial(control);
|
||||
|
||||
if (bridge != last_bridge) {
|
||||
app_unsubscribe_bridge(app, last_bridge);
|
||||
@@ -1306,7 +1318,7 @@ int stasis_app_exec(struct ast_channel *chan, const char *app_name, int argc,
|
||||
}
|
||||
}
|
||||
|
||||
if (bridge || dial) {
|
||||
if (bridge) {
|
||||
/* Bridge/dial is handling channel frames */
|
||||
control_wait(control);
|
||||
control_dispatch_all(control, chan);
|
||||
@@ -1951,6 +1963,8 @@ static int unload_module(void)
|
||||
ao2_cleanup(app_bridges_playback);
|
||||
app_bridges_playback = NULL;
|
||||
|
||||
stasis_app_control_shutdown();
|
||||
|
||||
STASIS_MESSAGE_TYPE_CLEANUP(end_message_type);
|
||||
STASIS_MESSAGE_TYPE_CLEANUP(start_message_type);
|
||||
|
||||
|
Reference in New Issue
Block a user