Hi all!
I have a problem sending a C struct from my Arduino Uno to my notebook.
If I try to send the structure from a C client, it works flawlessy.
Trying to send the same identical structure from the arduino sketch results in a buggy output.
Here's the code.
Arduino sketch:
#include <stdint.h>
#include <SPI.h>
#include <Ethernet.h>
void send_mystruct(struct mystruct *);
mystruct * create_mystruct();
void print_mystruct(mystruct);
void print_nadd(mystruct *);
void print_xadd(mystruct *);
#pragma pack(1)
struct mystruct {
unsigned char type:4;
unsigned int len:12;
uint8_t value;
uint8_t nadd[2];
uint8_t xadd[8];
uint64_t id;
uint8_t sum;
};
typedef struct mystruct mystruct;
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 192, 168, 33, 17 };
byte gateway[] = { 192, 168, 33, 13 };
byte server[] = { 192, 168, 33, 16 }; // notebook
uint8_t xa[8] = { 0xc, 0xd, 0xe, 0xf, 0x0, 0x1, 0x2, 0x3 };
uint8_t na[2] = { 0xa, 0xb };
Client client(server, 10001);
mystruct *h = NULL;
void setup() {
Ethernet.begin(mac, ip, gateway);
delay(1000);
Serial.begin(9600);
h = create_mystruct();
mystruct_set_nadd(h, na);
mystruct_set_xadd(h, xa);
if (h) {
print_mystruct(h);
}
Serial.println();
if (client.connect()) {
Serial.println("connected");
if (h) send_mystruct(h);
}
else {
Serial.println("connection failed");
}
}
void loop () {
if (!client.connected()) {
Serial.println();
Serial.println("disconnecting.");
client.stop();
for(;;)
;
}
}
void send_mystruct(struct mystruct *head) {
if (head) {
// client.println(head);
client.println((const char *) head);
}
}
void print_mystruct(mystruct *h) {
if (h) {
Serial.println("Header fields:");
Serial.print("Type = ");
Serial.println(h->type, DEC);
Serial.print("Len = ");
Serial.println(h->len, DEC);
Serial.print("IP = ");
Serial.println(h->value, DEC);
Serial.print("Network address = ");
print_nadd(h);
Serial.print("XBee address = ");
print_xadd(h);
Serial.print("id = ");
Serial.println((long) h->id);
Serial.print("Checksum = ");
Serial.println(h->sum, DEC);
}
}
void print_nadd(mystruct *h) {
if (!h) return;
uint8_t *na = h->nadd;
Serial.print("{ ");
for (int i = 0; i < 2; i++) {
Serial.print(na[i], DEC);
Serial.print(" ");
}
Serial.println("} ");
}
void print_xadd(mystruct *h) {
if (!h) return;
uint8_t *xa = h->xadd;
Serial.print("{ ");
for (int i = 0; i < 8; i++) {
Serial.print(xa[i], DEC);
Serial.print(" ");
}
Serial.println("} ");
}
mystruct * create_mystruct() {
mystruct *h = NULL;
h = (mystruct *) malloc(sizeof(mystruct));
if (h) {
h->len = 57;
h->type = 2;
h->value = 15;
h->sum = 99;
h->id = 1299;
mystruct_set_nadd(h, na);
mystruct_set_xadd(h, na);
}
return h;
}
void mystruct_set_nadd(mystruct *h, uint8_t *net) {
if (h) {
for (int i = 0; i < 2; i++) {
h->nadd[i] = net[i];
}
}
}
void mystruct_set_xadd(mystruct *h, uint8_t *xbee) {
if (h) {
for (int i = 0; i < 8; i++) {
h->xadd[i] = xbee[i];
}
}
}
C server:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#pragma pack(1)
struct mystruct {
unsigned char type:4;
unsigned int len:12;
uint8_t value;
uint8_t nadd[2];
uint8_t xadd[8];
uint64_t id;
uint8_t sum;
};
typedef struct mystruct mystruct;
const int STRUCT_LENGTH = 22;
mystruct * parse_mystruct(char *);
mystruct * mystruct_create(void);
void print_mystruct(mystruct *h);
void print_nadd(mystruct *h);
void print_xadd(mystruct *h);
void error(char *msg)
{
perror(msg);
exit(1);
}
int main(int argc, char *argv[])
{
int sockfd, newsockfd, portno, clilen;
char *buffer = NULL;
struct sockaddr_in serv_addr, cli_addr;
int n;
mystruct *h = NULL;
if (argc < 2) {
fprintf(stderr,"ERROR, no port provided\n");
exit(1);
}
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) {
error("ERROR opening socket");
}
memset((char *) &serv_addr, 0, sizeof(serv_addr));
portno = atoi(argv[1]);
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(portno);
if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) {
error("ERROR on binding");
}
listen(sockfd, 5);
clilen = sizeof(cli_addr);
newsockfd = accept(sockfd,
(struct sockaddr *) &cli_addr,
(socklen_t *) &clilen);
if (newsockfd < 0) {
error("ERROR on accept");
}
buffer = (char *) malloc(sizeof(char) * STRUCT_LENGTH);
memset(buffer, 0, STRUCT_LENGTH);
n = read(newsockfd, buffer, STRUCT_LENGTH);
if (n < 0) {
error("ERROR reading from socket");
}
h = parse_mystruct(buffer);
if (h)
print_mystruct(h);
return 0;
}
mystruct * parse_mystruct(char *buf) {
mystruct *tmp = NULL;
if (!buf)
return NULL;
tmp = mystruct_create();
if (tmp) {
memcpy(tmp, buf, STRUCT_LENGTH);
}
return tmp;
}
mystruct * mystruct_create() {
mystruct *tmp = NULL;
tmp = (mystruct *) malloc(sizeof(mystruct));
if (tmp) {
memset(tmp, 0, sizeof(mystruct));
tmp->type = 1;
tmp->value = 9;
tmp->id = (uint64_t) time(NULL);
}
return tmp;
}
void print_mystruct(mystruct *h) {
if (h) {
printf("Header fields:\n");
printf("type = %d\n", h->type);
printf("len = %d\n", h->len);
printf("ip = %d\n", h->value);
printf("net address = ");
print_nadd(h);
printf("xbee address = ");
print_xadd(h);
printf("id = %lu\n", h->id);
printf("sum = %d\n", h->sum);
}
}
void print_nadd(mystruct *h) {
int i;
uint8_t *na = h->nadd;
if (h) {
for (i = 0; i < 2; i ++) {
printf(" %d ", na[i]);
}
printf("\n");
}
}
void print_xadd(mystruct *h) {
int i;
uint8_t *xa = h->xadd;
if (h) {
for (i = 0; i < 8; i ++) {
printf(" %d ", xa[i]);
}
printf("\n");
}
}
Here's the arduino (correct) output:
Header fields:
Type = 2
Len = 57
IP = 15
Network address = { 10 11 }
XBee address = { 12 13 14 15 0 1 2 3 }
id = 1299
Checksum = 99
And here's the server (uncorrect) output:
Header fields:
type = 2
len = 57
ip = 15
net address = 10 11
xbee address = 12 13 14 15 0 0 0 0
id = 0
sum = 0
Any help will be really appreciated.