Programming between big and little endian

View: New views
11 Messages — Rating Filter:   Alert me  

Programming between big and little endian

by Roger Gilbert :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

I have a program that compiles and works fine on Debian for the NSLU2.

I try to compile it under unslung and it compiles and links with no errors.

Yet the program fails at the first case statement that checks a 32 bit value passed to it.

could this be that uNSLUng 6.10 is big endian and Debian for the NSLU2 is little endian ?

I define this value in the header file.

#define CHALLENGE_TEXT_LEN    8

enum
{
    NET_HOSTFS_CMD_HELLO = 0x00DA5800,
    NET_HOSTFS_CMD_IOINIT,
    NET_HOSTFS_CMD_IOEXIT,
    NET_HOSTFS_CMD_IOOPEN,
    NET_HOSTFS_CMD_IOCLOSE,
    NET_HOSTFS_CMD_IOREAD,
    NET_HOSTFS_CMD_IOWRITE,
    NET_HOSTFS_CMD_IOLSEEK,
    NET_HOSTFS_CMD_IOIOCTL,
    NET_HOSTFS_CMD_IOREMOVE,
    NET_HOSTFS_CMD_IOMKDIR,
    NET_HOSTFS_CMD_IORMDIR,
    NET_HOSTFS_CMD_IODOPEN,
    NET_HOSTFS_CMD_IODCLOSE,
    NET_HOSTFS_CMD_IODREAD,
    NET_HOSTFS_CMD_IOGETSTAT,
    NET_HOSTFS_CMD_IOCHSTAT,
    NET_HOSTFS_CMD_IORENAME,
    NET_HOSTFS_CMD_IODEVCTL,
    NET_HOSTFS_CMD_GETKEY        //GETKEY
}


This is my code section

        switch (cmd)
        {
            case NET_HOSTFS_CMD_HELLO:   
                process_func = process_hello;
            break;
   
            case NET_HOSTFS_CMD_IOINIT:
                process_func = process_ioinit;   
            break;
           
            case NET_HOSTFS_CMD_IOEXIT:
                process_func = process_ioexit;
            break;
   
            case NET_HOSTFS_CMD_IOOPEN:
                process_func = process_ioopen;
            break;
   
            case NET_HOSTFS_CMD_IOCLOSE:
                process_func = process_ioclose;
            break;
   
            case NET_HOSTFS_CMD_IOREAD:
                process_func = process_ioread;
            break;
   
            case NET_HOSTFS_CMD_IOWRITE:
                process_func = process_iowrite;
            break;
   
            case NET_HOSTFS_CMD_IOLSEEK:
                process_func = process_iolseek;
            break;
   
            case NET_HOSTFS_CMD_IOREMOVE:
                process_func = process_ioremove;
            break;
   
            case NET_HOSTFS_CMD_IOMKDIR:
                process_func = process_iomkdir;
            break;
   
            case NET_HOSTFS_CMD_IORMDIR:
                process_func = process_iormdir;
            break;
   
            case NET_HOSTFS_CMD_IODOPEN:
                process_func = process_iodopen;
            break;
   
            case NET_HOSTFS_CMD_IODCLOSE:
                process_func = process_iodclose;
            break;
   
            case NET_HOSTFS_CMD_IODREAD:
                process_func = process_iodread;
            break;
   
            case NET_HOSTFS_CMD_IOGETSTAT:
                process_func = process_iogetstat;
            break;
   
            case NET_HOSTFS_CMD_IOCHSTAT:
                process_func = process_iochstat;
            break;
   
            case NET_HOSTFS_CMD_IORENAME:
                process_func = process_iorename;
            break;

            case NET_HOSTFS_CMD_GETKEY:
                process_func = process_getkey;
            break;
   
            default:
                 printf("Unknown command [%d] sock [%d]: 0x%08X\n", spawn_idx, sock, cmd);
        }


This is the result I get from my program running

Listening for incoming connections...
Accepted new connection from IP 192.168.1.7
Adding multi-session for IP 192.168.1.7
Adding multi-session for IP 192.168.1.7
Adding multi-session for IP 192.168.1.7
Creating child for index #0...
Assigning pid (526) to index #0
cmd [0] sock [4]: 0058DA00
Unknown command [0] sock [4]: 0x0058DA00


It looks like I am getting the correct input yet it fails to compare

Or is it my command is 32 bit and uNSLUng 6.10 does not handle 32 bit correctly ?




     

Re: Programming between big and little endian

by Mike (mwester) :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Roger Gilbert wrote:

> I have a program that compiles and works fine on Debian for the NSLU2.
>
> I try to compile it under unslung and it compiles and links with no errors.
>
> Yet the program fails at the first case statement that checks a 32 bit
> value passed to it.
>
> could this be that uNSLUng 6.10 is big endian and Debian for the NSLU2
> is little endian ?
>
> I define this value in the header file.
>
> #define CHALLENGE_TEXT_LEN    8
>
> enum
> {
>     NET_HOSTFS_CMD_HELLO = 0x00DA5800,
>     NET_HOSTFS_CMD_IOINIT,
>     NET_HOSTFS_CMD_IOEXIT,
>     NET_HOSTFS_CMD_IOOPEN,
>     NET_HOSTFS_CMD_IOCLOSE,
>     NET_HOSTFS_CMD_IOREAD,
>     NET_HOSTFS_CMD_IOWRITE,
>     NET_HOSTFS_CMD_IOLSEEK,
>     NET_HOSTFS_CMD_IOIOCTL,
>     NET_HOSTFS_CMD_IOREMOVE,
>     NET_HOSTFS_CMD_IOMKDIR,
>     NET_HOSTFS_CMD_IORMDIR,
>     NET_HOSTFS_CMD_IODOPEN,
>     NET_HOSTFS_CMD_IODCLOSE,
>     NET_HOSTFS_CMD_IODREAD,
>     NET_HOSTFS_CMD_IOGETSTAT,
>     NET_HOSTFS_CMD_IOCHSTAT,
>     NET_HOSTFS_CMD_IORENAME,
>     NET_HOSTFS_CMD_IODEVCTL,
>     NET_HOSTFS_CMD_GETKEY        //GETKEY
> }
>
>
> This is my code section
>
>         switch (cmd)
>         {
>             case NET_HOSTFS_CMD_HELLO:  
>                 process_func = process_hello;
>             break;
>    
>             case NET_HOSTFS_CMD_IOINIT:
>                 process_func = process_ioinit;  
>             break;
>            
>             case NET_HOSTFS_CMD_IOEXIT:
>                 process_func = process_ioexit;
>             break;
>    
>             case NET_HOSTFS_CMD_IOOPEN:
>                 process_func = process_ioopen;
>             break;
>    
>             case NET_HOSTFS_CMD_IOCLOSE:
>                 process_func = process_ioclose;
>             break;
>    
>             case NET_HOSTFS_CMD_IOREAD:
>                 process_func = process_ioread;
>             break;
>    
>             case NET_HOSTFS_CMD_IOWRITE:
>                 process_func = process_iowrite;
>             break;
>    
>             case NET_HOSTFS_CMD_IOLSEEK:
>                 process_func = process_iolseek;
>             break;
>    
>             case NET_HOSTFS_CMD_IOREMOVE:
>                 process_func = process_ioremove;
>             break;
>    
>             case NET_HOSTFS_CMD_IOMKDIR:
>                 process_func = process_iomkdir;
>             break;
>    
>             case NET_HOSTFS_CMD_IORMDIR:
>                 process_func = process_iormdir;
>             break;
>    
>             case NET_HOSTFS_CMD_IODOPEN:
>                 process_func = process_iodopen;
>             break;
>    
>             case NET_HOSTFS_CMD_IODCLOSE:
>                 process_func = process_iodclose;
>             break;
>    
>             case NET_HOSTFS_CMD_IODREAD:
>                 process_func = process_iodread;
>             break;
>    
>             case NET_HOSTFS_CMD_IOGETSTAT:
>                 process_func = process_iogetstat;
>             break;
>    
>             case NET_HOSTFS_CMD_IOCHSTAT:
>                 process_func = process_iochstat;
>             break;
>    
>             case NET_HOSTFS_CMD_IORENAME:
>                 process_func = process_iorename;
>             break;
>
>             case NET_HOSTFS_CMD_GETKEY:
>                 process_func = process_getkey;
>             break;
>    
>             default:
>                  printf("Unknown command [%d] sock [%d]: 0x%08X\n",
> spawn_idx, sock, cmd);
>         }
>
>
> This is the result I get from my program running
>
> Listening for incoming connections...
> Accepted new connection from IP 192.168.1.7
> Adding multi-session for IP 192.168.1.7
> Adding multi-session for IP 192.168.1.7
> Adding multi-session for IP 192.168.1.7
> Creating child for index #0...
> Assigning pid (526) to index #0
> cmd [0] sock [4]: 0058DA00
> Unknown command [0] sock [4]: 0x0058DA00
>
>
> It looks like I am getting the correct input yet it fails to compare
>
> Or is it my command is 32 bit and uNSLUng 6.10 does not handle 32 bit
> correctly ?

That looks to be an endian-related problem -- note that the cmd differs
from the value you specified in the enum.  In this case, I'm willing to
bet that you are reading values that should be converted to/from network
byte order -- see the documentation on the htonl() function, for example.

Mike (mwester)

Re: Programming between big and little endian

by Roger Gilbert :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Can you tell me where to find that documentation ?


--- On Mon, 7/14/08, Mike (mwester) <mwester@...> wrote:
From: Mike (mwester) <mwester@...>
Subject: Re: [nslu2-linux] Programming between big and little endian
To: nslu2-linux@...
Date: Monday, July 14, 2008, 5:32 PM










   
            Roger Gilbert wrote:

> I have a program that compiles and works fine on Debian for the NSLU2.

>

> I try to compile it under unslung and it compiles and links with no errors.

>

> Yet the program fails at the first case statement that checks a 32 bit

> value passed to it.

>

> could this be that uNSLUng 6.10 is big endian and Debian for the NSLU2

> is little endian ?

>

> I define this value in the header file.

>

> #define CHALLENGE_TEXT_ LEN    8

>

> enum

> {

>     NET_HOSTFS_CMD_ HELLO = 0x00DA5800,

>     NET_HOSTFS_CMD_ IOINIT,

>     NET_HOSTFS_CMD_ IOEXIT,

>     NET_HOSTFS_CMD_ IOOPEN,

>     NET_HOSTFS_CMD_ IOCLOSE,

>     NET_HOSTFS_CMD_ IOREAD,

>     NET_HOSTFS_CMD_ IOWRITE,

>     NET_HOSTFS_CMD_ IOLSEEK,

>     NET_HOSTFS_CMD_ IOIOCTL,

>     NET_HOSTFS_CMD_ IOREMOVE,

>     NET_HOSTFS_CMD_ IOMKDIR,

>     NET_HOSTFS_CMD_ IORMDIR,

>     NET_HOSTFS_CMD_ IODOPEN,

>     NET_HOSTFS_CMD_ IODCLOSE,

>     NET_HOSTFS_CMD_ IODREAD,

>     NET_HOSTFS_CMD_ IOGETSTAT,

>     NET_HOSTFS_CMD_ IOCHSTAT,

>     NET_HOSTFS_CMD_ IORENAME,

>     NET_HOSTFS_CMD_ IODEVCTL,

>     NET_HOSTFS_CMD_ GETKEY        //GETKEY

> }

>

>

> This is my code section

>

>         switch (cmd)

>         {

>             case NET_HOSTFS_CMD_ HELLO:  

>                 process_func = process_hello;

>             break;

>    

>             case NET_HOSTFS_CMD_ IOINIT:

>                 process_func = process_ioinit;  

>             break;

>            

>             case NET_HOSTFS_CMD_ IOEXIT:

>                 process_func = process_ioexit;

>             break;

>    

>             case NET_HOSTFS_CMD_ IOOPEN:

>                 process_func = process_ioopen;

>             break;

>    

>             case NET_HOSTFS_CMD_ IOCLOSE:

>                 process_func = process_ioclose;

>             break;

>    

>             case NET_HOSTFS_CMD_ IOREAD:

>                 process_func = process_ioread;

>             break;

>    

>             case NET_HOSTFS_CMD_ IOWRITE:

>                 process_func = process_iowrite;

>             break;

>    

>             case NET_HOSTFS_CMD_ IOLSEEK:

>                 process_func = process_iolseek;

>             break;

>    

>             case NET_HOSTFS_CMD_ IOREMOVE:

>                 process_func = process_ioremove;

>             break;

>    

>             case NET_HOSTFS_CMD_ IOMKDIR:

>                 process_func = process_iomkdir;

>             break;

>    

>             case NET_HOSTFS_CMD_ IORMDIR:

>                 process_func = process_iormdir;

>             break;

>    

>             case NET_HOSTFS_CMD_ IODOPEN:

>                 process_func = process_iodopen;

>             break;

>    

>             case NET_HOSTFS_CMD_ IODCLOSE:

>                 process_func = process_iodclose;

>             break;

>    

>             case NET_HOSTFS_CMD_ IODREAD:

>                 process_func = process_iodread;

>             break;

>    

>             case NET_HOSTFS_CMD_ IOGETSTAT:

>                 process_func = process_iogetstat;

>             break;

>    

>             case NET_HOSTFS_CMD_ IOCHSTAT:

>                 process_func = process_iochstat;

>             break;

>    

>             case NET_HOSTFS_CMD_ IORENAME:

>                 process_func = process_iorename;

>             break;

>

>             case NET_HOSTFS_CMD_ GETKEY:

>                 process_func = process_getkey;

>             break;

>    

>             default:

>                  printf("Unknown command [%d] sock [%d]: 0x%08X\n",

> spawn_idx, sock, cmd);

>         }

>

>

> This is the result I get from my program running

>

> Listening for incoming connections. ..

> Accepted new connection from IP 192.168.1.7

> Adding multi-session for IP 192.168.1.7

> Adding multi-session for IP 192.168.1.7

> Adding multi-session for IP 192.168.1.7

> Creating child for index #0...

> Assigning pid (526) to index #0

> cmd [0] sock [4]: 0058DA00

> Unknown command [0] sock [4]: 0x0058DA00

>

>

> It looks like I am getting the correct input yet it fails to compare

>

> Or is it my command is 32 bit and uNSLUng 6.10 does not handle 32 bit

> correctly ?



That looks to be an endian-related problem -- note that the cmd differs

from the value you specified in the enum.  In this case, I'm willing to

bet that you are reading values that should be converted to/from network

byte order -- see the documentation on the htonl() function, for example.



Mike (mwester)


     

   
   
       
         
       
       








       


       
       


     

Re: Programming between big and little endian

by Mike (mwester) :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Roger Gilbert wrote:
> Can you tell me where to find that documentation ?

google htonl

This is a very common library; it's been around since the dawn of TCP/IP
and should be referenced and part of the examples for any bit of TCP/IP
programming you find in any competent reference manual.

Mike (mwester)

Re: Programming between big and little endian

by David Hawkins-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


> Can you tell me where to find that documentation ?

Try a man page under Linux, or just Google it.

Just a couple of notes to help you:

>      > enum
>      > {
>      > NET_HOSTFS_CMD_ HELLO = 0x00DA5800,

On a little-endian host, these bytes will look like:

00 58 DA 00

whereas on a big-endian host, they will look like:

00 DA 58 00

So on your server, you use that header, and send the
bytes in big-endian network byte-order using something
like this:

    uint32_t cmd = htonl(NET_HOSTFS_CMD);
    write(fd, &cmd, 4);

whereas on your client, you read the big-endian bytes,
and convert them to host-order using something like:

    uint32_t cmd;
    read(fd, &cmd, 4);
    cmd = ntohl(cmd);
    switch (cmd) {
    case NET_HOSTFS_CMD:

This complimentary sequence ensures that the enum definition
is used in the hosts native endian format, but the command
sequences over the wire are in big-endian, or network
byte-order, format.

In addition to endianness issues, if you are transmitting
data structures, you'll want to worry about alignment
(packing of structure members).

Cheers,
Dave

Re: Programming between big and little endian

by Roger Gilbert :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Yes I am transmitting large data structures.

This is a system that runs a disk data structure over wifi.

The NSLU2 translates commands from the wireless sends or reads to a usb hard drive and sends the resultant data back to the wireless link.

If course there is very heavy error checking.

--- On Mon, 7/14/08, David Hawkins <dwh@...> wrote:
From: David Hawkins <dwh@...>
Subject: Re: [nslu2-linux] Programming between big and little endian
To: nslu2-linux@...
Date: Monday, July 14, 2008, 6:10 PM










   
           

> Can you tell me where to find that documentation ?



Try a man page under Linux, or just Google it.



Just a couple of notes to help you:



>      > enum

>      > {

>      > NET_HOSTFS_CMD_ HELLO = 0x00DA5800,



On a little-endian host, these bytes will look like:



00 58 DA 00



whereas on a big-endian host, they will look like:



00 DA 58 00



So on your server, you use that header, and send the

bytes in big-endian network byte-order using something

like this:



uint32_t cmd = htonl(NET_HOSTFS_ CMD);

    write(fd, &cmd, 4);



whereas on your client, you read the big-endian bytes,

and convert them to host-order using something like:



uint32_t cmd;

    read(fd, &cmd, 4);

    cmd = ntohl(cmd);

    switch (cmd) {

    case NET_HOSTFS_CMD:



This complimentary sequence ensures that the enum definition

is used in the hosts native endian format, but the command

sequences over the wire are in big-endian, or network

byte-order, format.



In addition to endianness issues, if you are transmitting

data structures, you'll want to worry about alignment

(packing of structure members).



Cheers,

Dave


     

   
   
       
         
       
       








       


       
       


     

Re: Programming between big and little endian

by Roger Gilbert :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Thank you very much


--- On Mon, 7/14/08, Mike (mwester) <mwester@...> wrote:
From: Mike (mwester) <mwester@...>
Subject: Re: [nslu2-linux] Programming between big and little endian
To: nslu2-linux@...
Date: Monday, July 14, 2008, 6:08 PM










   
            Roger Gilbert wrote:

> Can you tell me where to find that documentation ?



google htonl



This is a very common library; it's been around since the dawn of TCP/IP

and should be referenced and part of the examples for any bit of TCP/IP

programming you find in any competent reference manual.



Mike (mwester)


     

   
   
       
         
       
       








       


       
       


     

Re: Programming between big and little endian

by David Hawkins-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi Roger,

> Yes I am transmitting large data structures.
>
> This is a system that runs a disk data structure over wifi.
>
> The NSLU2 translates commands from the wireless sends or reads to a usb
> hard drive and sends the resultant data back to the wireless link.
>
> If course there is very heavy error checking.

I'm curious, what's wrong with using NFS?

Note that NFS uses RPC (remote procedure calls) and XDR
(external data representation).

XDR is a machine independent binary format. The byte order
is defined as big-endian, and the packing rules for 8-bit
data, 16-bit data, 32-bit data, etc are defined.

NFS data is encoded and decoded into XDR format before
being transmitted over-the-wire.

So if you are reinventing the wheel here, you might want
to take a look at this stuff.

Unix Network Programming, by W. R. Stevens

has some nice discussion on this.

On the otherhand if you are defining your own protocol, and
you happen to use C++, the ACE C++ library has an implementation
of the Common Data Represenation (CDR) machine independent
binary format. CDR uses a 'reader-make-right' scheme where the
endianness of a serialized object is encoded at the start of the
data stream, and the reader has to byte-swap if its a
different endianness.

Cheers,
Dave

Re: Programming between big and little endian

by Roger Gilbert :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

The hand held unit has no structures. Never intended to have mass storage other than a flash card. The driver we have done makes the hand held think it has a storage card that is as big as the usb hard drive you plug into the NSLU2. So if you plug in a 750 gig hard drive the hand held thinks it has a 750 gig flash card.

The protocol is self defined and not based on any other standards.

--- On Mon, 7/14/08, David Hawkins <dwh@...> wrote:
From: David Hawkins <dwh@...>
Subject: Re: [nslu2-linux] Programming between big and little endian
To: nslu2-linux@...
Date: Monday, July 14, 2008, 6:39 PM










   
            Hi Roger,



> Yes I am transmitting large data structures.

>

> This is a system that runs a disk data structure over wifi.

>

> The NSLU2 translates commands from the wireless sends or reads to a usb

> hard drive and sends the resultant data back to the wireless link.

>

> If course there is very heavy error checking.



I'm curious, what's wrong with using NFS?



Note that NFS uses RPC (remote procedure calls) and XDR

(external data representation) .



XDR is a machine independent binary format. The byte order

is defined as big-endian, and the packing rules for 8-bit

data, 16-bit data, 32-bit data, etc are defined.



NFS data is encoded and decoded into XDR format before

being transmitted over-the-wire.



So if you are reinventing the wheel here, you might want

to take a look at this stuff.



Unix Network Programming, by W. R. Stevens



has some nice discussion on this.



On the otherhand if you are defining your own protocol, and

you happen to use C++, the ACE C++ library has an implementation

of the Common Data Represenation (CDR) machine independent

binary format. CDR uses a 'reader-make- right' scheme where the

endianness of a serialized object is encoded at the start of the

data stream, and the reader has to byte-swap if its a

different endianness.



Cheers,

Dave


     

   
   
       
         
       
       








       


       
       


     

Re: Programming between big and little endian

by David Hawkins-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi Roger,

> The hand held unit has no structures. Never intended to
> have mass storage other than a flash card. The driver
> we have done makes the hand held think it has a storage
> card that is as big as the usb hard drive you plug into
> the NSLU2. So if you plug in a 750 gig hard drive the hand
> held thinks it has a 750 gig flash card.
>
> The protocol is self defined and not based on any other standards.

Sorry, this isn't clear to me. Perhaps you could provide
a few more details - if you're allowed :)

Let me see if I have this correct ...

So you have a handheld unit with a WiFi connection to
the NSLU2. The handheld unit has a 'driver' that converts
its file access into Wifi transactions to the NSLU2.

By the sounds of it, the NSLU2 runs a server application
that the handheld 'driver' communicates with.

An 'application' on the handheld reads and writes files
using its filesystem driver interface, eg. read()/write()
function calls. The handheld 'driver' sends write data or
read requests to the server running on the NSLU2, and
that server performs NSLU2 harddrive accesses.

As far as the handheld is concerned its writing byte-streams
to a file, whereas infact the byte-stream is being transmitted
to the NSLU2 and it writes to a file.

BTW; is the handheld running an OS, or bare-metal code
with a Wifi connection? What is the processor?

Regarding structures and endianness, there's another
aspect to note:

Lets say the handheld writes a file with the integer value
0x11223344. If I open that same file on a PC, then depending
on the enddianness of the handheld processor I would read
0x11223344, or 0x44332211.

This issue is no different than me writing an integer to
a file using a big-endian PowerPC processor, and then opening
it to interpret it using an x86 processor.

Now lets say I have some PC support software for the user
of the handheld. That PC can also have a Wifi server, and
run identically to the NSLU2.

With the ntohl/hlton additions to your server, the server
running on the x86 will now appear no different than the
server running on the NSLU2. They'll both serve the
command codes in big-endian format.

Now what about support software. I would assume for debugging
purposes you'd want to be able to read any file written by
the handheld. You have two solutions there; use the
knowledge of the handheld processor endianness to interpret
the file, or have the handheld write in a machine independent
binary format. Obviously the second method is more complex,
but it does make changing the processor in the handheld
easier, since the support software would not change.

In my applications I have multiple big-endian or little-endian
processors communicating with little-endian x86 processors.
The processors all communicate using CDR encoded data, thus
eliminating any machine specific code (the machine specific
code is determined during compilation by the CDR encode and
decode functions).

Note that these are just a few comments on available options,
no offense regarding your solution is intended.

Cheers,
Dave


Re: Programming between big and little endian

by Roger Gilbert :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Dave,

 I am an old school real time machine code programmer. I am just learning to program in C, this is all new to me.

I did not write this original code. I was just trying to find out why it did not work when I compiled it to run on the NSLU2. The code functions perfectly on the little endian X86 in with Windows XP as the host.

At least when it was programmed they  used cygwin so it would run on the windows platform.

The handheld side I do not have the source code for. It is a black box that just works. I only have the server side software that I am trying to debug..

Between reading someone else's code with zero comments in it, my trying to stretch my brain just learning C, and not having the other side, I am sort of a non  swimmer in the deep end of the pool.

I have never programmed network sockets so I am trying to learn that at the same time.

Half of what you said I will have to Wiki or Google so that I can break it down into what I can understand.

I should have learned C years ago. But at that time, the compilers were not that good and I had to count instruction cycle times in clock cycles of the processors I was working in.

I was doing image recognition in assembler.

I thought this was a good project to get my feet wet and learn on. I think I may have bit off more than I can chew, but I am stubborn and will keep at it.

--- On Mon, 7/14/08, David Hawkins <dwh@...> wrote:
From: David Hawkins <dwh@...>
Subject: Re: [nslu2-linux] Programming between big and little endian
To: nslu2-linux@...
Date: Monday, July 14, 2008, 7:59 PM










   
            Hi Roger,



> The hand held unit has no structures. Never intended to

> have mass storage other than a flash card. The driver

> we have done makes the hand held think it has a storage

> card that is as big as the usb hard drive you plug into

> the NSLU2. So if you plug in a 750 gig hard drive the hand

> held thinks it has a 750 gig flash card.

>

> The protocol is self defined and not based on any other standards.



Sorry, this isn't clear to me. Perhaps you could provide

a few more details - if you're allowed :)



Let me see if I have this correct ...



So you have a handheld unit with a WiFi connection to

the NSLU2. The handheld unit has a 'driver' that converts

its file access into Wifi transactions to the NSLU2.



By the sounds of it, the NSLU2 runs a server application

that the handheld 'driver' communicates with.



An 'application' on the handheld reads and writes files

using its filesystem driver interface, eg. read()/write( )

function calls. The handheld 'driver' sends write data or

read requests to the server running on the NSLU2, and

that server performs NSLU2 harddrive accesses.



As far as the handheld is concerned its writing byte-streams

to a file, whereas infact the byte-stream is being transmitted

to the NSLU2 and it writes to a file.



BTW; is the handheld running an OS, or bare-metal code

with a Wifi connection? What is the processor?



Regarding structures and endianness, there's another

aspect to note:



Lets say the handheld writes a file with the integer value

0x11223344. If I open that same file on a PC, then depending

on the enddianness of the handheld processor I would read

0x11223344, or 0x44332211.



This issue is no different than me writing an integer to

a file using a big-endian PowerPC processor, and then opening

it to interpret it using an x86 processor.



Now lets say I have some PC support software for the user

of the handheld. That PC can also have a Wifi server, and

run identically to the NSLU2.



With the ntohl/hlton additions to your server, the server

running on the x86 will now appear no different than the

server running on the NSLU2. They'll both serve the

command codes in big-endian format.



Now what about support software. I would assume for debugging

purposes you'd want to be able to read any file written by

the handheld. You have two solutions there; use the

knowledge of the handheld processor endianness to interpret

the file, or have the handheld write in a machine independent

binary format. Obviously the second method is more complex,

but it does make changing the processor in the handheld

easier, since the support software would not change.



In my applications I have multiple big-endian or little-endian

processors communicating with little-endian x86 processors.

The processors all communicate using CDR encoded data, thus

eliminating any machine specific code (the machine specific

code is determined during compilation by the CDR encode and

decode functions).



Note that these are just a few comments on available options,

no offense regarding your solution is intended.



Cheers,

Dave