The online racing simulator
Quote from mikey_G :But indeed, the OSX functions were just nothing more then some usless empty function, weird...

It's ok, because on PC these functions do the conversion. These functions converts the host order to the network order (and the other way around). The network order is the same as on Mac, big endian, so no conversion is needed.
Quote from mikey_G :
I did get warnings though that I was overriding NTOHL and HTONL, so maybe they existed already.

Maybe they are in some header.

It's more complicated, than it seems :-). There is other problem with automatic conversions between floats and ints. Try the following two funcs:
float htonf (float *fg) {
unsigned int *tm;
unsigned int res_c;
float result;

tm = (unsigned int*)fg;
res_c = HTONL (*tm);
memcpy (&result, &res_c, 4);
return (result);
}

float ntohf (float *fg) {
unsigned int *tm;
unsigned int res_c;
float result;

tm = (unsigned int*)fg;
res_c = NTOHL (*tm);
memcpy (&result, &res_c, 4);
return (result);
}

So for the printing:
printf("RPM = %f, memory address is %X\n", htonf (&og_packet.RPM)), &og_packet.RPM);

You will need #include <string.h> for the above code.
I think I found something that works, and complies with Occam Razor

float floatSwap(char *value)
{
char buffer[ 4 ];

buffer[ 0 ] = value[ 3 ];
buffer[ 1 ] = value[ 2 ];
buffer[ 2 ] = value[ 1 ];
buffer[ 3 ] = value[ 0 ];

return *( (float *) &buffer );
}

I swap the RPM data type in the OutGuagepacket structure to "char RPM[4];"

and then i output it:

printf("RPM = %f, memory address is %X\n", floatSwap(&og_packet.RPM), &og_packet.RPM);

This does raise a warning for me:

warning: passing argument 1 of 'floatSwap' from incompatible pointer type

Would be nice if I could get rid of it.


This is my output now, check the RPM in the middle of the output:

[Session started at 2007-04-24 01:51:33 +0200.]


got packet from 192.168.1.2
packet is 96 bytes long

Time = 21180, memory address is BFFFF880
Car = FXO, memory address is BFFFF884
Speed = 0.000000, memory address is A
RPM = 7941.076172, memory address is BFFFF890
ID of connection = 1
sizeof struct = 96

RPM = 2432237568.000000, memory address is BFFFF890


OutGuageFoundation has exited with status 0.

It looks like its working, and the solution was the easiest I could ever think of.
Your solution works too, and I prefer yours to be honest. Putting the floats to char in the struct is just not nice.

Right now this is my output:
[Session started at 2007-04-24 02:01:01 +0200.]


got packet from 192.168.1.2
packet is 96 bytes long

Time = 23690, memory address is BFFFF910
Car = FXO, memory address is BFFFF914
Speed = 133.660039, memory address is BFFFF91C
RPM = 6800.274902, memory address is BFFFF920
ID of connection = 1
sizeof struct = 96


OutGuage has exited with status 0.

As you can see, it works!!!!


Thank you so much Kada_CZ, you've been a great help to me. I owe you one
Quote from mikey_G :I think I found something that works, and complies with Occam Razor

:-), nice. What about this small change to get rid of warnings and the need of RPM data type change:

float floatSwap (float fl)
{
char *value = (char*) &fl;
char buffer[ 4 ];

buffer[ 0 ] = value[ 3 ];
buffer[ 1 ] = value[ 2 ];
buffer[ 2 ] = value[ 1 ];
buffer[ 3 ] = value[ 0 ];

return *( (float *) &buffer );
}

:Handshake
-
(Kada_CZ) DELETED by Kada_CZ
That one is also working great, which one do you think I should use? I've once seen an app in Xcode to time your functions, but forgot how it worked.
It works really nice, I'll post an updated source tomorrow with all the other structure elements outputted.
I'm really glad the app works now, because I did get kinda hopeless (and I actually wanted to spend indepence day differently then coding the whole evening )

Anyhow, thanks again Kada, it wouldn't have been possible without you

me to bed now
Slightly more effective version:
float floatSwap (float value)
{
char buffer[ 4 ];

buffer[ 0 ] = ((char*)&value)[ 3 ];
buffer[ 1 ] = ((char*)&value)[ 2 ];
buffer[ 2 ] = ((char*)&value)[ 1 ];
buffer[ 3 ] = ((char*)&value)[ 0 ];
return *( (float *) &buffer );
}

Maybe some C guru post here #define solution in just one expression, I can't see it.

You'll buy me a beer, when I visit Israel .
I hope you like corona

Anyway, here is the working source

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#define OG_SHIFTLIGHT 1
#define OG_FULLBEAM 2
#define OG_HANDBRAKE 4
#define OG_PITSPEED 8
#define OG_TC 16
#define OG_HEADLIGHTS 32
#define OG_SIGNAL_L 64
#define OG_SIGNAL_R 128
#define OG_REDLINE 256
#define OG_OILWARN 512
#define OG_1 1024
#define OG_2 2048
#define OG_3 4096
#define OG_4 8192
#define OG_KM 16384
#define OG_BAR 32768

#define HTONL(n) (((((unsigned long)(n) & 0xFF)) << 24) | \
((((unsigned long)(n) & 0xFF00)) << 8) | \
((((unsigned long)(n) & 0xFF0000)) >> 8) | \
((((unsigned long)(n) & 0xFF000000)) >> 24))

#define NTOHL(n) (((((unsigned long)(n) & 0xFF)) << 24) | \
((((unsigned long)(n) & 0xFF00)) << 8) | \
((((unsigned long)(n) & 0xFF0000)) >> 8) | \
((((unsigned long)(n) & 0xFF000000)) >> 24))


#define MYPORT 55555 // the port users will be connecting to

typedef struct
{
unsigned int Time; // time in milliseconds (to check order)

char Car [4]; // Car name
unsigned short Flags; // OG_FLAGS (see below)
unsigned char Gear; // Reverse:0, Neutral:1, First:2...
unsigned char SpareB;
float Speed; // M/S
float RPM; // RPM
float Turbo; // BAR
float EngTemp; // C
float Fuel; // 0 to 1
float OilPress; // BAR
float Spare1;
float Spare2;
float Spare3;
float Throttle; // 0 to 1
float Brake; // 0 to 1
float Clutch; // 0 to 1
char Display1[16]; // Usually Fuel
char Display2[16]; // Usually Settings
int ID;
} __attribute__ ((packed)) OutGaugePacket;


float floatSwap (float value)
{
//char *value = (char*) &fl;
char buffer[ 4 ];

buffer[ 0 ] = ((char*)&value)[ 3 ];
buffer[ 1 ] = ((char*)&value)[ 2 ];
buffer[ 2 ] = ((char*)&value)[ 1 ];
buffer[ 3 ] = ((char*)&value)[ 0 ];

return *( (float *) &buffer );
}


int main(void)
{
int sockfd; // let's make a file descriptor
OutGaugePacket og_packet; // let's create an packet
struct sockaddr_in my_addr; // my address information
struct sockaddr_in their_addr; // connector's address information
socklen_t addr_len;
int numbytes;
memset(&(og_packet),'\0',96); // zero out the struct


//let's create the socket
if ((sockfd = socket(PF_INET, SOCK_DGRAM, 0)) == -1) {
perror("socket");
exit(1);
}

// setting up our contact information here
my_addr.sin_family = AF_INET;
my_addr.sin_port = htons(MYPORT); // short, network byte order
my_addr.sin_addr.s_addr = INADDR_ANY; // automatically fill with my IP
memset(&(my_addr.sin_zero), '\0', 8); // zero the rest of the struct


//binding our socket to a port and address
if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1) {
perror("bind");
exit(1);
}
addr_len = sizeof(struct sockaddr);

for (;;){
// receiving the goodies
if ((numbytes=recvfrom(sockfd, (void *)&og_packet, sizeof(OutGaugePacket) , 0, (struct sockaddr *)&their_addr, &addr_len)) == -1) {
perror("recvfrom");
exit(1);
}
printf("\ngot packet from %s\n",inet_ntoa(their_addr.sin_addr));
printf("packet is %d bytes long\n\n", numbytes);

printf("Contents of packet:\n");
printf("Time = %u \t\tmemory address is %#X\n", NTOHL(og_packet.Time), &og_packet.Time);
printf("Car = %s \t\t\tmemory address is %#X\n", &og_packet.Car, &og_packet.Car);
printf("Gear = %d \t\t\tmemory address is %#X\n", og_packet.Gear -1, &og_packet.Gear);
printf("SpareB = %d \t\tmemory address is %#X\n", og_packet.SpareB, &og_packet.Gear);
printf("Speed = %.f \t\tmemory address is %#X\n", (floatSwap(og_packet.Speed)) * 3.6, &og_packet.Speed);
printf("RPM = %.f \t\tmemory address is %#X\n", floatSwap(og_packet.RPM), &og_packet.RPM);
printf("Turbo = %f \tmemory address is %#X\n", floatSwap(og_packet.Turbo), &og_packet.Turbo);
printf("EngTemp = %.f \t\tmemory address is %#X\n", floatSwap(og_packet.EngTemp), &og_packet.EngTemp);
printf("Fuel = %f \tmemory address is %#X\n", floatSwap(og_packet.Fuel), &og_packet.Fuel);
printf("OilPress = %.2f \tmemory address is %#X\n", floatSwap(og_packet.OilPress), &og_packet.OilPress);
printf("Spare1 = %.2f \tmemory address is %#X\n", floatSwap(og_packet.Spare1), &og_packet.Spare1);
printf("Spare2 = %.2f \tmemory address is %#X\n", floatSwap(og_packet.Spare2), &og_packet.Spare2);
printf("Spare3 = %.2f \tmemory address is %#X\n", floatSwap(og_packet.Spare3), &og_packet.Spare3);
printf("Throttle = %.f%% \tmemory address is %#X\n", (floatSwap(og_packet.Throttle) * 100), &og_packet.Throttle);
printf("Brake = %.f%% \t\tmemory address is %#X\n", (floatSwap(og_packet.Brake)* 100), &og_packet.Brake);
printf("Clutch = %.f%% \t\tmemory address is %#X\n", (floatSwap(og_packet.Clutch)* 100), &og_packet.Clutch);
printf("Display1 = %s\t\t\t%#X\n", &og_packet.Display1, &og_packet.Display1);
printf("Display2 = %s\t\t\t%#X\n", &og_packet.Display2, &og_packet.Display2);
printf("ID = %u \t\t\tmemory address is %#X\n", NTOHL(og_packet.ID), &og_packet.ID);
}

close(sockfd);

return 0;
}


It's far from nice, but it's a easy sample application where other people can play with, I learned a lot of it anyway.


Here some output
got packet from 192.168.1.2
packet is 96 bytes long

Contents of packet:
Time = 167580 memory address is 0XBFFFF8B4
Car = RB4 memory address is 0XBFFFF8B8
Gear = 3 memory address is 0XBFFFF8BE
SpareB = 0 memory address is 0XBFFFF8BE
Speed = 96 memory address is 0XBFFFF8C0
RPM = 7090 memory address is 0XBFFFF8C4
Turbo = 0.082909 memory address is 0XBFFFF8C8
EngTemp = 0 memory address is 0XBFFFF8CC
Fuel = 0.069851 memory address is 0XBFFFF8D0
OilPress = 0.00 memory address is 0XBFFFF8D4
Spare1 = 0.00 memory address is 0XBFFFF8D8
Spare2 = 0.00 memory address is 0XBFFFF8DC
Spare3 = 0.00 memory address is 0XBFFFF8E0
Throttle = 80% memory address is 0XBFFFF8E4
Brake = 0% memory address is 0XBFFFF8E8
Clutch = 20% memory address is 0XBFFFF8EC
Display1 = Fuel 5.2 0XBFFFF8F0
Display2 = Brake Bal F 73% 0XBFFFF900
ID = 1 memory address is 0XBFFFF910

Now all I have to do is getting the values in to a nice Cocoa app, and then beauty ensues

Btw, does anyone have any tips for getting the flag status out of the 16 bit "Flags" element?
Thanks for the link. And yeah, I should've googled it a bit further, but a push in to the right direction is nice too for a n00b

But fortunately, after I get the flags bit down, I know eveything I need to know to make my app
2

FGED GREDG RDFGDR GSFDG