?? anycastm.nc
字號(hào):
/* 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; uint8_t packet_to_send; struct Mrouting *rtable[ROUTING_TABLE]; // routing table uint8_t sequences; // sequence number of packet uint16_t fault; uint16_t c_min; uint16_t c_max; bool first_click; uint16_t c_buffer[NUM_UNITS]; struct Anycast *cjoin; uint8_t find_entry(); command result_t Anycastlib.start_timer() { return call Sensor_Timer.start(TIMER_REPEAT, SENSOR_TIMER); } command result_t Anycastlib.start_verify(uint16_t t_fault,uint16_t t_min, uint16_t t_max, uint16_t t_buffer[]) { uint8_t i; /* [KS] Include buffer ADC */ // copy the parameters to be used in the packet for(i=0; i<NUM_UNITS; i++) c_buffer[i] = t_buffer[i]; fault = t_fault; c_min = t_min; c_max = t_max; 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 cjoin = NULL; // initalize routing table atomic { 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 start verify */ event result_t Sleep_Timer.fired() { state = VERIFY; packet_to_send = PACKET_TO_SEND; first_click = TRUE; call CLNNlib.start_verify(cjoin); return SUCCESS; } // send Marzullo result to Radio result_t sendMarzullo() { struct Cluster_Msg *datat; int8_t use_entry; result_t recv_train; // have we completed repeat pkt sending? if(packet_to_send == 0) { atomic { state = IDLE; // finish go to idle state call Sensor_Timer.stop(); call CLNNlib.reset(); } return SUCCESS; } atomic { datat = (struct Cluster_Msg *)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; 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; } // Send Verify data to Radio result_t sendVerify() { struct Cluster_Msg *datat; int8_t use_entry; // have we finish sending repeat pkts? if(packet_to_send == 0) { atomic { state = IDLE; call Sensor_Timer.stop(); } return SUCCESS; } atomic { datat = (struct Cluster_Msg *)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; // type datat->src = TOS_LOCAL_ADDRESS; // local address datat->train = fault; // number of fault of ADC readings /* [KS] Include 10 ADC readings */ datat->win1 = c_min; // ADC minimum reading datat->win2 = c_max; // ADC maximum reading // below is the latest 10 reading from the ADC datat->win3 = c_buffer[0]; datat->win4 = c_buffer[1]; datat->min1 = c_buffer[2]; datat->min2 = c_buffer[3]; datat->min3 = c_buffer[4]; datat->min4 = c_buffer[5]; datat->max1 = c_buffer[6]; datat->max2 = c_buffer[7]; datat->max3 = c_buffer[8]; datat->max4 = c_buffer[9]; 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; return SUCCESS; } if(state == TRAINING) sendMarzullo(); else if(state == VERIFY) sendVerify(); return SUCCESS; } event result_t SendMsg.sendDone(TOS_MsgPtr sent, result_t success) { return SUCCESS; } /* Operation to be done when the mote receive a Join from the monitor */ void doJoin(TOS_MsgPtr rmsg) { uint8_t t_seq; uint8_t i; struct Anycast *join; struct Anycast *sendt; join = (struct Anycast *)rmsg->data; if(state == IDLE && join->request == TRAINING) { atomic { state = TRAINING; packet_to_send = PACKET_TO_SEND; first_click = TRUE; call CLNNlib.start_training(); } } if(state == IDLE && join->request == VERIFY) { atomic { state = SLEEP; cjoin = join; call Sleep_Timer.start(TIMER_ONE_SHOT,VERIFY_DELAY); } } 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; // copy all the fields of the pkt sendt->seqNum = join->seqNum; sendt->request = join->request; sendt->hop = join->hop+1; sendt->min = join->min; sendt->max = join->max; sendt->min1 = join->min1; sendt->max1 = join->max1; sendt->min2 = join->min2; sendt->max2 = join->max2; sendt->min3 = join->min3; sendt->max3 = join->max3; sendt->nintervals = join->nintervals; 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; } } } // what to do when we receive a packet 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; }}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -