X-Git-Url: https://oss.titaniummirror.com/gitweb/?a=blobdiff_plain;f=tos%2Fchips%2Ftda5250%2Fmac%2FCsmaMacP.nc;h=7f17e4145d0ef57d8fd763f2ceea178dd0d0cac0;hb=a17321a72cfe58782f13e2b27afff01fae9b9e39;hp=aba1739608d4b919e4867ffadef8026d09559901;hpb=1ba974b83d19fc41bf80acd52726f36f7f1df297;p=tinyos-2.x.git diff --git a/tos/chips/tda5250/mac/CsmaMacP.nc b/tos/chips/tda5250/mac/CsmaMacP.nc index aba17396..7f17e414 100644 --- a/tos/chips/tda5250/mac/CsmaMacP.nc +++ b/tos/chips/tda5250/mac/CsmaMacP.nc @@ -29,8 +29,10 @@ */ + #include "radiopacketfunctions.h" #include "flagfunctions.h" +#include "PacketAck.h" /** * An implementation of a Csma Mac. @@ -39,58 +41,96 @@ * @author: Kevin Klues (klues@tkn.tu-berlin.de) * @author Philipp Huppertz (huppertz@tkn.tu-berlin.de) */ + +// #define MACM_DEBUG // debug... module CsmaMacP { provides { - interface Init; interface SplitControl; interface MacSend; interface MacReceive; + interface Packet; } uses { interface StdControl as CcaStdControl; interface PhySend as PacketSend; interface PhyReceive as PacketReceive; + interface RadioTimeStamping; interface Tda5250Control as RadioModes; + interface ResourceRequested as RadioResourceRequested; interface UartPhyControl; - + interface Packet as SubPacket; + interface ChannelMonitor; interface ChannelMonitorControl; interface ChannelMonitorData; + interface Resource as RssiAdcResource; interface Random; + + interface Timer as ReRxTimer; + interface Duplicate; + interface TimeDiff16; interface Alarm as Timer; - - interface GeneralIO as Led0; - interface GeneralIO as Led1; - interface GeneralIO as Led2; - interface GeneralIO as Led3; + async command am_addr_t amAddress(); + interface LocalTime as LocalTime32kHz; + +#ifdef MACM_DEBUG + interface SerialDebug; +#endif } } implementation { -#define CSMA_ACK 100 -#define BYTE_TIME 17 -// #define MACM_DEBUG // debug... -#define MAX_LONG_RETRY 3 // Missing acks, or short retry limit hits -> increase long retry -#define MAX_SHORT_RETRY 5 // busy channel -> increase short retry -#define DIFS 165 // 5ms to get an ACK started -#define ACK_TIMEOUT 20*BYTE_TIME -#define MIN_BACKOFF_MASK 0x7F // roughly 4ms for Rx/Tx turnaround defines this value -#define CHECK_RX_LIVENESS_INTERVALL 165 + /****** debug vars & defs & functions ***********************/ +#ifdef MACM_DEBUG + void sdDebug(uint16_t p) { + call SerialDebug.putPlace(p); + }; +#else + void sdDebug(uint16_t p) {}; +#endif + + /******* constants and type definitions *********************/ + enum { + + BYTE_TIME=ENCODED_32KHZ_BYTE_TIME, // phy encoded + PREAMBLE_BYTE_TIME=TDA5250_32KHZ_BYTE_TIME, // no coding + PHY_HEADER_TIME=6*PREAMBLE_BYTE_TIME, // 6 Phy Preamble + TIME_CORRECTION=TDA5250_32KHZ_BYTE_TIME+2, // difference between txSFD and rxSFD + + + SUB_HEADER_TIME=PHY_HEADER_TIME + sizeof(tda5250_header_t)*BYTE_TIME, + SUB_FOOTER_TIME=2*BYTE_TIME, // 2 bytes crc + MAXTIMERVALUE=0xFFFF, // helps to compute backoff + DATA_DETECT_TIME=17, + RX_SETUP_TIME=102, // time to set up receiver + TX_SETUP_TIME=58, // time to set up transmitter + ADDED_DELAY = 30, + RX_ACK_TIMEOUT=RX_SETUP_TIME + PHY_HEADER_TIME + 2*ADDED_DELAY, + TX_GAP_TIME=RX_ACK_TIMEOUT + TX_SETUP_TIME + 33, + MAX_SHORT_RETRY=7, + MAX_LONG_RETRY=4, + BACKOFF_MASK=0xFFF, // minimum time around one packet time + MIN_PREAMBLE_BYTES=2, + TOKEN_ACK_FLAG = 64, + TOKEN_ACK_MASK = 0x3f, + INVALID_SNR = 0xffff + }; /**************** Module Global Variables *****************/ /* state vars & defs */ typedef enum { - SW_CCA, // switch to CCA - CCA, // clear channel assessment + CCA, // clear channel assessment + CCA_ACK, SW_RX, // switch to receive RX, // rx mode done, listening & waiting for packet SW_RX_ACK, RX_ACK, + RX_ACK_P, RX_P, SW_TX, TX, @@ -102,123 +142,87 @@ implementation /* flags */ typedef enum { RSSI_STABLE = 1, - BUSY_DETECTED_VIA_RSSI = 2, - CHECK_RX_LIVENESS = 4, - DIFS_TIMER_FIRED = 8 + RESUME_BACKOFF = 2, + CANCEL_SEND = 4, + CCA_PENDING = 8 } flags_t; /* Packet vars */ - message_t* txBufPtr; + message_t* txBufPtr = NULL; message_t ackMsg; uint8_t txLen; - int16_t rssiValue; - uint8_t shortRetryCounter; - uint8_t longRetryCounter; + uint8_t shortRetryCounter = 0; - macState_t macState; - uint8_t flags; - - uint16_t slotMask; + uint8_t longRetryCounter = 0; + unsigned checkCounter; - /****** debug vars & defs & functions ***********************/ -#ifdef MACM_DEBUG -#define HISTORY_ENTRIES 40 - typedef struct { - int index; - macState_t state; - int place; - } history_t; - - history_t history[HISTORY_ENTRIES]; - unsigned histIndex; - void storeOldState(int p) { - atomic { - history[histIndex].index = histIndex; - history[histIndex].state = macState; - history[histIndex].place = p; - histIndex++; - if(histIndex >= HISTORY_ENTRIES) histIndex = 0; - } - } -#else - void storeOldState(int p) {}; -#endif - - void signalFailure(uint8_t place) { -#ifdef MACM_DEBUG - unsigned long i; - atomic { - for(;;) { - call Led0.set(); - call Led1.clr(); - call Led2.clr(); - call Led3.clr(); - - for(i = 0; i < 1000000; i++) { - ; - } - - (place & 1) ? call Led0.set() : call Led0.clr(); - (place & 2) ? call Led1.set() : call Led1.clr(); - (place & 4) ? call Led2.set() : call Led2.clr(); - (place & 8) ? call Led3.set() : call Led3.clr(); - - for(i = 0; i < 1000000; i++) { - ; - } - - (macState & 1) ? call Led0.set() : call Led0.clr(); - (macState & 2) ? call Led1.set() : call Led1.clr(); - (macState & 4) ? call Led2.set() : call Led2.clr(); - (macState & 8) ? call Led3.set() : call Led3.clr(); + macState_t macState = INIT; + uint8_t flags = 0; + uint8_t seqNo; + + uint16_t restLaufzeit; - for(i = 0; i < 1000000; i++) { - ; - } - } - } -#endif - } + uint16_t rssiValue = 0; - void signalMacState() { -#ifdef MACM_DEBUG -// (macState & 1) ? call Led0.set() : call Led0.clr(); -// (macState & 2) ? call Led1.set() : call Led1.clr(); -// (macState & 4) ? call Led2.set() : call Led2.clr(); -// (macState & 8) ? call Led3.set() : call Led3.clr(); -#endif - } + uint32_t rxTime = 0; /****** Secure switching of radio modes ***/ task void SetRxModeTask(); task void SetTxModeTask(); + + task void ReleaseAdcTask() { + macState_t ms; + atomic ms = macState; + if(isFlagSet(&flags, CCA_PENDING)) { + post ReleaseAdcTask(); + } + else { + if((ms > CCA) && (ms != INIT) && call RssiAdcResource.isOwner()) { + call RssiAdcResource.release(); + } + } + } void setRxMode(); void setTxMode(); + void requestAdc() { + if(macState != INIT) { + call RssiAdcResource.immediateRequest(); + } + else { + call RssiAdcResource.request(); + } + } + void setRxMode() { + rssiValue = INVALID_SNR; if(call RadioModes.RxMode() == FAIL) { post SetRxModeTask(); } + if(macState == INIT) { + requestAdc(); + } else { + post ReleaseAdcTask(); + } } task void SetRxModeTask() { atomic { if((macState == SW_RX) || (macState == SW_RX_ACK) || - (macState == SW_CCA) || (macState == INIT)) setRxMode(); } } void setTxMode() { clearFlag(&flags, RSSI_STABLE); - clearFlag(&flags, BUSY_DETECTED_VIA_RSSI); if(call RadioModes.TxMode() == FAIL) { post SetTxModeTask(); } + post ReleaseAdcTask(); } task void SetTxModeTask() { @@ -229,25 +233,67 @@ implementation } /**************** Helper functions ********/ - uint16_t backoff() { - uint16_t mask = slotMask; - unsigned i; - for(i = 0; i < longRetryCounter; i++) { - mask = (mask << 1) + 1; - } + + task void postponeReRx() { + call ReRxTimer.startOneShot(5000); + } + + uint16_t backoff(uint8_t counter) { + uint16_t mask = BACKOFF_MASK >> (MAX_LONG_RETRY - counter); return (call Random.rand16() & mask); } - + + void interruptBackoffTimer() { + if(call Timer.isRunning()) { + restLaufzeit = call TimeDiff16.computeDelta(call Timer.getAlarm(), call Timer.getNow()); + call Timer.stop(); + if(restLaufzeit > BACKOFF_MASK) { + restLaufzeit = call Random.rand16() & 0xFF; + } + setFlag(&flags, RESUME_BACKOFF); + } + } + + void storeStrength(message_t *m) { + if(rssiValue != INVALID_SNR) { + (getMetadata(m))->strength = rssiValue; + } + else { + if(call RssiAdcResource.isOwner()) { + (getMetadata(m))->strength = call ChannelMonitorData.readSnr(); + } + else { + (getMetadata(m))->strength = 1; + } + } + } + void signalSendDone(error_t error) { message_t *m; + error_t e = error; atomic { m = txBufPtr; txBufPtr = 0; txLen = 0; longRetryCounter = 0; shortRetryCounter = 0; + if(isFlagSet(&flags, CANCEL_SEND)) { + e = ECANCEL; + } + storeStrength(m); + clearFlag(&flags, CANCEL_SEND); + } + signal MacSend.sendDone(m, e); + } + + void updateLongRetryCounters() { + longRetryCounter++; + shortRetryCounter = 1; + if(longRetryCounter > MAX_LONG_RETRY) { + sdDebug(13); + getMetadata(txBufPtr)->ack = WAS_NOT_ACKED; + signalSendDone(FAIL); } - signal MacSend.sendDone(m, error); } void updateRetryCounters() { @@ -256,63 +302,100 @@ implementation longRetryCounter++; shortRetryCounter = 1; if(longRetryCounter > MAX_LONG_RETRY) { + getMetadata(txBufPtr)->ack = WAS_NOT_ACKED; signalSendDone(FAIL); } } } - void checkSend() { - if((txBufPtr != NULL) && (macState == RX) && (!call Timer.isRunning())) { - clearFlag(&flags, CHECK_RX_LIVENESS); - clearFlag(&flags, DIFS_TIMER_FIRED); - /* if(!call UartPhyControl.isBusy()) { */ - if(isFlagSet(&flags, RSSI_STABLE)) { - macState = CCA; - signalMacState(); - call Timer.start(DIFS); - call ChannelMonitor.start(); - storeOldState(130); - } else { - macState = SW_CCA; - signalMacState(); - storeOldState(131); - } - /* } - else { - storeOldState(132); - updateRetryCounters(); - setFlag(&flags, CHECK_RX_LIVENESS); - call Timer.start(backoff()); - } - */ - } + void computeBackoff() { + if(!isFlagSet(&flags, RESUME_BACKOFF)) { + setFlag(&flags, RESUME_BACKOFF); + restLaufzeit = backoff(longRetryCounter); + updateRetryCounters(); + sdDebug(92); + } + } + + bool isNewMsg(message_t* msg) { + return call Duplicate.isNew(getHeader(msg)->src, getHeader(msg)->dest, + (getHeader(msg)->token) & TOKEN_ACK_MASK); } - bool needsAck(message_t* msg) { - return FALSE; // (getHeader(msg)->addr != AM_BROADCAST_ADDR); + void rememberMsg(message_t* msg) { + call Duplicate.remember(getHeader(msg)->src, getHeader(msg)->dest, + (getHeader(msg)->token) & TOKEN_ACK_MASK); } - /**************** Init ************************/ + void checkSend() { + if((txBufPtr != NULL) && (macState == RX) && (!call Timer.isRunning())) { + macState = CCA; + checkCounter = 0; + requestAdc(); + call Timer.start(DATA_DETECT_TIME); + sdDebug(170); + } + else { + sdDebug(171); + post ReleaseAdcTask(); + } + } - command error_t Init.init(){ - atomic { - txBufPtr = NULL; - macState = INIT; - signalMacState(); - shortRetryCounter = 0; - longRetryCounter = 0; - flags = 0; - slotMask = MIN_BACKOFF_MASK; -#ifdef MACM_DEBUG - histIndex = 0; -#endif + bool needsAckRx(message_t* msg) { + bool rVal = FALSE; + uint8_t token; + if(getHeader(msg)->dest < AM_BROADCAST_ADDR) { + token = getHeader(msg)->token; + if(isFlagSet(&token, ACK_REQUESTED)) rVal = TRUE; } - return SUCCESS; + return rVal; + } + + bool needsAckTx(message_t* msg) { + bool rVal = FALSE; + if(getHeader(msg)->dest < AM_BROADCAST_ADDR) { + if((getMetadata(msg)->ack == ACK_REQUESTED) || (getMetadata(msg)->ack != NO_ACK_REQUESTED)) { + rVal = TRUE; + } + } + return rVal; + } + + void prepareAck(message_t* msg) { + uint8_t rToken = getHeader(msg)->token & TOKEN_ACK_MASK; + setFlag(&rToken, TOKEN_ACK_FLAG); + getHeader(&ackMsg)->token = rToken; + getHeader(&ackMsg)->src = call amAddress(); + getHeader(&ackMsg)->dest = getHeader(msg)->src; + getHeader(&ackMsg)->type = getHeader(msg)->type; + } + + bool msgIsForMe(message_t* msg) { + if(getHeader(msg)->dest == AM_BROADCAST_ADDR) return TRUE; + if(getHeader(msg)->dest == call amAddress()) return TRUE; + return FALSE; } + bool ackIsForMe(message_t* msg) { + uint8_t localToken = seqNo; + setFlag(&localToken, TOKEN_ACK_FLAG); + if((getHeader(msg)->dest == call amAddress()) && (localToken == getHeader(msg)->token)) return TRUE; + return FALSE; + } + + bool isControl(message_t* m) { + uint8_t token = getHeader(m)->token; + return isFlagSet(&token, TOKEN_ACK_FLAG); + } + /**************** SplitControl *****************/ task void StartDoneTask() { + atomic { + macState = RX; + call UartPhyControl.setNumPreambles(MIN_PREAMBLE_BYTES); + } + post ReleaseAdcTask(); signal SplitControl.startDone(SUCCESS); } @@ -320,9 +403,9 @@ implementation call CcaStdControl.start(); atomic { macState = INIT; - signalMacState(); + setRxMode(); - storeOldState(1); + sdDebug(1); } return SUCCESS; } @@ -331,11 +414,15 @@ implementation atomic { if (macState != RX) { post StopDone(); - storeOldState(2); + sdDebug(2); } else { - storeOldState(3); + sdDebug(3); call Timer.stop(); - call Init.init(); + txBufPtr = NULL; + macState = INIT; + shortRetryCounter = 0; + longRetryCounter = 0; + flags = 0; signal SplitControl.stopDone(SUCCESS); } } @@ -343,75 +430,100 @@ implementation command error_t SplitControl.stop() { call CcaStdControl.stop(); - storeOldState(4); + sdDebug(4); post StopDone(); return SUCCESS; } + /****** Packet interface ********************/ + command void Packet.clear(message_t* msg) { + call SubPacket.clear(msg); + } + + command uint8_t Packet.payloadLength(message_t* msg) { + return call SubPacket.payloadLength(msg); + } + + command void Packet.setPayloadLength(message_t* msg, uint8_t len) { + call SubPacket.setPayloadLength(msg,len); + } + + command uint8_t Packet.maxPayloadLength() { + return call SubPacket.maxPayloadLength(); + } + + command void* Packet.getPayload(message_t* msg, uint8_t len) { + return call SubPacket.getPayload(msg, len); + } + /****** Radio(Mode) events *************************/ async event void RadioModes.RssiStable() { atomic { setFlag(&flags, RSSI_STABLE); - if(macState == SW_CCA) { - storeOldState(10); - macState = CCA; - signalMacState(); - call Timer.start(DIFS); - call ChannelMonitor.start(); - } else if(macState == INIT) { - storeOldState(11); - call ChannelMonitorControl.updateNoiseFloor(); - } else { - storeOldState(13); + if(macState == INIT) { + sdDebug(11); + if(call RssiAdcResource.isOwner()) { + call ChannelMonitorControl.updateNoiseFloor(); + } + } + else { + sdDebug(12); } } } async event void RadioModes.RxModeDone() { + post postponeReRx(); atomic { if(macState == SW_RX) { - storeOldState(21); + sdDebug(21); macState = RX; - signalMacState(); - call Timer.start(backoff()); + + if(isFlagSet(&flags, RESUME_BACKOFF)) { + clearFlag(&flags, RESUME_BACKOFF); + call Timer.start(restLaufzeit); + } else { + call Timer.start(backoff(longRetryCounter)); + } } else if(macState == SW_RX_ACK) { - storeOldState(22); + sdDebug(22); macState = RX_ACK; - signalMacState(); - call Timer.start(ACK_TIMEOUT); - } - else if(macState == SW_CCA) { - storeOldState(23); } else if(macState == INIT) { - storeOldState(24); + sdDebug(24); } else { - storeOldState(25); - signalFailure(1); + sdDebug(25); } } } async event void RadioModes.TxModeDone() { + post postponeReRx(); atomic { if(macState == SW_TX) { - storeOldState(30); + sdDebug(30); if(txBufPtr) { macState = TX; - signalMacState(); if(call PacketSend.send(txBufPtr, txLen) == SUCCESS) { - storeOldState(31); + sdDebug(31); } else { - storeOldState(32); - signalFailure(2); + sdDebug(32); } } } + else if(macState == SW_TX_ACK) { + macState = TX_ACK; + + if(call PacketSend.send(&ackMsg, 0) == SUCCESS) { + sdDebug(53); + } else { + sdDebug(54); + } + } else { - storeOldState(33); - signalFailure(3); + sdDebug(33); } } } @@ -420,15 +532,22 @@ implementation async command error_t MacSend.send(message_t* msg, uint8_t len) { error_t err = SUCCESS; atomic { - if((shortRetryCounter == 0) && (txBufPtr == NULL)) { - storeOldState(40); + if((shortRetryCounter == 0) && (txBufPtr == NULL) && (macState != INIT)) { + sdDebug(40); shortRetryCounter = 1; + longRetryCounter = 1; txBufPtr = msg; txLen = len; - if((macState != RX_P) && (macState != RX_ACK)) checkSend(); + sdDebug(10); + sdDebug(len); + seqNo++; + if(seqNo >= TOKEN_ACK_FLAG) seqNo = 1; + getHeader(msg)->token = seqNo; + if(needsAckTx(msg)) getHeader(msg)->token |= ACK_REQUESTED; + if(macState != RX_P) checkSend(); } else { - storeOldState(41); + sdDebug(41); err = EBUSY; } } @@ -439,14 +558,14 @@ implementation error_t err = SUCCESS; if((shortRetryCounter != 0) && (txBufPtr == msg) && (macState != TX) && (macState != RX_ACK) && (macState != SW_RX_ACK)) { - storeOldState(50); + sdDebug(50); shortRetryCounter = 0; txBufPtr = NULL; txLen = 0; signal MacSend.sendDone(msg, ECANCEL); } else { - storeOldState(51); + sdDebug(51); err = FAIL; } return err; @@ -454,178 +573,250 @@ implementation /****** PacketSerializer events **********************/ async event void PacketReceive.receiveDetected() { + rssiValue = INVALID_SNR; if(macState <= RX_ACK) { - storeOldState(60); - rssiValue = 0xFFFF; - call Timer.stop(); - clearFlag(&flags, CHECK_RX_LIVENESS); - if(isFlagSet(&flags, BUSY_DETECTED_VIA_RSSI)) call ChannelMonitor.rxSuccess(); - call ChannelMonitorData.getSnr(); + sdDebug(60); + interruptBackoffTimer(); + if(macState == CCA) computeBackoff(); } if(macState <= RX) { - storeOldState(61); + sdDebug(61); macState = RX_P; - signalMacState(); + + requestAdc(); } else if(macState <= RX_ACK) { - storeOldState(62); - macState = RX_ACK; - signalMacState(); + sdDebug(62); + macState = RX_ACK_P; + } else if(macState == INIT) { - storeOldState(63); + sdDebug(63); } else { - storeOldState(64); - signalFailure(4); + post ReleaseAdcTask(); + sdDebug(64); } } async event message_t* PacketReceive.receiveDone(message_t* msg, void* payload, uint8_t len, error_t error) { message_t* m = msg; + bool isCnt; + macState_t action = RX; if(macState == RX_P) { - storeOldState(70); - if (error == SUCCESS) { - storeOldState(71); - (getMetadata(msg))->strength = rssiValue; - m = signal MacReceive.receiveDone(msg); + if(error == SUCCESS) { + sdDebug(82); + isCnt = isControl(msg); + if(msgIsForMe(msg)) { + if(!isCnt) { + storeStrength(msg); + if(isNewMsg(m)) { + m = signal MacReceive.receiveDone(msg); + rememberMsg(m); + } + if(needsAckRx(msg)) { + sdDebug(87); + action = CCA_ACK; + } else { + sdDebug(88); + } + } + else { + sdDebug(89); + } + } + else { + sdDebug(90); + } + } + else { + sdDebug(91); } - macState = RX; - signalMacState(); - call Timer.start(backoff()); } - else if(macState == RX_ACK) { - storeOldState(72); - if(txBufPtr == NULL) signalFailure(5); - if((error == SUCCESS) && - getFooter(msg)->crc && - (getHeader(msg)->type == CSMA_ACK) && - (*((uint16_t*)(msg->data)) == TOS_NODE_ID)) - { - storeOldState(73); - getMetadata(txBufPtr)->ack = 1; - signalSendDone(SUCCESS); + else if(macState == RX_ACK_P) { + if(error == SUCCESS) { + if(ackIsForMe(msg)) { + sdDebug(92); + (getMetadata(txBufPtr))->ack = WAS_ACKED; + signalSendDone(SUCCESS); + } + else { + sdDebug(93); + updateLongRetryCounters(); + } } else { - storeOldState(74); - updateRetryCounters(); + if(call Timer.isRunning()) { + sdDebug(94); + action = RX_ACK; + } + else { + sdDebug(95); + if(needsAckTx(txBufPtr)) { + updateLongRetryCounters(); + } + else { + signalSendDone(SUCCESS); + } + } } + } + else if(macState == INIT) { + action = INIT; + } + if(action == CCA_ACK) { + prepareAck(msg); + macState = CCA_ACK; + + call Timer.start(RX_SETUP_TIME - TX_SETUP_TIME + ADDED_DELAY); + } + else if(action == RX_ACK) { + macState = RX_ACK; + + } + else if(action == RX) { macState = RX; - signalMacState(); - call Timer.start(backoff()); - } else { - storeOldState(76); + + if(isFlagSet(&flags, RESUME_BACKOFF)) { + clearFlag(&flags, RESUME_BACKOFF); + call Timer.start(restLaufzeit); + } + else { + call Timer.start(backoff(longRetryCounter)); + } + } + else if(action == TX) { + macState = SW_TX; + + setTxMode(); + } + else if(action == INIT) { + + } + else { + sdDebug(94); } - return m; + post ReleaseAdcTask(); + return m; } async event void PacketSend.sendDone(message_t* msg, error_t error) { if(macState == TX) { - if(msg != txBufPtr) signalFailure(7); - if(needsAck(msg)) { - if(error == SUCCESS) { - storeOldState(80); - macState = SW_RX_ACK; - signalMacState(); - } else { - storeOldState(81); - macState = SW_RX; - signalMacState(); - } + if(needsAckTx(msg)) { + sdDebug(97); + macState = SW_RX_ACK; + + call Timer.start(RX_ACK_TIMEOUT); } else { - macState = SW_RX; - signalMacState(); + sdDebug(99); signalSendDone(error); + macState = SW_RX; + } + setRxMode(); } else if(macState == TX_ACK) { - storeOldState(83); - if(msg != &ackMsg) signalFailure(8); macState = SW_RX; - signalMacState(); - } - else { - storeOldState(84); - signalFailure(9); + + setRxMode(); } - setRxMode(); + post ReleaseAdcTask(); } /****** Timer ******************************/ + void checkOnBusy() { + if(macState == CCA) { + computeBackoff(); + macState = RX; + requestAdc(); + sdDebug(150); + + if(!call Timer.isRunning()) call Timer.start(TX_GAP_TIME >> 1); + } else if(macState == RX) { + if(!call Timer.isRunning()) call Timer.start(TX_GAP_TIME + backoff(0)); + } + } + + void checkOnIdle() { + if(macState == RX) { + checkSend(); + } + else if(macState == CCA) { + checkCounter++; + if(checkCounter < 3) { + sdDebug(158); + call Timer.start((TX_GAP_TIME + backoff(0))>>1); + requestAdc(); + } + else { + call Timer.stop(); + sdDebug(159); + macState = SW_TX; + + setTxMode(); + } + } + } async event void Timer.fired() { - if(macState == RX) { - storeOldState(90); - if(isFlagSet(&flags, CHECK_RX_LIVENESS)) { - /* if(call UartPhyControl.isBusy()) { - call Timer.start(CHECK_RX_LIVENESS_INTERVALL); + sdDebug(100); + if(macState == CCA) { + if((!call RssiAdcResource.isOwner()) || (call ChannelMonitor.start() != SUCCESS)) { + if(call UartPhyControl.isBusy()) { + sdDebug(101); + checkOnBusy(); } else { - */ - call ChannelMonitor.start(); - /*} */ + sdDebug(102); + checkOnIdle(); + } } else { - checkSend(); + setFlag(&flags, CCA_PENDING); } } else if(macState == RX_ACK) { - storeOldState(91); - updateRetryCounters(); - macState = RX; - signalMacState(); - call Timer.start(backoff()); + if(needsAckTx(txBufPtr)) { + sdDebug(103); + updateLongRetryCounters(); + macState = RX; + call Timer.start(backoff(longRetryCounter)); + } + else { + sdDebug(104); + } } - else if(macState == CCA) { - storeOldState(92); - setFlag(&flags, DIFS_TIMER_FIRED); - call ChannelMonitor.start(); + else if(macState == CCA_ACK) { + sdDebug(160); + macState = SW_TX_ACK; + + setTxMode(); + } + else if((macState == RX_ACK_P) || (macState == RX_P)) { + sdDebug(108); + } + else if(macState == INIT) { + sdDebug(109); + post StartDoneTask(); } else { - storeOldState(93); - signalFailure(10); + sdDebug(110); + checkSend(); } } /****** ChannelMonitor events *********************/ async event void ChannelMonitor.channelBusy() { - atomic { - if(macState == CCA) { - storeOldState(100); - macState = RX; - signalMacState(); - setFlag(&flags, BUSY_DETECTED_VIA_RSSI); - updateRetryCounters(); - call Timer.start(backoff()); - } - else if(macState == RX_P) { - storeOldState(101); - setFlag(&flags, BUSY_DETECTED_VIA_RSSI); - } - else if((macState == RX) && (isFlagSet(&flags, CHECK_RX_LIVENESS))) { - storeOldState(102); - call Timer.start(CHECK_RX_LIVENESS_INTERVALL); - } - } + clearFlag(&flags, CCA_PENDING); + sdDebug(120); + checkOnBusy(); } async event void ChannelMonitor.channelIdle() { - storeOldState(110); - if((macState == RX) && (isFlagSet(&flags, CHECK_RX_LIVENESS))) { - storeOldState(111); - clearFlag(&flags, CHECK_RX_LIVENESS); - call Timer.start(backoff()); - } - else if(macState == CCA) { - if(isFlagSet(&flags, DIFS_TIMER_FIRED)) { - clearFlag(&flags, DIFS_TIMER_FIRED); - storeOldState(112); - macState = SW_TX; - signalMacState(); - setTxMode(); - } - } + clearFlag(&flags, CCA_PENDING); + sdDebug(121); + checkOnIdle(); } @@ -633,28 +824,82 @@ implementation event void ChannelMonitorControl.updateNoiseFloorDone() { if(macState == INIT) { - storeOldState(120); - macState = RX; - signalMacState(); + sdDebug(122); post StartDoneTask(); } else { - storeOldState(121); - signalFailure(11); + sdDebug(124); } } /***** ChannelMonitorData events ******************/ async event void ChannelMonitorData.getSnrDone(int16_t data) { - atomic if(macState == RX_P) rssiValue = data; + atomic if((macState == RX_P) || (macState == RX_ACK_P)) rssiValue = data; + post ReleaseAdcTask(); } - /***** unused Radio Modes events **************************/ async event void RadioModes.TimerModeDone() {} - async event void RadioModes.SleepModeDone() {} + + async event void RadioModes.SleepModeDone() { + atomic setRxMode(); + } + async event void RadioModes.SelfPollingModeDone() {} async event void RadioModes.PWDDDInterrupt() {} + + event void ReRxTimer.fired() { + atomic { + if((macState == RX) && (call RadioModes.SleepMode() == SUCCESS)) { + // ok + } + else { + post postponeReRx(); + } + } + } + + /***** abused TimeStamping events **************************/ + async event void RadioTimeStamping.receivedSFD( uint16_t time ) { + if(call RssiAdcResource.isOwner()) call ChannelMonitorData.getSnr(); + if(macState == RX_P) { + rxTime = call LocalTime32kHz.get(); + call ChannelMonitor.rxSuccess(); + } + } + + async event void RadioTimeStamping.transmittedSFD( uint16_t time, message_t* p_msg ) { + if((macState == TX) && (p_msg == txBufPtr)) { + // to do + } + } + + /***** Rssi Resource events ******************/ + event void RssiAdcResource.granted() { + macState_t ms; + atomic ms = macState; + if((ms == INIT) && isFlagSet(&flags, RSSI_STABLE)) { + sdDebug(145); + call ChannelMonitorControl.updateNoiseFloor(); + } + else { + sdDebug(146); + call RssiAdcResource.release(); + } + } + + /***** RadioData Resource events **************/ + async event void RadioResourceRequested.requested() { + atomic { + /* This gives other devices the chance to get the Resource + because RxMode implies a new arbitration round. */ + if (macState == RX) setRxMode(); + } + } + + // we don't care about urgent Resource requestes + async event void RadioResourceRequested.immediateRequested() {} } +