📄 anycastm.nc
字号:
/* Anycast Implmentation. *//* Written by Kin Sun Ho (ksho@cse) *//* Last Modified: 07 September 2005 *//* History: 15/07/05: Created File 18/07/05: Implmented the handling of JOIN and the routing table 19/07/05: Started Testing, Received empty broadcast from monitor 20/07/05: Fixed the sending of packets from the monitor 21/07/05: Editing the header file (MN.h) for changes to Anycast 22/07/05: Implmented Sensor Data Packets Done some testing, AnycastM seems to be fine UART is not printing the message correctly 25/07/05: Rewritten ACBase from TOSBase, it works now! Minor Bug fix in AnycastM due to message buffers Implemented multihop forwarding 26/07/05: Testing multihop... however, it may not work very well... 27/07/05: Worked on exp1: refer to it. Wen Hu points out: 1. the routing table may need an atomic to prevent preempt 2. the renewal of sequence # will result in network hang after a while => tried to add atomic on point 1 but network performance decrease sharply => fixing the second point with force update if seq# <= 10 29/07/05: Done experiments, the maximum hop achieved is 3, although it is rare. But it is proved that a multihop of 2 would work 05/08/05: Done experiments with Tatiana. Removed ADC from Anycast. Wen points out table entries are still accessed after invalid => fixed added atomic statements within update of table 25/08/05: Modified the doData for copying pointers of the data packet 07/08/05: Fixed possible synchronization problem with doJoin*/includes Sasha;module AnycastM{ provides interface Anycastlib; provides interface StdControl; uses { interface Timer as Table_Timer; interface Timer as Sensor_Timer; interface Timer as Sleep_Timer; interface Leds; interface StdControl as CommControl; interface StdControl as CLNNControl; interface CLNNlib; interface ReceiveMsg; interface SendMsg; }}implementation{ TOS_Msg msg[2]; // data msg unicast buffer TOS_Msg jmsg[2]; // join msg rebroadcast buffer TOS_Msg fmsg[2]; // forwarding msg unicast buffer uint8_t currentMsg; // select between one and zero in the buffers uint8_t jcurrentMsg; uint8_t fcurrentMsg; uint8_t state; // current state of mote uint8_t packet_to_send; // repeat of pkt sending counter struct Mrouting *rtable[ROUTING_TABLE]; // routing table bool sleeping; // for future development uint8_t sequences; // sequence number of packet uint16_t fault; // numbber of fault in verify bool first_click; // don't send packet yet in the first click uint8_t find_entry(); // request to start sending marzullo result to radio command result_t Anycastlib.start_timer() { return call Sensor_Timer.start(TIMER_REPEAT, SENSOR_TIMER); } // request to start sending verify result to radio command result_t Anycastlib.start_verify(int16_t t_fault) { fault = t_fault; return call Sensor_Timer.start(TIMER_REPEAT, SENSOR_TIMER); } /** * Used to initialize this component. */ command result_t StdControl.init() { uint8_t i; //call Leds.init(); // initalize Leds call CommControl.init(); // initalize Radio sleeping = FALSE; // initalize routing table atomic { state = IDLE; // init set state = IDLE // initalize routing table for(i=0; i<ROUTING_TABLE;i++) { rtable[i] = (struct Mrouting*) malloc(sizeof(struct Mrouting)); rtable[i]->empty = TRUE; // asserting routing table empty } // initalize buffer/index values currentMsg = 0; jcurrentMsg = 0; fcurrentMsg = 0; sequences=0; } dbg(DBG_BOOT, "Anycast initialized\n"); return SUCCESS; } /** * Starts the SensorControl and CommControl components. * @return Always returns SUCCESS. */ command result_t StdControl.start() { // Starting each components call CommControl.start(); call CLNNControl.start(); call Table_Timer.start(TIMER_REPEAT, TABLE_TIMER); return SUCCESS; } /** * Stops the SensorControl and CommControl components. * @return Always returns SUCCESS. */ command result_t StdControl.stop() { // Stoping each components call CommControl.stop(); call Table_Timer.stop(); call CLNNControl.stop(); return SUCCESS; } /** * Signalled when the clock ticks. * @return Always returns SUCCESS. */ event result_t Table_Timer.fired() { int8_t i; //check for routing table timeout and time-- // set entry invalid when timeout for(i=0; i<ROUTING_TABLE; i++) { atomic { rtable[i]->timer--; if(rtable[i]->timer == 0 && rtable[i]->empty == FALSE) { rtable[i]->empty = TRUE; } } } return SUCCESS; } /* awake from sleep for future development */ event result_t Sleep_Timer.fired() { sleeping = FALSE; call StdControl.start(); call Sleep_Timer.stop(); return SUCCESS; } // sending of marzullo result to radio result_t sendMarzullo() { struct CLNNMsg *datat; int8_t use_entry; result_t recv_train; if(packet_to_send == 0) { atomic { state = IDLE; call Sensor_Timer.stop(); call CLNNlib.reset(); } return SUCCESS; } atomic { datat = (struct CLNNMsg *)msg[currentMsg].data; } use_entry = find_entry(); if(use_entry == -1) { // there is currently no route in routing table return SUCCESS; } // request for CLNN data recv_train = call CLNNlib.request(datat); if(recv_train != SUCCESS) { // CLNN has not finished. So, no need to send anything return SUCCESS; } // prepare for sending packet atomic { datat->type = DATA; datat->src = TOS_LOCAL_ADDRESS; datat->trust = 1; msg[currentMsg].length = TOSH_DATA_LENGTH; msg[currentMsg].group = TOS_AM_GROUP; msg[currentMsg].addr = rtable[use_entry]->parent; /* send the message to the parent */ if (call SendMsg.send(rtable[use_entry]->parent,TOSH_DATA_LENGTH, &msg[currentMsg])){ currentMsg ^= 0x1; packet_to_send--; //call Leds.redToggle(); } } return SUCCESS; } // request the sending of verfiy data to radio result_t sendVerify() { struct CLNNMsg *datat; int8_t use_entry; if(packet_to_send == 0) { atomic { state = IDLE; call Sensor_Timer.stop(); } return SUCCESS; } atomic { datat = (struct CLNNMsg *)msg[currentMsg].data; } use_entry = find_entry(); if(use_entry == -1) { // there is currently no route in routing table return SUCCESS; } // prepare for sending packet atomic { datat->type = DATA; datat->src = TOS_LOCAL_ADDRESS; datat->f = fault; datat->trust = 2; msg[currentMsg].length = TOSH_DATA_LENGTH; msg[currentMsg].group = TOS_AM_GROUP; msg[currentMsg].addr = rtable[use_entry]->parent; /* send the message to the parent */ if (call SendMsg.send(rtable[use_entry]->parent,TOSH_DATA_LENGTH, &msg[currentMsg])){ currentMsg ^= 0x1; packet_to_send--; //call Leds.redToggle(); } } return SUCCESS; } /* request for sensor data */ event result_t Sensor_Timer.fired() { if(first_click) { first_click = FALSE; // first click don't send anything due to return SUCCESS; // synchronization problem } if(state == TRAINING) sendMarzullo(); else if(state == VERIFY) sendVerify(); return SUCCESS; } event result_t SendMsg.sendDone(TOS_MsgPtr sent, result_t success) { return SUCCESS; } /* This will sleep the mote */ /* for future development */ void doSleep() { sleeping = TRUE; call StdControl.stop(); call Sleep_Timer.start(TIMER_ONE_SHOT, SLEEP_TIMER); } /* Operation to be done when the mote receive a Join from the monitor */ void doJoin(TOS_MsgPtr rmsg) { uint8_t i; uint8_t t_seq; struct Anycast *join; struct Anycast *sendt; join = (struct Anycast *)rmsg->data; // on receiving request from sink if(state == IDLE && join->request == TRAINING) { atomic { state = TRAINING; packet_to_send = PACKET_TO_SEND; first_click = TRUE; call CLNNlib.start_training(); // start training } } if(state == IDLE && join->request == VERIFY) { atomic { state = VERIFY; packet_to_send = PACKET_TO_SEND; first_click = TRUE; call CLNNlib.start_verify(join->min,join->max); // start verify } } atomic { /* check if sink exist */ for(i=0; i<ROUTING_TABLE; i++) { if(rtable[i]->sinkID == join->src && rtable[i]->empty == FALSE) // do not set sinkID = 2^16 = -1 break; } t_seq = 0; /* if sink does exist */ if(i < ROUTING_TABLE) t_seq = rtable[i]->seqNum; } /* check seq number: maximum 240 */ if(join->seqNum <= t_seq && t_seq < MAX_SEQ && i < ROUTING_TABLE) { // drop the rmsg return; } /* update the table */ else { atomic { rtable[i]->sinkID = join->src; rtable[i]->parent = join->parent; rtable[i]->seqNum = join->seqNum; rtable[i]->hop = join->hop; rtable[i]->timer = TABLE_EXIST; rtable[i]->empty = FALSE; } } /* if sink does not exist */ if(i >= ROUTING_TABLE) { atomic { /* check if any entry empty */ for(i=0; i<ROUTING_TABLE; i++) { if(rtable[i]->empty == TRUE) break; } /* if there is entry empty */ if(i < ROUTING_TABLE) { /* add sink */ rtable[i]->sinkID = join->src; rtable[i]->parent = join->parent; rtable[i]->hop = join->hop; rtable[i]->seqNum = join->seqNum; rtable[i]->timer = TABLE_EXIST; rtable[i]->empty = FALSE; } else { uint8_t depth = rtable[0]->hop; uint8_t max = 0; /* find the entry with max hop count */ for(i=1; i<ROUTING_TABLE; i++) { if(rtable[i]->hop > depth && rtable[i]->empty == FALSE) { depth = rtable[i]->hop; max = i; } } /* replace sink with max hop count */ rtable[i]->sinkID = join->src; rtable[i]->hop = join->hop; rtable[i]->seqNum = join->seqNum; rtable[i]->timer = TABLE_EXIST; rtable[i]->parent = join->parent; rtable[i]->empty = FALSE; } } } atomic { sendt = (struct Anycast *)jmsg[jcurrentMsg].data; sendt->type = JOIN; sendt->src = join->src; // sinkID sendt->parent = TOS_LOCAL_ADDRESS; sendt->seqNum = join->seqNum; sendt->hop = join->hop+1; sendt->request = join->request; sendt->min = join->min; sendt->max = join->max; jmsg[jcurrentMsg].length = TOSH_DATA_LENGTH; jmsg[jcurrentMsg].group = TOS_AM_GROUP; jmsg[jcurrentMsg].addr = TOS_BCAST_ADDR; /* rebroadcast the message */ if(call SendMsg.send(TOS_BCAST_ADDR,TOSH_DATA_LENGTH,&jmsg[jcurrentMsg])) { jcurrentMsg ^= 0x1; //call Leds.redToggle(); } } } /* find a shortest path sink */ uint8_t find_entry() { uint8_t i,j; uint8_t min, min_i; // find first valid entry for(i=0; i<ROUTING_TABLE; i++) { if(rtable[i]->empty == FALSE) break; } if(i == ROUTING_TABLE) return -1; min = rtable[i]->hop; min_i = i; for(j=i; j<ROUTING_TABLE; j++) { if(rtable[j]->hop < min && rtable[i]->empty == FALSE) { min = rtable[j]->hop; min_i = j; } } return min_i; } /* Operation to be done when the mote receive a Data from a child */ void doData(TOS_MsgPtr rmsg) { int8_t i; int16_t parent; TOS_MsgPtr fmsgpt; /*Find the shortes path*/ int8_t use_entry = find_entry(); if(use_entry == -1) { return; // if there is no route to parent, there is nothing we can do } atomic { parent = rtable[use_entry]->parent; fmsgpt = &fmsg[fcurrentMsg]; for(i=0; i<TOSH_DATA_LENGTH; i++) { fmsgpt->data[i] = rmsg->data[i]; } fmsg[fcurrentMsg].length = TOSH_DATA_LENGTH; fmsg[fcurrentMsg].group = TOS_AM_GROUP; fmsg[fcurrentMsg].addr = parent; /* forward the message to the parent */ if (call SendMsg.send(parent,TOSH_DATA_LENGTH,&fmsg[fcurrentMsg])){ fcurrentMsg ^= 0x1; //call Leds.yellowToggle(); } } } // on reciving a message event TOS_MsgPtr ReceiveMsg.receive(TOS_MsgPtr rmsg){ switch (rmsg->data[0]) { case(JOIN): doJoin(rmsg); break; case(DATA): doData(rmsg); break; default: break; } return rmsg; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -