*/
+
#include "radiopacketfunctions.h"
#include "flagfunctions.h"
+#include "PacketAck.h"
/**
* An implementation of a Csma Mac.
* @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<TMilli> as ReRxTimer;
+ interface Duplicate;
+ interface TimeDiff16;
interface Alarm<T32khz, uint16_t> 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<T32khz> 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,
/* 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() {
}
/**************** 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() {
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);
}
call CcaStdControl.start();
atomic {
macState = INIT;
- signalMacState();
+
setRxMode();
- storeOldState(1);
+ sdDebug(1);
}
return SUCCESS;
}
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);
}
}
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);
}
}
}
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;
}
}
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;
/****** 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();
}
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() {}
}
+