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