[Tinyos-help] TinyOS issues

Victor Cionca Victor.Cionca at ul.ie
Fri Apr 18 05:31:16 PDT 2008


Hello,

I am testing the algorithm using 4 tmotes. One is used as an initiator
to start the process, so that I don't have to worry about prior
synchronization for now. 

The three "worker" motes boot, set their number to 1 and a flag,
numberSet, to FALSE. They then wait for the initialization packet.
When they receive the initialization packet they build a beacon packet.
The beacon packet contains their ID and the number. Here, in the code, I
used to set the id to TOS_NODE_ID, but in the packet it would always be
0, I don't know why. So I set it to a random value, to have some guides
when analyzing traffic.

The beacon packet is sent and the nodes wait again. The number is set if
a beacon packet is completely sent (sendDone), and the number in the
packet >= current number.

If a beacon packet is received, and the number contained >= own number,
and the number is not yet set (numberSet = false) the number is set to
the one in the packet + 1, and a new beacon packet is broadcasted to
announce the change.

If the number has already been set when the beacon packet is received,
the receiver may have to correct the sender on its number, so let him
know that it has set an incorrect number. A correction packet is
employed, which contains the mote id and the number.

That's the algorithm.

I use the Queue interface to queue my packets and the global radioBusy
flag. I also use atomic blocks when incrementing the number and/or
building a packet, so it shouldn't get modified.

Here is the code, I hope it's ok if I send it entirely.
Also, I attach a flow chart of the algorithm.

Thanks a lot for your help!
Victor Cionca

---------------------------------------------------------------------
#include <Timer.h>
#include "MSH.h"
#include <stdio.h>

#define SEND(MSG) (call AMSend.send(AM_BROADCAST_ADDR, MSG, sizeof(MSPacket)))
#define SEND_TO(X, MSG) (call AMSend.send((X), MSG, sizeof(MSPacket)))

module MSModC{
	uses interface Boot;

	uses interface Packet;
	uses interface AMPacket;
	uses interface AMSend;
	uses interface Receive;
	uses interface SplitControl;

	uses interface Leds;
	
	uses interface Queue<QueuedPacket *> as Queue;
	uses interface Timer<TMilli> as Timer;
	uses interface Random;
	//uses interface RadioBackoff;
}

implementation{

	//packet info
	uint8_t counter;

	//node config
	bool iAmInitiator;
	uint16_t backoff;
	bool numberSet;
	uint8_t number;

	//radio info
	bool radioBusy;
	message_t radio_packet;

	void buildInitPacket(MSPacket*);
	void buildBeaconPacket(MSPacket *packet, uint16_t id, uint8_t my_number);//, bool my_newNode);
	void buildCorrectionPacket(MSPacket *packet, uint8_t number_t);
	void sendPacket(message_t *, uint16_t destination);
	char *print(MSPacket *);

	char *print(MSPacket *packet){
		char *output = malloc(18+2+2);

		sprintf(output, "Type = %d Number = %d", packet->type, packet->number);

		return output;
	}
	
	event void Boot.booted(){
		counter = 0;
		if (TOS_NODE_ID == 0) iAmInitiator = TRUE;
		else iAmInitiator = FALSE;

		backoff = call Random.rand16();

		numberSet = FALSE;
		number = 1;

		call Leds.led0Off();
		call Leds.led1Off();
		call Leds.led2Off();

		//start radio
		call SplitControl.start();

		dbg("Boot", "Booted as %s\n", ((iAmInitiator)?"initiator":"regular"));
	}

	event void Timer.fired(){
	}

	/****************************
	 * 	Radio is started
	 ****************************/
	event void SplitControl.startDone(error_t err){
		//message_t radio_packet;

		dbg("Boot", "Radio started\n");
		if (err == SUCCESS){
			if (iAmInitiator){
				MSPacket *initPacket;
				call Packet.clear(&radio_packet);
				initPacket = (MSPacket *)
					(call Packet.getPayload(&radio_packet,
								NULL));
				buildInitPacket(initPacket);
				if (SEND(&radio_packet) == SUCCESS){
					dbg("MS", "Sent init packet\n");
					radioBusy = TRUE;
				}else{
					dbg("MS", "Unable to send init packet\n");
				}

				call Leds.led1On();
			}
		}else{
			call SplitControl.start();
		}
	}

	event void SplitControl.stopDone(error_t err){
	}

	void buildInitPacket(MSPacket *packet){
		packet->mote_id = backoff;//TOS_NODE_ID;
	//	packet->newNode = TRUE;
		packet->type = INIT;
		packet->number = 0;
		packet->counter = counter++;
	}

	void buildBeaconPacket(MSPacket *packet, uint16_t id, uint8_t nr){//, bool my_newNode){
		packet->mote_id = backoff;//id;
		packet->type = BEACON;
	//	packet->newNode = TRUE;
		packet->number = nr;
		packet->counter = counter++;
	}

	void buildCorrectionPacket(MSPacket *packet, uint8_t nr){
		packet->mote_id = backoff;//TOS_NODE_ID;
	//	packet->newNode = TRUE;
		packet->type = CORRECTION;
		packet->number = nr;
		packet->counter = counter++;
	}

	/******************************************************
	 *	Send a packet or queue it
	 ******************************************************/
	void sendPacket(message_t *message, am_addr_t destination){
		if ((radioBusy == FALSE) && (SEND_TO(destination, message) == SUCCESS)){
			radioBusy = TRUE;
		}else{
			//queue the packet
			message_t newMessage;
			MSPacket *newPacket, *oldPacket;
			QueuedPacket qPack;
			call Packet.clear(&newMessage);
			call Packet.setPayloadLength(&newMessage, sizeof(MSPacket));
			newPacket = (MSPacket*)(call Packet.getPayload(&newMessage, NULL));
			oldPacket = (MSPacket*)(call Packet.getPayload(message, NULL));

			//set the information in the new packet
			newPacket->mote_id = oldPacket->mote_id;
			newPacket->type = oldPacket->type;
			newPacket->number = oldPacket->number;
			newPacket->counter = oldPacket->counter;

			//construct the queue message
			qPack.destination = destination;
			qPack.message = &newMessage;
			
			//enqueue it
			if ((call Queue.enqueue(&qPack)) != SUCCESS){
			}
		}
	}

	event void AMSend.sendDone(message_t *msg, error_t error){
		MSPacket *sentPacket;

		radioBusy = FALSE;
		sentPacket = (MSPacket*)(call Packet.getPayload(msg, NULL));

		if ((sentPacket->type == BEACON) && (sentPacket->number >= number)){
			atomic{
				number = sentPacket->number;
				call Leds.set(number);
				numberSet = TRUE;
			}
		}else{
			call Leds.led2On();
		}

		//send a new packet from the queue
		if ((call Queue.empty()) == FALSE){
			QueuedPacket *qPack = (QueuedPacket*)(call Queue.dequeue());
			sendPacket(qPack->message, qPack->destination);
		}

	}

	/****************************************
	 *	Receive init packet - start self-organizing
	 ****************************************/
	void receivedInitPacket(MSPacket *packet){
		//message_t radio_packet;
		MSPacket *beaconPacket;

		call Packet.clear(&radio_packet);
		call Packet.setPayloadLength(&radio_packet, sizeof(MSPacket));
		beaconPacket = (MSPacket*)(call Packet.getPayload(&radio_packet, NULL));

		//build beacon packet with own number
		buildBeaconPacket(beaconPacket, 0, number); 
		
		//send beacon packet
		sendPacket(&radio_packet, AM_BROADCAST_ADDR);
	}

	/**************************************************************
	 *	Receive beacon packet - adjust own number or send correction packet
	 **************************************************************/
	void receivedBeaconPacket(message_t *msg, MSPacket *packet){
		//message_t radio_packet;

		if (numberSet){
			//send correction packet
			if (packet->number <= number){
				am_addr_t source;
				atomic{
					MSPacket *corrPacket;
					call Packet.clear(&radio_packet);
					call Packet.setPayloadLength(&radio_packet, sizeof(MSPacket));
					corrPacket = (MSPacket*)(call Packet.getPayload(&radio_packet,
								NULL));
					buildCorrectionPacket(corrPacket, number);
				}
				
				source = call AMPacket.source(msg);
				sendPacket(&radio_packet, source);
			}
		}else{
			//modify own number
			if (packet->number >= number){
				atomic{
					MSPacket *beaconPacket;
					call Packet.clear(&radio_packet);
					call Packet.setPayloadLength(&radio_packet, sizeof(MSPacket));
					beaconPacket = (MSPacket*)(call Packet.getPayload(&radio_packet,
							       NULL));
					number = packet->number + 1;
					buildBeaconPacket(beaconPacket, 0, number);
				}

				sendPacket(&radio_packet, AM_BROADCAST_ADDR);
			}
		}
	}

	/**********************************************************************
	 *	Receive correction packet - correct own packet
	 **********************************************************************/
	void receivedCorrectionPacket(MSPacket *packet){
		//message_t radio_packet;

		if (packet->number >= number){
			atomic{
				MSPacket *beaconPacket;
				number = packet->number + 1;
				call Packet.clear(&radio_packet);
				call Packet.setPayloadLength(&radio_packet, sizeof(MSPacket));
				beaconPacket = (MSPacket*)(call Packet.getPayload(&radio_packet,
						       NULL));
				buildBeaconPacket(beaconPacket, 0, number);
			}

			sendPacket(&radio_packet, AM_BROADCAST_ADDR);
		}
	}

	event message_t *Receive.receive(message_t *msg, void *payload, uint8_t len){
		MSPacket *packet;
		if (len != sizeof(MSPacket)) return msg; //just ignore

		//get payload
		packet = (MSPacket*)payload;

		switch (packet->type){
			/**
			 * Hack for node discovery:
			 * if node settled on number will not reinit
			 */
			case INIT:{
					  if (numberSet == FALSE){
						  receivedInitPacket(packet);
					  }
					  break;
				  }
			case BEACON:{ 
					    //initiator ignores beacon messages
					    if (iAmInitiator) break;
					    receivedBeaconPacket(msg, packet); break;
				    }
			case CORRECTION:{
						if (iAmInitiator) break;
						if (call AMPacket.isForMe(msg)){
							receivedCorrectionPacket(packet);
						}
						break; //upon new node
					}
			default: break;
		}
		return msg;
	}

}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: flow.png
Type: image/png
Size: 51455 bytes
Desc: not available
Url : https://www.millennium.berkeley.edu/pipermail/tinyos-help/attachments/20080418/c957b2ad/attachment-0001.png 


More information about the Tinyos-help mailing list