📄 acbasem.nc
字号:
/* Anycast/Marzullo Base Implmentation. *//* Modified by Kin Sun Ho (ksho@cse) *//* Last Modified: 07 September 2005 *//* Modified from TOSBase *//* * @author Phil Buonadonna * @author Gilman Tolle *//* leds red: sending broadcast packets green: sending to UART yellow: receving data packets*/includes Sasha;#ifndef TOSBASE_BLINK_ON_DROP#define TOSBASE_BLINK_ON_DROP#endifmodule ACBaseM { provides interface StdControl; uses { interface StdControl as UARTControl; interface BareSendMsg as UARTSend; interface ReceiveMsg as UARTReceive; interface TokenReceiveMsg as UARTTokenReceive; interface StdControl as RadioControl; interface BareSendMsg as RadioSend; interface ReceiveMsg as RadioReceive; interface Leds; interface Timer as JTimer; interface Timer as MTimer; interface Marzullolib; interface StdControl as MarzulloControl; }}implementation{ enum { UART_QUEUE_LEN = 12, RADIO_QUEUE_LEN = 12, }; TOS_Msg marzullo_result; TOS_Msg uartQueueBufs[UART_QUEUE_LEN]; TOS_MsgPtr uartQueue[UART_QUEUE_LEN]; uint8_t uartIn, uartOut; bool uartBusy, uartFull; TOS_Msg radioQueueBufs[RADIO_QUEUE_LEN]; TOS_MsgPtr radioQueue[RADIO_QUEUE_LEN]; uint8_t radioIn, radioOut; bool radioBusy, radioFull; uint8_t sequences; // sequences number uint8_t state; // current state uint8_t repeat; // number of repeat for request broadcast uint16_t min; // - | used to do the verify uint16_t max; // - | uint16_t record[MAX_MOTES]; // resizeable array of Mote Info uint8_t nrecord; // number of mote heard uint8_t fault_mote;// number of fault mote task void UARTSendTask(); task void RadioSendTask(); void failBlink(); void dropBlink(); command result_t StdControl.init() { result_t ok1, ok2, ok3; uint8_t i; atomic { sequences = 0; state = TRAINING; repeat = REPEAT_MSG; } for (i = 0; i < UART_QUEUE_LEN; i++) { uartQueue[i] = &uartQueueBufs[i]; } uartIn = uartOut = 0; uartBusy = FALSE; uartFull = FALSE; for (i = 0; i < RADIO_QUEUE_LEN; i++) { radioQueue[i] = &radioQueueBufs[i]; } radioIn = radioOut = 0; radioBusy = FALSE; radioFull = FALSE; ok1 = call UARTControl.init(); ok2 = call RadioControl.init(); ok3 = call Leds.init(); dbg(DBG_BOOT, "TOSBase initialized\n"); return rcombine3(ok1, ok2, ok3); } command result_t StdControl.start() { call JTimer.start(TIMER_REPEAT,DISCOVERY); call UARTControl.start(); call RadioControl.start(); return SUCCESS; } command result_t StdControl.stop() { call UARTControl.stop(); call RadioControl.stop(); call JTimer.stop(); call MTimer.stop(); return SUCCESS; } /*Broadcast Join packet*/ task void BroadcastJoin() { struct Anycast *m; dbg(DBG_USR1, "Monitoring Node broadcasting Join packet.\n"); atomic { m= (Anycast *) (radioQueue[radioOut])->data; m->type = JOIN; m->src = TOS_LOCAL_ADDRESS; m->parent = TOS_LOCAL_ADDRESS; m->seqNum = sequences++; m->hop = 0; if(state == TRAINING || state == VERIFY) { m->request = state; if(state == VERIFY) { m->min = min; m->max = max; } repeat--; if(repeat == 0) { if(state == TRAINING) state = MARZULLO; if(state == VERIFY) state = WAIT; call MTimer.start(TIMER_ONE_SHOT,TEN_MIN); } } else m->request = 0; radioQueue[radioOut]->group = TOS_AM_GROUP; radioQueue[radioOut]->addr = TOS_BCAST_ADDR; radioQueue[radioOut]->length = TOSH_DATA_LENGTH; if (!radioBusy) { call RadioSend.send(radioQueue[radioOut]); radioBusy = TRUE; } }//end atomic }//end Broadcast Join // Operation when a DATA packet arrive // Add Data to the Marzullo structure result_t doData(TOS_MsgPtr rmsg) { struct CLNNMsg *datat; result_t r; datat = (struct CLNNMsg *)rmsg->data; // stop timer call MTimer.stop(); // store mote data r = call Marzullolib.add_mote(datat); // start timer again call MTimer.start(TIMER_ONE_SHOT,TIMEOUT); return r; } // Operation when a FAILT packet arrive // Check if this is a fault mote result_t doOnce(TOS_MsgPtr rmsg) { struct CLNNMsg *datat; int16_t mote_id; int16_t fault; int8_t i; datat = (struct CLNNMsg *)rmsg->data; call MTimer.stop(); mote_id = datat->src; fault = datat->f; for(i=0; i<nrecord; i++) { if(mote_id == record[i]) break; } if(i != nrecord) return FAIL; // drop if not new pkt if(nrecord == MAX_MOTES) return FAIL; record[nrecord] = mote_id; nrecord++; if(fault > MAX_FAULTS) fault_mote++; call MTimer.start(TIMER_ONE_SHOT,TIMEOUT); return SUCCESS; } event TOS_MsgPtr RadioReceive.receive(TOS_MsgPtr Msg) { result_t print; uint8_t t= Msg->data[0];//type of the packet TOS_MsgPtr pBuf = Msg; print = FAIL; dbg(DBG_USR1, "TOSBase received radio packet.\n"); if(Msg->addr != TOS_LOCAL_ADDRESS) return Msg; if(Msg->length != TOSH_DATA_LENGTH) return Msg; if ((!Msg->crc) || (Msg->group != TOS_AM_GROUP)) return Msg; /*What Kind of message is it*/ switch (t){ case(DATA): if(state == MARZULLO) { call Leds.greenToggle(); print = doData(Msg); // on recving result from mote } if(state == WAIT) { print = doOnce(Msg); call Leds.yellowToggle(); call MTimer.stop(); call MTimer.start(TIMER_ONE_SHOT,TIMEOUT); } if(print == SUCCESS) { atomic { if (!uartFull) { pBuf = uartQueue[uartIn]; uartQueue[uartIn] = Msg; if( ++uartIn >= UART_QUEUE_LEN ) uartIn = 0; if (uartIn == uartOut) { uartFull = TRUE; } if (!uartBusy) { if (post UARTSendTask()) { uartBusy = TRUE; } } } else { dropBlink(); } } } break; default: break; } return pBuf; } task void UARTSendTask() { bool noWork = FALSE; dbg (DBG_USR1, "TOSBase forwarding Radio packet to UART\n"); atomic { if (uartIn == uartOut && uartFull == FALSE) { uartBusy = FALSE; noWork = TRUE; } } if (noWork) { return; } if(uartQueue[uartOut]->length != TOSH_DATA_LENGTH) return; if (call UARTSend.send(uartQueue[uartOut]) == SUCCESS) { //call Leds.greenToggle(); } else { failBlink(); post UARTSendTask(); } } event result_t UARTSend.sendDone(TOS_MsgPtr msg, result_t success) { if (!success) { failBlink(); } else { atomic { if (msg == uartQueue[uartOut]) { if( ++uartOut >= UART_QUEUE_LEN ) uartOut = 0; if (uartFull) { uartFull = FALSE; } } } } post UARTSendTask(); return SUCCESS; } event TOS_MsgPtr UARTReceive.receive(TOS_MsgPtr Msg) { return Msg; } event TOS_MsgPtr UARTTokenReceive.receive(TOS_MsgPtr Msg, uint8_t Token) { TOS_MsgPtr pBuf = Msg; bool reflectToken = FALSE; dbg(DBG_USR1, "TOSBase received UART token packet.\n"); atomic { if (!radioFull) { reflectToken = TRUE; pBuf = radioQueue[radioIn]; radioQueue[radioIn] = Msg; if( ++radioIn >= RADIO_QUEUE_LEN ) radioIn = 0; if (radioIn == radioOut) radioFull = TRUE; if (!radioBusy) { if (post RadioSendTask()) { radioBusy = TRUE; } } } else { dropBlink(); } } if (reflectToken) { call UARTTokenReceive.ReflectToken(Token); } return pBuf; } task void RadioSendTask() { bool noWork = FALSE; dbg (DBG_USR1, "TOSBase forwarding UART packet to Radio\n"); atomic { if (radioIn == radioOut && radioFull == FALSE) { radioBusy = FALSE; noWork = TRUE; } } if (noWork) return; radioQueue[radioOut]->group = TOS_AM_GROUP; if (call RadioSend.send(radioQueue[radioOut]) == SUCCESS) { call Leds.redToggle(); } else { failBlink(); post RadioSendTask(); } } event result_t RadioSend.sendDone(TOS_MsgPtr msg, result_t success) { if (!success) { failBlink(); } else { atomic { if (msg == radioQueue[radioOut]) { if( ++radioOut >= RADIO_QUEUE_LEN ) radioOut = 0; if (radioFull) radioFull = FALSE; } } } post RadioSendTask(); return SUCCESS; }/* Time to rebrodcast Join Message*/ event result_t JTimer.fired() { post BroadcastJoin(); return SUCCESS; } // Marzullo Timeout event result_t MTimer.fired() { CLNNMsg *result; // The Verification Stage // Check # of fault mote, if > half -> retraining // else verify again if(state == WAIT) { if(nrecord == 0) { atomic { state = TRAINING; repeat = REPEAT_MSG; } return SUCCESS; } if(nrecord > 0 && nrecord-fault_mote >= fault_mote) { atomic { nrecord = 0; fault_mote = 0; state = VERIFY; repeat = REPEAT_MSG; } return SUCCESS; } atomic { state = TRAINING; repeat = REPEAT_MSG; } return SUCCESS; } // else if state == MARZULLO // doMarzullo and start verify marzullo_result.group = TOS_AM_GROUP; marzullo_result.addr = TOS_UART_ADDR; marzullo_result.length = TOSH_DATA_LENGTH; result = (struct CLNNMsg *)marzullo_result.data; // do marzullo result = call Marzullolib.doMarzullo(result); // if no Marzullo was done... if(result == NULL) { atomic { state = TRAINING; repeat = REPEAT_MSG; } } else { // set state to verify atomic { state = VERIFY; repeat = REPEAT_MSG; nrecord = 0; fault_mote = 0; min = result->min; max = result->max; radioQueue[radioOut]->group = TOS_AM_GROUP; radioQueue[radioOut]->addr = TOS_BCAST_ADDR; radioQueue[radioOut]->length = TOSH_DATA_LENGTH; // send result uart call UARTSend.send(&marzullo_result); } } // clear variables call Marzullolib.reset(); return SUCCESS; } void dropBlink() {#ifdef TOSBASE_BLINK_ON_DROP call Leds.yellowToggle();#endif } void failBlink() {#ifdef TOSBASE_BLINK_ON_FAIL call Leds.yellowToggle();#endif }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -