diff options
author | Mark Michelson <mmichelson@digium.com> | 2016-03-30 17:18:39 -0500 |
---|---|---|
committer | Joshua Colp <jcolp@digium.com> | 2016-04-05 18:14:17 -0500 |
commit | abbb2edd4c897fc3ac8a3589c5b799ff53ed10d2 (patch) | |
tree | 331914612f6d23a58a720f008065256b90c96a99 /res/ari | |
parent | dd48d60c5ba239f76b054b1bb6c1e17c68537497 (diff) |
ARI: Add method to Dial a created channel.
This adds a new ARI method that allows for you to dial a channel that
you previously created in ARI.
By combining this with the create method for channels, it allows for a
workflow where a channel can be created, manipulated, and then dialed.
The channel is under control of the ARI application during all stages of
the Dial and can even be manipulated based on channel state changes
observed within an ARI application.
The overarching goal for this is to eventually be able to add a dialed
channel to a Stasis bridge earlier than the "Up" state. However, at the
moment more work is needed in the Dial and Bridge APIs in order to
facilitate that.
ASTERISK-25889 #close
Change-Id: Ic6c399c791e66c4aa52454222fe4f8b02483a205
Diffstat (limited to 'res/ari')
-rw-r--r-- | res/ari/resource_channels.c | 68 | ||||
-rw-r--r-- | res/ari/resource_channels.h | 28 |
2 files changed, 96 insertions, 0 deletions
diff --git a/res/ari/resource_channels.c b/res/ari/resource_channels.c index 1954d6bf9..c838bc39c 100644 --- a/res/ari/resource_channels.c +++ b/res/ari/resource_channels.c @@ -1570,3 +1570,71 @@ void ast_ari_channels_create(struct ast_variable *headers, ao2_ref(snapshot, -1); } + +void ast_ari_channels_dial(struct ast_variable *headers, + struct ast_ari_channels_dial_args *args, + struct ast_ari_response *response) +{ + RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup); + RAII_VAR(struct ast_channel *, caller, NULL, ast_channel_cleanup); + struct ast_channel *callee; + struct ast_dial *dial; + + control = find_control(response, args->channel_id); + if (control == NULL) { + /* Response filled in by find_control */ + return; + } + + caller = ast_channel_get_by_name(args->caller); + + callee = ast_channel_get_by_name(args->channel_id); + if (!callee) { + ast_ari_response_error(response, 404, "Not Found", + "Callee not found"); + return; + } + + if (ast_channel_state(callee) != AST_STATE_DOWN) { + ast_channel_unref(callee); + ast_ari_response_error(response, 409, "Conflict", + "Channel is not in the 'Down' state"); + return; + } + + dial = ast_dial_create(); + if (!dial) { + ast_channel_unref(callee); + ast_ari_response_alloc_failed(response); + return; + } + + if (ast_dial_append_channel(dial, callee) < 0) { + ast_channel_unref(callee); + ast_dial_destroy(dial); + ast_ari_response_alloc_failed(response); + return; + } + + /* From this point, we don't have to unref the callee channel on + * failure paths because the dial owns the reference to the called + * channel and will unref the channel for us + */ + + if (ast_dial_prerun(dial, caller, NULL)) { + ast_dial_destroy(dial); + ast_ari_response_alloc_failed(response); + return; + } + + ast_dial_set_user_data(dial, control); + ast_dial_set_global_timeout(dial, args->timeout * 1000); + + if (stasis_app_control_dial(control, dial)) { + ast_dial_destroy(dial); + ast_ari_response_alloc_failed(response); + return; + } + + ast_ari_response_no_content(response); +} diff --git a/res/ari/resource_channels.h b/res/ari/resource_channels.h index bd34e0673..89b466d00 100644 --- a/res/ari/resource_channels.h +++ b/res/ari/resource_channels.h @@ -739,5 +739,33 @@ int ast_ari_channels_snoop_channel_with_id_parse_body( * \param[out] response HTTP response */ void ast_ari_channels_snoop_channel_with_id(struct ast_variable *headers, struct ast_ari_channels_snoop_channel_with_id_args *args, struct ast_ari_response *response); +/*! Argument struct for ast_ari_channels_dial() */ +struct ast_ari_channels_dial_args { + /*! Channel's id */ + const char *channel_id; + /*! Channel ID of caller */ + const char *caller; + /*! Dial timeout */ + int timeout; +}; +/*! + * \brief Body parsing function for /channels/{channelId}/dial. + * \param body The JSON body from which to parse parameters. + * \param[out] args The args structure to parse into. + * \retval zero on success + * \retval non-zero on failure + */ +int ast_ari_channels_dial_parse_body( + struct ast_json *body, + struct ast_ari_channels_dial_args *args); + +/*! + * \brief Dial a created channel. + * + * \param headers HTTP headers + * \param args Swagger parameters + * \param[out] response HTTP response + */ +void ast_ari_channels_dial(struct ast_variable *headers, struct ast_ari_channels_dial_args *args, struct ast_ari_response *response); #endif /* _ASTERISK_RESOURCE_CHANNELS_H */ |