aboutsummaryrefslogtreecommitdiffstats
path: root/channels/chan_jingle.c
diff options
context:
space:
mode:
authordvossel <dvossel@f38db490-d61c-443f-a65b-d21fe96a405b>2011-02-03 16:22:10 +0000
committerdvossel <dvossel@f38db490-d61c-443f-a65b-d21fe96a405b>2011-02-03 16:22:10 +0000
commit4aca3187a3db25ff4d2208f116f618b363dec7d5 (patch)
tree00da0caa5a07b7b25729f089dbcafb08129fa9be /channels/chan_jingle.c
parent8170aae0a0882a93ca1ef80736cb95c2d6126865 (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: http://svn.digium.com/svn/asterisk/trunk@306010 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'channels/chan_jingle.c')
-rw-r--r--channels/chan_jingle.c152
1 files changed, 99 insertions, 53 deletions
diff --git a/channels/chan_jingle.c b/channels/chan_jingle.c
index fd84f1f27..93d81d954 100644
--- a/channels/chan_jingle.c
+++ b/channels/chan_jingle.c
@@ -104,7 +104,6 @@ struct jingle_pvt {
iksrule *ringrule; /*!< Rule for matching RING request */
int initiator; /*!< If we're the initiator */
int alreadygone;
- format_t capability;
struct ast_codec_pref prefs;
struct jingle_candidate *theircandidates;
struct jingle_candidate *ourcandidates;
@@ -116,8 +115,9 @@ struct jingle_pvt {
struct ast_rtp_instance *rtp; /*!< RTP audio session */
char video_content_name[100]; /*!< name attribute of content tag */
struct ast_rtp_instance *vrtp; /*!< RTP video session */
- format_t jointcapability; /*!< Supported capability at both ends (codecs ) */
- format_t peercapability;
+ struct ast_format_cap *cap;
+ struct ast_format_cap *jointcap; /*!< Supported capability at both ends (codecs ) */
+ struct ast_format_cap *peercap;
struct jingle_pvt *next; /* Next entity */
};
@@ -147,7 +147,7 @@ struct jingle {
char user[100];
char context[100];
char accountcode[AST_MAX_ACCOUNT_CODE]; /*!< Account code */
- format_t capability;
+ struct ast_format_cap *cap;
ast_group_t callgroup; /*!< Call group */
ast_group_t pickupgroup; /*!< Pickup group */
int callingpres; /*!< Calling presentation */
@@ -164,12 +164,12 @@ struct jingle_container {
static const char desc[] = "Jingle Channel";
static const char channel_type[] = "Jingle";
-static format_t global_capability = AST_FORMAT_ULAW | AST_FORMAT_ALAW | AST_FORMAT_GSM | AST_FORMAT_H263;
+static struct ast_format_cap *global_capability;
AST_MUTEX_DEFINE_STATIC(jinglelock); /*!< Protect the interface list (of jingle_pvt's) */
/* Forward declarations */
-static struct ast_channel *jingle_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause);
+static struct ast_channel *jingle_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *data, int *cause);
static int jingle_sendtext(struct ast_channel *ast, const char *text);
static int jingle_digit_begin(struct ast_channel *ast, char digit);
static int jingle_digit_end(struct ast_channel *ast, char digit, unsigned int duration);
@@ -187,10 +187,9 @@ static char *jingle_show_channels(struct ast_cli_entry *e, int cmd, struct ast_c
static char *jingle_do_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a);
/*! \brief PBX interface structure for channel registration */
-static const struct ast_channel_tech jingle_tech = {
+static struct ast_channel_tech jingle_tech = {
.type = "Jingle",
.description = "Jingle Channel Driver",
- .capabilities = AST_FORMAT_AUDIO_MASK,
.requester = jingle_request,
.send_text = jingle_sendtext,
.send_digit_begin = jingle_digit_begin,
@@ -226,6 +225,7 @@ static struct jingle_container jingle_list;
static void jingle_member_destroy(struct jingle *obj)
{
+ obj->cap = ast_format_cap_destroy(obj->cap);
ast_free(obj);
}
@@ -255,7 +255,7 @@ static struct jingle *find_jingle(char *name, char *connection)
}
-static void add_codec_to_answer(const struct jingle_pvt *p, int codec, iks *dcodecs)
+static void add_codec_to_answer(const struct jingle_pvt *p, struct ast_format *codec, iks *dcodecs)
{
char *format = ast_getformatname(codec);
@@ -301,10 +301,10 @@ static int jingle_accept_call(struct jingle *client, struct jingle_pvt *p)
struct aji_client *c = client->connection;
iks *iq, *jingle, *dcodecs, *payload_red, *payload_audio, *payload_cn;
int x;
- format_t pref_codec = 0;
- int alreadysent = 0;
+ struct ast_format pref_codec;
+ struct ast_format_cap *alreadysent = ast_format_cap_alloc_nolock();
- if (p->initiator)
+ if (p->initiator || !alreadysent)
return 1;
iq = iks_new("iq");
@@ -313,15 +313,15 @@ static int jingle_accept_call(struct jingle *client, struct jingle_pvt *p)
if (iq && jingle && dcodecs) {
iks_insert_attrib(dcodecs, "xmlns", JINGLE_AUDIO_RTP_NS);
- for (x = 0; x < 64; x++) {
- if (!(pref_codec = ast_codec_pref_index(&client->prefs, x)))
+ for (x = 0; x < AST_CODEC_PREF_SIZE; x++) {
+ if (!(ast_codec_pref_index(&client->prefs, x, &pref_codec)))
break;
- if (!(client->capability & pref_codec))
+ if (!(ast_format_cap_iscompatible(client->cap, &pref_codec)))
continue;
- if (alreadysent & pref_codec)
+ if ((ast_format_cap_iscompatible(alreadysent, &pref_codec)))
continue;
- add_codec_to_answer(p, pref_codec, dcodecs);
- alreadysent |= pref_codec;
+ add_codec_to_answer(p, &pref_codec, dcodecs);
+ ast_format_cap_add(alreadysent, &pref_codec);
}
payload_red = iks_new("payload-type");
iks_insert_attrib(payload_red, "id", "117");
@@ -358,6 +358,7 @@ static int jingle_accept_call(struct jingle *client, struct jingle_pvt *p)
iks_delete(jingle);
iks_delete(iq);
}
+ alreadysent = ast_format_cap_destroy(alreadysent);
return 1;
}
@@ -405,13 +406,15 @@ static enum ast_rtp_glue_result jingle_get_rtp_peer(struct ast_channel *chan, st
return res;
}
-static format_t jingle_get_codec(struct ast_channel *chan)
+static void jingle_get_codec(struct ast_channel *chan, struct ast_format_cap *result)
{
struct jingle_pvt *p = chan->tech_pvt;
- return p->peercapability;
+ ast_mutex_lock(&p->lock);
+ ast_format_cap_copy(result, p->peercap);
+ ast_mutex_unlock(&p->lock);
}
-static int jingle_set_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance *rtp, struct ast_rtp_instance *vrtp, struct ast_rtp_instance *tpeer, format_t codecs, int nat_active)
+static int jingle_set_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance *rtp, struct ast_rtp_instance *vrtp, struct ast_rtp_instance *tpeer, const struct ast_format_cap *cap, int nat_active)
{
struct jingle_pvt *p;
@@ -772,6 +775,16 @@ static struct jingle_pvt *jingle_alloc(struct jingle *client, const char *from,
return NULL;
}
+ tmp->cap = ast_format_cap_alloc_nolock();
+ tmp->jointcap = ast_format_cap_alloc_nolock();
+ tmp->peercap = ast_format_cap_alloc_nolock();
+ if (!tmp->cap || !tmp->jointcap || !tmp->peercap) {
+ tmp->cap = ast_format_cap_destroy(tmp->cap);
+ tmp->jointcap = ast_format_cap_destroy(tmp->jointcap);
+ tmp->peercap = ast_format_cap_destroy(tmp->peercap);
+ ast_free(tmp);
+ return NULL;
+ }
memcpy(&tmp->prefs, &client->prefs, sizeof(tmp->prefs));
if (sid) {
@@ -803,8 +816,8 @@ static struct jingle_pvt *jingle_alloc(struct jingle *client, const char *from,
static struct ast_channel *jingle_new(struct jingle *client, struct jingle_pvt *i, int state, const char *title, const char *linkedid)
{
struct ast_channel *tmp;
- int fmt;
- int what;
+ struct ast_format_cap *what; /* SHALLOW COPY DO NOT DESTROY */
+ struct ast_format tmpfmt;
const char *str;
if (title)
@@ -820,10 +833,10 @@ static struct ast_channel *jingle_new(struct jingle *client, struct jingle_pvt *
/* Select our native format based on codec preference until we receive
something from another device to the contrary. */
- if (i->jointcapability)
- what = i->jointcapability;
- else if (i->capability)
- what = i->capability;
+ if (!ast_format_cap_is_empty(i->jointcap))
+ what = i->jointcap;
+ else if (!(ast_format_cap_is_empty(i->cap)))
+ what = i->cap;
else
what = global_capability;
@@ -831,8 +844,16 @@ static struct ast_channel *jingle_new(struct jingle *client, struct jingle_pvt *
if (i->rtp)
ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(i->rtp), i->rtp, &i->prefs);
- tmp->nativeformats = ast_codec_choose(&i->prefs, what, 1) | (i->jointcapability & AST_FORMAT_VIDEO_MASK);
- fmt = ast_best_codec(tmp->nativeformats);
+ ast_codec_choose(&i->prefs, what, 1, &tmpfmt);
+ ast_format_cap_add(tmp->nativeformats, &tmpfmt);
+
+ ast_format_cap_iter_start(i->jointcap);
+ while (!(ast_format_cap_iter_next(i->jointcap, &tmpfmt))) {
+ if (AST_FORMAT_GET_TYPE(tmpfmt.id) == AST_FORMAT_TYPE_VIDEO) {
+ ast_format_cap_add(tmp->nativeformats, &tmpfmt);
+ }
+ }
+ ast_format_cap_iter_end(i->jointcap);
if (i->rtp) {
ast_channel_set_fd(tmp, 0, ast_rtp_instance_fd(i->rtp, 0));
@@ -845,10 +866,13 @@ static struct ast_channel *jingle_new(struct jingle *client, struct jingle_pvt *
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_best_codec(tmp->nativeformats, &tmpfmt);
+ 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 = i;
tmp->callgroup = client->callgroup;
@@ -955,6 +979,10 @@ static void jingle_free_pvt(struct jingle *client, struct jingle_pvt *p)
if (p->vrtp)
ast_rtp_instance_destroy(p->vrtp);
jingle_free_candidates(p->theircandidates);
+ p->cap = ast_format_cap_destroy(p->cap);
+ p->jointcap = ast_format_cap_destroy(p->jointcap);
+ p->peercap = ast_format_cap_destroy(p->peercap);
+
ast_free(p);
}
@@ -1185,12 +1213,12 @@ static struct ast_frame *jingle_rtp_read(struct ast_channel *ast, struct jingle_
if (p->owner) {
/* We already hold the channel lock */
if (f->frametype == AST_FRAME_VOICE) {
- if (f->subclass.codec != (p->owner->nativeformats & AST_FORMAT_AUDIO_MASK)) {
- ast_debug(1, "Oooh, format changed to %s\n", ast_getformatname(f->subclass.codec));
- p->owner->nativeformats =
- (p->owner->nativeformats & AST_FORMAT_VIDEO_MASK) | f->subclass.codec;
- ast_set_read_format(p->owner, p->owner->readformat);
- ast_set_write_format(p->owner, p->owner->writeformat);
+ if (!(ast_format_cap_iscompatible(p->owner->nativeformats, &f->subclass.format))) {
+ ast_debug(1, "Oooh, format changed to %s\n", ast_getformatname(&f->subclass.format));
+ ast_format_cap_remove_bytype(p->owner->nativeformats, AST_FORMAT_TYPE_AUDIO);
+ ast_format_cap_add(p->owner->nativeformats, &f->subclass.format);
+ ast_set_read_format(p->owner, &p->owner->readformat);
+ ast_set_write_format(p->owner, &p->owner->writeformat);
}
/* if ((ast_test_flag(p, SIP_DTMF) == SIP_DTMF_INBAND) && p->vad) {
f = ast_dsp_process(p->owner, p->vad, f);
@@ -1222,13 +1250,13 @@ static int jingle_write(struct ast_channel *ast, struct ast_frame *frame)
switch (frame->frametype) {
case AST_FRAME_VOICE:
- if (!(frame->subclass.codec & ast->nativeformats)) {
+ if (!(ast_format_cap_iscompatible(ast->nativeformats, &frame->subclass.format))) {
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(buf, sizeof(buf), ast->nativeformats),
- ast_getformatname(ast->readformat),
- ast_getformatname(ast->writeformat));
+ ast_getformatname(&ast->readformat),
+ ast_getformatname(&ast->writeformat));
return 0;
}
if (p) {
@@ -1464,7 +1492,7 @@ static int jingle_call(struct ast_channel *ast, char *dest, int timeout)
}
ast_setstate(ast, AST_STATE_RING);
- p->jointcapability = p->capability;
+ ast_format_cap_copy(p->jointcap, p->cap);
if (!p->ringrule) {
ast_copy_string(p->ring, p->parent->connection->mid, sizeof(p->ring));
p->ringrule = iks_filter_add_rule(p->parent->connection->f, jingle_ringing_ack, p,
@@ -1498,7 +1526,7 @@ static int jingle_hangup(struct ast_channel *ast)
}
/*! \brief Part of PBX interface */
-static struct ast_channel *jingle_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause)
+static struct ast_channel *jingle_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *data, int *cause)
{
struct jingle_pvt *p = NULL;
struct jingle *client = NULL;
@@ -1588,8 +1616,8 @@ static char *jingle_show_channels(struct ast_cli_entry *e, int cmd, struct ast_c
chan->name,
jid,
resource,
- ast_getformatname(chan->readformat),
- ast_getformatname(chan->writeformat)
+ ast_getformatname(&chan->readformat),
+ ast_getformatname(&chan->writeformat)
);
else
ast_log(LOG_WARNING, "No available channel\n");
@@ -1717,9 +1745,9 @@ static int jingle_create_member(char *label, struct ast_variable *var, int allow
if (!strcasecmp(var->name, "username"))
ast_copy_string(member->user, var->value, sizeof(member->user));
else if (!strcasecmp(var->name, "disallow"))
- ast_parse_allow_disallow(&member->prefs, &member->capability, var->value, 0);
+ ast_parse_allow_disallow(&member->prefs, member->cap, var->value, 0);
else if (!strcasecmp(var->name, "allow"))
- ast_parse_allow_disallow(&member->prefs, &member->capability, var->value, 1);
+ ast_parse_allow_disallow(&member->prefs, member->cap, var->value, 1);
else if (!strcasecmp(var->name, "context"))
ast_copy_string(member->context, var->value, sizeof(member->context));
#if 0
@@ -1787,9 +1815,9 @@ static int jingle_load_config(void)
allowguest =
(ast_true(ast_variable_retrieve(cfg, "general", "allowguest"))) ? 1 : 0;
else if (!strcasecmp(var->name, "disallow"))
- ast_parse_allow_disallow(&prefs, &global_capability, var->value, 0);
+ ast_parse_allow_disallow(&prefs, global_capability, var->value, 0);
else if (!strcasecmp(var->name, "allow"))
- ast_parse_allow_disallow(&prefs, &global_capability, var->value, 1);
+ ast_parse_allow_disallow(&prefs, global_capability, var->value, 1);
else if (!strcasecmp(var->name, "context"))
ast_copy_string(context, var->value, sizeof(context));
else if (!strcasecmp(var->name, "externip"))
@@ -1818,6 +1846,7 @@ static int jingle_load_config(void)
member = ast_calloc(1, sizeof(*member));
ASTOBJ_INIT(member);
ASTOBJ_WRLOCK(member);
+ member->cap = ast_format_cap_alloc_nolock();
if (!strcasecmp(cat, "guest")) {
ast_copy_string(member->name, "guest", sizeof(member->name));
ast_copy_string(member->user, "guest", sizeof(member->user));
@@ -1826,10 +1855,10 @@ static int jingle_load_config(void)
member->prefs = prefs;
while (var) {
if (!strcasecmp(var->name, "disallow"))
- ast_parse_allow_disallow(&member->prefs, &member->capability,
+ ast_parse_allow_disallow(&member->prefs, member->cap,
var->value, 0);
else if (!strcasecmp(var->name, "allow"))
- ast_parse_allow_disallow(&member->prefs, &member->capability,
+ ast_parse_allow_disallow(&member->prefs, member->cap,
var->value, 1);
else if (!strcasecmp(var->name, "context"))
ast_copy_string(member->context, var->value,
@@ -1884,8 +1913,23 @@ static int load_module(void)
{
struct ast_sockaddr ourip_tmp;
struct ast_sockaddr bindaddr_tmp;
+ struct ast_format tmpfmt;
char *jabber_loaded = ast_module_helper("", "res_jabber.so", 0, 0, 0, 0);
+
+ if (!(jingle_tech.capabilities = ast_format_cap_alloc())) {
+ return AST_MODULE_LOAD_DECLINE;
+ }
+
+ ast_format_cap_add_all_by_type(jingle_tech.capabilities, AST_FORMAT_TYPE_AUDIO);
+ if (!(global_capability = ast_format_cap_alloc())) {
+ return AST_MODULE_LOAD_DECLINE;
+ }
+ ast_format_cap_add(global_capability, ast_format_set(&tmpfmt, AST_FORMAT_ULAW, 0));
+ ast_format_cap_add(global_capability, ast_format_set(&tmpfmt, AST_FORMAT_GSM, 0));
+ ast_format_cap_add(global_capability, ast_format_set(&tmpfmt, AST_FORMAT_ALAW, 0));
+ ast_format_cap_add(global_capability, ast_format_set(&tmpfmt, AST_FORMAT_H263, 0));
+
free(jabber_loaded);
if (!jabber_loaded) {
/* Dependency module has a different name, if embedded */
@@ -1965,6 +2009,8 @@ static int unload_module(void)
}
ASTOBJ_CONTAINER_DESTROYALL(&jingle_list, jingle_member_destroy);
ASTOBJ_CONTAINER_DESTROY(&jingle_list);
+
+ global_capability = ast_format_cap_destroy(global_capability);
return 0;
}