[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RE: [bluetooth-dev] Re: Porting to ARM



Gordon,

Just happened to see this exchange.  I do not know the details of the
headers, but these comments seem strange to me.

Correct me if I am wrong, but the endianness does not affect the order of
bits within a byte.  It only affects the order of the bytes within larger
data units.  Now some communications devices prescribe the order of the
bits, but that is usually hidden from the high level code by doing
converting to a properly bit ordered byte stream.

Are the Bluetooth headers defining reversed bit fields?

Hoping to clarify,
Norman

-----Original Message-----
From: Gordon McNutt [mailto:gmcnutt@xxxxxxx.com]
Sent: Wednesday, September 27, 2000 10:19 AM
Cc: bluetooth-dev@xxxxxxx.com
Subject: Re: [bluetooth-dev] Re: Porting to ARM


Peter Kjellerstedt wrote:

>
> struct iphdr
>   {
> #if __BYTE_ORDER == __LITTLE_ENDIAN
>     unsigned int ihl:4;
>     unsigned int version:4;
> #elif __BYTE_ORDER == __BIG_ENDIAN
>     unsigned int version:4;
>     unsigned int ihl:4;
> #else
> # error "Please fix <bits/endian.h>"
> #endif
>     u_int8_t tos;
>     u_int16_t tot_len;
>     ...
>   }
>
> It is not exactly beautiful code, but I believe it should work.
>
> //Peter

Hmm. I'm not sure that your example is correct. First , byte order does not
affect bits within the byte. Second, my linux/include/ip.h is using the
macros
__LITTLE_ENDIAN_BITFIELD__, etc. -- where the pertinent substring is "BIT",
as
opposed to byte.

So the example is not quite right. But will the idea still work? I could be
looking at it wrong, but I don't think it will.
Let's try it with the HCI header:

typedef struct cmd_pkt {
 u32 type:8;
#ifdef __LITTLE_ENDIAN
        u32 ocf:10;
        u32 ogf:6;
#elifdef __BIG_ENDIAN
        u32 ogf:6;
        u32 ocf:10;
#else
# error "Please fix <bits/endian.h>"
#endif
        u32 len:8;
        u8 data[256];
} __attribute__ ((packed)) cmd_pkt;

If I overlay this struct on the buffer and fill it out field by field, I
think
that in the BIG_ENDIAN case the ocf and ogf fields will be laid out
backwards
on the little-endian bytestream. I considered using a union so that we could
do
a single field assignment to cover both the ocf and ogf bitfields, but
nonetheless the value will have to shifted and coerced into lining up right
for
the assignment, so it doesn't really help to use unions.

I'm afraid that we're going to have to use something like this, and that
we'll
have to do so everywhere bitfields appear that aren't evenly divisible by 8
bits:

*ptr++ = ocf_val & 0xff;
*ptr = ocf_val >> 8;
*ptr |= ogf_val << 2 & 0xfc;

Prove me wrong, please. But hurry, because I'm already changing code.

--Gordon