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?