wiki:HardWare/MobileNode/Sensors/pseudocode

Referring to the big picture shown here, the pseudo-code for the drivers, client (both running on the sensing nodes either fixed or mobile), server node (on CentMesh nodes) and controller (located behind the gateway) are shown below:

Driver

while(TRUE){
  // in this section we take a measurement and ship it to the client process
  read sample (for example from A/D converter, autopilot, GPS receiver, file etc);
  form UDP datagram encapsulating the sample
  send UDP datagram to socket SENSING_PORT; // this packet goes to the Client
  
  // in this section we receive commands from the client (e.g., set some parameter for the device, or sensing period)
  timeout = false;
  remainingTimeoutTime = SENSING_PERIOD; // sensor period is specific to this sensor

  do{
      receive from UDP SENSING _PORT with timeout of remainingTimeoutTime seconds
      if packet_received // packet received before timeout
         process_packet();
         update remainingTimeoutTime;
      else // timeout before receiving packet
         timeout = true;
   }until (! timeout)
}

Client

SET_EXPECTED_SEQ = 0;
GET_NEXT_SEQ = 0;

while(TRUE){

  if currentTime() - lastTimeAHeartbeatWasSent > HEARTBEAT_PERIOD {
     send_heartbeat(); // This broadcasts a heartbeat to be received by server(s).
     lastTimeAHeartbeatWasSent = curentTime();
  }

  // This part receives commands from the server
  receive from UDP server port (SERVER_PORT) with a short timeout (1s)
  if packet_received // packet received before timeout
    if the packet is a SET & SEQ == EXPECTED_SEQ{ 
        processSET();
        SET_EXPECTED_SEQ++
    }
    else if the packet is a GET_ACK && GET_NEXT_SEQ {
       remove top packet from queue
       GET_NEXT_SEQ ++
    }

  // This part reads the samples from the drivers and enqueues them
   timeout = false;
   do{
      receive from UDP driver port (SENSING_PORT) with a very short timeout (e.g., 0.1 seconds)
      if packet_received // packet received before timeout
         enqueue_reading_in_a_circular queue();
      else // timeout before receiving packet
         timeout = true;
   }until (! timeout)

   // Finally, try to send packet from the top of the queue
   if (queue_not_empty)
       send_top_packet_from_queue(GET_NEXT_SEQ);
}



If the programming language supports it, both UDP ports (SENSING_PORT and SERVER_PORT) should be read simultaneously (e.g., via select).

Server

while(TRUE)
  receive packet from UDP port (SERVER_PORT);
  if it is a measurement (GET), processMeasurement(receivedPacket);
  elseif it is a command (SET), enqueue command in command queue;
  elseif it is a command cancel (SETCANCEL), dequeue command (if found in the queue - can be more than one instance) 
  elseif it is a SET_ACK, dequeue conmmand and send ACK to the controller.
  
  processCommandQueue();
} 


processMeasurement(receivedPacket){
  send measurement to central controller  // if unreliable backhaul, then use a thread and ACKs. TCP may be the way to go on backhaul
  send GET_ACK back to the client
}

processCommandQueue(){
  // single threaded version - tries all packets one after the others
  
  iterate through packets in the queue{
    result = send_packet_with_ACK(currentPacket, RETRIES)
      if  result = SUCCESS
        delete command from command queue
  }
}

// just a stop and wait with a few retries
result = send_packet_with_ACK (datagram, retries){
    while(retries-- > 0){
      send_datagram_to_server(SERVER_PORT);
      receive_ACK_from_server(timeout = 200ms);
        if (ACK received)
           return SUCCESSFUL;
    }
    return TIMEOUT;
}

Controller

while(TRUE){
  receive measurement()
  if old measurement (node id, sequence number) 
    continue;
  else // if new measurement
    storeMeasurement()

  receiveCommand() // from port/keyboard/etc/
  send command to all servers
  when receiving ack from at least one server send cancel command to all servers  
 
}

Last modified 17 months ago Last modified on Jul 14, 2014, 9:35:10 PM