summaryrefslogtreecommitdiff
path: root/channels/chan_iax2.c
diff options
context:
space:
mode:
Diffstat (limited to 'channels/chan_iax2.c')
-rw-r--r--channels/chan_iax2.c454
1 files changed, 292 insertions, 162 deletions
diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c
index 5de2c4a23..49434d678 100644
--- a/channels/chan_iax2.c
+++ b/channels/chan_iax2.c
@@ -317,22 +317,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_SLINEAR & \
- ~AST_FORMAT_SLINEAR16 & \
- ~AST_FORMAT_SIREN7 & \
- ~AST_FORMAT_SIREN14 & \
- ~AST_FORMAT_G719 & \
- ~AST_FORMAT_ULAW & \
- ~AST_FORMAT_ALAW & \
- ~AST_FORMAT_G722)
+ ~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))
/* A modem */
#define IAX_CAPABILITY_LOWBANDWIDTH (IAX_CAPABILITY_MEDBANDWIDTH & \
- ~AST_FORMAT_G726 & \
- ~AST_FORMAT_G726_AAL2 & \
- ~AST_FORMAT_ADPCM)
+ ~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))
#define IAX_CAPABILITY_LOWFREE (IAX_CAPABILITY_LOWBANDWIDTH & \
- ~AST_FORMAT_G723_1)
+ ~ast_format_id_to_old_bitfield(AST_FORMAT_G723_1))
#define DEFAULT_MAXMS 2000 /* Must be faster than 2 seconds by default */
@@ -361,7 +361,7 @@ static struct ast_sched_context *sched;
#define DONT_RESCHEDULE -2
-static format_t iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH;
+static iax2_format iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH;
static int iaxdebug = 0;
@@ -470,7 +470,7 @@ struct iax2_user {
int amaflags;
int adsi;
uint64_t flags;
- format_t capability;
+ iax2_format capability;
int maxauthreq; /*!< Maximum allowed outstanding AUTHREQs */
int curauthreq; /*!< Current number of outstanding AUTHREQs */
struct ast_codec_pref prefs;
@@ -517,7 +517,7 @@ struct iax2_peer {
int expire; /*!< Schedule entry for expiry */
int expiry; /*!< How soon to expire */
- format_t capability; /*!< Capability */
+ iax2_format capability; /*!< Capability */
/* Qualification */
int callno; /*!< Call number of POKE request */
@@ -648,15 +648,15 @@ struct chan_iax2_pvt {
/*! Socket to send/receive on for this call */
int sockfd;
/*! Last received voice format */
- format_t voiceformat;
+ iax2_format voiceformat;
/*! Last received video format */
- format_t videoformat;
+ iax2_format videoformat;
/*! Last sent voice format */
- format_t svoiceformat;
+ iax2_format svoiceformat;
/*! Last sent video format */
- format_t svideoformat;
+ iax2_format svideoformat;
/*! What we are capable of sending */
- format_t capability;
+ iax2_format capability;
/*! Last received timestamp */
unsigned int last;
/*! Last sent timestamp - never send the same timestamp twice in a single call */
@@ -690,11 +690,11 @@ struct chan_iax2_pvt {
/*! Negotiated format, this is only used to remember what format was
chosen for an unauthenticated call so that the channel can get
created later using the right format */
- format_t chosenformat;
+ iax2_format chosenformat;
/*! Peer selected format */
- format_t peerformat;
+ iax2_format peerformat;
/*! Peer capability */
- format_t peercapability;
+ iax2_format peercapability;
/*! timeval that we base our transmission on */
struct timeval offset;
/*! timeval that we base our delivery on */
@@ -1191,7 +1191,7 @@ static int send_command_final(struct chan_iax2_pvt *, char, int, unsigned int, c
static int send_command_immediate(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
static int send_command_locked(unsigned short callno, char, int, unsigned int, const unsigned char *, int, int);
static int send_command_transfer(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int);
-static struct ast_channel *iax2_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause);
+static struct ast_channel *iax2_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *data, int *cause);
static struct ast_frame *iax2_read(struct ast_channel *c);
static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly);
static struct iax2_user *build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly);
@@ -1211,10 +1211,9 @@ static int replace_callno(const void *obj);
static void sched_delay_remove(struct sockaddr_in *sin, struct callno_entry *callno_entry);
static void network_change_event_cb(const struct ast_event *, void *);
-static const struct ast_channel_tech iax2_tech = {
+static struct ast_channel_tech iax2_tech = {
.type = "IAX2",
.description = tdesc,
- .capabilities = IAX_CAPABILITY_FULLBANDWIDTH,
.properties = AST_CHAN_TP_WANTSJITTER,
.requester = iax2_request,
.devicestate = iax2_devicestate,
@@ -1604,7 +1603,7 @@ static int send_lagrq(const void *data)
return 0;
}
-static unsigned char compress_subclass(format_t subclass)
+static unsigned char compress_subclass(iax2_format subclass)
{
int x;
int power=-1;
@@ -1624,7 +1623,7 @@ static unsigned char compress_subclass(format_t subclass)
return power | IAX_FLAG_SC_LOG;
}
-static format_t uncompress_subclass(unsigned char csub)
+static iax2_format uncompress_subclass(unsigned char csub)
{
/* If the SC_LOG flag is set, return 2^csub otherwise csub */
if (csub & IAX_FLAG_SC_LOG) {
@@ -1638,6 +1637,90 @@ static format_t uncompress_subclass(unsigned char csub)
return csub;
}
+static iax2_format iax2_codec_choose(struct ast_codec_pref *pref, iax2_format formats, int find_best)
+{
+ struct ast_format_cap *cap;
+ struct ast_format tmpfmt;
+ iax2_format format = 0;
+ if ((cap = ast_format_cap_alloc_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);
+ }
+
+ return format;
+}
+
+static iax2_format iax2_best_codec(iax2_format formats)
+{
+ struct ast_format_cap *cap = ast_format_cap_alloc_nolock();
+ struct ast_format tmpfmt;
+ 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);
+}
+
+char *iax2_getformatname(iax2_format format)
+{
+ struct ast_format tmpfmt;
+ if (!(ast_format_from_old_bitfield(&tmpfmt, format))) {
+ return "Unknown";
+ }
+
+ return ast_getformatname(&tmpfmt);
+}
+
+static char *iax2_getformatname_multiple(char *codec_buf, size_t len, iax2_format format)
+{
+ struct ast_format_cap *cap = ast_format_cap_alloc_nolock();
+
+ 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);
+
+ return codec_buf;
+}
+
+static int iax2_parse_allow_disallow(struct ast_codec_pref *pref, iax2_format *formats, const char *list, int allowing)
+{
+ int res;
+ struct ast_format_cap *cap = ast_format_cap_alloc_nolock();
+ 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);
+
+ return res;
+}
+
+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_nolock();
+ if (!cap) {
+ return -1;
+ }
+ ast_format_cap_from_old_bitfield(cap, formats);
+ res = ast_data_add_codecs(root, node_name, cap);
+ cap = ast_format_cap_destroy(cap);
+ return res;
+}
+
/*!
* \note The only member of the peer passed here guaranteed to be set is the name field
*/
@@ -3727,7 +3810,7 @@ static char *handle_cli_iax2_show_peer(struct ast_cli_entry *e, int cmd, struct
struct iax2_peer *peer;
char codec_buf[512];
struct ast_str *encmethods = ast_str_alloca(256);
- int x = 0, codec = 0, load_realtime = 0;
+ int x = 0, load_realtime = 0;
switch (cmd) {
case CLI_INIT:
@@ -3772,16 +3855,16 @@ static char *handle_cli_iax2_show_peer(struct ast_cli_entry *e, int cmd, struct
ast_cli(a->fd, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port));
ast_cli(a->fd, " Username : %s\n", peer->username);
ast_cli(a->fd, " Codecs : ");
- ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability);
+ iax2_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability);
ast_cli(a->fd, "%s\n", codec_buf);
ast_cli(a->fd, " Codec Order : (");
- for(x = 0; x < 32 ; x++) {
- codec = ast_codec_pref_index(&peer->prefs,x);
- if(!codec)
+ 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(codec));
- if(x < 31 && ast_codec_pref_index(&peer->prefs,x+1))
+ ast_cli(a->fd, "%s", ast_getformatname(&tmpfmt));
+ if(x < 31 && ast_codec_pref_index(&peer->prefs, x+1, &tmpfmt))
ast_cli(a->fd, "|");
}
@@ -4067,7 +4150,9 @@ static void __get_from_jb(const void *p)
ms = ast_tvdiff_ms(now, pvt->rxcore);
if(ms >= (next = jb_next(pvt->jb))) {
- ret = jb_get(pvt->jb,&frame,ms,ast_codec_interp_len(pvt->voiceformat));
+ struct ast_format voicefmt;
+ ast_format_from_old_bitfield(&voicefmt, pvt->voiceformat);
+ ret = jb_get(pvt->jb, &frame, ms, ast_codec_interp_len(&voicefmt));
switch(ret) {
case JB_OK:
fr = frame.data;
@@ -4081,8 +4166,8 @@ static void __get_from_jb(const void *p)
/* create an interpolation frame */
af.frametype = AST_FRAME_VOICE;
- af.subclass.codec = pvt->voiceformat;
- af.samples = frame.ms * (ast_format_rate(pvt->voiceformat) / 1000);
+ ast_format_copy(&af.subclass.format, &voicefmt);
+ af.samples = frame.ms * (ast_format_rate(&voicefmt) / 1000);
af.src = "IAX2 JB interpolation";
af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000));
af.offset = AST_FRIENDLY_OFFSET;
@@ -4154,7 +4239,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.codec) / 1000);
+ len = ast_codec_get_samples(&fr->af) / (ast_format_rate(&fr->af.subclass.format) / 1000);
} else if(fr->af.frametype == AST_FRAME_CNG) {
type = JB_TYPE_SILENCE;
}
@@ -4511,7 +4596,7 @@ static void realtime_update_peer(const char *peername, struct ast_sockaddr *sock
}
struct create_addr_info {
- format_t capability;
+ iax2_format capability;
uint64_t flags;
int maxtime;
int encmethods;
@@ -4557,8 +4642,14 @@ static int create_addr(const char *peername, struct ast_channel *c, struct socka
/* use global iax prefs for unknown peer/user */
/* But move the calling channel's native codec to the top of the preference list */
memcpy(&ourprefs, &prefs, sizeof(ourprefs));
- if (c)
- ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1);
+ if (c) {
+ struct ast_format tmpfmt;
+ ast_format_cap_iter_start(c->nativeformats);
+ while (!(ast_format_cap_iter_next(c->nativeformats, &tmpfmt))) {
+ ast_codec_pref_prepend(&ourprefs, &tmpfmt, 1);
+ }
+ ast_format_cap_iter_end(c->nativeformats);
+ }
ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
return 0;
}
@@ -4585,8 +4676,13 @@ static int create_addr(const char *peername, struct ast_channel *c, struct socka
memcpy(&ourprefs, &peer->prefs, sizeof(ourprefs));
/* Move the calling channel's native codec to the top of the preference list */
if (c) {
- ast_debug(1, "prepending %llx to prefs\n", (unsigned long long) c->nativeformats);
- ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1);
+ struct ast_format tmpfmt;
+ ast_format_cap_iter_start(c->nativeformats);
+ while (!(ast_format_cap_iter_next(c->nativeformats, &tmpfmt))) {
+ ast_debug(1, "prepending %s to prefs\n", ast_getformatname(&tmpfmt));
+ ast_codec_pref_prepend(&ourprefs, &tmpfmt, 1);
+ }
+ ast_format_cap_iter_end(c->nativeformats);
}
ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
ast_copy_string(cai->context, peer->context, sizeof(cai->context));
@@ -4995,6 +5091,7 @@ static int iax2_call(struct ast_channel *c, char *dest, int timeout)
unsigned char osp_block_index;
unsigned int osp_block_length;
unsigned char osp_buffer[256];
+ iax2_format iax2_tmpfmt;
if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) {
ast_log(LOG_WARNING, "Channel is already in use (%s)?\n", c->name);
@@ -5121,8 +5218,10 @@ static int iax2_call(struct ast_channel *c, char *dest, int timeout)
if (pds.password)
ast_string_field_set(iaxs[callno], secret, pds.password);
- iax_ie_append_int(&ied, IAX_IE_FORMAT, (int) c->nativeformats);
- iax_ie_append_versioned_uint64(&ied, IAX_IE_FORMAT2, 0, c->nativeformats);
+ iax2_tmpfmt = ast_format_cap_to_old_bitfield(c->nativeformats);
+ iax_ie_append_int(&ied, IAX_IE_FORMAT, (int) iax2_tmpfmt);
+ iax_ie_append_versioned_uint64(&ied, IAX_IE_FORMAT2, 0, iax2_tmpfmt);
+
iax_ie_append_int(&ied, IAX_IE_CAPABILITY, (int) iaxs[callno]->capability);
iax_ie_append_versioned_uint64(&ied, IAX_IE_CAPABILITY2, 0, iaxs[callno]->capability);
iax_ie_append_short(&ied, IAX_IE_ADSICPE, c->adsicpe);
@@ -5471,7 +5570,7 @@ static enum ast_bridge_result iax2_bridge(struct ast_channel *c0, struct ast_cha
}
return AST_BRIDGE_FAILED_NOWARN;
}
- if (c0->nativeformats != c1->nativeformats) {
+ if (!(ast_format_cap_identical(c0->nativeformats, c1->nativeformats))) {
char buf0[256];
char buf1[256];
ast_getformatname_multiple(buf0, sizeof(buf0), c0->nativeformats);
@@ -5676,11 +5775,12 @@ static int iax2_getpeertrunk(struct sockaddr_in sin)
}
/*! \brief Create new call, interface with the PBX core */
-static struct ast_channel *ast_iax2_new(int callno, int state, format_t capability, const char *linkedid)
+static struct ast_channel *ast_iax2_new(int callno, int state, iax2_format capability, const char *linkedid)
{
struct ast_channel *tmp;
struct chan_iax2_pvt *i;
struct ast_variable *v = NULL;
+ struct ast_format tmpfmt;
if (!(i = iaxs[callno])) {
ast_log(LOG_WARNING, "No IAX2 pvt found for callno '%d' !\n", callno);
@@ -5705,9 +5805,14 @@ static struct ast_channel *ast_iax2_new(int callno, int state, format_t capabili
return NULL;
tmp->tech = &iax2_tech;
/* We can support any format by default, until we get restricted */
- tmp->nativeformats = capability;
- tmp->readformat = tmp->rawreadformat = ast_best_codec(capability);
- tmp->writeformat = tmp->rawwriteformat = ast_best_codec(capability);
+ ast_format_cap_from_old_bitfield(tmp->nativeformats, capability);
+ ast_best_codec(tmp->nativeformats, &tmpfmt);
+
+ ast_format_copy(&tmp->readformat, &tmpfmt);
+ ast_format_copy(&tmp->rawreadformat, &tmpfmt);
+ ast_format_copy(&tmp->writeformat, &tmpfmt);
+ ast_format_copy(&tmp->rawwriteformat, &tmpfmt);
+
tmp->tech_pvt = CALLNO_TO_PTR(i->callno);
if (!ast_strlen_zero(i->parkinglot))
@@ -5848,7 +5953,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.codec) / 1000;
+ int rate = ast_format_rate(&f->subclass.format) / 1000;
struct timeval *delivery = NULL;
@@ -6221,9 +6326,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) {
- f->subclass.codec = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
+ ast_format_from_old_bitfield(&f->subclass.format, (uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1)));
} else if (f->frametype == AST_FRAME_VOICE) {
- f->subclass.codec = uncompress_subclass(fh->csub);
+ ast_format_from_old_bitfield(&f->subclass.format, uncompress_subclass(fh->csub));
} else {
f->subclass.integer = uncompress_subclass(fh->csub);
}
@@ -6366,7 +6471,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.codec == pvt->svoiceformat)
+ (f->subclass.format.id == ast_format_id_from_old_bitfield(pvt->svoiceformat))
/* is the same type */ ) {
/* Force immediate rather than delayed transmission */
now = 1;
@@ -6380,7 +6485,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.codec & ~0x1LL) == pvt->svideoformat)
+ ((f->subclass.format.id) == ast_format_id_from_old_bitfield(pvt->svideoformat))
) {
now = 1;
sendmini = 1;
@@ -6435,9 +6540,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) {
- fh->csub = compress_subclass(fr->af.subclass.codec & ~0x1LL) | ((fr->af.subclass.codec & 0x1LL) << 6);
+ iax2_format tmpfmt = ast_format_to_old_bitfield(&fr->af.subclass.format);
+ tmpfmt |= ast_format_get_video_mark(&fr->af.subclass.format) ? 0x1LL : 0;
+ fh->csub = compress_subclass(tmpfmt | ((tmpfmt & 0x1LL) << 6));
} else if (fr->af.frametype == AST_FRAME_VOICE) {
- fh->csub = compress_subclass(fr->af.subclass.codec);
+ fh->csub = compress_subclass(ast_format_to_old_bitfield(&fr->af.subclass.format));
} else {
fh->csub = compress_subclass(fr->af.subclass.integer);
}
@@ -6460,9 +6567,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 = f->subclass.codec;
+ pvt->svoiceformat = ast_format_to_old_bitfield(&f->subclass.format);
else if (f->frametype == AST_FRAME_VIDEO)
- pvt->svideoformat = f->subclass.codec & ~0x1LL;
+ pvt->svideoformat = ast_format_to_old_bitfield(&f->subclass.format);
if (ast_test_flag64(pvt, IAX_ENCRYPTED)) {
if (ast_test_flag64(pvt, IAX_KEYPOPULATED)) {
if (fr->transfer)
@@ -6493,7 +6600,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) | (fr->af.subclass.codec & 0x1LL ? 0x8000 : 0));
+ vh->ts = htons((fr->ts & 0x7FFF) | (ast_format_get_video_mark(&fr->af.subclass.format) ? 0x8000 : 0));
fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_video_hdr);
fr->data = vh;
fr->retries = -1;
@@ -7167,7 +7274,7 @@ static char *handle_cli_iax2_show_channels(struct ast_cli_entry *e, int cmd, str
lag,
jitter,
localdelay,
- ast_getformatname(iaxs[x]->voiceformat),
+ iax2_getformatname(iaxs[x]->voiceformat),
(iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
first_message,
(iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
@@ -9659,7 +9766,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 {
- f.subclass.codec = iaxs[fr->callno]->voiceformat;
+ ast_format_from_old_bitfield(&f.subclass.format, iaxs[fr->callno]->voiceformat);
f.datalen = len;
if (f.datalen >= 0) {
if (f.datalen)
@@ -9806,7 +9913,7 @@ static int socket_process(struct iax2_thread *thread)
struct iax2_peer *peer;
struct iax_ies ies;
struct iax_ie_data ied0, ied1;
- format_t format;
+ iax2_format format;
int fd;
int exists;
int minivid = 0;
@@ -9877,9 +9984,12 @@ static int socket_process(struct iax2_thread *thread)
/* Retrieve the type and subclass */
f.frametype = fh->type;
if (f.frametype == AST_FRAME_VIDEO) {
- f.subclass.codec = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
+ ast_format_from_old_bitfield(&f.subclass.format, (uncompress_subclass(fh->csub & ~0x40)));
+ if ((fh->csub >> 6) & 0x1) {
+ ast_format_set_video_mark(&f.subclass.format);
+ }
} else if (f.frametype == AST_FRAME_VOICE) {
- f.subclass.codec = uncompress_subclass(fh->csub);
+ ast_format_from_old_bitfield(&f.subclass.format, uncompress_subclass(fh->csub));
} else {
f.subclass.integer = uncompress_subclass(fh->csub);
}
@@ -10250,21 +10360,24 @@ static int socket_process(struct iax2_thread *thread)
}
if (f.frametype == AST_FRAME_VOICE) {
- if (f.subclass.codec != iaxs[fr->callno]->voiceformat) {
- iaxs[fr->callno]->voiceformat = f.subclass.codec;
- ast_debug(1, "Ooh, voice format changed to '%s'\n", ast_getformatname(f.subclass.codec));
+ 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 (iaxs[fr->callno]->owner) {
iax2_lock_owner(fr->callno);
if (iaxs[fr->callno]) {
if (iaxs[fr->callno]->owner) {
- format_t orignative;
-
- orignative = iaxs[fr->callno]->owner->nativeformats;
- iaxs[fr->callno]->owner->nativeformats = f.subclass.codec;
- if (iaxs[fr->callno]->owner->readformat)
- ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);
- iaxs[fr->callno]->owner->nativeformats = orignative;
- ast_channel_unlock(iaxs[fr->callno]->owner);
+ struct ast_format_cap *orignative = ast_format_cap_dup(iaxs[fr->callno]->owner->nativeformats);
+ struct ast_format_cap *native = iaxs[fr->callno]->owner->nativeformats;
+ if (orignative) {
+ ast_format_cap_set(native, &f.subclass.format);
+ if (iaxs[fr->callno]->owner->readformat.id) {
+ ast_set_read_format(iaxs[fr->callno]->owner, &iaxs[fr->callno]->owner->readformat);
+ }
+ ast_format_cap_copy(native, orignative);
+ ast_channel_unlock(iaxs[fr->callno]->owner);
+ orignative = ast_format_cap_destroy(orignative);
+ }
}
} else {
ast_debug(1, "Neat, somebody took away the channel at a magical time but i found it!\n");
@@ -10281,9 +10394,9 @@ static int socket_process(struct iax2_thread *thread)
}
}
if (f.frametype == AST_FRAME_VIDEO) {
- if (f.subclass.codec != iaxs[fr->callno]->videoformat) {
- ast_debug(1, "Ooh, video format changed to %s\n", ast_getformatname(f.subclass.codec & ~0x1LL));
- iaxs[fr->callno]->videoformat = f.subclass.codec & ~0x1LL;
+ 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 (f.frametype == AST_FRAME_CONTROL && iaxs[fr->callno]->owner) {
@@ -10471,11 +10584,12 @@ static int socket_process(struct iax2_thread *thread)
strcpy(caller_pref_buf, "disabled");
strcpy(host_pref_buf, "disabled");
} else {
+ 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)) {
+ if (ast_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;
@@ -10486,7 +10600,7 @@ static int socket_process(struct iax2_thread *thread)
} else
pref = iaxs[fr->callno]->prefs;
- format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
+ 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);
}
@@ -10506,14 +10620,14 @@ static int socket_process(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_inet_ntoa(sin.sin_addr),
- ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat),
- ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
+ iax2_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat),
+ iax2_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
} else {
ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
ast_inet_ntoa(sin.sin_addr),
- ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat),
- ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability),
- ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability));
+ 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));
}
}
} else {
@@ -10525,12 +10639,13 @@ static int socket_process(struct iax2_thread *thread)
if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
using_prefs = ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
memset(&pref, 0, sizeof(pref));
- format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
+ format = iax2_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
strcpy(caller_pref_buf,"disabled");
strcpy(host_pref_buf,"disabled");
} else {
+ struct ast_format tmpfmt;
using_prefs = "mine";
- if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
+ if (ast_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;
@@ -10538,9 +10653,9 @@ static int socket_process(struct iax2_thread *thread)
pref = iaxs[fr->callno]->rprefs;
using_prefs = "caller";
}
- format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
+ format = iax2_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
} else /* if no codec_prefs IE do it the old way */
- format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
+ format = iax2_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
}
}
@@ -10549,7 +10664,7 @@ static int socket_process(struct iax2_thread *thread)
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", ast_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(tmp, sizeof(tmp), iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability));
send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
if (!iaxs[fr->callno]) {
break;
@@ -10557,9 +10672,9 @@ static int socket_process(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_inet_ntoa(sin.sin_addr),
- ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat),
- ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability),
- ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability));
+ 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));
}
ast_set_flag64(iaxs[fr->callno], IAX_ALREADYGONE);
break;
@@ -10582,11 +10697,11 @@ static int socket_process(struct iax2_thread *thread)
"%spriority = %s\n",
ast_inet_ntoa(sin.sin_addr),
VERBOSE_PREFIX_4,
- ast_getformatname(iaxs[fr->callno]->peerformat),
+ iax2_getformatname(iaxs[fr->callno]->peerformat),
VERBOSE_PREFIX_4,
caller_pref_buf,
VERBOSE_PREFIX_4,
- ast_getformatname(format),
+ iax2_getformatname(format),
VERBOSE_PREFIX_4,
host_pref_buf,
VERBOSE_PREFIX_4,
@@ -10730,11 +10845,11 @@ static int socket_process(struct iax2_thread *thread)
iaxs[fr->callno]->peerformat = ies.format;
} else {
if (iaxs[fr->callno]->owner)
- iaxs[fr->callno]->peerformat = iaxs[fr->callno]->owner->nativeformats;
+ iaxs[fr->callno]->peerformat = ast_format_cap_to_old_bitfield(iaxs[fr->callno]->owner->nativeformats);
else
iaxs[fr->callno]->peerformat = iaxs[fr->callno]->capability;
}
- ast_verb(3, "Call accepted by %s (format %s)\n", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), ast_getformatname(iaxs[fr->callno]->peerformat));
+ ast_verb(3, "Call accepted by %s (format %s)\n", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iax2_getformatname(iaxs[fr->callno]->peerformat));
if (!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) {
memset(&ied0, 0, sizeof(ied0));
iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
@@ -10747,22 +10862,23 @@ static int socket_process(struct iax2_thread *thread)
char tmp1[256], tmp2[256];
ast_log(LOG_NOTICE, "Rejected call to %s, format %s incompatible with our capability %s.\n",
ast_inet_ntoa(sin.sin_addr),
- ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
- ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
+ iax2_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
+ iax2_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
}
} else {
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];
/* Switch us to use a compatible format */
- iaxs[fr->callno]->owner->nativeformats = iaxs[fr->callno]->peerformat;
- ast_verb(3, "Format for call is %s\n", ast_getformatname(iaxs[fr->callno]->owner->nativeformats));
+ ast_format_cap_from_old_bitfield(iaxs[fr->callno]->owner->nativeformats, iaxs[fr->callno]->peerformat);
+ ast_verb(3, "Format for call is %s\n", ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->owner->nativeformats));
/* Setup read/write formats properly. */
- if (iaxs[fr->callno]->owner->writeformat)
- ast_set_write_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->writeformat);
- if (iaxs[fr->callno]->owner->readformat)
- ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);
+ if (iaxs[fr->callno]->owner->writeformat.id)
+ ast_set_write_format(iaxs[fr->callno]->owner, &iaxs[fr->callno]->owner->writeformat);
+ if (iaxs[fr->callno]->owner->readformat.id)
+ ast_set_read_format(iaxs[fr->callno]->owner, &iaxs[fr->callno]->owner->readformat);
ast_channel_unlock(iaxs[fr->callno]->owner);
}
}
@@ -10921,10 +11037,11 @@ static int socket_process(struct iax2_thread *thread)
strcpy(caller_pref_buf, "disabled");
strcpy(host_pref_buf, "disabled");
} else {
+ 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)) {
+ if (ast_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";
@@ -10933,7 +11050,7 @@ static int socket_process(struct iax2_thread *thread)
}
} else /* if no codec_prefs IE do it the old way */
pref = iaxs[fr->callno]->prefs;
- format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
+ 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);
}
@@ -10941,22 +11058,22 @@ static int socket_process(struct iax2_thread *thread)
char tmp1[256], tmp2[256], tmp3[256];
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",
- ast_getformatname(iaxs[fr->callno]->peerformat),
- ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peercapability));
+ iax2_getformatname(iaxs[fr->callno]->peerformat),
+ iax2_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peercapability));
format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
}
if (!format) {
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_inet_ntoa(sin.sin_addr),
- ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
- ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
+ iax2_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
+ iax2_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
} else {
ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
ast_inet_ntoa(sin.sin_addr),
- ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
- ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability),
- ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability));
+ 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));
}
}
memset(&ied0, 0, sizeof(ied0));
@@ -10976,12 +11093,13 @@ static int socket_process(struct iax2_thread *thread)
using_prefs = ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
memset(&pref, 0, sizeof(pref));
format = ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP) ?
- iaxs[fr->callno]->peerformat : ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
+ iaxs[fr->callno]->peerformat : iax2_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
strcpy(caller_pref_buf,"disabled");
strcpy(host_pref_buf,"disabled");
} else {
+ struct ast_format tmpfmt;
using_prefs = "mine";
- if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
+ if (ast_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;
@@ -10989,27 +11107,27 @@ static int socket_process(struct iax2_thread *thread)
pref = iaxs[fr->callno]->rprefs;
using_prefs = "caller";
}
- format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
+ format = iax2_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
} else /* if no codec_prefs IE do it the old way */
- format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
+ format = iax2_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
}
}
if (!format) {
char tmp1[256], tmp2[256], tmp3[256];
ast_log(LOG_ERROR, "No best format in %s???\n",
- ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability));
+ iax2_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability));
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_inet_ntoa(sin.sin_addr),
- ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
- ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
+ iax2_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
+ iax2_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
} else {
ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
ast_inet_ntoa(sin.sin_addr),
- ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
- ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability),
- ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability));
+ 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));
}
}
memset(&ied0, 0, sizeof(ied0));
@@ -11038,11 +11156,11 @@ static int socket_process(struct iax2_thread *thread)
"%spriority = %s\n",
ast_inet_ntoa(sin.sin_addr),
VERBOSE_PREFIX_4,
- ast_getformatname(iaxs[fr->callno]->peerformat),
+ iax2_getformatname(iaxs[fr->callno]->peerformat),
VERBOSE_PREFIX_4,
caller_pref_buf,
VERBOSE_PREFIX_4,
- ast_getformatname(format),
+ iax2_getformatname(format),
VERBOSE_PREFIX_4,
host_pref_buf,
VERBOSE_PREFIX_4,
@@ -11117,7 +11235,7 @@ immediatedial:
ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
ast_verb(3, "Accepting DIAL from %s, formats = %s\n",
ast_inet_ntoa(sin.sin_addr),
- ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat));
+ iax2_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat));
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)))
@@ -11396,9 +11514,12 @@ immediatedial:
send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
} else if (minivid) {
f.frametype = AST_FRAME_VIDEO;
- if (iaxs[fr->callno]->videoformat > 0)
- f.subclass.codec = iaxs[fr->callno]->videoformat | (ntohs(vh->ts) & 0x8000LL ? 1 : 0);
- else {
+ if (iaxs[fr->callno]->videoformat > 0) {
+ if (ntohs(vh->ts) & 0x8000LL) {
+ ast_format_set_video_mark(&f.subclass.format);
+ }
+ ast_format_from_old_bitfield(&f.subclass.format, iaxs[fr->callno]->videoformat);
+ } else {
ast_log(LOG_WARNING, "Received mini frame before first full video frame\n");
iax2_vnak(fr->callno);
ast_variables_destroy(ies.vars);
@@ -11420,7 +11541,7 @@ immediatedial:
/* A mini frame */
f.frametype = AST_FRAME_VOICE;
if (iaxs[fr->callno]->voiceformat > 0)
- f.subclass.codec = iaxs[fr->callno]->voiceformat;
+ ast_format_from_old_bitfield(&f.subclass.format, iaxs[fr->callno]->voiceformat);
else {
ast_debug(1, "Received mini frame before first full voice frame\n");
iax2_vnak(fr->callno);
@@ -11492,7 +11613,7 @@ immediatedial:
if (f.datalen && (f.frametype == AST_FRAME_VOICE)) {
f.samples = ast_codec_get_samples(&f);
/* We need to byteswap incoming slinear samples from network byte order */
- if (f.subclass.codec == AST_FORMAT_SLINEAR)
+ if (f.subclass.format.id == AST_FORMAT_SLINEAR)
ast_frame_byteswap_be(&f);
} else
f.samples = 0;
@@ -11982,11 +12103,10 @@ static void free_context(struct iax2_context *con)
}
}
-static struct ast_channel *iax2_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause)
+static struct ast_channel *iax2_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *data, int *cause)
{
int callno;
int res;
- format_t fmt, native;
struct sockaddr_in sin;
struct ast_channel *c;
struct parsed_dial_string pds;
@@ -12001,12 +12121,11 @@ static struct ast_channel *iax2_request(const char *type, format_t format, const
ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data);
return NULL;
}
-
memset(&cai, 0, sizeof(cai));
cai.capability = iax2_capability;
ast_copy_flags64(&cai, &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
-
+
/* Populate our address from the given */
if (create_addr(pds.peer, NULL, &sin, &cai)) {
*cause = AST_CAUSE_UNREGISTERED;
@@ -12039,23 +12158,28 @@ static struct ast_channel *iax2_request(const char *type, format_t format, const
ast_mutex_unlock(&iaxsl[callno]);
if (c) {
+ struct ast_format_cap *joint;
+
/* Choose a format we can live with */
- if (c->nativeformats & format)
- c->nativeformats &= format;
- else {
- native = c->nativeformats;
- fmt = format;
- res = ast_translator_best_choice(&fmt, &native);
+ if ((joint = ast_format_cap_joint(c->nativeformats, cap))) {
+ ast_format_cap_copy(c->nativeformats, joint);
+ joint = ast_format_cap_destroy(joint);
+ } else {
+ struct ast_format best_fmt_cap;
+ struct ast_format best_fmt_native;
+ res = ast_translator_best_choice(cap, c->nativeformats, &best_fmt_cap, &best_fmt_native);
if (res < 0) {
+ char tmp[256];
+ char tmp2[256];
ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n",
- ast_getformatname(c->nativeformats), ast_getformatname(fmt), c->name);
+ ast_getformatname_multiple(tmp, sizeof(tmp), c->nativeformats), ast_getformatname_multiple(tmp2, sizeof(tmp2), cap), c->name);
ast_hangup(c);
return NULL;
}
- c->nativeformats = native;
+ ast_format_cap_set(c->nativeformats, &best_fmt_native);
}
- c->readformat = ast_best_codec(c->nativeformats);
- c->writeformat = c->readformat;
+ ast_best_codec(c->nativeformats, &c->readformat);
+ ast_format_copy(&c->writeformat, &c->readformat);
}
return c;
@@ -12429,9 +12553,9 @@ static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, st
} else if (!strcasecmp(v->name, "username")) {
ast_string_field_set(peer, username, v->value);
} else if (!strcasecmp(v->name, "allow")) {
- ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1);
+ iax2_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1);
} else if (!strcasecmp(v->name, "disallow")) {
- ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0);
+ iax2_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0);
} else if (!strcasecmp(v->name, "callerid")) {
if (!ast_strlen_zero(v->value)) {
char name2[80];
@@ -12641,9 +12765,9 @@ static struct iax2_user *build_user(const char *name, struct ast_variable *v, st
}
}
} else if (!strcasecmp(v->name, "allow")) {
- ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1);
+ iax2_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1);
} else if (!strcasecmp(v->name, "disallow")) {
- ast_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0);
+ iax2_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0);
} else if (!strcasecmp(v->name, "trunk")) {
ast_set2_flag64(user, ast_true(v->value), IAX_TRUNK);
if (ast_test_flag64(user, IAX_TRUNK) && !timer) {
@@ -12903,7 +13027,7 @@ static void set_config_destroy(void)
static int set_config(const char *config_file, int reload)
{
struct ast_config *cfg, *ucfg;
- format_t capability = iax2_capability;
+ iax2_format capability = iax2_capability;
struct ast_variable *v;
char *cat;
const char *utype;
@@ -13164,9 +13288,9 @@ static int set_config(const char *config_file, int reload)
} else
ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n");
} else if (!strcasecmp(v->name, "allow")) {
- ast_parse_allow_disallow(&prefs, &capability, v->value, 1);
+ iax2_parse_allow_disallow(&prefs, &capability, v->value, 1);
} else if (!strcasecmp(v->name, "disallow")) {
- ast_parse_allow_disallow(&prefs, &capability, v->value, 0);
+ iax2_parse_allow_disallow(&prefs, &capability, v->value, 0);
} else if (!strcasecmp(v->name, "register")) {
iax2_register(v->value, v->lineno);
} else if (!strcasecmp(v->name, "iaxcompat")) {
@@ -13802,19 +13926,18 @@ 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")) {
- ast_getformatname_multiple(buf, len -1, peer->capability);
+ iax2_getformatname_multiple(buf, len -1, peer->capability);
} else if (!strncasecmp(colname, "codec[", 6)) {
char *codecnum, *ptr;
- int codec = 0;
-
+ struct ast_format tmpfmt;
codecnum = strchr(colname, '[');
*codecnum = '\0';
codecnum++;
if ((ptr = strchr(codecnum, ']'))) {
*ptr = '\0';
}
- if((codec = ast_codec_pref_index(&peer->prefs, atoi(codecnum)))) {
- ast_copy_string(buf, ast_getformatname(codec), len);
+ if((ast_codec_pref_index(&peer->prefs, atoi(codecnum), &tmpfmt))) {
+ ast_copy_string(buf, ast_getformatname(&tmpfmt), len);
} else {
buf[0] = '\0';
}
@@ -14273,6 +14396,8 @@ static int __unload_module(void)
if (con)
ast_context_destroy(con, "IAX2");
ast_unload_realtime("iaxpeers");
+
+ iax2_tech.capabilities = ast_format_cap_destroy(iax2_tech.capabilities);
return 0;
}
@@ -14436,7 +14561,7 @@ static int peers_data_provider_get(const struct ast_data_search *search,
ast_data_add_structure(iax2_peer, data_peer, peer);
- ast_data_add_codecs(data_peer, "codecs", peer->capability);
+ iax2_data_add_codecs(data_peer, "codecs", peer->capability);
peer_status(peer, status, sizeof(status));
ast_data_add_str(data_peer, "status", status);
@@ -14500,7 +14625,7 @@ static int users_data_provider_get(const struct ast_data_search *search,
ast_data_add_structure(iax2_user, data_user, user);
- ast_data_add_codecs(data_user, "codecs", user->capability);
+ iax2_data_add_codecs(data_user, "codecs", user->capability);
if (!ast_strlen_zero(user->secret)) {
ast_copy_string(auth, user->secret, sizeof(auth));
@@ -14576,6 +14701,11 @@ static int load_module(void)
int x = 0;
struct iax2_registry *reg = NULL;
+ if (!(iax2_tech.capabilities = ast_format_cap_alloc())) {
+ return AST_MODULE_LOAD_FAILURE;
+ }
+ ast_format_cap_add_all(iax2_tech.capabilities);
+
if (load_objects()) {
return AST_MODULE_LOAD_FAILURE;
}