   radio.startListening();
 
   /* Dump the configuration of the rf unit for debugging */
-  if ( DEBUG ) 
-    radio.printDetails();
+  if ( DEBUG ) radio.printDetails();
+    
+  /* Initialize the LEDs, 10 is also SPI SS*/
+  pinMode( 9, OUTPUT );
+  pinMode( 10, OUTPUT   );
+  digitalWrite( 9, LOW );
+  digitalWrite( 10, LOW );
 }
 
 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;
+    uint8_t button = NO_BUTTON;
+    switch ( client_state ) {
+      /* Request for a new ID */
+      case REQUEST_ID: 
+        transmitPacket( server_id, REQUEST_ID, role_id );
+        client_old_state = REQUEST_ID;
+        client_state = WAITING_TRANSMISSION;
+        break;
+      /* Waiting voting to be started */
+      case WAITING_VOTING: 
+        setStatusLEDs( LOW, LOW, false ); 
+        break;
+      /* Wait for user to vote */
+      case ACTIVE_VOTING:
+        setStatusLEDs( LOW, HIGH, true );
+        button = getPressedButton();
+        /* When the user has voted, send the vote */
+        if ( button != NO_BUTTON ) {
+          transmitPacket( server_id, VOTE_ID, button );
+          client_old_state = ACTIVE_VOTING;
+          client_state = WAITING_TRANSMISSION;
+        }
+        break;
+      /* Done voting */
+      case FINISHED_VOTING: 
+        setStatusLEDs( HIGH, LOW, false ); 
+        break;
+      /* Wait packet to be transmitted */
+      case WAITING_TRANSMISSION: 
+        if ( started_wait_time == 0 ) started_wait_time = millis();
+        if ( millis() - started_wait_time > 100 ) client_state = client_old_state;
+        break;
     }
+    /* When we escaped transmission waiting state */
+    if ( client_state != WAITING_TRANSMISSION ) started_wait_time = 0;
+    
     /* Receive ack with timeout */
-    uint8_t response = receivePacket( true );
-    if ( response == TIMEOUT || response == WRONG_DESTINATION ) {
-      return;
+    struct Packet rx_packet;
+    uint8_t response = receivePacket( rx_packet );
+    /* When responded with no data or wrong destination, don't process packet */
+    if ( response == NO_DATA || response == WRONG_DESTINATION ) return;
+    /* Process the received command in the packet */
+    switch ( rx_packet.command ) {
+      /* When vote state was received, change the voting state */
+      case VOTE_STATE: 
+        debug_printf( "got vote status %X", rx_packet.data ); 
+        client_state = rx_packet.data; 
+        break;
+      /* When new ID from the server was received, assign it */
+      case REQUEST_ACK: 
+        debug_printf( "got new id %X\n", rx_packet.data ); 
+        role_id = client_id = rx_packet.data; 
+        client_state = WAITING_VOTING; 
+        break;
+      /* When vote ack was received from server */
+      case VOTE_ACK: 
+        debug_printf( "got vote ack from server\n" );  
+        client_state = FINISHED_VOTING; break;
+      default: 
+        debug_printf( "unknown command received %X\n", rx_packet.command ); 
+        break;
     }
-    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 ) {
-      
+    /* When there are clients connected to server and we receive command from serial */
+    if ( client_count > 0 ) {
+      uint8_t button = getPressedButton();
+      char command;
+      /* When there is data available in serial, read the data */
+      if ( Serial.available() ) command = Serial.read();
+      uint8_t state = 0;
+      /* Specify the command from serial */
+      if ( command == 'w' || button == 1 ) state = WAITING_VOTING;
+      else if ( command == 'f' || button == 2 ) state = FINISHED_VOTING;
+      else if ( command == 'a' || button == 3 ) state = ACTIVE_VOTING;
+      /* When state was selected, send it to all the clients */
+      if ( state != 0 ) { transmitPacket( client_all_id, VOTE_STATE, state ); delay( 100 ); }
     }
-    //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;
+    struct Packet rx_packet;
+    uint8_t response = receivePacket( rx_packet );
+    /* When responded with no data or wrong destination, don't process packet */
+    if ( response == NO_DATA || response == WRONG_DESTINATION ) return;
+    
+    switch ( rx_packet.command ) {
+      /* When ID request was received, generate and send a new ID for the new client */
+      case REQUEST_ID: 
+        debug_printf( "id request\n" ); 
+        transmitPacket( rx_packet.source, REQUEST_ACK, getNewClientID() ); 
+        break;
+      /* When vote was received, send ack back to the client */
+      case VOTE_ID: 
+        debug_printf( "button %X was pressed\n", rx_packet.data ); 
+        transmitPacket( rx_packet.source, VOTE_ACK, rx_packet.data ); 
+        break;
+      default: 
+        debug_printf( "unknown command received %X\n", rx_packet.command ); 
+        break;
     }
   }
 

  /* optionally, increase the delay(1) between retries(2) & # of retries */
  radio.setRetries( 15, 15 );

  // optionally, reduce the payload size.  seems to
  // improve reliability
  radio.setPayloadSize( PAYLOAD );
  radio.setAutoAck( true );
  radio.setDataRate( RF24_2MBPS );

 * return - 0 when transmission successfuly finished
 */
uint8_t transmitPacket( byte destination, byte command, byte 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_packet, radio.getPayloadSize() );
  /* Now, resume listening so we catch the next packets. */
  radio.startListening();
  
  /* 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( BAUD_RATE );
  /* Direct printf to Arduino serial */
  printf_begin();

