mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-03 11:25:35 +00:00
ari/pjsip: Make it possible to control transfers through ARI
Introduce a ChannelTransfer event and the ability to notify progress to
ARI. Implement emitting this event from the PJSIP channel instead of
handling the transfer in Asterisk when configured.
Introduce a dialplan function to the PJSIP channel to switch between the
"core" and "ari-only" behavior.
UserNote: Call transfers on the PJSIP channel can now be controlled by
ARI. This can be enabled by using the PJSIP_TRANSFER_HANDLING(ari-only)
dialplan function.
(cherry picked from commit 71eb8a262f
)
This commit is contained in:
committed by
Asterisk Development Team
parent
007e281313
commit
0e8bde6bde
@@ -2428,6 +2428,60 @@ ari_validator ast_ari_validate_mailbox_fn(void)
|
||||
return ast_ari_validate_mailbox;
|
||||
}
|
||||
|
||||
int ast_ari_validate_additional_param(struct ast_json *json)
|
||||
{
|
||||
int res = 1;
|
||||
struct ast_json_iter *iter;
|
||||
int has_parameter_name = 0;
|
||||
int has_parameter_value = 0;
|
||||
|
||||
for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) {
|
||||
if (strcmp("parameter_name", ast_json_object_iter_key(iter)) == 0) {
|
||||
int prop_is_valid;
|
||||
has_parameter_name = 1;
|
||||
prop_is_valid = ast_ari_validate_string(
|
||||
ast_json_object_iter_value(iter));
|
||||
if (!prop_is_valid) {
|
||||
ast_log(LOG_ERROR, "ARI AdditionalParam field parameter_name failed validation\n");
|
||||
res = 0;
|
||||
}
|
||||
} else
|
||||
if (strcmp("parameter_value", ast_json_object_iter_key(iter)) == 0) {
|
||||
int prop_is_valid;
|
||||
has_parameter_value = 1;
|
||||
prop_is_valid = ast_ari_validate_string(
|
||||
ast_json_object_iter_value(iter));
|
||||
if (!prop_is_valid) {
|
||||
ast_log(LOG_ERROR, "ARI AdditionalParam field parameter_value failed validation\n");
|
||||
res = 0;
|
||||
}
|
||||
} else
|
||||
{
|
||||
ast_log(LOG_ERROR,
|
||||
"ARI AdditionalParam has undocumented field %s\n",
|
||||
ast_json_object_iter_key(iter));
|
||||
res = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!has_parameter_name) {
|
||||
ast_log(LOG_ERROR, "ARI AdditionalParam missing required field parameter_name\n");
|
||||
res = 0;
|
||||
}
|
||||
|
||||
if (!has_parameter_value) {
|
||||
ast_log(LOG_ERROR, "ARI AdditionalParam missing required field parameter_value\n");
|
||||
res = 0;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
ari_validator ast_ari_validate_additional_param_fn(void)
|
||||
{
|
||||
return ast_ari_validate_additional_param;
|
||||
}
|
||||
|
||||
int ast_ari_validate_application_move_failed(struct ast_json *json)
|
||||
{
|
||||
int res = 1;
|
||||
@@ -4915,6 +4969,126 @@ ari_validator ast_ari_validate_channel_talking_started_fn(void)
|
||||
return ast_ari_validate_channel_talking_started;
|
||||
}
|
||||
|
||||
int ast_ari_validate_channel_transfer(struct ast_json *json)
|
||||
{
|
||||
int res = 1;
|
||||
struct ast_json_iter *iter;
|
||||
int has_type = 0;
|
||||
int has_application = 0;
|
||||
int has_timestamp = 0;
|
||||
int has_refer_to = 0;
|
||||
int has_referred_by = 0;
|
||||
|
||||
for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) {
|
||||
if (strcmp("asterisk_id", ast_json_object_iter_key(iter)) == 0) {
|
||||
int prop_is_valid;
|
||||
prop_is_valid = ast_ari_validate_string(
|
||||
ast_json_object_iter_value(iter));
|
||||
if (!prop_is_valid) {
|
||||
ast_log(LOG_ERROR, "ARI ChannelTransfer field asterisk_id failed validation\n");
|
||||
res = 0;
|
||||
}
|
||||
} else
|
||||
if (strcmp("type", ast_json_object_iter_key(iter)) == 0) {
|
||||
int prop_is_valid;
|
||||
has_type = 1;
|
||||
prop_is_valid = ast_ari_validate_string(
|
||||
ast_json_object_iter_value(iter));
|
||||
if (!prop_is_valid) {
|
||||
ast_log(LOG_ERROR, "ARI ChannelTransfer field type failed validation\n");
|
||||
res = 0;
|
||||
}
|
||||
} else
|
||||
if (strcmp("application", ast_json_object_iter_key(iter)) == 0) {
|
||||
int prop_is_valid;
|
||||
has_application = 1;
|
||||
prop_is_valid = ast_ari_validate_string(
|
||||
ast_json_object_iter_value(iter));
|
||||
if (!prop_is_valid) {
|
||||
ast_log(LOG_ERROR, "ARI ChannelTransfer field application failed validation\n");
|
||||
res = 0;
|
||||
}
|
||||
} else
|
||||
if (strcmp("timestamp", ast_json_object_iter_key(iter)) == 0) {
|
||||
int prop_is_valid;
|
||||
has_timestamp = 1;
|
||||
prop_is_valid = ast_ari_validate_date(
|
||||
ast_json_object_iter_value(iter));
|
||||
if (!prop_is_valid) {
|
||||
ast_log(LOG_ERROR, "ARI ChannelTransfer field timestamp failed validation\n");
|
||||
res = 0;
|
||||
}
|
||||
} else
|
||||
if (strcmp("refer_to", ast_json_object_iter_key(iter)) == 0) {
|
||||
int prop_is_valid;
|
||||
has_refer_to = 1;
|
||||
prop_is_valid = ast_ari_validate_refer_to(
|
||||
ast_json_object_iter_value(iter));
|
||||
if (!prop_is_valid) {
|
||||
ast_log(LOG_ERROR, "ARI ChannelTransfer field refer_to failed validation\n");
|
||||
res = 0;
|
||||
}
|
||||
} else
|
||||
if (strcmp("referred_by", ast_json_object_iter_key(iter)) == 0) {
|
||||
int prop_is_valid;
|
||||
has_referred_by = 1;
|
||||
prop_is_valid = ast_ari_validate_referred_by(
|
||||
ast_json_object_iter_value(iter));
|
||||
if (!prop_is_valid) {
|
||||
ast_log(LOG_ERROR, "ARI ChannelTransfer field referred_by failed validation\n");
|
||||
res = 0;
|
||||
}
|
||||
} else
|
||||
if (strcmp("state", ast_json_object_iter_key(iter)) == 0) {
|
||||
int prop_is_valid;
|
||||
prop_is_valid = ast_ari_validate_string(
|
||||
ast_json_object_iter_value(iter));
|
||||
if (!prop_is_valid) {
|
||||
ast_log(LOG_ERROR, "ARI ChannelTransfer field state failed validation\n");
|
||||
res = 0;
|
||||
}
|
||||
} else
|
||||
{
|
||||
ast_log(LOG_ERROR,
|
||||
"ARI ChannelTransfer has undocumented field %s\n",
|
||||
ast_json_object_iter_key(iter));
|
||||
res = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!has_type) {
|
||||
ast_log(LOG_ERROR, "ARI ChannelTransfer missing required field type\n");
|
||||
res = 0;
|
||||
}
|
||||
|
||||
if (!has_application) {
|
||||
ast_log(LOG_ERROR, "ARI ChannelTransfer missing required field application\n");
|
||||
res = 0;
|
||||
}
|
||||
|
||||
if (!has_timestamp) {
|
||||
ast_log(LOG_ERROR, "ARI ChannelTransfer missing required field timestamp\n");
|
||||
res = 0;
|
||||
}
|
||||
|
||||
if (!has_refer_to) {
|
||||
ast_log(LOG_ERROR, "ARI ChannelTransfer missing required field refer_to\n");
|
||||
res = 0;
|
||||
}
|
||||
|
||||
if (!has_referred_by) {
|
||||
ast_log(LOG_ERROR, "ARI ChannelTransfer missing required field referred_by\n");
|
||||
res = 0;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
ari_validator ast_ari_validate_channel_transfer_fn(void)
|
||||
{
|
||||
return ast_ari_validate_channel_transfer;
|
||||
}
|
||||
|
||||
int ast_ari_validate_channel_unhold(struct ast_json *json)
|
||||
{
|
||||
int res = 1;
|
||||
@@ -5876,6 +6050,9 @@ int ast_ari_validate_event(struct ast_json *json)
|
||||
if (strcmp("ChannelTalkingStarted", discriminator) == 0) {
|
||||
return ast_ari_validate_channel_talking_started(json);
|
||||
} else
|
||||
if (strcmp("ChannelTransfer", discriminator) == 0) {
|
||||
return ast_ari_validate_channel_transfer(json);
|
||||
} else
|
||||
if (strcmp("ChannelUnhold", discriminator) == 0) {
|
||||
return ast_ari_validate_channel_unhold(json);
|
||||
} else
|
||||
@@ -6083,6 +6260,9 @@ int ast_ari_validate_message(struct ast_json *json)
|
||||
if (strcmp("ChannelTalkingStarted", discriminator) == 0) {
|
||||
return ast_ari_validate_channel_talking_started(json);
|
||||
} else
|
||||
if (strcmp("ChannelTransfer", discriminator) == 0) {
|
||||
return ast_ari_validate_channel_transfer(json);
|
||||
} else
|
||||
if (strcmp("ChannelUnhold", discriminator) == 0) {
|
||||
return ast_ari_validate_channel_unhold(json);
|
||||
} else
|
||||
@@ -7006,6 +7186,177 @@ ari_validator ast_ari_validate_recording_started_fn(void)
|
||||
return ast_ari_validate_recording_started;
|
||||
}
|
||||
|
||||
int ast_ari_validate_refer_to(struct ast_json *json)
|
||||
{
|
||||
int res = 1;
|
||||
struct ast_json_iter *iter;
|
||||
int has_requested_destination = 0;
|
||||
|
||||
for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) {
|
||||
if (strcmp("bridge", ast_json_object_iter_key(iter)) == 0) {
|
||||
int prop_is_valid;
|
||||
prop_is_valid = ast_ari_validate_bridge(
|
||||
ast_json_object_iter_value(iter));
|
||||
if (!prop_is_valid) {
|
||||
ast_log(LOG_ERROR, "ARI ReferTo field bridge failed validation\n");
|
||||
res = 0;
|
||||
}
|
||||
} else
|
||||
if (strcmp("connected_channel", ast_json_object_iter_key(iter)) == 0) {
|
||||
int prop_is_valid;
|
||||
prop_is_valid = ast_ari_validate_channel(
|
||||
ast_json_object_iter_value(iter));
|
||||
if (!prop_is_valid) {
|
||||
ast_log(LOG_ERROR, "ARI ReferTo field connected_channel failed validation\n");
|
||||
res = 0;
|
||||
}
|
||||
} else
|
||||
if (strcmp("destination_channel", ast_json_object_iter_key(iter)) == 0) {
|
||||
int prop_is_valid;
|
||||
prop_is_valid = ast_ari_validate_channel(
|
||||
ast_json_object_iter_value(iter));
|
||||
if (!prop_is_valid) {
|
||||
ast_log(LOG_ERROR, "ARI ReferTo field destination_channel failed validation\n");
|
||||
res = 0;
|
||||
}
|
||||
} else
|
||||
if (strcmp("requested_destination", ast_json_object_iter_key(iter)) == 0) {
|
||||
int prop_is_valid;
|
||||
has_requested_destination = 1;
|
||||
prop_is_valid = ast_ari_validate_required_destination(
|
||||
ast_json_object_iter_value(iter));
|
||||
if (!prop_is_valid) {
|
||||
ast_log(LOG_ERROR, "ARI ReferTo field requested_destination failed validation\n");
|
||||
res = 0;
|
||||
}
|
||||
} else
|
||||
{
|
||||
ast_log(LOG_ERROR,
|
||||
"ARI ReferTo has undocumented field %s\n",
|
||||
ast_json_object_iter_key(iter));
|
||||
res = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!has_requested_destination) {
|
||||
ast_log(LOG_ERROR, "ARI ReferTo missing required field requested_destination\n");
|
||||
res = 0;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
ari_validator ast_ari_validate_refer_to_fn(void)
|
||||
{
|
||||
return ast_ari_validate_refer_to;
|
||||
}
|
||||
|
||||
int ast_ari_validate_referred_by(struct ast_json *json)
|
||||
{
|
||||
int res = 1;
|
||||
struct ast_json_iter *iter;
|
||||
int has_source_channel = 0;
|
||||
|
||||
for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) {
|
||||
if (strcmp("bridge", ast_json_object_iter_key(iter)) == 0) {
|
||||
int prop_is_valid;
|
||||
prop_is_valid = ast_ari_validate_bridge(
|
||||
ast_json_object_iter_value(iter));
|
||||
if (!prop_is_valid) {
|
||||
ast_log(LOG_ERROR, "ARI ReferredBy field bridge failed validation\n");
|
||||
res = 0;
|
||||
}
|
||||
} else
|
||||
if (strcmp("connected_channel", ast_json_object_iter_key(iter)) == 0) {
|
||||
int prop_is_valid;
|
||||
prop_is_valid = ast_ari_validate_channel(
|
||||
ast_json_object_iter_value(iter));
|
||||
if (!prop_is_valid) {
|
||||
ast_log(LOG_ERROR, "ARI ReferredBy field connected_channel failed validation\n");
|
||||
res = 0;
|
||||
}
|
||||
} else
|
||||
if (strcmp("source_channel", ast_json_object_iter_key(iter)) == 0) {
|
||||
int prop_is_valid;
|
||||
has_source_channel = 1;
|
||||
prop_is_valid = ast_ari_validate_channel(
|
||||
ast_json_object_iter_value(iter));
|
||||
if (!prop_is_valid) {
|
||||
ast_log(LOG_ERROR, "ARI ReferredBy field source_channel failed validation\n");
|
||||
res = 0;
|
||||
}
|
||||
} else
|
||||
{
|
||||
ast_log(LOG_ERROR,
|
||||
"ARI ReferredBy has undocumented field %s\n",
|
||||
ast_json_object_iter_key(iter));
|
||||
res = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!has_source_channel) {
|
||||
ast_log(LOG_ERROR, "ARI ReferredBy missing required field source_channel\n");
|
||||
res = 0;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
ari_validator ast_ari_validate_referred_by_fn(void)
|
||||
{
|
||||
return ast_ari_validate_referred_by;
|
||||
}
|
||||
|
||||
int ast_ari_validate_required_destination(struct ast_json *json)
|
||||
{
|
||||
int res = 1;
|
||||
struct ast_json_iter *iter;
|
||||
|
||||
for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) {
|
||||
if (strcmp("additional_protocol_params", ast_json_object_iter_key(iter)) == 0) {
|
||||
int prop_is_valid;
|
||||
prop_is_valid = ast_ari_validate_list(
|
||||
ast_json_object_iter_value(iter),
|
||||
ast_ari_validate_additional_param);
|
||||
if (!prop_is_valid) {
|
||||
ast_log(LOG_ERROR, "ARI RequiredDestination field additional_protocol_params failed validation\n");
|
||||
res = 0;
|
||||
}
|
||||
} else
|
||||
if (strcmp("destination", ast_json_object_iter_key(iter)) == 0) {
|
||||
int prop_is_valid;
|
||||
prop_is_valid = ast_ari_validate_string(
|
||||
ast_json_object_iter_value(iter));
|
||||
if (!prop_is_valid) {
|
||||
ast_log(LOG_ERROR, "ARI RequiredDestination field destination failed validation\n");
|
||||
res = 0;
|
||||
}
|
||||
} else
|
||||
if (strcmp("protocol_id", ast_json_object_iter_key(iter)) == 0) {
|
||||
int prop_is_valid;
|
||||
prop_is_valid = ast_ari_validate_string(
|
||||
ast_json_object_iter_value(iter));
|
||||
if (!prop_is_valid) {
|
||||
ast_log(LOG_ERROR, "ARI RequiredDestination field protocol_id failed validation\n");
|
||||
res = 0;
|
||||
}
|
||||
} else
|
||||
{
|
||||
ast_log(LOG_ERROR,
|
||||
"ARI RequiredDestination has undocumented field %s\n",
|
||||
ast_json_object_iter_key(iter));
|
||||
res = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
ari_validator ast_ari_validate_required_destination_fn(void)
|
||||
{
|
||||
return ast_ari_validate_required_destination;
|
||||
}
|
||||
|
||||
int ast_ari_validate_stasis_end(struct ast_json *json)
|
||||
{
|
||||
int res = 1;
|
||||
|
@@ -571,6 +571,22 @@ int ast_ari_validate_mailbox(struct ast_json *json);
|
||||
*/
|
||||
ari_validator ast_ari_validate_mailbox_fn(void);
|
||||
|
||||
/*!
|
||||
* \brief Validator for AdditionalParam.
|
||||
*
|
||||
* Protocol specific additional parameter
|
||||
*
|
||||
* \param json JSON object to validate.
|
||||
* \retval True (non-zero) if valid.
|
||||
* \retval False (zero) if invalid.
|
||||
*/
|
||||
int ast_ari_validate_additional_param(struct ast_json *json);
|
||||
|
||||
/*!
|
||||
* \brief Function pointer to ast_ari_validate_additional_param().
|
||||
*/
|
||||
ari_validator ast_ari_validate_additional_param_fn(void);
|
||||
|
||||
/*!
|
||||
* \brief Validator for ApplicationMoveFailed.
|
||||
*
|
||||
@@ -911,6 +927,22 @@ int ast_ari_validate_channel_talking_started(struct ast_json *json);
|
||||
*/
|
||||
ari_validator ast_ari_validate_channel_talking_started_fn(void);
|
||||
|
||||
/*!
|
||||
* \brief Validator for ChannelTransfer.
|
||||
*
|
||||
* transfer on a channel.
|
||||
*
|
||||
* \param json JSON object to validate.
|
||||
* \retval True (non-zero) if valid.
|
||||
* \retval False (zero) if invalid.
|
||||
*/
|
||||
int ast_ari_validate_channel_transfer(struct ast_json *json);
|
||||
|
||||
/*!
|
||||
* \brief Function pointer to ast_ari_validate_channel_transfer().
|
||||
*/
|
||||
ari_validator ast_ari_validate_channel_transfer_fn(void);
|
||||
|
||||
/*!
|
||||
* \brief Validator for ChannelUnhold.
|
||||
*
|
||||
@@ -1215,6 +1247,54 @@ int ast_ari_validate_recording_started(struct ast_json *json);
|
||||
*/
|
||||
ari_validator ast_ari_validate_recording_started_fn(void);
|
||||
|
||||
/*!
|
||||
* \brief Validator for ReferTo.
|
||||
*
|
||||
* transfer destination requested by transferee
|
||||
*
|
||||
* \param json JSON object to validate.
|
||||
* \retval True (non-zero) if valid.
|
||||
* \retval False (zero) if invalid.
|
||||
*/
|
||||
int ast_ari_validate_refer_to(struct ast_json *json);
|
||||
|
||||
/*!
|
||||
* \brief Function pointer to ast_ari_validate_refer_to().
|
||||
*/
|
||||
ari_validator ast_ari_validate_refer_to_fn(void);
|
||||
|
||||
/*!
|
||||
* \brief Validator for ReferredBy.
|
||||
*
|
||||
* transfer destination requested by transferee
|
||||
*
|
||||
* \param json JSON object to validate.
|
||||
* \retval True (non-zero) if valid.
|
||||
* \retval False (zero) if invalid.
|
||||
*/
|
||||
int ast_ari_validate_referred_by(struct ast_json *json);
|
||||
|
||||
/*!
|
||||
* \brief Function pointer to ast_ari_validate_referred_by().
|
||||
*/
|
||||
ari_validator ast_ari_validate_referred_by_fn(void);
|
||||
|
||||
/*!
|
||||
* \brief Validator for RequiredDestination.
|
||||
*
|
||||
* Information about the requested destination
|
||||
*
|
||||
* \param json JSON object to validate.
|
||||
* \retval True (non-zero) if valid.
|
||||
* \retval False (zero) if invalid.
|
||||
*/
|
||||
int ast_ari_validate_required_destination(struct ast_json *json);
|
||||
|
||||
/*!
|
||||
* \brief Function pointer to ast_ari_validate_required_destination().
|
||||
*/
|
||||
ari_validator ast_ari_validate_required_destination_fn(void);
|
||||
|
||||
/*!
|
||||
* \brief Validator for StasisEnd.
|
||||
*
|
||||
@@ -1441,6 +1521,9 @@ ari_validator ast_ari_validate_application_fn(void);
|
||||
* - name: string (required)
|
||||
* - new_messages: int (required)
|
||||
* - old_messages: int (required)
|
||||
* AdditionalParam
|
||||
* - parameter_name: string (required)
|
||||
* - parameter_value: string (required)
|
||||
* ApplicationMoveFailed
|
||||
* - asterisk_id: string
|
||||
* - type: string (required)
|
||||
@@ -1606,6 +1689,14 @@ ari_validator ast_ari_validate_application_fn(void);
|
||||
* - application: string (required)
|
||||
* - timestamp: Date (required)
|
||||
* - channel: Channel (required)
|
||||
* ChannelTransfer
|
||||
* - asterisk_id: string
|
||||
* - type: string (required)
|
||||
* - application: string (required)
|
||||
* - timestamp: Date (required)
|
||||
* - refer_to: ReferTo (required)
|
||||
* - referred_by: ReferredBy (required)
|
||||
* - state: string
|
||||
* ChannelUnhold
|
||||
* - asterisk_id: string
|
||||
* - type: string (required)
|
||||
@@ -1726,6 +1817,19 @@ ari_validator ast_ari_validate_application_fn(void);
|
||||
* - application: string (required)
|
||||
* - timestamp: Date (required)
|
||||
* - recording: LiveRecording (required)
|
||||
* ReferTo
|
||||
* - bridge: Bridge
|
||||
* - connected_channel: Channel
|
||||
* - destination_channel: Channel
|
||||
* - requested_destination: RequiredDestination (required)
|
||||
* ReferredBy
|
||||
* - bridge: Bridge
|
||||
* - connected_channel: Channel
|
||||
* - source_channel: Channel (required)
|
||||
* RequiredDestination
|
||||
* - additional_protocol_params: List[AdditionalParam]
|
||||
* - destination: string
|
||||
* - protocol_id: string
|
||||
* StasisEnd
|
||||
* - asterisk_id: string
|
||||
* - type: string (required)
|
||||
|
@@ -2252,3 +2252,44 @@ void ast_ari_channels_external_media(struct ast_variable *headers,
|
||||
"The encapsulation and/or transport is not supported");
|
||||
}
|
||||
}
|
||||
|
||||
void ast_ari_channels_transfer_progress(struct ast_variable *headers, struct ast_ari_channels_transfer_progress_args *args, struct ast_ari_response *response)
|
||||
{
|
||||
enum ast_control_transfer message;
|
||||
RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup);
|
||||
RAII_VAR(struct ast_channel *, chan, NULL, ast_channel_cleanup);
|
||||
|
||||
control = find_control(response, args->channel_id);
|
||||
if (control == NULL) {
|
||||
/* Response filled in by find_control */
|
||||
return;
|
||||
}
|
||||
|
||||
chan = ast_channel_get_by_name(args->channel_id);
|
||||
if (!chan) {
|
||||
ast_ari_response_error(response, 404, "Not Found",
|
||||
"Callee not found");
|
||||
return;
|
||||
}
|
||||
|
||||
if (ast_strlen_zero(args->states)) {
|
||||
ast_ari_response_error(response, 400, "Bad Request", "states must not be empty");
|
||||
return;
|
||||
}
|
||||
|
||||
if (strcasecmp(args->states, "channel_progress") == 0) {
|
||||
message = AST_TRANSFER_PROGRESS;
|
||||
} else if (strcasecmp(args->states, "channel_answered") == 0) {
|
||||
message = AST_TRANSFER_SUCCESS;
|
||||
} else if (strcasecmp(args->states, "channel_unavailable") == 0) {
|
||||
message = AST_TRANSFER_UNAVAILABLE;
|
||||
} else if (strcasecmp(args->states, "channel_declined") == 0) {
|
||||
message = AST_TRANSFER_FAILED;
|
||||
} else {
|
||||
ast_ari_response_error(response, 400, "Bad Request", "Invalid states value");
|
||||
return;
|
||||
}
|
||||
|
||||
ast_indicate_data(chan, AST_CONTROL_TRANSFER, &message, sizeof(message));
|
||||
ast_ari_response_no_content(response);
|
||||
}
|
||||
|
@@ -870,5 +870,31 @@ int ast_ari_channels_external_media_parse_body(
|
||||
* \param[out] response HTTP response
|
||||
*/
|
||||
void ast_ari_channels_external_media(struct ast_variable *headers, struct ast_ari_channels_external_media_args *args, struct ast_ari_response *response);
|
||||
/*! Argument struct for ast_ari_channels_transfer_progress() */
|
||||
struct ast_ari_channels_transfer_progress_args {
|
||||
/*! Channel's id */
|
||||
const char *channel_id;
|
||||
/*! The state of the progress */
|
||||
const char *states;
|
||||
};
|
||||
/*!
|
||||
* \brief Body parsing function for /channels/{channelId}/transfer_progress.
|
||||
* \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_transfer_progress_parse_body(
|
||||
struct ast_json *body,
|
||||
struct ast_ari_channels_transfer_progress_args *args);
|
||||
|
||||
/*!
|
||||
* \brief Inform the channel about the progress of the attended/blind transfer.
|
||||
*
|
||||
* \param headers HTTP headers
|
||||
* \param args Swagger parameters
|
||||
* \param[out] response HTTP response
|
||||
*/
|
||||
void ast_ari_channels_transfer_progress(struct ast_variable *headers, struct ast_ari_channels_transfer_progress_args *args, struct ast_ari_response *response);
|
||||
|
||||
#endif /* _ASTERISK_RESOURCE_CHANNELS_H */
|
||||
|
Reference in New Issue
Block a user