[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