[Asterisk-Dev] Explicit endianness support.

Mike Taht mike.taht at gmail.com
Sat Mar 26 08:48:18 MST 2005


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?

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
>



More information about the asterisk-dev mailing list