  * return - 0 when transmission successfuly finished
  */
 uint8_t transmitPacket( byte destination, byte command, byte data ) {
-  tx_message[DESTINATION] = destination;
-  tx_message[SOURCE] = role_id;
-  tx_message[COMMAND] = command;
-  tx_message[DATA] = data;
-  //tx_message[CHECKSUM] = destination ^ role_id ^ data;
+  /* Assemble the transmission packet */
+  struct Packet tx_packet;
+  tx_packet.destination = destination;
+  tx_packet.source = role_id;
+  tx_packet.command = command;
+  tx_packet.data = data;
   
   /* First, stop listening so we can talk */
   radio.stopListening();
-  /* send the packet to the chosen destination */
-  bool ok = radio.write( tx_message, radio.getPayloadSize() );
+  /* Send the packet to the chosen destination */
+  bool ok = radio.write( &tx_packet, radio.getPayloadSize() );
   /* Now, resume listening so we catch the next packets. */
   radio.startListening();
   
-  /* When the transmission was successful */
-  if ( ok )
-    debug_printf( "transmit %X ok\n", command );
-  else
-    debug_printf( "failed.\n\r" );
+  /* When the transmission was not successful */
+  if ( !ok ) {
+    debug_printf( "transmit failed.\n\r" );
+    return TRANSMIT_FAILED;
+  }
   
+  debug_printf( "transmit %X ok\n", command );
   return SUCCESS;
 }
 
 void setup() {
   /* Initialize serial connection */
-  Serial.begin( 57600 );
+  Serial.begin( BAUD_RATE );
   /* Direct printf to Arduino serial */
   printf_begin();
 

  radio.startListening();

  /* Dump the configuration of the rf unit for debugging */
  if ( DEBUG ) 
    radio.printDetails();
}

void loop() {
  /* Client role, send vote and receive ack */
  if ( role_id == client_id ) {
    /* Require new ID */
    if ( role_id == 0xC0 ) {
      transmitPacket( server_id, REQUEST_ID, role_id );
    /* Active voting sate */
    } else if ( voting_active ) {
      uint8_t button = NO_BUTTON;
      while ( button == NO_BUTTON ) {
        getPressedButton( &button );
      }
      /* send packet to server */
      transmitPacket( server_id, VOTE_ID, (byte) button );
      
      /* Take the time, and send it.  This will block until complete */
      //unsigned long time = micros();
      /* Transmit and receive time */
      //debug_printf( "%d\n", micros() - time );
    /* Done voting or voting dind't start yet */
    } else {
      if ( !radio.available() )
        return;
    }
    /* Receive ack with timeout */
    uint8_t response = receivePacket( true );
    if ( response == TIMEOUT || response == WRONG_DESTINATION ) {
      return;
    }
    switch ( rx_message[COMMAND] ) {
      /* When vote status was received, change the voting status */
      case VOTE_STATUS: debug_printf( "got vote status %X", rx_message[DATA] ); voting_active = rx_message[DATA]; break;
      /* When new ID from the server was received, assign it */
      case REQUEST_ACK: debug_printf( "got new id %X\n", rx_message[DATA] ); role_id = client_id = rx_message[DATA]; break;
      /* When vote ack was received from server */
      case VOTE_ACK: debug_printf( "got vote ack from server\n" ); digitalWrite( 9, HIGH ); break;
      default: debug_printf( "unknown command received %X\n", rx_message[COMMAND] ); break;
    }

    // Try again 1s later
    //delay(1000);
    digitalWrite( 9, LOW );
  }

  /* Server role, receive vote and send ack */
  if ( role_id == server_id ) {
    //digitalWrite( 9, HIGH );
    uint8_t response = receivePacket( false );
    if ( response == WRONG_DESTINATION ) {
      
    }
    //digitalWrite( 9, LOW );
    
    switch ( rx_message[COMMAND] ) {
      /* when ID request was received, generate and send a new ID for the new client */
      case REQUEST_ID: debug_printf( "id request\n" ); uint8_t id; getClientID( &id ); transmitPacket( rx_message[SOURCE], REQUEST_ACK, id ); break;
      /* when vote was received, send ack back to the client */
      case VOTE_ID: debug_printf( "button %X was pressed\n", rx_message[DATA] ); transmitPacket( rx_message[SOURCE], VOTE_ACK, rx_message[DATA] ); break;
      default: debug_printf( "unknown command received %X\n", rx_message[COMMAND] ); break;
    }
  }


#include "printf.h"

/* MAY NEED TO BE CHANGED FOR DIFFERENT STATIONS */
#define BAUD_RATE 115200
/* Switch on = 1 or off = 0 for debug messages */
#define DEBUG 1
/* Voting buttons for clients */
#define BUTTONS_COUNT 4
uint8_t buttons[BUTTONS_COUNT] = { A1, A2, A3, A4 };
/* Role IDs */
uint8_t server_id = 0xB0;
uint8_t client_id = 0xC0;
uint8_t client_all_id = 0xAA;
/* The role of the current running sketch */
uint8_t role_id = server_id;

/* RETURN CODES */
#define SUCCESS 0
#define NO_BUTTON 0
#define NO_DATA 1
#define TRANSMIT_FAILED 2
#define WRONG_DESTINATION 3
/* RX/TX PACKET STRUCTURE */
struct Packet {
  byte destination;
  byte source;
  byte command;
  byte data;
};
/* Each packet is 4 bytes */
#define PAYLOAD 4

/* COMMAND CODES */
/* Sent from server when vote was received */
#define VOTE_ACK 0xAC
/* Sent from client when user has voted */
#define VOTE_ID 0xAB
/* Sent from server when voting got active/inactive */
#define VOTE_STATE 0xEA
/* Sent from server when client requested new ID */
#define REQUEST_ACK 0xEC
/* Sent from client when it got active and needs new ID */
#define REQUEST_ID 0x1D
/* For debugging */
#define debug_printf( args ... ) if ( DEBUG ) printf( args )
/* VOTING STATES */
#define WAITING_VOTING 0xE1
#define ACTIVE_VOTING 0xE2
#define FINISHED_VOTING 0xE3
#define WAITING_TRANSMISSION 0xE4
/* Saves the time, so we can wait for a short period */
unsigned long started_wait_time = 0;
uint8_t client_old_state;
uint8_t client_state = REQUEST_ID;

/* RADIO CONFIGURATION */

