summaryrefslogtreecommitdiff
path: root/channels/chan_skinny.c
diff options
context:
space:
mode:
Diffstat (limited to 'channels/chan_skinny.c')
-rw-r--r--channels/chan_skinny.c362
1 files changed, 171 insertions, 191 deletions
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;
}