summaryrefslogtreecommitdiff
path: root/channels
diff options
context:
space:
mode:
authorMatthew Jordan <mjordan@digium.com>2014-07-20 22:06:33 +0000
committerMatthew Jordan <mjordan@digium.com>2014-07-20 22:06:33 +0000
commita2c912e9972c91973ea66902d217746133f96026 (patch)
tree50e01d14ba62950e3f78766d5ba435ba51ca327d /channels
parentb299052e203807c9a2111eb2cd919246d7589cb3 (diff)
media formats: re-architect handling of media for performance improvements
In the old times media formats were represented using a bit field. This was fast but had a few limitations. 1. Asterisk was limited in how many formats it could handle. 2. Formats, being a bit field, could not include any attribute information. A format was strictly its type, e.g., "this is ulaw". This was changed in Asterisk 10 (see https://wiki.asterisk.org/wiki/display/AST/Media+Architecture+Proposal for notes on that work) which led to the creation of the ast_format structure. This structure allowed Asterisk to handle attributes and bundle information with a format. Additionally, ast_format_cap was created to act as a container for multiple formats that, together, formed the capability of some entity. Another mechanism was added to allow logic to be registered which performed format attribute negotiation. Everywhere throughout the codebase Asterisk was changed to use this strategy. Unfortunately, in software, there is no free lunch. These new capabilities came at a cost. Performance analysis and profiling showed that we spend an inordinate amount of time comparing, copying, and generally manipulating formats and their related structures. Basic prototyping has shown that a reasonably large performance improvement could be made in this area. This patch is the result of that project, which overhauled the media format architecture and its usage in Asterisk to improve performance. Generally, the new philosophy for handling formats is as follows: * The ast_format structure is reference counted. This removed a large amount of the memory allocations and copying that was done in prior versions. * In order to prevent race conditions while keeping things performant, the ast_format structure is immutable by convention and lock-free. Violate this tenet at your peril! * Because formats are reference counted, codecs are also reference counted. The Asterisk core generally provides built-in codecs and caches the ast_format structures created to represent them. Generally, to prevent inordinate amounts of module reference bumping, codecs and formats can be added at run-time but cannot be removed. * All compatibility with the bit field representation of codecs/formats has been moved to a compatibility API. The primary user of this representation is chan_iax2, which must continue to maintain its bit-field usage of formats for interoperability concerns. * When a format is negotiated with attributes, or when a format cannot be represented by one of the cached formats, a new format object is created or cloned from an existing format. That format may have the same codec underlying it, but is a different format than a version of the format with different attributes or without attributes. * While formats are reference counted objects, the reference count maintained on the format should be manipulated with care. Formats are generally cached and will persist for the lifetime of Asterisk and do not explicitly need to have their lifetime modified. An exception to this is when the user of a format does not know where the format came from *and* the user may outlive the provider of the format. This occurs, for example, when a format is read from a channel: the channel may have a format with attributes (hence, non-cached) and the user of the format may last longer than the channel (if the reference to the channel is released prior to the format's reference). For more information on this work, see the API design notes: https://wiki.asterisk.org/wiki/display/AST/Media+Format+Rewrite Finally, this work was the culmination of a large number of developer's efforts. Extra thanks goes to Corey Farrell, who took on a large amount of the work in the Asterisk core, chan_sip, and was an invaluable resource in peer reviews throughout this project. There were a substantial number of patches contributed during this work; the following issues/patch names simply reflect some of the work (and will cause the release scripts to give attribution to the individuals who work on them). Reviews: https://reviewboard.asterisk.org/r/3814 https://reviewboard.asterisk.org/r/3808 https://reviewboard.asterisk.org/r/3805 https://reviewboard.asterisk.org/r/3803 https://reviewboard.asterisk.org/r/3801 https://reviewboard.asterisk.org/r/3798 https://reviewboard.asterisk.org/r/3800 https://reviewboard.asterisk.org/r/3794 https://reviewboard.asterisk.org/r/3793 https://reviewboard.asterisk.org/r/3792 https://reviewboard.asterisk.org/r/3791 https://reviewboard.asterisk.org/r/3790 https://reviewboard.asterisk.org/r/3789 https://reviewboard.asterisk.org/r/3788 https://reviewboard.asterisk.org/r/3787 https://reviewboard.asterisk.org/r/3786 https://reviewboard.asterisk.org/r/3784 https://reviewboard.asterisk.org/r/3783 https://reviewboard.asterisk.org/r/3778 https://reviewboard.asterisk.org/r/3774 https://reviewboard.asterisk.org/r/3775 https://reviewboard.asterisk.org/r/3772 https://reviewboard.asterisk.org/r/3761 https://reviewboard.asterisk.org/r/3754 https://reviewboard.asterisk.org/r/3753 https://reviewboard.asterisk.org/r/3751 https://reviewboard.asterisk.org/r/3750 https://reviewboard.asterisk.org/r/3748 https://reviewboard.asterisk.org/r/3747 https://reviewboard.asterisk.org/r/3746 https://reviewboard.asterisk.org/r/3742 https://reviewboard.asterisk.org/r/3740 https://reviewboard.asterisk.org/r/3739 https://reviewboard.asterisk.org/r/3738 https://reviewboard.asterisk.org/r/3737 https://reviewboard.asterisk.org/r/3736 https://reviewboard.asterisk.org/r/3734 https://reviewboard.asterisk.org/r/3722 https://reviewboard.asterisk.org/r/3713 https://reviewboard.asterisk.org/r/3703 https://reviewboard.asterisk.org/r/3689 https://reviewboard.asterisk.org/r/3687 https://reviewboard.asterisk.org/r/3674 https://reviewboard.asterisk.org/r/3671 https://reviewboard.asterisk.org/r/3667 https://reviewboard.asterisk.org/r/3665 https://reviewboard.asterisk.org/r/3625 https://reviewboard.asterisk.org/r/3602 https://reviewboard.asterisk.org/r/3519 https://reviewboard.asterisk.org/r/3518 https://reviewboard.asterisk.org/r/3516 https://reviewboard.asterisk.org/r/3515 https://reviewboard.asterisk.org/r/3512 https://reviewboard.asterisk.org/r/3506 https://reviewboard.asterisk.org/r/3413 https://reviewboard.asterisk.org/r/3410 https://reviewboard.asterisk.org/r/3387 https://reviewboard.asterisk.org/r/3388 https://reviewboard.asterisk.org/r/3389 https://reviewboard.asterisk.org/r/3390 https://reviewboard.asterisk.org/r/3321 https://reviewboard.asterisk.org/r/3320 https://reviewboard.asterisk.org/r/3319 https://reviewboard.asterisk.org/r/3318 https://reviewboard.asterisk.org/r/3266 https://reviewboard.asterisk.org/r/3265 https://reviewboard.asterisk.org/r/3234 https://reviewboard.asterisk.org/r/3178 ASTERISK-23114 #close Reported by: mjordan media_formats_translation_core.diff uploaded by kharwell (License 6464) rb3506.diff uploaded by mjordan (License 6283) media_format_app_file.diff uploaded by kharwell (License 6464) misc-2.diff uploaded by file (License 5000) chan_mild-3.diff uploaded by file (License 5000) chan_obscure.diff uploaded by file (License 5000) jingle.diff uploaded by file (License 5000) funcs.diff uploaded by file (License 5000) formats.diff uploaded by file (License 5000) core.diff uploaded by file (License 5000) bridges.diff uploaded by file (License 5000) mf-codecs-2.diff uploaded by file (License 5000) mf-app_fax.diff uploaded by file (License 5000) mf-apps-3.diff uploaded by file (License 5000) media-formats-3.diff uploaded by file (License 5000) ASTERISK-23715 rb3713.patch uploaded by coreyfarrell (License 5909) rb3689.patch uploaded by mjordan (License 6283) ASTERISK-23957 rb3722.patch uploaded by mjordan (License 6283) mf-attributes-3.diff uploaded by file (License 5000) ASTERISK-23958 Tested by: jrose rb3822.patch uploaded by coreyfarrell (License 5909) rb3800.patch uploaded by jrose (License 6182) chan_sip.diff uploaded by mjordan (License 6283) rb3747.patch uploaded by jrose (License 6182) ASTERISK-23959 #close Tested by: sgriepentrog, mjordan, coreyfarrell sip_cleanup.diff uploaded by opticron (License 6273) chan_sip_caps.diff uploaded by mjordan (License 6283) rb3751.patch uploaded by coreyfarrell (License 5909) chan_sip-3.diff uploaded by file (License 5000) ASTERISK-23960 #close Tested by: opticron direct_media.diff uploaded by opticron (License 6273) pjsip-direct-media.diff uploaded by file (License 5000) format_cap_remove.diff uploaded by opticron (License 6273) media_format_fixes.diff uploaded by opticron (License 6273) chan_pjsip-2.diff uploaded by file (License 5000) ASTERISK-23966 #close Tested by: rmudgett rb3803.patch uploaded by rmudgetti (License 5621) chan_dahdi.diff uploaded by file (License 5000) ASTERISK-24064 #close Tested by: coreyfarrell, mjordan, opticron, file, rmudgett, sgriepentrog, jrose rb3814.patch uploaded by rmudgett (License 5621) moh_cleanup.diff uploaded by opticron (License 6273) bridge_leak.diff uploaded by opticron (License 6273) translate.diff uploaded by file (License 5000) rb3795.patch uploaded by rmudgett (License 5621) tls_fix.diff uploaded by mjordan (License 6283) fax-mf-fix-2.diff uploaded by file (License 5000) rtp_transfer_stuff uploaded by mjordan (License 6283) rb3787.patch uploaded by rmudgett (License 5621) media-formats-explicit-translate-format-3.diff uploaded by file (License 5000) format_cache_case_fix.diff uploaded by opticron (License 6273) rb3774.patch uploaded by rmudgett (License 5621) rb3775.patch uploaded by rmudgett (License 5621) rtp_engine_fix.diff uploaded by opticron (License 6273) rtp_crash_fix.diff uploaded by opticron (License 6273) rb3753.patch uploaded by mjordan (License 6283) rb3750.patch uploaded by mjordan (License 6283) rb3748.patch uploaded by rmudgett (License 5621) media_format_fixes.diff uploaded by opticron (License 6273) rb3740.patch uploaded by mjordan (License 6283) rb3739.patch uploaded by mjordan (License 6283) rb3734.patch uploaded by mjordan (License 6283) rb3689.patch uploaded by mjordan (License 6283) rb3674.patch uploaded by coreyfarrell (License 5909) rb3671.patch uploaded by coreyfarrell (License 5909) rb3667.patch uploaded by coreyfarrell (License 5909) rb3665.patch uploaded by mjordan (License 6283) rb3625.patch uploaded by coreyfarrell (License 5909) rb3602.patch uploaded by coreyfarrell (License 5909) format_compatibility-2.diff uploaded by file (License 5000) core.diff uploaded by file (License 5000) git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@419044 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'channels')
-rw-r--r--channels/chan_alsa.c27
-rw-r--r--channels/chan_bridge_media.c14
-rw-r--r--channels/chan_console.c35
-rw-r--r--channels/chan_dahdi.c129
-rw-r--r--channels/chan_iax2.c505
-rw-r--r--channels/chan_mgcp.c378
-rw-r--r--channels/chan_misdn.c55
-rw-r--r--channels/chan_motif.c185
-rw-r--r--channels/chan_multicast_rtp.c36
-rw-r--r--channels/chan_nbs.c56
-rw-r--r--channels/chan_oss.c23
-rw-r--r--channels/chan_phone.c208
-rw-r--r--channels/chan_pjsip.c83
-rw-r--r--channels/chan_sip.c791
-rw-r--r--channels/chan_skinny.c362
-rw-r--r--channels/chan_unistim.c165
-rw-r--r--channels/chan_vpb.cc97
-rw-r--r--channels/dahdi/bridge_native_dahdi.c13
-rw-r--r--channels/iax2/codec_pref.c333
-rw-r--r--channels/iax2/format_compatibility.c73
-rw-r--r--channels/iax2/include/codec_pref.h123
-rw-r--r--channels/iax2/include/format_compatibility.h55
-rw-r--r--channels/iax2/parser.c15
-rw-r--r--channels/iax2/provision.c9
-rw-r--r--channels/pjsip/dialplan_functions.c46
-rw-r--r--channels/sip/include/sip.h2
26 files changed, 2319 insertions, 1499 deletions
diff --git a/channels/chan_alsa.c b/channels/chan_alsa.c
index 9d43ba139..f74e78fd6 100644
--- a/channels/chan_alsa.c
+++ b/channels/chan_alsa.c
@@ -63,6 +63,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/musiconhold.h"
#include "asterisk/poll-compat.h"
#include "asterisk/stasis_channels.h"
+#include "asterisk/format_cache.h"
/*! Global jitterbuffer configuration - by default, jb is disabled
* \note Values shown here match the defaults shown in alsa.conf.sample */
@@ -511,7 +512,7 @@ static struct ast_frame *alsa_read(struct ast_channel *chan)
}
f.frametype = AST_FRAME_VOICE;
- ast_format_set(&f.subclass.format, AST_FORMAT_SLINEAR, 0);
+ f.subclass.format = ast_format_slin;
f.samples = FRAME_SIZE;
f.datalen = FRAME_SIZE * 2;
f.data.ptr = buf;
@@ -585,9 +586,9 @@ static struct ast_channel *alsa_new(struct chan_alsa_pvt *p, int state, const st
ast_channel_tech_set(tmp, &alsa_tech);
ast_channel_set_fd(tmp, 0, readdev);
- ast_format_set(ast_channel_readformat(tmp), AST_FORMAT_SLINEAR, 0);
- ast_format_set(ast_channel_writeformat(tmp), AST_FORMAT_SLINEAR, 0);
- ast_format_cap_add(ast_channel_nativeformats(tmp), ast_channel_writeformat(tmp));
+ ast_channel_set_readformat(tmp, ast_format_slin);
+ ast_channel_set_writeformat(tmp, ast_format_slin);
+ ast_channel_nativeformats_set(tmp, alsa_tech.capabilities);
ast_channel_tech_pvt_set(tmp, p);
if (!ast_strlen_zero(p->context))
@@ -616,14 +617,11 @@ static struct ast_channel *alsa_new(struct chan_alsa_pvt *p, int state, const st
static struct ast_channel *alsa_request(const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, int *cause)
{
- struct ast_format tmpfmt;
- char buf[256];
struct ast_channel *tmp = NULL;
- ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR, 0);
-
- if (!(ast_format_cap_iscompatible(cap, &tmpfmt))) {
- ast_log(LOG_NOTICE, "Asked to get a channel of format '%s'\n", ast_getformatname_multiple(buf, sizeof(buf), cap));
+ if (ast_format_cap_iscompatible_format(cap, ast_format_slin) == AST_FORMAT_CMP_NOT_EQUAL) {
+ struct ast_str *codec_buf = ast_str_alloca(64);
+ ast_log(LOG_NOTICE, "Asked to get a channel of format '%s'\n", ast_format_cap_get_names(cap, &codec_buf));
return NULL;
}
@@ -959,12 +957,11 @@ static int load_module(void)
struct ast_config *cfg;
struct ast_variable *v;
struct ast_flags config_flags = { 0 };
- struct ast_format tmpfmt;
- if (!(alsa_tech.capabilities = ast_format_cap_alloc(0))) {
+ if (!(alsa_tech.capabilities = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT))) {
return AST_MODULE_LOAD_DECLINE;
}
- ast_format_cap_add(alsa_tech.capabilities, ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR, 0));
+ ast_format_cap_append(alsa_tech.capabilities, ast_format_slin, 0);
/* Copy the default jb config over global_jbconf */
memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf));
@@ -1042,7 +1039,9 @@ static int unload_module(void)
if (alsa.owner)
return -1;
- alsa_tech.capabilities = ast_format_cap_destroy(alsa_tech.capabilities);
+ ao2_cleanup(alsa_tech.capabilities);
+ alsa_tech.capabilities = NULL;
+
return 0;
}
diff --git a/channels/chan_bridge_media.c b/channels/chan_bridge_media.c
index ac15e7d70..6502b5c77 100644
--- a/channels/chan_bridge_media.c
+++ b/channels/chan_bridge_media.c
@@ -164,11 +164,13 @@ static struct ast_channel *record_request(const char *type, struct ast_format_ca
static void cleanup_capabilities(void)
{
if (announce_tech.capabilities) {
- announce_tech.capabilities = ast_format_cap_destroy(announce_tech.capabilities);
+ ao2_ref(announce_tech.capabilities, -1);
+ announce_tech.capabilities = NULL;
}
if (record_tech.capabilities) {
- record_tech.capabilities = ast_format_cap_destroy(record_tech.capabilities);
+ ao2_ref(record_tech.capabilities, -1);
+ record_tech.capabilities = NULL;
}
}
@@ -182,18 +184,18 @@ static int unload_module(void)
static int load_module(void)
{
- announce_tech.capabilities = ast_format_cap_alloc(0);
+ announce_tech.capabilities = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
if (!announce_tech.capabilities) {
return AST_MODULE_LOAD_DECLINE;
}
- record_tech.capabilities = ast_format_cap_alloc(0);
+ record_tech.capabilities = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
if (!record_tech.capabilities) {
return AST_MODULE_LOAD_DECLINE;
}
- ast_format_cap_add_all(announce_tech.capabilities);
- ast_format_cap_add_all(record_tech.capabilities);
+ ast_format_cap_append_by_type(announce_tech.capabilities, AST_MEDIA_TYPE_UNKNOWN);
+ ast_format_cap_append_by_type(record_tech.capabilities, AST_MEDIA_TYPE_UNKNOWN);
if (ast_channel_register(&announce_tech)) {
ast_log(LOG_ERROR, "Unable to register channel technology %s(%s).\n",
diff --git a/channels/chan_console.c b/channels/chan_console.c
index b1f5cdf7c..3aeda931a 100644
--- a/channels/chan_console.c
+++ b/channels/chan_console.c
@@ -77,6 +77,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/callerid.h"
#include "asterisk/astobj2.h"
#include "asterisk/stasis_channels.h"
+#include "asterisk/format_cache.h"
/*!
* \brief The sample rate to request from PortAudio
@@ -270,12 +271,12 @@ static void *stream_monitor(void *data)
PaError res;
struct ast_frame f = {
.frametype = AST_FRAME_VOICE,
+ .subclass.format = ast_format_slin16,
.src = "console_stream_monitor",
.data.ptr = buf,
.datalen = sizeof(buf),
.samples = sizeof(buf) / sizeof(int16_t),
};
- ast_format_set(&f.subclass.format, AST_FORMAT_SLINEAR16, 0);
for (;;) {
pthread_testcancel();
@@ -421,19 +422,28 @@ static int stop_stream(struct console_pvt *pvt)
*/
static struct ast_channel *console_new(struct console_pvt *pvt, const char *ext, const char *ctx, int state, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor)
{
+ struct ast_format_cap *caps;
struct ast_channel *chan;
+ caps = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
+ if (!caps) {
+ return NULL;
+ }
+
if (!(chan = ast_channel_alloc(1, state, pvt->cid_num, pvt->cid_name, NULL,
ext, ctx, assignedids, requestor, 0, "Console/%s", pvt->name))) {
+ ao2_ref(caps, -1);
return NULL;
}
ast_channel_stage_snapshot(chan);
ast_channel_tech_set(chan, &console_tech);
- ast_format_set(ast_channel_readformat(chan), AST_FORMAT_SLINEAR16, 0);
- ast_format_set(ast_channel_writeformat(chan), AST_FORMAT_SLINEAR16, 0);
- ast_format_cap_add(ast_channel_nativeformats(chan), ast_channel_readformat(chan));
+ ast_channel_set_readformat(chan, ast_format_slin16);
+ ast_channel_set_writeformat(chan, ast_format_slin16);
+ ast_format_cap_append(caps, ast_format_slin16, 0);
+ ast_channel_nativeformats_set(chan, caps);
+ ao2_ref(caps, -1);
ast_channel_tech_pvt_set(chan, ref_pvt(pvt));
pvt->owner = chan;
@@ -462,15 +472,16 @@ static struct ast_channel *console_request(const char *type, struct ast_format_c
{
struct ast_channel *chan = NULL;
struct console_pvt *pvt;
- char buf[512];
if (!(pvt = find_pvt(data))) {
ast_log(LOG_ERROR, "Console device '%s' not found\n", data);
return NULL;
}
- if (!(ast_format_cap_has_joint(cap, console_tech.capabilities))) {
- ast_log(LOG_NOTICE, "Channel requested with unsupported format(s): '%s'\n", ast_getformatname_multiple(buf, sizeof(buf), cap));
+ if (!(ast_format_cap_iscompatible(cap, console_tech.capabilities))) {
+ struct ast_str *cap_buf = ast_str_alloca(64);
+ ast_log(LOG_NOTICE, "Channel requested with unsupported format(s): '%s'\n",
+ ast_format_cap_get_names(cap, &cap_buf));
goto return_unref;
}
@@ -1467,7 +1478,8 @@ static void stop_streams(void)
static int unload_module(void)
{
- console_tech.capabilities = ast_format_cap_destroy(console_tech.capabilities);
+ ao2_ref(console_tech.capabilities, -1);
+ console_tech.capabilities = NULL;
ast_channel_unregister(&console_tech);
ast_cli_unregister_multiple(cli_console, ARRAY_LEN(cli_console));
@@ -1495,13 +1507,12 @@ static int unload_module(void)
*/
static int load_module(void)
{
- struct ast_format tmpfmt;
PaError res;
- if (!(console_tech.capabilities = ast_format_cap_alloc(0))) {
+ if (!(console_tech.capabilities = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT))) {
return AST_MODULE_LOAD_DECLINE;
}
- ast_format_cap_add(console_tech.capabilities, ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR16, 0));
+ ast_format_cap_append(console_tech.capabilities, ast_format_slin16, 0);
init_pvt(&globals, NULL);
@@ -1538,6 +1549,8 @@ return_error:
if (pvts)
ao2_ref(pvts, -1);
pvts = NULL;
+ ao2_ref(console_tech.capabilities, -1);
+ console_tech.capabilities = NULL;
pvt_destructor(&globals);
return AST_MODULE_LOAD_DECLINE;
diff --git a/channels/chan_dahdi.c b/channels/chan_dahdi.c
index 81242533e..c22833da5 100644
--- a/channels/chan_dahdi.c
+++ b/channels/chan_dahdi.c
@@ -129,6 +129,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/bridge.h"
#include "asterisk/stasis_channels.h"
#include "asterisk/parking.h"
+#include "asterisk/format_cache.h"
#include "chan_dahdi.h"
#include "dahdi/bridge_native_dahdi.h"
@@ -461,7 +462,7 @@ static struct ast_jb_conf global_jbconf;
/*! \brief Typically, how many rings before we should send Caller*ID */
#define DEFAULT_CIDRINGS 1
-#define AST_LAW(p) (((p)->law == DAHDI_LAW_ALAW) ? AST_FORMAT_ALAW : AST_FORMAT_ULAW)
+#define AST_LAW(p) (((p)->law == DAHDI_LAW_ALAW) ? ast_format_alaw : ast_format_ulaw)
/*! \brief Signaling types that need to use MF detection should be placed in this macro */
@@ -1321,7 +1322,6 @@ static int my_get_callerid(void *pvt, char *namebuf, char *numbuf, enum analog_e
int res;
unsigned char buf[256];
int flags;
- struct ast_format tmpfmt;
poller.fd = p->subs[SUB_REAL].dfd;
poller.events = POLLPRI | POLLIN;
@@ -1354,9 +1354,9 @@ static int my_get_callerid(void *pvt, char *namebuf, char *numbuf, enum analog_e
}
if (p->cid_signalling == CID_SIG_V23_JP) {
- res = callerid_feed_jp(p->cs, buf, res, ast_format_set(&tmpfmt, AST_LAW(p), 0));
+ res = callerid_feed_jp(p->cs, buf, res, AST_LAW(p));
} else {
- res = callerid_feed(p->cs, buf, res, ast_format_set(&tmpfmt, AST_LAW(p), 0));
+ res = callerid_feed(p->cs, buf, res, AST_LAW(p));
}
if (res < 0) {
/*
@@ -1525,7 +1525,7 @@ static int restore_conference(struct dahdi_pvt *p);
static int my_callwait(void *pvt)
{
struct dahdi_pvt *p = pvt;
- struct ast_format tmpfmt;
+
p->callwaitingrepeat = CALLWAITING_REPEAT_SAMPLES;
if (p->cidspill) {
ast_log(LOG_WARNING, "Spill already exists?!?\n");
@@ -1542,11 +1542,11 @@ static int my_callwait(void *pvt)
/* Silence */
memset(p->cidspill, 0x7f, 2400 + 600 + READ_SIZE * 4);
if (!p->callwaitrings && p->callwaitingcallerid) {
- ast_gen_cas(p->cidspill, 1, 2400 + 680, ast_format_set(&tmpfmt, AST_LAW(p), 0));
+ ast_gen_cas(p->cidspill, 1, 2400 + 680, AST_LAW(p));
p->callwaitcas = 1;
p->cidlen = 2400 + 680 + READ_SIZE * 4;
} else {
- ast_gen_cas(p->cidspill, 1, 2400, ast_format_set(&tmpfmt, AST_LAW(p), 0));
+ ast_gen_cas(p->cidspill, 1, 2400, AST_LAW(p));
p->callwaitcas = 0;
p->cidlen = 2400 + READ_SIZE * 4;
}
@@ -1559,7 +1559,6 @@ static int my_callwait(void *pvt)
static int my_send_callerid(void *pvt, int cwcid, struct ast_party_caller *caller)
{
struct dahdi_pvt *p = pvt;
- struct ast_format tmpfmt;
ast_debug(2, "Starting cid spill\n");
@@ -1573,7 +1572,7 @@ static int my_send_callerid(void *pvt, int cwcid, struct ast_party_caller *calle
p->cidlen = ast_callerid_generate(p->cidspill,
caller->id.name.str,
caller->id.number.str,
- ast_format_set(&tmpfmt, AST_LAW(p), 0));
+ AST_LAW(p));
} else {
ast_verb(3, "CPE supports Call Waiting Caller*ID. Sending '%s/%s'\n",
caller->id.name.str, caller->id.number.str);
@@ -1582,7 +1581,7 @@ static int my_send_callerid(void *pvt, int cwcid, struct ast_party_caller *calle
p->cidlen = ast_callerid_callwaiting_generate(p->cidspill,
caller->id.name.str,
caller->id.number.str,
- ast_format_set(&tmpfmt, AST_LAW(p), 0));
+ AST_LAW(p));
p->cidlen += READ_SIZE * 4;
}
p->cidpos = 0;
@@ -4965,14 +4964,12 @@ static int restore_conference(struct dahdi_pvt *p)
static int send_cwcidspill(struct dahdi_pvt *p)
{
- struct ast_format tmpfmt;
-
p->callwaitcas = 0;
p->cidcwexpire = 0;
p->cid_suppress_expire = 0;
if (!(p->cidspill = ast_malloc(MAX_CALLERID_SIZE)))
return -1;
- p->cidlen = ast_callerid_callwaiting_generate(p->cidspill, p->callwait_name, p->callwait_num, ast_format_set(&tmpfmt, AST_LAW(p), 0));
+ p->cidlen = ast_callerid_callwaiting_generate(p->cidspill, p->callwait_name, p->callwait_num, AST_LAW(p));
/* Make sure we account for the end */
p->cidlen += READ_SIZE * 4;
p->cidpos = 0;
@@ -5038,7 +5035,7 @@ static int send_callerid(struct dahdi_pvt *p)
static int dahdi_callwait(struct ast_channel *ast)
{
struct dahdi_pvt *p = ast_channel_tech_pvt(ast);
- struct ast_format tmpfmt;
+
p->callwaitingrepeat = CALLWAITING_REPEAT_SAMPLES;
if (p->cidspill) {
ast_log(LOG_WARNING, "Spill already exists?!?\n");
@@ -5055,11 +5052,11 @@ static int dahdi_callwait(struct ast_channel *ast)
/* Silence */
memset(p->cidspill, 0x7f, 2400 + 600 + READ_SIZE * 4);
if (!p->callwaitrings && p->callwaitingcallerid) {
- ast_gen_cas(p->cidspill, 1, 2400 + 680, ast_format_set(&tmpfmt, AST_LAW(p), 0));
+ ast_gen_cas(p->cidspill, 1, 2400 + 680, AST_LAW(p));
p->callwaitcas = 1;
p->cidlen = 2400 + 680 + READ_SIZE * 4;
} else {
- ast_gen_cas(p->cidspill, 1, 2400, ast_format_set(&tmpfmt, AST_LAW(p), 0));
+ ast_gen_cas(p->cidspill, 1, 2400, AST_LAW(p));
p->callwaitcas = 0;
p->cidlen = 2400 + READ_SIZE * 4;
}
@@ -8504,25 +8501,20 @@ static struct ast_frame *dahdi_read(struct ast_channel *ast)
return f;
}
- if (ast_channel_rawreadformat(ast)->id == AST_FORMAT_SLINEAR) {
+ if (ast_format_cmp(ast_channel_rawreadformat(ast), ast_format_slin) == AST_FORMAT_CMP_EQUAL) {
if (!p->subs[idx].linear) {
p->subs[idx].linear = 1;
res = dahdi_setlinear(p->subs[idx].dfd, p->subs[idx].linear);
if (res)
ast_log(LOG_WARNING, "Unable to set channel %d (index %d) to linear mode.\n", p->channel, idx);
}
- } else if ((ast_channel_rawreadformat(ast)->id == AST_FORMAT_ULAW) ||
- (ast_channel_rawreadformat(ast)->id == AST_FORMAT_ALAW)) {
+ } else {
if (p->subs[idx].linear) {
p->subs[idx].linear = 0;
res = dahdi_setlinear(p->subs[idx].dfd, p->subs[idx].linear);
if (res)
ast_log(LOG_WARNING, "Unable to set channel %d (index %d) to companded mode.\n", p->channel, idx);
}
- } else {
- ast_log(LOG_WARNING, "Don't know how to read frames in format %s\n", ast_getformatname(ast_channel_rawreadformat(ast)));
- ast_mutex_unlock(&p->lock);
- return NULL;
}
readbuf = ((unsigned char *)p->subs[idx].buffer) + AST_FRIENDLY_OFFSET;
CHECK_BLOCKING(ast);
@@ -8612,7 +8604,7 @@ static struct ast_frame *dahdi_read(struct ast_channel *ast)
}
p->subs[idx].f.frametype = AST_FRAME_VOICE;
- ast_format_copy(&p->subs[idx].f.subclass.format, ast_channel_rawreadformat(ast));
+ p->subs[idx].f.subclass.format = ast_channel_rawreadformat(ast);
p->subs[idx].f.samples = READ_SIZE;
p->subs[idx].f.mallocd = 0;
p->subs[idx].f.offset = AST_FRIENDLY_OFFSET;
@@ -8795,12 +8787,6 @@ static int dahdi_write(struct ast_channel *ast, struct ast_frame *frame)
ast_log(LOG_WARNING, "Don't know what to do with frame type '%u'\n", frame->frametype);
return 0;
}
- if ((frame->subclass.format.id != AST_FORMAT_SLINEAR) &&
- (frame->subclass.format.id != AST_FORMAT_ULAW) &&
- (frame->subclass.format.id != AST_FORMAT_ALAW)) {
- ast_log(LOG_WARNING, "Cannot handle frames in %s format\n", ast_getformatname(&frame->subclass.format));
- return -1;
- }
if (p->dialing) {
ast_debug(5, "Dropping frame since I'm still dialing on %s...\n",ast_channel_name(ast));
return 0;
@@ -8818,7 +8804,7 @@ static int dahdi_write(struct ast_channel *ast, struct ast_frame *frame)
if (!frame->data.ptr || !frame->datalen)
return 0;
- if (frame->subclass.format.id == AST_FORMAT_SLINEAR) {
+ if (ast_format_cmp(frame->subclass.format, ast_format_slin) == AST_FORMAT_CMP_EQUAL) {
if (!p->subs[idx].linear) {
p->subs[idx].linear = 1;
res = dahdi_setlinear(p->subs[idx].dfd, p->subs[idx].linear);
@@ -8826,7 +8812,8 @@ static int dahdi_write(struct ast_channel *ast, struct ast_frame *frame)
ast_log(LOG_WARNING, "Unable to set linear mode on channel %d\n", p->channel);
}
res = my_dahdi_write(p, (unsigned char *)frame->data.ptr, frame->datalen, idx, 1);
- } else {
+ } else if (ast_format_cmp(frame->subclass.format, ast_format_ulaw) == AST_FORMAT_CMP_EQUAL
+ || ast_format_cmp(frame->subclass.format, ast_format_alaw) == AST_FORMAT_CMP_EQUAL) {
/* x-law already */
if (p->subs[idx].linear) {
p->subs[idx].linear = 0;
@@ -8835,6 +8822,10 @@ static int dahdi_write(struct ast_channel *ast, struct ast_frame *frame)
ast_log(LOG_WARNING, "Unable to set companded mode on channel %d\n", p->channel);
}
res = my_dahdi_write(p, (unsigned char *)frame->data.ptr, frame->datalen, idx, 0);
+ } else {
+ ast_log(LOG_WARNING, "Cannot handle frames in %s format\n",
+ ast_format_get_name(frame->subclass.format));
+ return -1;
}
if (res < 0) {
ast_log(LOG_WARNING, "write failed: %s\n", strerror(errno));
@@ -9024,7 +9015,8 @@ static struct ast_channel *dahdi_new_callid_clean(struct dahdi_pvt *i, int state
static struct ast_channel *dahdi_new(struct dahdi_pvt *i, int state, int startpbx, int idx, int law, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, struct ast_callid *callid)
{
struct ast_channel *tmp;
- struct ast_format deflaw;
+ struct ast_format_cap *caps;
+ struct ast_format *deflaw;
int x;
int features;
struct ast_str *chan_name;
@@ -9037,7 +9029,6 @@ static struct ast_channel *dahdi_new(struct dahdi_pvt *i, int state, int startpb
return NULL;
}
- ast_format_clear(&deflaw);
#if defined(HAVE_PRI)
/*
* The dnid has been stuffed with the called-number[:subaddress]
@@ -9051,9 +9042,16 @@ static struct ast_channel *dahdi_new(struct dahdi_pvt *i, int state, int startpb
return NULL;
}
+ caps = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
+ if (!caps) {
+ ast_free(chan_name);
+ return NULL;
+ }
+
tmp = ast_channel_alloc(0, state, i->cid_num, i->cid_name, i->accountcode, i->exten, i->context, assignedids, requestor, i->amaflags, "DAHDI/%s", ast_str_buffer(chan_name));
ast_free(chan_name);
if (!tmp) {
+ ao2_ref(caps, -1);
return NULL;
}
@@ -9073,9 +9071,9 @@ static struct ast_channel *dahdi_new(struct dahdi_pvt *i, int state, int startpb
if (law) {
i->law = law;
if (law == DAHDI_LAW_ALAW) {
- ast_format_set(&deflaw, AST_FORMAT_ALAW, 0);
+ deflaw = ast_format_alaw;
} else {
- ast_format_set(&deflaw, AST_FORMAT_ULAW, 0);
+ deflaw = ast_format_ulaw;
}
} else {
switch (i->sig) {
@@ -9089,18 +9087,20 @@ static struct ast_channel *dahdi_new(struct dahdi_pvt *i, int state, int startpb
break;
}
if (i->law_default == DAHDI_LAW_ALAW) {
- ast_format_set(&deflaw, AST_FORMAT_ALAW, 0);
+ deflaw = ast_format_alaw;
} else {
- ast_format_set(&deflaw, AST_FORMAT_ULAW, 0);
+ deflaw = ast_format_ulaw;
}
}
ast_channel_set_fd(tmp, 0, i->subs[idx].dfd);
- ast_format_cap_add(ast_channel_nativeformats(tmp), &deflaw);
+ ast_format_cap_append(caps, deflaw, 0);
+ ast_channel_nativeformats_set(tmp, caps);
+ ao2_ref(caps, -1);
/* Start out assuming ulaw since it's smaller :) */
- ast_format_copy(ast_channel_rawreadformat(tmp), &deflaw);
- ast_format_copy(ast_channel_readformat(tmp), &deflaw);
- ast_format_copy(ast_channel_rawwriteformat(tmp), &deflaw);
- ast_format_copy(ast_channel_writeformat(tmp), &deflaw);
+ ast_channel_set_rawreadformat(tmp, deflaw);
+ ast_channel_set_readformat(tmp, deflaw);
+ ast_channel_set_rawwriteformat(tmp, deflaw);
+ ast_channel_set_writeformat(tmp, deflaw);
i->subs[idx].linear = 0;
dahdi_setlinear(i->subs[idx].dfd, i->subs[idx].linear);
features = 0;
@@ -9397,7 +9397,6 @@ static void *analog_ss_thread(void *data)
int len = 0;
int res;
int idx;
- struct ast_format tmpfmt;
RAII_VAR(struct ast_features_pickup_config *, pickup_cfg, NULL, ao2_cleanup);
const char *pickupexten;
@@ -10114,9 +10113,9 @@ static void *analog_ss_thread(void *data)
samples += res;
if (p->cid_signalling == CID_SIG_V23_JP) {
- res = callerid_feed_jp(cs, buf, res, ast_format_set(&tmpfmt, AST_LAW(p), 0));
+ res = callerid_feed_jp(cs, buf, res, AST_LAW(p));
} else {
- res = callerid_feed(cs, buf, res, ast_format_set(&tmpfmt, AST_LAW(p), 0));
+ res = callerid_feed(cs, buf, res, AST_LAW(p));
}
if (res < 0) {
/*
@@ -10399,7 +10398,7 @@ static void *analog_ss_thread(void *data)
}
}
samples += res;
- res = callerid_feed(cs, buf, res, ast_format_set(&tmpfmt, AST_LAW(p), 0));
+ res = callerid_feed(cs, buf, res, AST_LAW(p));
if (res < 0) {
/*
* The previous diagnostic message output likely
@@ -10569,7 +10568,7 @@ struct mwi_thread_data {
size_t len;
};
-static int calc_energy(const unsigned char *buf, int len, enum ast_format_id law)
+static int calc_energy(const unsigned char *buf, int len, struct ast_format *law)
{
int x;
int sum = 0;
@@ -10578,7 +10577,7 @@ static int calc_energy(const unsigned char *buf, int len, enum ast_format_id law
return 0;
for (x = 0; x < len; x++)
- sum += abs(law == AST_FORMAT_ULAW ? AST_MULAW(buf[x]) : AST_ALAW(buf[x]));
+ sum += abs(law == ast_format_ulaw ? AST_MULAW(buf[x]) : AST_ALAW(buf[x]));
return sum / len;
}
@@ -10594,13 +10593,12 @@ static void *mwi_thread(void *data)
int i, res;
unsigned int spill_done = 0;
int spill_result = -1;
- struct ast_format tmpfmt;
if (!(cs = callerid_new(mtd->pvt->cid_signalling))) {
goto quit_no_clean;
}
- callerid_feed(cs, mtd->buf, mtd->len, ast_format_set(&tmpfmt, AST_LAW(mtd->pvt), 0));
+ callerid_feed(cs, mtd->buf, mtd->len, AST_LAW(mtd->pvt));
bump_gains(mtd->pvt);
@@ -10686,7 +10684,7 @@ static void *mwi_thread(void *data)
}
samples += res;
if (!spill_done) {
- if ((spill_result = callerid_feed(cs, mtd->buf, res, ast_format_set(&tmpfmt, AST_LAW(mtd->pvt), 0))) < 0) {
+ if ((spill_result = callerid_feed(cs, mtd->buf, res, AST_LAW(mtd->pvt))) < 0) {
/*
* The previous diagnostic message output likely
* explains why it failed.
@@ -10744,7 +10742,6 @@ quit_no_clean:
static int mwi_send_init(struct dahdi_pvt * pvt)
{
int x;
- struct ast_format tmpfmt;
#ifdef HAVE_DAHDI_LINEREVERSE_VMWI
/* Determine how this spill is to be sent */
@@ -10786,8 +10783,8 @@ static int mwi_send_init(struct dahdi_pvt * pvt)
#ifdef HAVE_DAHDI_LINEREVERSE_VMWI
if (pvt->mwisend_fsk) {
#endif
- pvt->cidlen = ast_callerid_vmwi_generate(pvt->cidspill, has_voicemail(pvt), CID_MWI_TYPE_MDMF_FULL,
- ast_format_set(&tmpfmt, AST_LAW(pvt), 0), pvt->cid_name, pvt->cid_num, 0);
+ pvt->cidlen = ast_callerid_vmwi_generate(pvt->cidspill, has_voicemail(pvt),
+ CID_MWI_TYPE_MDMF_FULL, AST_LAW(pvt), pvt->cid_name, pvt->cid_num, 0);
pvt->cidpos = 0;
#ifdef HAVE_DAHDI_LINEREVERSE_VMWI
}
@@ -17314,7 +17311,8 @@ static int __unload_module(void)
dahdi_native_unload();
- dahdi_tech.capabilities = ast_format_cap_destroy(dahdi_tech.capabilities);
+ ao2_cleanup(dahdi_tech.capabilities);
+ dahdi_tech.capabilities = NULL;
STASIS_MESSAGE_TYPE_CLEANUP(dahdichannel_type);
return 0;
}
@@ -19496,7 +19494,6 @@ static const struct ast_data_entry dahdi_data_providers[] = {
static int load_module(void)
{
int res;
- struct ast_format tmpfmt;
#if defined(HAVE_PRI) || defined(HAVE_SS7)
int y;
#endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */
@@ -19505,14 +19502,15 @@ static int load_module(void)
return AST_MODULE_LOAD_FAILURE;
}
- if (!(dahdi_tech.capabilities = ast_format_cap_alloc(0))) {
+ if (!(dahdi_tech.capabilities = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT))) {
return AST_MODULE_LOAD_FAILURE;
}
- ast_format_cap_add(dahdi_tech.capabilities, ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR, 0));
- ast_format_cap_add(dahdi_tech.capabilities, ast_format_set(&tmpfmt, AST_FORMAT_ULAW, 0));
- ast_format_cap_add(dahdi_tech.capabilities, ast_format_set(&tmpfmt, AST_FORMAT_ALAW, 0));
+ ast_format_cap_append(dahdi_tech.capabilities, ast_format_slin, 0);
+ ast_format_cap_append(dahdi_tech.capabilities, ast_format_ulaw, 0);
+ ast_format_cap_append(dahdi_tech.capabilities, ast_format_alaw, 0);
if (dahdi_native_load(ast_module_info->self, &dahdi_tech)) {
+ ao2_ref(dahdi_tech.capabilities, -1);
return AST_MODULE_LOAD_FAILURE;
}
@@ -19558,8 +19556,10 @@ static int load_module(void)
#endif /* defined(HAVE_SS7) */
res = setup_dahdi(0);
/* Make sure we can register our DAHDI channel type */
- if (res)
+ if (res) {
+ __unload_module();
return AST_MODULE_LOAD_DECLINE;
+ }
if (ast_channel_register(&dahdi_tech)) {
ast_log(LOG_ERROR, "Unable to register channel class 'DAHDI'\n");
__unload_module();
@@ -19652,10 +19652,9 @@ static int dahdi_sendtext(struct ast_channel *c, const char *text)
return -1;
mybuf = buf;
if (p->mate) {
- struct ast_format tmp;
/* PUT_CLI_MARKMS is a macro and requires a format ptr called codec to be present */
- struct ast_format *codec = &tmp;
- ast_format_set(codec, AST_LAW(p), 0);
+ struct ast_format *codec = AST_LAW(p);
+
for (x = 0; x < HEADER_MS; x++) { /* 50 ms of Mark */
PUT_CLID_MARKMS;
}
diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c
index 4beacfb22..be5b4c751 100644
--- a/channels/chan_iax2.c
+++ b/channels/chan_iax2.c
@@ -116,11 +116,17 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/stasis.h"
#include "asterisk/stasis_system.h"
#include "asterisk/stasis_channels.h"
+#include "asterisk/format_cache.h"
+#include "asterisk/format_compatibility.h"
+#include "asterisk/format_cap.h"
#include "iax2/include/iax2.h"
#include "iax2/include/firmware.h"
#include "iax2/include/parser.h"
#include "iax2/include/provision.h"
+#include "iax2/include/codec_pref.h"
+#include "iax2/include/format_compatibility.h"
+
#include "jitterbuf.h"
/*** DOCUMENTATION
@@ -279,7 +285,7 @@ static int nochecksums = 0;
/* Sample over last 100 units to determine historic jitter */
#define GAMMA (0.01)
-static struct ast_codec_pref prefs;
+static struct iax2_codec_pref prefs;
static const char tdesc[] = "Inter Asterisk eXchange Driver (Ver 2)";
@@ -347,22 +353,22 @@ static int (*iax2_regfunk)(const char *username, int onoff) = NULL;
#define IAX_CAPABILITY_FULLBANDWIDTH 0xFFFF
/* T1, maybe ISDN */
#define IAX_CAPABILITY_MEDBANDWIDTH (IAX_CAPABILITY_FULLBANDWIDTH & \
- ~ast_format_id_to_old_bitfield(AST_FORMAT_SLINEAR) & \
- ~ast_format_id_to_old_bitfield(AST_FORMAT_SLINEAR16) & \
- ~ast_format_id_to_old_bitfield(AST_FORMAT_SIREN7) & \
- ~ast_format_id_to_old_bitfield(AST_FORMAT_SIREN14) & \
- ~ast_format_id_to_old_bitfield(AST_FORMAT_G719) & \
- ~ast_format_id_to_old_bitfield(AST_FORMAT_ULAW) & \
- ~ast_format_id_to_old_bitfield(AST_FORMAT_ALAW) & \
- ~ast_format_id_to_old_bitfield(AST_FORMAT_G722))
+ ~ast_format_compatibility_format2bitfield(ast_format_slin) & \
+ ~ast_format_compatibility_format2bitfield(ast_format_slin16) & \
+ ~ast_format_compatibility_format2bitfield(ast_format_siren7) & \
+ ~ast_format_compatibility_format2bitfield(ast_format_siren14) & \
+ ~ast_format_compatibility_format2bitfield(ast_format_g719) & \
+ ~ast_format_compatibility_format2bitfield(ast_format_ulaw) & \
+ ~ast_format_compatibility_format2bitfield(ast_format_alaw) & \
+ ~ast_format_compatibility_format2bitfield(ast_format_g722))
/* A modem */
#define IAX_CAPABILITY_LOWBANDWIDTH (IAX_CAPABILITY_MEDBANDWIDTH & \
- ~ast_format_id_to_old_bitfield(AST_FORMAT_G726) & \
- ~ast_format_id_to_old_bitfield(AST_FORMAT_G726_AAL2) & \
- ~ast_format_id_to_old_bitfield(AST_FORMAT_ADPCM))
+ ~ast_format_compatibility_format2bitfield(ast_format_g726) & \
+ ~ast_format_compatibility_format2bitfield(ast_format_g726_aal2) & \
+ ~ast_format_compatibility_format2bitfield(ast_format_adpcm))
#define IAX_CAPABILITY_LOWFREE (IAX_CAPABILITY_LOWBANDWIDTH & \
- ~ast_format_id_to_old_bitfield(AST_FORMAT_G723_1))
+ ~ast_format_compatibility_format2bitfield(ast_format_g723))
#define DEFAULT_MAXMS 2000 /* Must be faster than 2 seconds by default */
@@ -503,7 +509,7 @@ struct iax2_user {
iax2_format capability;
int maxauthreq; /*!< Maximum allowed outstanding AUTHREQs */
int curauthreq; /*!< Current number of outstanding AUTHREQs */
- struct ast_codec_pref prefs;
+ struct iax2_codec_pref prefs;
struct ast_acl_list *acl;
struct iax2_context *contexts;
struct ast_variable *vars;
@@ -532,7 +538,7 @@ struct iax2_peer {
AST_STRING_FIELD(zonetag); /*!< Time Zone */
AST_STRING_FIELD(parkinglot); /*!< Default parkinglot for device */
);
- struct ast_codec_pref prefs;
+ struct iax2_codec_pref prefs;
struct ast_dnsmgr_entry *dnsmgr; /*!< DNS refresh manager */
struct ast_sockaddr addr;
int formats;
@@ -708,9 +714,9 @@ struct chan_iax2_pvt {
/*! Peer Address */
struct ast_sockaddr addr;
/*! Actual used codec preferences */
- struct ast_codec_pref prefs;
+ struct iax2_codec_pref prefs;
/*! Requested codec preferences */
- struct ast_codec_pref rprefs;
+ struct iax2_codec_pref rprefs;
/*! Our call number */
unsigned short callno;
/*! Our callno_entry entry */
@@ -1809,17 +1815,18 @@ static iax2_format uncompress_subclass(unsigned char csub)
return csub;
}
-static iax2_format iax2_codec_choose(struct ast_codec_pref *pref, iax2_format formats, int find_best)
+static iax2_format iax2_codec_choose(struct iax2_codec_pref *pref, iax2_format formats, int find_best)
{
struct ast_format_cap *cap;
- struct ast_format tmpfmt;
+ struct ast_format *tmpfmt;
iax2_format format = 0;
- if ((cap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_NOLOCK))) {
- ast_format_clear(&tmpfmt);
- ast_format_cap_from_old_bitfield(cap, formats);
- ast_codec_choose(pref, cap, find_best, &tmpfmt);
- format = ast_format_to_old_bitfield(&tmpfmt);
- cap = ast_format_cap_destroy(cap);
+
+ if ((cap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT))) {
+ iax2_format_compatibility_bitfield2cap(formats, cap);
+ tmpfmt = ast_format_cap_get_format(cap, 0);
+ format = ast_format_compatibility_format2bitfield(tmpfmt);
+ ao2_ref(tmpfmt, -1);
+ ao2_ref(cap, -1);
}
return format;
@@ -1827,55 +1834,84 @@ static iax2_format iax2_codec_choose(struct ast_codec_pref *pref, iax2_format fo
static iax2_format iax2_best_codec(iax2_format formats)
{
- struct ast_format_cap *cap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_NOLOCK);
- struct ast_format tmpfmt;
+ struct ast_format_cap *cap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
+ struct ast_format *tmpfmt;
+ iax2_format format;
+
if (!cap) {
return 0;
}
- ast_format_clear(&tmpfmt);
- ast_format_cap_from_old_bitfield(cap, formats);
- ast_best_codec(cap, &tmpfmt);
- cap = ast_format_cap_destroy(cap);
- return ast_format_to_old_bitfield(&tmpfmt);
+ iax2_format_compatibility_bitfield2cap(formats, cap);
+ tmpfmt = ast_format_cap_get_format(cap, 0);
+ format = ast_format_compatibility_format2bitfield(tmpfmt);
+ ao2_ref(tmpfmt, -1);
+ ao2_ref(cap, -1);
+
+ return format;
}
const char *iax2_getformatname(iax2_format format)
{
- struct ast_format tmpfmt;
- if (!(ast_format_from_old_bitfield(&tmpfmt, format))) {
+ struct ast_format *tmpfmt;
+
+ tmpfmt = ast_format_compatibility_bitfield2format(format);
+ if (!tmpfmt) {
return "Unknown";
}
- return ast_getformatname(&tmpfmt);
+ return ast_format_get_name(tmpfmt);
}
-static char *iax2_getformatname_multiple(char *codec_buf, size_t len, iax2_format format)
+static const char *iax2_getformatname_multiple(iax2_format format, struct ast_str **codec_buf)
{
- struct ast_format_cap *cap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_NOLOCK);
+ struct ast_format_cap *cap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
if (!cap) {
return "(Nothing)";
}
- ast_format_cap_from_old_bitfield(cap, format);
- ast_getformatname_multiple(codec_buf, len, cap);
- cap = ast_format_cap_destroy(cap);
+ iax2_format_compatibility_bitfield2cap(format, cap);
+ ast_format_cap_get_names(cap, codec_buf);
+ ao2_ref(cap, -1);
- return codec_buf;
+ return ast_str_buffer(*codec_buf);
}
-static int iax2_parse_allow_disallow(struct ast_codec_pref *pref, iax2_format *formats, const char *list, int allowing)
+static int iax2_parse_allow_disallow(struct iax2_codec_pref *pref, iax2_format *formats, const char *list, int allowing)
{
- int res;
- struct ast_format_cap *cap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_NOLOCK);
+ int res, i;
+ struct ast_format_cap *cap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
+
if (!cap) {
return 1;
}
- ast_format_cap_from_old_bitfield(cap, *formats);
- res = ast_parse_allow_disallow(pref, cap, list, allowing);
- *formats = ast_format_cap_to_old_bitfield(cap);
- cap = ast_format_cap_destroy(cap);
+ /* We want to add the formats to the cap in the preferred order */
+ for (i = 0; i < IAX2_CODEC_PREF_SIZE; i++) {
+ uint64_t pref_as_bitfield = iax2_codec_pref_order_value_to_format_bitfield(pref->order[i]);
+
+ if (!pref_as_bitfield) {
+ break;
+ }
+
+ if (iax2_format_compatibility_bitfield2cap(pref_as_bitfield, cap)) {
+ ao2_ref(cap, -1);
+ return 1;
+ }
+ }
+
+ res = ast_format_cap_update_by_allow_disallow(cap, list, allowing);
+ *formats = iax2_format_compatibility_cap2bitfield(cap);
+
+ iax2_codec_pref_remove_missing(pref, *formats);
+
+ for (i = 0; i < ast_format_cap_count(cap); i++) {
+ struct ast_format *fmt = ast_format_cap_get_format(cap, i);
+ iax2_codec_pref_append(pref, fmt, ast_format_cap_get_format_framing(cap, fmt));
+ ao2_ref(fmt, -1);
+ }
+
+ ao2_ref(cap, -1);
return res;
}
@@ -1883,13 +1919,13 @@ static int iax2_parse_allow_disallow(struct ast_codec_pref *pref, iax2_format *f
static int iax2_data_add_codecs(struct ast_data *root, const char *node_name, iax2_format formats)
{
int res;
- struct ast_format_cap *cap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_NOLOCK);
+ struct ast_format_cap *cap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
if (!cap) {
return -1;
}
- ast_format_cap_from_old_bitfield(cap, formats);
+ iax2_format_compatibility_bitfield2cap(formats, cap);
res = ast_data_add_codecs(root, node_name, cap);
- cap = ast_format_cap_destroy(cap);
+ ao2_ref(cap, -1);
return res;
}
@@ -3737,9 +3773,9 @@ static char *handle_cli_iax2_show_peer(struct ast_cli_entry *e, int cmd, struct
char status[30];
char cbuf[256];
struct iax2_peer *peer;
- char codec_buf[512];
+ struct ast_str *codec_buf = ast_str_alloca(64);
struct ast_str *encmethods = ast_str_alloca(256);
- int x = 0, load_realtime = 0;
+ int load_realtime = 0;
switch (cmd) {
case CLI_INIT:
@@ -3789,23 +3825,13 @@ static char *handle_cli_iax2_show_peer(struct ast_cli_entry *e, int cmd, struct
ast_cli(a->fd, " Defaddr->IP : %s Port %s\n", str_defaddr, str_defport);
ast_cli(a->fd, " Username : %s\n", peer->username);
ast_cli(a->fd, " Codecs : ");
- iax2_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability);
- ast_cli(a->fd, "%s\n", codec_buf);
+ ast_cli(a->fd, "%s\n", iax2_getformatname_multiple(peer->capability, &codec_buf));
- ast_cli(a->fd, " Codec Order : (");
- for(x = 0; x < AST_CODEC_PREF_SIZE; x++) {
- struct ast_format tmpfmt;
- if(!(ast_codec_pref_index(&peer->prefs, x, &tmpfmt)))
- break;
- ast_cli(a->fd, "%s", ast_getformatname(&tmpfmt));
- if(x < 31 && ast_codec_pref_index(&peer->prefs, x+1, &tmpfmt))
- ast_cli(a->fd, "|");
+ ast_cli(a->fd, " Codec Order : ");
+ if (iax2_codec_pref_string(&peer->prefs, cbuf, sizeof(cbuf)) != -1) {
+ ast_cli(a->fd, "%s\n", cbuf);
}
- if (!x)
- ast_cli(a->fd, "none");
- ast_cli(a->fd, ")\n");
-
ast_cli(a->fd, " Status : ");
peer_status(peer, status, sizeof(status));
ast_cli(a->fd, "%s\n",status);
@@ -4084,9 +4110,9 @@ static void __get_from_jb(const void *p)
ms = ast_tvdiff_ms(now, pvt->rxcore);
if(ms >= (next = jb_next(pvt->jb))) {
- struct ast_format voicefmt;
- ast_format_from_old_bitfield(&voicefmt, pvt->voiceformat);
- ret = jb_get(pvt->jb, &frame, ms, ast_codec_interp_len(&voicefmt));
+ struct ast_format *voicefmt;
+ voicefmt = ast_format_compatibility_bitfield2format(pvt->voiceformat);
+ ret = jb_get(pvt->jb, &frame, ms, ast_format_get_default_ms(voicefmt));
switch(ret) {
case JB_OK:
fr = frame.data;
@@ -4100,8 +4126,8 @@ static void __get_from_jb(const void *p)
/* create an interpolation frame */
af.frametype = AST_FRAME_VOICE;
- ast_format_copy(&af.subclass.format, &voicefmt);
- af.samples = frame.ms * (ast_format_rate(&voicefmt) / 1000);
+ af.subclass.format = voicefmt;
+ af.samples = frame.ms * (ast_format_get_sample_rate(voicefmt) / 1000);
af.src = "IAX2 JB interpolation";
af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000));
af.offset = AST_FRIENDLY_OFFSET;
@@ -4182,7 +4208,7 @@ static int schedule_delivery(struct iax_frame *fr, int updatehistory, int fromtr
if(fr->af.frametype == AST_FRAME_VOICE) {
type = JB_TYPE_VOICE;
- len = ast_codec_get_samples(&fr->af) / (ast_format_rate(&fr->af.subclass.format) / 1000);
+ len = ast_codec_samples_count(&fr->af) / (ast_format_get_sample_rate(fr->af.subclass.format) / 1000);
} else if(fr->af.frametype == AST_FRAME_CNG) {
type = JB_TYPE_SILENCE;
}
@@ -4579,7 +4605,7 @@ static int create_addr(const char *peername, struct ast_channel *c, struct ast_s
{
struct iax2_peer *peer;
int res = -1;
- struct ast_codec_pref ourprefs;
+ struct iax2_codec_pref ourprefs;
ast_clear_flag64(cai, IAX_SENDANI | IAX_TRUNK);
cai->sockfd = defaultsockfd;
@@ -4604,14 +4630,16 @@ static int create_addr(const char *peername, struct ast_channel *c, struct ast_s
/* But move the calling channel's native codec to the top of the preference list */
memcpy(&ourprefs, &prefs, sizeof(ourprefs));
if (c) {
- struct ast_format tmpfmt;
- ast_format_cap_iter_start(ast_channel_nativeformats(c));
- while (!(ast_format_cap_iter_next(ast_channel_nativeformats(c), &tmpfmt))) {
- ast_codec_pref_prepend(&ourprefs, &tmpfmt, 1);
+ int i;
+
+ for (i = 0; i < ast_format_cap_count(ast_channel_nativeformats(c)); i++) {
+ struct ast_format *format = ast_format_cap_get_format(
+ ast_channel_nativeformats(c), i);
+ iax2_codec_pref_prepend(&ourprefs, format, ast_format_cap_get_format_framing(ast_channel_nativeformats(c), format), 1);
+ ao2_ref(format, -1);
}
- ast_format_cap_iter_end(ast_channel_nativeformats(c));
}
- ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
+ iax2_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
return 0;
}
@@ -4635,15 +4663,16 @@ static int create_addr(const char *peername, struct ast_channel *c, struct ast_s
memcpy(&ourprefs, &peer->prefs, sizeof(ourprefs));
/* Move the calling channel's native codec to the top of the preference list */
if (c) {
- struct ast_format tmpfmt;
- ast_format_cap_iter_start(ast_channel_nativeformats(c));
- while (!(ast_format_cap_iter_next(ast_channel_nativeformats(c), &tmpfmt))) {
- ast_debug(1, "prepending %s to prefs\n", ast_getformatname(&tmpfmt));
- ast_codec_pref_prepend(&ourprefs, &tmpfmt, 1);
+ int i;
+
+ for (i = 0; i < ast_format_cap_count(ast_channel_nativeformats(c)); i++) {
+ struct ast_format *tmpfmt = ast_format_cap_get_format(
+ ast_channel_nativeformats(c), i);
+ iax2_codec_pref_prepend(&ourprefs, tmpfmt, ast_format_cap_get_format_framing(ast_channel_nativeformats(c), tmpfmt), 1);
+ ao2_ref(tmpfmt, -1);
}
- ast_format_cap_iter_end(ast_channel_nativeformats(c));
}
- ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
+ iax2_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
ast_copy_string(cai->context, peer->context, sizeof(cai->context));
ast_copy_string(cai->peercontext, peer->peercontext, sizeof(cai->peercontext));
ast_copy_string(cai->username, peer->username, sizeof(cai->username));
@@ -5181,7 +5210,7 @@ static int iax2_call(struct ast_channel *c, const char *dest, int timeout)
if (pds.password)
ast_string_field_set(iaxs[callno], secret, pds.password);
- iax2_tmpfmt = ast_format_cap_to_old_bitfield(ast_channel_nativeformats(c));
+ iax2_tmpfmt = iax2_format_compatibility_cap2bitfield(ast_channel_nativeformats(c));
iax_ie_append_int(&ied, IAX_IE_FORMAT, (int) iax2_tmpfmt);
iax_ie_append_versioned_uint64(&ied, IAX_IE_FORMAT2, 0, iax2_tmpfmt);
@@ -5551,11 +5580,13 @@ static enum ast_bridge_result iax2_bridge(struct ast_channel *c0, struct ast_cha
return AST_BRIDGE_FAILED_NOWARN;
}
if (!(ast_format_cap_identical(ast_channel_nativeformats(c0), ast_channel_nativeformats(c1)))) {
- char buf0[256];
- char buf1[256];
- ast_getformatname_multiple(buf0, sizeof(buf0), ast_channel_nativeformats(c0));
- ast_getformatname_multiple(buf1, sizeof(buf1), ast_channel_nativeformats(c1));
- ast_verb(3, "Operating with different codecs [%s] [%s] , can't native bridge...\n", buf0, buf1);
+ struct ast_str *c0_buf = ast_str_alloca(64);
+ struct ast_str *c1_buf = ast_str_alloca(64);
+
+ ast_verb(3, "Operating with different codecs [%s] [%s] , can't native bridge...\n",
+ ast_format_cap_get_names(ast_channel_nativeformats(c0), &c0_buf),
+ ast_format_cap_get_names(ast_channel_nativeformats(c1), &c1_buf));
+
/* Remove from native mode */
lock_both(callno0, callno1);
if (iaxs[callno0])
@@ -5780,7 +5811,8 @@ static struct ast_channel *ast_iax2_new(int callno, int state, iax2_format capab
struct ast_channel *tmp;
struct chan_iax2_pvt *i;
struct ast_variable *v = NULL;
- struct ast_format tmpfmt;
+ struct ast_format_cap *native;
+ struct ast_format *tmpfmt;
struct ast_callid *callid;
if (!(i = iaxs[callno])) {
@@ -5788,6 +5820,11 @@ static struct ast_channel *ast_iax2_new(int callno, int state, iax2_format capab
return NULL;
}
+ native = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
+ if (!native) {
+ return NULL;
+ }
+
/* Don't hold call lock */
ast_mutex_unlock(&iaxsl[callno]);
tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, i->accountcode, i->exten, i->context, assignedids, requestor, i->amaflags, "IAX2/%s-%d", i->host, i->callno);
@@ -5800,9 +5837,11 @@ static struct ast_channel *ast_iax2_new(int callno, int state, iax2_format capab
tmp = ast_channel_release(tmp);
ast_mutex_lock(&iaxsl[callno]);
}
+ ao2_ref(native, -1);
return NULL;
}
if (!tmp) {
+ ao2_ref(native, -1);
return NULL;
}
@@ -5813,14 +5852,19 @@ static struct ast_channel *ast_iax2_new(int callno, int state, iax2_format capab
}
ast_channel_tech_set(tmp, &iax2_tech);
+
/* We can support any format by default, until we get restricted */
- ast_format_cap_from_old_bitfield(ast_channel_nativeformats(tmp), capability);
- ast_best_codec(ast_channel_nativeformats(tmp), &tmpfmt);
+ iax2_format_compatibility_bitfield2cap(capability, native);
+ ast_channel_nativeformats_set(tmp, native);
+ tmpfmt = ast_format_cap_get_format(ast_channel_nativeformats(tmp), 0);
- ast_format_copy(ast_channel_readformat(tmp), &tmpfmt);
- ast_format_copy(ast_channel_rawreadformat(tmp), &tmpfmt);
- ast_format_copy(ast_channel_writeformat(tmp), &tmpfmt);
- ast_format_copy(ast_channel_rawwriteformat(tmp), &tmpfmt);
+ ast_channel_set_readformat(tmp, tmpfmt);
+ ast_channel_set_rawreadformat(tmp, tmpfmt);
+ ast_channel_set_writeformat(tmp, tmpfmt);
+ ast_channel_set_rawwriteformat(tmp, tmpfmt);
+
+ ao2_ref(tmpfmt, -1);
+ ao2_ref(native, -1);
ast_channel_tech_pvt_set(tmp, CALLNO_TO_PTR(i->callno));
@@ -5971,7 +6015,7 @@ static unsigned int calc_timestamp(struct chan_iax2_pvt *p, unsigned int ts, str
int voice = 0;
int genuine = 0;
int adjust;
- int rate = ast_format_rate(&f->subclass.format) / 1000;
+ int rate = 0;
struct timeval *delivery = NULL;
@@ -5983,6 +6027,7 @@ static unsigned int calc_timestamp(struct chan_iax2_pvt *p, unsigned int ts, str
*/
if (f->frametype == AST_FRAME_VOICE) {
voice = 1;
+ rate = ast_format_get_sample_rate(f->subclass.format) / 1000;
delivery = &f->delivery;
} else if (f->frametype == AST_FRAME_IAX) {
genuine = 1;
@@ -6092,8 +6137,9 @@ static unsigned int calc_timestamp(struct chan_iax2_pvt *p, unsigned int ts, str
}
}
p->lastsent = ms;
- if (voice)
+ if (voice) {
p->nextpred = p->nextpred + f->samples / rate;
+ }
return ms;
}
@@ -6344,9 +6390,9 @@ static int decode_frame(ast_aes_decrypt_key *dcx, struct ast_iax2_full_hdr *fh,
memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
f->frametype = fh->type;
if (f->frametype == AST_FRAME_VIDEO) {
- ast_format_from_old_bitfield(&f->subclass.format, (uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1)));
+ f->subclass.format = ast_format_compatibility_bitfield2format(uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1));
} else if (f->frametype == AST_FRAME_VOICE) {
- ast_format_from_old_bitfield(&f->subclass.format, uncompress_subclass(fh->csub));
+ f->subclass.format = ast_format_compatibility_bitfield2format(uncompress_subclass(fh->csub));
} else {
f->subclass.integer = uncompress_subclass(fh->csub);
}
@@ -6487,7 +6533,7 @@ static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned in
/* High two bytes are the same on timestamp, or sending on a trunk */ &&
(f->frametype == AST_FRAME_VOICE)
/* is a voice frame */ &&
- (f->subclass.format.id == ast_format_id_from_old_bitfield(pvt->svoiceformat))
+ (ast_format_cmp(f->subclass.format, ast_format_compatibility_bitfield2format(pvt->svoiceformat)))
/* is the same type */ ) {
/* Force immediate rather than delayed transmission */
now = 1;
@@ -6501,7 +6547,7 @@ static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned in
* Otherwise send a mini video frame
*/
if (((fts & 0xFFFF8000L) == (pvt->lastvsent & 0xFFFF8000L)) &&
- ((f->subclass.format.id) == ast_format_id_from_old_bitfield(pvt->svideoformat))
+ (ast_format_cmp(f->subclass.format, ast_format_compatibility_bitfield2format(pvt->svideoformat)))
) {
now = 1;
sendmini = 1;
@@ -6556,11 +6602,11 @@ static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned in
fh->type = fr->af.frametype & 0xFF;
if (fr->af.frametype == AST_FRAME_VIDEO) {
- iax2_format tmpfmt = ast_format_to_old_bitfield(&fr->af.subclass.format);
- tmpfmt |= ast_format_get_video_mark(&fr->af.subclass.format) ? 0x1LL : 0;
+ iax2_format tmpfmt = ast_format_compatibility_format2bitfield(fr->af.subclass.format);
+ tmpfmt |= fr->af.subclass.frame_ending ? 0x1LL : 0;
fh->csub = compress_subclass(tmpfmt | ((tmpfmt & 0x1LL) << 6));
} else if (fr->af.frametype == AST_FRAME_VOICE) {
- fh->csub = compress_subclass(ast_format_to_old_bitfield(&fr->af.subclass.format));
+ fh->csub = compress_subclass(ast_format_compatibility_format2bitfield(fr->af.subclass.format));
} else {
fh->csub = compress_subclass(fr->af.subclass.integer);
}
@@ -6583,9 +6629,9 @@ static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned in
if ((f->frametype == AST_FRAME_IAX) && (f->subclass.integer == IAX_COMMAND_ACK))
fr->retries = -1;
else if (f->frametype == AST_FRAME_VOICE)
- pvt->svoiceformat = ast_format_to_old_bitfield(&f->subclass.format);
+ pvt->svoiceformat = ast_format_compatibility_format2bitfield(f->subclass.format);
else if (f->frametype == AST_FRAME_VIDEO)
- pvt->svideoformat = ast_format_to_old_bitfield(&f->subclass.format);
+ pvt->svideoformat = ast_format_compatibility_format2bitfield(f->subclass.format);
if (ast_test_flag64(pvt, IAX_ENCRYPTED)) {
if (ast_test_flag64(pvt, IAX_KEYPOPULATED)) {
if (fr->transfer)
@@ -6616,7 +6662,7 @@ static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned in
vh = (struct ast_iax2_video_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_video_hdr));
vh->zeros = 0;
vh->callno = htons(0x8000 | fr->callno);
- vh->ts = htons((fr->ts & 0x7FFF) | (ast_format_get_video_mark(&fr->af.subclass.format) ? 0x8000 : 0));
+ vh->ts = htons((fr->ts & 0x7FFF) | (fr->af.subclass.frame_ending ? 0x8000 : 0));
fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_video_hdr);
fr->data = vh;
fr->retries = -1;
@@ -7767,8 +7813,8 @@ static int check_access(int callno, struct ast_sockaddr *addr, struct iax_ies *i
/* Use provided preferences until told otherwise for actual preferences */
if (ies->codec_prefs) {
- ast_codec_pref_convert(&iaxs[callno]->rprefs, ies->codec_prefs, 32, 0);
- ast_codec_pref_convert(&iaxs[callno]->prefs, ies->codec_prefs, 32, 0);
+ iax2_codec_pref_convert(&iaxs[callno]->rprefs, ies->codec_prefs, 32, 0);
+ iax2_codec_pref_convert(&iaxs[callno]->prefs, ies->codec_prefs, 32, 0);
}
if (!gotcapability) {
@@ -9827,7 +9873,7 @@ static int socket_process_meta(int packet_len, struct ast_iax2_meta_hdr *meta, s
ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n");
iax2_vnak(fr->callno);
} else {
- ast_format_from_old_bitfield(&f.subclass.format, iaxs[fr->callno]->voiceformat);
+ f.subclass.format = ast_format_compatibility_bitfield2format(iaxs[fr->callno]->voiceformat);
f.datalen = len;
if (f.datalen >= 0) {
if (f.datalen)
@@ -9847,7 +9893,7 @@ static int socket_process_meta(int packet_len, struct ast_iax2_meta_hdr *meta, s
f.mallocd = 0;
f.offset = 0;
if (f.datalen && (f.frametype == AST_FRAME_VOICE))
- f.samples = ast_codec_get_samples(&f);
+ f.samples = ast_codec_samples_count(&f);
else
f.samples = 0;
fr->outoforder = 0;
@@ -10004,7 +10050,7 @@ static int socket_process_helper(struct iax2_thread *thread)
struct iax_frame *duped_fr;
char host_pref_buf[128];
char caller_pref_buf[128];
- struct ast_codec_pref pref;
+ struct iax2_codec_pref pref;
char *using_prefs = "mine";
/* allocate an iax_frame with 4096 bytes of data buffer */
@@ -10069,12 +10115,12 @@ static int socket_process_helper(struct iax2_thread *thread)
/* Retrieve the type and subclass */
f.frametype = fh->type;
if (f.frametype == AST_FRAME_VIDEO) {
- ast_format_from_old_bitfield(&f.subclass.format, (uncompress_subclass(fh->csub & ~0x40)));
+ f.subclass.format = ast_format_compatibility_bitfield2format(uncompress_subclass(fh->csub & ~0x40));
if ((fh->csub >> 6) & 0x1) {
- ast_format_set_video_mark(&f.subclass.format);
+ f.subclass.frame_ending = 1;
}
} else if (f.frametype == AST_FRAME_VOICE) {
- ast_format_from_old_bitfield(&f.subclass.format, uncompress_subclass(fh->csub));
+ f.subclass.format = ast_format_compatibility_bitfield2format(uncompress_subclass(fh->csub));
} else {
f.subclass.integer = uncompress_subclass(fh->csub);
}
@@ -10498,22 +10544,21 @@ static int socket_process_helper(struct iax2_thread *thread)
}
if (f.frametype == AST_FRAME_VOICE) {
- if (ast_format_to_old_bitfield(&f.subclass.format) != iaxs[fr->callno]->voiceformat) {
- iaxs[fr->callno]->voiceformat = ast_format_to_old_bitfield(&f.subclass.format);
- ast_debug(1, "Ooh, voice format changed to '%s'\n", ast_getformatname(&f.subclass.format));
+ if (ast_format_compatibility_format2bitfield(f.subclass.format) != iaxs[fr->callno]->voiceformat) {
+ iaxs[fr->callno]->voiceformat = ast_format_compatibility_format2bitfield(f.subclass.format);
+ ast_debug(1, "Ooh, voice format changed to '%s'\n", ast_format_get_name(f.subclass.format));
if (iaxs[fr->callno]->owner) {
iax2_lock_owner(fr->callno);
if (iaxs[fr->callno]) {
if (iaxs[fr->callno]->owner) {
- struct ast_format_cap *orignative = ast_format_cap_dup(ast_channel_nativeformats(iaxs[fr->callno]->owner));
- struct ast_format_cap *native = ast_channel_nativeformats(iaxs[fr->callno]->owner);
- if (orignative) {
- ast_format_cap_set(native, &f.subclass.format);
- if (ast_channel_readformat(iaxs[fr->callno]->owner)->id) {
+ struct ast_format_cap *native = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
+ if (native) {
+ ast_format_cap_append(native, f.subclass.format, 0);
+ ast_channel_nativeformats_set(iaxs[fr->callno]->owner, native);
+ if (ast_channel_readformat(iaxs[fr->callno]->owner)) {
ast_set_read_format(iaxs[fr->callno]->owner, ast_channel_readformat(iaxs[fr->callno]->owner));
}
- ast_format_cap_copy(native, orignative);
- orignative = ast_format_cap_destroy(orignative);
+ ao2_ref(native, -1);
}
ast_channel_unlock(iaxs[fr->callno]->owner);
}
@@ -10532,9 +10577,9 @@ static int socket_process_helper(struct iax2_thread *thread)
}
}
if (f.frametype == AST_FRAME_VIDEO) {
- if (f.subclass.format.id != ast_format_id_from_old_bitfield(iaxs[fr->callno]->videoformat)) {
- ast_debug(1, "Ooh, video format changed to %s\n", ast_getformatname(&f.subclass.format));
- iaxs[fr->callno]->videoformat = ast_format_to_old_bitfield(&f.subclass.format);
+ if (ast_format_compatibility_format2bitfield(f.subclass.format) != iaxs[fr->callno]->videoformat) {
+ ast_debug(1, "Ooh, video format changed to %s\n", ast_format_get_name(f.subclass.format));
+ iaxs[fr->callno]->videoformat = ast_format_compatibility_format2bitfield(f.subclass.format);
}
}
if (f.frametype == AST_FRAME_IAX) {
@@ -10697,12 +10742,12 @@ static int socket_process_helper(struct iax2_thread *thread)
strcpy(caller_pref_buf, "disabled");
strcpy(host_pref_buf, "disabled");
} else {
- struct ast_format tmpfmt;
+ struct ast_format *tmpfmt;
using_prefs = "mine";
/* If the information elements are in here... use them */
if (ies.codec_prefs)
- ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
- if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0, &tmpfmt)) {
+ iax2_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
+ if (iax2_codec_pref_index(&iaxs[fr->callno]->rprefs, 0, &tmpfmt)) {
/* If we are codec_first_choice we let the caller have the 1st shot at picking the codec.*/
if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
pref = iaxs[fr->callno]->rprefs;
@@ -10714,8 +10759,8 @@ static int socket_process_helper(struct iax2_thread *thread)
pref = iaxs[fr->callno]->prefs;
format = iax2_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
- ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
- ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
+ iax2_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
+ iax2_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
}
if (!format) {
if(!ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP))
@@ -10729,18 +10774,21 @@ static int socket_process_helper(struct iax2_thread *thread)
break;
}
if (authdebug) {
- char tmp[256], tmp2[256], tmp3[256];
+ struct ast_str *peer_buf = ast_str_alloca(64);
+ struct ast_str *cap_buf = ast_str_alloca(64);
+ struct ast_str *peer_form_buf = ast_str_alloca(64);
+
if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n",
ast_sockaddr_stringify(&addr),
- iax2_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat),
- iax2_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
+ iax2_getformatname_multiple(iaxs[fr->callno]->peerformat, &peer_form_buf),
+ iax2_getformatname_multiple(iaxs[fr->callno]->capability, &cap_buf));
} else {
ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
ast_sockaddr_stringify(&addr),
- iax2_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat),
- iax2_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability),
- iax2_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability));
+ iax2_getformatname_multiple(iaxs[fr->callno]->peerformat, &peer_form_buf),
+ iax2_getformatname_multiple(iaxs[fr->callno]->peercapability, &peer_buf),
+ iax2_getformatname_multiple(iaxs[fr->callno]->capability, &cap_buf));
}
}
} else {
@@ -10756,9 +10804,9 @@ static int socket_process_helper(struct iax2_thread *thread)
strcpy(caller_pref_buf,"disabled");
strcpy(host_pref_buf,"disabled");
} else {
- struct ast_format tmpfmt;
+ struct ast_format *tmpfmt;
using_prefs = "mine";
- if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0, &tmpfmt)) {
+ if (iax2_codec_pref_index(&iaxs[fr->callno]->rprefs, 0, &tmpfmt)) {
/* Do the opposite of what we tried above. */
if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
pref = iaxs[fr->callno]->prefs;
@@ -10773,11 +10821,14 @@ static int socket_process_helper(struct iax2_thread *thread)
}
if (!format) {
- char tmp[256], tmp2[256], tmp3[256];
+ struct ast_str *peer_buf = ast_str_alloca(64);
+ struct ast_str *cap_buf = ast_str_alloca(64);
+ struct ast_str *peer_form_buf = ast_str_alloca(64);
+
memset(&ied0, 0, sizeof(ied0));
iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
- ast_log(LOG_ERROR, "No best format in '%s'???\n", iax2_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability));
+ ast_log(LOG_ERROR, "No best format in '%s'???\n", iax2_getformatname_multiple(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, &cap_buf));
send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
if (!iaxs[fr->callno]) {
break;
@@ -10785,9 +10836,9 @@ static int socket_process_helper(struct iax2_thread *thread)
if (authdebug) {
ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
ast_sockaddr_stringify(&addr),
- iax2_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat),
- iax2_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability),
- iax2_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability));
+ iax2_getformatname_multiple(iaxs[fr->callno]->peerformat, &peer_form_buf),
+ iax2_getformatname_multiple(iaxs[fr->callno]->peercapability, &peer_buf),
+ iax2_getformatname_multiple(iaxs[fr->callno]->capability, &cap_buf));
}
ast_set_flag64(iaxs[fr->callno], IAX_ALREADYGONE);
break;
@@ -10935,7 +10986,7 @@ static int socket_process_helper(struct iax2_thread *thread)
iaxs[fr->callno]->peerformat = ies.format;
} else {
if (iaxs[fr->callno]->owner)
- iaxs[fr->callno]->peerformat = ast_format_cap_to_old_bitfield(ast_channel_nativeformats(iaxs[fr->callno]->owner));
+ iaxs[fr->callno]->peerformat = iax2_format_compatibility_cap2bitfield(ast_channel_nativeformats(iaxs[fr->callno]->owner));
else
iaxs[fr->callno]->peerformat = iaxs[fr->callno]->capability;
}
@@ -10950,28 +11001,36 @@ static int socket_process_helper(struct iax2_thread *thread)
break;
}
if (authdebug) {
- char tmp1[256], tmp2[256];
+ struct ast_str *peer_buf = ast_str_alloca(64);
+ struct ast_str *cap_buf = ast_str_alloca(64);
+
ast_log(LOG_NOTICE, "Rejected call to %s, format %s incompatible with our capability %s.\n",
ast_sockaddr_stringify(&addr),
- iax2_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
- iax2_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
+ iax2_getformatname_multiple(iaxs[fr->callno]->peerformat, &peer_buf),
+ iax2_getformatname_multiple(iaxs[fr->callno]->capability, &cap_buf));
}
} else {
+ struct ast_format_cap *native = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
+
ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
iax2_lock_owner(fr->callno);
- if (iaxs[fr->callno] && iaxs[fr->callno]->owner) {
- char tmp[256];
+ if (iaxs[fr->callno] && iaxs[fr->callno]->owner && native) {
+ struct ast_str *cap_buf = ast_str_alloca(64);
+
/* Switch us to use a compatible format */
- ast_format_cap_from_old_bitfield(ast_channel_nativeformats(iaxs[fr->callno]->owner), iaxs[fr->callno]->peerformat);
- ast_verb(3, "Format for call is %s\n", ast_getformatname_multiple(tmp, sizeof(tmp), ast_channel_nativeformats(iaxs[fr->callno]->owner)));
+ iax2_format_compatibility_bitfield2cap(iaxs[fr->callno]->peerformat, native);
+ ast_channel_nativeformats_set(iaxs[fr->callno]->owner, native);
+ ast_verb(3, "Format for call is %s\n", ast_format_cap_get_names(ast_channel_nativeformats(iaxs[fr->callno]->owner), &cap_buf));
/* Setup read/write formats properly. */
- if (ast_channel_writeformat(iaxs[fr->callno]->owner)->id)
+ if (ast_channel_writeformat(iaxs[fr->callno]->owner))
ast_set_write_format(iaxs[fr->callno]->owner, ast_channel_writeformat(iaxs[fr->callno]->owner));
- if (ast_channel_readformat(iaxs[fr->callno]->owner)->id)
+ if (ast_channel_readformat(iaxs[fr->callno]->owner))
ast_set_read_format(iaxs[fr->callno]->owner, ast_channel_readformat(iaxs[fr->callno]->owner));
ast_channel_unlock(iaxs[fr->callno]->owner);
}
+
+ ao2_cleanup(native);
}
if (iaxs[fr->callno]) {
AST_LIST_LOCK(&dpcache);
@@ -11140,11 +11199,11 @@ static int socket_process_helper(struct iax2_thread *thread)
strcpy(caller_pref_buf, "disabled");
strcpy(host_pref_buf, "disabled");
} else {
- struct ast_format tmpfmt;
+ struct ast_format *tmpfmt;
using_prefs = "mine";
if (ies.codec_prefs)
- ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
- if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0, &tmpfmt)) {
+ iax2_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
+ if (iax2_codec_pref_index(&iaxs[fr->callno]->rprefs, 0, &tmpfmt)) {
if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
pref = iaxs[fr->callno]->rprefs;
using_prefs = "caller";
@@ -11154,15 +11213,18 @@ static int socket_process_helper(struct iax2_thread *thread)
} else /* if no codec_prefs IE do it the old way */
pref = iaxs[fr->callno]->prefs;
format = iax2_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
- ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
- ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
+ iax2_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
+ iax2_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
}
if (!format) {
- char tmp1[256], tmp2[256], tmp3[256];
+ struct ast_str *cap_buf = ast_str_alloca(64);
+ struct ast_str *peer_buf = ast_str_alloca(64);
+ struct ast_str *peer_form_buf = ast_str_alloca(64);
+
if(!ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
ast_debug(1, "We don't do requested format %s, falling back to peer capability '%s'\n",
iax2_getformatname(iaxs[fr->callno]->peerformat),
- iax2_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peercapability));
+ iax2_getformatname_multiple(iaxs[fr->callno]->peercapability, &peer_buf));
format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
}
if (!format) {
@@ -11170,14 +11232,14 @@ static int socket_process_helper(struct iax2_thread *thread)
if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n",
ast_sockaddr_stringify(&addr),
- iax2_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
- iax2_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
+ iax2_getformatname_multiple(iaxs[fr->callno]->peerformat, &peer_form_buf),
+ iax2_getformatname_multiple(iaxs[fr->callno]->capability, &cap_buf));
} else {
ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
ast_sockaddr_stringify(&addr),
- iax2_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
- iax2_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability),
- iax2_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability));
+ iax2_getformatname_multiple(iaxs[fr->callno]->peerformat, &peer_form_buf),
+ iax2_getformatname_multiple(iaxs[fr->callno]->peercapability, &peer_buf),
+ iax2_getformatname_multiple(iaxs[fr->callno]->capability, &cap_buf));
}
}
memset(&ied0, 0, sizeof(ied0));
@@ -11201,9 +11263,9 @@ static int socket_process_helper(struct iax2_thread *thread)
strcpy(caller_pref_buf,"disabled");
strcpy(host_pref_buf,"disabled");
} else {
- struct ast_format tmpfmt;
+ struct ast_format *tmpfmt;
using_prefs = "mine";
- if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0, &tmpfmt)) {
+ if (iax2_codec_pref_index(&iaxs[fr->callno]->rprefs, 0, &tmpfmt)) {
/* Do the opposite of what we tried above. */
if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
pref = iaxs[fr->callno]->prefs;
@@ -11217,21 +11279,24 @@ static int socket_process_helper(struct iax2_thread *thread)
}
}
if (!format) {
- char tmp1[256], tmp2[256], tmp3[256];
+ struct ast_str *cap_buf = ast_str_alloca(64);
+ struct ast_str *peer_buf = ast_str_alloca(64);
+ struct ast_str *peer_form_buf = ast_str_alloca(64);
+
ast_log(LOG_ERROR, "No best format in %s???\n",
- iax2_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability));
+ iax2_getformatname_multiple(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, &cap_buf));
if (authdebug) {
if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n",
ast_sockaddr_stringify(&addr),
- iax2_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
- iax2_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
+ iax2_getformatname_multiple(iaxs[fr->callno]->peerformat, &peer_form_buf),
+ iax2_getformatname_multiple(iaxs[fr->callno]->capability, &cap_buf));
} else {
ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
ast_sockaddr_stringify(&addr),
- iax2_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
- iax2_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability),
- iax2_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability));
+ iax2_getformatname_multiple(iaxs[fr->callno]->peerformat, &peer_form_buf),
+ iax2_getformatname_multiple(iaxs[fr->callno]->peercapability, &peer_buf),
+ iax2_getformatname_multiple(iaxs[fr->callno]->capability, &cap_buf));
}
}
memset(&ied0, 0, sizeof(ied0));
@@ -11338,11 +11403,11 @@ immediatedial:
break;
}
} else {
- char tmp[256];
+ struct ast_str *cap_buf = ast_str_alloca(64);
ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
ast_verb(3, "Accepting DIAL from %s, formats = %s\n",
ast_sockaddr_stringify(&addr),
- iax2_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat));
+ iax2_getformatname_multiple(iaxs[fr->callno]->peerformat, &cap_buf));
ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1);
if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat, NULL, NULL, 1)))
@@ -11662,9 +11727,9 @@ immediatedial:
f.frametype = AST_FRAME_VIDEO;
if (iaxs[fr->callno]->videoformat > 0) {
if (ntohs(vh->ts) & 0x8000LL) {
- ast_format_set_video_mark(&f.subclass.format);
+ f.subclass.frame_ending = 1;
}
- ast_format_from_old_bitfield(&f.subclass.format, iaxs[fr->callno]->videoformat);
+ f.subclass.format = ast_format_compatibility_bitfield2format(iaxs[fr->callno]->videoformat);
} else {
ast_log(LOG_WARNING, "Received mini frame before first full video frame\n");
iax2_vnak(fr->callno);
@@ -11687,7 +11752,7 @@ immediatedial:
/* A mini frame */
f.frametype = AST_FRAME_VOICE;
if (iaxs[fr->callno]->voiceformat > 0)
- ast_format_from_old_bitfield(&f.subclass.format, iaxs[fr->callno]->voiceformat);
+ f.subclass.format = ast_format_compatibility_bitfield2format(iaxs[fr->callno]->voiceformat);
else {
ast_debug(1, "Received mini frame before first full voice frame\n");
iax2_vnak(fr->callno);
@@ -11795,9 +11860,9 @@ immediatedial:
f.offset = 0;
f.len = 0;
if (f.datalen && (f.frametype == AST_FRAME_VOICE)) {
- f.samples = ast_codec_get_samples(&f);
+ f.samples = ast_codec_samples_count(&f);
/* We need to byteswap incoming slinear samples from network byte order */
- if (f.subclass.format.id == AST_FORMAT_SLINEAR)
+ if (ast_format_cmp(f.subclass.format, ast_format_slin) == AST_FORMAT_CMP_EQUAL)
ast_frame_byteswap_be(&f);
} else
f.samples = 0;
@@ -12376,32 +12441,48 @@ static struct ast_channel *iax2_request(const char *type, struct ast_format_cap
if (c) {
struct ast_format_cap *joint;
+ struct ast_format *format;
if (callid) {
ast_channel_lock(c);
ast_channel_callid_set(c, callid);
ast_channel_unlock(c);
}
- /* Choose a format we can live with */
- if ((joint = ast_format_cap_joint(ast_channel_nativeformats(c), cap))) {
- ast_format_cap_copy(ast_channel_nativeformats(c), joint);
- joint = ast_format_cap_destroy(joint);
- } else {
- struct ast_format best_fmt_cap;
- struct ast_format best_fmt_native;
+ joint = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
+ if (!joint) {
+ ast_hangup(c);
+ return NULL;
+ }
+
+ ast_format_cap_get_compatible(ast_channel_nativeformats(c), cap, joint);
+
+ /* If there is no joint format find one through translation */
+ if (!ast_format_cap_count(joint)) {
+ struct ast_format *best_fmt_cap = NULL;
+ struct ast_format *best_fmt_native = NULL;
res = ast_translator_best_choice(cap, ast_channel_nativeformats(c), &best_fmt_cap, &best_fmt_native);
if (res < 0) {
- char tmp[256];
- char tmp2[256];
+ struct ast_str *native_cap_buf = ast_str_alloca(64);
+ struct ast_str *cap_buf = ast_str_alloca(64);
+
ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n",
- ast_getformatname_multiple(tmp, sizeof(tmp), ast_channel_nativeformats(c)), ast_getformatname_multiple(tmp2, sizeof(tmp2), cap), ast_channel_name(c));
+ ast_format_cap_get_names(ast_channel_nativeformats(c), &native_cap_buf),
+ ast_format_cap_get_names(cap, &cap_buf),
+ ast_channel_name(c));
ast_hangup(c);
return NULL;
}
- ast_format_cap_set(ast_channel_nativeformats(c), &best_fmt_native);
+ ast_format_cap_append(joint, best_fmt_native, 0);
+ ao2_ref(best_fmt_cap, -1);
+ ao2_ref(best_fmt_native, -1);
}
- ast_best_codec(ast_channel_nativeformats(c), ast_channel_readformat(c));
- ast_format_copy(ast_channel_writeformat(c), ast_channel_readformat(c));
+ ast_channel_nativeformats_set(c, joint);
+ format = ast_format_cap_get_format(ast_channel_nativeformats(c), 0);
+ ast_channel_set_readformat(c, format);
+ ast_channel_set_writeformat(c, format);
+
+ ao2_ref(joint, -1);
+ ao2_ref(format, -1);
}
if (callid) {
@@ -13355,7 +13436,7 @@ static int set_config(const char *config_file, int reload, int forced)
ast_sockaddr_parse(&bindaddr, "0.0.0.0:0", 0);
/* Reset global codec prefs */
- memset(&prefs, 0 , sizeof(struct ast_codec_pref));
+ memset(&prefs, 0 , sizeof(struct iax2_codec_pref));
/* Reset Global Flags */
memset(&globalflags, 0, sizeof(globalflags));
@@ -14234,10 +14315,13 @@ static int function_iaxpeer(struct ast_channel *chan, const char *cmd, char *dat
} else if (!strcasecmp(colname, "callerid_num")) {
ast_copy_string(buf, peer->cid_num, len);
} else if (!strcasecmp(colname, "codecs")) {
- iax2_getformatname_multiple(buf, len -1, peer->capability);
+ struct ast_str *codec_buf;
+
+ iax2_getformatname_multiple(peer->capability, &codec_buf);
+ ast_copy_string(buf, ast_str_buffer(codec_buf), len);
} else if (!strncasecmp(colname, "codec[", 6)) {
char *codecnum, *ptr;
- struct ast_format tmpfmt;
+ struct ast_format *tmpfmt;
/* skip over "codec" to the '[' */
codecnum = colname + 5;
@@ -14246,8 +14330,8 @@ static int function_iaxpeer(struct ast_channel *chan, const char *cmd, char *dat
if ((ptr = strchr(codecnum, ']'))) {
*ptr = '\0';
}
- if((ast_codec_pref_index(&peer->prefs, atoi(codecnum), &tmpfmt))) {
- ast_copy_string(buf, ast_getformatname(&tmpfmt), len);
+ if((iax2_codec_pref_index(&peer->prefs, atoi(codecnum), &tmpfmt))) {
+ ast_copy_string(buf, ast_format_get_name(tmpfmt), len);
} else {
buf[0] = '\0';
}
@@ -14604,7 +14688,8 @@ static int __unload_module(void)
ast_context_destroy(con, "IAX2");
ast_unload_realtime("iaxpeers");
- iax2_tech.capabilities = ast_format_cap_destroy(iax2_tech.capabilities);
+ ao2_ref(iax2_tech.capabilities, -1);
+ iax2_tech.capabilities = NULL;
return 0;
}
@@ -14914,10 +14999,10 @@ static int load_module(void)
int x = 0;
struct iax2_registry *reg = NULL;
- if (!(iax2_tech.capabilities = ast_format_cap_alloc(0))) {
+ if (!(iax2_tech.capabilities = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT))) {
return AST_MODULE_LOAD_FAILURE;
}
- ast_format_cap_add_all(iax2_tech.capabilities);
+ ast_format_cap_append_by_type(iax2_tech.capabilities, AST_MEDIA_TYPE_UNKNOWN);
if (load_objects()) {
return AST_MODULE_LOAD_FAILURE;
diff --git a/channels/chan_mgcp.c b/channels/chan_mgcp.c
index 2d0afe29d..6021b6c1d 100644
--- a/channels/chan_mgcp.c
+++ b/channels/chan_mgcp.c
@@ -86,6 +86,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/features_config.h"
#include "asterisk/parking.h"
#include "asterisk/stasis_channels.h"
+#include "asterisk/format_cache.h"
/*
* Define to work around buggy dlink MGCP phone firmware which
@@ -1199,9 +1200,20 @@ static struct ast_frame *mgcp_rtp_read(struct mgcp_subchannel *sub)
if (sub->owner) {
/* We already hold the channel lock */
if (f->frametype == AST_FRAME_VOICE) {
- if (!ast_format_cap_iscompatible(ast_channel_nativeformats(sub->owner), &f->subclass.format)) {
- ast_debug(1, "Oooh, format changed to %s\n", ast_getformatname(&f->subclass.format));
- ast_format_cap_set(ast_channel_nativeformats(sub->owner), &f->subclass.format);
+ if (ast_format_cap_iscompatible_format(ast_channel_nativeformats(sub->owner), f->subclass.format) == AST_FORMAT_CMP_NOT_EQUAL) {
+ struct ast_format_cap *caps;
+
+ ast_debug(1, "Oooh, format changed to %s\n", ast_format_get_name(f->subclass.format));
+
+ caps = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
+ if (caps) {
+ ast_format_cap_append(caps, f->subclass.format, 0);
+ ast_channel_nativeformats_set(sub->owner, caps);
+ ao2_ref(caps, -1);
+ } else {
+ return &ast_null_frame;
+ }
+
ast_set_read_format(sub->owner, ast_channel_readformat(sub->owner));
ast_set_write_format(sub->owner, ast_channel_writeformat(sub->owner));
}
@@ -1239,7 +1251,6 @@ static int mgcp_write(struct ast_channel *ast, struct ast_frame *frame)
{
struct mgcp_subchannel *sub = ast_channel_tech_pvt(ast);
int res = 0;
- char buf[256];
if (frame->frametype != AST_FRAME_VOICE) {
if (frame->frametype == AST_FRAME_IMAGE)
@@ -1249,12 +1260,14 @@ static int mgcp_write(struct ast_channel *ast, struct ast_frame *frame)
return 0;
}
} else {
- if (!(ast_format_cap_iscompatible(ast_channel_nativeformats(ast), &frame->subclass.format))) {
+ if (ast_format_cap_iscompatible_format(ast_channel_nativeformats(ast), frame->subclass.format) == AST_FORMAT_CMP_NOT_EQUAL) {
+ struct ast_str *cap_buf = ast_str_alloca(64);
+
ast_log(LOG_WARNING, "Asked to transmit frame type %s, while native formats is %s (read/write = %s/%s)\n",
- ast_getformatname(&frame->subclass.format),
- ast_getformatname_multiple(buf, sizeof(buf), ast_channel_nativeformats(ast)),
- ast_getformatname(ast_channel_readformat(ast)),
- ast_getformatname(ast_channel_writeformat(ast)));
+ ast_format_get_name(frame->subclass.format),
+ ast_format_cap_get_names(ast_channel_nativeformats(ast), &cap_buf),
+ ast_format_get_name(ast_channel_readformat(ast)),
+ ast_format_get_name(ast_channel_writeformat(ast)));
/* return -1; */
}
}
@@ -1490,90 +1503,103 @@ static int mgcp_indicate(struct ast_channel *ast, int ind, const void *data, siz
static struct ast_channel *mgcp_new(struct mgcp_subchannel *sub, int state, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor)
{
+ struct ast_format_cap *caps = NULL;
struct ast_channel *tmp;
struct ast_variable *v = NULL;
struct mgcp_endpoint *i = sub->parent;
- struct ast_format tmpfmt;
+ struct ast_format *tmpfmt;
+ caps = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
+ if (!caps) {
+ ast_log(LOG_ERROR, "Format capabilities could not be created\n");
+ return NULL;
+ }
tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, i->accountcode, i->exten, i->context, assignedids, requestor, i->amaflags, "MGCP/%s@%s-%d", i->name, i->parent->name, sub->id);
- if (tmp) {
- ast_channel_stage_snapshot(tmp);
- ast_channel_tech_set(tmp, &mgcp_tech);
- ast_format_cap_copy(ast_channel_nativeformats(tmp), i->cap);
- if (ast_format_cap_is_empty(ast_channel_nativeformats(tmp))) {
- ast_format_cap_copy(ast_channel_nativeformats(tmp), global_capability);
- }
- if (sub->rtp) {
- ast_channel_set_fd(tmp, 0, ast_rtp_instance_fd(sub->rtp, 0));
- }
- if (i->dtmfmode & (MGCP_DTMF_INBAND | MGCP_DTMF_HYBRID)) {
- i->dsp = ast_dsp_new();
- ast_dsp_set_features(i->dsp, DSP_FEATURE_DIGIT_DETECT);
- /* this is to prevent clipping of dtmf tones during dsp processing */
- ast_dsp_set_digitmode(i->dsp, DSP_DIGITMODE_NOQUELCH);
- } else {
- i->dsp = NULL;
- }
- if (state == AST_STATE_RING)
- ast_channel_rings_set(tmp, 1);
-
- ast_best_codec(ast_channel_nativeformats(tmp), &tmpfmt);
- ast_format_copy(ast_channel_writeformat(tmp), &tmpfmt);
- ast_format_copy(ast_channel_rawwriteformat(tmp), &tmpfmt);
- ast_format_copy(ast_channel_readformat(tmp), &tmpfmt);
- ast_format_copy(ast_channel_rawreadformat(tmp), &tmpfmt);
- ast_channel_tech_pvt_set(tmp, sub);
- if (!ast_strlen_zero(i->language))
- ast_channel_language_set(tmp, i->language);
- if (!ast_strlen_zero(i->accountcode))
- ast_channel_accountcode_set(tmp, i->accountcode);
- if (i->amaflags)
- ast_channel_amaflags_set(tmp, i->amaflags);
- mgcp_set_owner(sub, tmp);
- ast_module_ref(ast_module_info->self);
- ast_channel_callgroup_set(tmp, i->callgroup);
- ast_channel_pickupgroup_set(tmp, i->pickupgroup);
- ast_channel_call_forward_set(tmp, i->call_forward);
- ast_channel_context_set(tmp, i->context);
- ast_channel_exten_set(tmp, i->exten);
-
- /* Don't use ast_set_callerid() here because it will
- * generate a needless NewCallerID event */
- if (!ast_strlen_zero(i->cid_num)) {
- ast_channel_caller(tmp)->ani.number.valid = 1;
- ast_channel_caller(tmp)->ani.number.str = ast_strdup(i->cid_num);
- }
-
- if (!i->adsi) {
- ast_channel_adsicpe_set(tmp, AST_ADSI_UNAVAILABLE);
- }
- ast_channel_priority_set(tmp, 1);
+ if (!tmp) {
+ ast_log(LOG_WARNING, "Channel could not be created\n");
+ ao2_ref(caps, -1);
+ return NULL;
+ }
- /* Set channel variables for this call from configuration */
- for (v = i->chanvars ; v ; v = v->next) {
- char valuebuf[1024];
- pbx_builtin_setvar_helper(tmp, v->name, ast_get_encoded_str(v->value, valuebuf, sizeof(valuebuf)));
- }
+ ast_channel_stage_snapshot(tmp);
+ ast_channel_tech_set(tmp, &mgcp_tech);
+ if (ast_format_cap_count(i->cap)) {
+ ast_format_cap_append_from_cap(caps, i->cap, AST_MEDIA_TYPE_UNKNOWN);
+ } else {
+ ast_format_cap_append_from_cap(caps, global_capability, AST_MEDIA_TYPE_UNKNOWN);
+ }
+ ast_channel_nativeformats_set(tmp, caps);
+ ao2_ref(caps, -1);
+ if (sub->rtp) {
+ ast_channel_set_fd(tmp, 0, ast_rtp_instance_fd(sub->rtp, 0));
+ }
+ if (i->dtmfmode & (MGCP_DTMF_INBAND | MGCP_DTMF_HYBRID)) {
+ i->dsp = ast_dsp_new();
+ ast_dsp_set_features(i->dsp, DSP_FEATURE_DIGIT_DETECT);
+ /* this is to prevent clipping of dtmf tones during dsp processing */
+ ast_dsp_set_digitmode(i->dsp, DSP_DIGITMODE_NOQUELCH);
+ } else {
+ i->dsp = NULL;
+ }
+ if (state == AST_STATE_RING) {
+ ast_channel_rings_set(tmp, 1);
+ }
+
+ tmpfmt = ast_format_cap_get_format(ast_channel_nativeformats(tmp), 0);
+ ast_channel_set_writeformat(tmp, tmpfmt);
+ ast_channel_set_rawwriteformat(tmp, tmpfmt);
+ ast_channel_set_readformat(tmp, tmpfmt);
+ ast_channel_set_rawreadformat(tmp, tmpfmt);
+ ao2_ref(tmpfmt, -1);
+ ast_channel_tech_pvt_set(tmp, sub);
+ if (!ast_strlen_zero(i->language))
+ ast_channel_language_set(tmp, i->language);
+ if (!ast_strlen_zero(i->accountcode))
+ ast_channel_accountcode_set(tmp, i->accountcode);
+ if (i->amaflags)
+ ast_channel_amaflags_set(tmp, i->amaflags);
+ mgcp_set_owner(sub, tmp);
+ ast_module_ref(ast_module_info->self);
+ ast_channel_callgroup_set(tmp, i->callgroup);
+ ast_channel_pickupgroup_set(tmp, i->pickupgroup);
+ ast_channel_call_forward_set(tmp, i->call_forward);
+ ast_channel_context_set(tmp, i->context);
+ ast_channel_exten_set(tmp, i->exten);
+ /* Don't use ast_set_callerid() here because it will
+ * generate a needless NewCallerID event */
+ if (!ast_strlen_zero(i->cid_num)) {
+ ast_channel_caller(tmp)->ani.number.valid = 1;
+ ast_channel_caller(tmp)->ani.number.str = ast_strdup(i->cid_num);
+ }
+
+ if (!i->adsi) {
+ ast_channel_adsicpe_set(tmp, AST_ADSI_UNAVAILABLE);
+ }
+ ast_channel_priority_set(tmp, 1);
+
+ /* Set channel variables for this call from configuration */
+ for (v = i->chanvars ; v ; v = v->next) {
+ char valuebuf[1024];
+ pbx_builtin_setvar_helper(tmp, v->name, ast_get_encoded_str(v->value, valuebuf, sizeof(valuebuf)));
+ }
- if (sub->rtp) {
- ast_jb_configure(tmp, &global_jbconf);
- }
+ if (sub->rtp) {
+ ast_jb_configure(tmp, &global_jbconf);
+ }
- ast_channel_stage_snapshot_done(tmp);
- ast_channel_unlock(tmp);
+ ast_channel_stage_snapshot_done(tmp);
+ ast_channel_unlock(tmp);
- if (state != AST_STATE_DOWN) {
- if (ast_pbx_start(tmp)) {
- ast_log(LOG_WARNING, "Unable to start PBX on %s\n", ast_channel_name(tmp));
- ast_hangup(tmp);
- tmp = NULL;
- }
+ if (state != AST_STATE_DOWN) {
+ if (ast_pbx_start(tmp)) {
+ ast_log(LOG_WARNING, "Unable to start PBX on %s\n", ast_channel_name(tmp));
+ ast_hangup(tmp);
+ tmp = NULL;
}
- ast_verb(3, "MGCP mgcp_new(%s) created in state: %s\n",
- ast_channel_name(tmp), ast_state2str(state));
- } else {
- ast_log(LOG_WARNING, "Unable to allocate channel structure\n");
}
+ ast_verb(3, "MGCP mgcp_new(%s) created in state: %s\n",
+ ast_channel_name(tmp), ast_state2str(state));
+
return tmp;
}
@@ -1973,7 +1999,9 @@ static int process_sdp(struct mgcp_subchannel *sub, struct mgcp_request *req)
int codec, codec_count=0;
int iterator;
struct mgcp_endpoint *p = sub->parent;
- char tmp1[256], tmp2[256], tmp3[256];
+ struct ast_str *global_buf = ast_str_alloca(64);
+ struct ast_str *peer_buf = ast_str_alloca(64);
+ struct ast_str *pvt_buf = ast_str_alloca(64);
/* Get codec and RTP info from SDP */
m = get_sdp(req, "m");
@@ -2030,20 +2058,20 @@ static int process_sdp(struct mgcp_subchannel *sub, struct mgcp_request *req)
}
/* Now gather all of the codecs that were asked for: */
- if (!(peercap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_NOLOCK))) {
+ if (!(peercap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT))) {
return -1;
}
ast_rtp_codecs_payload_formats(ast_rtp_instance_get_codecs(sub->rtp), peercap, &peerNonCodecCapability);
- ast_format_cap_joint_copy(global_capability, peercap, p->cap);
+ ast_format_cap_get_compatible(global_capability, peercap, p->cap);
ast_debug(1, "Capabilities: us - %s, them - %s, combined - %s\n",
- ast_getformatname_multiple(tmp1, sizeof(tmp1), global_capability),
- ast_getformatname_multiple(tmp2, sizeof(tmp2), peercap),
- ast_getformatname_multiple(tmp3, sizeof(tmp3), p->cap));
- peercap = ast_format_cap_destroy(peercap);
+ ast_format_cap_get_names(global_capability, &global_buf),
+ ast_format_cap_get_names(peercap, &peer_buf),
+ ast_format_cap_get_names(p->cap, &pvt_buf));
+ ao2_ref(peercap, -1);
ast_debug(1, "Non-codec capabilities: us - %d, them - %d, combined - %d\n",
nonCodecCapability, peerNonCodecCapability, p->nonCodecCapability);
- if (ast_format_cap_is_empty(p->cap)) {
+ if (!ast_format_cap_count(p->cap)) {
ast_log(LOG_WARNING, "No compatible codecs!\n");
return -1;
}
@@ -2201,7 +2229,6 @@ static int add_sdp(struct mgcp_request *resp, struct mgcp_subchannel *sub, struc
char m[256] = "";
char a[1024] = "";
int x;
- struct ast_format tmpfmt;
struct sockaddr_in dest = { 0, };
struct ast_sockaddr dest_tmp;
struct mgcp_endpoint *p = sub->parent;
@@ -2236,24 +2263,25 @@ static int add_sdp(struct mgcp_request *resp, struct mgcp_subchannel *sub, struc
ast_copy_string(t, "t=0 0\r\n", sizeof(t));
snprintf(m, sizeof(m), "m=audio %d RTP/AVP", ntohs(dest.sin_port));
- ast_format_cap_iter_start(p->cap);
- while (!(ast_format_cap_iter_next(p->cap, &tmpfmt))) {
- if (AST_FORMAT_GET_TYPE(tmpfmt.id) != AST_FORMAT_TYPE_AUDIO) {
- /* Audio is now discontiguous */
+ for (x = 0; x < ast_format_cap_count(p->cap); x++) {
+ struct ast_format *format = ast_format_cap_get_format(p->cap, x);
+
+ if (ast_format_get_type(format) != AST_MEDIA_TYPE_AUDIO) {
+ ao2_ref(format, -1);
continue;
}
- if (ast_format_cap_iscompatible(p->cap, &tmpfmt)) {
- ast_debug(1, "Answering with capability %s\n", ast_getformatname(&tmpfmt));
- codec = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(sub->rtp), 1, &tmpfmt, 0);
- if (codec > -1) {
- snprintf(costr, sizeof(costr), " %d", codec);
- strncat(m, costr, sizeof(m) - strlen(m) - 1);
- snprintf(costr, sizeof(costr), "a=rtpmap:%d %s/8000\r\n", codec, ast_rtp_lookup_mime_subtype2(1, &tmpfmt, 0, 0));
- strncat(a, costr, sizeof(a) - strlen(a) - 1);
- }
+
+ ast_debug(1, "Answering with capability %s\n", ast_format_get_name(format));
+ codec = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(sub->rtp), 1, format, 0);
+ if (codec > -1) {
+ snprintf(costr, sizeof(costr), " %d", codec);
+ strncat(m, costr, sizeof(m) - strlen(m) - 1);
+ snprintf(costr, sizeof(costr), "a=rtpmap:%d %s/8000\r\n", codec, ast_rtp_lookup_mime_subtype2(1, format, 0, 0));
+ strncat(a, costr, sizeof(a) - strlen(a) - 1);
}
+
+ ao2_ref(format, -1);
}
- ast_format_cap_iter_end(p->cap);
for (x = 1LL; x <= AST_RTP_MAX; x <<= 1) {
if (p->nonCodecCapability & x) {
@@ -2292,7 +2320,7 @@ static int transmit_modify_with_sdp(struct mgcp_subchannel *sub, struct ast_rtp_
char local[256];
char tmp[80];
struct mgcp_endpoint *p = sub->parent;
- struct ast_format tmpfmt;
+ int i;
struct ast_sockaddr sub_tmpdest_tmp;
unsigned int oseq;
@@ -2304,18 +2332,20 @@ static int transmit_modify_with_sdp(struct mgcp_subchannel *sub, struct ast_rtp_
return 0;
}
ast_copy_string(local, "e:on, s:off, p:20", sizeof(local));
- ast_format_cap_iter_start(p->cap);
- while (!(ast_format_cap_iter_next(p->cap, &tmpfmt))) {
- if (AST_FORMAT_GET_TYPE(tmpfmt.id) != AST_FORMAT_TYPE_AUDIO) {
- /* Audio is now discontiguous */
+
+ for (i = 0; i < ast_format_cap_count(p->cap); i++) {
+ struct ast_format *format = ast_format_cap_get_format(p->cap, i);
+
+ if (ast_format_get_type(format) != AST_MEDIA_TYPE_AUDIO) {
+ ao2_ref(format, -1);
continue;
}
- if (ast_format_cap_iscompatible(p->cap, &tmpfmt)) {
- snprintf(tmp, sizeof(tmp), ", a:%s", ast_rtp_lookup_mime_subtype2(1, &tmpfmt, 0, 0));
- strncat(local, tmp, sizeof(local) - strlen(local) - 1);
- }
+
+ snprintf(tmp, sizeof(tmp), ", a:%s", ast_rtp_lookup_mime_subtype2(1, format, 0, 0));
+ strncat(local, tmp, sizeof(local) - strlen(local) - 1);
+
+ ao2_ref(format, -1);
}
- ast_format_cap_iter_end(p->cap);
if (sub->gate) {
if (sub->gate->state == GATE_ALLOCATED || sub->gate->state == GATE_OPEN) {
@@ -2351,7 +2381,7 @@ static int transmit_connect_with_sdp(struct mgcp_subchannel *sub, struct ast_rtp
struct mgcp_request resp;
char local[256];
char tmp[80];
- struct ast_format tmpfmt;
+ int i;
struct mgcp_endpoint *p = sub->parent;
unsigned int oseq;
@@ -2360,18 +2390,19 @@ static int transmit_connect_with_sdp(struct mgcp_subchannel *sub, struct ast_rtp
ast_copy_string(local, "e:on, s:off, p:20", sizeof(local));
- ast_format_cap_iter_start(p->cap);
- while (!(ast_format_cap_iter_next(p->cap, &tmpfmt))) {
- if (AST_FORMAT_GET_TYPE(tmpfmt.id) != AST_FORMAT_TYPE_AUDIO) {
- /* Audio is now discontiguous */
+ for (i = 0; i < ast_format_cap_count(p->cap); i++) {
+ struct ast_format *format = ast_format_cap_get_format(p->cap, i);
+
+ if (ast_format_get_type(format) != AST_MEDIA_TYPE_AUDIO) {
+ ao2_ref(format, -1);
continue;
}
- if (ast_format_cap_iscompatible(p->cap, &tmpfmt)) {
- snprintf(tmp, sizeof(tmp), ", a:%s", ast_rtp_lookup_mime_subtype2(1, &tmpfmt, 0, 0));
- strncat(local, tmp, sizeof(local) - strlen(local) - 1);
- }
+
+ snprintf(tmp, sizeof(tmp), ", a:%s", ast_rtp_lookup_mime_subtype2(1, format, 0, 0));
+ strncat(local, tmp, sizeof(local) - strlen(local) - 1);
+
+ ao2_ref(format, -1);
}
- ast_format_cap_iter_end(p->cap);
if (sub->gate) {
if(sub->gate->state == GATE_ALLOCATED) {
@@ -2447,22 +2478,23 @@ static int mgcp_alloc_pktcgate(struct mgcp_subchannel *sub)
static int transmit_connect(struct mgcp_subchannel *sub)
{
struct mgcp_request resp;
+ int x;
char local[256];
char tmp[80];
- struct ast_format tmpfmt;
+ struct ast_format *tmpfmt;
struct mgcp_endpoint *p = sub->parent;
unsigned int oseq;
ast_copy_string(local, "p:20, s:off, e:on", sizeof(local));
- ast_format_cap_iter_start(p->cap);
- while (!(ast_format_cap_iter_next(p->cap, &tmpfmt))) {
- if (ast_format_cap_iscompatible(p->cap, &tmpfmt)) {
- snprintf(tmp, sizeof(tmp), ", a:%s", ast_rtp_lookup_mime_subtype2(1, &tmpfmt, 0, 0));
- strncat(local, tmp, sizeof(local) - strlen(local) - 1);
- }
+ for (x = 0; x < ast_format_cap_count(p->cap); x++) {
+ tmpfmt = ast_format_cap_get_format(p->cap, x);
+
+ snprintf(tmp, sizeof(tmp), ", a:%s", ast_rtp_lookup_mime_subtype2(1, tmpfmt, 0, 0));
+ strncat(local, tmp, sizeof(local) - strlen(local) - 1);
+
+ ao2_ref(tmpfmt, -1);
}
- ast_format_cap_iter_end(p->cap);
ast_debug(3, "Creating connection for %s@%s-%d in cxmode: %s callid: %s\n",
p->name, p->parent->name, sub->id, mgcp_cxmodes[sub->cxmode], sub->callid);
@@ -2557,7 +2589,7 @@ static int transmit_modify_request(struct mgcp_subchannel *sub)
{
struct mgcp_request resp;
struct mgcp_endpoint *p = sub->parent;
- struct ast_format tmpfmt;
+ int i;
int fc = 1;
char local[256];
char tmp[80];
@@ -2572,18 +2604,22 @@ static int transmit_modify_request(struct mgcp_subchannel *sub)
p->name, p->parent->name, sub->id, mgcp_cxmodes[sub->cxmode], sub->callid);
ast_copy_string(local, "", sizeof(local));
- ast_format_cap_iter_start(p->cap);
- while (!(ast_format_cap_iter_next(p->cap, &tmpfmt))) {
+ for (i = 0; i < ast_format_cap_count(p->cap); i++) {
+ struct ast_format *format = ast_format_cap_get_format(p->cap, i);
+
if (p->ncs && !fc) {
- ast_format_cap_set(p->cap, &tmpfmt); /* sb5120e bug */
+ ast_format_cap_remove_by_type(p->cap, AST_MEDIA_TYPE_UNKNOWN);
+ ast_format_cap_append(p->cap, format, 0); /* sb5120e bug */
+ ao2_ref(format, -1);
break;
} else {
fc = 0;
- snprintf(tmp, sizeof(tmp), ", a:%s", ast_rtp_lookup_mime_subtype2(1, &tmpfmt, 0, 0));
+ snprintf(tmp, sizeof(tmp), ", a:%s", ast_rtp_lookup_mime_subtype2(1, format, 0, 0));
}
strncat(local, tmp, sizeof(local) - strlen(local) - 1);
+
+ ao2_ref(format, -1);
}
- ast_format_cap_iter_end(p->cap);
if (!sub->sdpsent) {
if (sub->gate) {
@@ -3948,8 +3984,10 @@ static struct ast_channel *mgcp_request(const char *type, struct ast_format_cap
struct ast_channel *tmpc = NULL;
char tmp[256];
- if (!(ast_format_cap_has_joint(cap, global_capability))) {
- ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%s'\n", ast_getformatname_multiple(tmp, sizeof(tmp), cap));
+ if (!(ast_format_cap_iscompatible(cap, global_capability))) {
+ struct ast_str *cap_buf = ast_str_alloca(64);
+ ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%s'\n",
+ ast_format_cap_get_names(cap, &cap_buf));
/*return NULL;*/
}
ast_copy_string(tmp, dest, sizeof(tmp));
@@ -4185,7 +4223,7 @@ static struct mgcp_gateway *build_gateway(char *cat, struct ast_variable *v)
ast_mutex_init(&e->lock);
ast_mutex_init(&e->rqnt_queue_lock);
ast_mutex_init(&e->cmd_queue_lock);
- e->cap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_NOLOCK);
+ e->cap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
ast_copy_string(e->name, v->value, sizeof(e->name));
e->needaudit = 1;
}
@@ -4210,7 +4248,7 @@ static struct mgcp_gateway *build_gateway(char *cat, struct ast_variable *v)
snprintf(e->rqnt_ident, sizeof(e->rqnt_ident), "%08lx", (unsigned long)ast_random());
e->msgstate = -1;
e->amaflags = amaflags;
- ast_format_cap_copy(e->cap, global_capability);
+ ast_format_cap_append_from_cap(e->cap, global_capability, AST_MEDIA_TYPE_UNKNOWN);
e->parent = gw;
e->ncs = ncs;
e->dtmfmode = dtmfmode;
@@ -4292,7 +4330,7 @@ static struct mgcp_gateway *build_gateway(char *cat, struct ast_variable *v)
ast_mutex_init(&e->lock);
ast_mutex_init(&e->rqnt_queue_lock);
ast_mutex_init(&e->cmd_queue_lock);
- e->cap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_NOLOCK);
+ e->cap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
ast_copy_string(e->name, v->value, sizeof(e->name));
e->needaudit = 1;
}
@@ -4314,7 +4352,7 @@ static struct mgcp_gateway *build_gateway(char *cat, struct ast_variable *v)
e->parent = gw;
}
e->amaflags = amaflags;
- ast_format_cap_copy(e->cap, global_capability);
+ ast_format_cap_append_from_cap(e->cap, global_capability, AST_MEDIA_TYPE_UNKNOWN);
e->dtmfmode = dtmfmode;
e->ncs = ncs;
e->pktcgatealloc = pktcgatealloc;
@@ -4470,7 +4508,8 @@ static void mgcp_get_codec(struct ast_channel *chan, struct ast_format_cap *resu
{
struct mgcp_subchannel *sub = ast_channel_tech_pvt(chan);
struct mgcp_endpoint *p = sub->parent;
- ast_format_cap_copy(result, p->cap);
+
+ ast_format_cap_append_from_cap(result, p->cap, AST_MEDIA_TYPE_UNKNOWN);
}
static struct ast_rtp_glue mgcp_rtp_glue = {
@@ -4556,7 +4595,7 @@ static void destroy_endpoint(struct mgcp_endpoint *e)
ast_mutex_destroy(&e->lock);
ast_mutex_destroy(&e->rqnt_queue_lock);
ast_mutex_destroy(&e->cmd_queue_lock);
- e->cap = ast_format_cap_destroy(e->cap);
+ ao2_ref(e->cap, -1);
ast_free(e);
}
@@ -4654,7 +4693,6 @@ static int reload_config(int reload)
char *cat;
struct ast_hostent ahp;
struct hostent *hp;
- struct ast_format format;
struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
if (gethostname(ourhost, sizeof(ourhost)-1)) {
@@ -4694,19 +4732,9 @@ static int reload_config(int reload)
memcpy(&bindaddr.sin_addr, hp->h_addr, sizeof(bindaddr.sin_addr));
}
} else if (!strcasecmp(v->name, "allow")) {
- ast_getformatbyname(v->value, &format);
- if (!format.id) {
- ast_log(LOG_WARNING, "Cannot allow unknown format '%s'\n", v->value);
- } else {
- ast_format_cap_add(global_capability, &format);
- }
+ ast_format_cap_update_by_allow_disallow(global_capability, v->value, 1);
} else if (!strcasecmp(v->name, "disallow")) {
- ast_getformatbyname(v->value, &format);
- if (!format.id) {
- ast_log(LOG_WARNING, "Cannot allow unknown format '%s'\n", v->value);
- } else {
- ast_format_cap_remove(global_capability, &format);
- }
+ ast_format_cap_update_by_allow_disallow(global_capability, v->value, 0);
} else if (!strcasecmp(v->name, "tos")) {
if (ast_str2tos(v->value, &qos.tos)) {
ast_log(LOG_WARNING, "Invalid tos value at line %d, refer to QoS documentation\n", v->lineno);
@@ -4831,36 +4859,44 @@ static int reload_config(int reload)
*/
static int load_module(void)
{
- struct ast_format tmpfmt;
-
- if (!(global_capability = ast_format_cap_alloc(0))) {
+ if (!(global_capability = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT))) {
return AST_MODULE_LOAD_FAILURE;
}
- if (!(mgcp_tech.capabilities = ast_format_cap_alloc(0))) {
+ if (!(mgcp_tech.capabilities = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT))) {
+ ao2_ref(global_capability, -1);
return AST_MODULE_LOAD_FAILURE;
}
- ast_format_cap_add(global_capability, ast_format_set(&tmpfmt, AST_FORMAT_ULAW, 0));
- ast_format_cap_add(mgcp_tech.capabilities, ast_format_set(&tmpfmt, AST_FORMAT_ULAW, 0));
- ast_format_cap_add(mgcp_tech.capabilities, ast_format_set(&tmpfmt, AST_FORMAT_ALAW, 0));
+ ast_format_cap_append(global_capability, ast_format_ulaw, 0);
+ ast_format_cap_append(mgcp_tech.capabilities, ast_format_ulaw, 0);
+ ast_format_cap_append(mgcp_tech.capabilities, ast_format_alaw, 0);
if (!(sched = ast_sched_context_create())) {
ast_log(LOG_WARNING, "Unable to create schedule context\n");
+ ao2_ref(global_capability, -1);
+ ao2_ref(mgcp_tech.capabilities, -1);
return AST_MODULE_LOAD_FAILURE;
}
if (!(io = io_context_create())) {
ast_log(LOG_WARNING, "Unable to create I/O context\n");
ast_sched_context_destroy(sched);
+ ao2_ref(global_capability, -1);
+ ao2_ref(mgcp_tech.capabilities, -1);
return AST_MODULE_LOAD_FAILURE;
}
- if (reload_config(0))
+ if (reload_config(0)) {
+ ao2_ref(global_capability, -1);
+ ao2_ref(mgcp_tech.capabilities, -1);
return AST_MODULE_LOAD_DECLINE;
+ }
/* Make sure we can register our mgcp channel type */
if (ast_channel_register(&mgcp_tech)) {
ast_log(LOG_ERROR, "Unable to register channel class 'MGCP'\n");
io_context_destroy(io);
ast_sched_context_destroy(sched);
+ ao2_ref(global_capability, -1);
+ ao2_ref(mgcp_tech.capabilities, -1);
return AST_MODULE_LOAD_FAILURE;
}
@@ -4973,8 +5009,10 @@ static int unload_module(void)
ast_cli_unregister_multiple(cli_mgcp, sizeof(cli_mgcp) / sizeof(struct ast_cli_entry));
ast_sched_context_destroy(sched);
- global_capability = ast_format_cap_destroy(global_capability);
- mgcp_tech.capabilities = ast_format_cap_destroy(mgcp_tech.capabilities);
+ ao2_ref(global_capability, -1);
+ global_capability = NULL;
+ ao2_ref(mgcp_tech.capabilities, -1);
+ mgcp_tech.capabilities = NULL;
return 0;
}
diff --git a/channels/chan_misdn.c b/channels/chan_misdn.c
index 47d5947c3..0774e3c15 100644
--- a/channels/chan_misdn.c
+++ b/channels/chan_misdn.c
@@ -120,6 +120,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/features_config.h"
#include "asterisk/bridge.h"
#include "asterisk/pickup.h"
+#include "asterisk/format_cache.h"
#include "chan_misdn_config.h"
#include "isdn_lib.h"
@@ -691,9 +692,6 @@ static const char misdn_type[] = "mISDN";
static int tracing = 0;
-/*! \brief Only alaw and mulaw is allowed for now */
-static struct ast_format prefformat; /* AST_FORMAT_SLINEAR ; AST_FORMAT_ULAW | */
-
static int *misdn_debug;
static int *misdn_debug_only;
static int max_ports;
@@ -7436,7 +7434,7 @@ static struct ast_frame *misdn_read(struct ast_channel *ast)
}
tmp->frame.frametype = AST_FRAME_VOICE;
- ast_format_set(&tmp->frame.subclass.format, AST_FORMAT_ALAW, 0);
+ tmp->frame.subclass.format = ast_format_alaw;
tmp->frame.datalen = len;
tmp->frame.samples = len;
tmp->frame.mallocd = 0;
@@ -7501,13 +7499,14 @@ static int misdn_write(struct ast_channel *ast, struct ast_frame *frame)
}
- if (!frame->subclass.format.id) {
+ if (!frame->subclass.format) {
chan_misdn_log(4, ch->bc->port, "misdn_write: * prods us\n");
return 0;
}
- if (ast_format_cmp(&frame->subclass.format, &prefformat) == AST_FORMAT_CMP_NOT_EQUAL) {
- chan_misdn_log(-1, ch->bc->port, "Got Unsupported Frame with Format:%s\n", ast_getformatname(&frame->subclass.format));
+ if (ast_format_cmp(frame->subclass.format, ast_format_alaw) == AST_FORMAT_CMP_NOT_EQUAL) {
+ chan_misdn_log(-1, ch->bc->port, "Got Unsupported Frame with Format:%s\n",
+ ast_format_get_name(frame->subclass.format));
return 0;
}
@@ -8174,12 +8173,18 @@ static void update_name(struct ast_channel *tmp, int port, int c)
static struct ast_channel *misdn_new(struct chan_list *chlist, int state, char *exten, char *callerid, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, int port, int c)
{
+ struct ast_format_cap *native;
struct ast_channel *tmp;
char *cid_name = NULL;
char *cid_num = NULL;
int chan_offset = 0;
int tmp_port = misdn_cfg_get_next_port(0);
- struct ast_format tmpfmt;
+ struct ast_format *tmpfmt;
+
+ native = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
+ if (!native) {
+ return NULL;
+ }
for (; tmp_port > 0; tmp_port = misdn_cfg_get_next_port(tmp_port)) {
if (tmp_port == port) {
@@ -8199,12 +8204,15 @@ static struct ast_channel *misdn_new(struct chan_list *chlist, int state, char
if (tmp) {
chan_misdn_log(2, port, " --> * NEW CHANNEL dialed:%s caller:%s\n", exten, callerid);
- ast_best_codec(cap, &tmpfmt);
- ast_format_cap_add(ast_channel_nativeformats(tmp), &prefformat);
- ast_format_copy(ast_channel_writeformat(tmp), &tmpfmt);
- ast_format_copy(ast_channel_rawwriteformat(tmp), &tmpfmt);
- ast_format_copy(ast_channel_readformat(tmp), &tmpfmt);
- ast_format_copy(ast_channel_rawreadformat(tmp), &tmpfmt);
+ tmpfmt = ast_format_cap_get_format(cap, 0);
+ ast_format_cap_append(native, ast_format_alaw, 0);
+ ast_channel_nativeformats_set(tmp, native);
+ ast_channel_set_writeformat(tmp, tmpfmt);
+ ast_channel_set_rawwriteformat(tmp, tmpfmt);
+ ast_channel_set_readformat(tmp, tmpfmt);
+ ast_channel_set_rawreadformat(tmp, tmpfmt);
+
+ ao2_ref(tmpfmt, -1);
/* Link the channel and private together */
chan_list_ref(chlist, "Give a reference to ast_channel");
@@ -8242,6 +8250,8 @@ static struct ast_channel *misdn_new(struct chan_list *chlist, int state, char
chan_misdn_log(-1, 0, "Unable to allocate channel structure\n");
}
+ ao2_ref(native, -1);
+
return tmp;
}
@@ -10207,14 +10217,13 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
ch->addr = bc->addr;
{
- struct ast_format_cap *cap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_NOLOCK);
- struct ast_format tmpfmt;
+ struct ast_format_cap *cap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
if (!(cap)) {
return RESPONSE_ERR;
}
- ast_format_cap_add(cap, ast_format_set(&tmpfmt, AST_FORMAT_ALAW, 0));
+ ast_format_cap_append(cap, ast_format_alaw, 0);
chan = misdn_new(ch, AST_STATE_RESERVED, bc->dialed.number, bc->caller.number, cap, NULL, NULL, bc->port, bc->channel);
- cap = ast_format_cap_destroy(cap);
+ ao2_ref(cap, -1);
}
if (!chan) {
chan_list_unref(ch, "Failed to create a new channel");
@@ -10849,7 +10858,7 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
/* In Data Modes we queue frames */
memset(&frame, 0, sizeof(frame));
frame.frametype = AST_FRAME_VOICE; /* we have no data frames yet */
- ast_format_set(&frame.subclass.format, AST_FORMAT_ALAW, 0);
+ frame.subclass.format = ast_format_alaw;
frame.datalen = bc->bframe_len;
frame.samples = bc->bframe_len;
frame.mallocd = 0;
@@ -11287,7 +11296,8 @@ static int unload_module(void)
#if defined(AST_MISDN_ENHANCEMENTS)
misdn_cc_destroy();
#endif /* defined(AST_MISDN_ENHANCEMENTS) */
- misdn_tech.capabilities = ast_format_cap_destroy(misdn_tech.capabilities);
+ ao2_cleanup(misdn_tech.capabilities);
+ misdn_tech.capabilities = NULL;
return 0;
}
@@ -11316,11 +11326,10 @@ static int load_module(void)
};
- if (!(misdn_tech.capabilities = ast_format_cap_alloc(0))) {
+ if (!(misdn_tech.capabilities = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT))) {
return AST_MODULE_LOAD_DECLINE;
}
- ast_format_set(&prefformat, AST_FORMAT_ALAW, 0);
- ast_format_cap_add(misdn_tech.capabilities, &prefformat);
+ ast_format_cap_append(misdn_tech.capabilities, ast_format_alaw, 0);
max_ports = misdn_lib_maxports_get();
diff --git a/channels/chan_motif.c b/channels/chan_motif.c
index d853839ab..4b1d7d26b 100644
--- a/channels/chan_motif.c
+++ b/channels/chan_motif.c
@@ -77,6 +77,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/abstract_jb.h"
#include "asterisk/xmpp.h"
#include "asterisk/stasis_channels.h"
+#include "asterisk/format_cache.h"
/*** DOCUMENTATION
<configInfo name="chan_motif" language="en_US">
@@ -286,7 +287,6 @@ struct jingle_endpoint {
iksrule *rule; /*!< Active matching rule */
unsigned int maxicecandidates; /*!< Maximum number of ICE candidates we will offer */
unsigned int maxpayloads; /*!< Maximum number of payloads we will offer */
- struct ast_codec_pref prefs; /*!< Codec preferences */
struct ast_format_cap *cap; /*!< Formats to use */
ast_group_t callgroup; /*!< Call group */
ast_group_t pickupgroup; /*!< Pickup group */
@@ -309,7 +309,6 @@ struct jingle_session {
char remote_original[XMPP_MAX_JIDLEN];/*!< Identifier of the original remote party (remote may have changed due to redirect) */
char remote[XMPP_MAX_JIDLEN]; /*!< Identifier of the remote party */
iksrule *rule; /*!< Session matching rule */
- struct ast_codec_pref prefs; /*!< Codec preferences */
struct ast_channel *owner; /*!< Master Channel */
struct ast_rtp_instance *rtp; /*!< RTP audio session */
struct ast_rtp_instance *vrtp; /*!< RTP video session */
@@ -454,8 +453,7 @@ static void jingle_endpoint_destructor(void *obj)
ast_xmpp_client_unref(endpoint->connection);
}
- ast_format_cap_destroy(endpoint->cap);
-
+ ao2_cleanup(endpoint->cap);
ao2_ref(endpoint->state, -1);
ast_string_field_free_memory(endpoint);
@@ -519,7 +517,7 @@ static void *jingle_endpoint_alloc(const char *cat)
ast_string_field_set(endpoint, name, cat);
- endpoint->cap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_NOLOCK);
+ endpoint->cap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
endpoint->transport = JINGLE_TRANSPORT_ICE_UDP;
return endpoint;
@@ -583,9 +581,9 @@ static void jingle_session_destructor(void *obj)
ast_rtp_instance_destroy(session->vrtp);
}
- ast_format_cap_destroy(session->cap);
- ast_format_cap_destroy(session->jointcap);
- ast_format_cap_destroy(session->peercap);
+ ao2_cleanup(session->cap);
+ ao2_cleanup(session->jointcap);
+ ao2_cleanup(session->peercap);
if (session->callid) {
ast_callid_unref(session->callid);
@@ -681,7 +679,7 @@ static void jingle_enable_video(struct jingle_session *session)
}
/* If there are no configured video codecs do not turn video support on, it just won't work */
- if (!ast_format_cap_has_type(session->cap, AST_FORMAT_TYPE_VIDEO)) {
+ if (!ast_format_cap_has_type(session->cap, AST_MEDIA_TYPE_VIDEO)) {
return;
}
@@ -695,8 +693,8 @@ static void jingle_enable_video(struct jingle_session *session)
ast_rtp_instance_set_channel_id(session->vrtp, ast_channel_uniqueid(session->owner));
ast_channel_set_fd(session->owner, 2, ast_rtp_instance_fd(session->vrtp, 0));
ast_channel_set_fd(session->owner, 3, ast_rtp_instance_fd(session->vrtp, 1));
- ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(session->vrtp), session->vrtp, &session->prefs);
-
+ ast_rtp_codecs_set_framing(ast_rtp_instance_get_codecs(session->vrtp),
+ ast_format_cap_get_framing(session->cap));
if (session->transport == JINGLE_TRANSPORT_GOOGLE_V2 && (ice = ast_rtp_instance_get_ice(session->vrtp))) {
ice->stop(session->vrtp);
}
@@ -741,15 +739,15 @@ static struct jingle_session *jingle_alloc(struct jingle_endpoint *endpoint, con
session->connection = endpoint->connection;
session->transport = endpoint->transport;
- if (!(session->cap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_NOLOCK)) ||
- !(session->jointcap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_NOLOCK)) ||
- !(session->peercap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_NOLOCK)) ||
+ if (!(session->cap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT)) ||
+ !(session->jointcap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT)) ||
+ !(session->peercap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT)) ||
!session->callid) {
ao2_ref(session, -1);
return NULL;
}
- ast_format_cap_copy(session->cap, endpoint->cap);
+ ast_format_cap_append_from_cap(session->cap, endpoint->cap, AST_MEDIA_TYPE_UNKNOWN);
/* While we rely on res_xmpp for communication we still need a temporary ast_sockaddr to tell the RTP engine
* that we want IPv4 */
@@ -763,8 +761,6 @@ static struct jingle_session *jingle_alloc(struct jingle_endpoint *endpoint, con
ast_rtp_instance_set_prop(session->rtp, AST_RTP_PROPERTY_RTCP, 1);
ast_rtp_instance_set_prop(session->rtp, AST_RTP_PROPERTY_DTMF, 1);
- memcpy(&session->prefs, &endpoint->prefs, sizeof(session->prefs));
-
session->maxicecandidates = endpoint->maxicecandidates;
session->maxpayloads = endpoint->maxpayloads;
@@ -776,13 +772,20 @@ static struct ast_channel *jingle_new(struct jingle_endpoint *endpoint, struct j
{
struct ast_channel *chan;
const char *str = S_OR(title, session->remote);
- struct ast_format tmpfmt;
+ struct ast_format_cap *caps;
+ struct ast_format *tmpfmt;
+
+ if (!ast_format_cap_count(session->cap)) {
+ return NULL;
+ }
- if (ast_format_cap_is_empty(session->cap)) {
+ caps = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
+ if (!caps) {
return NULL;
}
if (!(chan = ast_channel_alloc(1, state, S_OR(title, ""), S_OR(cid_name, ""), "", "", "", assignedids, requestor, 0, "Motif/%s-%04lx", str, (unsigned long)(ast_random() & 0xffff)))) {
+ ao2_ref(caps, -1);
return NULL;
}
@@ -794,15 +797,17 @@ static struct ast_channel *jingle_new(struct jingle_endpoint *endpoint, struct j
ast_channel_callid_set(chan, session->callid);
- ast_format_cap_copy(ast_channel_nativeformats(chan), session->cap);
- ast_codec_choose(&session->prefs, session->cap, 1, &tmpfmt);
+ ast_format_cap_append_from_cap(caps, session->cap, AST_MEDIA_TYPE_UNKNOWN);
+ ast_channel_nativeformats_set(chan, caps);
+ ao2_ref(caps, -1);
if (session->rtp) {
struct ast_rtp_engine_ice *ice;
ast_channel_set_fd(chan, 0, ast_rtp_instance_fd(session->rtp, 0));
ast_channel_set_fd(chan, 1, ast_rtp_instance_fd(session->rtp, 1));
- ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(session->rtp), session->rtp, &session->prefs);
+ ast_rtp_codecs_set_framing(ast_rtp_instance_get_codecs(session->rtp),
+ ast_format_cap_get_framing(session->cap));
if (((session->transport == JINGLE_TRANSPORT_GOOGLE_V2) ||
(session->transport == JINGLE_TRANSPORT_GOOGLE_V1)) &&
@@ -818,11 +823,12 @@ static struct ast_channel *jingle_new(struct jingle_endpoint *endpoint, struct j
ast_channel_adsicpe_set(chan, AST_ADSI_UNAVAILABLE);
- ast_best_codec(ast_channel_nativeformats(chan), &tmpfmt);
- ast_format_copy(ast_channel_writeformat(chan), &tmpfmt);
- ast_format_copy(ast_channel_rawwriteformat(chan), &tmpfmt);
- ast_format_copy(ast_channel_readformat(chan), &tmpfmt);
- ast_format_copy(ast_channel_rawreadformat(chan), &tmpfmt);
+ tmpfmt = ast_format_cap_get_format(session->cap, 0);
+ ast_channel_set_writeformat(chan, tmpfmt);
+ ast_channel_set_rawwriteformat(chan, tmpfmt);
+ ast_channel_set_readformat(chan, tmpfmt);
+ ast_channel_set_rawreadformat(chan, tmpfmt);
+ ao2_ref(tmpfmt, -1);
ao2_lock(endpoint);
@@ -1300,30 +1306,24 @@ static void jingle_send_transport_info(struct jingle_session *session, const cha
}
/*! \brief Internal helper function which adds payloads to a description */
-static int jingle_add_payloads_to_description(struct jingle_session *session, struct ast_rtp_instance *rtp, iks *description, iks **payloads, enum ast_format_type type)
+static int jingle_add_payloads_to_description(struct jingle_session *session, struct ast_rtp_instance *rtp, iks *description, iks **payloads, enum ast_media_type type)
{
- struct ast_format format;
int x = 0, i = 0, res = 0;
- for (x = 0; (x < AST_CODEC_PREF_SIZE) && (i < (session->maxpayloads - 2)); x++) {
+ for (x = 0; (x < ast_format_cap_count(session->jointcap)) && (i < (session->maxpayloads - 2)); x++) {
+ struct ast_format *format = ast_format_cap_get_format(session->jointcap, x);
int rtp_code;
iks *payload;
char tmp[32];
- if (!ast_codec_pref_index(&session->prefs, x, &format)) {
- break;
- }
-
- if (AST_FORMAT_GET_TYPE(format.id) != type) {
- continue;
- }
-
- if (!ast_format_cap_iscompatible(session->jointcap, &format)) {
+ if (ast_format_get_type(format) != type) {
+ ao2_ref(format, -1);
continue;
}
- if (((rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(rtp), 1, &format, 0)) == -1) ||
+ if (((rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(rtp), 1, format, 0)) == -1) ||
(!(payload = iks_new("payload-type")))) {
+ ao2_ref(format, -1);
return -1;
}
@@ -1333,17 +1333,18 @@ static int jingle_add_payloads_to_description(struct jingle_session *session, st
snprintf(tmp, sizeof(tmp), "%d", rtp_code);
iks_insert_attrib(payload, "id", tmp);
- iks_insert_attrib(payload, "name", ast_rtp_lookup_mime_subtype2(1, &format, 0, 0));
+ iks_insert_attrib(payload, "name", ast_rtp_lookup_mime_subtype2(1, format, 0, 0));
iks_insert_attrib(payload, "channels", "1");
- if ((format.id == AST_FORMAT_G722) && ((session->transport == JINGLE_TRANSPORT_GOOGLE_V1) || (session->transport == JINGLE_TRANSPORT_GOOGLE_V2))) {
+ if ((ast_format_cmp(format, ast_format_g722) == AST_FORMAT_CMP_EQUAL) &&
+ ((session->transport == JINGLE_TRANSPORT_GOOGLE_V1) || (session->transport == JINGLE_TRANSPORT_GOOGLE_V2))) {
iks_insert_attrib(payload, "clockrate", "16000");
} else {
- snprintf(tmp, sizeof(tmp), "%u", ast_rtp_lookup_sample_rate2(1, &format, 0));
+ snprintf(tmp, sizeof(tmp), "%u", ast_rtp_lookup_sample_rate2(1, format, 0));
iks_insert_attrib(payload, "clockrate", tmp);
}
- if ((type == AST_FORMAT_TYPE_VIDEO) && (session->transport == JINGLE_TRANSPORT_GOOGLE_V2)) {
+ if ((type == AST_MEDIA_TYPE_VIDEO) && (session->transport == JINGLE_TRANSPORT_GOOGLE_V2)) {
iks *parameter;
/* Google requires these parameters to be set, but alas we can not give accurate values so use some safe defaults */
@@ -1366,9 +1367,11 @@ static int jingle_add_payloads_to_description(struct jingle_session *session, st
iks_insert_node(description, payload);
payloads[i++] = payload;
+
+ ao2_ref(format, -1);
}
/* If this is for audio and there is room for RFC2833 add it in */
- if ((type == AST_FORMAT_TYPE_AUDIO) && (i < session->maxpayloads)) {
+ if ((type == AST_MEDIA_TYPE_AUDIO) && (i < session->maxpayloads)) {
iks *payload;
if ((payload = iks_new("payload-type"))) {
@@ -1390,7 +1393,7 @@ static int jingle_add_payloads_to_description(struct jingle_session *session, st
/*! \brief Helper function which adds content to a description */
static int jingle_add_content(struct jingle_session *session, iks *jingle, iks *content, iks *description, iks *transport,
- const char *name, enum ast_format_type type, struct ast_rtp_instance *rtp, iks **payloads)
+ const char *name, enum ast_media_type type, struct ast_rtp_instance *rtp, iks **payloads)
{
int res = 0;
@@ -1400,9 +1403,9 @@ static int jingle_add_content(struct jingle_session *session, iks *jingle, iks *
iks_insert_node(jingle, content);
iks_insert_attrib(description, "xmlns", JINGLE_RTP_NS);
- if (type == AST_FORMAT_TYPE_AUDIO) {
+ if (type == AST_MEDIA_TYPE_AUDIO) {
iks_insert_attrib(description, "media", "audio");
- } else if (type == AST_FORMAT_TYPE_VIDEO) {
+ } else if (type == AST_MEDIA_TYPE_VIDEO) {
iks_insert_attrib(description, "media", "video");
} else {
return -1;
@@ -1469,7 +1472,7 @@ static void jingle_send_session_action(struct jingle_session *session, const cha
if (session->rtp && (audio = iks_new("content")) && (audio_description = iks_new("description")) &&
(audio_transport = iks_new("transport"))) {
res = jingle_add_content(session, jingle, audio, audio_description, audio_transport, session->audio_name,
- AST_FORMAT_TYPE_AUDIO, session->rtp, audio_payloads);
+ AST_MEDIA_TYPE_AUDIO, session->rtp, audio_payloads);
} else {
ast_log(LOG_ERROR, "Failed to allocate audio content stanzas for session '%s', hanging up\n", session->sid);
res = -1;
@@ -1479,7 +1482,7 @@ static void jingle_send_session_action(struct jingle_session *session, const cha
if ((video = iks_new("content")) && (video_description = iks_new("description")) &&
(video_transport = iks_new("transport"))) {
res = jingle_add_content(session, jingle, video, video_description, video_transport, session->video_name,
- AST_FORMAT_TYPE_VIDEO, session->vrtp, video_payloads);
+ AST_MEDIA_TYPE_VIDEO, session->vrtp, video_payloads);
} else {
ast_log(LOG_ERROR, "Failed to allocate video content stanzas for session '%s', hanging up\n", session->sid);
res = -1;
@@ -1668,17 +1671,24 @@ static struct ast_frame *jingle_read(struct ast_channel *ast)
}
if (frame && frame->frametype == AST_FRAME_VOICE &&
- !ast_format_cap_iscompatible(ast_channel_nativeformats(ast), &frame->subclass.format)) {
- if (!ast_format_cap_iscompatible(session->jointcap, &frame->subclass.format)) {
+ ast_format_cap_iscompatible_format(ast_channel_nativeformats(ast), frame->subclass.format) == AST_FORMAT_CMP_NOT_EQUAL) {
+ if (ast_format_cap_iscompatible_format(session->jointcap, frame->subclass.format) == AST_FORMAT_CMP_NOT_EQUAL) {
ast_debug(1, "Bogus frame of format '%s' received from '%s'!\n",
- ast_getformatname(&frame->subclass.format), ast_channel_name(ast));
+ ast_format_get_name(frame->subclass.format), ast_channel_name(ast));
ast_frfree(frame);
frame = &ast_null_frame;
} else {
+ struct ast_format_cap *caps;
+
ast_debug(1, "Oooh, format changed to %s\n",
- ast_getformatname(&frame->subclass.format));
- ast_format_cap_remove_bytype(ast_channel_nativeformats(ast), AST_FORMAT_TYPE_AUDIO);
- ast_format_cap_add(ast_channel_nativeformats(ast), &frame->subclass.format);
+ ast_format_get_name(frame->subclass.format));
+
+ caps = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
+ if (caps) {
+ ast_format_cap_append(caps, frame->subclass.format, 0);
+ ast_channel_nativeformats_set(ast, caps);
+ ao2_ref(caps, -1);
+ }
ast_set_read_format(ast, ast_channel_readformat(ast));
ast_set_write_format(ast, ast_channel_writeformat(ast));
}
@@ -1692,17 +1702,18 @@ static int jingle_write(struct ast_channel *ast, struct ast_frame *frame)
{
struct jingle_session *session = ast_channel_tech_pvt(ast);
int res = 0;
- char buf[256];
switch (frame->frametype) {
case AST_FRAME_VOICE:
- if (!(ast_format_cap_iscompatible(ast_channel_nativeformats(ast), &frame->subclass.format))) {
+ if (ast_format_cap_iscompatible_format(ast_channel_nativeformats(ast), frame->subclass.format) == AST_FORMAT_CMP_NOT_EQUAL) {
+ struct ast_str *codec_buf = ast_str_alloca(64);
+
ast_log(LOG_WARNING,
"Asked to transmit frame type %s, while native formats is %s (read/write = %s/%s)\n",
- ast_getformatname(&frame->subclass.format),
- ast_getformatname_multiple(buf, sizeof(buf), ast_channel_nativeformats(ast)),
- ast_getformatname(ast_channel_readformat(ast)),
- ast_getformatname(ast_channel_writeformat(ast)));
+ ast_format_get_name(frame->subclass.format),
+ ast_format_cap_get_names(ast_channel_nativeformats(ast), &codec_buf),
+ ast_format_get_name(ast_channel_readformat(ast)),
+ ast_format_get_name(ast_channel_writeformat(ast)));
return 0;
}
if (session && session->rtp) {
@@ -1845,7 +1856,7 @@ static int jingle_call(struct ast_channel *ast, const char *dest, int timeout)
ast_setstate(ast, AST_STATE_RING);
/* Since we have no idea of the remote capabilities use ours for now */
- ast_format_cap_copy(session->jointcap, session->cap);
+ ast_format_cap_append_from_cap(session->jointcap, session->cap, AST_MEDIA_TYPE_UNKNOWN);
/* We set up a hook so we can know when our session-initiate message was accepted or rejected */
session->rule = iks_filter_add_rule(session->connection->filter, jingle_outgoing_hook, session,
@@ -1908,7 +1919,7 @@ static struct ast_channel *jingle_request(const char *type, struct ast_format_ca
);
/* We require at a minimum one audio format to be requested */
- if (!ast_format_cap_has_type(cap, AST_FORMAT_TYPE_AUDIO)) {
+ if (!ast_format_cap_has_type(cap, AST_MEDIA_TYPE_AUDIO)) {
ast_log(LOG_ERROR, "Motif channel driver requires an audio format when dialing a destination\n");
*cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
return NULL;
@@ -2001,7 +2012,7 @@ static struct ast_channel *jingle_request(const char *type, struct ast_format_ca
}
/* If video was requested try to enable it on the session */
- if (ast_format_cap_has_type(cap, AST_FORMAT_TYPE_VIDEO)) {
+ if (ast_format_cap_has_type(cap, AST_MEDIA_TYPE_VIDEO)) {
jingle_enable_video(session);
}
@@ -2043,8 +2054,8 @@ static int jingle_interpret_description(struct jingle_session *session, iks *des
ast_string_field_set(session, audio_name, name);
}
*rtp = session->rtp;
- ast_format_cap_remove_bytype(session->peercap, AST_FORMAT_TYPE_AUDIO);
- ast_format_cap_remove_bytype(session->jointcap, AST_FORMAT_TYPE_AUDIO);
+ ast_format_cap_remove_by_type(session->peercap, AST_MEDIA_TYPE_AUDIO);
+ ast_format_cap_remove_by_type(session->jointcap, AST_MEDIA_TYPE_AUDIO);
} else if (!strcasecmp(media, "video")) {
if (!ast_strlen_zero(name)) {
ast_string_field_set(session, video_name, name);
@@ -2060,8 +2071,8 @@ static int jingle_interpret_description(struct jingle_session *session, iks *des
return -1;
}
- ast_format_cap_remove_bytype(session->peercap, AST_FORMAT_TYPE_VIDEO);
- ast_format_cap_remove_bytype(session->jointcap, AST_FORMAT_TYPE_VIDEO);
+ ast_format_cap_remove_by_type(session->peercap, AST_MEDIA_TYPE_VIDEO);
+ ast_format_cap_remove_by_type(session->jointcap, AST_MEDIA_TYPE_VIDEO);
} else {
/* Unknown media type */
jingle_queue_hangup_with_cause(session, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
@@ -2082,8 +2093,6 @@ static int jingle_interpret_description(struct jingle_session *session, iks *des
int rtp_id, rtp_clockrate;
if (!ast_strlen_zero(id) && !ast_strlen_zero(name) && (sscanf(id, "%30d", &rtp_id) == 1)) {
- ast_rtp_codecs_payloads_set_m_type(&codecs, NULL, rtp_id);
-
if (!ast_strlen_zero(clockrate) && (sscanf(clockrate, "%30d", &rtp_clockrate) == 1)) {
ast_rtp_codecs_payloads_set_rtpmap_type_rate(&codecs, NULL, rtp_id, media, name, 0, rtp_clockrate);
} else {
@@ -2093,9 +2102,9 @@ static int jingle_interpret_description(struct jingle_session *session, iks *des
}
ast_rtp_codecs_payload_formats(&codecs, session->peercap, &othercapability);
- ast_format_cap_joint_append(session->cap, session->peercap, session->jointcap);
+ ast_format_cap_get_compatible(session->cap, session->peercap, session->jointcap);
- if (ast_format_cap_is_empty(session->jointcap)) {
+ if (!ast_format_cap_count(session->jointcap)) {
/* We have no compatible codecs, so terminate the session appropriately */
jingle_queue_hangup_with_cause(session, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
ast_rtp_codecs_payloads_destroy(&codecs);
@@ -2355,12 +2364,20 @@ static int jingle_interpret_content(struct jingle_session *session, ikspak *pak)
}
if ((chan = jingle_session_lock_full(session))) {
- struct ast_format fmt;
+ struct ast_format_cap *caps;
+ struct ast_format *fmt;
+
+ caps = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
+ if (caps) {
+ ast_format_cap_append_from_cap(caps, session->jointcap, AST_MEDIA_TYPE_UNKNOWN);
+ ast_channel_nativeformats_set(chan, caps);
+ ao2_ref(caps, -1);
+ }
- ast_format_cap_copy(ast_channel_nativeformats(chan), session->jointcap);
- ast_codec_choose(&session->prefs, session->jointcap, 1, &fmt);
- ast_set_read_format(chan, &fmt);
- ast_set_write_format(chan, &fmt);
+ fmt = ast_format_cap_get_format(session->jointcap, 0);
+ ast_set_read_format(chan, fmt);
+ ast_set_write_format(chan, fmt);
+ ao2_ref(fmt, -1);
ast_channel_unlock(chan);
ast_channel_unref(chan);
@@ -2710,7 +2727,7 @@ static int custom_transport_handler(const struct aco_option *opt, struct ast_var
*/
static int load_module(void)
{
- if (!(jingle_tech.capabilities = ast_format_cap_alloc(0))) {
+ if (!(jingle_tech.capabilities = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT))) {
return AST_MODULE_LOAD_DECLINE;
}
@@ -2726,8 +2743,8 @@ static int load_module(void)
aco_option_register(&cfg_info, "musicclass", ACO_EXACT, endpoint_options, NULL, OPT_STRINGFIELD_T, 0, STRFLDSET(struct jingle_endpoint, musicclass));
aco_option_register(&cfg_info, "parkinglot", ACO_EXACT, endpoint_options, NULL, OPT_STRINGFIELD_T, 0, STRFLDSET(struct jingle_endpoint, parkinglot));
aco_option_register(&cfg_info, "accountcode", ACO_EXACT, endpoint_options, NULL, OPT_STRINGFIELD_T, 0, STRFLDSET(struct jingle_endpoint, accountcode));
- aco_option_register(&cfg_info, "allow", ACO_EXACT, endpoint_options, "ulaw,alaw", OPT_CODEC_T, 1, FLDSET(struct jingle_endpoint, prefs, cap));
- aco_option_register(&cfg_info, "disallow", ACO_EXACT, endpoint_options, "all", OPT_CODEC_T, 0, FLDSET(struct jingle_endpoint, prefs, cap));
+ aco_option_register(&cfg_info, "allow", ACO_EXACT, endpoint_options, "ulaw,alaw", OPT_CODEC_T, 1, FLDSET(struct jingle_endpoint, cap));
+ aco_option_register(&cfg_info, "disallow", ACO_EXACT, endpoint_options, "all", OPT_CODEC_T, 0, FLDSET(struct jingle_endpoint, cap));
aco_option_register_custom(&cfg_info, "connection", ACO_EXACT, endpoint_options, NULL, custom_connection_handler, 0);
aco_option_register_custom(&cfg_info, "transport", ACO_EXACT, endpoint_options, NULL, custom_transport_handler, 0);
aco_option_register(&cfg_info, "maxicecandidates", ACO_EXACT, endpoint_options, DEFAULT_MAX_ICE_CANDIDATES, OPT_UINT_T, PARSE_DEFAULT,
@@ -2735,9 +2752,10 @@ static int load_module(void)
aco_option_register(&cfg_info, "maxpayloads", ACO_EXACT, endpoint_options, DEFAULT_MAX_PAYLOADS, OPT_UINT_T, PARSE_DEFAULT,
FLDSET(struct jingle_endpoint, maxpayloads), DEFAULT_MAX_PAYLOADS);
- ast_format_cap_add_all_by_type(jingle_tech.capabilities, AST_FORMAT_TYPE_AUDIO);
+ ast_format_cap_append_by_type(jingle_tech.capabilities, AST_MEDIA_TYPE_AUDIO);
if (aco_process_config(&cfg_info, 0)) {
+ ao2_ref(jingle_tech.capabilities, -1);
ast_log(LOG_ERROR, "Unable to read config file motif.conf. Module loaded but not running.\n");
aco_info_destroy(&cfg_info);
return AST_MODULE_LOAD_DECLINE;
@@ -2763,6 +2781,7 @@ static int load_module(void)
return 0;
end:
+ ao2_cleanup(jingle_tech.capabilities);
ast_rtp_glue_unregister(&jingle_rtp_glue);
if (sched) {
@@ -2784,7 +2803,7 @@ static int reload(void)
static int unload_module(void)
{
ast_channel_unregister(&jingle_tech);
- ast_format_cap_destroy(jingle_tech.capabilities);
+ ao2_cleanup(jingle_tech.capabilities);
jingle_tech.capabilities = NULL;
ast_rtp_glue_unregister(&jingle_rtp_glue);
ast_sched_context_destroy(sched);
diff --git a/channels/chan_multicast_rtp.c b/channels/chan_multicast_rtp.c
index 730b2f459..ae6022cb6 100644
--- a/channels/chan_multicast_rtp.c
+++ b/channels/chan_multicast_rtp.c
@@ -117,8 +117,10 @@ static struct ast_channel *multicast_rtp_request(const char *type, struct ast_fo
struct ast_sockaddr control_address;
struct ast_sockaddr destination_address;
struct ast_channel *chan;
- struct ast_format fmt;
- ast_best_codec(cap, &fmt);
+ struct ast_format_cap *caps = NULL;
+ struct ast_format *fmt = NULL;
+
+ fmt = ast_format_cap_get_format(cap, 0);
ast_sockaddr_setnull(&control_address);
@@ -145,6 +147,11 @@ static struct ast_channel *multicast_rtp_request(const char *type, struct ast_fo
goto failure;
}
+ caps = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
+ if (!caps) {
+ goto failure;
+ }
+
if (!(instance = ast_rtp_instance_new("multicast", NULL, &control_address, multicast_type))) {
goto failure;
}
@@ -158,19 +165,25 @@ static struct ast_channel *multicast_rtp_request(const char *type, struct ast_fo
ast_channel_tech_set(chan, &multicast_rtp_tech);
- ast_format_cap_add(ast_channel_nativeformats(chan), &fmt);
- ast_format_copy(ast_channel_writeformat(chan), &fmt);
- ast_format_copy(ast_channel_rawwriteformat(chan), &fmt);
- ast_format_copy(ast_channel_readformat(chan), &fmt);
- ast_format_copy(ast_channel_rawreadformat(chan), &fmt);
+ ast_format_cap_append(caps, fmt, 0);
+ ast_channel_nativeformats_set(chan, caps);
+ ast_channel_set_writeformat(chan, fmt);
+ ast_channel_set_rawwriteformat(chan, fmt);
+ ast_channel_set_readformat(chan, fmt);
+ ast_channel_set_rawreadformat(chan, fmt);
ast_channel_tech_pvt_set(chan, instance);
ast_channel_unlock(chan);
+ ao2_ref(fmt, -1);
+ ao2_ref(caps, -1);
+
return chan;
failure:
+ ao2_cleanup(fmt);
+ ao2_cleanup(caps);
*cause = AST_CAUSE_FAILURE;
return NULL;
}
@@ -178,12 +191,14 @@ failure:
/*! \brief Function called when our module is loaded */
static int load_module(void)
{
- if (!(multicast_rtp_tech.capabilities = ast_format_cap_alloc(0))) {
+ if (!(multicast_rtp_tech.capabilities = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT))) {
return AST_MODULE_LOAD_DECLINE;
}
- ast_format_cap_add_all(multicast_rtp_tech.capabilities);
+ ast_format_cap_append_by_type(multicast_rtp_tech.capabilities, AST_MEDIA_TYPE_UNKNOWN);
if (ast_channel_register(&multicast_rtp_tech)) {
ast_log(LOG_ERROR, "Unable to register channel class 'MulticastRTP'\n");
+ ao2_ref(multicast_rtp_tech.capabilities, -1);
+ multicast_rtp_tech.capabilities = NULL;
return AST_MODULE_LOAD_DECLINE;
}
@@ -194,7 +209,8 @@ static int load_module(void)
static int unload_module(void)
{
ast_channel_unregister(&multicast_rtp_tech);
- multicast_rtp_tech.capabilities = ast_format_cap_destroy(multicast_rtp_tech.capabilities);
+ ao2_ref(multicast_rtp_tech.capabilities, -1);
+ multicast_rtp_tech.capabilities = NULL;
return 0;
}
diff --git a/channels/chan_nbs.c b/channels/chan_nbs.c
index cbfb6b3c4..1be9bffeb 100644
--- a/channels/chan_nbs.c
+++ b/channels/chan_nbs.c
@@ -47,12 +47,10 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/module.h"
#include "asterisk/pbx.h"
#include "asterisk/utils.h"
+#include "asterisk/format_cache.h"
static const char tdesc[] = "Network Broadcast Sound Driver";
-/* Only linear is allowed */
-static struct ast_format prefformat;
-
static char context[AST_MAX_EXTENSION] = "default";
static const char type[] = "NBS";
@@ -63,7 +61,6 @@ struct nbs_pvt {
struct ast_channel *owner; /* Channel we belong to, possibly NULL */
char app[16]; /* Our app */
char stream[80]; /* Our stream */
- struct ast_frame fr; /* "null" frame */
struct ast_module_user *u; /*! for holding a reference to this module */
};
@@ -178,37 +175,14 @@ static int nbs_hangup(struct ast_channel *ast)
static struct ast_frame *nbs_xread(struct ast_channel *ast)
{
- struct nbs_pvt *p = ast_channel_tech_pvt(ast);
-
-
- /* Some nice norms */
- p->fr.datalen = 0;
- p->fr.samples = 0;
- p->fr.data.ptr = NULL;
- p->fr.src = type;
- p->fr.offset = 0;
- p->fr.mallocd=0;
- p->fr.delivery.tv_sec = 0;
- p->fr.delivery.tv_usec = 0;
-
ast_debug(1, "Returning null frame on %s\n", ast_channel_name(ast));
- return &p->fr;
+ return &ast_null_frame;
}
static int nbs_xwrite(struct ast_channel *ast, struct ast_frame *frame)
{
struct nbs_pvt *p = ast_channel_tech_pvt(ast);
- /* Write a frame of (presumably voice) data */
- if (frame->frametype != AST_FRAME_VOICE) {
- if (frame->frametype != AST_FRAME_IMAGE)
- ast_log(LOG_WARNING, "Don't know what to do with frame type '%d'\n", frame->frametype);
- return 0;
- }
- if (frame->subclass.format.id != (AST_FORMAT_SLINEAR)) {
- ast_log(LOG_WARNING, "Cannot handle frames in %s format\n", ast_getformatname(&frame->subclass.format));
- return 0;
- }
if (ast_channel_state(ast) != AST_STATE_UP) {
/* Don't try tos end audio on-hook */
return 0;
@@ -226,11 +200,11 @@ static struct ast_channel *nbs_new(struct nbs_pvt *i, int state, const struct as
ast_channel_tech_set(tmp, &nbs_tech);
ast_channel_set_fd(tmp, 0, nbs_fd(i->nbs));
- ast_format_cap_add(ast_channel_nativeformats(tmp), &prefformat);
- ast_format_copy(ast_channel_rawreadformat(tmp), &prefformat);
- ast_format_copy(ast_channel_rawwriteformat(tmp), &prefformat);
- ast_format_copy(ast_channel_writeformat(tmp), &prefformat);
- ast_format_copy(ast_channel_readformat(tmp), &prefformat);
+ ast_channel_nativeformats_set(tmp, nbs_tech.capabilities);
+ ast_channel_set_rawreadformat(tmp, ast_format_slin);
+ ast_channel_set_rawwriteformat(tmp, ast_format_slin);
+ ast_channel_set_writeformat(tmp, ast_format_slin);
+ ast_channel_set_readformat(tmp, ast_format_slin);
if (state == AST_STATE_RING)
ast_channel_rings_set(tmp, 1);
ast_channel_tech_pvt_set(tmp, i);
@@ -257,9 +231,11 @@ static struct ast_channel *nbs_request(const char *type, struct ast_format_cap *
struct nbs_pvt *p;
struct ast_channel *tmp = NULL;
- if (!(ast_format_cap_iscompatible(cap, &prefformat))) {
- char tmp[256];
- ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%s'\n", ast_getformatname_multiple(tmp, sizeof(tmp), cap));
+ if (ast_format_cap_iscompatible_format(cap, ast_format_slin) == AST_FORMAT_CMP_NOT_EQUAL) {
+ struct ast_str *cap_buf = ast_str_alloca(64);
+
+ ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%s'\n",
+ ast_format_cap_get_names(cap, &cap_buf));
return NULL;
}
p = nbs_alloc(data);
@@ -275,17 +251,17 @@ static int unload_module(void)
{
/* First, take us out of the channel loop */
ast_channel_unregister(&nbs_tech);
- nbs_tech.capabilities = ast_format_cap_destroy(nbs_tech.capabilities);
+ ao2_ref(nbs_tech.capabilities, -1);
+ nbs_tech.capabilities = NULL;
return 0;
}
static int load_module(void)
{
- ast_format_set(&prefformat, AST_FORMAT_SLINEAR, 0);
- if (!(nbs_tech.capabilities = ast_format_cap_alloc(0))) {
+ if (!(nbs_tech.capabilities = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT))) {
return AST_MODULE_LOAD_FAILURE;
}
- ast_format_cap_add(nbs_tech.capabilities, &prefformat);
+ ast_format_cap_append(nbs_tech.capabilities, ast_format_slin, 0);
/* Make sure we can register our channel type */
if (ast_channel_register(&nbs_tech)) {
ast_log(LOG_ERROR, "Unable to register channel class %s\n", type);
diff --git a/channels/chan_oss.c b/channels/chan_oss.c
index 4459b4b6f..46b751d7c 100644
--- a/channels/chan_oss.c
+++ b/channels/chan_oss.c
@@ -69,6 +69,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/musiconhold.h"
#include "asterisk/app.h"
#include "asterisk/bridge.h"
+#include "asterisk/format_cache.h"
#include "console_video.h"
@@ -726,7 +727,7 @@ static struct ast_frame *oss_read(struct ast_channel *c)
return f;
/* ok we can build and deliver the frame to the caller */
f->frametype = AST_FRAME_VOICE;
- ast_format_set(&f->subclass.format, AST_FORMAT_SLINEAR, 0);
+ f->subclass.format = ao2_bump(ast_format_slin);
f->samples = FRAME_SIZE;
f->datalen = FRAME_SIZE * 2;
f->data.ptr = o->oss_read_buf + AST_FRIENDLY_OFFSET;
@@ -804,9 +805,9 @@ static struct ast_channel *oss_new(struct chan_oss_pvt *o, char *ext, char *ctx,
setformat(o, O_RDWR);
ast_channel_set_fd(c, 0, o->sounddev); /* -1 if device closed, override later */
- ast_format_set(ast_channel_readformat(c), AST_FORMAT_SLINEAR, 0);
- ast_format_set(ast_channel_writeformat(c), AST_FORMAT_SLINEAR, 0);
- ast_format_cap_add(ast_channel_nativeformats(c), ast_channel_readformat(c));
+ ast_channel_set_readformat(c, ast_format_slin);
+ ast_channel_set_writeformat(c, ast_format_slin);
+ ast_channel_nativeformats_set(c, oss_tech.capabilities);
/* if the console makes the call, add video to the offer */
/* if (state == AST_STATE_RINGING) TODO XXX CONSOLE VIDEO IS DISABLED UNTIL IT GETS A MAINTAINER
@@ -851,8 +852,6 @@ static struct ast_channel *oss_request(const char *type, struct ast_format_cap *
AST_APP_ARG(flags);
);
char *parse = ast_strdupa(data);
- char buf[256];
- struct ast_format tmpfmt;
AST_NONSTANDARD_APP_ARGS(args, parse, '/');
o = find_desc(args.name);
@@ -863,8 +862,9 @@ static struct ast_channel *oss_request(const char *type, struct ast_format_cap *
/* XXX we could default to 'dsp' perhaps ? */
return NULL;
}
- if (!(ast_format_cap_iscompatible(cap, ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR, 0)))) {
- ast_log(LOG_NOTICE, "Format %s unsupported\n", ast_getformatname_multiple(buf, sizeof(buf), cap));
+ if (ast_format_cap_iscompatible_format(cap, ast_format_slin) == AST_FORMAT_CMP_NOT_EQUAL) {
+ struct ast_str *codec_buf = ast_str_alloca(64);
+ ast_log(LOG_NOTICE, "Format %s unsupported\n", ast_format_cap_get_names(cap, &codec_buf));
return NULL;
}
if (o->owner) {
@@ -1452,7 +1452,6 @@ static int load_module(void)
struct ast_config *cfg = NULL;
char *ctg = NULL;
struct ast_flags config_flags = { 0 };
- struct ast_format tmpfmt;
/* Copy the default jb config over global_jbconf */
memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf));
@@ -1482,7 +1481,7 @@ static int load_module(void)
if (!(oss_tech.capabilities = ast_format_cap_alloc(0))) {
return AST_MODULE_LOAD_FAILURE;
}
- ast_format_cap_add(oss_tech.capabilities, ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR, 0));
+ ast_format_cap_append(oss_tech.capabilities, ast_format_slin, 0);
/* TODO XXX CONSOLE VIDEO IS DISABLE UNTIL IT HAS A MAINTAINER
* add console_video_formats to oss_tech.capabilities once this occurs. */
@@ -1517,7 +1516,9 @@ static int unload_module(void)
ast_free(o);
o = next;
}
- oss_tech.capabilities = ast_format_cap_destroy(oss_tech.capabilities);
+ ao2_cleanup(oss_tech.capabilities);
+ oss_tech.capabilities = NULL;
+
return 0;
}
diff --git a/channels/chan_phone.c b/channels/chan_phone.c
index 1e5e19d57..72f38291b 100644
--- a/channels/chan_phone.c
+++ b/channels/chan_phone.c
@@ -67,6 +67,8 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/causes.h"
#include "asterisk/stringfields.h"
#include "asterisk/musiconhold.h"
+#include "asterisk/format_cache.h"
+#include "asterisk/format_compatibility.h"
#include "chan_phone.h"
@@ -134,8 +136,8 @@ static struct phone_pvt {
int fd; /* Raw file descriptor for this device */
struct ast_channel *owner; /* Channel we belong to, possibly NULL */
int mode; /* Is this in the */
- struct ast_format lastformat; /* Last output format */
- struct ast_format lastinput; /* Last input format */
+ struct ast_format *lastformat; /* Last output format */
+ struct ast_format *lastinput; /* Last input format */
int ministate; /* Miniature state, for dialtone mode */
char dev[256]; /* Device name */
struct phone_pvt *next; /* Next channel in list */
@@ -218,7 +220,8 @@ static int phone_indicate(struct ast_channel *chan, int condition, const void *d
ioctl(p->fd, IXJCTL_PSTN_SET_STATE, PSTN_ON_HOOK);
usleep(320000);
ioctl(p->fd, IXJCTL_PSTN_SET_STATE, PSTN_OFF_HOOK);
- ast_format_clear(&p->lastformat);
+ ao2_cleanup(p->lastformat);
+ p->lastformat = NULL;
res = 0;
break;
case AST_CONTROL_HOLD:
@@ -282,7 +285,8 @@ static int phone_digit_end(struct ast_channel *ast, char digit, unsigned int dur
ioctl(p->fd, IXJCTL_PSTN_SET_STATE, PSTN_ON_HOOK);
usleep(320000);
ioctl(p->fd, IXJCTL_PSTN_SET_STATE, PSTN_OFF_HOOK);
- ast_format_clear(&p->lastformat);
+ ao2_cleanup(p->lastformat);
+ p->lastformat = NULL;
return 0;
default:
ast_log(LOG_WARNING, "Unknown digit '%c'\n", digit);
@@ -290,7 +294,8 @@ static int phone_digit_end(struct ast_channel *ast, char digit, unsigned int dur
}
ast_debug(1, "Dialed %d\n", outdigit);
ioctl(p->fd, PHONE_PLAY_TONE, outdigit);
- ast_format_clear(&p->lastformat);
+ ao2_cleanup(p->lastformat);
+ p->lastformat = NULL;
return 0;
}
@@ -381,8 +386,10 @@ static int phone_hangup(struct ast_channel *ast)
ioctl(p->fd, PHONE_BUSY);
p->cpt = 1;
}
- ast_format_clear(&p->lastformat);
- ast_format_clear(&p->lastinput);
+ ao2_cleanup(p->lastformat);
+ p->lastformat = NULL;
+ ao2_cleanup(p->lastinput);
+ p->lastinput = NULL;
p->ministate = 0;
p->obuflen = 0;
p->dialtone = 0;
@@ -402,38 +409,38 @@ static int phone_setup(struct ast_channel *ast)
p = ast_channel_tech_pvt(ast);
ioctl(p->fd, PHONE_CPT_STOP);
/* Nothing to answering really, just start recording */
- if (ast_channel_rawreadformat(ast)->id == AST_FORMAT_G729A) {
+ if (ast_format_cmp(ast_channel_rawreadformat(ast), ast_format_g729) == AST_FORMAT_CMP_EQUAL) {
/* Prefer g729 */
ioctl(p->fd, PHONE_REC_STOP);
- if (p->lastinput.id != AST_FORMAT_G729A) {
- ast_format_set(&p->lastinput, AST_FORMAT_G729A, 0);
+ if (!p->lastinput || (ast_format_cmp(p->lastinput, ast_format_g729) != AST_FORMAT_CMP_EQUAL)) {
+ ao2_replace(p->lastinput, ast_format_g729);
if (ioctl(p->fd, PHONE_REC_CODEC, G729)) {
ast_log(LOG_WARNING, "Failed to set codec to g729\n");
return -1;
}
}
- } else if (ast_channel_rawreadformat(ast)->id == AST_FORMAT_G723_1) {
+ } else if (ast_format_cmp(ast_channel_rawreadformat(ast), ast_format_g723) == AST_FORMAT_CMP_EQUAL) {
ioctl(p->fd, PHONE_REC_STOP);
- if (p->lastinput.id != AST_FORMAT_G723_1) {
- ast_format_set(&p->lastinput, AST_FORMAT_G723_1, 0);
+ if (!p->lastinput || (ast_format_cmp(p->lastinput, ast_format_g723) != AST_FORMAT_CMP_EQUAL)) {
+ ao2_replace(p->lastinput, ast_format_g723);
if (ioctl(p->fd, PHONE_REC_CODEC, G723_63)) {
ast_log(LOG_WARNING, "Failed to set codec to g723.1\n");
return -1;
}
}
- } else if (ast_channel_rawreadformat(ast)->id == AST_FORMAT_SLINEAR) {
+ } else if (ast_format_cmp(ast_channel_rawreadformat(ast), ast_format_slin) == AST_FORMAT_CMP_EQUAL) {
ioctl(p->fd, PHONE_REC_STOP);
- if (p->lastinput.id != AST_FORMAT_SLINEAR) {
- ast_format_set(&p->lastinput, AST_FORMAT_SLINEAR, 0);
+ if (!p->lastinput || (ast_format_cmp(p->lastinput, ast_format_slin) != AST_FORMAT_CMP_EQUAL)) {
+ ao2_replace(p->lastinput, ast_format_slin);
if (ioctl(p->fd, PHONE_REC_CODEC, LINEAR16)) {
ast_log(LOG_WARNING, "Failed to set codec to signed linear 16\n");
return -1;
}
}
- } else if (ast_channel_rawreadformat(ast)->id == AST_FORMAT_ULAW) {
+ } else if (ast_format_cmp(ast_channel_rawreadformat(ast), ast_format_ulaw) == AST_FORMAT_CMP_EQUAL) {
ioctl(p->fd, PHONE_REC_STOP);
- if (p->lastinput.id != AST_FORMAT_ULAW) {
- ast_format_set(&p->lastinput, AST_FORMAT_ULAW, 0);
+ if (!p->lastinput || (ast_format_cmp(p->lastinput, ast_format_ulaw) != AST_FORMAT_CMP_EQUAL)) {
+ ao2_replace(p->lastinput, ast_format_ulaw);
if (ioctl(p->fd, PHONE_REC_CODEC, ULAW)) {
ast_log(LOG_WARNING, "Failed to set codec to uLaw\n");
return -1;
@@ -441,16 +448,16 @@ static int phone_setup(struct ast_channel *ast)
}
} else if (p->mode == MODE_FXS) {
ioctl(p->fd, PHONE_REC_STOP);
- if (ast_format_cmp(&p->lastinput, ast_channel_rawreadformat(ast)) == AST_FORMAT_CMP_NOT_EQUAL) {
- ast_format_copy(&p->lastinput, ast_channel_rawreadformat(ast));
+ if (!p->lastinput || (ast_format_cmp(p->lastinput, ast_channel_rawreadformat(ast)) == AST_FORMAT_CMP_NOT_EQUAL)) {
+ ao2_replace(p->lastinput, ast_channel_rawreadformat(ast));
if (ioctl(p->fd, PHONE_REC_CODEC, ast_channel_rawreadformat(ast))) {
ast_log(LOG_WARNING, "Failed to set codec to %s\n",
- ast_getformatname(ast_channel_rawreadformat(ast)));
+ ast_format_get_name(ast_channel_rawreadformat(ast)));
return -1;
}
}
} else {
- ast_log(LOG_WARNING, "Can't do format %s\n", ast_getformatname(ast_channel_rawreadformat(ast)));
+ ast_log(LOG_WARNING, "Can't do format %s\n", ast_format_get_name(ast_channel_rawreadformat(ast)));
return -1;
}
if (ioctl(p->fd, PHONE_REC_START)) {
@@ -601,13 +608,13 @@ static struct ast_frame *phone_read(struct ast_channel *ast)
}
p->fr.samples = 240;
p->fr.datalen = res;
- p->fr.frametype = AST_FORMAT_GET_TYPE(p->lastinput.id) == AST_FORMAT_TYPE_AUDIO ?
- AST_FRAME_VOICE : AST_FORMAT_GET_TYPE(p->lastinput.id) == AST_FORMAT_TYPE_IMAGE ?
+ p->fr.frametype = ast_format_get_type(p->lastinput) == AST_MEDIA_TYPE_AUDIO ?
+ AST_FRAME_VOICE : ast_format_get_type(p->lastinput) == AST_MEDIA_TYPE_IMAGE ?
AST_FRAME_IMAGE : AST_FRAME_VIDEO;
- ast_format_copy(&p->fr.subclass.format, &p->lastinput);
+ p->fr.subclass.format = p->lastinput;
p->fr.offset = AST_FRIENDLY_OFFSET;
/* Byteswap from little-endian to native-endian */
- if (p->fr.subclass.format.id == AST_FORMAT_SLINEAR)
+ if (ast_format_cmp(p->fr.subclass.format, ast_format_slin) == AST_FORMAT_CMP_EQUAL)
ast_frame_byteswap_le(&p->fr);
return &p->fr;
}
@@ -669,14 +676,6 @@ static int phone_write(struct ast_channel *ast, struct ast_frame *frame)
ast_log(LOG_WARNING, "Don't know what to do with frame type '%u'\n", frame->frametype);
return 0;
}
- if (!(frame->subclass.format.id == AST_FORMAT_G723_1 ||
- frame->subclass.format.id == AST_FORMAT_SLINEAR ||
- frame->subclass.format.id == AST_FORMAT_ULAW ||
- frame->subclass.format.id == AST_FORMAT_G729A) &&
- p->mode != MODE_FXS) {
- ast_log(LOG_WARNING, "Cannot handle frames in %s format\n", ast_getformatname(&frame->subclass.format));
- return -1;
- }
#if 0
/* If we're not in up mode, go into up mode now */
if (ast->_state != AST_STATE_UP) {
@@ -689,8 +688,8 @@ static int phone_write(struct ast_channel *ast, struct ast_frame *frame)
return 0;
}
#endif
- if (frame->subclass.format.id == AST_FORMAT_G729A) {
- if (p->lastformat.id != AST_FORMAT_G729A) {
+ if (ast_format_cmp(frame->subclass.format, ast_format_g729) == AST_FORMAT_CMP_EQUAL) {
+ if (!p->lastformat || (ast_format_cmp(p->lastformat, ast_format_g729) != AST_FORMAT_CMP_EQUAL)) {
ioctl(p->fd, PHONE_PLAY_STOP);
ioctl(p->fd, PHONE_REC_STOP);
if (ioctl(p->fd, PHONE_PLAY_CODEC, G729)) {
@@ -701,8 +700,8 @@ static int phone_write(struct ast_channel *ast, struct ast_frame *frame)
ast_log(LOG_WARNING, "Unable to set G729 mode\n");
return -1;
}
- ast_format_set(&p->lastformat, AST_FORMAT_G729A, 0);
- ast_format_set(&p->lastinput, AST_FORMAT_G729A, 0);
+ ao2_replace(p->lastformat, ast_format_g729);
+ ao2_replace(p->lastinput, ast_format_g729);
/* Reset output buffer */
p->obuflen = 0;
codecset = 1;
@@ -712,8 +711,8 @@ static int phone_write(struct ast_channel *ast, struct ast_frame *frame)
return -1;
}
maxfr = 80;
- } else if (frame->subclass.format.id == AST_FORMAT_G723_1) {
- if (p->lastformat.id != AST_FORMAT_G723_1) {
+ } else if (ast_format_cmp(frame->subclass.format, ast_format_g723) == AST_FORMAT_CMP_EQUAL) {
+ if (!p->lastformat || (ast_format_cmp(p->lastformat, ast_format_g723) != AST_FORMAT_CMP_EQUAL)) {
ioctl(p->fd, PHONE_PLAY_STOP);
ioctl(p->fd, PHONE_REC_STOP);
if (ioctl(p->fd, PHONE_PLAY_CODEC, G723_63)) {
@@ -724,8 +723,8 @@ static int phone_write(struct ast_channel *ast, struct ast_frame *frame)
ast_log(LOG_WARNING, "Unable to set G723.1 mode\n");
return -1;
}
- ast_format_set(&p->lastformat, AST_FORMAT_G723_1, 0);
- ast_format_set(&p->lastinput, AST_FORMAT_G723_1, 0);
+ ao2_replace(p->lastformat, ast_format_g723);
+ ao2_replace(p->lastinput, ast_format_g723);
/* Reset output buffer */
p->obuflen = 0;
codecset = 1;
@@ -735,8 +734,8 @@ static int phone_write(struct ast_channel *ast, struct ast_frame *frame)
return -1;
}
maxfr = 24;
- } else if (frame->subclass.format.id == AST_FORMAT_SLINEAR) {
- if (p->lastformat.id != AST_FORMAT_SLINEAR) {
+ } else if (ast_format_cmp(frame->subclass.format, ast_format_slin) == AST_FORMAT_CMP_EQUAL) {
+ if (!p->lastformat || (ast_format_cmp(p->lastformat, ast_format_slin) != AST_FORMAT_CMP_EQUAL)) {
ioctl(p->fd, PHONE_PLAY_STOP);
ioctl(p->fd, PHONE_REC_STOP);
if (ioctl(p->fd, PHONE_PLAY_CODEC, LINEAR16)) {
@@ -747,15 +746,15 @@ static int phone_write(struct ast_channel *ast, struct ast_frame *frame)
ast_log(LOG_WARNING, "Unable to set 16-bit linear mode\n");
return -1;
}
- ast_format_set(&p->lastformat, AST_FORMAT_SLINEAR, 0);
- ast_format_set(&p->lastinput, AST_FORMAT_SLINEAR, 0);
+ ao2_replace(p->lastformat, ast_format_slin);
+ ao2_replace(p->lastinput, ast_format_slin);
codecset = 1;
/* Reset output buffer */
p->obuflen = 0;
}
maxfr = 480;
- } else if (frame->subclass.format.id == AST_FORMAT_ULAW) {
- if (p->lastformat.id != AST_FORMAT_ULAW) {
+ } else if (ast_format_cmp(frame->subclass.format, ast_format_ulaw) == AST_FORMAT_CMP_EQUAL) {
+ if (!p->lastformat || (ast_format_cmp(p->lastformat, ast_format_ulaw) != AST_FORMAT_CMP_EQUAL)) {
ioctl(p->fd, PHONE_PLAY_STOP);
ioctl(p->fd, PHONE_REC_STOP);
if (ioctl(p->fd, PHONE_PLAY_CODEC, ULAW)) {
@@ -766,29 +765,29 @@ static int phone_write(struct ast_channel *ast, struct ast_frame *frame)
ast_log(LOG_WARNING, "Unable to set uLaw mode\n");
return -1;
}
- ast_format_set(&p->lastformat, AST_FORMAT_ULAW, 0);
- ast_format_set(&p->lastinput, AST_FORMAT_ULAW, 0);
+ ao2_replace(p->lastformat, ast_format_ulaw);
+ ao2_replace(p->lastinput, ast_format_ulaw);
codecset = 1;
/* Reset output buffer */
p->obuflen = 0;
}
maxfr = 240;
} else {
- if (ast_format_cmp(&p->lastformat, &frame->subclass.format) != AST_FORMAT_CMP_EQUAL) {
+ if (!p->lastformat || (ast_format_cmp(p->lastformat, frame->subclass.format) != AST_FORMAT_CMP_EQUAL)) {
ioctl(p->fd, PHONE_PLAY_STOP);
ioctl(p->fd, PHONE_REC_STOP);
- if (ioctl(p->fd, PHONE_PLAY_CODEC, (int) frame->subclass.format.id)) {
+ if (ioctl(p->fd, PHONE_PLAY_CODEC, ast_format_compatibility_format2bitfield(frame->subclass.format))) {
ast_log(LOG_WARNING, "Unable to set %s mode\n",
- ast_getformatname(&frame->subclass.format));
+ ast_format_get_name(frame->subclass.format));
return -1;
}
- if (ioctl(p->fd, PHONE_REC_CODEC, (int) frame->subclass.format.id)) {
+ if (ioctl(p->fd, PHONE_REC_CODEC, ast_format_compatibility_format2bitfield(frame->subclass.format))) {
ast_log(LOG_WARNING, "Unable to set %s mode\n",
- ast_getformatname(&frame->subclass.format));
+ ast_format_get_name(frame->subclass.format));
return -1;
}
- ast_format_copy(&p->lastformat, &frame->subclass.format);
- ast_format_copy(&p->lastinput, &frame->subclass.format);
+ ao2_replace(p->lastformat, frame->subclass.format);
+ ao2_replace(p->lastinput, frame->subclass.format);
codecset = 1;
/* Reset output buffer */
p->obuflen = 0;
@@ -857,11 +856,13 @@ static int phone_write(struct ast_channel *ast, struct ast_frame *frame)
static struct ast_channel *phone_new(struct phone_pvt *i, int state, char *cntx, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor)
{
+ struct ast_format_cap *caps = NULL;
struct ast_channel *tmp;
struct phone_codec_data queried_codec;
- struct ast_format tmpfmt;
+ struct ast_format *tmpfmt;
+ caps = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, "", i->ext, i->context, assignedids, requestor, 0, "Phone/%s", i->dev + 5);
- if (tmp) {
+ if (tmp && caps) {
ast_channel_lock(tmp);
ast_channel_tech_set(tmp, cur_tech);
ast_channel_set_fd(tmp, 0, i->fd);
@@ -869,18 +870,20 @@ static struct ast_channel *phone_new(struct phone_pvt *i, int state, char *cntx,
if (i->mode == MODE_FXS &&
ioctl(i->fd, PHONE_QUERY_CODEC, &queried_codec) == 0) {
if (queried_codec.type == LINEAR16) {
- ast_format_cap_add(ast_channel_nativeformats(tmp), ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR, 0));
- ast_format_copy(ast_channel_rawreadformat(tmp), &tmpfmt);
- ast_format_copy(ast_channel_rawwriteformat(tmp), &tmpfmt);
+ ast_format_cap_append(caps, ast_format_slin, 0);
} else {
- ast_format_cap_remove(prefcap, ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR, 0));
+ ast_format_cap_remove(prefcap, ast_format_slin);
+ ast_format_cap_append_from_cap(caps, prefcap, AST_MEDIA_TYPE_UNKNOWN);
}
} else {
- ast_format_cap_copy(ast_channel_nativeformats(tmp), prefcap);
- ast_best_codec(ast_channel_nativeformats(tmp), &tmpfmt);
- ast_format_copy(ast_channel_rawreadformat(tmp), &tmpfmt);
- ast_format_copy(ast_channel_rawwriteformat(tmp), &tmpfmt);
+ ast_format_cap_append_from_cap(caps, prefcap, AST_MEDIA_TYPE_UNKNOWN);
}
+ tmpfmt = ast_format_cap_get_format(caps, 0);
+ ast_channel_nativeformats_set(tmp, caps);
+ ao2_ref(caps, -1);
+ ast_channel_set_rawreadformat(tmp, tmpfmt);
+ ast_channel_set_rawwriteformat(tmp, tmpfmt);
+ ao2_ref(tmpfmt, -1);
/* no need to call ast_setstate: the channel_alloc already did its job */
if (state == AST_STATE_RING)
ast_channel_rings_set(tmp, 1);
@@ -913,8 +916,10 @@ static struct ast_channel *phone_new(struct phone_pvt *i, int state, char *cntx,
ast_hangup(tmp);
}
}
- } else
+ } else {
+ ao2_cleanup(caps);
ast_log(LOG_WARNING, "Unable to allocate channel structure\n");
+ }
return tmp;
}
@@ -989,7 +994,8 @@ static void phone_check_exception(struct phone_pvt *i)
ioctl(i->fd, PHONE_PLAY_STOP);
ioctl(i->fd, PHONE_PLAY_CODEC, ULAW);
ioctl(i->fd, PHONE_PLAY_START);
- ast_format_clear(&i->lastformat);
+ ao2_cleanup(i->lastformat);
+ i->lastformat = NULL;
} else if (i->mode == MODE_SIGMA) {
ast_module_ref(ast_module_info->self);
/* Reset the extension */
@@ -1010,7 +1016,8 @@ static void phone_check_exception(struct phone_pvt *i)
ioctl(i->fd, PHONE_PLAY_STOP);
ioctl(i->fd, PHONE_REC_STOP);
i->dialtone = 0;
- ast_format_clear(&i->lastformat);
+ ao2_cleanup(i->lastformat);
+ i->lastformat = NULL;
}
}
if (phonee.bits.pstn_ring) {
@@ -1222,8 +1229,10 @@ static struct phone_pvt *mkif(const char *iface, int mode, int txgain, int rxgai
flags = fcntl(tmp->fd, F_GETFL);
fcntl(tmp->fd, F_SETFL, flags | O_NONBLOCK);
tmp->owner = NULL;
- ast_format_clear(&tmp->lastformat);
- ast_format_clear(&tmp->lastinput);
+ ao2_cleanup(tmp->lastformat);
+ tmp->lastformat = NULL;
+ ao2_cleanup(tmp->lastinput);
+ tmp->lastinput = NULL;
tmp->ministate = 0;
memset(tmp->ext, 0, sizeof(tmp->ext));
ast_copy_string(tmp->language, language, sizeof(tmp->language));
@@ -1256,7 +1265,7 @@ static struct ast_channel *phone_request(const char *type, struct ast_format_cap
}
p = iflist;
while(p) {
- if (p->mode == MODE_FXS || (ast_format_cap_has_joint(cap, phone_tech.capabilities))) {
+ if (p->mode == MODE_FXS || (ast_format_cap_iscompatible(cap, phone_tech.capabilities))) {
size_t length = strlen(p->dev + 5);
if (strncmp(name, p->dev + 5, length) == 0 &&
!isalnum(name[length])) {
@@ -1272,9 +1281,10 @@ static struct ast_channel *phone_request(const char *type, struct ast_format_cap
ast_mutex_unlock(&iflock);
restart_monitor();
if (tmp == NULL) {
- if (!(ast_format_cap_has_joint(cap, phone_tech.capabilities))) {
- char buf[256];
- ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%s'\n", ast_getformatname_multiple(buf, sizeof(buf), cap));
+ if (!(ast_format_cap_iscompatible(cap, phone_tech.capabilities))) {
+ struct ast_str *codec_buf = ast_str_alloca(64);
+ ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%s'\n",
+ ast_format_cap_get_names(cap, &codec_buf));
return NULL;
}
}
@@ -1357,9 +1367,10 @@ static int __unload_module(void)
return -1;
}
- phone_tech.capabilities = ast_format_cap_destroy(phone_tech.capabilities);
- phone_tech_fxs.capabilities = ast_format_cap_destroy(phone_tech_fxs.capabilities);
- prefcap = ast_format_cap_destroy(prefcap);
+ ao2_ref(phone_tech.capabilities, -1);
+ ao2_ref(phone_tech_fxs.capabilities, -1);
+ ao2_ref(prefcap, -1);
+
return 0;
}
@@ -1376,21 +1387,21 @@ static int load_module(void)
int mode = MODE_IMMEDIATE;
int txgain = DEFAULT_GAIN, rxgain = DEFAULT_GAIN; /* default gain 1.0 */
struct ast_flags config_flags = { 0 };
- struct ast_format tmpfmt;
- if (!(phone_tech.capabilities = ast_format_cap_alloc(0))) {
+ if (!(phone_tech.capabilities = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT))) {
return AST_MODULE_LOAD_DECLINE;
}
- ast_format_cap_add(phone_tech.capabilities, ast_format_set(&tmpfmt, AST_FORMAT_G723_1, 0));
- ast_format_cap_add(phone_tech.capabilities, ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR, 0));
- ast_format_cap_add(phone_tech.capabilities, ast_format_set(&tmpfmt, AST_FORMAT_ULAW, 0));
- ast_format_cap_add(phone_tech.capabilities, ast_format_set(&tmpfmt, AST_FORMAT_G729A, 0));
- if (!(prefcap = ast_format_cap_alloc(0))) {
+ ast_format_cap_append(phone_tech.capabilities, ast_format_g723, 0);
+ ast_format_cap_append(phone_tech.capabilities, ast_format_slin, 0);
+ ast_format_cap_append(phone_tech.capabilities, ast_format_ulaw, 0);
+ ast_format_cap_append(phone_tech.capabilities, ast_format_g729, 0);
+
+ if (!(prefcap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT))) {
return AST_MODULE_LOAD_DECLINE;
}
- ast_format_cap_copy(prefcap, phone_tech.capabilities);
- if (!(phone_tech_fxs.capabilities = ast_format_cap_alloc(0))) {
+ ast_format_cap_append_from_cap(prefcap, phone_tech.capabilities, AST_MEDIA_TYPE_UNKNOWN);
+ if (!(phone_tech_fxs.capabilities = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT))) {
return AST_MODULE_LOAD_DECLINE;
}
@@ -1440,7 +1451,7 @@ static int load_module(void)
mode = MODE_IMMEDIATE;
else if (!strncasecmp(v->value, "fxs", 3)) {
mode = MODE_FXS;
- ast_format_cap_remove_bytype(prefcap, AST_FORMAT_TYPE_AUDIO); /* All non-voice */
+ ast_format_cap_remove_by_type(prefcap, AST_MEDIA_TYPE_AUDIO); /* All non-voice */
}
else if (!strncasecmp(v->value, "fx", 2))
mode = MODE_FXO;
@@ -1450,18 +1461,21 @@ static int load_module(void)
ast_copy_string(context, v->value, sizeof(context));
} else if (!strcasecmp(v->name, "format")) {
if (!strcasecmp(v->value, "g729")) {
- ast_format_cap_set(prefcap, ast_format_set(&tmpfmt, AST_FORMAT_G729A, 0));
+ ast_format_cap_remove_by_type(prefcap, AST_MEDIA_TYPE_UNKNOWN);
+ ast_format_cap_append(prefcap, ast_format_g729, 0);
} else if (!strcasecmp(v->value, "g723.1")) {
- ast_format_cap_set(prefcap, ast_format_set(&tmpfmt, AST_FORMAT_G723_1, 0));
+ ast_format_cap_remove_by_type(prefcap, AST_MEDIA_TYPE_UNKNOWN);
+ ast_format_cap_append(prefcap, ast_format_g723, 0);
} else if (!strcasecmp(v->value, "slinear")) {
- ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR, 0);
if (mode == MODE_FXS) {
- ast_format_cap_add(prefcap, &tmpfmt);
+ ast_format_cap_append(prefcap, ast_format_slin, 0);
} else {
- ast_format_cap_set(prefcap, &tmpfmt);
+ ast_format_cap_remove_by_type(prefcap, AST_MEDIA_TYPE_UNKNOWN);
+ ast_format_cap_append(prefcap, ast_format_slin, 0);
}
} else if (!strcasecmp(v->value, "ulaw")) {
- ast_format_cap_set(prefcap, ast_format_set(&tmpfmt, AST_FORMAT_ULAW, 0));
+ ast_format_cap_remove_by_type(prefcap, AST_MEDIA_TYPE_UNKNOWN);
+ ast_format_cap_append(prefcap, ast_format_ulaw, 0);
} else
ast_log(LOG_WARNING, "Unknown format '%s'\n", v->value);
} else if (!strcasecmp(v->name, "echocancel")) {
@@ -1485,7 +1499,7 @@ static int load_module(void)
ast_mutex_unlock(&iflock);
if (mode == MODE_FXS) {
- ast_format_cap_copy(phone_tech_fxs.capabilities, prefcap);
+ ast_format_cap_append_from_cap(phone_tech_fxs.capabilities, prefcap, AST_MEDIA_TYPE_UNKNOWN);
cur_tech = &phone_tech_fxs;
} else
cur_tech = (struct ast_channel_tech *) &phone_tech;
diff --git a/channels/chan_pjsip.c b/channels/chan_pjsip.c
index 695211480..5812360c5 100644
--- a/channels/chan_pjsip.c
+++ b/channels/chan_pjsip.c
@@ -57,6 +57,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/stasis_endpoints.h"
#include "asterisk/stasis_channels.h"
#include "asterisk/indications.h"
+#include "asterisk/format_cache.h"
#include "asterisk/threadstorage.h"
#include "asterisk/features_config.h"
#include "asterisk/pickup.h"
@@ -210,7 +211,7 @@ static void chan_pjsip_get_codec(struct ast_channel *chan, struct ast_format_cap
{
struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(chan);
- ast_format_cap_copy(result, channel->session->endpoint->media.codecs);
+ ast_format_cap_append_from_cap(result, channel->session->endpoint->media.codecs, AST_MEDIA_TYPE_UNKNOWN);
}
static int send_direct_media_request(void *data)
@@ -325,8 +326,9 @@ static int chan_pjsip_set_rtp_peer(struct ast_channel *chan,
return 0;
}
- if (cap && !ast_format_cap_is_empty(cap) && !ast_format_cap_identical(session->direct_media_cap, cap)) {
- ast_format_cap_copy(session->direct_media_cap, cap);
+ if (cap && ast_format_cap_count(cap) && !ast_format_cap_identical(session->direct_media_cap, cap)) {
+ ast_format_cap_remove_by_type(session->direct_media_cap, AST_MEDIA_TYPE_UNKNOWN);
+ ast_format_cap_append_from_cap(session->direct_media_cap, cap, AST_MEDIA_TYPE_UNKNOWN);
changed = 1;
}
@@ -355,7 +357,8 @@ static struct ast_rtp_glue chan_pjsip_rtp_glue = {
static struct ast_channel *chan_pjsip_new(struct ast_sip_session *session, int state, const char *exten, const char *title, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *cid_name)
{
struct ast_channel *chan;
- struct ast_format fmt;
+ struct ast_format_cap *caps;
+ struct ast_format *fmt;
RAII_VAR(struct chan_pjsip_pvt *, pvt, NULL, ao2_cleanup);
struct ast_sip_channel_pvt *channel;
struct ast_variable *var;
@@ -363,19 +366,21 @@ static struct ast_channel *chan_pjsip_new(struct ast_sip_session *session, int s
if (!(pvt = ao2_alloc(sizeof(*pvt), chan_pjsip_pvt_dtor))) {
return NULL;
}
+ caps = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
+ if (!caps) {
+ return NULL;
+ }
-
- chan = ast_channel_alloc(1, state, S_OR(session->id.number.str, ""), S_OR(session->id.name.str, ""),
- session->endpoint->accountcode, "", "", assignedids,
- requestor, 0, "PJSIP/%s-%08x", ast_sorcery_object_get_id(session->endpoint),
- (unsigned)ast_atomic_fetchadd_int((int *)&chan_idx, +1));
- if (!chan) {
+ if (!(chan = ast_channel_alloc(1, state, S_OR(session->id.number.str, ""), S_OR(session->id.name.str, ""), session->endpoint->accountcode, "", "", assignedids, requestor, 0, "PJSIP/%s-%08x", ast_sorcery_object_get_id(session->endpoint),
+ (unsigned)ast_atomic_fetchadd_int((int *)&chan_idx, +1)))) {
+ ao2_ref(caps, -1);
return NULL;
}
ast_channel_tech_set(chan, &chan_pjsip_tech);
if (!(channel = ast_sip_channel_pvt_alloc(pvt, session))) {
+ ao2_ref(caps, -1);
ast_channel_unlock(chan);
ast_hangup(chan);
return NULL;
@@ -391,17 +396,21 @@ static struct ast_channel *chan_pjsip_new(struct ast_sip_session *session, int s
ast_channel_tech_pvt_set(chan, channel);
- if (ast_format_cap_is_empty(session->req_caps) || !ast_format_cap_has_joint(session->req_caps, session->endpoint->media.codecs)) {
- ast_format_cap_copy(ast_channel_nativeformats(chan), session->endpoint->media.codecs);
+ if (!ast_format_cap_count(session->req_caps) ||
+ !ast_format_cap_iscompatible(session->req_caps, session->endpoint->media.codecs)) {
+ ast_format_cap_append_from_cap(caps, session->endpoint->media.codecs, AST_MEDIA_TYPE_UNKNOWN);
} else {
- ast_format_cap_copy(ast_channel_nativeformats(chan), session->req_caps);
+ ast_format_cap_append_from_cap(caps, session->req_caps, AST_MEDIA_TYPE_UNKNOWN);
}
- ast_codec_choose(&session->endpoint->media.prefs, ast_channel_nativeformats(chan), 1, &fmt);
- ast_format_copy(ast_channel_writeformat(chan), &fmt);
- ast_format_copy(ast_channel_rawwriteformat(chan), &fmt);
- ast_format_copy(ast_channel_readformat(chan), &fmt);
- ast_format_copy(ast_channel_rawreadformat(chan), &fmt);
+ ast_channel_nativeformats_set(chan, caps);
+ fmt = ast_format_cap_get_format(caps, 0);
+ ast_channel_set_writeformat(chan, fmt);
+ ast_channel_set_rawwriteformat(chan, fmt);
+ ast_channel_set_readformat(chan, fmt);
+ ast_channel_set_rawreadformat(chan, fmt);
+ ao2_ref(fmt, -1);
+ ao2_ref(caps, -1);
if (state == AST_STATE_RING) {
ast_channel_rings_set(chan, 1);
@@ -584,9 +593,18 @@ static struct ast_frame *chan_pjsip_read(struct ast_channel *ast)
return f;
}
- if (!(ast_format_cap_iscompatible(ast_channel_nativeformats(ast), &f->subclass.format))) {
- ast_debug(1, "Oooh, format changed to %s\n", ast_getformatname(&f->subclass.format));
- ast_format_cap_set(ast_channel_nativeformats(ast), &f->subclass.format);
+ if (ast_format_cap_iscompatible_format(ast_channel_nativeformats(ast), f->subclass.format) == AST_FORMAT_CMP_NOT_EQUAL) {
+ struct ast_format_cap *caps;
+
+ ast_debug(1, "Oooh, format changed to %s\n", ast_format_get_name(f->subclass.format));
+
+ caps = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
+ if (caps) {
+ ast_format_cap_append(caps, f->subclass.format, 0);
+ ast_channel_nativeformats_set(ast, caps);
+ ao2_ref(caps, -1);
+ }
+
ast_set_read_format(ast, ast_channel_readformat(ast));
ast_set_write_format(ast, ast_channel_writeformat(ast));
}
@@ -623,15 +641,15 @@ static int chan_pjsip_write(struct ast_channel *ast, struct ast_frame *frame)
if (!media) {
return 0;
}
- if (!(ast_format_cap_iscompatible(ast_channel_nativeformats(ast), &frame->subclass.format))) {
- char buf[256];
+ if (ast_format_cap_iscompatible_format(ast_channel_nativeformats(ast), frame->subclass.format) == AST_FORMAT_CMP_NOT_EQUAL) {
+ struct ast_str *cap_buf = ast_str_alloca(64);
ast_log(LOG_WARNING,
"Asked to transmit frame type %s, while native formats is %s (read/write = %s/%s)\n",
- ast_getformatname(&frame->subclass.format),
- ast_getformatname_multiple(buf, sizeof(buf), ast_channel_nativeformats(ast)),
- ast_getformatname(ast_channel_readformat(ast)),
- ast_getformatname(ast_channel_writeformat(ast)));
+ ast_format_get_name(frame->subclass.format),
+ ast_format_cap_get_names(ast_channel_nativeformats(ast), &cap_buf),
+ ast_format_get_name(ast_channel_readformat(ast)),
+ ast_format_get_name(ast_channel_writeformat(ast)));
return 0;
}
if (media->rtp) {
@@ -1127,10 +1145,8 @@ static int chan_pjsip_indicate(struct ast_channel *ast, int condition, const voi
if (media && media->rtp) {
/* FIXME: Only use this for VP8. Additional work would have to be done to
* fully support other video codecs */
- struct ast_format_cap *fcap = ast_channel_nativeformats(ast);
- struct ast_format vp8;
- ast_format_set(&vp8, AST_FORMAT_VP8, 0);
- if (ast_format_cap_iscompatible(fcap, &vp8)) {
+
+ if (ast_format_cap_iscompatible_format(ast_channel_nativeformats(ast), ast_format_vp8) != AST_FORMAT_CMP_NOT_EQUAL) {
/* FIXME Fake RTP write, this will be sent as an RTCP packet. Ideally the
* RTP engine would provide a way to externally write/schedule RTCP
* packets */
@@ -2162,11 +2178,11 @@ static int load_module(void)
{
struct ao2_container *endpoints;
- if (!(chan_pjsip_tech.capabilities = ast_format_cap_alloc(0))) {
+ if (!(chan_pjsip_tech.capabilities = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT))) {
return AST_MODULE_LOAD_DECLINE;
}
- ast_format_cap_add_all_by_type(chan_pjsip_tech.capabilities, AST_FORMAT_TYPE_AUDIO);
+ ast_format_cap_append_by_type(chan_pjsip_tech.capabilities, AST_MEDIA_TYPE_AUDIO);
ast_rtp_glue_register(&chan_pjsip_rtp_glue);
@@ -2259,6 +2275,7 @@ static int unload_module(void)
ast_custom_function_unregister(&chan_pjsip_dial_contacts_function);
ast_channel_unregister(&chan_pjsip_tech);
+ ao2_ref(chan_pjsip_tech.capabilities, -1);
ast_rtp_glue_unregister(&chan_pjsip_rtp_glue);
return 0;
diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index 095b5a763..44629dc3d 100644
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -285,6 +285,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/stasis_channels.h"
#include "asterisk/features_config.h"
#include "asterisk/http_websocket.h"
+#include "asterisk/format_cache.h"
/*** DOCUMENTATION
<application name="SIPDtmfMode" language="en_US">
@@ -747,7 +748,6 @@ static char default_mohsuggest[MAX_MUSICCLASS]; /*!< Global setting for moh c
static char default_parkinglot[AST_MAX_CONTEXT]; /*!< Parkinglot */
static char default_engine[256]; /*!< Default RTP engine */
static int default_maxcallbitrate; /*!< Maximum bitrate for call */
-static struct ast_codec_pref default_prefs; /*!< Default codec prefs */
static char default_zone[MAX_TONEZONE_COUNTRY]; /*!< Default tone zone for channels created from the SIP driver */
static unsigned int default_transports; /*!< Default Transports (enum ast_transport) that are acceptable */
static unsigned int default_primary_transport; /*!< Default primary Transport (enum ast_transport) for outbound connections to devices */
@@ -1295,7 +1295,6 @@ static int str2dtmfmode(const char *str) attribute_unused;
static const char *insecure2str(int mode) attribute_const;
static const char *allowoverlap2str(int mode) attribute_const;
static void cleanup_stale_contexts(char *new, char *old);
-static void print_codec_to_cli(int fd, struct ast_codec_pref *pref);
static const char *domain_mode_to_text(const enum domain_mode mode);
static char *sip_show_domains(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a);
static char *_sip_show_peer(int type, int fd, struct mansession *s, const struct message *m, int argc, const char *argv[]);
@@ -1764,7 +1763,7 @@ static void destroy_escs(void)
{
int i;
for (i = 0; i < ARRAY_LEN(event_state_compositors); i++) {
- ao2_ref(event_state_compositors[i].compositor, -1);
+ ao2_cleanup(event_state_compositors[i].compositor);
}
}
@@ -3385,7 +3384,7 @@ static void unlink_peers_from_tables(peer_unlink_flag_t flag)
ao2_t_callback(peers, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE,
match_and_cleanup_peer_sched, &flag, "initiating callback to remove marked peers");
ao2_t_callback(peers_by_ip, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE,
- match_and_cleanup_peer_sched, &flag, "initiating callback to remove marked peers");
+ match_and_cleanup_peer_sched, &flag, "initiating callback to remove marked peers_by_ip");
}
/* \brief Unlink all marked peers from ao2 containers */
@@ -5308,7 +5307,7 @@ static void sip_destroy_peer(struct sip_peer *peer)
ast_string_field_free_memory(peer);
- peer->caps = ast_format_cap_destroy(peer->caps);
+ ao2_cleanup(peer->caps);
ast_rtp_dtls_cfg_free(&peer->dtls_cfg);
@@ -5967,7 +5966,7 @@ static int dialog_initialize_rtp(struct sip_pvt *dialog)
}
if (ast_test_flag(&dialog->flags[1], SIP_PAGE2_VIDEOSUPPORT_ALWAYS) ||
- (ast_test_flag(&dialog->flags[1], SIP_PAGE2_VIDEOSUPPORT) && (ast_format_cap_has_type(dialog->caps, AST_FORMAT_TYPE_VIDEO)))) {
+ (ast_test_flag(&dialog->flags[1], SIP_PAGE2_VIDEOSUPPORT) && (ast_format_cap_has_type(dialog->caps, AST_MEDIA_TYPE_VIDEO)))) {
if (!(dialog->vrtp = ast_rtp_instance_new(dialog->engine, sched, &bindaddr_tmp, NULL))) {
return -1;
}
@@ -6053,8 +6052,11 @@ static int create_addr_from_peer(struct sip_pvt *dialog, struct sip_peer *peer)
ast_copy_flags(&dialog->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY);
ast_copy_flags(&dialog->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY);
ast_copy_flags(&dialog->flags[2], &peer->flags[2], SIP_PAGE3_FLAGS_TO_COPY);
- ast_format_cap_copy(dialog->caps, peer->caps);
- dialog->prefs = peer->prefs;
+ /* Take the peer's caps */
+ if (peer->caps) {
+ ast_format_cap_remove_by_type(dialog->caps, AST_MEDIA_TYPE_UNKNOWN);
+ ast_format_cap_append_from_cap(dialog->caps, peer->caps, AST_MEDIA_TYPE_UNKNOWN);
+ }
dialog->amaflags = peer->amaflags;
ast_string_field_set(dialog, engine, peer->engine);
@@ -6078,8 +6080,8 @@ static int create_addr_from_peer(struct sip_pvt *dialog, struct sip_peer *peer)
ast_rtp_instance_set_prop(dialog->rtp, AST_RTP_PROPERTY_DTMF, ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833);
ast_rtp_instance_set_prop(dialog->rtp, AST_RTP_PROPERTY_DTMF_COMPENSATE, ast_test_flag(&dialog->flags[1], SIP_PAGE2_RFC2833_COMPENSATE));
/* Set Frame packetization */
- ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(dialog->rtp), dialog->rtp, &dialog->prefs);
dialog->autoframing = peer->autoframing;
+ ast_rtp_codecs_set_framing(ast_rtp_instance_get_codecs(dialog->rtp), ast_format_cap_get_framing(dialog->caps));
}
/* XXX TODO: get fields directly from peer only as they are needed using dialog->relatedpeer */
@@ -6456,7 +6458,7 @@ static int sip_call(struct ast_channel *ast, const char *dest, int timeout)
p->jointnoncodeccapability = p->noncodeccapability;
/* If there are no audio formats left to offer, punt */
- if (!(ast_format_cap_has_type(p->jointcaps, AST_FORMAT_TYPE_AUDIO))) {
+ if (!(ast_format_cap_has_type(p->jointcaps, AST_MEDIA_TYPE_AUDIO))) {
ast_log(LOG_WARNING, "No audio format found to offer. Cancelling call to %s\n", p->username);
res = -1;
} else {
@@ -6721,11 +6723,11 @@ void __sip_destroy(struct sip_pvt *p, int lockowner, int lockdialoglist)
p->named_callgroups = ast_unref_namedgroups(p->named_callgroups);
p->named_pickupgroups = ast_unref_namedgroups(p->named_pickupgroups);
- p->caps = ast_format_cap_destroy(p->caps);
- p->jointcaps = ast_format_cap_destroy(p->jointcaps);
- p->peercaps = ast_format_cap_destroy(p->peercaps);
- p->redircaps = ast_format_cap_destroy(p->redircaps);
- p->prefcaps = ast_format_cap_destroy(p->prefcaps);
+ ao2_cleanup(p->caps);
+ ao2_cleanup(p->jointcaps);
+ ao2_cleanup(p->peercaps);
+ ao2_cleanup(p->redircaps);
+ ao2_cleanup(p->prefcaps);
ast_rtp_dtls_cfg_free(&p->dtls_cfg);
@@ -7308,7 +7310,6 @@ static int sip_hangup(struct ast_channel *ast)
/*! \brief Try setting the codecs suggested by the SIP_CODEC channel variable */
static void try_suggested_sip_codec(struct sip_pvt *p)
{
- struct ast_format fmt;
const char *codec_list;
char *codec_list_copy;
struct ast_format_cap *original_jointcaps;
@@ -7328,31 +7329,44 @@ static void try_suggested_sip_codec(struct sip_pvt *p)
}
codec_list_copy = ast_strdupa(codec_list);
- original_jointcaps = ast_format_cap_dup(p->jointcaps);
+
+ original_jointcaps = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
+ if (!original_jointcaps) {
+ return;
+ }
+ ast_format_cap_append_from_cap(original_jointcaps, p->jointcaps, AST_MEDIA_TYPE_UNKNOWN);
for (codec = strtok_r(codec_list_copy, ",", &strtok_ptr); codec; codec = strtok_r(NULL, ",", &strtok_ptr)) {
+ struct ast_format *fmt;
+
codec = ast_strip(codec);
- if (!ast_getformatbyname(codec, &fmt)) {
+ fmt = ast_format_cache_get(codec);
+ if (!fmt) {
ast_log(AST_LOG_NOTICE, "Ignoring ${SIP_CODEC*} variable because of unrecognized/not configured codec %s (check allow/disallow in sip.conf)\n", codec);
continue;
}
- if (ast_format_cap_iscompatible(original_jointcaps, &fmt)) {
+ if (ast_format_cap_iscompatible_format(original_jointcaps, fmt) != AST_FORMAT_CMP_NOT_EQUAL) {
if (first_codec) {
ast_verb(4, "Set codec to '%s' for this call because of ${SIP_CODEC*} variable\n", codec);
- ast_format_cap_set(p->jointcaps, &fmt);
- ast_format_cap_set(p->caps, &fmt);
+ ast_format_cap_remove_by_type(p->jointcaps, AST_MEDIA_TYPE_UNKNOWN);
+ ast_format_cap_append(p->jointcaps, fmt, 0);
+ ast_format_cap_remove_by_type(p->caps, AST_MEDIA_TYPE_UNKNOWN);
+ ast_format_cap_append(p->caps, fmt, 0);
first_codec = 0;
} else {
ast_verb(4, "Add codec to '%s' for this call because of ${SIP_CODEC*} variable\n", codec);
- ast_format_cap_add(p->jointcaps, &fmt);
- ast_format_cap_add(p->caps, &fmt);
+ /* Add the format to the capabilities structure */
+ ast_format_cap_append(p->jointcaps, fmt, 0);
+ ast_format_cap_append(p->caps, fmt, 0);
}
} else {
ast_log(AST_LOG_NOTICE, "Ignoring ${SIP_CODEC*} variable because it is not shared by both ends: %s\n", codec);
}
+
+ ao2_ref(fmt, -1);
}
- ast_format_cap_destroy(original_jointcaps);
+ ao2_ref(original_jointcaps, -1);
return;
}
@@ -7401,13 +7415,13 @@ static int sip_write(struct ast_channel *ast, struct ast_frame *frame)
switch (frame->frametype) {
case AST_FRAME_VOICE:
- if (!(ast_format_cap_iscompatible(ast_channel_nativeformats(ast), &frame->subclass.format))) {
- char s1[512];
+ if (ast_format_cap_iscompatible_format(ast_channel_nativeformats(ast), frame->subclass.format) == AST_FORMAT_CMP_NOT_EQUAL) {
+ struct ast_str *codec_buf = ast_str_alloca(64);
ast_log(LOG_WARNING, "Asked to transmit frame type %s, while native formats is %s read/write = %s/%s\n",
- ast_getformatname(&frame->subclass.format),
- ast_getformatname_multiple(s1, sizeof(s1), ast_channel_nativeformats(ast)),
- ast_getformatname(ast_channel_readformat(ast)),
- ast_getformatname(ast_channel_writeformat(ast)));
+ ast_format_get_name(frame->subclass.format),
+ ast_format_cap_get_names(ast_channel_nativeformats(ast), &codec_buf),
+ ast_format_get_name(ast_channel_readformat(ast)),
+ ast_format_get_name(ast_channel_writeformat(ast)));
return 0;
}
if (p) {
@@ -7929,10 +7943,7 @@ static int sip_indicate(struct ast_channel *ast, int condition, const void *data
if (p->vrtp && !p->novideo) {
/* FIXME: Only use this for VP8. Additional work would have to be done to
* fully support other video codecs */
- struct ast_format_cap *fcap = ast_channel_nativeformats(ast);
- struct ast_format vp8;
- ast_format_set(&vp8, AST_FORMAT_VP8, 0);
- if (ast_format_cap_iscompatible(fcap, &vp8)) {
+ if (ast_format_cap_iscompatible_format(ast_channel_nativeformats(ast), ast_format_vp8) != AST_FORMAT_CMP_NOT_EQUAL) {
/* FIXME Fake RTP write, this will be sent as an RTCP packet. Ideally the
* RTP engine would provide a way to externally write/schedule RTCP
* packets */
@@ -8036,15 +8047,21 @@ static int sip_indicate(struct ast_channel *ast, int condition, const void *data
*/
static struct ast_channel *sip_new(struct sip_pvt *i, int state, const char *title, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, struct ast_callid *callid)
{
+ struct ast_format_cap *caps;
struct ast_channel *tmp;
struct ast_variable *v = NULL;
- struct ast_format fmt;
+ struct ast_format *fmt;
struct ast_format_cap *what = NULL; /* SHALLOW COPY DO NOT DESTROY! */
+ struct ast_str *codec_buf = ast_str_alloca(64);
int needvideo = 0;
int needtext = 0;
- char buf[SIPBUFSIZE];
char *exten;
+ caps = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
+ if (!caps) {
+ return NULL;
+ }
+
{
const char *my_name; /* pick a good name */
@@ -8060,6 +8077,7 @@ static struct ast_channel *sip_new(struct sip_pvt *i, int state, const char *tit
}
if (!tmp) {
ast_log(LOG_WARNING, "Unable to allocate AST channel structure for SIP channel\n");
+ ao2_ref(caps, -1);
sip_pvt_lock(i);
return NULL;
}
@@ -8068,6 +8086,7 @@ static struct ast_channel *sip_new(struct sip_pvt *i, int state, const char *tit
if (ast_endpoint_add_channel(i->relatedpeer->endpoint, tmp)) {
ast_channel_unlock(tmp);
ast_channel_unref(tmp);
+ ao2_ref(caps, -1);
sip_pvt_lock(i);
return NULL;
}
@@ -8088,27 +8107,40 @@ static struct ast_channel *sip_new(struct sip_pvt *i, int state, const char *tit
/* Select our native format based on codec preference until we receive
something from another device to the contrary. */
- if (!(ast_format_cap_is_empty(i->jointcaps))) { /* The joint capabilities of us and peer */
+ if (ast_format_cap_count(i->jointcaps)) { /* The joint capabilities of us and peer */
what = i->jointcaps;
- } else if (!(ast_format_cap_is_empty(i->caps))) { /* Our configured capability for this peer */
+ } else if (ast_format_cap_count(i->caps)) { /* Our configured capability for this peer */
what = i->caps;
} else {
what = sip_cfg.caps;
}
/* Set the native formats */
- ast_format_cap_copy(ast_channel_nativeformats(tmp), what);
- /* choose and use only the best audio format for our native formats */
- ast_codec_choose(&i->prefs, ast_channel_nativeformats(tmp), 1, &fmt); /* get the best audio format */
- ast_format_cap_remove_bytype(ast_channel_nativeformats(tmp), AST_FORMAT_TYPE_AUDIO); /* remove only the other audio formats */
- ast_format_cap_add(ast_channel_nativeformats(tmp), &fmt); /* add our best choice back */
+ ast_format_cap_append_from_cap(caps, what, AST_MEDIA_TYPE_UNKNOWN);
+ /* Use only the preferred audio format, which is stored at the '0' index */
+ fmt = ast_format_cap_get_best_by_type(what, AST_MEDIA_TYPE_AUDIO); /* get the best audio format */
+ if (fmt) {
+ ast_format_cap_remove_by_type(caps, AST_MEDIA_TYPE_AUDIO); /* remove only the other audio formats */
+ ast_format_cap_append(caps, fmt, 0); /* add our best choice back */
+ } else {
+ /* If we don't have an audio format, try to get something */
+ fmt = ast_format_cap_get_format(caps, 0);
+ if (!fmt) {
+ ast_log(LOG_WARNING, "No compatible formats could be found for %s\n", ast_channel_name(tmp));
+ ao2_ref(caps, -1);
+ tmp = ast_channel_unref(tmp);
+ return NULL;
+ }
+ }
+ ast_channel_nativeformats_set(tmp, caps);
+ ao2_ref(caps, -1);
- ast_debug(3, "*** Our native formats are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, ast_channel_nativeformats(tmp)));
- ast_debug(3, "*** Joint capabilities are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->jointcaps));
- ast_debug(3, "*** Our capabilities are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->caps));
- ast_debug(3, "*** AST_CODEC_CHOOSE formats are %s \n", ast_getformatname(&fmt));
- if (!ast_format_cap_is_empty(i->prefcaps)) {
- ast_debug(3, "*** Our preferred formats from the incoming channel are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->prefcaps));
+ ast_debug(3, "*** Our native formats are %s \n", ast_format_cap_get_names(ast_channel_nativeformats(tmp), &codec_buf));
+ ast_debug(3, "*** Joint capabilities are %s \n", ast_format_cap_get_names(i->jointcaps, &codec_buf));
+ ast_debug(3, "*** Our capabilities are %s \n", ast_format_cap_get_names(i->caps, &codec_buf));
+ ast_debug(3, "*** AST_CODEC_CHOOSE formats are %s \n", ast_format_get_name(fmt));
+ if (ast_format_cap_count(i->prefcaps)) {
+ ast_debug(3, "*** Our preferred formats from the incoming channel are %s \n", ast_format_cap_get_names(i->prefcaps, &codec_buf));
}
/* If we have a prefcodec setting, we have an inbound channel that set a
@@ -8118,17 +8150,17 @@ static struct ast_channel *sip_new(struct sip_pvt *i, int state, const char *tit
if (i->vrtp) {
if (ast_test_flag(&i->flags[1], SIP_PAGE2_VIDEOSUPPORT))
needvideo = 1;
- else if (!ast_format_cap_is_empty(i->prefcaps))
- needvideo = ast_format_cap_has_type(i->prefcaps, AST_FORMAT_TYPE_VIDEO); /* Outbound call */
+ else if (ast_format_cap_count(i->prefcaps))
+ needvideo = ast_format_cap_has_type(i->prefcaps, AST_MEDIA_TYPE_VIDEO); /* Outbound call */
else
- needvideo = ast_format_cap_has_type(i->jointcaps, AST_FORMAT_TYPE_VIDEO); /* Inbound call */
+ needvideo = ast_format_cap_has_type(i->jointcaps, AST_MEDIA_TYPE_VIDEO); /* Inbound call */
}
if (i->trtp) {
- if (!ast_format_cap_is_empty(i->prefcaps))
- needtext = ast_format_cap_has_type(i->prefcaps, AST_FORMAT_TYPE_TEXT); /* Outbound call */
+ if (ast_format_cap_count(i->prefcaps))
+ needtext = ast_format_cap_has_type(i->prefcaps, AST_MEDIA_TYPE_TEXT); /* Outbound call */
else
- needtext = ast_format_cap_has_type(i->jointcaps, AST_FORMAT_TYPE_TEXT); /* Inbound call */
+ needtext = ast_format_cap_has_type(i->jointcaps, AST_MEDIA_TYPE_TEXT); /* Inbound call */
}
if (needvideo) {
@@ -8156,8 +8188,8 @@ static struct ast_channel *sip_new(struct sip_pvt *i, int state, const char *tit
if (i->rtp) {
ast_channel_set_fd(tmp, 0, ast_rtp_instance_fd(i->rtp, 0));
ast_channel_set_fd(tmp, 1, ast_rtp_instance_fd(i->rtp, 1));
- ast_rtp_instance_set_write_format(i->rtp, &fmt);
- ast_rtp_instance_set_read_format(i->rtp, &fmt);
+ ast_rtp_instance_set_write_format(i->rtp, fmt);
+ ast_rtp_instance_set_read_format(i->rtp, fmt);
}
if (needvideo && i->vrtp) {
ast_channel_set_fd(tmp, 2, ast_rtp_instance_fd(i->vrtp, 0));
@@ -8175,11 +8207,13 @@ static struct ast_channel *sip_new(struct sip_pvt *i, int state, const char *tit
}
ast_channel_adsicpe_set(tmp, AST_ADSI_UNAVAILABLE);
- ast_format_copy(ast_channel_writeformat(tmp), &fmt);
- ast_format_copy(ast_channel_rawwriteformat(tmp), &fmt);
+ ast_channel_set_writeformat(tmp, fmt);
+ ast_channel_set_rawwriteformat(tmp, fmt);
+
+ ast_channel_set_readformat(tmp, fmt);
+ ast_channel_set_rawreadformat(tmp, fmt);
- ast_format_copy(ast_channel_readformat(tmp), &fmt);
- ast_format_copy(ast_channel_rawreadformat(tmp), &fmt);
+ ao2_ref(fmt, -1);
ast_channel_tech_pvt_set(tmp, dialog_ref(i, "sip_new: set chan->tech_pvt to i"));
@@ -8534,17 +8568,26 @@ static struct ast_frame *sip_rtp_read(struct ast_channel *ast, struct sip_pvt *p
return f;
}
- if (f && !ast_format_cap_iscompatible(ast_channel_nativeformats(p->owner), &f->subclass.format)) {
- if (!ast_format_cap_iscompatible(p->jointcaps, &f->subclass.format)) {
+ if (f && ast_format_cap_iscompatible_format(ast_channel_nativeformats(p->owner), f->subclass.format) == AST_FORMAT_CMP_NOT_EQUAL) {
+ struct ast_format_cap *caps;
+
+ if (ast_format_cap_iscompatible_format(p->jointcaps, f->subclass.format) == AST_FORMAT_CMP_NOT_EQUAL) {
ast_debug(1, "Bogus frame of format '%s' received from '%s'!\n",
- ast_getformatname(&f->subclass.format), ast_channel_name(p->owner));
+ ast_format_get_name(f->subclass.format), ast_channel_name(p->owner));
ast_frfree(f);
return &ast_null_frame;
}
ast_debug(1, "Oooh, format changed to %s\n",
- ast_getformatname(&f->subclass.format));
- ast_format_cap_remove_bytype(ast_channel_nativeformats(p->owner), AST_FORMAT_TYPE_AUDIO);
- ast_format_cap_add(ast_channel_nativeformats(p->owner), &f->subclass.format);
+ ast_format_get_name(f->subclass.format));
+
+ caps = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
+ if (caps) {
+ ast_format_cap_append_from_cap(caps, ast_channel_nativeformats(p->owner), AST_MEDIA_TYPE_UNKNOWN);
+ ast_format_cap_remove_by_type(caps, AST_MEDIA_TYPE_AUDIO);
+ ast_format_cap_append(caps, f->subclass.format, 0);
+ ast_channel_nativeformats_set(p->owner, caps);
+ ao2_ref(caps, -1);
+ }
ast_set_read_format(p->owner, ast_channel_readformat(p->owner));
ast_set_write_format(p->owner, ast_channel_writeformat(p->owner));
}
@@ -8796,18 +8839,18 @@ struct sip_pvt *sip_alloc(ast_string_field callid, struct ast_sockaddr *addr,
sip_pvt_callid_set(p, logger_callid);
}
- p->caps = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_NOLOCK);
- p->jointcaps = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_NOLOCK);
- p->peercaps = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_NOLOCK);
- p->redircaps = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_NOLOCK);
- p->prefcaps = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_NOLOCK);
+ p->caps = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
+ p->jointcaps = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
+ p->peercaps = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
+ p->redircaps = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
+ p->prefcaps = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
- if (!p->caps|| !p->jointcaps || !p->peercaps || !p->redircaps) {
- p->caps = ast_format_cap_destroy(p->caps);
- p->jointcaps = ast_format_cap_destroy(p->jointcaps);
- p->peercaps = ast_format_cap_destroy(p->peercaps);
- p->redircaps = ast_format_cap_destroy(p->redircaps);
- p->prefcaps = ast_format_cap_destroy(p->prefcaps);
+ if (!p->caps|| !p->jointcaps || !p->peercaps || !p->redircaps || !p->prefcaps) {
+ ao2_cleanup(p->caps);
+ ao2_cleanup(p->jointcaps);
+ ao2_cleanup(p->peercaps);
+ ao2_cleanup(p->redircaps);
+ ao2_cleanup(p->prefcaps);
ao2_t_ref(p, -1, "Yuck, couldn't allocate format capabilities. Get rid o' p");
return NULL;
}
@@ -8857,7 +8900,6 @@ struct sip_pvt *sip_alloc(ast_string_field callid, struct ast_sockaddr *addr,
p->sessionversion_remote = -1;
p->session_modify = TRUE;
p->stimer = NULL;
- p->prefs = default_prefs; /* Set default codecs for this call */
ast_copy_string(p->zone, default_zone, sizeof(p->zone));
p->maxforwards = sip_cfg.default_max_forwards;
@@ -8909,7 +8951,7 @@ struct sip_pvt *sip_alloc(ast_string_field callid, struct ast_sockaddr *addr,
/* Assign default music on hold class */
ast_string_field_set(p, mohinterpret, default_mohinterpret);
ast_string_field_set(p, mohsuggest, default_mohsuggest);
- ast_format_cap_copy(p->caps, sip_cfg.caps);
+ ast_format_cap_append_from_cap(p->caps, sip_cfg.caps, AST_MEDIA_TYPE_UNKNOWN);
p->allowtransfer = sip_cfg.allowtransfer;
if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) ||
(ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) {
@@ -10034,15 +10076,17 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req, int t38action
int udptlportno = -1; /*!< UDPTL image destination port number */
/* Peer capability is the capability in the SDP, non codec is RFC2833 DTMF (101) */
- struct ast_format_cap *peercapability = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_NOLOCK);
- struct ast_format_cap *vpeercapability = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_NOLOCK);
- struct ast_format_cap *tpeercapability = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_NOLOCK);
+ struct ast_format_cap *peercapability = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
+ struct ast_format_cap *vpeercapability = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
+ struct ast_format_cap *tpeercapability = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
int peernoncodeccapability = 0, vpeernoncodeccapability = 0, tpeernoncodeccapability = 0;
- struct ast_rtp_codecs newaudiortp = { 0, }, newvideortp = { 0, }, newtextrtp = { 0, };
- struct ast_format_cap *newjointcapability = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_NOLOCK); /* Negotiated capability */
- struct ast_format_cap *newpeercapability = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_NOLOCK);
+ struct ast_rtp_codecs newaudiortp = AST_RTP_CODECS_NULL_INIT;
+ struct ast_rtp_codecs newvideortp = AST_RTP_CODECS_NULL_INIT;
+ struct ast_rtp_codecs newtextrtp = AST_RTP_CODECS_NULL_INIT;
+ struct ast_format_cap *newjointcapability = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT); /* Negotiated capability */
+ struct ast_format_cap *newpeercapability = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
int newnoncodeccapability;
const char *codecs;
@@ -10062,8 +10106,8 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req, int t38action
int debug = sip_debug_test_pvt(p);
/* START UNKNOWN */
- char buf[SIPBUFSIZE];
- struct ast_format tmp_fmt;
+ struct ast_str *codec_buf = ast_str_alloca(64);
+ struct ast_format *tmp_fmt;
/* END UNKNOWN */
/* Initial check */
@@ -10625,10 +10669,12 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req, int t38action
/* Ensure crypto lines are provided where necessary */
if (audio && secure_audio && !processed_crypto) {
ast_log(LOG_WARNING, "Rejecting secure audio stream without encryption details: %s\n", m);
- return -1;
+ res = -1;
+ goto process_sdp_cleanup;
} else if (video && secure_video && !processed_crypto) {
ast_log(LOG_WARNING, "Rejecting secure video stream without encryption details: %s\n", m);
- return -1;
+ res = -1;
+ goto process_sdp_cleanup;
}
}
@@ -10687,12 +10733,12 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req, int t38action
ast_rtp_codecs_payload_formats(&newvideortp, vpeercapability, &vpeernoncodeccapability);
ast_rtp_codecs_payload_formats(&newtextrtp, tpeercapability, &tpeernoncodeccapability);
- ast_format_cap_append(newpeercapability, peercapability);
- ast_format_cap_append(newpeercapability, vpeercapability);
- ast_format_cap_append(newpeercapability, tpeercapability);
+ ast_format_cap_append_from_cap(newpeercapability, peercapability, AST_MEDIA_TYPE_AUDIO);
+ ast_format_cap_append_from_cap(newpeercapability, vpeercapability, AST_MEDIA_TYPE_VIDEO);
+ ast_format_cap_append_from_cap(newpeercapability, tpeercapability, AST_MEDIA_TYPE_TEXT);
- ast_format_cap_joint_copy(p->caps, newpeercapability, newjointcapability);
- if (ast_format_cap_is_empty(newjointcapability) && udptlportno == -1) {
+ ast_format_cap_get_compatible(p->caps, newpeercapability, newjointcapability);
+ if (!ast_format_cap_count(newjointcapability) && udptlportno == -1) {
ast_log(LOG_NOTICE, "No compatible codecs, not accepting this offer!\n");
/* Do NOT Change current setting */
res = -1;
@@ -10703,14 +10749,18 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req, int t38action
if (debug) {
/* shame on whoever coded this.... */
- char s1[SIPBUFSIZE], s2[SIPBUFSIZE], s3[SIPBUFSIZE], s4[SIPBUFSIZE], s5[SIPBUFSIZE];
+ struct ast_str *cap_buf = ast_str_alloca(64);
+ struct ast_str *peer_buf = ast_str_alloca(64);
+ struct ast_str *vpeer_buf = ast_str_alloca(64);
+ struct ast_str *tpeer_buf = ast_str_alloca(64);
+ struct ast_str *joint_buf = ast_str_alloca(64);
ast_verbose("Capabilities: us - %s, peer - audio=%s/video=%s/text=%s, combined - %s\n",
- ast_getformatname_multiple(s1, SIPBUFSIZE, p->caps),
- ast_getformatname_multiple(s2, SIPBUFSIZE, peercapability),
- ast_getformatname_multiple(s3, SIPBUFSIZE, vpeercapability),
- ast_getformatname_multiple(s4, SIPBUFSIZE, tpeercapability),
- ast_getformatname_multiple(s5, SIPBUFSIZE, newjointcapability));
+ ast_format_cap_get_names(p->caps, &cap_buf),
+ ast_format_cap_get_names(peercapability, &peer_buf),
+ ast_format_cap_get_names(vpeercapability, &vpeer_buf),
+ ast_format_cap_get_names(tpeercapability, &tpeer_buf),
+ ast_format_cap_get_names(newjointcapability, &joint_buf));
}
if (debug) {
struct ast_str *s1 = ast_str_alloca(SIPBUFSIZE);
@@ -10726,14 +10776,21 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req, int t38action
if (portno != -1 || vportno != -1 || tportno != -1) {
/* We are now ready to change the sip session and RTP structures with the offered codecs, since
they are acceptable */
- ast_format_cap_copy(p->jointcaps, newjointcapability); /* Our joint codec profile for this call */
- ast_format_cap_copy(p->peercaps, newpeercapability); /* The other side's capability in latest offer */
+ ast_format_cap_remove_by_type(p->jointcaps, AST_MEDIA_TYPE_UNKNOWN);
+ ast_format_cap_append_from_cap(p->jointcaps, newjointcapability, AST_MEDIA_TYPE_UNKNOWN); /* Our joint codec profile for this call */
+ ast_format_cap_remove_by_type(p->peercaps, AST_MEDIA_TYPE_UNKNOWN);
+ ast_format_cap_append_from_cap(p->peercaps, newpeercapability, AST_MEDIA_TYPE_UNKNOWN); /* The other side's capability in latest offer */
p->jointnoncodeccapability = newnoncodeccapability; /* DTMF capabilities */
/* respond with single most preferred joint codec, limiting the other side's choice */
if (ast_test_flag(&p->flags[1], SIP_PAGE2_PREFERRED_CODEC)) {
- ast_codec_choose(&p->prefs, p->jointcaps, 1, &tmp_fmt);
- ast_format_cap_set(p->jointcaps, &tmp_fmt);
+ unsigned int framing;
+
+ tmp_fmt = ast_format_cap_get_format(p->jointcaps, 0);
+ framing = ast_format_cap_get_format_framing(p->jointcaps, tmp_fmt);
+ ast_format_cap_remove_by_type(p->jointcaps, AST_MEDIA_TYPE_UNKNOWN);
+ ast_format_cap_append(p->jointcaps, tmp_fmt, framing);
+ ao2_ref(tmp_fmt, -1);
}
}
@@ -10813,7 +10870,7 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req, int t38action
ast_verbose("Peer T.140 RTP is at port %s\n",
ast_sockaddr_stringify(tsa));
}
- if (ast_format_cap_iscompatible(p->jointcaps, ast_format_set(&tmp_fmt, AST_FORMAT_T140RED, 0))) {
+ if (ast_format_cap_iscompatible_format(p->jointcaps, ast_format_t140_red) != AST_FORMAT_CMP_NOT_EQUAL) {
p->red = 1;
ast_rtp_red_init(p->trtp, 300, red_data_pt, 2);
} else {
@@ -10890,7 +10947,7 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req, int t38action
}
/* Ok, we're going with this offer */
- ast_debug(2, "We're settling with these formats: %s\n", ast_getformatname_multiple(buf, SIPBUFSIZE, p->jointcaps));
+ ast_debug(2, "We're settling with these formats: %s\n", ast_format_cap_get_names(p->jointcaps, &codec_buf));
if (!p->owner) { /* There's no open channel owning us so we can return here. For a re-invite or so, we proceed */
res = 0;
@@ -10898,19 +10955,30 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req, int t38action
}
ast_debug(4, "We have an owner, now see if we need to change this call\n");
- if (ast_format_cap_has_type(p->jointcaps, AST_FORMAT_TYPE_AUDIO)) {
+ if (ast_format_cap_has_type(p->jointcaps, AST_MEDIA_TYPE_AUDIO)) {
+ struct ast_format_cap *caps;
+ unsigned int framing;
+
if (debug) {
- char s1[SIPBUFSIZE], s2[SIPBUFSIZE];
+ struct ast_str *cap_buf = ast_str_alloca(64);
+ struct ast_str *joint_buf = ast_str_alloca(64);
+
ast_debug(1, "Setting native formats after processing SDP. peer joint formats %s, old nativeformats %s\n",
- ast_getformatname_multiple(s1, SIPBUFSIZE, p->jointcaps),
- ast_getformatname_multiple(s2, SIPBUFSIZE, ast_channel_nativeformats(p->owner)));
+ ast_format_cap_get_names(p->jointcaps, &joint_buf),
+ ast_format_cap_get_names(ast_channel_nativeformats(p->owner), &cap_buf));
}
- ast_codec_choose(&p->prefs, p->jointcaps, 1, &tmp_fmt);
-
- ast_format_cap_set(ast_channel_nativeformats(p->owner), &tmp_fmt);
- ast_format_cap_joint_append(p->caps, vpeercapability, ast_channel_nativeformats(p->owner));
- ast_format_cap_joint_append(p->caps, tpeercapability, ast_channel_nativeformats(p->owner));
+ caps = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
+ if (caps) {
+ tmp_fmt = ast_format_cap_get_format(p->jointcaps, 0);
+ framing = ast_format_cap_get_format_framing(p->jointcaps, tmp_fmt);
+ ast_format_cap_append(caps, tmp_fmt, framing);
+ ast_format_cap_append_from_cap(caps, vpeercapability, AST_MEDIA_TYPE_VIDEO);
+ ast_format_cap_append_from_cap(caps, tpeercapability, AST_MEDIA_TYPE_TEXT);
+ ast_channel_nativeformats_set(p->owner, caps);
+ ao2_ref(caps, -1);
+ ao2_ref(tmp_fmt, -1);
+ }
ast_set_read_format(p->owner, ast_channel_readformat(p->owner));
ast_set_write_format(p->owner, ast_channel_writeformat(p->owner));
@@ -10942,11 +11010,11 @@ process_sdp_cleanup:
ast_rtp_codecs_payloads_destroy(&newtextrtp);
ast_rtp_codecs_payloads_destroy(&newvideortp);
ast_rtp_codecs_payloads_destroy(&newaudiortp);
- ast_format_cap_destroy(peercapability);
- ast_format_cap_destroy(vpeercapability);
- ast_format_cap_destroy(tpeercapability);
- ast_format_cap_destroy(newjointcapability);
- ast_format_cap_destroy(newpeercapability);
+ ao2_cleanup(peercapability);
+ ao2_cleanup(vpeercapability);
+ ao2_cleanup(tpeercapability);
+ ao2_cleanup(newjointcapability);
+ ao2_cleanup(newpeercapability);
return res;
}
@@ -11203,17 +11271,10 @@ static int process_sdp_a_audio(const char *a, struct sip_pvt *p, struct ast_rtp_
ast_debug(1, "Can't read framing from SDP: %s\n", a);
}
}
+
if (framing && p->autoframing) {
- struct ast_codec_pref *pref = &ast_rtp_instance_get_codecs(p->rtp)->pref;
- int codec_n;
- for (codec_n = 0; codec_n < AST_RTP_MAX_PT; codec_n++) {
- struct ast_rtp_payload_type format = ast_rtp_codecs_payload_lookup(ast_rtp_instance_get_codecs(p->rtp), codec_n);
- if (!format.asterisk_format) /* non-codec or not found */
- continue;
- ast_debug(1, "Setting framing for %s to %ld\n", ast_getformatname(&format.format), framing);
- ast_codec_pref_setsize(pref, &format.format, framing);
- }
- ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(p->rtp), p->rtp, pref);
+ ast_debug(1, "Setting framing to %ld\n", framing);
+ ast_rtp_codecs_set_framing(ast_rtp_instance_get_codecs(p->rtp), framing);
}
found = TRUE;
} else if (sscanf(a, "rtpmap: %30u %127[^/]/%30u", &codec, mimeSubtype, &sample_rate) == 3) {
@@ -11240,15 +11301,19 @@ static int process_sdp_a_audio(const char *a, struct sip_pvt *p, struct ast_rtp_
if ((format = ast_rtp_codecs_get_payload_format(newaudiortp, codec))) {
unsigned int bit_rate;
+ struct ast_format *format_parsed;
- if (!ast_format_sdp_parse(format, fmtp_string)) {
+ format_parsed = ast_format_parse_sdp_fmtp(format, fmtp_string);
+ if (format_parsed) {
+ ast_rtp_codecs_payload_replace_format(newaudiortp, codec, format_parsed);
+ ao2_replace(format, format_parsed);
+ ao2_ref(format_parsed, -1);
found = TRUE;
} else {
ast_rtp_codecs_payloads_unset(newaudiortp, NULL, codec);
}
- switch ((int) format->id) {
- case AST_FORMAT_SIREN7:
+ if (ast_format_cmp(format, ast_format_siren7) == AST_FORMAT_CMP_EQUAL) {
if (sscanf(fmtp_string, "bitrate=%30u", &bit_rate) == 1) {
if (bit_rate != 32000) {
ast_log(LOG_WARNING, "Got Siren7 offer at %u bps, but only 32000 bps supported; ignoring.\n", bit_rate);
@@ -11257,8 +11322,7 @@ static int process_sdp_a_audio(const char *a, struct sip_pvt *p, struct ast_rtp_
found = TRUE;
}
}
- break;
- case AST_FORMAT_SIREN14:
+ } else if (ast_format_cmp(format, ast_format_siren14) == AST_FORMAT_CMP_EQUAL) {
if (sscanf(fmtp_string, "bitrate=%30u", &bit_rate) == 1) {
if (bit_rate != 48000) {
ast_log(LOG_WARNING, "Got Siren14 offer at %u bps, but only 48000 bps supported; ignoring.\n", bit_rate);
@@ -11267,8 +11331,7 @@ static int process_sdp_a_audio(const char *a, struct sip_pvt *p, struct ast_rtp_
found = TRUE;
}
}
- break;
- case AST_FORMAT_G719:
+ } else if (ast_format_cmp(format, ast_format_g719) == AST_FORMAT_CMP_EQUAL) {
if (sscanf(fmtp_string, "bitrate=%30u", &bit_rate) == 1) {
if (bit_rate != 64000) {
ast_log(LOG_WARNING, "Got G.719 offer at %u bps, but only 64000 bps supported; ignoring.\n", bit_rate);
@@ -11277,8 +11340,8 @@ static int process_sdp_a_audio(const char *a, struct sip_pvt *p, struct ast_rtp_
found = TRUE;
}
}
- break;
}
+ ao2_ref(format, -1);
}
}
@@ -11320,11 +11383,19 @@ static int process_sdp_a_video(const char *a, struct sip_pvt *p, struct ast_rtp_
struct ast_format *format;
if ((format = ast_rtp_codecs_get_payload_format(newvideortp, codec))) {
- if (!ast_format_sdp_parse(format, fmtp_string)) {
+ struct ast_format *format_parsed;
+
+ format_parsed = ast_format_parse_sdp_fmtp(format, fmtp_string);
+
+ if (format_parsed) {
+ ast_rtp_codecs_payload_replace_format(newvideortp, codec, format_parsed);
+ ao2_replace(format, format_parsed);
+ ao2_ref(format_parsed, -1);
found = TRUE;
} else {
ast_rtp_codecs_payloads_unset(newvideortp, NULL, codec);
}
+ ao2_ref(format, -1);
}
}
@@ -12890,12 +12961,11 @@ static void add_codec_to_sdp(const struct sip_pvt *p,
int *max_packet_size)
{
int rtp_code;
- struct ast_format_list fmt;
const char *mime;
- unsigned int rate;
+ unsigned int rate, framing;
if (debug)
- ast_verbose("Adding codec %u (%s) to SDP\n", format->id, ast_getformatname(format));
+ ast_verbose("Adding codec %s to SDP\n", ast_format_get_name(format));
if (((rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(p->rtp), 1, format, 0)) == -1) ||
!(mime = ast_rtp_lookup_mime_subtype2(1, format, 0, ast_test_flag(&p->flags[0], SIP_G726_NONSTANDARD) ? AST_RTP_OPT_G726_NONSTANDARD : 0)) ||
@@ -12903,63 +12973,54 @@ static void add_codec_to_sdp(const struct sip_pvt *p,
return;
}
- if (p->rtp) {
- struct ast_codec_pref *pref = &ast_rtp_instance_get_codecs(p->rtp)->pref;
- fmt = ast_codec_pref_getsize(pref, format);
- } else /* I don't see how you couldn't have p->rtp, but good to check for and error out if not there like earlier code */
- return;
ast_str_append(m_buf, 0, " %d", rtp_code);
/* Opus mandates 2 channels in rtpmap */
- if ((int)format->id == AST_FORMAT_OPUS) {
+ if (ast_format_cmp(format, ast_format_opus) == AST_FORMAT_CMP_EQUAL) {
ast_str_append(a_buf, 0, "a=rtpmap:%d %s/%u/2\r\n", rtp_code, mime, rate);
} else {
ast_str_append(a_buf, 0, "a=rtpmap:%d %s/%u\r\n", rtp_code, mime, rate);
}
- ast_format_sdp_generate(format, rtp_code, a_buf);
+ ast_format_generate_sdp_fmtp(format, rtp_code, a_buf);
+
+ framing = ast_format_cap_get_format_framing(p->caps, format);
- switch ((int) format->id) {
- case AST_FORMAT_G729A:
+ if (ast_format_cmp(format, ast_format_g729) == AST_FORMAT_CMP_EQUAL) {
/* Indicate that we don't support VAD (G.729 annex B) */
ast_str_append(a_buf, 0, "a=fmtp:%d annexb=no\r\n", rtp_code);
- break;
- case AST_FORMAT_G723_1:
+ } else if (ast_format_cmp(format, ast_format_g723) == AST_FORMAT_CMP_EQUAL) {
/* Indicate that we don't support VAD (G.723.1 annex A) */
ast_str_append(a_buf, 0, "a=fmtp:%d annexa=no\r\n", rtp_code);
- break;
- case AST_FORMAT_ILBC:
+ } else if (ast_format_cmp(format, ast_format_ilbc) == AST_FORMAT_CMP_EQUAL) {
/* Add information about us using only 20/30 ms packetization */
- ast_str_append(a_buf, 0, "a=fmtp:%d mode=%d\r\n", rtp_code, fmt.cur_ms);
- break;
- case AST_FORMAT_SIREN7:
+ ast_str_append(a_buf, 0, "a=fmtp:%d mode=%u\r\n", rtp_code, framing);
+ } else if (ast_format_cmp(format, ast_format_siren7) == AST_FORMAT_CMP_EQUAL) {
/* Indicate that we only expect 32Kbps */
ast_str_append(a_buf, 0, "a=fmtp:%d bitrate=32000\r\n", rtp_code);
- break;
- case AST_FORMAT_SIREN14:
+ } else if (ast_format_cmp(format, ast_format_siren14) == AST_FORMAT_CMP_EQUAL) {
/* Indicate that we only expect 48Kbps */
ast_str_append(a_buf, 0, "a=fmtp:%d bitrate=48000\r\n", rtp_code);
- break;
- case AST_FORMAT_G719:
+ } else if (ast_format_cmp(format, ast_format_g719) == AST_FORMAT_CMP_EQUAL) {
/* Indicate that we only expect 64Kbps */
ast_str_append(a_buf, 0, "a=fmtp:%d bitrate=64000\r\n", rtp_code);
- break;
}
- if (max_packet_size && fmt.max_ms && (fmt.max_ms < *max_packet_size)) {
- *max_packet_size = fmt.max_ms;
+ if (max_packet_size && ast_format_get_maximum_ms(format) &&
+ (ast_format_get_maximum_ms(format) < *max_packet_size)) {
+ *max_packet_size = ast_format_get_maximum_ms(format);
}
- if (fmt.cur_ms && (fmt.cur_ms < *min_packet_size)) {
- *min_packet_size = fmt.cur_ms;
+ if (framing && (framing < *min_packet_size)) {
+ *min_packet_size = framing;
}
/* Our first codec packetization processed cannot be zero */
- if ((*min_packet_size) == 0 && fmt.cur_ms) {
- *min_packet_size = fmt.cur_ms;
+ if ((*min_packet_size) == 0 && framing) {
+ *min_packet_size = framing;
}
- if ((*max_packet_size) == 0 && fmt.max_ms) {
- *max_packet_size = fmt.max_ms;
+ if ((*max_packet_size) == 0 && ast_format_get_maximum_ms(format)) {
+ *max_packet_size = ast_format_get_maximum_ms(format);
}
}
@@ -12977,7 +13038,7 @@ static void add_vcodec_to_sdp(const struct sip_pvt *p, struct ast_format *format
return;
if (debug)
- ast_verbose("Adding video codec %u (%s) to SDP\n", format->id, ast_getformatname(format));
+ ast_verbose("Adding video codec %s to SDP\n", ast_format_get_name(format));
if (((rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(p->vrtp), 1, format, 0)) == -1) ||
!(subtype = ast_rtp_lookup_mime_subtype2(1, format, 0, 0)) ||
@@ -12988,11 +13049,11 @@ static void add_vcodec_to_sdp(const struct sip_pvt *p, struct ast_format *format
ast_str_append(m_buf, 0, " %d", rtp_code);
ast_str_append(a_buf, 0, "a=rtpmap:%d %s/%u\r\n", rtp_code, subtype, rate);
/* VP8: add RTCP FIR support */
- if ((int)format->id == AST_FORMAT_VP8) {
+ if (ast_format_cmp(format, ast_format_vp8) == AST_FORMAT_CMP_EQUAL) {
ast_str_append(a_buf, 0, "a=rtcp-fb:* ccm fir\r\n");
}
- ast_format_sdp_generate(format, rtp_code, a_buf);
+ ast_format_generate_sdp_fmtp(format, rtp_code, a_buf);
}
/*! \brief Add text codec offer to SDP offer/answer body in INVITE or 200 OK */
@@ -13006,7 +13067,7 @@ static void add_tcodec_to_sdp(const struct sip_pvt *p, struct ast_format *format
return;
if (debug)
- ast_verbose("Adding text codec %u (%s) to SDP\n", format->id, ast_getformatname(format));
+ ast_verbose("Adding text codec %s to SDP\n", ast_format_get_name(format));
if ((rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(p->trtp), 1, format, 0)) == -1)
return;
@@ -13017,9 +13078,8 @@ static void add_tcodec_to_sdp(const struct sip_pvt *p, struct ast_format *format
ast_rtp_lookup_sample_rate2(1, format, 0));
/* Add fmtp code here */
- if (format->id == AST_FORMAT_T140RED) {
- struct ast_format tmp_fmt;
- int t140code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(p->trtp), 1, ast_format_set(&tmp_fmt, AST_FORMAT_T140, 0), 0);
+ if (ast_format_cmp(format, ast_format_t140_red) == AST_FORMAT_CMP_EQUAL) {
+ int t140code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(p->trtp), 1, ast_format_t140, 0);
ast_str_append(a_buf, 0, "a=fmtp:%d %d/%d/%d\r\n", rtp_code,
t140code,
t140code,
@@ -13194,8 +13254,8 @@ static char *crypto_get_attrib(struct ast_sdp_srtp *srtp, int dtls_enabled, int
*/
static enum sip_result add_sdp(struct sip_request *resp, struct sip_pvt *p, int oldsdp, int add_audio, int add_t38)
{
- struct ast_format_cap *alreadysent = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_NOLOCK);
- struct ast_format_cap *tmpcap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_NOLOCK);
+ struct ast_format_cap *alreadysent = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
+ struct ast_format_cap *tmpcap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
int res = AST_SUCCESS;
int doing_directmedia = FALSE;
struct ast_sockaddr addr = { {0,} };
@@ -13229,7 +13289,7 @@ static enum sip_result add_sdp(struct sip_request *resp, struct sip_pvt *p, int
RAII_VAR(char *, t_a_crypto, NULL, ast_free);
int x;
- struct ast_format tmp_fmt;
+ struct ast_format *tmp_fmt;
int needaudio = FALSE;
int needvideo = FALSE;
int needtext = FALSE;
@@ -13239,8 +13299,7 @@ static enum sip_result add_sdp(struct sip_request *resp, struct sip_pvt *p, int
int min_video_packet_size = 0;
int min_text_packet_size = 0;
- char codecbuf[SIPBUFSIZE];
- char buf[SIPBUFSIZE];
+ struct ast_str *codec_buf = ast_str_alloca(64);
/* Set the SDP session name */
snprintf(subject, sizeof(subject), "s=%s\r\n", ast_strlen_zero(global_sdpsession) ? "-" : global_sdpsession);
@@ -13268,11 +13327,24 @@ static enum sip_result add_sdp(struct sip_request *resp, struct sip_pvt *p, int
}
if (add_audio) {
- doing_directmedia = (!ast_sockaddr_isnull(&p->redirip) && !(ast_format_cap_is_empty(p->redircaps))) ? TRUE : FALSE;
+ doing_directmedia = (!ast_sockaddr_isnull(&p->redirip) && (ast_format_cap_count(p->redircaps))) ? TRUE : FALSE;
+
+ if (doing_directmedia) {
+ ast_format_cap_get_compatible(p->jointcaps, p->redircaps, tmpcap);
+ ast_debug(1, "** Our native-bridge filtered capablity: %s\n", ast_format_cap_get_names(tmpcap, &codec_buf));
+ } else {
+ ast_format_cap_append_from_cap(tmpcap, p->jointcaps, AST_MEDIA_TYPE_UNKNOWN);
+ }
+
+ /* Check if we need audio */
+ if (ast_format_cap_has_type(tmpcap, AST_MEDIA_TYPE_AUDIO)
+ || ast_format_cap_has_type(p->caps, AST_MEDIA_TYPE_AUDIO)) {
+ needaudio = TRUE;
+ }
+
/* Check if we need video in this call */
- if ((ast_format_cap_has_type(p->jointcaps, AST_FORMAT_TYPE_VIDEO)) && !p->novideo) {
- ast_format_cap_joint_copy(p->jointcaps, p->redircaps, tmpcap);
- if (doing_directmedia && !ast_format_cap_has_type(tmpcap, AST_FORMAT_TYPE_VIDEO)) {
+ if ((ast_format_cap_has_type(tmpcap, AST_MEDIA_TYPE_VIDEO)) && !p->novideo) {
+ if (doing_directmedia && !ast_format_cap_has_type(tmpcap, AST_MEDIA_TYPE_VIDEO)) {
ast_debug(2, "This call needs video offers, but caller probably did not offer it!\n");
} else if (p->vrtp) {
needvideo = TRUE;
@@ -13281,8 +13353,9 @@ static enum sip_result add_sdp(struct sip_request *resp, struct sip_pvt *p, int
ast_debug(2, "This call needs video offers, but there's no video support enabled!\n");
}
}
+
/* Check if we need text in this call */
- if ((ast_format_cap_has_type(p->jointcaps, AST_FORMAT_TYPE_TEXT)) && !p->notext) {
+ if ((ast_format_cap_has_type(p->jointcaps, AST_MEDIA_TYPE_TEXT)) && !p->notext) {
if (sipdebug_text)
ast_verbose("We think we can do text\n");
if (p->trtp) {
@@ -13295,6 +13368,12 @@ static enum sip_result add_sdp(struct sip_request *resp, struct sip_pvt *p, int
ast_debug(2, "This call needs text offers, but there's no text support enabled ! \n");
}
}
+
+ /* XXX note, Video and Text are negated - 'true' means 'no' */
+ ast_debug(1, "** Our capability: %s Video flag: %s Text flag: %s\n",
+ ast_format_cap_get_names(tmpcap, &codec_buf),
+ p->novideo ? "True" : "False", p->notext ? "True" : "False");
+ ast_debug(1, "** Our prefcodec: %s \n", ast_format_cap_get_names(p->prefcaps, &codec_buf));
}
get_our_media_address(p, needvideo, needtext, &addr, &vaddr, &taddr, &dest, &vdest, &tdest);
@@ -13322,22 +13401,6 @@ static enum sip_result add_sdp(struct sip_request *resp, struct sip_pvt *p, int
hold = "a=sendrecv\r\n";
}
- ast_format_cap_copy(tmpcap, p->jointcaps);
-
- /* XXX note, Video and Text are negated - 'true' means 'no' */
- ast_debug(1, "** Our capability: %s Video flag: %s Text flag: %s\n", ast_getformatname_multiple(codecbuf, sizeof(codecbuf), tmpcap),
- p->novideo ? "True" : "False", p->notext ? "True" : "False");
- ast_debug(1, "** Our prefcodec: %s \n", ast_getformatname_multiple(codecbuf, sizeof(codecbuf), p->prefcaps));
-
- if (doing_directmedia) {
- ast_format_cap_joint_copy(p->jointcaps, p->redircaps, tmpcap);
- ast_debug(1, "** Our native-bridge filtered capablity: %s\n", ast_getformatname_multiple(codecbuf, sizeof(codecbuf), tmpcap));
- }
-
- /* Check if we need audio */
- if (ast_format_cap_has_type(tmpcap, AST_FORMAT_TYPE_AUDIO))
- needaudio = TRUE;
-
if (debug) {
ast_verbose("Audio is at %s\n", ast_sockaddr_stringify_port(&addr));
}
@@ -13406,8 +13469,8 @@ static enum sip_result add_sdp(struct sip_request *resp, struct sip_pvt *p, int
/* Now, start adding audio codecs. These are added in this order:
- First what was requested by the calling channel
+ - Then our mutually shared capabilities, determined previous in tmpcap
- Then preferences in order from sip.conf device config for this peer/user
- - Then other codecs in capabilities, including video
*/
@@ -13415,57 +13478,62 @@ static enum sip_result add_sdp(struct sip_request *resp, struct sip_pvt *p, int
* configured codecs.
*/
if (!ast_test_flag(&p->flags[2], SIP_PAGE3_IGNORE_PREFCAPS)) {
- ast_format_cap_iter_start(p->prefcaps);
- while (!(ast_format_cap_iter_next(p->prefcaps, &tmp_fmt))) {
- if (AST_FORMAT_GET_TYPE(tmp_fmt.id) != AST_FORMAT_TYPE_AUDIO ||
- !ast_format_cap_iscompatible(tmpcap, &tmp_fmt)) {
+ for (x = 0; x < ast_format_cap_count(p->prefcaps); x++) {
+ tmp_fmt = ast_format_cap_get_format(p->prefcaps, x);
+
+ if ((ast_format_get_type(tmp_fmt) != AST_MEDIA_TYPE_AUDIO) ||
+ (ast_format_cap_iscompatible_format(tmpcap, tmp_fmt) == AST_FORMAT_CMP_NOT_EQUAL)) {
+ ao2_ref(tmp_fmt, -1);
continue;
}
- add_codec_to_sdp(p, &tmp_fmt, &m_audio, &a_audio, debug, &min_audio_packet_size, &max_audio_packet_size);
- ast_format_cap_add(alreadysent, &tmp_fmt);
+
+ add_codec_to_sdp(p, tmp_fmt, &m_audio, &a_audio, debug, &min_audio_packet_size, &max_audio_packet_size);
+ ast_format_cap_append(alreadysent, tmp_fmt, 0);
+ ao2_ref(tmp_fmt, -1);
}
- ast_format_cap_iter_end(p->prefcaps);
}
- /* Start by sending our preferred audio/video codecs */
- for (x = 0; x < AST_CODEC_PREF_SIZE; x++) {
- struct ast_format pref;
-
- if (!(ast_codec_pref_index(&p->prefs, x, &pref)))
- break;
-
- if (!ast_format_cap_get_compatible_format(tmpcap, &pref, &tmp_fmt))
- continue;
+ /* Now send any other common codecs */
+ for (x = 0; x < ast_format_cap_count(tmpcap); x++) {
+ tmp_fmt = ast_format_cap_get_format(tmpcap, x);
- if (ast_format_cap_iscompatible(alreadysent, &tmp_fmt))
+ if (ast_format_cap_iscompatible_format(alreadysent, tmp_fmt) != AST_FORMAT_CMP_NOT_EQUAL) {
+ ao2_ref(tmp_fmt, -1);
continue;
+ }
- if (AST_FORMAT_GET_TYPE(tmp_fmt.id) == AST_FORMAT_TYPE_AUDIO) {
- add_codec_to_sdp(p, &tmp_fmt, &m_audio, &a_audio, debug, &min_audio_packet_size, &max_audio_packet_size);
- } else if (needvideo && (AST_FORMAT_GET_TYPE(tmp_fmt.id) == AST_FORMAT_TYPE_VIDEO)) {
- add_vcodec_to_sdp(p, &tmp_fmt, &m_video, &a_video, debug, &min_video_packet_size);
- } else if (needtext && (AST_FORMAT_GET_TYPE(tmp_fmt.id) == AST_FORMAT_TYPE_TEXT)) {
- add_tcodec_to_sdp(p, &tmp_fmt, &m_text, &a_text, debug, &min_text_packet_size);
+ if (ast_format_get_type(tmp_fmt) == AST_MEDIA_TYPE_AUDIO) {
+ add_codec_to_sdp(p, tmp_fmt, &m_audio, &a_audio, debug, &min_audio_packet_size, &max_audio_packet_size);
+ } else if (needvideo && ast_format_get_type(tmp_fmt) == AST_MEDIA_TYPE_VIDEO) {
+ add_vcodec_to_sdp(p, tmp_fmt, &m_video, &a_video, debug, &min_video_packet_size);
+ } else if (needtext && ast_format_get_type(tmp_fmt) == AST_MEDIA_TYPE_TEXT) {
+ add_tcodec_to_sdp(p, tmp_fmt, &m_text, &a_text, debug, &min_text_packet_size);
}
- ast_format_cap_add(alreadysent, &tmp_fmt);
+ ast_format_cap_append(alreadysent, tmp_fmt, 0);
+ ao2_ref(tmp_fmt, -1);
}
- /* Now send any other common audio and video codecs, and non-codec formats: */
- ast_format_cap_iter_start(tmpcap);
- while (!(ast_format_cap_iter_next(tmpcap, &tmp_fmt))) {
- if (ast_format_cap_iscompatible(alreadysent, &tmp_fmt))
+ /* Finally our remaining audio/video codecs */
+ for (x = 0; x < ast_format_cap_count(p->caps); x++) {
+ tmp_fmt = ast_format_cap_get_format(p->caps, x);
+
+ if (ast_format_cap_iscompatible_format(alreadysent, tmp_fmt) != AST_FORMAT_CMP_NOT_EQUAL) {
+ ao2_ref(tmp_fmt, -1);
continue;
+ }
- if (AST_FORMAT_GET_TYPE(tmp_fmt.id) == AST_FORMAT_TYPE_AUDIO) {
- add_codec_to_sdp(p, &tmp_fmt, &m_audio, &a_audio, debug, &min_audio_packet_size, &max_audio_packet_size);
- } else if (needvideo && (AST_FORMAT_GET_TYPE(tmp_fmt.id) == AST_FORMAT_TYPE_VIDEO)) {
- add_vcodec_to_sdp(p, &tmp_fmt, &m_video, &a_video, debug, &min_video_packet_size);
- } else if (needtext && (AST_FORMAT_GET_TYPE(tmp_fmt.id) == AST_FORMAT_TYPE_TEXT)) {
- add_tcodec_to_sdp(p, &tmp_fmt, &m_text, &a_text, debug, &min_text_packet_size);
+ if (ast_format_get_type(tmp_fmt) == AST_MEDIA_TYPE_AUDIO) {
+ add_codec_to_sdp(p, tmp_fmt, &m_audio, &a_audio, debug, &min_audio_packet_size, &max_audio_packet_size);
+ } else if (needvideo && ast_format_get_type(tmp_fmt) == AST_MEDIA_TYPE_VIDEO) {
+ add_vcodec_to_sdp(p, tmp_fmt, &m_video, &a_video, debug, &min_video_packet_size);
+ } else if (needtext && ast_format_get_type(tmp_fmt) == AST_MEDIA_TYPE_TEXT) {
+ add_tcodec_to_sdp(p, tmp_fmt, &m_text, &a_text, debug, &min_text_packet_size);
}
+
+ ast_format_cap_append(alreadysent, tmp_fmt, 0);
+ ao2_ref(tmp_fmt, -1);
}
- ast_format_cap_iter_end(tmpcap);
/* Now add DTMF RFC2833 telephony-event as a codec */
for (x = 1LL; x <= AST_RTP_MAX; x <<= 1) {
@@ -13677,14 +13745,15 @@ static enum sip_result add_sdp(struct sip_request *resp, struct sip_pvt *p, int
ao2_t_link(dialogs_rtpcheck, p, "link pvt into dialogs_rtpcheck container");
ao2_unlock(dialogs_rtpcheck);
- ast_debug(3, "Done building SDP. Settling with this capability: %s\n", ast_getformatname_multiple(buf, SIPBUFSIZE, tmpcap));
+ ast_debug(3, "Done building SDP. Settling with this capability: %s\n",
+ ast_format_cap_get_names(tmpcap, &codec_buf));
add_sdp_cleanup:
ast_free(a_text);
ast_free(a_video);
ast_free(a_audio);
- alreadysent = ast_format_cap_destroy(alreadysent);
- tmpcap = ast_format_cap_destroy(tmpcap);
+ ao2_cleanup(alreadysent);
+ ao2_cleanup(tmpcap);
return res;
}
@@ -13792,7 +13861,7 @@ static int transmit_response_with_sdp(struct sip_pvt *p, const char *msg, const
if (p->rtp) {
if (!p->autoframing && !ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
ast_debug(1, "Setting framing from config on incoming call\n");
- ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(p->rtp), p->rtp, &p->prefs);
+ ast_rtp_codecs_set_framing(ast_rtp_instance_get_codecs(p->rtp), ast_format_cap_get_framing(p->caps));
}
ast_rtp_instance_activate(p->rtp);
try_suggested_sip_codec(p);
@@ -18475,10 +18544,9 @@ static enum check_auth_result check_peer_ok(struct sip_pvt *p, char *of,
peer->name, of, ast_sockaddr_stringify(&p->recv));
}
- /* XXX what about p->prefs = peer->prefs; ? */
/* Set Frame packetization */
if (p->rtp) {
- ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(p->rtp), p->rtp, &peer->prefs);
+ ast_rtp_codecs_set_framing(ast_rtp_instance_get_codecs(p->rtp), ast_format_cap_get_framing(peer->caps));
p->autoframing = peer->autoframing;
}
@@ -18595,20 +18663,22 @@ static enum check_auth_result check_peer_ok(struct sip_pvt *p, char *of,
p->named_callgroups = ast_ref_namedgroups(peer->named_callgroups);
ast_unref_namedgroups(p->named_pickupgroups);
p->named_pickupgroups = ast_ref_namedgroups(peer->named_pickupgroups);
- ast_format_cap_copy(p->caps, peer->caps);
- ast_format_cap_copy(p->jointcaps, peer->caps);
- p->prefs = peer->prefs;
+ ast_format_cap_remove_by_type(p->caps, AST_MEDIA_TYPE_UNKNOWN);
+ ast_format_cap_append_from_cap(p->caps, peer->caps, AST_MEDIA_TYPE_UNKNOWN);
+ ast_format_cap_remove_by_type(p->jointcaps, AST_MEDIA_TYPE_UNKNOWN);
+ ast_format_cap_append_from_cap(p->jointcaps, peer->caps, AST_MEDIA_TYPE_UNKNOWN);
ast_copy_string(p->zone, peer->zone, sizeof(p->zone));
if (peer->maxforwards > 0) {
p->maxforwards = peer->maxforwards;
}
- if (!(ast_format_cap_is_empty(p->peercaps))) {
- struct ast_format_cap *tmp = ast_format_cap_joint(p->jointcaps, p->peercaps);
- struct ast_format_cap *tmp2;
- if (tmp) {
- tmp2 = p->jointcaps;
- p->jointcaps = tmp;
- ast_format_cap_destroy(tmp2);
+ if (ast_format_cap_count(p->peercaps)) {
+ struct ast_format_cap *joint;
+
+ joint = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
+ if (joint) {
+ ast_format_cap_get_compatible(p->jointcaps, p->peercaps, joint);
+ ao2_ref(p->jointcaps, -1);
+ p->jointcaps = joint;
}
}
p->maxcallbitrate = peer->maxcallbitrate;
@@ -18623,7 +18693,7 @@ static enum check_auth_result check_peer_ok(struct sip_pvt *p, char *of,
p->rtpkeepalive = peer->rtpkeepalive;
if (!dialog_initialize_rtp(p)) {
if (p->rtp) {
- ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(p->rtp), p->rtp, &peer->prefs);
+ ast_rtp_codecs_set_framing(ast_rtp_instance_get_codecs(p->rtp), ast_format_cap_get_framing(peer->caps));
p->autoframing = peer->autoframing;
}
} else {
@@ -19959,25 +20029,6 @@ static char *sip_prune_realtime(struct ast_cli_entry *e, int cmd, struct ast_cli
return CLI_SUCCESS;
}
-/*! \brief Print codec list from preference to CLI/manager */
-static void print_codec_to_cli(int fd, struct ast_codec_pref *pref)
-{
- int x;
- struct ast_format codec;
-
- for(x = 0; x < AST_CODEC_PREF_SIZE; x++) {
- if (!(ast_codec_pref_index(pref, x, &codec))) {
- break;
- }
- ast_cli(fd, "%s", ast_getformatname(&codec));
- ast_cli(fd, ":%d", pref->framing[x]);
- if (x < 31 && ast_codec_pref_index(pref, x + 1, &codec))
- ast_cli(fd, ",");
- }
- if (!x)
- ast_cli(fd, "none");
-}
-
/*! \brief Print domain mode to cli */
static const char *domain_mode_to_text(const enum domain_mode mode)
{
@@ -20262,11 +20313,9 @@ static char *_sip_show_peer(int type, int fd, struct mansession *s, const struct
char status[30] = "";
char cbuf[256];
struct sip_peer *peer;
- char codec_buf[512];
- struct ast_codec_pref *pref;
+ struct ast_str *codec_buf = ast_str_alloca(64);
struct ast_variable *v;
int x = 0, load_realtime;
- struct ast_format codec;
int realtimepeers;
realtimepeers = ast_check_realtime("sippeers");
@@ -20415,12 +20464,7 @@ static char *_sip_show_peer(int type, int fd, struct mansession *s, const struct
ast_cli(fd, "(none)");
ast_cli(fd, "\n");
- ast_cli(fd, " Codecs : ");
- ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->caps);
- ast_cli(fd, "%s\n", codec_buf);
- ast_cli(fd, " Codec Order : (");
- print_codec_to_cli(fd, &peer->prefs);
- ast_cli(fd, ")\n");
+ ast_cli(fd, " Codecs : %s\n", ast_format_cap_get_names(peer->caps, &codec_buf));
ast_cli(fd, " Auto-Framing : %s\n", AST_CLI_YESNO(peer->autoframing));
ast_cli(fd, " Status : ");
@@ -20523,21 +20567,7 @@ static char *_sip_show_peer(int type, int fd, struct mansession *s, const struct
astman_append(s, "Default-Username: %s\r\n", peer->username);
if (!ast_strlen_zero(sip_cfg.regcontext))
astman_append(s, "RegExtension: %s\r\n", peer->regexten);
- astman_append(s, "Codecs: ");
- ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->caps);
- astman_append(s, "%s\r\n", codec_buf);
- astman_append(s, "CodecOrder: ");
- pref = &peer->prefs;
- for(x = 0; x < AST_CODEC_PREF_SIZE ; x++) {
- if (!(ast_codec_pref_index(pref, x, &codec))) {
- break;
- }
- astman_append(s, "%s", ast_getformatname(&codec));
- if ((x < (AST_CODEC_PREF_SIZE - 1)) && ast_codec_pref_index(pref, x+1, &codec))
- astman_append(s, ",");
- }
-
- astman_append(s, "\r\n");
+ astman_append(s, "Codecs: %s\r\n", ast_format_cap_get_names(peer->caps, &codec_buf));
astman_append(s, "Status: ");
peer_status(peer, status, sizeof(status));
astman_append(s, "%s\r\n", status);
@@ -20660,10 +20690,6 @@ static char *sip_show_user(struct ast_cli_entry *e, int cmd, struct ast_cli_args
ast_cli(a->fd, " Sess-Min-SE : %d secs\n", user->stimer.st_min_se);
ast_cli(a->fd, " RTP Engine : %s\n", user->engine);
- ast_cli(a->fd, " Codec Order : (");
- print_codec_to_cli(a->fd, &user->prefs);
- ast_cli(a->fd, ")\n");
-
ast_cli(a->fd, " Auto-Framing: %s \n", AST_CLI_YESNO(user->autoframing));
if (user->chanvars) {
ast_cli(a->fd, " Variables :\n");
@@ -20916,7 +20942,7 @@ static char *sip_show_settings(struct ast_cli_entry *e, int cmd, struct ast_cli_
{
int realtimepeers;
int realtimeregs;
- char codec_buf[SIPBUFSIZE];
+ struct ast_str *codec_buf = ast_str_alloca(64);
const char *msg; /* temporary msg pointer */
struct sip_auth_container *credentials;
@@ -21069,12 +21095,7 @@ static char *sip_show_settings(struct ast_cli_entry *e, int cmd, struct ast_cli_
}
ast_cli(a->fd, "\nGlobal Signalling Settings:\n");
ast_cli(a->fd, "---------------------------\n");
- ast_cli(a->fd, " Codecs: ");
- ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, sip_cfg.caps);
- ast_cli(a->fd, "%s\n", codec_buf);
- ast_cli(a->fd, " Codec Order: ");
- print_codec_to_cli(a->fd, &default_prefs);
- ast_cli(a->fd, "\n");
+ ast_cli(a->fd, " Codecs: %s\n", ast_format_cap_get_names(sip_cfg.caps, &codec_buf));
ast_cli(a->fd, " Relax DTMF: %s\n", AST_CLI_YESNO(global_relaxdtmf));
ast_cli(a->fd, " RFC2833 Compensation: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_RFC2833_COMPENSATE)));
ast_cli(a->fd, " Symmetric RTP: %s\n", comedia_string(global_flags));
@@ -21233,12 +21254,12 @@ static int show_channels_cb(void *__cur, void *__arg, int flags)
if (cur->subscribed == NONE && !arg->subscriptions) {
/* set if SIP transfer in progress */
const char *referstatus = cur->refer ? referstatus2str(cur->refer->status) : "";
- char formatbuf[SIPBUFSIZE/2];
+ struct ast_str *codec_buf = ast_str_alloca(64);
ast_cli(arg->fd, FORMAT, ast_sockaddr_stringify_addr(dst),
S_OR(cur->username, S_OR(cur->cid_num, "(None)")),
cur->callid,
- cur->owner ? ast_getformatname_multiple(formatbuf, sizeof(formatbuf), ast_channel_nativeformats(cur->owner)) : "(nothing)",
+ cur->owner ? ast_format_cap_get_names(ast_channel_nativeformats(cur->owner), &codec_buf) : "(nothing)",
AST_CLI_YESNO(ast_test_flag(&cur->flags[1], SIP_PAGE2_CALL_ONHOLD)),
cur->needdestroy ? "(d)" : "",
cur->lastmsg ,
@@ -21479,7 +21500,8 @@ static char *sip_show_channel(struct ast_cli_entry *e, int cmd, struct ast_cli_a
if (!strncasecmp(cur->callid, a->argv[3], len)) {
struct ast_str *strbuf;
- char formatbuf[SIPBUFSIZE/2];
+ struct ast_str *codec_buf = ast_str_alloca(64);
+
ast_cli(a->fd, "\n");
if (cur->subscribed != NONE) {
ast_cli(a->fd, " * Subscription (type: %s)\n", subscription_type2str(cur->subscribed));
@@ -21489,11 +21511,11 @@ static char *sip_show_channel(struct ast_cli_entry *e, int cmd, struct ast_cli_a
ast_cli(a->fd, " Curr. trans. direction: %s\n", ast_test_flag(&cur->flags[0], SIP_OUTGOING) ? "Outgoing" : "Incoming");
ast_cli(a->fd, " Call-ID: %s\n", cur->callid);
ast_cli(a->fd, " Owner channel ID: %s\n", cur->owner ? ast_channel_name(cur->owner) : "<none>");
- ast_cli(a->fd, " Our Codec Capability: %s\n", ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->caps));
+ ast_cli(a->fd, " Our Codec Capability: %s\n", ast_format_cap_get_names(cur->caps, &codec_buf));
ast_cli(a->fd, " Non-Codec Capability (DTMF): %d\n", cur->noncodeccapability);
- ast_cli(a->fd, " Their Codec Capability: %s\n", ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->peercaps));
- ast_cli(a->fd, " Joint Codec Capability: %s\n", ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->jointcaps));
- ast_cli(a->fd, " Format: %s\n", cur->owner ? ast_getformatname_multiple(formatbuf, sizeof(formatbuf), ast_channel_nativeformats(cur->owner)) : "(nothing)" );
+ ast_cli(a->fd, " Their Codec Capability: %s\n", ast_format_cap_get_names(cur->peercaps, &codec_buf));
+ ast_cli(a->fd, " Joint Codec Capability: %s\n", ast_format_cap_get_names(cur->jointcaps, &codec_buf));
+ ast_cli(a->fd, " Format: %s\n", cur->owner ? ast_format_cap_get_names(ast_channel_nativeformats(cur->owner), &codec_buf) : "(nothing)" );
ast_cli(a->fd, " T.38 support %s\n", AST_CLI_YESNO(cur->udptl != NULL));
ast_cli(a->fd, " Video support %s\n", AST_CLI_YESNO(cur->vrtp != NULL));
ast_cli(a->fd, " MaxCallBR: %d kbps\n", cur->maxcallbitrate);
@@ -22437,7 +22459,9 @@ static int function_sippeer(struct ast_channel *chan, const char *cmd, char *dat
} else if (!strcasecmp(colname, "callerid_num")) {
ast_copy_string(buf, peer->cid_num, len);
} else if (!strcasecmp(colname, "codecs")) {
- ast_getformatname_multiple(buf, len -1, peer->caps);
+ struct ast_str *codec_buf = ast_str_alloca(64);
+ ast_format_cap_get_names(peer->caps, &codec_buf);
+ ast_copy_string(buf, ast_str_buffer(codec_buf), len);
} else if (!strcasecmp(colname, "encryption")) {
snprintf(buf, len, "%u", ast_test_flag(&peer->flags[1], SIP_PAGE2_USE_SRTP));
} else if (!strncasecmp(colname, "chanvar[", 8)) {
@@ -22452,12 +22476,14 @@ static int function_sippeer(struct ast_channel *chan, const char *cmd, char *dat
}
} else if (!strncasecmp(colname, "codec[", 6)) {
char *codecnum;
- struct ast_format codec;
+ struct ast_format *codec;
codecnum = colname + 6; /* move past the '[' */
codecnum = strsep(&codecnum, "]"); /* trim trailing ']' if any */
- if((ast_codec_pref_index(&peer->prefs, atoi(codecnum), &codec))) {
- ast_copy_string(buf, ast_getformatname(&codec), len);
+ codec = ast_format_cap_get_format(peer->caps, atoi(codecnum));
+ if (codec) {
+ ast_copy_string(buf, ast_format_get_name(codec), len);
+ ao2_ref(codec, -1);
} else {
buf[0] = '\0';
}
@@ -25476,7 +25502,8 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, str
}
ast_queue_control(p->owner, AST_CONTROL_SRCUPDATE);
} else {
- ast_format_cap_copy(p->jointcaps, p->caps);
+ ast_format_cap_remove_by_type(p->jointcaps, AST_MEDIA_TYPE_UNKNOWN);
+ ast_format_cap_append_from_cap(p->jointcaps, p->caps, AST_MEDIA_TYPE_UNKNOWN);
ast_debug(1, "Hm.... No sdp for the moment\n");
/* Some devices signal they want to be put off hold by sending a re-invite
*without* an SDP, which is supposed to mean "Go back to your state"
@@ -25541,7 +25568,8 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, str
goto request_invite_cleanup;
}
} else { /* No SDP in invite, call control session */
- ast_format_cap_copy(p->jointcaps, p->caps);
+ ast_format_cap_remove_by_type(p->jointcaps, AST_MEDIA_TYPE_UNKNOWN);
+ ast_format_cap_append_from_cap(p->jointcaps, p->caps, AST_MEDIA_TYPE_UNKNOWN);
ast_debug(2, "No SDP in Invite, third party call control\n");
}
@@ -25855,7 +25883,7 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, str
if (p && (p->autokillid == -1)) {
const char *msg;
- if ((ast_format_cap_is_empty(p->jointcaps)))
+ if ((!ast_format_cap_count(p->jointcaps)))
msg = "488 Not Acceptable Here (codec error)";
else {
ast_log(LOG_NOTICE, "Unable to create/find SIP channel for this INVITE\n");
@@ -29539,7 +29567,8 @@ static struct ast_channel *sip_request_call(const char *type, struct ast_format_
struct ast_channel *tmpc = NULL;
char *ext = NULL, *host;
char tmp[256];
- char tmp2[256];
+ struct ast_str *codec_buf = ast_str_alloca(64);
+ struct ast_str *cap_buf = ast_str_alloca(64);
char *dnid;
char *secret = NULL;
char *md5secret = NULL;
@@ -29562,14 +29591,14 @@ static struct ast_channel *sip_request_call(const char *type, struct ast_format_
* configured from sip.conf, and sip_tech.capabilities, which is
* hardwired to all audio formats.
*/
- if (!(ast_format_cap_has_type(cap, AST_FORMAT_TYPE_AUDIO))) {
+ if (!(ast_format_cap_has_type(cap, AST_MEDIA_TYPE_AUDIO))) {
ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format %s while capability is %s\n",
- ast_getformatname_multiple(tmp, sizeof(tmp), cap),
- ast_getformatname_multiple(tmp2, sizeof(tmp2), sip_cfg.caps));
+ ast_format_cap_get_names(cap, &codec_buf),
+ ast_format_cap_get_names(sip_cfg.caps, &cap_buf));
*cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; /* Can't find codec to connect to host */
return NULL;
}
- ast_debug(1, "Asked to create a SIP channel with formats: %s\n", ast_getformatname_multiple(tmp, sizeof(tmp), cap));
+ ast_debug(1, "Asked to create a SIP channel with formats: %s\n", ast_format_cap_get_names(cap, &codec_buf));
if (ast_strlen_zero(dest)) {
ast_log(LOG_ERROR, "Unable to create channel with empty destination.\n");
@@ -29739,8 +29768,8 @@ static struct ast_channel *sip_request_call(const char *type, struct ast_format_
#if 0
printf("Setting up to call extension '%s' at '%s'\n", ext ? ext : "<none>", host);
#endif
- ast_format_cap_append(p->prefcaps, cap);
- ast_format_cap_joint_copy(cap, p->caps, p->jointcaps);
+ ast_format_cap_append_from_cap(p->prefcaps, cap, AST_MEDIA_TYPE_UNKNOWN);
+ ast_format_cap_get_compatible(cap, p->caps, p->jointcaps);
sip_pvt_lock(p);
@@ -30217,7 +30246,7 @@ static void set_peer_defaults(struct sip_peer *peer)
ast_string_field_set(peer, engine, default_engine);
ast_sockaddr_setnull(&peer->addr);
ast_sockaddr_setnull(&peer->defaddr);
- ast_format_cap_copy(peer->caps, sip_cfg.caps);
+ ast_format_cap_append_from_cap(peer->caps, sip_cfg.caps, AST_MEDIA_TYPE_UNKNOWN);
peer->maxcallbitrate = default_maxcallbitrate;
peer->rtptimeout = global_rtptimeout;
peer->rtpholdtimeout = global_rtpholdtimeout;
@@ -30243,7 +30272,6 @@ static void set_peer_defaults(struct sip_peer *peer)
peer->pickupgroup = 0;
peer->maxms = default_qualify;
peer->keepalive = default_keepalive;
- peer->prefs = default_prefs;
ast_string_field_set(peer, zone, default_zone);
peer->stimer.st_mode_oper = global_st_mode; /* Session-Timers */
peer->stimer.st_ref = global_st_refresher;
@@ -30279,7 +30307,7 @@ static struct sip_peer *temp_peer(const char *name)
return NULL;
}
- if (!(peer->caps = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_NOLOCK))) {
+ if (!(peer->caps = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT))) {
ao2_t_ref(peer, -1, "failed to allocate format capabilities, drop peer");
return NULL;
}
@@ -30291,7 +30319,6 @@ static struct sip_peer *temp_peer(const char *name)
peer->selfdestruct = TRUE;
peer->host_dynamic = TRUE;
- peer->prefs = default_prefs;
reg_source_db(peer);
return peer;
@@ -30384,7 +30411,7 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, str
if (!(peer->endpoint = ast_endpoint_create("SIP", name))) {
return NULL;
}
- if (!(peer->caps = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_NOLOCK))) {
+ if (!(peer->caps = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT))) {
ao2_t_ref(peer, -1, "failed to allocate format capabilities, drop peer");
return NULL;
}
@@ -30705,12 +30732,12 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, str
} else if (!strcasecmp(v->name, "namedpickupgroup")) {
peer->named_pickupgroups = ast_get_namedgroups(v->value);
} else if (!strcasecmp(v->name, "allow")) {
- int error = ast_parse_allow_disallow(&peer->prefs, peer->caps, v->value, TRUE);
+ int error = ast_format_cap_update_by_allow_disallow(peer->caps, v->value, TRUE);
if (error) {
ast_log(LOG_WARNING, "Codec configuration errors found in line %d : %s = %s\n", v->lineno, v->name, v->value);
}
} else if (!strcasecmp(v->name, "disallow")) {
- int error = ast_parse_allow_disallow(&peer->prefs, peer->caps, v->value, FALSE);
+ int error = ast_format_cap_update_by_allow_disallow(peer->caps, v->value, FALSE);
if (error) {
ast_log(LOG_WARNING, "Codec configuration errors found in line %d : %s = %s\n", v->lineno, v->name, v->value);
}
@@ -31104,14 +31131,11 @@ static int peer_markall_autopeers_func(void *device, void *arg, int flags)
*/
static void sip_set_default_format_capabilities(struct ast_format_cap *cap)
{
- struct ast_format tmp_fmt;
-
- ast_format_cap_remove_all(cap);
- ast_format_cap_add(cap, ast_format_set(&tmp_fmt, AST_FORMAT_ULAW, 0));
- ast_format_cap_add(cap, ast_format_set(&tmp_fmt, AST_FORMAT_TESTLAW, 0));
- ast_format_cap_add(cap, ast_format_set(&tmp_fmt, AST_FORMAT_ALAW, 0));
- ast_format_cap_add(cap, ast_format_set(&tmp_fmt, AST_FORMAT_GSM, 0));
- ast_format_cap_add(cap, ast_format_set(&tmp_fmt, AST_FORMAT_H263, 0));
+ ast_format_cap_remove_by_type(cap, AST_MEDIA_TYPE_UNKNOWN);
+ ast_format_cap_append(cap, ast_format_ulaw, 0);
+ ast_format_cap_append(cap, ast_format_alaw, 0);
+ ast_format_cap_append(cap, ast_format_gsm, 0);
+ ast_format_cap_append(cap, ast_format_h263, 0);
}
static void display_nat_warning(const char *cat, int reason, struct ast_flags *flags) {
@@ -31276,7 +31300,6 @@ static int reload_config(enum channelreloadreason reason)
memset(&localaddr, 0, sizeof(localaddr));
memset(&externaddr, 0, sizeof(externaddr));
memset(&media_address, 0, sizeof(media_address));
- memset(&default_prefs, 0 , sizeof(default_prefs));
memset(&sip_cfg.outboundproxy, 0, sizeof(struct sip_proxy));
sip_cfg.outboundproxy.force = FALSE; /*!< Don't force proxy usage, use route: headers */
default_transports = AST_TRANSPORT_UDP;
@@ -31768,12 +31791,12 @@ static int reload_config(enum channelreloadreason reason)
ast_log(LOG_WARNING, "Invalid externtlsport value, must be a positive integer between 1 and 65535 at line %d\n", v->lineno);
}
} else if (!strcasecmp(v->name, "allow")) {
- int error = ast_parse_allow_disallow(&default_prefs, sip_cfg.caps, v->value, TRUE);
+ int error = ast_format_cap_update_by_allow_disallow(sip_cfg.caps, v->value, TRUE);
if (error) {
ast_log(LOG_WARNING, "Codec configuration errors found in line %d : %s = %s\n", v->lineno, v->name, v->value);
}
} else if (!strcasecmp(v->name, "disallow")) {
- int error = ast_parse_allow_disallow(&default_prefs, sip_cfg.caps, v->value, FALSE);
+ int error = ast_format_cap_update_by_allow_disallow(sip_cfg.caps, v->value, FALSE);
if (error) {
ast_log(LOG_WARNING, "Codec configuration errors found in line %d : %s = %s\n", v->lineno, v->name, v->value);
}
@@ -32565,8 +32588,9 @@ static int sip_set_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance *i
memset(&p->tredirip, 0, sizeof(p->tredirip));
changed = 1;
}
- if (cap && !ast_format_cap_is_empty(cap) && !ast_format_cap_identical(p->redircaps, cap)) {
- ast_format_cap_copy(p->redircaps, cap);
+ if (cap && ast_format_cap_count(cap) && !ast_format_cap_identical(cap, p->redircaps)) {
+ ast_format_cap_remove_by_type(p->redircaps, AST_MEDIA_TYPE_UNKNOWN);
+ ast_format_cap_append_from_cap(p->redircaps, cap, AST_MEDIA_TYPE_UNKNOWN);
changed = 1;
}
@@ -32603,7 +32627,8 @@ static int sip_set_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance *i
static void sip_get_codec(struct ast_channel *chan, struct ast_format_cap *result)
{
struct sip_pvt *p = ast_channel_tech_pvt(chan);
- ast_format_cap_append(result, ast_format_cap_is_empty(p->peercaps) ? p->caps : p->peercaps);
+
+ ast_format_cap_append_from_cap(result, !ast_format_cap_count(p->peercaps) ? p->caps : p->peercaps, AST_MEDIA_TYPE_UNKNOWN);
}
static struct ast_rtp_glue sip_rtp_glue = {
@@ -34217,6 +34242,8 @@ static const struct ast_sip_api_tech chan_sip_api_provider = {
.sipinfo_send = sipinfo_send,
};
+static int unload_module(void);
+
/*!
* \brief Load the module
*
@@ -34232,14 +34259,17 @@ static int load_module(void)
ast_verbose("SIP channel loading...\n");
if (STASIS_MESSAGE_TYPE_INIT(session_timeout_type)) {
+ unload_module();
return AST_MODULE_LOAD_FAILURE;
}
if (!(sip_tech.capabilities = ast_format_cap_alloc(0))) {
+ unload_module();
return AST_MODULE_LOAD_FAILURE;
}
if (ast_sip_api_provider_register(&chan_sip_api_provider)) {
+ unload_module();
return AST_MODULE_LOAD_FAILURE;
}
@@ -34254,24 +34284,28 @@ static int load_module(void)
if (!peers || !peers_by_ip || !dialogs || !dialogs_needdestroy || !dialogs_rtpcheck
|| !threadt) {
ast_log(LOG_ERROR, "Unable to create primary SIP container(s)\n");
+ unload_module();
return AST_MODULE_LOAD_FAILURE;
}
- if (!(sip_cfg.caps = ast_format_cap_alloc(0))) {
+ if (!(sip_cfg.caps = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT))) {
+ unload_module();
return AST_MODULE_LOAD_FAILURE;
}
- ast_format_cap_add_all_by_type(sip_tech.capabilities, AST_FORMAT_TYPE_AUDIO);
+ ast_format_cap_append_by_type(sip_tech.capabilities, AST_MEDIA_TYPE_AUDIO);
ASTOBJ_CONTAINER_INIT(&regl); /* Registry object list -- not searched for anything */
ASTOBJ_CONTAINER_INIT(&submwil); /* MWI subscription object list */
if (!(sched = ast_sched_context_create())) {
ast_log(LOG_ERROR, "Unable to create scheduler context\n");
+ unload_module();
return AST_MODULE_LOAD_FAILURE;
}
if (!(io = io_context_create())) {
ast_log(LOG_ERROR, "Unable to create I/O context\n");
+ unload_module();
return AST_MODULE_LOAD_FAILURE;
}
@@ -34279,15 +34313,14 @@ static int load_module(void)
can_parse_xml = sip_is_xml_parsable();
if (reload_config(sip_reloadreason)) { /* Load the configuration from sip.conf */
- ast_sip_api_provider_unregister();
+ unload_module();
return AST_MODULE_LOAD_DECLINE;
}
/* Initialize bogus peer. Can be done first after reload_config() */
if (!(bogus_peer = temp_peer("(bogus_peer)"))) {
ast_log(LOG_ERROR, "Unable to create bogus_peer for authentication\n");
- io_context_destroy(io);
- ast_sched_context_destroy(sched);
+ unload_module();
return AST_MODULE_LOAD_FAILURE;
}
/* Make sure the auth will always fail. */
@@ -34302,16 +34335,14 @@ static int load_module(void)
memset((void *) &sip_tech_info.send_digit_begin, 0, sizeof(sip_tech_info.send_digit_begin));
if (ast_msg_tech_register(&sip_msg_tech)) {
- /* LOAD_FAILURE stops Asterisk, so cleanup is a moot point. */
+ unload_module();
return AST_MODULE_LOAD_FAILURE;
}
/* Make sure we can register our sip channel type */
if (ast_channel_register(&sip_tech)) {
ast_log(LOG_ERROR, "Unable to register channel type 'SIP'\n");
- ao2_t_ref(bogus_peer, -1, "unref the bogus_peer");
- io_context_destroy(io);
- ast_sched_context_destroy(sched);
+ unload_module();
return AST_MODULE_LOAD_FAILURE;
}
@@ -34358,13 +34389,13 @@ static int load_module(void)
initialize_escs();
if (sip_epa_register(&cc_epa_static_data)) {
- ast_sip_api_provider_unregister();
+ unload_module();
return AST_MODULE_LOAD_DECLINE;
}
if (sip_reqresp_parser_init() == -1) {
ast_log(LOG_ERROR, "Unable to initialize the SIP request and response parser\n");
- ast_sip_api_provider_unregister();
+ unload_module();
return AST_MODULE_LOAD_DECLINE;
}
@@ -34373,16 +34404,16 @@ static int load_module(void)
* in incoming PUBLISH requests
*/
if (ast_cc_agent_register(&sip_cc_agent_callbacks)) {
- ast_sip_api_provider_unregister();
+ unload_module();
return AST_MODULE_LOAD_DECLINE;
}
}
if (ast_cc_monitor_register(&sip_cc_monitor_callbacks)) {
- ast_sip_api_provider_unregister();
+ unload_module();
return AST_MODULE_LOAD_DECLINE;
}
if (!(sip_monitor_instances = ao2_container_alloc(37, sip_monitor_instance_hash_fn, sip_monitor_instance_cmp_fn))) {
- ast_sip_api_provider_unregister();
+ unload_module();
return AST_MODULE_LOAD_DECLINE;
}
@@ -34523,7 +34554,7 @@ static int unload_module(void)
ast_mutex_lock(&authl_lock);
if (authl) {
- ao2_t_ref(authl, -1, "Removing global authentication");
+ ao2_t_cleanup(authl, "Removing global authentication");
authl = NULL;
}
ast_mutex_unlock(&authl_lock);
@@ -34568,15 +34599,15 @@ static int unload_module(void)
ast_debug(2, "TCP/TLS thread container did not become empty :(\n");
}
- ao2_t_ref(bogus_peer, -1, "unref the bogus_peer");
+ ao2_t_cleanup(bogus_peer, "unref the bogus_peer");
- ao2_t_ref(peers, -1, "unref the peers table");
- ao2_t_ref(peers_by_ip, -1, "unref the peers_by_ip table");
- ao2_t_ref(dialogs, -1, "unref the dialogs table");
- ao2_t_ref(dialogs_needdestroy, -1, "unref dialogs_needdestroy");
- ao2_t_ref(dialogs_rtpcheck, -1, "unref dialogs_rtpcheck");
- ao2_t_ref(threadt, -1, "unref the thread table");
- ao2_t_ref(sip_monitor_instances, -1, "unref the sip_monitor_instances table");
+ ao2_t_cleanup(peers, "unref the peers table");
+ ao2_t_cleanup(peers_by_ip, "unref the peers_by_ip table");
+ ao2_t_cleanup(dialogs, "unref the dialogs table");
+ ao2_t_cleanup(dialogs_needdestroy, "unref dialogs_needdestroy");
+ ao2_t_cleanup(dialogs_rtpcheck, "unref dialogs_rtpcheck");
+ ao2_t_cleanup(threadt, "unref the thread table");
+ ao2_t_cleanup(sip_monitor_instances, "unref the sip_monitor_instances table");
clear_sip_domains();
sip_cfg.contact_acl = ast_free_acl_list(sip_cfg.contact_acl);
@@ -34604,8 +34635,10 @@ static int unload_module(void)
notify_types = NULL;
}
- ast_format_cap_destroy(sip_tech.capabilities);
- sip_cfg.caps = ast_format_cap_destroy(sip_cfg.caps);
+ ao2_cleanup(sip_tech.capabilities);
+ sip_tech.capabilities = NULL;
+ ao2_cleanup(sip_cfg.caps);
+ sip_cfg.caps = NULL;
STASIS_MESSAGE_TYPE_CLEANUP(session_timeout_type);
diff --git a/channels/chan_skinny.c b/channels/chan_skinny.c
index 49ff8d548..e4882dbba 100644
--- a/channels/chan_skinny.c
+++ b/channels/chan_skinny.c
@@ -84,6 +84,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/bridge.h"
#include "asterisk/parking.h"
#include "asterisk/stasis_channels.h"
+#include "asterisk/format_cache.h"
/*** DOCUMENTATION
<manager name="SKINNYdevices" language="en_US">
@@ -146,8 +147,6 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#ifdef AST_DEVMODE
static int skinnydebug = 0;
char dbgcli_buf[256];
-char dbgreg_buf[256];
-char dbgsub_buf[256];
#define DEBUG_GENERAL (1 << 1)
#define DEBUG_SUB (1 << 2)
#define DEBUG_PACKET (1 << 3)
@@ -174,7 +173,6 @@ static const char tdesc[] = "Skinny Client Control Protocol (Skinny)";
static const char config[] = "skinny.conf";
static struct ast_format_cap *default_cap;
-static struct ast_codec_pref default_prefs;
enum skinny_codecs {
SKINNY_CODEC_ALAW = 2,
@@ -1454,8 +1452,6 @@ struct skinny_subchannel {
int amaflags; \
int instance; \
int group; \
- struct ast_codec_pref confprefs; \
- struct ast_codec_pref prefs; \
int nonCodecCapability; \
int immediate; \
int nat; \
@@ -1568,7 +1564,6 @@ struct skinny_addon {
int hookstate; \
int lastlineinstance; \
int lastcallreference; \
- struct ast_codec_pref confprefs; \
int earlyrtp; \
int transfer; \
int callwaiting; \
@@ -1679,11 +1674,11 @@ static struct skinny_line *skinny_line_alloc(void)
return NULL;
}
- l->cap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_NOLOCK);
- l->confcap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_NOLOCK);
+ l->cap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
+ l->confcap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
if (!l->cap || !l->confcap) {
- l->cap = ast_format_cap_destroy(l->cap);
- l->confcap = ast_format_cap_destroy(l->confcap);
+ ao2_cleanup(l->cap);
+ ao2_cleanup(l->confcap);
ast_free(l);
return NULL;
}
@@ -1691,8 +1686,8 @@ static struct skinny_line *skinny_line_alloc(void)
}
static struct skinny_line *skinny_line_destroy(struct skinny_line *l)
{
- l->cap = ast_format_cap_destroy(l->cap);
- l->confcap = ast_format_cap_destroy(l->confcap);
+ ao2_ref(l->cap, -1);
+ ao2_ref(l->confcap, -1);
l->named_callgroups = ast_unref_namedgroups(l->named_callgroups);
l->named_pickupgroups = ast_unref_namedgroups(l->named_pickupgroups);
ast_free(l->container);
@@ -1706,12 +1701,12 @@ static struct skinny_device *skinny_device_alloc(const char *dname)
return NULL;
}
- d->cap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_NOLOCK);
- d->confcap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_NOLOCK);
+ d->cap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
+ d->confcap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
d->endpoint = ast_endpoint_create("Skinny", dname);
if (!d->cap || !d->confcap || !d->endpoint) {
- d->cap = ast_format_cap_destroy(d->cap);
- d->confcap = ast_format_cap_destroy(d->confcap);
+ ao2_cleanup(d->cap);
+ ao2_cleanup(d->confcap);
ast_free(d);
return NULL;
}
@@ -1722,8 +1717,8 @@ static struct skinny_device *skinny_device_alloc(const char *dname)
}
static struct skinny_device *skinny_device_destroy(struct skinny_device *d)
{
- d->cap = ast_format_cap_destroy(d->cap);
- d->confcap = ast_format_cap_destroy(d->confcap);
+ ao2_ref(d->cap, -1);
+ ao2_ref(d->confcap, -1);
ast_endpoint_shutdown(d->endpoint);
ast_free(d);
return NULL;
@@ -2103,51 +2098,49 @@ static struct skinny_speeddial *find_speeddial_by_instance(struct skinny_device
return sd;
}
-static struct ast_format *codec_skinny2ast(enum skinny_codecs skinnycodec, struct ast_format *result)
+static struct ast_format *codec_skinny2ast(enum skinny_codecs skinnycodec)
{
switch (skinnycodec) {
case SKINNY_CODEC_ALAW:
- return ast_format_set(result, AST_FORMAT_ALAW, 0);
+ return ast_format_alaw;
case SKINNY_CODEC_ULAW:
- return ast_format_set(result, AST_FORMAT_ULAW, 0);
+ return ast_format_ulaw;
case SKINNY_CODEC_G722:
- return ast_format_set(result, AST_FORMAT_G722, 0);
+ return ast_format_g722;
case SKINNY_CODEC_G723_1:
- return ast_format_set(result, AST_FORMAT_G723_1, 0);
+ return ast_format_g723;
case SKINNY_CODEC_G729A:
- return ast_format_set(result, AST_FORMAT_G729A, 0);
+ return ast_format_g729;
case SKINNY_CODEC_G726_32:
- return ast_format_set(result, AST_FORMAT_G726_AAL2, 0); /* XXX Is this right? */
+ return ast_format_g726; /* XXX Is this right? */
case SKINNY_CODEC_H261:
- return ast_format_set(result, AST_FORMAT_H261, 0);
+ return ast_format_h261;
case SKINNY_CODEC_H263:
- return ast_format_set(result, AST_FORMAT_H263 ,0);
+ return ast_format_h263;
default:
- ast_format_clear(result);
- return result;
+ return ast_format_none;
}
}
static int codec_ast2skinny(const struct ast_format *astcodec)
{
- switch (astcodec->id) {
- case AST_FORMAT_ALAW:
+ if (ast_format_cmp(astcodec, ast_format_alaw) == AST_FORMAT_CMP_EQUAL) {
return SKINNY_CODEC_ALAW;
- case AST_FORMAT_ULAW:
+ } else if (ast_format_cmp(astcodec, ast_format_ulaw) == AST_FORMAT_CMP_EQUAL) {
return SKINNY_CODEC_ULAW;
- case AST_FORMAT_G722:
+ } else if (ast_format_cmp(astcodec, ast_format_g722) == AST_FORMAT_CMP_EQUAL) {
return SKINNY_CODEC_G722;
- case AST_FORMAT_G723_1:
+ } else if (ast_format_cmp(astcodec, ast_format_g723) == AST_FORMAT_CMP_EQUAL) {
return SKINNY_CODEC_G723_1;
- case AST_FORMAT_G729A:
+ } else if (ast_format_cmp(astcodec, ast_format_g729) == AST_FORMAT_CMP_EQUAL) {
return SKINNY_CODEC_G729A;
- case AST_FORMAT_G726_AAL2: /* XXX Is this right? */
+ } else if (ast_format_cmp(astcodec, ast_format_g726) == AST_FORMAT_CMP_EQUAL) {
return SKINNY_CODEC_G726_32;
- case AST_FORMAT_H261:
+ } else if (ast_format_cmp(astcodec, ast_format_h261) == AST_FORMAT_CMP_EQUAL) {
return SKINNY_CODEC_H261;
- case AST_FORMAT_H263:
+ } else if (ast_format_cmp(astcodec, ast_format_h263) == AST_FORMAT_CMP_EQUAL) {
return SKINNY_CODEC_H263;
- default:
+ } else {
return 0;
}
}
@@ -2312,13 +2305,8 @@ static int skinny_register(struct skinny_req *req, struct skinnysession *s)
instance++;
}
AST_LIST_TRAVERSE(&d->lines, l, list) {
- ast_format_cap_joint_copy(l->confcap, d->cap, l->cap);
- l->prefs = l->confprefs;
- if (!l->prefs.order[0]) {
- l->prefs = d->confprefs;
- }
- /* l->capability = d->capability;
- l->prefs = d->prefs; */
+ ast_format_cap_get_compatible(l->confcap, d->cap, l->cap);
+ /* l->capability = d->capability; */
l->instance = instance;
l->newmsgs = ast_app_has_voicemail(l->mailbox, NULL);
set_callforwards(l, NULL, SKINNY_CFWD_ALL|SKINNY_CFWD_BUSY|SKINNY_CFWD_NOANSWER);
@@ -2656,23 +2644,27 @@ static void transmit_connect(struct skinny_device *d, struct skinny_subchannel *
{
struct skinny_req *req;
struct skinny_line *l = sub->line;
- struct ast_format_list fmt;
- struct ast_format tmpfmt;
+ struct ast_format *tmpfmt;
+ unsigned int framing;
if (!(req = req_alloc(sizeof(struct open_receive_channel_message), OPEN_RECEIVE_CHANNEL_MESSAGE)))
return;
- ast_best_codec(l->cap, &tmpfmt);
- fmt = ast_codec_pref_getsize(&l->prefs, &tmpfmt);
+
+ tmpfmt = ast_format_cap_get_format(l->cap, 0);
+ framing = ast_format_cap_get_format_framing(l->cap, tmpfmt);
req->data.openreceivechannel.conferenceId = htolel(sub->callid);
req->data.openreceivechannel.partyId = htolel(sub->callid);
- req->data.openreceivechannel.packets = htolel(fmt.cur_ms);
- req->data.openreceivechannel.capability = htolel(codec_ast2skinny(&fmt.format));
+ req->data.openreceivechannel.packets = htolel(framing);
+ req->data.openreceivechannel.capability = htolel(codec_ast2skinny(tmpfmt));
req->data.openreceivechannel.echo = htolel(0);
req->data.openreceivechannel.bitrate = htolel(0);
SKINNY_DEBUG(DEBUG_PACKET, 3, "Transmitting OPEN_RECEIVE_CHANNEL_MESSAGE to %s, confid %u, partyid %u, ms %d, fmt %d, echo %d, brate %d\n",
- d->name, sub->callid, sub->callid, fmt.cur_ms, codec_ast2skinny(&fmt.format), 0, 0);
+ d->name, sub->callid, sub->callid, framing, codec_ast2skinny(tmpfmt), 0, 0);
+
+ ao2_ref(tmpfmt, -1);
+
transmit_response(d, req);
}
@@ -3033,7 +3025,8 @@ static void transmit_stopmediatransmission(struct skinny_device *d, struct skinn
transmit_response(d, req);
}
-static void transmit_startmediatransmission(struct skinny_device *d, struct skinny_subchannel *sub, struct sockaddr_in dest, struct ast_format_list fmt)
+static void transmit_startmediatransmission(struct skinny_device *d, struct skinny_subchannel *sub, struct sockaddr_in dest,
+ struct ast_format *format, unsigned int framing)
{
struct skinny_req *req;
@@ -3044,8 +3037,8 @@ static void transmit_startmediatransmission(struct skinny_device *d, struct skin
req->data.startmedia_ip4.passThruPartyId = htolel(sub->callid);
req->data.startmedia_ip4.remoteIp = dest.sin_addr.s_addr;
req->data.startmedia_ip4.remotePort = htolel(ntohs(dest.sin_port));
- req->data.startmedia_ip4.packetSize = htolel(fmt.cur_ms);
- req->data.startmedia_ip4.payloadType = htolel(codec_ast2skinny(&fmt.format));
+ req->data.startmedia_ip4.packetSize = htolel(framing);
+ req->data.startmedia_ip4.payloadType = htolel(codec_ast2skinny(format));
req->data.startmedia_ip4.qualifier.precedence = htolel(127);
req->data.startmedia_ip4.qualifier.vad = htolel(0);
req->data.startmedia_ip4.qualifier.packets = htolel(0);
@@ -3057,8 +3050,8 @@ static void transmit_startmediatransmission(struct skinny_device *d, struct skin
req->data.startmedia_ip6.passThruPartyId = htolel(sub->callid);
memcpy(req->data.startmedia_ip6.remoteIp, &dest.sin_addr.s_addr, sizeof(dest.sin_addr.s_addr));
req->data.startmedia_ip6.remotePort = htolel(ntohs(dest.sin_port));
- req->data.startmedia_ip6.packetSize = htolel(fmt.cur_ms);
- req->data.startmedia_ip6.payloadType = htolel(codec_ast2skinny(&fmt.format));
+ req->data.startmedia_ip6.packetSize = htolel(framing);
+ req->data.startmedia_ip6.payloadType = htolel(codec_ast2skinny(format));
req->data.startmedia_ip6.qualifier.precedence = htolel(127);
req->data.startmedia_ip6.qualifier.vad = htolel(0);
req->data.startmedia_ip6.qualifier.packets = htolel(0);
@@ -3066,7 +3059,7 @@ static void transmit_startmediatransmission(struct skinny_device *d, struct skin
}
SKINNY_DEBUG(DEBUG_PACKET, 3, "Transmitting START_MEDIA_TRANSMISSION_MESSAGE to %s, callid %u, passthrupartyid %u, ip %s:%d, ms %d, fmt %d, prec 127\n",
- d->name, sub->callid, sub->callid, ast_inet_ntoa(dest.sin_addr), dest.sin_port, fmt.cur_ms, codec_ast2skinny(&fmt.format));
+ d->name, sub->callid, sub->callid, ast_inet_ntoa(dest.sin_addr), dest.sin_port, framing, codec_ast2skinny(format));
transmit_response(d, req);
}
@@ -3643,7 +3636,6 @@ static int skinny_set_rtp_peer(struct ast_channel *c, struct ast_rtp_instance *r
struct skinny_subchannel *sub;
struct skinny_line *l;
struct skinny_device *d;
- struct ast_format_list fmt;
struct sockaddr_in us = { 0, };
struct sockaddr_in them = { 0, };
struct ast_sockaddr them_tmp;
@@ -3662,7 +3654,8 @@ static int skinny_set_rtp_peer(struct ast_channel *c, struct ast_rtp_instance *r
d = l->device;
if (rtp){
- struct ast_format tmpfmt;
+ struct ast_format *tmpfmt;
+ unsigned int framing;
ast_rtp_instance_get_remote_address(rtp, &them_tmp);
ast_sockaddr_to_sin(&them_tmp, &them);
@@ -3671,20 +3664,22 @@ static int skinny_set_rtp_peer(struct ast_channel *c, struct ast_rtp_instance *r
SKINNY_DEBUG(DEBUG_AUDIO, 4, "Peerip = %s:%d\n", ast_inet_ntoa(them.sin_addr), ntohs(them.sin_port));
- ast_best_codec(l->cap, &tmpfmt);
- fmt = ast_codec_pref_getsize(&l->prefs, &tmpfmt);
+ tmpfmt = ast_format_cap_get_format(l->cap, 0);
+ framing = ast_format_cap_get_format_framing(l->cap, tmpfmt);
- SKINNY_DEBUG(DEBUG_AUDIO, 4, "Setting payloadType to '%s' (%d ms)\n", ast_getformatname(&fmt.format), fmt.cur_ms);
+ SKINNY_DEBUG(DEBUG_AUDIO, 4, "Setting payloadType to '%s' (%d ms)\n", ast_format_get_name(tmpfmt), framing);
if (!(l->directmedia) || (l->nat)){
ast_rtp_instance_get_local_address(rtp, &us_tmp);
ast_sockaddr_to_sin(&us_tmp, &us);
us.sin_addr.s_addr = us.sin_addr.s_addr ? us.sin_addr.s_addr : d->ourip.s_addr;
- transmit_startmediatransmission(d, sub, us, fmt);
+ transmit_startmediatransmission(d, sub, us, tmpfmt, framing);
} else {
- transmit_startmediatransmission(d, sub, them, fmt);
+ transmit_startmediatransmission(d, sub, them, tmpfmt, framing);
}
+ ao2_ref(tmpfmt, -1);
+
return 0;
}
/* Need a return here to break the bridge */
@@ -4067,25 +4062,6 @@ static char *device2str(int type)
}
}
-/*! \brief Print codec list from preference to CLI/manager */
-static void print_codec_to_cli(int fd, struct ast_codec_pref *pref)
-{
- int x;
- struct ast_format tmpfmt;
-
- for(x = 0; x < 32 ; x++) {
- ast_codec_pref_index(pref, x, &tmpfmt);
- if (!tmpfmt.id)
- break;
- ast_cli(fd, "%s", ast_getformatname(&tmpfmt));
- ast_cli(fd, ":%d", pref->framing[x]);
- if (x < 31 && ast_codec_pref_index(pref, x + 1, &tmpfmt))
- ast_cli(fd, ",");
- }
- if (!x)
- ast_cli(fd, "none");
-}
-
static char *_skinny_show_devices(int fd, int *total, struct mansession *s, const struct message *m, int argc, const char * const *argv)
{
struct skinny_device *d;
@@ -4204,7 +4180,7 @@ static char *_skinny_show_device(int type, int fd, struct mansession *s, const s
struct skinny_speeddial *sd;
struct skinny_addon *sa;
struct skinny_serviceurl *surl;
- char codec_buf[512];
+ struct ast_str *codec_buf = ast_str_alloca(64);
if (argc < 4) {
return CLI_SHOWUSAGE;
@@ -4238,12 +4214,8 @@ static char *_skinny_show_device(int type, int fd, struct mansession *s, const s
ast_cli(fd, "Ip address: %s\n", (d->session ? ast_inet_ntoa(d->session->sin.sin_addr) : "Unknown"));
ast_cli(fd, "Port: %d\n", (d->session ? ntohs(d->session->sin.sin_port) : 0));
ast_cli(fd, "Device Type: %s\n", device2str(d->type));
- ast_cli(fd, "Conf Codecs:");
- ast_getformatname_multiple(codec_buf, sizeof(codec_buf) - 1, d->confcap);
- ast_cli(fd, "%s\n", codec_buf);
- ast_cli(fd, "Neg Codecs: ");
- ast_getformatname_multiple(codec_buf, sizeof(codec_buf) - 1, d->cap);
- ast_cli(fd, "%s\n", codec_buf);
+ ast_cli(fd, "Conf Codecs: %s\n", ast_format_cap_get_names(d->confcap, &codec_buf));
+ ast_cli(fd, "Neg Codecs: %s\n", ast_format_cap_get_names(d->cap, &codec_buf));
ast_cli(fd, "Registered: %s\n", (d->session ? "Yes" : "No"));
ast_cli(fd, "Lines: %d\n", numlines);
AST_LIST_TRAVERSE(&d->lines, l, list) {
@@ -4270,12 +4242,8 @@ static char *_skinny_show_device(int type, int fd, struct mansession *s, const s
astman_append(s, "Ipaddress: %s\r\n", (d->session ? ast_inet_ntoa(d->session->sin.sin_addr) : "Unknown"));
astman_append(s, "Port: %d\r\n", (d->session ? ntohs(d->session->sin.sin_port) : 0));
astman_append(s, "DeviceType: %s\r\n", device2str(d->type));
- astman_append(s, "Codecs: ");
- ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, d->confcap);
- astman_append(s, "%s\r\n", codec_buf);
- astman_append(s, "CodecOrder: ");
- ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, d->cap);
- astman_append(s, "%s\r\n", codec_buf);
+ astman_append(s, "Codecs: %s\r\n", ast_format_cap_get_names(d->confcap, &codec_buf));
+ astman_append(s, "CodecOrder: %s\r\n", ast_format_cap_get_names(d->cap, &codec_buf));
astman_append(s, "Devicestatus: %s\r\n", (d->session?"registered":"unregistered"));
astman_append(s, "NumberOfLines: %d\r\n", numlines);
AST_LIST_TRAVERSE(&d->lines, l, list) {
@@ -4468,9 +4436,7 @@ static char *_skinny_show_line(int type, int fd, struct mansession *s, const str
struct skinny_device *d;
struct skinny_line *l;
struct skinny_subline *subline;
- struct ast_codec_pref *pref;
- int x = 0;
- char codec_buf[512];
+ struct ast_str *codec_buf = ast_str_alloca(64);
char group_buf[256];
char cbuf[256];
@@ -4536,15 +4502,8 @@ static char *_skinny_show_line(int type, int fd, struct mansession *s, const str
ast_cli(fd, "immediate: %s\n", (l->immediate ? "Yes" : "No"));
ast_cli(fd, "Group: %d\n", l->group);
ast_cli(fd, "Parkinglot: %s\n", S_OR(l->parkinglot, "<not set>"));
- ast_cli(fd, "Conf Codecs: ");
- ast_getformatname_multiple(codec_buf, sizeof(codec_buf) - 1, l->confcap);
- ast_cli(fd, "%s\n", codec_buf);
- ast_cli(fd, "Neg Codecs: ");
- ast_getformatname_multiple(codec_buf, sizeof(codec_buf) - 1, l->cap);
- ast_cli(fd, "%s\n", codec_buf);
- ast_cli(fd, "Codec Order: (");
- print_codec_to_cli(fd, &l->prefs);
- ast_cli(fd, ")\n");
+ ast_cli(fd, "Conf Codecs: %s\n", ast_format_cap_get_names(l->confcap, &codec_buf));
+ ast_cli(fd, "Neg Codecs: %s\n", ast_format_cap_get_names(l->cap, &codec_buf));
if (AST_LIST_FIRST(&l->sublines)) {
ast_cli(fd, "Sublines:\n");
AST_LIST_TRAVERSE(&l->sublines, subline, list) {
@@ -4592,19 +4551,7 @@ static char *_skinny_show_line(int type, int fd, struct mansession *s, const str
astman_append(s, "immediate: %s\r\n", (l->immediate ? "Yes" : "No"));
astman_append(s, "Group: %d\r\n", l->group);
astman_append(s, "Parkinglot: %s\r\n", S_OR(l->parkinglot, "<not set>"));
- ast_getformatname_multiple(codec_buf, sizeof(codec_buf) - 1, l->confcap);
- astman_append(s, "Codecs: %s\r\n", codec_buf);
- astman_append(s, "CodecOrder: ");
- pref = &l->prefs;
- for(x = 0; x < 32 ; x++) {
- struct ast_format tmpfmt;
- ast_codec_pref_index(pref, x, &tmpfmt);
- if (!tmpfmt.id)
- break;
- astman_append(s, "%s", ast_getformatname(&tmpfmt));
- if (x < 31 && ast_codec_pref_index(pref, x+1, &tmpfmt))
- astman_append(s, ",");
- }
+ astman_append(s, "Codecs: %s\r\n", ast_format_cap_get_names(l->confcap, &codec_buf));
astman_append(s, "\r\n");
}
}
@@ -4802,7 +4749,7 @@ static void start_rtp(struct skinny_subchannel *sub)
struct ast_sockaddr bindaddr_tmp;
skinny_locksub(sub);
- /* Allocate the RTP */
+ SKINNY_DEBUG(DEBUG_AUDIO, 3, "Sub %u - Starting RTP\n", sub->callid);
ast_sockaddr_from_sin(&bindaddr_tmp, &bindaddr);
sub->rtp = ast_rtp_instance_new("asterisk", sched, &bindaddr_tmp, NULL);
if (hasvideo)
@@ -4828,14 +4775,14 @@ static void start_rtp(struct skinny_subchannel *sub)
if (sub->rtp) {
ast_rtp_instance_set_qos(sub->rtp, qos.tos_audio, qos.cos_audio, "Skinny RTP");
ast_rtp_instance_set_prop(sub->rtp, AST_RTP_PROPERTY_NAT, l->nat);
+ /* Set frame packetization */
+ ast_rtp_codecs_set_framing(ast_rtp_instance_get_codecs(sub->rtp),
+ ast_format_cap_get_framing(l->cap));
}
if (sub->vrtp) {
ast_rtp_instance_set_qos(sub->vrtp, qos.tos_video, qos.cos_video, "Skinny VRTP");
ast_rtp_instance_set_prop(sub->vrtp, AST_RTP_PROPERTY_NAT, l->nat);
}
- /* Set Frame packetization */
- if (sub->rtp)
- ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(sub->rtp), sub->rtp, &l->prefs);
/* Create the RTP connection */
transmit_connect(d, sub);
@@ -5097,9 +5044,17 @@ static struct ast_frame *skinny_rtp_read(struct skinny_subchannel *sub)
if (ast) {
/* We already hold the channel lock */
if (f->frametype == AST_FRAME_VOICE) {
- if (!(ast_format_cap_iscompatible(ast_channel_nativeformats(ast), &f->subclass.format))) {
- ast_debug(1, "Oooh, format changed to %s\n", ast_getformatname(&f->subclass.format));
- ast_format_cap_set(ast_channel_nativeformats(ast), &f->subclass.format);
+ if (ast_format_cap_iscompatible_format(ast_channel_nativeformats(ast), f->subclass.format) == AST_FORMAT_CMP_NOT_EQUAL) {
+ struct ast_format_cap *caps;
+
+ ast_debug(1, "Oooh, format changed to %s\n", ast_format_get_name(f->subclass.format));
+
+ caps = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
+ if (caps) {
+ ast_format_cap_append(caps, f->subclass.format, 0);
+ ast_channel_nativeformats_set(ast, caps);
+ ao2_ref(caps, -1);
+ }
ast_set_read_format(ast, ast_channel_readformat(ast));
ast_set_write_format(ast, ast_channel_writeformat(ast));
}
@@ -5130,13 +5085,13 @@ static int skinny_write(struct ast_channel *ast, struct ast_frame *frame)
return 0;
}
} else {
- if (!(ast_format_cap_iscompatible(ast_channel_nativeformats(ast), &frame->subclass.format))) {
- char buf[256];
+ if (ast_format_cap_iscompatible_format(ast_channel_nativeformats(ast), frame->subclass.format) == AST_FORMAT_CMP_NOT_EQUAL) {
+ struct ast_str *codec_buf = ast_str_alloca(64);
ast_log(LOG_WARNING, "Asked to transmit frame type %s, while native formats is %s (read/write = %s/%s)\n",
- ast_getformatname(&frame->subclass.format),
- ast_getformatname_multiple(buf, sizeof(buf), ast_channel_nativeformats(ast)),
- ast_getformatname(ast_channel_readformat(ast)),
- ast_getformatname(ast_channel_writeformat(ast)));
+ ast_format_get_name(frame->subclass.format),
+ ast_format_cap_get_names(ast_channel_nativeformats(ast), &codec_buf),
+ ast_format_get_name(ast_channel_readformat(ast)),
+ ast_format_get_name(ast_channel_writeformat(ast)));
return -1;
}
}
@@ -5403,23 +5358,33 @@ static struct ast_channel *skinny_new(struct skinny_line *l, struct skinny_subli
struct skinny_subchannel *sub;
struct skinny_device *d = l->device;
struct ast_variable *v = NULL;
- struct ast_format tmpfmt;
+ struct ast_format *tmpfmt;
+ struct ast_format_cap *caps;
if (!l->device || !l->device->session) {
ast_log(LOG_WARNING, "Device for line %s is not registered.\n", l->name);
return NULL;
}
+ caps = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
+ if (!caps) {
+ return NULL;
+ }
+
tmp = ast_channel_alloc(1, state, l->cid_num, l->cid_name, l->accountcode, l->exten, l->context, assignedids, requestor, l->amaflags, "Skinny/%s@%s-%d", l->name, d->name, callnums);
if (!tmp) {
ast_log(LOG_WARNING, "Unable to allocate channel structure\n");
+ ao2_ref(caps, -1);
return NULL;
} else {
+ struct ast_str *codec_buf = ast_str_alloca(64);
+
sub = ast_calloc(1, sizeof(*sub));
if (!sub) {
ast_log(LOG_WARNING, "Unable to allocate Skinny subchannel\n");
ast_channel_unlock(tmp);
ast_channel_unref(tmp);
+ ao2_ref(caps, -1);
return NULL;
} else {
skinny_set_owner(sub, tmp);
@@ -5452,25 +5417,28 @@ static struct ast_channel *skinny_new(struct skinny_line *l, struct skinny_subli
ast_channel_stage_snapshot(tmp);
ast_channel_tech_set(tmp, &skinny_tech);
ast_channel_tech_pvt_set(tmp, sub);
- ast_format_cap_copy(ast_channel_nativeformats(tmp), l->cap);
- if (ast_format_cap_is_empty(ast_channel_nativeformats(tmp))) {
- // Should throw an error
- ast_format_cap_copy(ast_channel_nativeformats(tmp), default_cap);
+ if (!ast_format_cap_count(l->cap)) {
+ ast_format_cap_append_from_cap(caps, l->cap, AST_MEDIA_TYPE_UNKNOWN);
+ } else {
+ ast_format_cap_append_from_cap(caps, default_cap, AST_MEDIA_TYPE_UNKNOWN);
}
- ast_best_codec(ast_channel_nativeformats(tmp), &tmpfmt);
+ ast_channel_nativeformats_set(tmp, caps);
+ ao2_ref(caps, -1);
+ tmpfmt = ast_format_cap_get_format(ast_channel_nativeformats(tmp), 0);
SKINNY_DEBUG(DEBUG_SUB, 3, "skinny_new: tmp->nativeformats=%s fmt=%s\n",
- ast_getformatname_multiple(dbgsub_buf, sizeof(dbgsub_buf), ast_channel_nativeformats(tmp)),
- ast_getformatname(&tmpfmt));
+ ast_format_cap_get_names(ast_channel_nativeformats(tmp), &codec_buf),
+ ast_format_get_name(tmpfmt));
if (sub->rtp) {
ast_channel_set_fd(tmp, 0, ast_rtp_instance_fd(sub->rtp, 0));
}
if (state == AST_STATE_RING) {
ast_channel_rings_set(tmp, 1);
}
- ast_format_copy(ast_channel_writeformat(tmp), &tmpfmt);
- ast_format_copy(ast_channel_rawwriteformat(tmp), &tmpfmt);
- ast_format_copy(ast_channel_readformat(tmp), &tmpfmt);
- ast_format_copy(ast_channel_rawreadformat(tmp), &tmpfmt);
+ ast_channel_set_writeformat(tmp, tmpfmt);
+ ast_channel_set_rawwriteformat(tmp, tmpfmt);
+ ast_channel_set_readformat(tmp, tmpfmt);
+ ast_channel_set_rawreadformat(tmp, tmpfmt);
+ ao2_ref(tmpfmt, -1);
if (!ast_strlen_zero(l->language))
ast_channel_language_set(tmp, l->language);
@@ -6676,7 +6644,8 @@ static int handle_capabilities_res_message(struct skinny_req *req, struct skinny
struct skinny_device *d = s->device;
struct skinny_line *l;
uint32_t count = 0;
- struct ast_format_cap *codecs = ast_format_cap_alloc(0);
+ struct ast_format_cap *codecs = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
+ struct ast_str *codec_buf = ast_str_alloca(64);
int i;
if (!codecs) {
@@ -6690,23 +6659,23 @@ static int handle_capabilities_res_message(struct skinny_req *req, struct skinny
}
for (i = 0; i < count; i++) {
- struct ast_format acodec;
+ struct ast_format *acodec;
int scodec = 0;
scodec = letohl(req->data.caps.caps[i].codec);
- codec_skinny2ast(scodec, &acodec);
- SKINNY_DEBUG(DEBUG_AUDIO, 4, "Adding codec capability %s (%d)\n", ast_getformatname(&acodec), scodec);
- ast_format_cap_add(codecs, &acodec);
+ acodec = codec_skinny2ast(scodec);
+ SKINNY_DEBUG(DEBUG_AUDIO, 4, "Adding codec capability %s (%d)\n", ast_format_get_name(acodec), scodec);
+ ast_format_cap_append(codecs, acodec, 0);
}
- ast_format_cap_joint_copy(d->confcap, codecs, d->cap);
- SKINNY_DEBUG(DEBUG_AUDIO, 4, "Device capability set to '%s'\n", ast_getformatname_multiple(dbgreg_buf, sizeof(dbgreg_buf), d->cap));
+ ast_format_cap_get_compatible(d->confcap, codecs, d->cap);
+ SKINNY_DEBUG(DEBUG_AUDIO, 4, "Device capability set to '%s'\n", ast_format_cap_get_names(d->cap, &codec_buf));
AST_LIST_TRAVERSE(&d->lines, l, list) {
ast_mutex_lock(&l->lock);
- ast_format_cap_joint_copy(l->confcap, d->cap, l->cap);
+ ast_format_cap_get_compatible(l->confcap, d->cap, l->cap);
ast_mutex_unlock(&l->lock);
}
- codecs = ast_format_cap_destroy(codecs);
+ ao2_ref(codecs, -1);
return 1;
}
@@ -6877,16 +6846,16 @@ static int handle_open_receive_channel_ack_message(struct skinny_req *req, struc
struct skinny_device *d = s->device;
struct skinny_line *l;
struct skinny_subchannel *sub;
- struct ast_format_list fmt;
struct sockaddr_in sin = { 0, };
struct sockaddr_in us = { 0, };
struct ast_sockaddr sin_tmp;
struct ast_sockaddr us_tmp;
- struct ast_format tmpfmt;
+ struct ast_format *tmpfmt;
uint32_t addr;
int port;
int status;
int callid;
+ unsigned int framing;
status = (d->protocolversion<17) ? letohl(req->data.openreceivechannelack_ip4.status) : letohl(req->data.openreceivechannelack_ip6.status);
@@ -6937,12 +6906,14 @@ static int handle_open_receive_channel_ack_message(struct skinny_req *req, struc
SKINNY_DEBUG(DEBUG_PACKET, 4, "device ipaddr = %s:%d\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
SKINNY_DEBUG(DEBUG_PACKET, 4, "asterisk ipaddr = %s:%d\n", ast_inet_ntoa(us.sin_addr), ntohs(us.sin_port));
- ast_best_codec(l->cap, &tmpfmt);
- fmt = ast_codec_pref_getsize(&l->prefs, &tmpfmt);
+ tmpfmt = ast_format_cap_get_format(l->cap, 0);
+ framing = ast_format_cap_get_format_framing(l->cap, tmpfmt);
- SKINNY_DEBUG(DEBUG_PACKET, 4, "Setting payloadType to '%s' (%d ms)\n", ast_getformatname(&fmt.format), fmt.cur_ms);
+ SKINNY_DEBUG(DEBUG_PACKET, 4, "Setting payloadType to '%s' (%d ms)\n", ast_format_get_name(tmpfmt), framing);
- transmit_startmediatransmission(d, sub, us, fmt);
+ transmit_startmediatransmission(d, sub, us, tmpfmt, framing);
+
+ ao2_ref(tmpfmt, -1);
return 1;
}
@@ -7496,8 +7467,8 @@ static void skinny_session_cleanup(void *data)
if (l->device != d) {
continue;
}
- ast_format_cap_remove_all(l->cap);
- ast_parse_allow_disallow(&l->prefs, l->cap, "all", 0);
+ ast_format_cap_remove_by_type(l->cap, AST_MEDIA_TYPE_UNKNOWN);
+ ast_format_cap_update_by_allow_disallow(l->cap, "all", 0);
l->instance = 0;
unregister_exten(l);
ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "Skinny/%s", l->name);
@@ -7713,8 +7684,9 @@ static struct ast_channel *skinny_request(const char *type, struct ast_format_ca
struct ast_channel *tmpc = NULL;
char tmp[256];
- if (!(ast_format_cap_has_type(cap, AST_FORMAT_TYPE_AUDIO))) {
- ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%s'\n", ast_getformatname_multiple(tmp, sizeof(tmp), cap));
+ if (!(ast_format_cap_has_type(cap, AST_MEDIA_TYPE_AUDIO))) {
+ struct ast_str *codec_buf = ast_str_alloca(64);
+ ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%s'\n", ast_format_cap_get_names(cap, &codec_buf));
return NULL;
}
@@ -7870,10 +7842,10 @@ static void config_parse_variables(int type, void *item, struct ast_variable *vp
}
continue;
} else if (!strcasecmp(v->name, "allow")) {
- ast_parse_allow_disallow(&default_prefs, default_cap, v->value, 1);
+ ast_format_cap_update_by_allow_disallow(default_cap, v->value, 1);
continue;
} else if (!strcasecmp(v->name, "disallow")) {
- ast_parse_allow_disallow(&default_prefs, default_cap, v->value, 0);
+ ast_format_cap_update_by_allow_disallow(default_cap, v->value, 0);
continue;
}
}
@@ -8080,20 +8052,20 @@ static void config_parse_variables(int type, void *item, struct ast_variable *vp
}
} else if (!strcasecmp(v->name, "allow")) {
if (type & (TYPE_DEF_DEVICE | TYPE_DEVICE)) {
- ast_parse_allow_disallow(&CDEV->confprefs, CDEV->confcap, v->value, 1);
+ ast_format_cap_update_by_allow_disallow(CDEV->confcap, v->value, 1);
continue;
}
if (type & (TYPE_DEF_LINE | TYPE_LINE)) {
- ast_parse_allow_disallow(&CLINE->confprefs, CLINE->confcap, v->value, 1);
+ ast_format_cap_update_by_allow_disallow(CLINE->confcap, v->value, 1);
continue;
}
} else if (!strcasecmp(v->name, "disallow")) {
if (type & (TYPE_DEF_DEVICE | TYPE_DEVICE)) {
- ast_parse_allow_disallow(&CDEV->confprefs, CDEV->confcap, v->value, 0);
+ ast_format_cap_update_by_allow_disallow(CDEV->confcap, v->value, 0);
continue;
}
if (type & (TYPE_DEF_LINE | TYPE_LINE)) {
- ast_parse_allow_disallow(&CLINE->confprefs, CLINE->confcap, v->value, 0);
+ ast_format_cap_update_by_allow_disallow(CLINE->confcap, v->value, 0);
continue;
}
} else if (!strcasecmp(v->name, "version")) {
@@ -8303,7 +8275,7 @@ static struct skinny_line *config_line(const char *lname, struct ast_variable *v
memcpy(l, default_line, sizeof(*default_line));
ast_mutex_init(&l->lock);
ast_copy_string(l->name, lname, sizeof(l->name));
- ast_format_cap_copy(l->confcap, default_cap);
+ ast_format_cap_append_from_cap(l->confcap, default_cap, AST_MEDIA_TYPE_UNKNOWN);
AST_LIST_INSERT_TAIL(&lines, l, all);
ast_mutex_lock(&l->lock);
@@ -8362,7 +8334,7 @@ static struct skinny_device *config_device(const char *dname, struct ast_variabl
memcpy(d, default_device, sizeof(*default_device));
ast_mutex_init(&d->lock);
ast_copy_string(d->name, dname, sizeof(d->name));
- ast_format_cap_copy(d->confcap, default_cap);
+ ast_format_cap_append_from_cap(d->confcap, default_cap, AST_MEDIA_TYPE_UNKNOWN);
AST_LIST_INSERT_TAIL(&devices, d, list);
ast_mutex_lock(&d->lock);
@@ -8453,7 +8425,6 @@ static int config_load(void)
}
memset(&bindaddr, 0, sizeof(bindaddr));
- memset(&default_prefs, 0, sizeof(default_prefs));
immed_dialchar = '\0';
memset(&vmexten, '\0', sizeof(vmexten));
@@ -8482,7 +8453,6 @@ static int config_load(void)
bindaddr.sin_family = AF_INET;
/* load the lines sections */
- default_line->confprefs = default_prefs;
config_parse_variables(TYPE_DEF_LINE, default_line, ast_variable_browse(cfg, "lines"));
cat = ast_category_browse(cfg, "lines");
while (cat && strcasecmp(cat, "general") && strcasecmp(cat, "devices")) {
@@ -8491,7 +8461,6 @@ static int config_load(void)
}
/* load the devices sections */
- default_device->confprefs = default_prefs;
config_parse_variables(TYPE_DEF_DEVICE, default_device, ast_variable_browse(cfg, "devices"));
cat = ast_category_browse(cfg, "devices");
while (cat && strcasecmp(cat, "general") && strcasecmp(cat, "lines")) {
@@ -8678,17 +8647,18 @@ int skinny_reload(void)
static int load_module(void)
{
int res = 0;
- struct ast_format tmpfmt;
- if (!(default_cap = ast_format_cap_alloc(0))) {
+
+ if (!(default_cap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT))) {
return AST_MODULE_LOAD_DECLINE;
}
- if (!(skinny_tech.capabilities = ast_format_cap_alloc(0))) {
+ if (!(skinny_tech.capabilities = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT))) {
+ ao2_ref(default_cap, -1);
return AST_MODULE_LOAD_DECLINE;
}
- ast_format_cap_add_all_by_type(skinny_tech.capabilities, AST_FORMAT_TYPE_AUDIO);
- ast_format_cap_add(default_cap, ast_format_set(&tmpfmt, AST_FORMAT_ULAW, 0));
- ast_format_cap_add(default_cap, ast_format_set(&tmpfmt, AST_FORMAT_ALAW, 0));
+ ast_format_cap_append_by_type(skinny_tech.capabilities, AST_MEDIA_TYPE_AUDIO);
+ ast_format_cap_append(default_cap, ast_format_ulaw, 0);
+ ast_format_cap_append(default_cap, ast_format_alaw, 0);
for (; res < ARRAY_LEN(soft_key_template_default); res++) {
soft_key_template_default[res].softKeyEvent = htolel(soft_key_template_default[res].softKeyEvent);
@@ -8696,11 +8666,23 @@ static int load_module(void)
/* load and parse config */
res = config_load();
if (res == -1) {
+ ao2_ref(skinny_tech.capabilities, -1);
+ ao2_ref(default_cap, -1);
return AST_MODULE_LOAD_DECLINE;
}
+ sched = ast_sched_context_create();
+ if (!sched) {
+ ao2_ref(skinny_tech.capabilities, -1);
+ ao2_ref(default_cap, -1);
+ ast_log(LOG_WARNING, "Unable to create schedule context\n");
+ return AST_MODULE_LOAD_FAILURE;
+ }
+
/* Make sure we can register our skinny channel type */
if (ast_channel_register(&skinny_tech)) {
+ ao2_ref(default_cap, -1);
+ ao2_ref(skinny_tech.capabilities, -1);
ast_log(LOG_ERROR, "Unable to register channel class 'Skinny'\n");
return -1;
}
@@ -8713,14 +8695,12 @@ static int load_module(void)
ast_manager_register_xml("SKINNYlines", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_skinny_show_lines);
ast_manager_register_xml("SKINNYshowline", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_skinny_show_line);
- sched = ast_sched_context_create();
- if (!sched) {
- ast_log(LOG_WARNING, "Unable to create schedule context\n");
- return AST_MODULE_LOAD_FAILURE;
- }
if (ast_sched_start_thread(sched)) {
ast_sched_context_destroy(sched);
sched = NULL;
+ ast_channel_unregister(&skinny_tech);
+ ao2_ref(default_cap, -1);
+ ao2_ref(skinny_tech.capabilities, -1);
return AST_MODULE_LOAD_FAILURE;
}
@@ -8738,6 +8718,7 @@ static int unload_module(void)
ast_rtp_glue_unregister(&skinny_rtp_glue);
ast_channel_unregister(&skinny_tech);
+ ao2_cleanup(skinny_tech.capabilities);
ast_cli_unregister_multiple(cli_skinny, ARRAY_LEN(cli_skinny));
ast_manager_unregister("SKINNYdevices");
@@ -8797,8 +8778,7 @@ static int unload_module(void)
if (con)
ast_context_destroy(con, "Skinny");
- default_cap = ast_format_cap_destroy(default_cap);
- skinny_tech.capabilities = ast_format_cap_destroy(skinny_tech.capabilities);
+ ao2_ref(default_cap, -1);
return 0;
}
diff --git a/channels/chan_unistim.c b/channels/chan_unistim.c
index 7525f3921..3f6fd01c8 100644
--- a/channels/chan_unistim.c
+++ b/channels/chan_unistim.c
@@ -78,6 +78,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/features_config.h"
#include "asterisk/bridge.h"
#include "asterisk/stasis_channels.h"
+#include "asterisk/format_cache.h"
#define DEFAULTCONTEXT "default"
#define DEFAULTCALLERID "Unknown"
@@ -1933,7 +1934,7 @@ static void unistim_line_copy(struct unistim_line *dst, struct unistim_line *src
struct ast_format_cap *tmp = src->cap;
memcpy(dst, src, sizeof(*dst)); /* this over writes the cap ptr, so we have to reset it */
src->cap = tmp;
- ast_format_cap_copy(src->cap, dst->cap);
+ ast_format_cap_append_from_cap(src->cap, dst->cap, AST_MEDIA_TYPE_UNKNOWN);
}
static struct unistim_line *unistim_line_destroy(struct unistim_line *l)
@@ -1941,7 +1942,7 @@ static struct unistim_line *unistim_line_destroy(struct unistim_line *l)
if (!l) {
return NULL;
}
- l->cap = ast_format_cap_destroy(l->cap);
+ ao2_ref(l->cap, -1);
ast_free(l);
return NULL;
}
@@ -1953,7 +1954,7 @@ static struct unistim_line *unistim_line_alloc(void)
return NULL;
}
- if (!(l->cap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_NOLOCK))) {
+ if (!(l->cap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT))) {
ast_free(l);
return NULL;
}
@@ -2699,15 +2700,15 @@ static void send_start_rtp(struct unistim_subchannel *sub)
if (unistimdebug) {
ast_verb(0, "RTP started : Our IP/port is : %s:%hd with codec %s\n",
ast_inet_ntoa(us.sin_addr),
- htons(us.sin_port), ast_getformatname(ast_channel_readformat(sub->owner)));
+ htons(us.sin_port), ast_format_get_name(ast_channel_readformat(sub->owner)));
ast_verb(0, "Starting phone RTP stack. Our public IP is %s\n",
ast_inet_ntoa(public.sin_addr));
}
pte = sub->parent->parent->session;
codec = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(sub->rtp), 1, ast_channel_readformat(sub->owner), 0);
- if ((ast_channel_readformat(sub->owner)->id == AST_FORMAT_ULAW) ||
- (ast_channel_readformat(sub->owner)->id == AST_FORMAT_ALAW)) {
+ if ((ast_format_cmp(ast_channel_readformat(sub->owner), ast_format_ulaw) == AST_FORMAT_CMP_EQUAL) ||
+ (ast_format_cmp(ast_channel_readformat(sub->owner), ast_format_alaw) == AST_FORMAT_CMP_EQUAL)) {
if (unistimdebug) {
ast_verb(0, "Sending packet_send_rtp_packet_size for codec %d\n", codec);
}
@@ -2804,17 +2805,17 @@ static void send_start_rtp(struct unistim_subchannel *sub)
/* Codec */
buffsend[40] = codec;
buffsend[41] = codec;
- if (ast_channel_readformat(sub->owner)->id == AST_FORMAT_ULAW) {
+ if (ast_format_cmp(ast_channel_readformat(sub->owner), ast_format_ulaw) == AST_FORMAT_CMP_EQUAL) {
buffsend[42] = 1; /* 1 = 20ms (160 bytes), 2 = 40ms (320 bytes) */
- } else if (ast_channel_readformat(sub->owner)->id == AST_FORMAT_ALAW) {
+ } else if (ast_format_cmp(ast_channel_readformat(sub->owner), ast_format_alaw) == AST_FORMAT_CMP_EQUAL) {
buffsend[42] = 1; /* 1 = 20ms (160 bytes), 2 = 40ms (320 bytes) */
- } else if (ast_channel_readformat(sub->owner)->id == AST_FORMAT_G723_1) {
+ } else if (ast_format_cmp(ast_channel_readformat(sub->owner), ast_format_g723) == AST_FORMAT_CMP_EQUAL) {
buffsend[42] = 2; /* 1 = 30ms (24 bytes), 2 = 60 ms (48 bytes) */
- } else if (ast_channel_readformat(sub->owner)->id == AST_FORMAT_G729A) {
+ } else if (ast_format_cmp(ast_channel_readformat(sub->owner), ast_format_g729) == AST_FORMAT_CMP_EQUAL) {
buffsend[42] = 2; /* 1 = 10ms (10 bytes), 2 = 20ms (20 bytes) */
} else {
ast_log(LOG_WARNING, "Unsupported codec %s!\n",
- ast_getformatname(ast_channel_readformat(sub->owner)));
+ ast_format_get_name(ast_channel_readformat(sub->owner)));
}
/* Source port for transmit RTP and Destination port for receiving RTP */
buffsend[45] = (htons(sin.sin_port) & 0xff00) >> 8;
@@ -2883,18 +2884,20 @@ static void start_rtp(struct unistim_subchannel *sub)
sin.sin_port = htons(find_rtp_port(sub));
ast_sockaddr_from_sin(&sin_tmp, &sin);
ast_rtp_instance_set_remote_address(sub->rtp, &sin_tmp);
- if (!ast_format_cap_iscompatible(ast_channel_nativeformats(sub->owner), ast_channel_readformat(sub->owner))) {
- struct ast_format tmpfmt;
- char tmp[256];
- ast_best_codec(ast_channel_nativeformats(sub->owner), &tmpfmt);
+ if (ast_format_cap_iscompatible_format(ast_channel_nativeformats(sub->owner), ast_channel_readformat(sub->owner)) == AST_FORMAT_CMP_NOT_EQUAL) {
+ struct ast_format *tmpfmt;
+ struct ast_str *cap_buf = ast_str_alloca(64);
+
+ tmpfmt = ast_format_cap_get_format(ast_channel_nativeformats(sub->owner), 0);
ast_log(LOG_WARNING,
"Our read/writeformat has been changed to something incompatible: %s, using %s best codec from %s\n",
- ast_getformatname(ast_channel_readformat(sub->owner)),
- ast_getformatname(&tmpfmt),
- ast_getformatname_multiple(tmp, sizeof(tmp), ast_channel_nativeformats(sub->owner)));
+ ast_format_get_name(ast_channel_readformat(sub->owner)),
+ ast_format_get_name(tmpfmt),
+ ast_format_cap_get_names(ast_channel_nativeformats(sub->owner), &cap_buf));
- ast_format_copy(ast_channel_readformat(sub->owner), &tmpfmt);
- ast_format_copy(ast_channel_writeformat(sub->owner), &tmpfmt);
+ ast_channel_set_readformat(sub->owner, tmpfmt);
+ ast_channel_set_writeformat(sub->owner, tmpfmt);
+ ao2_ref(tmpfmt, -1);
}
send_start_rtp(sub);
ast_mutex_unlock(&sub->lock);
@@ -5132,14 +5135,21 @@ static struct ast_frame *unistim_rtp_read(const struct ast_channel *ast,
if (sub->owner) {
/* We already hold the channel lock */
if (f->frametype == AST_FRAME_VOICE) {
- if (!(ast_format_cap_iscompatible(ast_channel_nativeformats(sub->owner), &f->subclass.format))) {
- char tmp[256];
+ if (ast_format_cap_iscompatible_format(ast_channel_nativeformats(sub->owner), f->subclass.format) == AST_FORMAT_CMP_NOT_EQUAL) {
+ struct ast_str *cap_buf = ast_str_alloca(64);
+ struct ast_format_cap *caps;
+
ast_debug(1,
"Oooh, format changed from %s to %s\n",
- ast_getformatname_multiple(tmp, sizeof(tmp), ast_channel_nativeformats(sub->owner)),
- ast_getformatname(&f->subclass.format));
-
- ast_format_cap_set(ast_channel_nativeformats(sub->owner), &f->subclass.format);
+ ast_format_cap_get_names(ast_channel_nativeformats(sub->owner), &cap_buf),
+ ast_format_get_name(f->subclass.format));
+
+ caps = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
+ if (caps) {
+ ast_format_cap_append(caps, f->subclass.format, 0);
+ ast_channel_nativeformats_set(sub->owner, caps);
+ ao2_ref(caps, -1);
+ }
ast_set_read_format(sub->owner, ast_channel_readformat(sub->owner));
ast_set_write_format(sub->owner, ast_channel_writeformat(sub->owner));
}
@@ -5175,14 +5185,15 @@ static int unistim_write(struct ast_channel *ast, struct ast_frame *frame)
return 0;
}
} else {
- if (!(ast_format_cap_iscompatible(ast_channel_nativeformats(ast), &frame->subclass.format))) {
- char tmp[256];
+ if (ast_format_cap_iscompatible_format(ast_channel_nativeformats(ast), frame->subclass.format) == AST_FORMAT_CMP_NOT_EQUAL) {
+ struct ast_str *cap_buf = ast_str_alloca(64);
+
ast_log(LOG_WARNING,
"Asked to transmit frame type %s, while native formats is %s (read/write = (%s/%s)\n",
- ast_getformatname(&frame->subclass.format),
- ast_getformatname_multiple(tmp, sizeof(tmp), ast_channel_nativeformats(ast)),
- ast_getformatname(ast_channel_readformat(ast)),
- ast_getformatname(ast_channel_writeformat(ast)));
+ ast_format_get_name(frame->subclass.format),
+ ast_format_cap_get_names(ast_channel_nativeformats(ast), &cap_buf),
+ ast_format_get_name(ast_channel_readformat(ast)),
+ ast_format_get_name(ast_channel_writeformat(ast)));
return -1;
}
}
@@ -5661,9 +5672,10 @@ static int unistim_send_mwi_to_peer(struct unistim_line *peer, unsigned int tick
/* called from unistim_request (calls from the pbx ) */
static struct ast_channel *unistim_new(struct unistim_subchannel *sub, int state, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor)
{
+ struct ast_format_cap *caps;
struct ast_channel *tmp;
struct unistim_line *l;
- struct ast_format tmpfmt;
+ struct ast_format *tmpfmt;
if (!sub) {
ast_log(LOG_WARNING, "subchannel null in unistim_new\n");
@@ -5673,6 +5685,12 @@ static struct ast_channel *unistim_new(struct unistim_subchannel *sub, int state
ast_log(LOG_WARNING, "no line for subchannel %p\n", sub);
return NULL;
}
+
+ caps = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
+ if (!caps) {
+ return NULL;
+ }
+
l = sub->parent;
tmp = ast_channel_alloc(1, state, l->cid_num, NULL, l->accountcode, l->exten,
l->parent->context, assignedids, requestor, l->amaflags, "USTM/%s@%s-%p", l->name, l->parent->name, sub);
@@ -5681,24 +5699,32 @@ static struct ast_channel *unistim_new(struct unistim_subchannel *sub, int state
}
if (!tmp) {
ast_log(LOG_WARNING, "Unable to allocate channel structure\n");
+ ao2_ref(caps, -1);
return NULL;
}
ast_channel_stage_snapshot(tmp);
- ast_format_cap_copy(ast_channel_nativeformats(tmp), l->cap);
- if (ast_format_cap_is_empty(ast_channel_nativeformats(tmp))) {
- ast_format_cap_copy(ast_channel_nativeformats(tmp), global_cap);
+ if (ast_format_cap_count(l->cap)) {
+ ast_format_cap_append_from_cap(caps, l->cap, AST_MEDIA_TYPE_UNKNOWN);
+ } else {
+ ast_format_cap_append_from_cap(caps, global_cap, AST_MEDIA_TYPE_UNKNOWN);
}
- ast_best_codec(ast_channel_nativeformats(tmp), &tmpfmt);
+ ast_channel_nativeformats_set(tmp, caps);
+ ao2_ref(caps, -1);
+
+ tmpfmt = ast_format_cap_get_format(ast_channel_nativeformats(tmp), 0);
if (unistimdebug) {
- char tmp1[256], tmp2[256], tmp3[256];
+ struct ast_str *native_buf = ast_str_alloca(64);
+ struct ast_str *cap_buf = ast_str_alloca(64);
+ struct ast_str *global_buf = ast_str_alloca(64);
+
ast_verb(0, "Best codec = %s from nativeformats %s (line cap=%s global=%s)\n",
- ast_getformatname(&tmpfmt),
- ast_getformatname_multiple(tmp1, sizeof(tmp1), ast_channel_nativeformats(tmp)),
- ast_getformatname_multiple(tmp2, sizeof(tmp2), l->cap),
- ast_getformatname_multiple(tmp3, sizeof(tmp3), global_cap));
+ ast_format_get_name(tmpfmt),
+ ast_format_cap_get_names(ast_channel_nativeformats(tmp), &native_buf),
+ ast_format_cap_get_names(l->cap, &cap_buf),
+ ast_format_cap_get_names(global_cap, &global_buf));
}
if ((sub->rtp) && (sub->subtype == 0)) {
if (unistimdebug) {
@@ -5716,10 +5742,13 @@ static struct ast_channel *unistim_new(struct unistim_subchannel *sub, int state
ast_channel_rings_set(tmp, 1);
}
ast_channel_adsicpe_set(tmp, AST_ADSI_UNAVAILABLE);
- ast_format_copy(ast_channel_writeformat(tmp), &tmpfmt);
- ast_format_copy(ast_channel_rawwriteformat(tmp), &tmpfmt);
- ast_format_copy(ast_channel_readformat(tmp), &tmpfmt);
- ast_format_copy(ast_channel_rawreadformat(tmp), &tmpfmt);
+
+ ast_channel_set_writeformat(tmp, tmpfmt);
+ ast_channel_set_rawwriteformat(tmp, tmpfmt);
+ ast_channel_set_readformat(tmp, tmpfmt);
+ ast_channel_set_rawreadformat(tmp, tmpfmt);
+ ao2_ref(tmpfmt, -1);
+
ast_channel_tech_pvt_set(tmp, sub);
ast_channel_tech_set(tmp, &unistim_tech);
@@ -5900,12 +5929,14 @@ static struct ast_channel *unistim_request(const char *type, struct ast_format_c
struct unistim_device *d;
struct ast_channel *tmpc = NULL;
char tmp[256];
- char tmp2[256];
- if (!(ast_format_cap_has_joint(cap, global_cap))) {
+ if (!(ast_format_cap_iscompatible(cap, global_cap))) {
+ struct ast_str *cap_buf = ast_str_alloca(64);
+ struct ast_str *global_buf = ast_str_alloca(64);
ast_log(LOG_NOTICE,
"Asked to get a channel of unsupported format %s while capability is %s\n",
- ast_getformatname_multiple(tmp2, sizeof(tmp2), cap), ast_getformatname_multiple(tmp, sizeof(tmp), global_cap));
+ ast_format_cap_get_names(cap, &cap_buf),
+ ast_format_cap_get_names(global_cap, &global_buf));
return NULL;
}
@@ -5956,7 +5987,8 @@ static struct ast_channel *unistim_request(const char *type, struct ast_format_c
}
sub->subtype = SUB_RING;
sub->softkey = -1;
- ast_format_cap_copy(sub->parent->cap, cap);
+
+ ast_format_cap_append_from_cap(sub->parent->cap, cap, AST_MEDIA_TYPE_UNKNOWN);
tmpc = unistim_new(sub, AST_STATE_DOWN, assignedids, requestor);
if (!tmpc) {
ast_log(LOG_WARNING, "Unable to make channel for '%s'\n", tmp);
@@ -5975,6 +6007,7 @@ static char *unistim_show_info(struct ast_cli_entry *e, int cmd, struct ast_cli_
struct unistim_line *line;
struct unistim_subchannel *sub;
struct unistimsession *s;
+ struct ast_str *cap_buf = ast_str_alloca(64);
switch (cmd) {
case CLI_INIT:
@@ -6005,11 +6038,10 @@ static char *unistim_show_info(struct ast_cli_entry *e, int cmd, struct ast_cli_
device, device->selected, device->height);
AST_LIST_LOCK(&device->lines);
AST_LIST_TRAVERSE(&device->lines,line,list) {
- char tmp2[256];
ast_cli(a->fd,
"->name=%s fullname=%s exten=%s callid=%s cap=%s line=%p\n",
line->name, line->fullname, line->exten, line->cid_num,
- ast_getformatname_multiple(tmp2, sizeof(tmp2), line->cap), line);
+ ast_format_cap_get_names(line->cap, &cap_buf), line);
}
AST_LIST_UNLOCK(&device->lines);
@@ -6595,7 +6627,7 @@ static struct unistim_device *build_device(const char *cat, const struct ast_var
ast_verb(3, "Setting mailbox '%s' on %s@%s\n", l->mailbox, d->name, l->name);
}
}
- ast_format_cap_copy(l->cap, global_cap);
+ ast_format_cap_append_from_cap(l->cap, global_cap, AST_MEDIA_TYPE_UNKNOWN);
l->parent = d;
linecnt++;
AST_LIST_LOCK(&d->lines);
@@ -7011,17 +7043,18 @@ static struct ast_rtp_glue unistim_rtp_glue = {
int load_module(void)
{
int res;
- struct ast_format tmpfmt;
- if (!(global_cap = ast_format_cap_alloc(0))) {
+
+ if (!(global_cap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT))) {
goto buff_failed;
}
- if (!(unistim_tech.capabilities = ast_format_cap_alloc(0))) {
+ if (!(unistim_tech.capabilities = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT))) {
goto buff_failed;
}
- ast_format_cap_add(global_cap, ast_format_set(&tmpfmt, AST_FORMAT_ULAW, 0));
- ast_format_cap_add(global_cap, ast_format_set(&tmpfmt, AST_FORMAT_ALAW, 0));
- ast_format_cap_copy(unistim_tech.capabilities, global_cap);
+ ast_format_cap_append(global_cap, ast_format_ulaw, 0);
+ ast_format_cap_append(global_cap, ast_format_alaw, 0);
+ ast_format_cap_append_from_cap(unistim_tech.capabilities, global_cap, AST_MEDIA_TYPE_AUDIO);
+
if (!(buff = ast_malloc(SIZE_PAGE))) {
goto buff_failed;
}
@@ -7040,6 +7073,10 @@ int load_module(void)
res = reload_config();
if (res) {
+ ao2_ref(unistim_tech.capabilities, -1);
+ ao2_ref(global_cap, -1);
+ ast_sched_context_destroy(sched);
+ io_context_destroy(io);
return AST_MODULE_LOAD_DECLINE;
}
/* Make sure we can register our unistim channel type */
@@ -7066,9 +7103,11 @@ sched_failed:
io_failed:
ast_free(buff);
buff = NULL;
- global_cap = ast_format_cap_destroy(global_cap);
- unistim_tech.capabilities = ast_format_cap_destroy(unistim_tech.capabilities);
buff_failed:
+ ao2_cleanup(global_cap);
+ global_cap = NULL;
+ ao2_cleanup(unistim_tech.capabilities);
+ unistim_tech.capabilities = NULL;
return AST_MODULE_LOAD_FAILURE;
}
@@ -7082,6 +7121,7 @@ static int unload_module(void)
ast_cli_unregister_multiple(unistim_cli, ARRAY_LEN(unistim_cli));
ast_channel_unregister(&unistim_tech);
+ ao2_cleanup(unistim_tech.capabilities);
ast_rtp_glue_unregister(&unistim_rtp_glue);
ast_mutex_lock(&monlock);
@@ -7099,8 +7139,7 @@ static int unload_module(void)
if (unistimsock > -1) {
close(unistimsock);
}
- global_cap = ast_format_cap_destroy(global_cap);
- unistim_tech.capabilities = ast_format_cap_destroy(unistim_tech.capabilities);
+ ao2_ref(global_cap, -1);
return 0;
}
diff --git a/channels/chan_vpb.cc b/channels/chan_vpb.cc
index f1a45ab63..181e50aee 100644
--- a/channels/chan_vpb.cc
+++ b/channels/chan_vpb.cc
@@ -71,6 +71,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/dsp.h"
#include "asterisk/features.h"
#include "asterisk/musiconhold.h"
+#include "asterisk/format_cache.h"
}
#include <sys/socket.h>
@@ -766,11 +767,10 @@ static void get_callerid_ast(struct vpb_pvt *p)
#endif
vpb_record_buf_start(p->handle, VPB_MULAW);
while ((rc == 0) && (sam_count < 8000 * 3)) {
- struct ast_format tmpfmt;
vrc = vpb_record_buf_sync(p->handle, (char*)buf, sizeof(buf));
if (vrc != VPB_OK)
ast_log(LOG_ERROR, "%s: Caller ID couldn't read audio buffer!\n", p->dev);
- rc = callerid_feed(cs, (unsigned char *)buf, sizeof(buf), ast_format_set(&tmpfmt, AST_FORMAT_ULAW, 0));
+ rc = callerid_feed(cs, (unsigned char *)buf, sizeof(buf), ast_format_ulaw);
#ifdef ANALYSE_CID
vpb_wave_write(ws, (char *)buf, sizeof(buf));
#endif
@@ -2070,46 +2070,41 @@ static struct ast_frame *vpb_read(struct ast_channel *ast)
static inline AudioCompress ast2vpbformat(struct ast_format *format)
{
- switch (format->id) {
- case AST_FORMAT_ALAW:
+ if (ast_format_cmp(format, ast_format_alaw) == AST_FORMAT_CMP_EQUAL) {
return VPB_ALAW;
- case AST_FORMAT_SLINEAR:
+ } else if (ast_format_cmp(format, ast_format_slin) == AST_FORMAT_CMP_EQUAL) {
return VPB_LINEAR;
- case AST_FORMAT_ULAW:
+ } else if (ast_format_cmp(format, ast_format_ulaw) == AST_FORMAT_CMP_EQUAL) {
return VPB_MULAW;
- case AST_FORMAT_ADPCM:
+ } else if (ast_format_cmp(format, ast_format_adpcm) == AST_FORMAT_CMP_EQUAL) {
return VPB_OKIADPCM;
- default:
+ } else {
return VPB_RAW;
}
}
static inline const char * ast2vpbformatname(struct ast_format *format)
{
- switch(format->id) {
- case AST_FORMAT_ALAW:
+ if (ast_format_cmp(format, ast_format_alaw) == AST_FORMAT_CMP_EQUAL) {
return "AST_FORMAT_ALAW:VPB_ALAW";
- case AST_FORMAT_SLINEAR:
+ } else if (ast_format_cmp(format, ast_format_slin) == AST_FORMAT_CMP_EQUAL) {
return "AST_FORMAT_SLINEAR:VPB_LINEAR";
- case AST_FORMAT_ULAW:
+ } else if (ast_format_cmp(format, ast_format_ulaw) == AST_FORMAT_CMP_EQUAL) {
return "AST_FORMAT_ULAW:VPB_MULAW";
- case AST_FORMAT_ADPCM:
+ } else if (ast_format_cmp(format, ast_format_adpcm) == AST_FORMAT_CMP_EQUAL) {
return "AST_FORMAT_ADPCM:VPB_OKIADPCM";
- default:
+ } else {
return "UNKN:UNKN";
}
}
static inline int astformatbits(struct ast_format *format)
{
- switch (format->id) {
- case AST_FORMAT_SLINEAR:
+ if (ast_format_cmp(format, ast_format_slin) == AST_FORMAT_CMP_EQUAL) {
return 16;
- case AST_FORMAT_ADPCM:
+ } else if (ast_format_cmp(format, ast_format_adpcm) == AST_FORMAT_CMP_EQUAL) {
return 4;
- case AST_FORMAT_ALAW:
- case AST_FORMAT_ULAW:
- default:
+ } else {
return 8;
}
}
@@ -2146,7 +2141,8 @@ static int vpb_write(struct ast_channel *ast, struct ast_frame *frame)
/* ast_mutex_unlock(&p->lock); */
return 0;
} else if (ast_channel_state(ast) != AST_STATE_UP) {
- ast_verb(4, "%s: vpb_write: Attempt to Write frame type[%d]subclass[%s] on not up chan(state[%d])\n", ast_channel_name(ast), frame->frametype, ast_getformatname(&frame->subclass.format), ast_channel_state(ast));
+ ast_verb(4, "%s: vpb_write: Attempt to Write frame type[%d]subclass[%s] on not up chan(state[%d])\n",
+ ast_channel_name(ast), frame->frametype, ast_format_get_name(frame->subclass.format), ast_channel_state(ast));
p->lastoutput = -1;
/* ast_mutex_unlock(&p->lock); */
return 0;
@@ -2154,9 +2150,10 @@ static int vpb_write(struct ast_channel *ast, struct ast_frame *frame)
/* ast_debug(1, "%s: vpb_write: Checked frame type..\n", p->dev); */
- fmt = ast2vpbformat(&frame->subclass.format);
+ fmt = ast2vpbformat(frame->subclass.format);
if (fmt < 0) {
- ast_log(LOG_WARNING, "%s: vpb_write: Cannot handle frames of %s format!\n", ast_channel_name(ast), ast_getformatname(&frame->subclass.format));
+ ast_log(LOG_WARNING, "%s: vpb_write: Cannot handle frames of %s format!\n", ast_channel_name(ast),
+ ast_format_get_name(frame->subclass.format));
return -1;
}
@@ -2180,7 +2177,7 @@ static int vpb_write(struct ast_channel *ast, struct ast_frame *frame)
/* Check if we have set up the play_buf */
if (p->lastoutput == -1) {
vpb_play_buf_start(p->handle, fmt);
- ast_verb(2, "%s: vpb_write: Starting play mode (codec=%d)[%s]\n", p->dev, fmt, ast2vpbformatname(&frame->subclass.format));
+ ast_verb(2, "%s: vpb_write: Starting play mode (codec=%d)[%s]\n", p->dev, fmt, ast2vpbformatname(frame->subclass.format));
p->lastoutput = fmt;
ast_mutex_unlock(&p->play_lock);
return 0;
@@ -2230,7 +2227,7 @@ static void *do_chanreads(void *pvt)
struct ast_frame *fr = &p->fr;
char *readbuf = ((char *)p->buf) + AST_FRIENDLY_OFFSET;
int bridgerec = 0;
- struct ast_format tmpfmt;
+ struct ast_format *tmpfmt;
int readlen, res, trycnt=0;
AudioCompress fmt;
int ignore_dtmf;
@@ -2315,22 +2312,22 @@ static void *do_chanreads(void *pvt)
ast_mutex_unlock(&p->play_dtmf_lock);
if (p->owner) {
- ast_format_copy(&tmpfmt, ast_channel_rawreadformat(p->owner));
+ tmpfmt = ast_channel_rawreadformat(p->owner);
} else {
- ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR, 0);
+ tmpfmt = ast_format_slin;
}
- fmt = ast2vpbformat(&tmpfmt);
+ fmt = ast2vpbformat(tmpfmt);
if (fmt < 0) {
- ast_log(LOG_WARNING, "%s: Record failure (unsupported format %s)\n", p->dev, ast_getformatname(&tmpfmt));
+ ast_log(LOG_WARNING, "%s: Record failure (unsupported format %s)\n", p->dev, ast_format_get_name(tmpfmt));
return NULL;
}
- readlen = VPB_SAMPLES * astformatbits(&tmpfmt) / 8;
+ readlen = VPB_SAMPLES * astformatbits(tmpfmt) / 8;
if (p->lastinput == -1) {
vpb_record_buf_start(p->handle, fmt);
/* vpb_reset_record_fifo_alarm(p->handle); */
p->lastinput = fmt;
- ast_verb(2, "%s: Starting record mode (codec=%d)[%s]\n", p->dev, fmt, ast2vpbformatname(&tmpfmt));
+ ast_verb(2, "%s: Starting record mode (codec=%d)[%s]\n", p->dev, fmt, ast2vpbformatname(tmpfmt));
continue;
} else if (p->lastinput != fmt) {
vpb_record_buf_finish(p->handle);
@@ -2349,7 +2346,7 @@ static void *do_chanreads(void *pvt)
a_gain_vector(p->rxswgain - MAX_VPB_GAIN, (short *)readbuf, readlen / sizeof(short));
ast_verb(6, "%s: chanreads: applied gain\n", p->dev);
- ast_format_copy(&fr->subclass.format, &tmpfmt);
+ fr->subclass.format = tmpfmt;
fr->data.ptr = readbuf;
fr->datalen = readlen;
fr->frametype = AST_FRAME_VOICE;
@@ -2429,7 +2426,6 @@ static struct ast_channel *vpb_new(struct vpb_pvt *me, enum ast_channel_state st
struct ast_channel *tmp;
char cid_num[256];
char cid_name[256];
- struct ast_format tmpfmt;
if (me->owner) {
ast_log(LOG_WARNING, "Called vpb_new on owned channel (%s) ?!\n", me->dev);
@@ -2452,9 +2448,9 @@ static struct ast_channel *vpb_new(struct vpb_pvt *me, enum ast_channel_state st
* they are all converted to/from linear in the vpb code. Best for us to use
* linear since we can then adjust volume in this modules.
*/
- ast_format_cap_add(ast_channel_nativeformats(tmp), ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR, 0));
- ast_format_copy(ast_channel_rawreadformat(tmp), &tmpfmt);
- ast_format_copy(ast_channel_rawwriteformat(tmp), &tmpfmt);
+ ast_channel_nativeformats_set(tmp, vpb_tech.capabilities);
+ ast_channel_set_rawreadformat(tmp, ast_format_slin);
+ ast_channel_set_rawwriteformat(tmp, ast_format_slin);
if (state == AST_STATE_RING) {
ast_channel_rings_set(tmp, 1);
cid_name[0] = '\0';
@@ -2508,13 +2504,17 @@ static struct ast_channel *vpb_request(const char *type, struct ast_format_cap *
char *sepstr, *name;
const char *s;
int group = -1;
- struct ast_format slin;
- ast_format_set(&slin, AST_FORMAT_SLINEAR, 0);
+ if (!(ast_format_cap_iscompatible_format(cap, ast_format_slin))) {
+ struct ast_str *buf;
- if (!(ast_format_cap_iscompatible(cap, &slin))) {
- char tmp[256];
- ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%s'\n", ast_getformatname_multiple(tmp, sizeof(tmp), cap));
+ buf = ast_str_create(256);
+ if (!buf) {
+ return NULL;
+ }
+ ast_log(LOG_NOTICE, "Asked to create a channel for unsupported formats: %s\n",
+ ast_format_cap_get_names(cap, &buf));
+ ast_free(buf);
return NULL;
}
@@ -2636,8 +2636,10 @@ static int unload_module(void)
ast_free(bridges);
}
- ast_format_cap_destroy(vpb_tech.capabilities);
- ast_format_cap_destroy(vpb_tech_indicate.capabilities);
+ ao2_cleanup(vpb_tech.capabilities);
+ vpb_tech.capabilities = NULL;
+ ao2_cleanup(vpb_tech_indicate.capabilities);
+ vpb_tech_indicate.capabilities = NULL;
return 0;
}
@@ -2671,19 +2673,18 @@ static enum ast_module_load_result load_module()
int bal2 = -1;
int bal3 = -1;
char * callerid = NULL;
- struct ast_format tmpfmt;
int num_cards = 0;
- vpb_tech.capabilities = ast_format_cap_alloc((enum ast_format_cap_flags) 0);
+ vpb_tech.capabilities = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
if (!vpb_tech.capabilities) {
return AST_MODULE_LOAD_DECLINE;
}
- vpb_tech_indicate.capabilities = ast_format_cap_alloc((enum ast_format_cap_flags) 0);
+ vpb_tech_indicate.capabilities = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
if (!vpb_tech_indicate.capabilities) {
return AST_MODULE_LOAD_DECLINE;
}
- ast_format_cap_add(vpb_tech.capabilities, ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR, 0));
- ast_format_cap_add(vpb_tech_indicate.capabilities, ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR, 0));
+ ast_format_cap_append(vpb_tech.capabilities, ast_format_slin, 0);
+ ast_format_cap_append(vpb_tech_indicate.capabilities, ast_format_slin, 0);
try {
num_cards = vpb_get_num_cards();
} catch (std::exception e) {
diff --git a/channels/dahdi/bridge_native_dahdi.c b/channels/dahdi/bridge_native_dahdi.c
index 2f4fd170e..85cb4bfef 100644
--- a/channels/dahdi/bridge_native_dahdi.c
+++ b/channels/dahdi/bridge_native_dahdi.c
@@ -44,6 +44,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/bridge.h"
#include "asterisk/bridge_technology.h"
#include "asterisk/frame.h"
+#include "asterisk/format_cache.h"
/* ------------------------------------------------------------------- */
@@ -892,7 +893,7 @@ static struct ast_bridge_technology native_bridge = {
void dahdi_native_unload(void)
{
ast_bridge_technology_unregister(&native_bridge);
- ast_format_cap_destroy(native_bridge.format_capabilities);
+ ao2_cleanup(native_bridge.format_capabilities);
}
/*!
@@ -905,11 +906,9 @@ void dahdi_native_unload(void)
*/
int dahdi_native_load(struct ast_module *mod, const struct ast_channel_tech *tech)
{
- struct ast_format format;
-
dahdi_tech = tech;
- native_bridge.format_capabilities = ast_format_cap_alloc(0);
+ native_bridge.format_capabilities = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
if (!native_bridge.format_capabilities) {
return -1;
}
@@ -918,9 +917,9 @@ int dahdi_native_load(struct ast_module *mod, const struct ast_channel_tech *tec
* This is used to make channels compatible with the bridge
* itself not with each other.
*/
- ast_format_cap_add(native_bridge.format_capabilities, ast_format_set(&format, AST_FORMAT_SLINEAR, 0));
- ast_format_cap_add(native_bridge.format_capabilities, ast_format_set(&format, AST_FORMAT_ULAW, 0));
- ast_format_cap_add(native_bridge.format_capabilities, ast_format_set(&format, AST_FORMAT_ALAW, 0));
+ ast_format_cap_append(native_bridge.format_capabilities, ast_format_slin, 0);
+ ast_format_cap_append(native_bridge.format_capabilities, ast_format_ulaw, 0);
+ ast_format_cap_append(native_bridge.format_capabilities, ast_format_alaw, 0);
return __ast_bridge_technology_register(&native_bridge, mod);
}
diff --git a/channels/iax2/codec_pref.c b/channels/iax2/codec_pref.c
new file mode 100644
index 000000000..903dca4cc
--- /dev/null
+++ b/channels/iax2/codec_pref.c
@@ -0,0 +1,333 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2014, Digium, Inc.
+ *
+ * Joshua Colp <jcolp@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ *
+ * \brief Media Format Bitfield Compatibility API
+ *
+ * \author Joshua Colp <jcolp@digium.com>
+ */
+
+/*** MODULEINFO
+ <support_level>core</support_level>
+ ***/
+
+#include "asterisk.h"
+
+ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
+
+#include "asterisk/logger.h"
+#include "asterisk/astobj2.h"
+#include "asterisk/codec.h"
+#include "asterisk/format.h"
+#include "asterisk/format_compatibility.h"
+#include "asterisk/format_cache.h"
+#include "asterisk/format_cap.h"
+
+#include "include/codec_pref.h"
+#include "include/format_compatibility.h"
+
+void iax2_codec_pref_convert(struct iax2_codec_pref *pref, char *buf, size_t size, int right)
+{
+ static int differential = (int) 'A';
+ int x;
+
+ if (right) {
+ for (x = 0; x < IAX2_CODEC_PREF_SIZE && x < size; x++) {
+ if (!pref->order[x]) {
+ break;
+ }
+
+ buf[x] = pref->order[x] + differential;
+ }
+
+ buf[x] = '\0';
+ } else {
+ for (x = 0; x < IAX2_CODEC_PREF_SIZE && x < size; x++) {
+ if (buf[x] == '\0') {
+ break;
+ }
+
+ pref->order[x] = buf[x] - differential;
+ }
+
+ if (x < size) {
+ pref->order[x] = 0;
+ }
+ }
+}
+
+struct ast_format *iax2_codec_pref_index(struct iax2_codec_pref *pref, int idx, struct ast_format **result)
+{
+ if ((idx >= 0) && (idx < sizeof(pref->order)) && pref->order[idx]) {
+ *result = ast_format_compatibility_bitfield2format(pref->order[idx]);
+ } else {
+ *result = NULL;
+ }
+
+ return *result;
+}
+
+void iax2_codec_pref_to_cap(struct iax2_codec_pref *pref, struct ast_format_cap *cap)
+{
+ int idx;
+
+ for (idx = 0; idx < sizeof(pref->order); idx++) {
+ if (!pref->order[idx]) {
+ break;
+ }
+ ast_format_cap_append(cap, ast_format_compatibility_bitfield2format(pref->order[idx]), pref->framing[idx]);
+ }
+}
+
+int iax2_codec_pref_string(struct iax2_codec_pref *pref, char *buf, size_t size)
+{
+ int x;
+ struct ast_format_cap *cap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
+ size_t total_len;
+ char *cur;
+
+ if (!cap) {
+ return -1;
+ }
+
+ /* This function is useless if you have less than a 6 character buffer.
+ * '(...)' is six characters. */
+ if (size < 6) {
+ return -1;
+ }
+
+ /* Convert the preferences into a format cap so that we can read the formst names */
+ for (x = 0; x < IAX2_CODEC_PREF_SIZE; x++) {
+ uint64_t bitfield = iax2_codec_pref_order_value_to_format_bitfield(pref->order[x]);
+ if (!bitfield) {
+ break;
+ }
+
+ iax2_format_compatibility_bitfield2cap(bitfield, cap);
+ }
+
+ /* We know that at a minimum, 3 characters are used - (, ), and \0 */
+ total_len = size - 3;
+
+ memset(buf, 0, size);
+
+ /* This character has already been accounted for total_len purposes */
+ buf[0] = '(';
+ cur = buf + 1;
+
+ /* Loop through the formats and write as many into the buffer as we can */
+ for (x = 0; x < ast_format_cap_count(cap); x++) {
+ size_t name_len;
+ struct ast_format *fmt = ast_format_cap_get_format(cap, x);
+ const char *name = ast_format_get_name(fmt);
+
+ name_len = strlen(name);
+
+ /* all entries after the first need a delimiter character */
+ if (x) {
+ name_len++;
+ }
+
+ /* Terminate the list early if we don't have room for the entry.
+ * If it's not the last entry in the list, save enough room to write '...'.
+ */
+ if (((x == ast_format_cap_count(cap) - 1) && (total_len < name_len)) ||
+ ((x < ast_format_cap_count(cap) - 1) && (total_len < name_len + 3))) {
+ strcpy(cur, "...");
+ cur += 3;
+ total_len -= 3;
+ ao2_ref(fmt, -1);
+ break;
+ }
+
+ sprintf(cur, "%s%s", x ? "|" : "", name);
+ cur += name_len;
+ total_len -= name_len;
+
+ ao2_ref(fmt, -1);
+ }
+ ao2_ref(cap, -1);
+
+ /* These two characters have already been accounted for total_len purposes */
+ cur[0] = ')';
+ cur[1] = '\0';
+
+ return size - total_len;
+}
+
+static void codec_pref_remove_index(struct iax2_codec_pref *pref, int codec_pref_index)
+{
+ int x;
+
+ for (x = codec_pref_index; x < IAX2_CODEC_PREF_SIZE; x++) {
+ pref->order[x] = pref->order[x + 1];
+ pref->framing[x] = pref->framing[x + 1];
+ if (!pref->order[x]) {
+ return;
+ }
+ }
+}
+
+/*! \brief Remove codec from pref list */
+static void codec_pref_remove(struct iax2_codec_pref *pref, int format_index)
+{
+ int x;
+
+ if (!pref->order[0]) {
+ return;
+ }
+
+ for (x = 0; x < IAX2_CODEC_PREF_SIZE; x++) {
+ if (!pref->order[x]) {
+ break;
+ }
+
+ if (pref->order[x] == format_index) {
+ codec_pref_remove_index(pref, x);
+ break;
+ }
+ }
+}
+
+void iax2_codec_pref_remove_missing(struct iax2_codec_pref *pref, uint64_t bitfield)
+{
+ int x;
+
+ if (!pref->order[0]) {
+ return;
+ }
+
+ for (x = 0; x < IAX2_CODEC_PREF_SIZE; x++) {
+ uint64_t format_as_bitfield = iax2_codec_pref_order_value_to_format_bitfield(pref->order[x]);
+ if (!pref->order[x]) {
+ break;
+ }
+
+ /* If this format isn't in the bitfield, remove it from the prefs. */
+ if (!(format_as_bitfield & bitfield)) {
+ codec_pref_remove_index(pref, x);
+ }
+ }
+}
+
+uint64_t iax2_codec_pref_order_value_to_format_bitfield(uint64_t order_value)
+{
+ if (!order_value) {
+ return 0;
+ }
+
+ return 1 << (order_value - 1);
+}
+
+uint64_t iax2_codec_pref_format_bitfield_to_order_value(uint64_t bitfield)
+{
+ int format_index = 1;
+
+ if (!bitfield) {
+ return 0;
+ }
+
+ while (bitfield > 1) {
+ bitfield = bitfield >> 1;
+ format_index++;
+ }
+
+ return format_index;
+}
+
+/*! \brief Append codec to list */
+int iax2_codec_pref_append(struct iax2_codec_pref *pref, struct ast_format *format, unsigned int framing)
+{
+ uint64_t bitfield = ast_format_compatibility_format2bitfield(format);
+ int format_index = iax2_codec_pref_format_bitfield_to_order_value(bitfield);
+ int x;
+
+ codec_pref_remove(pref, format_index);
+
+ for (x = 0; x < IAX2_CODEC_PREF_SIZE; x++) {
+ if (!pref->order[x]) {
+ pref->order[x] = format_index;
+ pref->framing[x] = framing;
+ break;
+ }
+ }
+
+ return x;
+}
+
+/*! \brief Prepend codec to list */
+void iax2_codec_pref_prepend(struct iax2_codec_pref *pref, struct ast_format *format, unsigned int framing,
+ int only_if_existing)
+{
+ uint64_t bitfield = ast_format_compatibility_format2bitfield(format);
+ int x;
+
+ /* Now find any existing occurrence, or the end */
+ for (x = 0; x < IAX2_CODEC_PREF_SIZE; x++) {
+ if (!pref->order[x] || pref->order[x] == bitfield)
+ break;
+ }
+
+ /* If we failed to find any occurrence, set to the end */
+ if (x == IAX2_CODEC_PREF_SIZE) {
+ --x;
+ }
+
+ if (only_if_existing && !pref->order[x]) {
+ return;
+ }
+
+ /* Move down to make space to insert - either all the way to the end,
+ or as far as the existing location (which will be overwritten) */
+ for (; x > 0; x--) {
+ pref->order[x] = pref->order[x - 1];
+ pref->framing[x] = pref->framing[x - 1];
+ }
+
+ /* And insert the new entry */
+ pref->order[0] = bitfield;
+ pref->framing[0] = framing;
+}
+
+unsigned int iax2_codec_pref_getsize(struct iax2_codec_pref *pref, int idx)
+{
+ if ((idx >= 0) && (idx < sizeof(pref->order)) && pref->order[idx]) {
+ return pref->framing[idx];
+ } else {
+ return 0;
+ }
+}
+
+int iax2_codec_pref_setsize(struct iax2_codec_pref *pref, struct ast_format *format, int framems)
+{
+ int idx;
+
+ for (idx = 0; idx < sizeof(pref->order); idx++) {
+ if (!pref->order[idx]) {
+ break;
+ } else if (ast_format_cmp(ast_format_compatibility_bitfield2format(pref->order[idx]),
+ format) != AST_FORMAT_CMP_EQUAL) {
+ continue;
+ }
+ pref->framing[idx] = framems;
+ return 0;
+ }
+
+ return -1;
+}
diff --git a/channels/iax2/format_compatibility.c b/channels/iax2/format_compatibility.c
new file mode 100644
index 000000000..8085c2c26
--- /dev/null
+++ b/channels/iax2/format_compatibility.c
@@ -0,0 +1,73 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2014, Digium, Inc.
+ *
+ * Joshua Colp <jcolp@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ *
+ * \brief Media Format Bitfield Compatibility API
+ *
+ * \author Joshua Colp <jcolp@digium.com>
+ */
+
+/*** MODULEINFO
+ <support_level>core</support_level>
+ ***/
+
+#include "asterisk.h"
+
+ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
+
+#include "asterisk/logger.h"
+#include "asterisk/astobj2.h"
+#include "asterisk/codec.h"
+#include "asterisk/format.h"
+#include "asterisk/format_compatibility.h"
+#include "asterisk/format_cache.h"
+#include "asterisk/format_cap.h"
+
+#include "include/format_compatibility.h"
+
+uint64_t iax2_format_compatibility_cap2bitfield(const struct ast_format_cap *cap)
+{
+ uint64_t bitfield = 0;
+ int x;
+
+ for (x = 0; x < ast_format_cap_count(cap); x++) {
+ struct ast_format *format = ast_format_cap_get_format(cap, x);
+
+ bitfield |= ast_format_compatibility_format2bitfield(format);
+
+ ao2_ref(format, -1);
+ }
+
+ return bitfield;
+}
+
+int iax2_format_compatibility_bitfield2cap(uint64_t bitfield, struct ast_format_cap *cap)
+{
+ int x;
+
+ for (x = 0; x < 64; x++) {
+ uint64_t tmp = (1ULL << x);
+
+ if ((tmp & bitfield) && ast_format_cap_append(cap, ast_format_compatibility_bitfield2format(tmp), 0)) {
+ return -1;
+ }
+ }
+
+ return 0;
+}
diff --git a/channels/iax2/include/codec_pref.h b/channels/iax2/include/codec_pref.h
new file mode 100644
index 000000000..bfb889164
--- /dev/null
+++ b/channels/iax2/include/codec_pref.h
@@ -0,0 +1,123 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2014, Digium, Inc.
+ *
+ * Joshua Colp <jcolp@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*!
+ * \file
+ * \brief Media Format Bitfield Compatibility API
+ *
+ * \author Joshua Colp <jcolp@digium.com>
+ */
+
+#ifndef _IAX2_CODEC_PREF_H_
+#define _IAX2_CODEC_PREF_H_
+
+struct ast_format;
+struct ast_codec;
+struct ast_format_cap;
+
+#define IAX2_CODEC_PREF_SIZE 64
+struct iax2_codec_pref {
+ /*! This array is ordered by preference and contains the codec bitfield. */
+ uint64_t order[IAX2_CODEC_PREF_SIZE];
+ /*! Framing size of the codec */
+ unsigned int framing[IAX2_CODEC_PREF_SIZE];
+};
+
+/*!
+ * \brief Convert an iax2_codec_pref order value into a format bitfield
+ *
+ * \param order_value value being converted
+ *
+ * \return the bitfield value of the order_value format
+ */
+uint64_t iax2_codec_pref_order_value_to_format_bitfield(uint64_t order_value);
+
+/*!
+ * \brief Convert a format bitfield into an iax2_codec_pref order value
+ *
+ * \param bitfield value being converted
+ *
+ * \return the iax2_codec_pref order value of the most significant format
+ * in the bitfield.
+ *
+ * \note This is really meant to be used on single format bitfields.
+ * It will work with multiformat bitfields, but it can only return the
+ * index of the most significant one if that is the case.
+ */
+uint64_t iax2_codec_pref_format_bitfield_to_order_value(uint64_t bitfield);
+
+/*!
+ * \brief Codec located at a particular place in the preference index.
+ * \param pref preference structure to get the codec out of
+ * \param index to retrieve from
+ * \param result ast_format structure to store the index value in
+ * \return pointer to input ast_format on success, NULL on failure
+*/
+struct ast_format *iax2_codec_pref_index(struct iax2_codec_pref *pref, int index, struct ast_format **result);
+
+/*! \brief Convert a preference structure to a capabilities structure */
+void iax2_codec_pref_to_cap(struct iax2_codec_pref *pref, struct ast_format_cap *cap);
+
+/*! \brief Removes format from the pref list that aren't in the bitfield */
+void iax2_codec_pref_remove_missing(struct iax2_codec_pref *pref, uint64_t bitfield);
+
+/*!
+ * \brief Dump audio codec preference list into a string
+ *
+ * \param pref preference structure to dump string representation of order for
+ * \param buf character buffer to put string into
+ * \param size size of the character buffer
+ *
+ * \return -1 on error. Otherwise returns the remaining spaaaaaace in the buffer.
+ *
+ * \note Format is (codec1|codec2|codec3|...) -- if the list is too long for the
+ * size of the buffer, codecs will be written until they exceed the length
+ * remaining in which case the list will be closed with '...)' after the last
+ * writable codec.
+ */
+int iax2_codec_pref_string(struct iax2_codec_pref *pref, char *buf, size_t size);
+
+/*! \brief Append a audio codec to a preference list, removing it first if it was already there
+*/
+int iax2_codec_pref_append(struct iax2_codec_pref *pref, struct ast_format *format, unsigned int framing);
+
+/*! \brief Prepend an audio codec to a preference list, removing it first if it was already there
+*/
+void iax2_codec_pref_prepend(struct iax2_codec_pref *pref, struct ast_format *format, unsigned int framing,
+ int only_if_existing);
+
+/*! \brief Get packet size for codec
+*/
+unsigned int iax2_codec_pref_getsize(struct iax2_codec_pref *pref, int index);
+
+/*! \brief Set packet size for codec
+*/
+int iax2_codec_pref_setsize(struct iax2_codec_pref *pref, struct ast_format *format, int framems);
+
+/*! \brief Shift an audio codec preference list up or down 65 bytes so that it becomes an ASCII string
+ * \note Due to a misunderstanding in how codec preferences are stored, this
+ * list starts at 'B', not 'A'. For backwards compatibility reasons, this
+ * cannot change.
+ * \param pref A codec preference list structure
+ * \param buf A string denoting codec preference, appropriate for use in line transmission
+ * \param size Size of \a buf
+ * \param right Boolean: if 0, convert from \a buf to \a pref; if 1, convert from \a pref to \a buf.
+ */
+void iax2_codec_pref_convert(struct iax2_codec_pref *pref, char *buf, size_t size, int right);
+
+#endif /* _IAX2_CODEC_PREF_H_ */
diff --git a/channels/iax2/include/format_compatibility.h b/channels/iax2/include/format_compatibility.h
new file mode 100644
index 000000000..aa29cfa2c
--- /dev/null
+++ b/channels/iax2/include/format_compatibility.h
@@ -0,0 +1,55 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2014, Digium, Inc.
+ *
+ * Joshua Colp <jcolp@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*!
+ * \file
+ * \brief Media Format Bitfield Compatibility API
+ *
+ * \author Joshua Colp <jcolp@digium.com>
+ */
+
+#ifndef _IAX2_FORMAT_COMPATIBILITY_H_
+#define _IAX2_FORMAT_COMPATIBILITY_H_
+
+struct ast_format;
+struct ast_format_cap;
+
+/*!
+ * \brief Convert a format capabilities structure to a bitfield
+ *
+ * \param cap Capabilities structure containing formats
+ *
+ * \retval non-zero success
+ * \retval zero no formats present or no formats supported
+ */
+uint64_t iax2_format_compatibility_cap2bitfield(const struct ast_format_cap *cap);
+
+/*!
+ * \brief Convert a bitfield to a format capabilities structure
+ *
+ * \param bitfield The bitfield for the media formats
+ * \param cap Capabilities structure to place formats into
+ *
+ * \retval non-NULL success
+ * \retval NULL failure
+ *
+ * \note If failure occurs the capabilities structure may contain a partial set of formats
+ */
+int iax2_format_compatibility_bitfield2cap(uint64_t bitfield, struct ast_format_cap *cap);
+
+#endif /* _IAX2_FORMAT_COMPATIBILITY_H */
diff --git a/channels/iax2/parser.c b/channels/iax2/parser.c
index f5c7ba05d..f1fc8f82d 100644
--- a/channels/iax2/parser.c
+++ b/channels/iax2/parser.c
@@ -42,10 +42,13 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/lock.h"
#include "asterisk/threadstorage.h"
#include "asterisk/netsock2.h"
+#include "asterisk/format_cache.h"
+#include "asterisk/format_compatibility.h"
#include "include/iax2.h"
#include "include/parser.h"
#include "include/provision.h"
+#include "include/codec_pref.h"
static int frames = 0;
static int iframes = 0;
@@ -124,7 +127,7 @@ static void dump_string(char *output, int maxlen, void *value, int len)
static void dump_prefs(char *output, int maxlen, void *value, int len)
{
- struct ast_codec_pref pref;
+ struct iax2_codec_pref pref;
int total_len = 0;
maxlen--;
@@ -136,9 +139,9 @@ static void dump_prefs(char *output, int maxlen, void *value, int len)
strncpy(output, value, maxlen);
output[maxlen] = '\0';
- ast_codec_pref_convert(&pref, output, total_len, 0);
+ iax2_codec_pref_convert(&pref, output, total_len, 0);
memset(output,0,total_len);
- ast_codec_pref_string(&pref, output, total_len);
+ iax2_codec_pref_string(&pref, output, total_len);
}
static void dump_int(char *output, int maxlen, void *value, int len)
@@ -1180,7 +1183,8 @@ int iax_parse_ies(struct iax_ies *ies, unsigned char *data, int datalen)
void iax_frame_wrap(struct iax_frame *fr, struct ast_frame *f)
{
fr->af.frametype = f->frametype;
- ast_format_copy(&fr->af.subclass.format, &f->subclass.format);
+ fr->af.subclass.format = f->subclass.format;
+ fr->af.subclass.integer = f->subclass.integer;
fr->af.mallocd = 0; /* Our frame is static relative to the container */
fr->af.datalen = f->datalen;
fr->af.samples = f->samples;
@@ -1199,7 +1203,8 @@ void iax_frame_wrap(struct iax_frame *fr, struct ast_frame *f)
}
#if __BYTE_ORDER == __LITTLE_ENDIAN
/* We need to byte-swap slinear samples from network byte order */
- if ((fr->af.frametype == AST_FRAME_VOICE) && (fr->af.subclass.format.id == AST_FORMAT_SLINEAR)) {
+ if ((fr->af.frametype == AST_FRAME_VOICE) &&
+ (ast_format_cmp(fr->af.subclass.format, ast_format_slin) == AST_FORMAT_CMP_EQUAL)) {
/* 2 bytes / sample for SLINEAR */
ast_swapcopy_samples(fr->af.data.ptr, f->data.ptr, copy_len / 2);
} else
diff --git a/channels/iax2/provision.c b/channels/iax2/provision.c
index 78e0b1b3d..85dfe9448 100644
--- a/channels/iax2/provision.c
+++ b/channels/iax2/provision.c
@@ -45,6 +45,8 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/astdb.h"
#include "asterisk/utils.h"
#include "asterisk/acl.h"
+#include "asterisk/format_cache.h"
+#include "asterisk/format_compatibility.h"
#include "include/iax2.h"
#include "include/provision.h"
@@ -345,9 +347,10 @@ static int iax_template_parse(struct iax_template *cur, struct ast_config *cfg,
} else
ast_log(LOG_WARNING, "Ignoring invalid %s '%s' for '%s' at line %d\n", v->name, v->value, s, v->lineno);
} else if (!strcasecmp(v->name, "codec")) {
- struct ast_format tmpfmt;
- if ((ast_getformatbyname(v->value, &tmpfmt)) > 0) {
- cur->format = ast_format_to_old_bitfield(&tmpfmt);
+ struct ast_format *tmpfmt;
+ if ((tmpfmt = ast_format_cache_get(v->value))) {
+ cur->format = ast_format_compatibility_format2bitfield(tmpfmt);
+ ao2_ref(tmpfmt, -1);
} else
ast_log(LOG_WARNING, "Ignoring invalid codec '%s' for '%s' at line %d\n", v->value, s, v->lineno);
} else if (!strcasecmp(v->name, "tos")) {
diff --git a/channels/pjsip/dialplan_functions.c b/channels/pjsip/dialplan_functions.c
index c50dbf3fc..054552b5a 100644
--- a/channels/pjsip/dialplan_functions.c
+++ b/channels/pjsip/dialplan_functions.c
@@ -806,35 +806,32 @@ int pjsip_acf_dial_contacts_read(struct ast_channel *chan, const char *cmd, char
}
static int media_offer_read_av(struct ast_sip_session *session, char *buf,
- size_t len, enum ast_format_type media_type)
+ size_t len, enum ast_media_type media_type)
{
int i, size = 0;
- struct ast_format fmt;
- const char *name;
- for (i = 0; ast_codec_pref_index(&session->override_prefs, i, &fmt); ++i) {
- if (AST_FORMAT_GET_TYPE(fmt.id) != media_type) {
- continue;
- }
+ for (i = 0; i < ast_format_cap_count(session->req_caps); i++) {
+ struct ast_format *fmt = ast_format_cap_get_format(session->req_caps, i);
- name = ast_getformatname(&fmt);
-
- if (ast_strlen_zero(name)) {
- ast_log(LOG_WARNING, "PJSIP_MEDIA_OFFER unrecognized format %s\n", name);
+ if (ast_format_get_type(fmt) != media_type) {
+ ao2_ref(fmt, -1);
continue;
}
/* add one since we'll include a comma */
- size = strlen(name) + 1;
+ size = strlen(ast_format_get_name(fmt)) + 1;
len -= size;
if ((len) < 0) {
+ ao2_ref(fmt, -1);
break;
}
/* no reason to use strncat here since we have already ensured buf has
enough space, so strcat can be safely used */
- strcat(buf, name);
+ strcat(buf, ast_format_get_name(fmt));
strcat(buf, ",");
+
+ ao2_ref(fmt, -1);
}
if (size) {
@@ -846,23 +843,16 @@ static int media_offer_read_av(struct ast_sip_session *session, char *buf,
struct media_offer_data {
struct ast_sip_session *session;
- enum ast_format_type media_type;
+ enum ast_media_type media_type;
const char *value;
};
static int media_offer_write_av(void *obj)
{
struct media_offer_data *data = obj;
- int i;
- struct ast_format fmt;
- /* remove all of the given media type first */
- for (i = 0; ast_codec_pref_index(&data->session->override_prefs, i, &fmt); ++i) {
- if (AST_FORMAT_GET_TYPE(fmt.id) == data->media_type) {
- ast_codec_pref_remove(&data->session->override_prefs, &fmt);
- }
- }
- ast_format_cap_remove_bytype(data->session->req_caps, data->media_type);
- ast_parse_allow_disallow(&data->session->override_prefs, data->session->req_caps, data->value, 1);
+
+ ast_format_cap_remove_by_type(data->session->req_caps, data->media_type);
+ ast_format_cap_update_by_allow_disallow(data->session->req_caps, data->value, 1);
return 0;
}
@@ -879,9 +869,9 @@ int pjsip_acf_media_offer_read(struct ast_channel *chan, const char *cmd, char *
channel = ast_channel_tech_pvt(chan);
if (!strcmp(data, "audio")) {
- return media_offer_read_av(channel->session, buf, len, AST_FORMAT_TYPE_AUDIO);
+ return media_offer_read_av(channel->session, buf, len, AST_MEDIA_TYPE_AUDIO);
} else if (!strcmp(data, "video")) {
- return media_offer_read_av(channel->session, buf, len, AST_FORMAT_TYPE_VIDEO);
+ return media_offer_read_av(channel->session, buf, len, AST_MEDIA_TYPE_VIDEO);
}
return 0;
@@ -903,9 +893,9 @@ int pjsip_acf_media_offer_write(struct ast_channel *chan, const char *cmd, char
mdata.session = channel->session;
if (!strcmp(data, "audio")) {
- mdata.media_type = AST_FORMAT_TYPE_AUDIO;
+ mdata.media_type = AST_MEDIA_TYPE_AUDIO;
} else if (!strcmp(data, "video")) {
- mdata.media_type = AST_FORMAT_TYPE_VIDEO;
+ mdata.media_type = AST_MEDIA_TYPE_VIDEO;
}
return ast_sip_push_task_synchronous(channel->session->serializer, media_offer_write_av, &mdata);
diff --git a/channels/sip/include/sip.h b/channels/sip/include/sip.h
index 11078d5b7..8ce63ee9d 100644
--- a/channels/sip/include/sip.h
+++ b/channels/sip/include/sip.h
@@ -1082,7 +1082,6 @@ struct sip_pvt {
int timer_b; /*!< SIP timer B, ms */
unsigned int sipoptions; /*!< Supported SIP options on the other end */
unsigned int reqsipoptions; /*!< Required SIP options on the other end */
- struct ast_codec_pref prefs; /*!< codec prefs */
struct ast_format_cap *caps; /*!< Special capability (codec) */
struct ast_format_cap *jointcaps; /*!< Supported capability at both ends (codecs) */
struct ast_format_cap *peercaps; /*!< Supported peer capability */
@@ -1310,7 +1309,6 @@ struct sip_peer {
int busy_level; /*!< Level of active channels where we signal busy */
int maxforwards; /*!< SIP Loop prevention */
enum transfermodes allowtransfer; /*! SIP Refer restriction scheme */
- struct ast_codec_pref prefs; /*!< codec prefs */
int lastmsgssent; /*!< The last known VM message counts (new/old) */
unsigned int sipoptions; /*!< Supported SIP options */
struct ast_flags flags[3]; /*!< SIP_ flags */