summaryrefslogtreecommitdiff
path: root/channels/chan_unistim.c
diff options
context:
space:
mode:
authorDavid Vossel <dvossel@digium.com>2011-02-03 16:22:10 +0000
committerDavid Vossel <dvossel@digium.com>2011-02-03 16:22:10 +0000
commitc26c190711a1bbe3b5fff1a93facae333757c56e (patch)
tree00da0caa5a07b7b25729f089dbcafb08129fa9be /channels/chan_unistim.c
parent652fb64a01c7a8656697d07e606620ee0ced6929 (diff)
Asterisk media architecture conversion - no more format bitfields
This patch is the foundation of an entire new way of looking at media in Asterisk. The code present in this patch is everything required to complete phase1 of my Media Architecture proposal. For more information about this project visit the link below. https://wiki.asterisk.org/wiki/display/AST/Media+Architecture+Proposal The primary function of this patch is to convert all the usages of format bitfields in Asterisk to use the new format and format_cap APIs. Functionally no change in behavior should be present in this patch. Thanks to twilson and russell for all the time they spent reviewing these changes. Review: https://reviewboard.asterisk.org/r/1083/ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@306010 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'channels/chan_unistim.c')
-rw-r--r--channels/chan_unistim.c179
1 files changed, 111 insertions, 68 deletions
diff --git a/channels/chan_unistim.c b/channels/chan_unistim.c
index 155890250..4cb5dd71a 100644
--- a/channels/chan_unistim.c
+++ b/channels/chan_unistim.c
@@ -71,7 +71,6 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/indications.h"
/*! Beware, G729 and G723 are not supported by asterisk, except with the proper licence */
-#define CAPABILITY AST_FORMAT_ALAW | AST_FORMAT_ULAW /* | AST_FORMAT_G729A | AST_FORMAT_G723_1 */
#define DEFAULTCONTEXT "default"
#define DEFAULTCALLERID "Unknown"
@@ -102,6 +101,8 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#define SUB_THREEWAY 1
#define MAX_SUBS 2
+struct ast_format_cap *global_cap;
+
enum autoprovision {
AUTOPROVISIONING_NO = 0,
AUTOPROVISIONING_YES,
@@ -409,7 +410,7 @@ struct unistim_line {
/*! AMA flags (for billing) */
int amaflags;
/*! Codec supported */
- format_t capability;
+ struct ast_format_cap *cap;
/*! Parkinglot */
char parkinglot[AST_MAX_CONTEXT];
struct unistim_line *next;
@@ -679,7 +680,7 @@ static int reload(void);
static int unload_module(void);
static int reload_config(void);
static void show_main_page(struct unistimsession *pte);
-static struct ast_channel *unistim_request(const char *type, format_t format, const struct ast_channel *requestor,
+static struct ast_channel *unistim_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor,
void *data, int *cause);
static int unistim_call(struct ast_channel *ast, char *dest, int timeout);
static int unistim_hangup(struct ast_channel *ast);
@@ -698,10 +699,9 @@ static int write_entry_history(struct unistimsession *pte, FILE * f, char c,
char *line1);
static void change_callerid(struct unistimsession *pte, int type, char *callerid);
-static const struct ast_channel_tech unistim_tech = {
+static struct ast_channel_tech unistim_tech = {
.type = channel_type,
.description = tdesc,
- .capabilities = CAPABILITY,
.properties = AST_CHAN_TP_WANTSJITTER | AST_CHAN_TP_CREATESJITTER,
.requester = unistim_request,
.call = unistim_call,
@@ -1483,6 +1483,38 @@ static int unistim_register(struct unistimsession *s)
return 1;
}
+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);
+}
+
+static struct unistim_line *unistim_line_destroy(struct unistim_line *l)
+{
+ if (!l) {
+ return NULL;
+ }
+ l->cap = ast_format_cap_destroy(l->cap);
+ ast_free(l);
+ return NULL;
+}
+
+static struct unistim_line *unistim_line_alloc(void)
+{
+ struct unistim_line *l;
+ if (!(l = ast_calloc(1, sizeof(*l)))) {
+ return NULL;
+ }
+
+ if (!(l->cap = ast_format_cap_alloc_nolock())) {
+ ast_free(l);
+ return NULL;
+ }
+ return l;
+}
+
static int alloc_sub(struct unistim_line *l, int x)
{
struct unistim_subchannel *sub;
@@ -1554,16 +1586,16 @@ static void rcv_mac_addr(struct unistimsession *pte, const unsigned char *buf)
}
memcpy(newd, d, sizeof(*newd));
- if (!(newl = ast_malloc(sizeof(*newl)))) {
+ if (!(newl = unistim_line_alloc())) {
ast_free(newd);
ast_mutex_unlock(&devicelock);
return;
}
- memcpy(newl, d->lines, sizeof(*newl));
+ unistim_line_copy(d->lines, newl);
if (!alloc_sub(newl, SUB_REAL)) {
ast_free(newd);
- ast_free(newl);
+ unistim_line_destroy(newl);
ast_mutex_unlock(&devicelock);
return;
}
@@ -2038,7 +2070,7 @@ static void start_rtp(struct unistim_subchannel *sub)
struct sockaddr_in us = { 0, };
struct sockaddr_in public = { 0, };
struct sockaddr_in sin = { 0, };
- format_t codec;
+ int codec;
struct sockaddr_in sout = { 0, };
struct ast_sockaddr us_tmp;
struct ast_sockaddr sin_tmp;
@@ -2093,19 +2125,19 @@ static void start_rtp(struct unistim_subchannel *sub)
sin.sin_port = htons(sub->parent->parent->rtp_port);
ast_sockaddr_from_sin(&sin_tmp, &sin);
ast_rtp_instance_set_remote_address(sub->rtp, &sin_tmp);
- if (!(sub->owner->nativeformats & sub->owner->readformat)) {
- format_t fmt;
+ if (!(ast_format_cap_iscompatible(sub->owner->nativeformats, &sub->owner->readformat))) {
+ struct ast_format tmpfmt;
char tmp[256];
- fmt = ast_best_codec(sub->owner->nativeformats);
+ ast_best_codec(sub->owner->nativeformats, &tmpfmt);
ast_log(LOG_WARNING,
"Our read/writeformat has been changed to something incompatible: %s, using %s best codec from %s\n",
- ast_getformatname(sub->owner->readformat),
- ast_getformatname(fmt),
+ ast_getformatname(&sub->owner->readformat),
+ ast_getformatname(&tmpfmt),
ast_getformatname_multiple(tmp, sizeof(tmp), sub->owner->nativeformats));
- sub->owner->readformat = fmt;
- sub->owner->writeformat = fmt;
+ ast_format_copy(&sub->owner->readformat, &tmpfmt);
+ ast_format_copy(&sub->owner->writeformat, &tmpfmt);
}
- codec = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(sub->rtp), 1, sub->owner->readformat);
+ codec = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(sub->rtp), 1, &sub->owner->readformat, 0);
/* Setting up RTP of the phone */
if (public_ip.sin_family == 0) /* NAT IP override ? */
memcpy(&public, &us, sizeof(public)); /* No defined, using IP from recvmsg */
@@ -2114,14 +2146,14 @@ static void 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(sub->owner->readformat));
+ htons(us.sin_port), ast_getformatname(&sub->owner->readformat));
ast_verb(0, "Starting phone RTP stack. Our public IP is %s\n",
ast_inet_ntoa(public.sin_addr));
}
- if ((sub->owner->readformat == AST_FORMAT_ULAW) ||
- (sub->owner->readformat == AST_FORMAT_ALAW)) {
+ if ((sub->owner->readformat.id == AST_FORMAT_ULAW) ||
+ (sub->owner->readformat.id == AST_FORMAT_ALAW)) {
if (unistimdebug)
- ast_verb(0, "Sending packet_send_rtp_packet_size for codec %s\n", ast_getformatname(codec));
+ ast_verb(0, "Sending packet_send_rtp_packet_size for codec %d\n", codec);
memcpy(buffsend + SIZE_HEADER, packet_send_rtp_packet_size,
sizeof(packet_send_rtp_packet_size));
buffsend[10] = (int) codec & 0xffffffffLL;
@@ -2214,17 +2246,17 @@ static void start_rtp(struct unistim_subchannel *sub)
/* Codec */
buffsend[40] = codec;
buffsend[41] = codec;
- if (sub->owner->readformat == AST_FORMAT_ULAW)
+ if (sub->owner->readformat.id == AST_FORMAT_ULAW)
buffsend[42] = 1; /* 1 = 20ms (160 bytes), 2 = 40ms (320 bytes) */
- else if (sub->owner->readformat == AST_FORMAT_ALAW)
+ else if (sub->owner->readformat.id == AST_FORMAT_ALAW)
buffsend[42] = 1; /* 1 = 20ms (160 bytes), 2 = 40ms (320 bytes) */
- else if (sub->owner->readformat == AST_FORMAT_G723_1)
+ else if (sub->owner->readformat.id == AST_FORMAT_G723_1)
buffsend[42] = 2; /* 1 = 30ms (24 bytes), 2 = 60 ms (48 bytes) */
- else if (sub->owner->readformat == AST_FORMAT_G729A)
+ else if (sub->owner->readformat.id == AST_FORMAT_G729A)
buffsend[42] = 2; /* 1 = 10ms (10 bytes), 2 = 20ms (20 bytes) */
else
ast_log(LOG_WARNING, "Unsupported codec %s!\n",
- ast_getformatname(sub->owner->readformat));
+ ast_getformatname(&sub->owner->readformat));
/* Source port for transmit RTP and Destination port for receiving RTP */
buffsend[45] = (htons(sin.sin_port) & 0xff00) >> 8;
buffsend[46] = (htons(sin.sin_port) & 0x00ff);
@@ -4005,15 +4037,16 @@ 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 (f->subclass.codec != sub->owner->nativeformats) {
+ if (!(ast_format_cap_iscompatible(sub->owner->nativeformats, &f->subclass.format))) {
+ char tmp[256];
ast_debug(1,
"Oooh, format changed from %s to %s\n",
- ast_getformatname(sub->owner->nativeformats),
- ast_getformatname(f->subclass.codec));
+ ast_getformatname_multiple(tmp, sizeof(tmp), sub->owner->nativeformats),
+ ast_getformatname(&f->subclass.format));
- sub->owner->nativeformats = f->subclass.codec;
- ast_set_read_format(sub->owner, sub->owner->readformat);
- ast_set_write_format(sub->owner, sub->owner->writeformat);
+ ast_format_cap_set(sub->owner->nativeformats, &f->subclass.format);
+ ast_set_read_format(sub->owner, &sub->owner->readformat);
+ ast_set_write_format(sub->owner, &sub->owner->writeformat);
}
}
}
@@ -4047,14 +4080,14 @@ static int unistim_write(struct ast_channel *ast, struct ast_frame *frame)
return 0;
}
} else {
- if (!(frame->subclass.codec & ast->nativeformats)) {
+ if (!(ast_format_cap_iscompatible(ast->nativeformats, &frame->subclass.format))) {
char tmp[256];
ast_log(LOG_WARNING,
"Asked to transmit frame type %s, while native formats is %s (read/write = (%s/%s)\n",
- ast_getformatname(frame->subclass.codec),
+ ast_getformatname(&frame->subclass.format),
ast_getformatname_multiple(tmp, sizeof(tmp), ast->nativeformats),
- ast_getformatname(ast->readformat),
- ast_getformatname(ast->writeformat));
+ ast_getformatname(&ast->readformat),
+ ast_getformatname(&ast->writeformat));
return -1;
}
}
@@ -4499,7 +4532,7 @@ static struct ast_channel *unistim_new(struct unistim_subchannel *sub, int state
{
struct ast_channel *tmp;
struct unistim_line *l;
- int fmt;
+ struct ast_format tmpfmt;
if (!sub) {
ast_log(LOG_WARNING, "subchannel null in unistim_new\n");
@@ -4519,17 +4552,17 @@ static struct ast_channel *unistim_new(struct unistim_subchannel *sub, int state
return NULL;
}
- tmp->nativeformats = l->capability;
- if (!tmp->nativeformats)
- tmp->nativeformats = CAPABILITY;
- fmt = ast_best_codec(tmp->nativeformats);
+ ast_format_cap_copy(tmp->nativeformats, l->cap);
+ if (ast_format_cap_is_empty(tmp->nativeformats))
+ ast_format_cap_copy(tmp->nativeformats, global_cap);
+ ast_best_codec(tmp->nativeformats, &tmpfmt);
if (unistimdebug) {
char tmp1[256], tmp2[256], tmp3[256];
ast_verb(0, "Best codec = %s from nativeformats %s (line cap=%s global=%s)\n",
- ast_getformatname(fmt),
+ ast_getformatname(&tmpfmt),
ast_getformatname_multiple(tmp1, sizeof(tmp1), tmp->nativeformats),
- ast_getformatname_multiple(tmp2, sizeof(tmp2), l->capability),
- ast_getformatname_multiple(tmp3, sizeof(tmp3), CAPABILITY));
+ ast_getformatname_multiple(tmp2, sizeof(tmp2), l->cap),
+ ast_getformatname_multiple(tmp3, sizeof(tmp3), global_cap));
}
if ((sub->rtp) && (sub->subtype == 0)) {
if (unistimdebug)
@@ -4545,10 +4578,10 @@ static struct ast_channel *unistim_new(struct unistim_subchannel *sub, int state
if (state == AST_STATE_RING)
tmp->rings = 1;
tmp->adsicpe = AST_ADSI_UNAVAILABLE;
- tmp->writeformat = fmt;
- tmp->rawwriteformat = fmt;
- tmp->readformat = fmt;
- tmp->rawreadformat = fmt;
+ ast_format_copy(&tmp->writeformat, &tmpfmt);
+ ast_format_copy(&tmp->rawwriteformat, &tmpfmt);
+ ast_format_copy(&tmp->readformat, &tmpfmt);
+ ast_format_copy(&tmp->rawreadformat, &tmpfmt);
tmp->tech_pvt = sub;
tmp->tech = &unistim_tech;
if (!ast_strlen_zero(l->language))
@@ -4699,26 +4732,19 @@ static int restart_monitor(void)
/*--- unistim_request: PBX interface function ---*/
/* UNISTIM calls initiated by the PBX arrive here */
-static struct ast_channel *unistim_request(const char *type, format_t format, const struct ast_channel *requestor, void *data,
+static struct ast_channel *unistim_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *data,
int *cause)
{
- format_t oldformat;
struct unistim_subchannel *sub;
struct ast_channel *tmpc = NULL;
char tmp[256];
+ char tmp2[256];
char *dest = data;
- oldformat = format;
- format &= CAPABILITY;
- ast_log(LOG_NOTICE,
- "Asked to get a channel of format %s while capability is %s result : %s\n",
- ast_getformatname(oldformat),
- ast_getformatname_multiple(tmp, sizeof(tmp), CAPABILITY),
- ast_getformatname(format));
- if (!format) {
+ if (!(ast_format_cap_has_joint(cap, global_cap))) {
ast_log(LOG_NOTICE,
"Asked to get a channel of unsupported format %s while capability is %s\n",
- ast_getformatname(oldformat), ast_getformatname_multiple(tmp, sizeof(tmp), CAPABILITY));
+ ast_getformatname_multiple(tmp2, sizeof(tmp2), cap), ast_getformatname_multiple(tmp, sizeof(tmp), global_cap));
return NULL;
}
@@ -4743,7 +4769,7 @@ static struct ast_channel *unistim_request(const char *type, format_t format, co
*cause = AST_CAUSE_BUSY;
return NULL;
}
- sub->parent->capability = format;
+ ast_format_cap_copy(sub->parent->cap, cap);
tmpc = unistim_new(sub, AST_STATE_DOWN, requestor ? requestor->linkedid : NULL);
if (!tmpc)
ast_log(LOG_WARNING, "Unable to make channel for '%s'\n", tmp);
@@ -4786,10 +4812,11 @@ static char *unistim_info(struct ast_cli_entry *e, int cmd, struct ast_cli_args
device);
line = device->lines;
while (line) {
+ char tmp2[256];
ast_cli(a->fd,
- "->name=%s fullname=%s exten=%s callid=%s cap=%" PRId64 " device=%p line=%p\n",
+ "->name=%s fullname=%s exten=%s callid=%s cap=%s device=%p line=%p\n",
line->name, line->fullname, line->exten, line->cid_num,
- line->capability, line->parent, line);
+ ast_getformatname_multiple(tmp2, sizeof(tmp2), line->cap), line->parent, line);
for (i = 0; i < MAX_SUBS; i++) {
sub = line->subs[i];
if (!sub)
@@ -5080,6 +5107,7 @@ static void finish_bookmark(void)
}
}
+
static struct unistim_device *build_device(const char *cat, const struct ast_variable *v)
{
struct unistim_device *d;
@@ -5115,7 +5143,7 @@ static struct unistim_device *build_device(const char *cat, const struct ast_var
if (!(d = ast_calloc(1, sizeof(*d))))
return NULL;
- if (!(l = ast_calloc(1, sizeof(*l)))) {
+ if (!(l = unistim_line_alloc())) {
ast_free(d);
return NULL;
}
@@ -5232,7 +5260,7 @@ static struct unistim_device *build_device(const char *cat, const struct ast_var
"You must use bookmark AFTER line=>. Only one line is supported in this version\n");
if (create) {
ast_free(d);
- ast_free(l);
+ unistim_line_destroy(l);
}
return NULL;
}
@@ -5277,13 +5305,13 @@ 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);
}
- l->capability = CAPABILITY;
+ ast_format_cap_copy(l->cap, global_cap);
l->parent = d;
if (create) {
if (!alloc_sub(l, SUB_REAL)) {
ast_mutex_destroy(&l->lock);
- ast_free(l);
+ unistim_line_destroy(l);
ast_free(d);
return NULL;
}
@@ -5311,7 +5339,7 @@ static struct unistim_device *build_device(const char *cat, const struct ast_var
if (!d->lines) {
ast_log(LOG_ERROR, "An Unistim device must have at least one line!\n");
ast_mutex_destroy(&l->lock);
- ast_free(l);
+ unistim_line_destroy(l);
if (d->tz) {
d->tz = ast_tone_zone_unref(d->tz);
}
@@ -5331,7 +5359,7 @@ static struct unistim_device *build_device(const char *cat, const struct ast_var
if (strcmp(d->name, "template")) {
ast_log(LOG_ERROR, "You must specify the mac address with device=\n");
ast_mutex_destroy(&l->lock);
- ast_free(l);
+ unistim_line_destroy(l);
if (d->tz) {
d->tz = ast_tone_zone_unref(d->tz);
}
@@ -5635,7 +5663,17 @@ 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())) {
+ goto buff_failed;
+ }
+ if (!(unistim_tech.capabilities = ast_format_cap_alloc())) {
+ 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);
if (!(buff = ast_malloc(SIZE_PAGE)))
goto buff_failed;
@@ -5679,6 +5717,8 @@ 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:
return AST_MODULE_LOAD_FAILURE;
}
@@ -5709,6 +5749,9 @@ 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);
+
return 0;
}