summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES12
-rw-r--r--addons/ooh323c/src/Makefile.in2
-rw-r--r--channels/chan_pjsip.c9
-rw-r--r--channels/chan_sip.c3
-rw-r--r--include/asterisk/codec.h2
-rw-r--r--include/asterisk/compat.h2
-rw-r--r--include/asterisk/poll-compat.h2
-rw-r--r--include/asterisk/res_hep.h8
-rw-r--r--main/ast_expr2.c1
-rw-r--r--main/ast_expr2.y1
-rw-r--r--main/astfd.c2
-rw-r--r--main/codec.c10
-rw-r--r--main/codec_builtin.c6
-rw-r--r--main/editline/Makefile.in2
-rw-r--r--res/ari/resource_channels.c47
-rw-r--r--res/ari/resource_channels.h4
-rw-r--r--res/res_ari_channels.c14
-rw-r--r--res/res_hep.c12
-rw-r--r--res/res_hep.exports.in1
-rw-r--r--res/res_hep_pjsip.c5
-rw-r--r--res/res_hep_rtcp.c4
-rw-r--r--rest-api/api-docs/channels.json17
-rw-r--r--tests/test_netsock2.c6
23 files changed, 156 insertions, 16 deletions
diff --git a/CHANGES b/CHANGES
index 8d740f13a..9922937ab 100644
--- a/CHANGES
+++ b/CHANGES
@@ -85,6 +85,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 ------------
------------------------------------------------------------------------------
diff --git a/addons/ooh323c/src/Makefile.in b/addons/ooh323c/src/Makefile.in
index d3a96024b..15b14f7df 100644
--- a/addons/ooh323c/src/Makefile.in
+++ b/addons/ooh323c/src/Makefile.in
@@ -104,7 +104,7 @@ CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
LIBRARIES = $(noinst_LIBRARIES)
-libooh323c_a_AR = $(AR) cru
+libooh323c_a_AR = $(AR) cr
libooh323c_a_LIBADD =
am_libooh323c_a_OBJECTS = ooLogChan.$(OBJEXT) ooUtils.$(OBJEXT) \
ooGkClient.$(OBJEXT) context.$(OBJEXT) ooDateTime.$(OBJEXT) \
diff --git a/channels/chan_pjsip.c b/channels/chan_pjsip.c
index f081bd899..970fef496 100644
--- a/channels/chan_pjsip.c
+++ b/channels/chan_pjsip.c
@@ -269,6 +269,9 @@ static int direct_media_mitigate_glare(struct ast_sip_session *session)
return 0;
}
+/*!
+ * \pre chan is locked
+ */
static int check_for_rtp_changes(struct ast_channel *chan, struct ast_rtp_instance *rtp,
struct ast_sip_session_media *media, int rtcp_fd)
{
@@ -338,6 +341,11 @@ static int send_direct_media_request(void *data)
int changed = 0;
int res = 0;
+ /* The channel needs to be locked when checking for RTP changes.
+ * Otherwise, we could end up destroying an underlying RTCP structure
+ * at the same time that the channel thread is attempting to read RTCP
+ */
+ ast_channel_lock(cdata->chan);
if (pvt->media[SIP_MEDIA_AUDIO]) {
changed |= check_for_rtp_changes(
cdata->chan, cdata->rtp, pvt->media[SIP_MEDIA_AUDIO], 1);
@@ -346,6 +354,7 @@ static int send_direct_media_request(void *data)
changed |= check_for_rtp_changes(
cdata->chan, cdata->vrtp, pvt->media[SIP_MEDIA_VIDEO], 3);
}
+ ast_channel_unlock(cdata->chan);
if (direct_media_mitigate_glare(cdata->session)) {
ast_debug(4, "Disregarding setting RTP on %s: mitigating re-INVITE glare\n", ast_channel_name(cdata->chan));
diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index f64845472..77f438262 100644
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -15790,11 +15790,12 @@ static void start_register_timeout(struct sip_registry *reg)
static const char *sip_sanitized_host(const char *host)
{
- struct ast_sockaddr addr = { { 0, 0, }, };
+ struct ast_sockaddr addr;
/* peer/sip_pvt->tohost and sip_registry->hostname should never have a port
* in them, so we use PARSE_PORT_FORBID here. If this lookup fails, we return
* the original host which is most likely a host name and not an IP. */
+ memset(&addr, 0, sizeof(addr));
if (!ast_sockaddr_parse(&addr, host, PARSE_PORT_FORBID)) {
return host;
}
diff --git a/include/asterisk/codec.h b/include/asterisk/codec.h
index 28befec50..fb2b7da38 100644
--- a/include/asterisk/codec.h
+++ b/include/asterisk/codec.h
@@ -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;
};
/*!
diff --git a/include/asterisk/compat.h b/include/asterisk/compat.h
index c9c99c150..c7bc5b093 100644
--- a/include/asterisk/compat.h
+++ b/include/asterisk/compat.h
@@ -68,7 +68,7 @@
#endif
#ifndef AST_POLL_COMPAT
-#include <sys/poll.h>
+#include <poll.h>
#else
#include "asterisk/poll-compat.h"
#endif
diff --git a/include/asterisk/poll-compat.h b/include/asterisk/poll-compat.h
index cbb610925..72ac2c3e2 100644
--- a/include/asterisk/poll-compat.h
+++ b/include/asterisk/poll-compat.h
@@ -83,7 +83,7 @@
#ifndef AST_POLL_COMPAT
-#include <sys/poll.h>
+#include <poll.h>
#define ast_poll(a, b, c) poll(a, b, c)
diff --git a/include/asterisk/res_hep.h b/include/asterisk/res_hep.h
index bd0129eea..cfd213ad7 100644
--- a/include/asterisk/res_hep.h
+++ b/include/asterisk/res_hep.h
@@ -118,6 +118,14 @@ int hepv3_send_packet(struct hepv3_capture_info *capture_info);
*/
enum hep_uuid_type hepv3_get_uuid_type(void);
+/*!
+ * \brief Return whether or not we're currently loaded and active
+ *
+ * \retval 0 The module is not loaded
+ * \retval 1 The module is loaded
+ */
+int hepv3_is_loaded(void);
+
#if defined(__cplusplus) || defined(c_plusplus)
}
#endif
diff --git a/main/ast_expr2.c b/main/ast_expr2.c
index 798e3d3ce..a9e4eff44 100644
--- a/main/ast_expr2.c
+++ b/main/ast_expr2.c
@@ -93,6 +93,7 @@
#include "asterisk.h"
+#include <sys/cdefs.h>
#include <sys/types.h>
#include <stdio.h>
diff --git a/main/ast_expr2.y b/main/ast_expr2.y
index 83d3effe3..869dfe9ea 100644
--- a/main/ast_expr2.y
+++ b/main/ast_expr2.y
@@ -14,6 +14,7 @@
#include "asterisk.h"
+#include <sys/cdefs.h>
#include <sys/types.h>
#include <stdio.h>
diff --git a/main/astfd.c b/main/astfd.c
index d2cb73a6b..a96471d60 100644
--- a/main/astfd.c
+++ b/main/astfd.c
@@ -271,7 +271,7 @@ static char *handle_show_fd(struct ast_cli_entry *e, int cmd, struct ast_cli_arg
case CLI_GENERATE:
return NULL;
}
- getrlimit(RLIMIT_FSIZE, &rl);
+ getrlimit(RLIMIT_NOFILE, &rl);
if (rl.rlim_cur == RLIM_INFINITY || rl.rlim_max == RLIM_INFINITY) {
ast_copy_string(line, "unlimited", sizeof(line));
} else {
diff --git a/main/codec.c b/main/codec.c
index 543d4d0bd..c8644fd34 100644
--- a/main/codec.c
+++ b/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);
diff --git a/main/codec_builtin.c b/main/codec_builtin.c
index 346b47b87..d7d253ab8 100644
--- a/main/codec_builtin.c
+++ b/main/codec_builtin.c
@@ -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); \
diff --git a/main/editline/Makefile.in b/main/editline/Makefile.in
index 112b68b64..2be4333d5 100644
--- a/main/editline/Makefile.in
+++ b/main/editline/Makefile.in
@@ -187,7 +187,7 @@ distclean : clean
#
$(LIB_A) : $(BGCSRCS:.c=.o_a) $(CCSRCS:.c=.o_a)
- $(AR) cru $@ $?
+ $(AR) cr $@ $?
$(RANLIB) $@
$(LIB_S) : $(BGCSRCS:.c=.o_s) $(CCSRCS:.c=.o_s)
diff --git a/res/ari/resource_channels.c b/res/ari/resource_channels.c
index 9e2db9de6..6baac7a4e 100644
--- a/res/ari/resource_channels.c
+++ b/res/ari/resource_channels.c
@@ -912,6 +912,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;
@@ -930,6 +931,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))) {
@@ -944,6 +946,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';
@@ -1066,7 +1074,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);
@@ -1075,6 +1117,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) {
@@ -1215,6 +1258,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);
}
@@ -1251,6 +1295,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);
}
diff --git a/res/ari/resource_channels.h b/res/ari/resource_channels.h
index 4d3ad5f8b..5bb6f7f1e 100644
--- a/res/ari/resource_channels.h
+++ b/res/ari/resource_channels.h
@@ -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.
@@ -141,6 +143,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}.
diff --git a/res/res_ari_channels.c b/res/res_ari_channels.c
index d1ae80196..a14a9c8cb 100644
--- a/res/res_ari_channels.c
+++ b/res/res_ari_channels.c
@@ -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 */
@@ -377,6 +384,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;
}
@@ -434,6 +445,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) {
diff --git a/res/res_hep.c b/res/res_hep.c
index 723b27df8..15e779012 100644
--- a/res/res_hep.c
+++ b/res/res_hep.c
@@ -409,9 +409,21 @@ enum hep_uuid_type hepv3_get_uuid_type(void)
{
RAII_VAR(struct module_config *, config, ao2_global_obj_ref(global_config), ao2_cleanup);
+ if (!config) {
+ /* Well, that's unfortunate. Return something. */
+ return HEP_UUID_TYPE_CALL_ID;
+ }
+
return config->general->uuid_type;
}
+int hepv3_is_loaded(void)
+{
+ RAII_VAR(struct module_config *, config, ao2_global_obj_ref(global_config), ao2_cleanup);
+
+ return (config != NULL) ? 1 : 0;
+}
+
struct hepv3_capture_info *hepv3_create_capture_info(const void *payload, size_t len)
{
struct hepv3_capture_info *info;
diff --git a/res/res_hep.exports.in b/res/res_hep.exports.in
index df0f2b4f7..e318ac97f 100644
--- a/res/res_hep.exports.in
+++ b/res/res_hep.exports.in
@@ -3,6 +3,7 @@
LINKER_SYMBOL_PREFIX*hepv3_send_packet;
LINKER_SYMBOL_PREFIX*hepv3_create_capture_info;
LINKER_SYMBOL_PREFIX*hepv3_get_uuid_type;
+ LINKER_SYMBOL_PREFIX*hepv3_is_loaded;
local:
*;
};
diff --git a/res/res_hep_pjsip.c b/res/res_hep_pjsip.c
index 936db9300..8f5baa2cb 100644
--- a/res/res_hep_pjsip.c
+++ b/res/res_hep_pjsip.c
@@ -210,6 +210,11 @@ static int load_module(void)
{
CHECK_PJSIP_MODULE_LOADED();
+ if (!ast_module_check("res_hep.so") || !hepv3_is_loaded()) {
+ ast_log(AST_LOG_WARNING, "res_hep is not loaded or running; declining module load\n");
+ return AST_MODULE_LOAD_DECLINE;
+ }
+
ast_sip_register_service(&logging_module);
return AST_MODULE_LOAD_SUCCESS;
}
diff --git a/res/res_hep_rtcp.c b/res/res_hep_rtcp.c
index 49a92539f..d77b19c92 100644
--- a/res/res_hep_rtcp.c
+++ b/res/res_hep_rtcp.c
@@ -149,6 +149,10 @@ static void rtp_topic_handler(void *data, struct stasis_subscription *sub, struc
static int load_module(void)
{
+ if (!ast_module_check("res_hep.so") || !hepv3_is_loaded()) {
+ ast_log(AST_LOG_WARNING, "res_hep is not loaded or running; declining module load\n");
+ return AST_MODULE_LOAD_DECLINE;
+ }
stasis_rtp_subscription = stasis_subscribe(ast_rtp_topic(),
rtp_topic_handler, NULL);
diff --git a/rest-api/api-docs/channels.json b/rest-api/api-docs/channels.json
index cb41fb681..8eaa5eb9b 100644
--- a/rest-api/api-docs/channels.json
+++ b/rest-api/api-docs/channels.json
@@ -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": [
@@ -276,6 +284,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": [
@@ -284,7 +300,6 @@
"reason": "Invalid parameters for originating a channel."
}
]
-
},
{
"httpMethod": "DELETE",
diff --git a/tests/test_netsock2.c b/tests/test_netsock2.c
index e182b0a75..fec1ae2d5 100644
--- a/tests/test_netsock2.c
+++ b/tests/test_netsock2.c
@@ -75,7 +75,7 @@ AST_TEST_DEFINE(parsing)
};
size_t x;
- struct ast_sockaddr addr = { { 0, 0, } };
+ struct ast_sockaddr addr;
int parse_result;
switch (cmd) {
@@ -91,15 +91,17 @@ AST_TEST_DEFINE(parsing)
}
for (x = 0; x < ARRAY_LEN(test_vals); x++) {
+ memset(&addr, 0, sizeof(addr));
if ((parse_result = ast_sockaddr_parse(&addr, test_vals[x].address, 0)) != test_vals[x].expected_result) {
ast_test_status_update(test, "On '%s' expected %d but got %d\n", test_vals[x].address, test_vals[x].expected_result, parse_result);
res = AST_TEST_FAIL;
}
if (parse_result) {
- struct ast_sockaddr tmp_addr = { { 0, 0, } };
+ struct ast_sockaddr tmp_addr;
const char *tmp;
tmp = ast_sockaddr_stringify(&addr);
+ memset(&tmp_addr, 0, sizeof(tmp_addr));
ast_sockaddr_parse(&tmp_addr, tmp, 0);
if (ast_sockaddr_cmp_addr(&addr, &tmp_addr)) {
char buf[64];