summaryrefslogtreecommitdiff
path: root/channels
diff options
context:
space:
mode:
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 */