[asterisk-commits] qwell: trunk r43651 - in /trunk: ./
channels/chan_skinny.c
asterisk-commits at lists.digium.com
asterisk-commits at lists.digium.com
Tue Sep 26 08:35:38 MST 2006
Author: qwell
Date: Tue Sep 26 10:35:37 2006
New Revision: 43651
URL: http://svn.digium.com/view/asterisk?rev=43651&view=rev
Log:
Merged revisions 43650 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r43650 | qwell | 2006-09-26 08:33:47 -0700 (Tue, 26 Sep 2006) | 11 lines
Add proper codec support to chan_skinny. Works with at least ulaw, alaw, and g729a.
This is technically a "new feature", but there are justifications for it.
I found a bug with the recent rtp packetization changes, which caused the media setup to
fail under certain circumstances, particularly when using allow=all, or having no allow=
statements (globally or on the device).
I could have either removed the rtp packetization features, or I could add proper codec
support (which, without, I think most people would consider to be a bug anyways).
........
Modified:
trunk/ (props changed)
trunk/channels/chan_skinny.c
Propchange: trunk/
------------------------------------------------------------------------------
--- branch-1.4-merged (original)
+++ branch-1.4-merged Tue Sep 26 10:35:37 2006
@@ -1,1 +1,1 @@
-/branches/1.4:1-43376,43383,43386,43388,43392,43396,43405,43410,43422,43441,43445,43450,43454,43456,43464,43466,43469,43477,43482,43486,43489,43492,43518,43524,43553,43564,43616,43640,43642
+/branches/1.4:1-43376,43383,43386,43388,43392,43396,43405,43410,43422,43441,43445,43450,43454,43456,43464,43466,43469,43477,43482,43486,43489,43492,43518,43524,43553,43564,43616,43640,43642,43650
Modified: trunk/channels/chan_skinny.c
URL: http://svn.digium.com/view/asterisk/trunk/channels/chan_skinny.c?rev=43651&r1=43650&r2=43651&view=diff
==============================================================================
--- trunk/channels/chan_skinny.c (original)
+++ trunk/channels/chan_skinny.c Tue Sep 26 10:35:37 2006
@@ -80,9 +80,18 @@
static const char tdesc[] = "Skinny Client Control Protocol (Skinny)";
static const char config[] = "skinny.conf";
-/* Just about everybody seems to support ulaw, so make it a nice default */
-static int default_capability = AST_FORMAT_ULAW;
+static int default_capability = AST_FORMAT_ULAW | AST_FORMAT_ALAW;
static struct ast_codec_pref default_prefs;
+
+enum skinny_codecs {
+ SKINNY_CODEC_ALAW = 2,
+ SKINNY_CODEC_ULAW = 4,
+ SKINNY_CODEC_G723_1 = 9,
+ SKINNY_CODEC_G729A = 12,
+ SKINNY_CODEC_G726_32 = 82, /* XXX Which packing order does this translate to? */
+ SKINNY_CODEC_H261 = 100,
+ SKINNY_CODEC_H263 = 101
+};
#define DEFAULT_SKINNY_PORT 2000
#define DEFAULT_SKINNY_BACKLOG 2
@@ -183,7 +192,7 @@
uint32_t frames;
union {
char res[8];
- uint64_t rate;
+ uint32_t rate;
} payloads;
};
@@ -1282,6 +1291,50 @@
return sd;
}
+static int codec_skinny2ast(enum skinny_codecs skinnycodec)
+{
+ switch (skinnycodec) {
+ case SKINNY_CODEC_ALAW:
+ return AST_FORMAT_ALAW;
+ case SKINNY_CODEC_ULAW:
+ return AST_FORMAT_ULAW;
+ case SKINNY_CODEC_G723_1:
+ return AST_FORMAT_G723_1;
+ case SKINNY_CODEC_G729A:
+ return AST_FORMAT_G729A;
+ case SKINNY_CODEC_G726_32:
+ return AST_FORMAT_G726_AAL2; /* XXX Is this right? */
+ case SKINNY_CODEC_H261:
+ return AST_FORMAT_H261;
+ case SKINNY_CODEC_H263:
+ return AST_FORMAT_H263;
+ default:
+ return 0;
+ }
+}
+
+static int codec_ast2skinny(int astcodec)
+{
+ switch (astcodec) {
+ case AST_FORMAT_ALAW:
+ return SKINNY_CODEC_ALAW;
+ case AST_FORMAT_ULAW:
+ return SKINNY_CODEC_ULAW;
+ case AST_FORMAT_G723_1:
+ return SKINNY_CODEC_G723_1;
+ case AST_FORMAT_G729A:
+ return SKINNY_CODEC_G729A;
+ case AST_FORMAT_G726_AAL2: /* XXX Is this right? */
+ return SKINNY_CODEC_G726_32;
+ case AST_FORMAT_H261:
+ return SKINNY_CODEC_H261;
+ case AST_FORMAT_H263:
+ return SKINNY_CODEC_H263;
+ default:
+ return 0;
+ }
+}
+
static int transmit_response(struct skinnysession *s, struct skinny_req *req)
{
int res = 0;
@@ -1302,13 +1355,6 @@
}
ast_mutex_unlock(&s->lock);
return 1;
-}
-
-/* XXX Do this right */
-static int convert_cap(int capability)
-{
- return 4; /* ulaw (this is not the same as asterisk's '4' */
-
}
static void transmit_speaker_mode(struct skinnysession *s, int mode)
@@ -1405,14 +1451,17 @@
{
struct skinny_req *req;
struct skinny_line *l = sub->parent;
+ struct ast_format_list fmt;
if (!(req = req_alloc(sizeof(struct open_receive_channel_message), OPEN_RECEIVE_CHANNEL_MESSAGE)))
return;
+ fmt = ast_codec_pref_getsize(&l->prefs, ast_best_codec(l->capability));
+
req->data.openreceivechannel.conferenceId = htolel(0);
req->data.openreceivechannel.partyId = htolel(sub->callid);
- req->data.openreceivechannel.packets = htolel(l->prefs.framing[0]);
- req->data.openreceivechannel.capability = htolel(convert_cap(l->capability));
+ req->data.openreceivechannel.packets = htolel(fmt.cur_ms);
+ req->data.openreceivechannel.capability = htolel(codec_ast2skinny(fmt.bits));
req->data.openreceivechannel.echo = htolel(0);
req->data.openreceivechannel.bitrate = htolel(0);
transmit_response(s, req);
@@ -3279,7 +3328,32 @@
static int handle_capabilities_res_message(struct skinny_req *req, struct skinnysession *s)
{
- /* XXX process the capabilites */
+ struct skinny_device *d = s->device;
+ struct skinny_line *l;
+ int count = 0;
+ int codecs = 0;
+ int i;
+
+ count = letohl(req->data.caps.count);
+
+ for (i = 0; i < count; i++) {
+ int acodec = 0;
+ int scodec = 0;
+ scodec = letohl(req->data.caps.caps[i].codec);
+ acodec = codec_skinny2ast(scodec);
+ if (skinnydebug)
+ ast_verbose("Adding codec capability '%d (%d)'\n", acodec, scodec);
+ codecs |= acodec;
+ }
+
+ d->capability &= codecs;
+ ast_verbose("Device capability set to '%d'\n", d->capability);
+ for (l = d->lines; l; l = l->next) {
+ ast_mutex_lock(&l->lock);
+ l->capability = d->capability;
+ ast_mutex_unlock(&l->lock);
+ }
+
return 1;
}
@@ -3509,6 +3583,7 @@
struct skinny_device *d = s->device;
struct skinny_line *l;
struct skinny_subchannel *sub;
+ struct ast_format_list fmt;
struct sockaddr_in sin;
struct sockaddr_in us;
uint32_t addr;
@@ -3552,12 +3627,17 @@
if (!(req = req_alloc(sizeof(struct start_media_transmission_message), START_MEDIA_TRANSMISSION_MESSAGE)))
return -1;
+ fmt = ast_codec_pref_getsize(&l->prefs, ast_best_codec(l->capability));
+
+ if (skinnydebug)
+ ast_verbose("Setting payloadType to '%d' (%d ms)\n", fmt.bits, fmt.cur_ms);
+
req->data.startmedia.conferenceId = htolel(0);
req->data.startmedia.passThruPartyId = htolel(sub->callid);
req->data.startmedia.remoteIp = htolel(d->ourip.s_addr);
req->data.startmedia.remotePort = htolel(ntohs(us.sin_port));
- req->data.startmedia.packetSize = htolel(l->prefs.framing[0]);
- req->data.startmedia.payloadType = htolel(convert_cap(l->capability));
+ req->data.startmedia.packetSize = htolel(fmt.cur_ms);
+ req->data.startmedia.payloadType = htolel(codec_ast2skinny(fmt.bits));
req->data.startmedia.qualifier.precedence = htolel(127);
req->data.startmedia.qualifier.vad = htolel(0);
req->data.startmedia.qualifier.packets = htolel(0);
@@ -4312,6 +4392,7 @@
return -1;
}
memset(&bindaddr, 0, sizeof(bindaddr));
+ memset(&default_prefs, 0, sizeof(default_prefs));
/* Copy the default jb config over global_jbconf */
memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf));
More information about the asterisk-commits
mailing list