[Asterisk-Dev] Explicit endianness support.
Steve Kann
stevek at stevek.com
Sat Mar 26 14:03:51 MST 2005
On Mar 26, 2005, at 10:48 AM, Mike Taht wrote:
> I went poking about for other endian issues in the code last night,
> and found a big endian bug in iax2-parser.c. (tested, patch supplied
> below) Also, rtp.c looks questionable at put_uint32 without something
> similar. (patch not supplied, untested, my Xscale is at the office,
> with no way to test rtp til monday)
>
> It's unclear to me if all this rigamarole on pulling in an endian
> header is really necessessary... but if it is, it's needed for David's
> patches as well.
>
> With this patch, a big endian Xscale can successfully negotiate codecs
> with other iax2 boxes, without it, only the ulaw path works. Shall I
> file a bug?
This patch doesn't quite make sense to me. The whole get_uint32 and
friends stuff needs to be set up on any platform where you cannot make
unaligned memory access; The endian-ness doesn't matter.
So, for example, your patch would unfairly penalize POWERPC, which can
(at least for modern versions) do unaligned access just fine, but are
also big-endian.
-SteveK
> Index: iax2-parser.c
> ===================================================================
> RCS file: /usr/cvsroot/asterisk/channels/iax2-parser.c,v
> retrieving revision 1.38
> diff -u -r1.38 iax2-parser.c
> --- iax2-parser.c 17 Mar 2005 23:12:15 -0000 1.38
> +++ iax2-parser.c 26 Mar 2005 15:39:06 -0000
> @@ -21,6 +21,21 @@
> #include <unistd.h>
> #include <stdlib.h>
> #include <stdio.h>
> +#if defined( __OpenBSD__ )
> +# include <machine/types.h>
> +# include <sys/endian.h>
> +#elif defined( __FreeBSD__ ) || defined( __NetBSD__ )
> +# include <sys/types.h>
> +# include <sys/endian.h>
> +#elif defined( BSD ) && ( BSD >= 199103 ) || defined(__APPLE__)
> +# include <machine/endian.h>
> +#elif defined( __sparc__ ) && defined( SOLARIS )
> +# define BIG_ENDIAN 4321
> +# define BYTE_ORDER BIG_ENDIAN
> +# define __BYTE_ORDER __BIG_ENDIAN
> +#else
> +# include <endian.h>
> +#endif
> #include "iax2.h"
> #include "iax2-parser.h"
> #include "iax2-provision.h"
> @@ -30,13 +45,13 @@
> static int iframes = 0;
> static int oframes = 0;
>
> -#if defined(SOLARIS) && defined(__sparc__)
> -static unsigned int get_uint32(unsigned char *p)
> +#if __BYTE_ORDER == __BIG_ENDIAN
> +static inline unsigned int get_uint32(unsigned char *p)
> {
> return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
> }
>
> -static unsigned short get_uint16(unsigned char *p)
> +static inline unsigned short get_uint16(unsigned char *p)
> {
> return (p[0] << 8) | p[1] ;
> }
>
>
>
> On Fri, 25 Mar 2005 11:40:16 +0000, David Woodhouse
> <dwmw2 at infradead.org> wrote:
>> Separate patch to make channels explicitly specify the endianness of
>> the
>> linear frames they produce or require.
>>
>> I haven't changed chan_nbs or chan_vpb because I'm not sure if the
>> library we use for each works with native-endian samples or not.
>>
>> Comments or alternative solutions...?
>>
>> Index: rtp.c
>> ===================================================================
>> RCS file: /usr/cvsroot/asterisk/rtp.c,v
>> retrieving revision 1.114
>> diff -u -r1.114 rtp.c
>> --- rtp.c 17 Mar 2005 23:12:15 -0000 1.114
>> +++ rtp.c 25 Mar 2005 11:38:28 -0000
>> @@ -593,7 +593,8 @@
>> case AST_FORMAT_ALAW:
>> rtp->f.samples = rtp->f.datalen;
>> break;
>> - case AST_FORMAT_SLINEAR:
>> + case AST_FORMAT_SLINEAR_LE:
>> + case AST_FORMAT_SLINEAR_BE:
>> rtp->f.samples = rtp->f.datalen / 2;
>> break;
>> case AST_FORMAT_GSM:
>> @@ -654,7 +655,7 @@
>> {{1, AST_FORMAT_ALAW}, "audio", "PCMA"},
>> {{1, AST_FORMAT_G726}, "audio", "G726-32"},
>> {{1, AST_FORMAT_ADPCM}, "audio", "DVI4"},
>> - {{1, AST_FORMAT_SLINEAR}, "audio", "L16"},
>> + {{1, AST_FORMAT_SLINEAR_BE}, "audio", "L16"},
>> {{1, AST_FORMAT_LPC10}, "audio", "LPC"},
>> {{1, AST_FORMAT_G729A}, "audio", "G729"},
>> {{1, AST_FORMAT_SPEEX}, "audio", "speex"},
>> @@ -681,8 +682,8 @@
>> [6] = {1, AST_FORMAT_ADPCM}, /* 16 kHz */
>> [7] = {1, AST_FORMAT_LPC10},
>> [8] = {1, AST_FORMAT_ALAW},
>> - [10] = {1, AST_FORMAT_SLINEAR}, /* 2 channels */
>> - [11] = {1, AST_FORMAT_SLINEAR}, /* 1 channel */
>> + [10] = {1, AST_FORMAT_SLINEAR_BE}, /* 2 channels */
>> + [11] = {1, AST_FORMAT_SLINEAR_BE}, /* 1 channel */
>> [13] = {0, AST_RTP_CN},
>> [16] = {1, AST_FORMAT_ADPCM}, /* 11.025 kHz */
>> [17] = {1, AST_FORMAT_ADPCM}, /* 22.050 kHz */
>> @@ -1328,6 +1329,20 @@
>>
>> switch(subclass) {
>> + case AST_FORMAT_SLINEAR_LE:
>> + case AST_FORMAT_SLINEAR_BE:
>> + if (!rtp->smoother) {
>> + rtp->smoother = ast_smoother_new(640);
>> + }
>> + if (!rtp->smoother) {
>> + ast_log(LOG_WARNING, "Unable to create
>> smoother :(\n");
>> + return -1;
>> + }
>> + ast_smoother_feed(rtp->smoother, _f);
>> +
>> + while((f = ast_smoother_read(rtp->smoother)))
>> + ast_rtp_raw_write(rtp, f, codec);
>> + break;
>> case AST_FORMAT_ULAW:
>> case AST_FORMAT_ALAW:
>> if (!rtp->smoother) {
>> Index: channels/chan_iax2.c
>> ===================================================================
>> RCS file: /usr/cvsroot/asterisk/channels/chan_iax2.c,v
>> retrieving revision 1.259
>> diff -u -r1.259 chan_iax2.c
>> --- channels/chan_iax2.c 24 Mar 2005 05:02:49 -0000 1.259
>> +++ channels/chan_iax2.c 25 Mar 2005 11:32:21 -0000
>> @@ -153,7 +153,8 @@
>> #define IAX_CAPABILITY_FULLBANDWIDTH 0xFFFF
>> /* T1, maybe ISDN */
>> #define IAX_CAPABILITY_MEDBANDWIDTH (IAX_CAPABILITY_FULLBANDWIDTH
>> & \
>> -
>> ~AST_FORMAT_SLINEAR & \
>> +
>> ~AST_FORMAT_SLINEAR_LE & \
>> +
>> ~AST_FORMAT_SLINEAR_BE & \
>>
>> ~AST_FORMAT_ULAW & \
>>
>> ~AST_FORMAT_ALAW)
>> /* A modem */
>> @@ -870,7 +871,8 @@
>> case AST_FORMAT_G729A:
>> samples = 160 * (f->datalen / 20);
>> break;
>> - case AST_FORMAT_SLINEAR:
>> + case AST_FORMAT_SLINEAR_LE:
>> + case AST_FORMAT_SLINEAR_BE:
>> samples = f->datalen / 2;
>> break;
>> case AST_FORMAT_LPC10:
>> Index: channels/chan_modem.c
>> ===================================================================
>> RCS file: /usr/cvsroot/asterisk/channels/chan_modem.c,v
>> retrieving revision 1.38
>> diff -u -r1.38 chan_modem.c
>> --- channels/chan_modem.c 4 Mar 2005 06:47:24 -0000 1.38
>> +++ channels/chan_modem.c 25 Mar 2005 11:32:21 -0000
>> @@ -108,7 +108,7 @@
>> static const struct ast_channel_tech modem_tech = {
>> .type = type,
>> .description = tdesc,
>> - .capabilities = AST_FORMAT_SLINEAR,
>> + .capabilities = AST_FORMAT_SLINEAR_LE,
>> .requester = modem_request,
>> .send_digit = modem_digit,
>> .call = modem_call,
>> Index: channels/chan_modem_aopen.c
>> ===================================================================
>> RCS file: /usr/cvsroot/asterisk/channels/chan_modem_aopen.c,v
>> retrieving revision 1.13
>> diff -u -r1.13 chan_modem_aopen.c
>> --- channels/chan_modem_aopen.c 24 Jun 2004 13:27:44 -0000 1.13
>> +++ channels/chan_modem_aopen.c 25 Mar 2005 11:32:21 -0000
>> @@ -316,7 +316,7 @@
>> return f;
>> /* If we get here, we have a complete voice frame */
>> p->fr.frametype = AST_FRAME_VOICE;
>> - p->fr.subclass = AST_FORMAT_SLINEAR;
>> + p->fr.subclass = AST_FORMAT_SLINEAR_LE;
>> p->fr.samples = 240;
>> p->fr.data = p->obuf;
>> p->fr.datalen = p->obuflen;
>> @@ -436,7 +436,7 @@
>> {
>> "AOpen",
>> aopen_idents,
>> - AST_FORMAT_SLINEAR,
>> + AST_FORMAT_SLINEAR_LE,
>> 0, /* Not full duplex */
>> aopen_incusecnt, /* incusecnt */
>> aopen_decusecnt, /* decusecnt */
>> Index: channels/chan_modem_bestdata.c
>> ===================================================================
>> RCS file: /usr/cvsroot/asterisk/channels/chan_modem_bestdata.c,v
>> retrieving revision 1.14
>> diff -u -r1.14 chan_modem_bestdata.c
>> --- channels/chan_modem_bestdata.c 25 Feb 2005 17:32:37 -0000
>> 1.14
>> +++ channels/chan_modem_bestdata.c 25 Mar 2005 11:32:21 -0000
>> @@ -365,7 +365,7 @@
>> if (f) return f;
>> /* If we get here, we have a complete voice frame */
>> p->fr.frametype = AST_FRAME_VOICE;
>> - p->fr.subclass = AST_FORMAT_SLINEAR;
>> + p->fr.subclass = AST_FORMAT_SLINEAR_LE;
>> p->fr.samples = 240;
>> p->fr.data = p->obuf;
>> p->fr.datalen = p->obuflen;
>> @@ -548,7 +548,7 @@
>> {
>> "BestData",
>> bestdata_idents,
>> - AST_FORMAT_SLINEAR,
>> + AST_FORMAT_SLINEAR_LE,
>> 0, /* Not full duplex */
>> bestdata_incusecnt, /* incusecnt */
>> bestdata_decusecnt, /* decusecnt */
>> Index: channels/chan_modem_i4l.c
>> ===================================================================
>> RCS file: /usr/cvsroot/asterisk/channels/chan_modem_i4l.c,v
>> retrieving revision 1.23
>> diff -u -r1.23 chan_modem_i4l.c
>> --- channels/chan_modem_i4l.c 24 Jan 2005 21:43:35 -0000 1.23
>> +++ channels/chan_modem_i4l.c 25 Mar 2005 11:32:21 -0000
>> @@ -435,7 +436,7 @@
>>
>> /* If we get here, we have a complete voice frame */
>> p->fr.frametype = AST_FRAME_VOICE;
>> - p->fr.subclass = AST_FORMAT_SLINEAR;
>> + p->fr.subclass = AST_FORMAT_SLINEAR_LE;
>> p->fr.samples = 240;
>> p->fr.data = p->obuf;
>> p->fr.datalen = p->obuflen;
>> @@ -475,8 +499,8 @@
>> ast_log(LOG_WARNING, "Don't know how to handle %d
>> type frames\n", f->frametype);
>> return -1;
>> }
>> - if (f->subclass != AST_FORMAT_SLINEAR) {
>> - ast_log(LOG_WARNING, "Don't know how to handle
>> anything but signed linear frames\n");
>> + if (f->subclass != AST_FORMAT_SLINEAR_LE) {
>> + ast_log(LOG_WARNING, "Don't know how to handle
>> anything but little-endian signed linear frames\n");
>> return -1;
>> }
>> for (x=0;x<f->datalen/2;x++) {
>> @@ -651,7 +675,7 @@
>> {
>> "i4l",
>> i4l_idents,
>> - AST_FORMAT_SLINEAR,
>> + AST_FORMAT_SLINEAR_LE,
>> 0, /* Not full duplex */
>> i4l_incusecnt, /* incusecnt */
>> i4l_decusecnt, /* decusecnt */
>> Index: channels/chan_phone.c
>> ===================================================================
>> RCS file: /usr/cvsroot/asterisk/channels/chan_phone.c,v
>> retrieving revision 1.45
>> diff -u -r1.45 chan_phone.c
>> --- channels/chan_phone.c 4 Mar 2005 06:47:24 -0000 1.45
>> +++ channels/chan_phone.c 25 Mar 2005 11:32:21 -0000
>> @@ -77,7 +77,7 @@
>>
>> static int silencesupression = 0;
>>
>> -static int prefformat = AST_FORMAT_G723_1 | AST_FORMAT_SLINEAR |
>> AST_FORMAT_ULAW;
>> +static int prefformat = AST_FORMAT_G723_1 | AST_FORMAT_SLINEAR_LE |
>> AST_FORMAT_ULAW;
>>
>> AST_MUTEX_DEFINE_STATIC(usecnt_lock);
>>
>> @@ -144,7 +144,7 @@
>> static const struct ast_channel_tech phone_tech = {
>> .type = type,
>> .description = tdesc,
>> - .capabilities = AST_FORMAT_G723_1 | AST_FORMAT_SLINEAR |
>> AST_FORMAT_ULAW,
>> + .capabilities = AST_FORMAT_G723_1 | AST_FORMAT_SLINEAR_LE |
>> AST_FORMAT_ULAW,
>> .requester = phone_request,
>> .send_digit = phone_digit,
>> .call = phone_call,
>> @@ -341,10 +341,10 @@
>> return -1;
>> }
>> }
>> - } else if (ast->rawreadformat == AST_FORMAT_SLINEAR) {
>> + } else if (ast->rawreadformat == AST_FORMAT_SLINEAR_LE) {
>> ioctl(p->fd, PHONE_REC_STOP);
>> - if (p->lastinput != AST_FORMAT_SLINEAR) {
>> - p->lastinput = AST_FORMAT_SLINEAR;
>> + if (p->lastinput != AST_FORMAT_SLINEAR_LE) {
>> + p->lastinput = AST_FORMAT_SLINEAR_LE;
>> if (ioctl(p->fd, PHONE_REC_CODEC, LINEAR16)) {
>> ast_log(LOG_WARNING, "Failed to set
>> codec to signed linear 16\n");
>> return -1;
>> @@ -591,7 +591,7 @@
>> return 0;
>> }
>> if (!(frame->subclass &
>> - (AST_FORMAT_G723_1 | AST_FORMAT_SLINEAR |
>> AST_FORMAT_ULAW)) &&
>> + (AST_FORMAT_G723_1 | AST_FORMAT_SLINEAR_LE |
>> AST_FORMAT_ULAW)) &&
>> p->mode != MODE_FXS) {
>> ast_log(LOG_WARNING, "Cannot handle frames in %d
>> format\n", frame->subclass);
>> return -1;
>> @@ -631,8 +631,8 @@
>> return -1;
>> }
>> maxfr = 24;
>> - } else if (frame->subclass == AST_FORMAT_SLINEAR) {
>> - if (p->lastformat != AST_FORMAT_SLINEAR) {
>> + } else if (frame->subclass == AST_FORMAT_SLINEAR_LE) {
>> + if (p->lastformat != AST_FORMAT_SLINEAR_LE) {
>> ioctl(p->fd, PHONE_PLAY_STOP);
>> ioctl(p->fd, PHONE_REC_STOP);
>> if (ioctl(p->fd, PHONE_PLAY_CODEC, LINEAR16))
>> {
>> @@ -643,8 +643,8 @@
>> ast_log(LOG_WARNING, "Unable to set
>> 16-bit linear mode\n");
>> return -1;
>> }
>> - p->lastformat = AST_FORMAT_SLINEAR;
>> - p->lastinput = AST_FORMAT_SLINEAR;
>> + p->lastformat = AST_FORMAT_SLINEAR_LE;
>> + p->lastinput = AST_FORMAT_SLINEAR_LE;
>> codecset = 1;
>> /* Reset output buffer */
>> p->obuflen = 0;
>> @@ -764,12 +764,12 @@
>> tmp->nativeformats =
>> tmp->rawreadformat =
>> tmp->rawwriteformat =
>> - AST_FORMAT_SLINEAR;
>> + AST_FORMAT_SLINEAR_LE;
>> else {
>> tmp->nativeformats =
>> tmp->rawreadformat =
>> tmp->rawwriteformat =
>> - prefformat & ~AST_FORMAT_SLINEAR;
>> + prefformat & ~AST_FORMAT_SLINEAR_LE;
>> }
>> }
>> else {
>> @@ -1149,7 +1149,7 @@
>> p = iflist;
>> while(p) {
>> if (p->mode == MODE_FXS ||
>> - format & (AST_FORMAT_G723_1 | AST_FORMAT_SLINEAR
>> | AST_FORMAT_ULAW)) {
>> + format & (AST_FORMAT_G723_1 |
>> AST_FORMAT_SLINEAR_LE | AST_FORMAT_ULAW)) {
>> size_t length = strlen(p->dev + 5);
>> if (strncmp(name, p->dev + 5, length) == 0 &&
>> !isalnum(name[length])) {
>> @@ -1166,7 +1166,7 @@
>> restart_monitor();
>> if (tmp == NULL) {
>> oldformat = format;
>> - format &= (AST_FORMAT_G723_1 | AST_FORMAT_SLINEAR |
>> AST_FORMAT_ULAW);
>> + format &= (AST_FORMAT_G723_1 | AST_FORMAT_SLINEAR_LE
>> | AST_FORMAT_ULAW);
>> if (!format) {
>> ast_log(LOG_NOTICE, "Asked to get a channel
>> of unsupported format '%d'\n", oldformat);
>> return NULL;
>> @@ -1317,8 +1317,8 @@
>> prefformat = AST_FORMAT_G723_1;
>> } else if (!strcasecmp(v->value, "slinear")) {
>> if (mode == MODE_FXS)
>> - prefformat |= AST_FORMAT_SLINEAR;
>> - else prefformat = AST_FORMAT_SLINEAR;
>> + prefformat |=
>> AST_FORMAT_SLINEAR_LE;
>> + else prefformat =
>> AST_FORMAT_SLINEAR_LE;
>> } else if (!strcasecmp(v->value, "ulaw")) {
>> prefformat = AST_FORMAT_ULAW;
>> } else
>> Index: channels/chan_zap.c
>> ===================================================================
>> RCS file: /usr/cvsroot/asterisk/channels/chan_zap.c,v
>> retrieving revision 1.420
>> diff -u -r1.420 chan_zap.c
>> --- channels/chan_zap.c 23 Mar 2005 21:12:01 -0000 1.420
>> +++ channels/chan_zap.c 25 Mar 2005 11:32:24 -0000
>> @@ -630,7 +630,7 @@
>> static const struct ast_channel_tech zap_tech = {
>> .type = type,
>> .description = tdesc,
>> - .capabilities = AST_FORMAT_SLINEAR | AST_FORMAT_ULAW,
>> + .capabilities = AST_FORMAT_SLINEAR_LE | AST_FORMAT_ULAW,
>> .requester = zt_request,
>> .send_digit = zt_digit,
>> .send_text = zt_sendtext,
>> @@ -4119,7 +4119,7 @@
>> return &p->subs[index].f;
>> }
>>
>> - if (ast->rawreadformat == AST_FORMAT_SLINEAR) {
>> + if (ast->rawreadformat == AST_FORMAT_SLINEAR_LE) {
>> if (!p->subs[index].linear) {
>> p->subs[index].linear = 1;
>> res = zt_setlinear(p->subs[index].zfd,
>> p->subs[index].linear);
>> @@ -4380,7 +4380,7 @@
>> ast_log(LOG_WARNING, "Don't know what to do
>> with frame type '%d'\n", frame->frametype);
>> return 0;
>> }
>> - if ((frame->subclass != AST_FORMAT_SLINEAR) &&
>> + if ((frame->subclass != AST_FORMAT_SLINEAR_LE) &&
>> (frame->subclass != AST_FORMAT_ULAW) &&
>> (frame->subclass != AST_FORMAT_ALAW)) {
>> ast_log(LOG_WARNING, "Cannot handle frames in %d
>> format\n", frame->subclass);
>> @@ -4409,7 +4409,7 @@
>> return 0;
>> }
>>
>> - if (frame->subclass == AST_FORMAT_SLINEAR) {
>> + if (frame->subclass == AST_FORMAT_SLINEAR_LE) {
>> if (!p->subs[index].linear) {
>> p->subs[index].linear = 1;
>> res = zt_setlinear(p->subs[index].zfd,
>> p->subs[index].linear);
>> @@ -4679,7 +4679,7 @@
>> } while (x < 3);
>> tmp->type = type;
>> tmp->fds[0] = i->subs[index].zfd;
>> - tmp->nativeformats = AST_FORMAT_SLINEAR | deflaw;
>> + tmp->nativeformats = AST_FORMAT_SLINEAR_LE | deflaw;
>> /* Start out assuming ulaw since it's smaller :) */
>> tmp->rawreadformat = deflaw;
>> tmp->readformat = deflaw;
>> @@ -7059,7 +7059,7 @@
>> end = ifend;
>> /* We do signed linear */
>> oldformat = format;
>> - format &= (AST_FORMAT_SLINEAR | AST_FORMAT_ULAW);
>> + format &= (AST_FORMAT_SLINEAR_LE | AST_FORMAT_ULAW);
>> if (!format) {
>> ast_log(LOG_NOTICE, "Asked to get a channel of
>> unsupported format '%d'\n", oldformat);
>> return NULL;
>>
>>
>> --
>> dwmw2
>>
>> _______________________________________________
>> Asterisk-Dev mailing list
>> Asterisk-Dev at lists.digium.com
>> http://lists.digium.com/mailman/listinfo/asterisk-dev
>> To UNSUBSCRIBE or update options visit:
>> http://lists.digium.com/mailman/listinfo/asterisk-dev
>>
> _______________________________________________
> Asterisk-Dev mailing list
> Asterisk-Dev at lists.digium.com
> http://lists.digium.com/mailman/listinfo/asterisk-dev
> To UNSUBSCRIBE or update options visit:
> http://lists.digium.com/mailman/listinfo/asterisk-dev
>
More information about the asterisk-dev
mailing list