mirror of
https://github.com/asterisk/asterisk.git
synced 2025-10-12 15:45:18 +00:00
Merge "ari/resource_channels: Add 'formats' to channel create/originate"
This commit is contained in:
12
CHANGES
12
CHANGES
@@ -395,6 +395,18 @@ app_confbridge
|
||||
server installations via alternate means (DUNDI for example). By default
|
||||
this feature is not used.
|
||||
|
||||
Codecs
|
||||
------------------
|
||||
* Added the associated format name to 'core show codecs'.
|
||||
|
||||
res_ari_channels
|
||||
------------------
|
||||
* Added 'formats' to channel create/originate to allow setting the allowed
|
||||
formats for a channel when no originator channel is available. Especially
|
||||
useful for Local channel creation where no other format information is
|
||||
available. 'core show codecs' can now be used to look up suitable format
|
||||
names.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
--- Functionality changes from Asterisk 13.8.0 to Asterisk 13.9.0 ------------
|
||||
------------------------------------------------------------------------------
|
||||
|
@@ -77,6 +77,8 @@ struct ast_codec {
|
||||
unsigned int smooth;
|
||||
/*! \brief The module that registered this codec */
|
||||
struct ast_module *mod;
|
||||
/*! \brief A format name for a default sane format using this codec */
|
||||
const char *format_name;
|
||||
};
|
||||
|
||||
/*!
|
||||
|
10
main/codec.c
10
main/codec.c
@@ -135,8 +135,8 @@ static char *show_codecs(struct ast_cli_entry *e, int cmd, struct ast_cli_args *
|
||||
"\tIt does not indicate anything about your configuration.\n");
|
||||
}
|
||||
|
||||
ast_cli(a->fd, "%8s %5s %8s %s\n","ID","TYPE","NAME","DESCRIPTION");
|
||||
ast_cli(a->fd, "-----------------------------------------------------------------------------------\n");
|
||||
ast_cli(a->fd, "%8s %-5s %-12s %-16s %s\n","ID","TYPE","NAME","FORMAT","DESCRIPTION");
|
||||
ast_cli(a->fd, "------------------------------------------------------------------------------------------------\n");
|
||||
|
||||
ao2_rdlock(codecs);
|
||||
i = ao2_iterator_init(codecs, AO2_ITERATOR_DONTLOCK);
|
||||
@@ -164,10 +164,11 @@ static char *show_codecs(struct ast_cli_entry *e, int cmd, struct ast_cli_args *
|
||||
}
|
||||
}
|
||||
|
||||
ast_cli(a->fd, "%8u %5s %8s (%s)\n",
|
||||
ast_cli(a->fd, "%8u %-5s %-12s %-16s (%s)\n",
|
||||
codec->id,
|
||||
ast_codec_media_type2str(codec->type),
|
||||
codec->name,
|
||||
S_OR(codec->format_name, "no cached format"),
|
||||
codec->description);
|
||||
}
|
||||
|
||||
@@ -216,7 +217,8 @@ static char *show_codec(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a
|
||||
return CLI_SUCCESS;
|
||||
}
|
||||
|
||||
ast_cli(a->fd, "%11u %s\n", (unsigned int) codec->id, codec->description);
|
||||
ast_cli(a->fd, "%11u %s (%s)\n", (unsigned int) codec->id, codec->description,
|
||||
S_OR(codec->format_name, "no format"));
|
||||
|
||||
ao2_ref(codec, -1);
|
||||
|
||||
|
@@ -774,6 +774,7 @@ static struct ast_codec t140 = {
|
||||
int __res_ ## __LINE__ = 0; \
|
||||
struct ast_format *__fmt_ ## __LINE__; \
|
||||
struct ast_codec *__codec_ ## __LINE__; \
|
||||
codec.format_name = (codec).name; \
|
||||
res |= __ast_codec_register(&(codec), NULL); \
|
||||
__codec_ ## __LINE__ = ast_codec_get((codec).name, (codec).type, (codec).sample_rate); \
|
||||
__fmt_ ## __LINE__ = __codec_ ## __LINE__ ? ast_format_create(__codec_ ## __LINE__) : NULL; \
|
||||
@@ -783,14 +784,15 @@ static struct ast_codec t140 = {
|
||||
__res_ ## __LINE__; \
|
||||
})
|
||||
|
||||
#define CODEC_REGISTER_AND_CACHE_NAMED(format_name, codec) \
|
||||
#define CODEC_REGISTER_AND_CACHE_NAMED(fmt_name, codec) \
|
||||
({ \
|
||||
int __res_ ## __LINE__ = 0; \
|
||||
struct ast_format *__fmt_ ## __LINE__; \
|
||||
struct ast_codec *__codec_ ## __LINE__; \
|
||||
codec.format_name = fmt_name; \
|
||||
res |= __ast_codec_register(&(codec), NULL); \
|
||||
__codec_ ## __LINE__ = ast_codec_get((codec).name, (codec).type, (codec).sample_rate); \
|
||||
__fmt_ ## __LINE__ = ast_format_create_named((format_name), __codec_ ## __LINE__); \
|
||||
__fmt_ ## __LINE__ = ast_format_create_named((fmt_name), __codec_ ## __LINE__); \
|
||||
res |= ast_format_cache_set(__fmt_ ## __LINE__); \
|
||||
ao2_ref(__fmt_ ## __LINE__, -1); \
|
||||
ao2_ref(__codec_ ## __LINE__, -1); \
|
||||
|
@@ -916,6 +916,7 @@ static void ari_channels_handle_originate_with_id(const char *args_endpoint,
|
||||
const char *args_channel_id,
|
||||
const char *args_other_channel_id,
|
||||
const char *args_originator,
|
||||
const char *args_formats,
|
||||
struct ast_ari_response *response)
|
||||
{
|
||||
char *dialtech;
|
||||
@@ -934,6 +935,7 @@ static void ari_channels_handle_originate_with_id(const char *args_endpoint,
|
||||
};
|
||||
struct ari_origination *origination;
|
||||
pthread_t thread;
|
||||
struct ast_format_cap *format_cap = NULL;
|
||||
|
||||
if ((assignedids.uniqueid && AST_MAX_PUBLIC_UNIQUEID < strlen(assignedids.uniqueid))
|
||||
|| (assignedids.uniqueid2 && AST_MAX_PUBLIC_UNIQUEID < strlen(assignedids.uniqueid2))) {
|
||||
@@ -948,6 +950,12 @@ static void ari_channels_handle_originate_with_id(const char *args_endpoint,
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ast_strlen_zero(args_originator) && !ast_strlen_zero(args_formats)) {
|
||||
ast_ari_response_error(response, 400, "Bad Request",
|
||||
"Originator and formats can't both be specified");
|
||||
return;
|
||||
}
|
||||
|
||||
dialtech = ast_strdupa(args_endpoint);
|
||||
if ((stuff = strchr(dialtech, '/'))) {
|
||||
*stuff++ = '\0';
|
||||
@@ -1070,7 +1078,41 @@ static void ari_channels_handle_originate_with_id(const char *args_endpoint,
|
||||
}
|
||||
}
|
||||
|
||||
if (ast_dial_prerun(dial, other, NULL)) {
|
||||
if (!ast_strlen_zero(args_formats)) {
|
||||
char *format_name;
|
||||
char *formats_copy = ast_strdupa(args_formats);
|
||||
|
||||
if (!(format_cap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT))) {
|
||||
ast_ari_response_alloc_failed(response);
|
||||
ast_dial_destroy(dial);
|
||||
ast_free(origination);
|
||||
ast_channel_cleanup(other);
|
||||
return;
|
||||
}
|
||||
|
||||
while ((format_name = ast_strip(strsep(&formats_copy, ",")))) {
|
||||
struct ast_format *fmt = ast_format_cache_get(format_name);
|
||||
|
||||
if (!fmt || ast_format_cap_append(format_cap, fmt, 0)) {
|
||||
if (!fmt) {
|
||||
ast_ari_response_error(
|
||||
response, 400, "Bad Request",
|
||||
"Provided format (%s) was not found", format_name);
|
||||
} else {
|
||||
ast_ari_response_alloc_failed(response);
|
||||
}
|
||||
ast_dial_destroy(dial);
|
||||
ast_free(origination);
|
||||
ast_channel_cleanup(other);
|
||||
ao2_ref(format_cap, -1);
|
||||
ao2_cleanup(fmt);
|
||||
return;
|
||||
}
|
||||
ao2_ref(fmt, -1);
|
||||
}
|
||||
}
|
||||
|
||||
if (ast_dial_prerun(dial, other, format_cap)) {
|
||||
ast_ari_response_alloc_failed(response);
|
||||
ast_dial_destroy(dial);
|
||||
ast_free(origination);
|
||||
@@ -1079,6 +1121,7 @@ static void ari_channels_handle_originate_with_id(const char *args_endpoint,
|
||||
}
|
||||
|
||||
ast_channel_cleanup(other);
|
||||
ao2_cleanup(format_cap);
|
||||
|
||||
chan = ast_dial_get_channel(dial, 0);
|
||||
if (!chan) {
|
||||
@@ -1219,6 +1262,7 @@ void ast_ari_channels_originate_with_id(struct ast_variable *headers,
|
||||
args->channel_id,
|
||||
args->other_channel_id,
|
||||
args->originator,
|
||||
args->formats,
|
||||
response);
|
||||
ast_variables_destroy(variables);
|
||||
}
|
||||
@@ -1255,6 +1299,7 @@ void ast_ari_channels_originate(struct ast_variable *headers,
|
||||
args->channel_id,
|
||||
args->other_channel_id,
|
||||
args->originator,
|
||||
args->formats,
|
||||
response);
|
||||
ast_variables_destroy(variables);
|
||||
}
|
||||
@@ -1589,6 +1634,12 @@ void ast_ari_channels_create(struct ast_variable *headers,
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ast_strlen_zero(args->originator) && !ast_strlen_zero(args->formats)) {
|
||||
ast_ari_response_error(response, 400, "Bad Request",
|
||||
"Originator and formats can't both be specified");
|
||||
return;
|
||||
}
|
||||
|
||||
chan_data->stasis_stuff = ast_str_create(32);
|
||||
if (!chan_data->stasis_stuff) {
|
||||
ast_ari_response_alloc_failed(response);
|
||||
@@ -1610,8 +1661,41 @@ void ast_ari_channels_create(struct ast_variable *headers,
|
||||
originator = ast_channel_get_by_name(args->originator);
|
||||
if (originator) {
|
||||
request_cap = ao2_bump(ast_channel_nativeformats(originator));
|
||||
} else if (!ast_strlen_zero(args->formats)) {
|
||||
char *format_name;
|
||||
char *formats_copy = ast_strdupa(args->formats);
|
||||
|
||||
if (!(request_cap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT))) {
|
||||
ast_ari_response_alloc_failed(response);
|
||||
chan_data_destroy(chan_data);
|
||||
return;
|
||||
}
|
||||
|
||||
while ((format_name = ast_strip(strsep(&formats_copy, ",")))) {
|
||||
struct ast_format *fmt = ast_format_cache_get(format_name);
|
||||
|
||||
if (!fmt || ast_format_cap_append(request_cap, fmt, 0)) {
|
||||
if (!fmt) {
|
||||
ast_ari_response_error(
|
||||
response, 400, "Bad Request",
|
||||
"Provided format (%s) was not found", format_name);
|
||||
} else {
|
||||
ast_ari_response_alloc_failed(response);
|
||||
}
|
||||
ao2_ref(request_cap, -1);
|
||||
ao2_cleanup(fmt);
|
||||
chan_data_destroy(chan_data);
|
||||
return;
|
||||
}
|
||||
ao2_ref(fmt, -1);
|
||||
}
|
||||
} else {
|
||||
request_cap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
|
||||
if (!(request_cap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT))) {
|
||||
ast_ari_response_alloc_failed(response);
|
||||
chan_data_destroy(chan_data);
|
||||
return;
|
||||
}
|
||||
|
||||
ast_format_cap_append_by_type(request_cap, AST_MEDIA_TYPE_AUDIO);
|
||||
}
|
||||
|
||||
|
@@ -78,6 +78,8 @@ struct ast_ari_channels_originate_args {
|
||||
const char *other_channel_id;
|
||||
/*! The unique id of the channel which is originating this one. */
|
||||
const char *originator;
|
||||
/*! The format name capability list to use if originator is not specified. Ex. "ulaw,slin16". Format names an be found with "core show codecs". */
|
||||
const char *formats;
|
||||
};
|
||||
/*!
|
||||
* \brief Body parsing function for /channels.
|
||||
@@ -114,6 +116,8 @@ struct ast_ari_channels_create_args {
|
||||
const char *other_channel_id;
|
||||
/*! Unique ID of the calling channel */
|
||||
const char *originator;
|
||||
/*! The format name capability list to use if originator is not specified. Ex. "ulaw,slin16". Format names an be found with "core show codecs". */
|
||||
const char *formats;
|
||||
};
|
||||
/*!
|
||||
* \brief Body parsing function for /channels/create.
|
||||
@@ -175,6 +179,8 @@ struct ast_ari_channels_originate_with_id_args {
|
||||
const char *other_channel_id;
|
||||
/*! The unique id of the channel which is originating this one. */
|
||||
const char *originator;
|
||||
/*! The format name capability list to use if originator is not specified. Ex. "ulaw,slin16". Format names an be found with "core show codecs". */
|
||||
const char *formats;
|
||||
};
|
||||
/*!
|
||||
* \brief Body parsing function for /channels/{channelId}.
|
||||
|
@@ -157,6 +157,10 @@ int ast_ari_channels_originate_parse_body(
|
||||
if (field) {
|
||||
args->originator = ast_json_string_get(field);
|
||||
}
|
||||
field = ast_json_object_get(body, "formats");
|
||||
if (field) {
|
||||
args->formats = ast_json_string_get(field);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -217,6 +221,9 @@ static void ast_ari_channels_originate_cb(
|
||||
if (strcmp(i->name, "originator") == 0) {
|
||||
args.originator = (i->value);
|
||||
} else
|
||||
if (strcmp(i->name, "formats") == 0) {
|
||||
args.formats = (i->value);
|
||||
} else
|
||||
{}
|
||||
}
|
||||
/* Look for a JSON request entity */
|
||||
@@ -298,6 +305,10 @@ int ast_ari_channels_create_parse_body(
|
||||
if (field) {
|
||||
args->originator = ast_json_string_get(field);
|
||||
}
|
||||
field = ast_json_object_get(body, "formats");
|
||||
if (field) {
|
||||
args->formats = ast_json_string_get(field);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -340,6 +351,9 @@ static void ast_ari_channels_create_cb(
|
||||
if (strcmp(i->name, "originator") == 0) {
|
||||
args.originator = (i->value);
|
||||
} else
|
||||
if (strcmp(i->name, "formats") == 0) {
|
||||
args.formats = (i->value);
|
||||
} else
|
||||
{}
|
||||
}
|
||||
/* Look for a JSON request entity */
|
||||
@@ -502,6 +516,10 @@ int ast_ari_channels_originate_with_id_parse_body(
|
||||
if (field) {
|
||||
args->originator = ast_json_string_get(field);
|
||||
}
|
||||
field = ast_json_object_get(body, "formats");
|
||||
if (field) {
|
||||
args->formats = ast_json_string_get(field);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -559,6 +577,9 @@ static void ast_ari_channels_originate_with_id_cb(
|
||||
if (strcmp(i->name, "originator") == 0) {
|
||||
args.originator = (i->value);
|
||||
} else
|
||||
if (strcmp(i->name, "formats") == 0) {
|
||||
args.formats = (i->value);
|
||||
} else
|
||||
{}
|
||||
}
|
||||
for (i = path_vars; i; i = i->next) {
|
||||
|
@@ -257,6 +257,7 @@ static void ast_ari_recordings_get_stored_file_cb(
|
||||
break;
|
||||
case 500: /* Internal Server Error */
|
||||
case 501: /* Not Implemented */
|
||||
case 403: /* The recording file could not be opened */
|
||||
case 404: /* Recording not found */
|
||||
is_valid = 1;
|
||||
break;
|
||||
|
@@ -128,6 +128,14 @@
|
||||
"required": false,
|
||||
"allowMultiple": false,
|
||||
"dataType": "string"
|
||||
},
|
||||
{
|
||||
"name": "formats",
|
||||
"description": "The format name capability list to use if originator is not specified. Ex. \"ulaw,slin16\". Format names can be found with \"core show codecs\".",
|
||||
"paramType": "query",
|
||||
"required": false,
|
||||
"allowMultiple": false,
|
||||
"dataType": "string"
|
||||
}
|
||||
],
|
||||
"errorResponses": [
|
||||
@@ -196,6 +204,14 @@
|
||||
"required": false,
|
||||
"allowMultiple": false,
|
||||
"dataType": "string"
|
||||
},
|
||||
{
|
||||
"name": "formats",
|
||||
"description": "The format name capability list to use if originator is not specified. Ex. \"ulaw,slin16\". Format names can be found with \"core show codecs\".",
|
||||
"paramType": "query",
|
||||
"required": false,
|
||||
"allowMultiple": false,
|
||||
"dataType": "string"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -338,6 +354,14 @@
|
||||
"required": false,
|
||||
"allowMultiple": false,
|
||||
"dataType": "string"
|
||||
},
|
||||
{
|
||||
"name": "formats",
|
||||
"description": "The format name capability list to use if originator is not specified. Ex. \"ulaw,slin16\". Format names can be found with \"core show codecs\".",
|
||||
"paramType": "query",
|
||||
"required": false,
|
||||
"allowMultiple": false,
|
||||
"dataType": "string"
|
||||
}
|
||||
],
|
||||
"errorResponses": [
|
||||
|
Reference in New Issue
Block a user