[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