#include "PacketAck.h"
#include "RedMac.h"
-// #define MACM_DEBUG // debug...
+#ifdef DELTATIMEDEBUG
+#include "DeltaTrace.h"
+#endif
+
module RedMacP {
provides {
interface Init;
interface MacSend;
interface MacReceive;
interface Packet;
- interface LocalTime<T32khz> as LocalTime32khz;
- interface SleepTime;
+ interface Sleeptime;
interface Teamgeist;
interface ChannelCongestion;
+#ifdef MAC_EVAL
+ interface MacEval;
+#endif
}
uses {
interface StdControl as CcaStdControl;
interface Alarm<T32khz, uint16_t> as Timer;
interface Alarm<T32khz, uint16_t> as SampleTimer;
- interface Counter<T32khz,uint16_t> as Counter32khz16;
+ interface LocalTime<T32khz> as LocalTime32kHz;
+
+ interface Duplicate;
+ interface TimeDiff16;
+ interface TimeDiff32;
+
async command am_addr_t amAddress();
-#ifdef MACM_DEBUG
+/*
interface GeneralIO as Led0;
interface GeneralIO as Led1;
interface GeneralIO as Led2;
- interface GeneralIO as Led3;
+ interface GeneralIO as Led3;
+*/
+#ifdef REDMAC_DEBUG
+ interface SerialDebug;
+#endif
+#ifdef REDMAC_PERFORMANCE
+ interface Performance;
+#endif
+#ifdef DELTATIMEDEBUG
+ interface DeltaTrace;
#endif
}
}
macState_t macState;
/****** debug vars & defs & functions ***********************/
-#ifdef MACM_DEBUG
-#define HISTORY_ENTRIES 60
- 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;
- }
+#ifdef REDMAC_DEBUG
+ void sdDebug(uint16_t p) {
+ call SerialDebug.putPlace(p);
}
+ uint8_t repCounter;
#else
- void storeOldState(int p) {};
-#endif
-
- void signalFailure(uint8_t place) {
-#ifdef MACM_DEBUG
- unsigned long i,j;
- atomic {
- for(;;) {
- call Led0.clr();
- call Led1.clr();
- call Led2.clr();
- call Led3.clr();
-
- for(i = 0; i < 100; i++) {
- for(j=0; j < 200; j++) {
- (i & 1) ? call Led0.set() : call Led0.clr();
- }
- for(j=0; j < 200; j++) {
- (i & 2) ? call Led1.set() : call Led1.clr();
- }
- for(j=0; j < 200; j++) {
- (i & 4) ? call Led2.set() : call Led2.clr();
- }
- for(j=0; j < 200; j++) {
- (i & 8) ? call Led3.set() : call Led3.clr();
- }
- }
-
- (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();
-
- for(i = 0; i < 1000000; i++) {
- ;
- }
- }
- }
+ void sdDebug(uint16_t p) {};
#endif
- }
-
- 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();
-*/
+
+#ifdef REDMAC_PERFORMANCE
+ PfmTxMsg_t txStat;
+ PfmRxMsg_t rxStat;
#endif
- }
-
/**************** Module Global Constants *****************/
enum {
- BYTE_TIME=13, // byte at 38400 kBit/s, 4b6b encoded
- PREAMBLE_BYTE_TIME=9, // byte at 38400 kBit/s, no coding
- PHY_HEADER_TIME=51, // 6 Phy Preamble at 38400
- SUB_HEADER_TIME=PHY_HEADER_TIME + sizeof(tda5250_header_t)*BYTE_TIME,
- SUB_FOOTER_TIME=2*BYTE_TIME, // 2 bytes crc 38400 kBit/s with 4b6b encoding
- MAX_TIME_VALUE=0xFFFFFFFF,
- MAXTIMERVALUE=0xFFFF, // helps to compute backoff
- DEFAULT_SLEEP_TIME=3250,
- // DEFAULT_SLEEP_TIME=6500,
- // DEFAULT_SLEEP_TIME=9750,
+
+ 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(message_header_t)*BYTE_TIME,
+ SUB_FOOTER_TIME=2*BYTE_TIME, // 2 bytes crc
+ // DEFAULT_SLEEP_TIME=1625,
+#ifndef DEFAULT_SLEEP_TIME
+ DEFAULT_SLEEP_TIME=2048,
+ // DEFAULT_SLEEP_TIME=4096,
+ // DEFAULT_SLEEP_TIME=8192,
+ // DEFAULT_SLEEP_TIME=16384,
+ // DEFAULT_SLEEP_TIME=32768U,
+ // DEFAULT_SLEEP_TIME=65535U,
+#endif
DATA_DETECT_TIME=17,
- RX_SETUP_TIME=111, // time to set up receiver
- TX_SETUP_TIME=69, // time to set up transmitter
- ADDED_DELAY = 40,
- RX_ACK_TIMEOUT = RX_SETUP_TIME + PHY_HEADER_TIME + 29 + 2*ADDED_DELAY,
- TX_GAP_TIME=RX_ACK_TIMEOUT + TX_SETUP_TIME + 11,
+ 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 + ADDED_DELAY + 30,
+ TX_GAP_TIME = RX_ACK_TIMEOUT + TX_SETUP_TIME + 33,
// the duration of a send ACK
ACK_DURATION = SUB_HEADER_TIME + SUB_FOOTER_TIME,
- MAX_SHORT_RETRY=7,
- MAX_LONG_RETRY=2,
- MAX_AGE=2*MAX_LONG_RETRY*MAX_SHORT_RETRY,
- MSG_TABLE_ENTRIES=20,
+ NAV_FACTOR = 4,
+#ifndef MAC_EVAL
+ MAX_SHORT_RETRY=9,
+ MAX_LONG_RETRY=3,
+ ADD_NAV = 2,
+ INCREASE_BACKOFF = TRUE,
+#endif
TOKEN_ACK_FLAG = 64,
TOKEN_ACK_MASK = 0x3f,
- /* correct the difference between the transmittedSFD and the receivedSFD
- that appears due to buffering, measured value on an osci is 320us, so this
- value is actually 10.48576
- */
- TIME_CORRECTION = 10,
INVALID_SNR = 0xffff,
- PREAMBLE_LONG = 6,
- PREAMBLE_SHORT = 2,
+ // PREAMBLE_LONG = 5,
+ // PREAMBLE_SHORT = 2,
+ // reduced minimal backoff
+ ZERO_BACKOFF_MASK = 0xff
};
-
+#ifdef MAC_EVAL
+ uint8_t MAX_SHORT_RETRY = 9;
+ uint8_t MAX_LONG_RETRY = 3;
+ uint8_t ADD_NAV = 4;
+ bool INCREASE_BACKOFF = TRUE;
+#endif
+#ifdef DELTATIMEDEBUG
+ DeltaTrace_t dTrace;
+#endif
/**************** Module Global Variables *****************/
- typedef union
- {
- uint32_t op;
- struct {
- uint16_t lo;
- uint16_t hi;
- };
- } ui32parts_t;
-
/* flags */
typedef enum {
SWITCHING = 1,
TEAMGEIST_ACTIVE=128
} flags_t;
- /* duplicate suppression */
- typedef struct knownMessage_t {
- am_addr_t src;
- uint8_t token;
- uint8_t age;
- } knownMessage_t;
-
- knownMessage_t knownMsgTable[MSG_TABLE_ENTRIES];
- uint8_t flags;
- uint8_t checkCounter;
- uint8_t shortRetryCounter;
- uint8_t longRetryCounter;
- uint16_t sleepTime;
- uint16_t rssiValue;
- uint32_t restLaufzeit;
+ uint8_t flags = 0;
+ uint8_t checkCounter = 0;
+ uint8_t shortRetryCounter = 0;
+ uint8_t longRetryCounter = 0;
+ uint16_t networkSleeptime = DEFAULT_SLEEP_TIME;
+ uint16_t localSleeptime = DEFAULT_SLEEP_TIME;
+ uint16_t rssiValue = 0;
+ uint32_t restLaufzeit = 0;
- message_t *txBufPtr;
- uint16_t txLen;
- red_mac_header_t *txMacHdr;
+ uint32_t rxTime = 0;
+
+ am_id_t teamgeistType = 0;
+ uint8_t congestionLevel = 0;
+
+ message_t *txBufPtr = NULL;
+ uint16_t txLen = 0;
+ red_mac_header_t *txMacHdr = NULL;
uint16_t seqNo;
message_t ackMsg;
- uint16_t counter2sec;
- uint32_t rxTime;
-
- am_id_t teamgeistType;
-
- uint8_t congestionLevel;
uint16_t MIN_BACKOFF_MASK;
-
+
/****** Secure switching of radio modes ***/
void interruptBackoffTimer();
void setRxMode() {
setFlag(&flags, SWITCHING);
clearFlag(&flags, RSSI_STABLE);
- storeOldState(0);
+ // sdDebug(10);
checkCounter = 0;
rssiValue = INVALID_SNR;
if(call RadioModes.RxMode() == FAIL) {
post SetRxModeTask();
}
+ else {
+#ifdef REDMAC_PERFORMANCE
+ call Performance.macRxMode();
+#endif
+ }
requestAdc();
}
}
void setSleepMode() {
- storeOldState(161);
+ // sdDebug(20);
clearFlag(&flags, RSSI_STABLE);
post ReleaseAdcTask();
setFlag(&flags, SWITCHING);
if(call RadioModes.SleepMode() == FAIL) {
post SetSleepModeTask();
}
+ else {
+#ifdef REDMAC_PERFORMANCE
+ call Performance.macSleepMode();
+#endif
+ }
}
task void SetSleepModeTask() {
void setTxMode() {
post ReleaseAdcTask();
- storeOldState(2);
+ // sdDebug(30);
clearFlag(&flags, RSSI_STABLE);
setFlag(&flags, SWITCHING);
if(call RadioModes.TxMode() == FAIL) {
post SetTxModeTask();
}
+ else {
+#ifdef REDMAC_PERFORMANCE
+ call Performance.macTxMode();
+#endif
+ }
}
task void SetTxModeTask() {
}
}
- /**************** Helper functions ************************/
+ /**************** Helper functions ************************/
+ void computeBackoff();
+
void checkSend() {
- storeOldState(10);
if((shortRetryCounter) && (txBufPtr != NULL) && (isFlagSet(&flags, MESSAGE_PREPARED)) &&
(macState == SLEEP) && (!isFlagSet(&flags, RESUME_BACKOFF)) && (!call Timer.isRunning())) {
- storeOldState(11);
+ // sdDebug(40);
macState = CCA;
checkCounter = 0;
setRxMode();
}
+/* else {
+ if(txBufPtr) // sdDebug(41);
+ if(shortRetryCounter) // sdDebug(42);
+ if(isFlagSet(&flags, MESSAGE_PREPARED)) // sdDebug(43);
+ if(txBufPtr) {
+ if(macState == SLEEP) // sdDebug(44);
+ if(!isFlagSet(&flags, RESUME_BACKOFF)) // sdDebug(45);
+ if(!call Timer.isRunning()) // sdDebug(46);
+ }
+ }
+*/
}
uint32_t backoff(uint8_t counter) {
uint32_t rVal = call Random.rand16() & MIN_BACKOFF_MASK;
- return rVal << counter;
+ if(!INCREASE_BACKOFF) counter = 1;
+ return (rVal << counter) + ZERO_BACKOFF_MASK;
}
bool needsAckTx(message_t* msg) {
if(isFlagSet(&flags, TEAMGEIST_ACTIVE) &&
(getHeader(msg)->type == teamgeistType)) {
if(rssiValue != INVALID_SNR) snr = rssiValue;
+ *level = 2;
rVal = signal Teamgeist.needsAck(msg, getHeader(msg)->src, getHeader(msg)->dest, snr);
- *level = 1;
}
}
}
atomic {
msg = txBufPtr;
length = txLen;
- sT = sleepTime;
+ sT = networkSleeptime;
}
if(msg == NULL) return;
- macHdr = (red_mac_header_t *)call SubPacket.getPayload(msg, NULL);
+ macHdr = (red_mac_header_t *)call SubPacket.getPayload(msg, sizeof(red_mac_header_t));
macHdr->repetitionCounter = sT/(length * BYTE_TIME + SUB_HEADER_TIME + SUB_FOOTER_TIME +
TX_GAP_TIME) + 1;
atomic {
txMacHdr = macHdr;
setFlag(&flags, MESSAGE_PREPARED);
if((macState == SLEEP) && (!call Timer.isRunning()) && (!isFlagSet(&flags, RESUME_BACKOFF))) {
- call Timer.start(backoff(longRetryCounter));
+ if((longRetryCounter == 1) &&
+ (getHeader(msg)->dest != AM_BROADCAST_ADDR)) {
+ call Timer.start((call Random.rand16() >> 3) & ZERO_BACKOFF_MASK);
+ }
+ else {
+ sdDebug(332);
+ sdDebug(macHdr->repetitionCounter);
+ call Timer.start(backoff(longRetryCounter));
+ }
+ }
+#ifdef REDMAC_PERFORMANCE
+ txStat.type = getHeader(msg)->type;
+ txStat.to = getHeader(msg)->dest;
+ txStat.token = getHeader(msg)->token;
+ txStat.maxRepCounter = macHdr->repetitionCounter;
+ txStat.creationTime = getMetadata(msg)->time;
+#endif
+ getMetadata(msg)->maxRepetitions = macHdr->repetitionCounter;
+ }
+ }
+
+ 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;
}
}
}
bool prepareRepetition() {
bool repeat;
atomic {
- if(isFlagSet(&flags, CANCEL_SEND)) txMacHdr->repetitionCounter = 0;
- repeat = (txMacHdr->repetitionCounter >= 1);
- txMacHdr->repetitionCounter--;
+ if(isFlagSet(&flags, CANCEL_SEND)) {
+ repeat = txMacHdr->repetitionCounter = 0;
+ }
+ else {
+ repeat = txMacHdr->repetitionCounter;
+ txMacHdr->repetitionCounter--;
+ }
}
return repeat;
}
-
+
void signalSendDone(error_t error) {
message_t *m;
error_t e = error;
- storeOldState(12);
+ // sdDebug(50);
atomic {
m = txBufPtr;
txBufPtr = NULL;
txLen = 0;
+#ifdef REDMAC_PERFORMANCE
+ txStat.repCounter = txMacHdr->repetitionCounter;
+ txStat.longRetry = longRetryCounter;
+ txStat.shortRetry = shortRetryCounter;
+#endif
longRetryCounter = 0;
shortRetryCounter = 0;
- if(rssiValue != INVALID_SNR) {
- (getMetadata(m))->strength = rssiValue;
- }
- else {
- (getMetadata(m))->strength = call ChannelMonitorData.readSnr();
- }
+ storeStrength(m);
if(isFlagSet(&flags, CANCEL_SEND)) {
e = ECANCEL;
}
+ clearFlag(&flags, MESSAGE_PREPARED);
clearFlag(&flags, CANCEL_SEND);
}
+ // sdDebug(3000 + e);
+ // sdDebug(4000 + getHeader(m)->type);
signal MacSend.sendDone(m, e);
+#ifdef REDMAC_PERFORMANCE
+ txStat.success = e;
+ txStat.strength = getMetadata(m)->strength;
+ call Performance.macTxMsgStats(&txStat);
+#endif
}
void updateRetryCounters() {
longRetryCounter++;
shortRetryCounter = 1;
if(longRetryCounter > MAX_LONG_RETRY) {
- storeOldState(13);
+ // sdDebug(60);
signalSendDone(FAIL);
}
}
longRetryCounter++;
shortRetryCounter = 1;
if(longRetryCounter > MAX_LONG_RETRY) {
- storeOldState(13);
+ // sdDebug(70);
signalSendDone(FAIL);
} else {
post PrepareMsgTask();
}
void interruptBackoffTimer() {
- uint16_t now;
if(call Timer.isRunning()) {
- restLaufzeit = call Timer.getAlarm();
+ restLaufzeit = call TimeDiff16.computeDelta(call Timer.getAlarm(), call Timer.getNow());
call Timer.stop();
- now = call Timer.getNow();
- if(restLaufzeit >= now) {
- restLaufzeit = restLaufzeit - now;
- }
- else {
- restLaufzeit += MAXTIMERVALUE - now;
- }
if(restLaufzeit > MIN_BACKOFF_MASK << MAX_LONG_RETRY) {
- restLaufzeit = backoff(0);
+ restLaufzeit = call Random.rand16() & ZERO_BACKOFF_MASK;
}
setFlag(&flags, RESUME_BACKOFF);
}
setFlag(&flags, RESUME_BACKOFF);
restLaufzeit = backoff(longRetryCounter);
updateRetryCounters();
- storeOldState(92);
}
}
}
bool isNewMsg(message_t* msg) {
- bool rVal = TRUE;
- uint8_t i;
- for(i=0; i < MSG_TABLE_ENTRIES; i++) {
- if((getHeader(msg)->src == knownMsgTable[i].src) &&
- (((getHeader(msg)->token) & TOKEN_ACK_MASK) == knownMsgTable[i].token) &&
- (knownMsgTable[i].age < MAX_AGE)) {
- knownMsgTable[i].age = 0;
- rVal = FALSE;
- break;
- }
- }
- return rVal;
- }
-
- unsigned findOldest() {
- unsigned i;
- unsigned oldIndex = 0;
- unsigned age = knownMsgTable[oldIndex].age;
- for(i = 1; i < MSG_TABLE_ENTRIES; i++) {
- if(age < knownMsgTable[i].age) {
- oldIndex = i;
- age = knownMsgTable[i].age;
- }
- }
- return oldIndex;
- }
+ return call Duplicate.isNew(getHeader(msg)->src,
+ getHeader(msg)->dest,
+ (getHeader(msg)->token) & TOKEN_ACK_MASK);
+ }
void rememberMsg(message_t* msg) {
- unsigned oldest = findOldest();
- knownMsgTable[oldest].src = getHeader(msg)->src;
- knownMsgTable[oldest].token = (getHeader(msg)->token) & TOKEN_ACK_MASK;
- knownMsgTable[oldest].age = 0;
+ call Duplicate.remember(getHeader(msg)->src, getHeader(msg)->dest,
+ (getHeader(msg)->token) & TOKEN_ACK_MASK);
}
void prepareAck(message_t* msg) {
getHeader(&ackMsg)->src = call amAddress();
getHeader(&ackMsg)->dest = getHeader(msg)->src;
getHeader(&ackMsg)->type = getHeader(msg)->type;
+#ifdef REDMAC_DEBUG
+ repCounter = ((red_mac_header_t *)
+ call SubPacket.getPayload(msg, sizeof(red_mac_header_t)))->repetitionCounter;
+#endif
}
uint32_t calcGeneratedTime(red_mac_header_t *m) {
- return rxTime - m->time - TIME_CORRECTION;
+ uint32_t lt = rxTime - m->time - TIME_CORRECTION;
+#ifdef DELTATIMEDEBUG
+ dTrace.now = rxTime;
+ dTrace.msgTime = lt;
+ dTrace.delta = m->time;
+ call DeltaTrace.traceRx(&dTrace);
+#endif
+ return lt;
}
-
+
/**************** Init ************************/
command error_t Init.init(){
- uint8_t i;
atomic {
macState = INIT;
- flags = 0;
- checkCounter = 0;
- rssiValue = 0;
- restLaufzeit = 0;
seqNo = call Random.rand16() % TOKEN_ACK_FLAG;
- txBufPtr = NULL;
- txLen = 0;
- txMacHdr = NULL;
- sleepTime = DEFAULT_SLEEP_TIME;
- for(i = 0; i < MSG_TABLE_ENTRIES; i++) {
- knownMsgTable[i].age = MAX_AGE;
- }
- for(MIN_BACKOFF_MASK = 1; MIN_BACKOFF_MASK < sleepTime; ) {
+ for(MIN_BACKOFF_MASK = 1; MIN_BACKOFF_MASK < networkSleeptime; ) {
MIN_BACKOFF_MASK = (MIN_BACKOFF_MASK << 1) + 1;
}
MIN_BACKOFF_MASK >>= 2;
- storeOldState(20);
- shortRetryCounter = 0;
- longRetryCounter = 0;
- counter2sec = 127;
- rxTime = 0;
- teamgeistType = 0;
}
+#ifdef REDMAC_DEBUG
+ call SerialDebug.putShortDesc("RedMacP");
+#endif
return SUCCESS;
}
/**************** SplitControl *****************/
task void StartDoneTask() {
- storeOldState(14);
+ // sdDebug(90);
atomic {
- call SampleTimer.start(sleepTime);
+ call SampleTimer.start(localSleeptime);
macState = SLEEP;
setFlag(&flags, TEAMGEIST_ACTIVE);
teamgeistType = signal Teamgeist.observedAMType();
call CcaStdControl.start();
atomic {
macState = INIT;
- // signalMacState();
setRxMode();
- storeOldState(15);
+ // sdDebug(100);
}
return SUCCESS;
}
task void StopDoneTask() {
call Init.init();
- storeOldState(16);
+ // sdDebug(110);
signal SplitControl.stopDone(SUCCESS);
}
atomic {
if((macState == SLEEP) && isFlagSet(&flags, SWITCHING)) {
macState = STOP;
- storeOldState(17);
+ // sdDebug(120);
}
else {
macState = STOP;
setSleepMode();
- storeOldState(18);
+ // sdDebug(121);
}
}
return SUCCESS;
return call SubPacket.maxPayloadLength() - sizeof(red_mac_header_t);
}
- command void* Packet.getPayload(message_t* msg, uint8_t* len) {
- nx_uint8_t *payload = (nx_uint8_t *)call SubPacket.getPayload(msg, len);
- if (len != NULL) {
- *len -= sizeof(red_mac_header_t);
- }
+ command void* Packet.getPayload(message_t* msg, uint8_t len) {
+ nx_uint8_t *payload = (nx_uint8_t *)call SubPacket.getPayload(msg, len + sizeof(red_mac_header_t));
return (void*)(payload + sizeof(red_mac_header_t));
}
/****** Radio(Mode) events *************************/
async event void RadioModes.RssiStable() {
- if(isFlagSet(&flags, RSSI_STABLE)) signalFailure(0);
setFlag(&flags, RSSI_STABLE);
if((macState == RX) || (macState == CCA)) {
call Timer.start(DATA_DETECT_TIME);
- storeOldState(30);
+ // sdDebug(130);
}
else if(macState == RX_P) {
- storeOldState(31);
+ // sdDebug(131);
if(call RssiAdcResource.isOwner()) call ChannelMonitorData.getSnr();
}
else if(macState == RX_ACK) {
- // if(call RssiAdcResource.isOwner()) call ChannelMonitor.start();
- storeOldState(32);
}
else if(macState == RX_ACK_P) {
}
else if(macState == INIT) {
- storeOldState(33);
+ // sdDebug(133);
if(call RssiAdcResource.isOwner()) {
call ChannelMonitorControl.updateNoiseFloor();
} else {
}
}
else if(macState == STOP) {
- storeOldState(34);
+ // sdDebug(134);
}
else {
- storeOldState(35);
- signalFailure(1);
+ // sdDebug(135);
}
}
async event void RadioModes.RxModeDone() {
- storeOldState(40);
- if(!isFlagSet(&flags, SWITCHING)) signalFailure(2);
atomic {
clearFlag(&flags, SWITCHING);
if((macState == RX) || (macState == RX_ACK) || (macState == CCA) ||
(macState == INIT) || (macState == STOP)) {
- storeOldState(41);
+ // sdDebug(140);
if(macState != RX_ACK) requestAdc();
}
else {
- storeOldState(42);
- signalFailure(3);
+ // sdDebug(141);
}
}
}
async event void RadioModes.TxModeDone() {
- storeOldState(50);
- if(!isFlagSet(&flags, SWITCHING)) signalFailure(4);
+ // sdDebug(150);
atomic {
clearFlag(&flags, SWITCHING);
if(macState == TX) {
- call UartPhyControl.setNumPreambles(PREAMBLE_SHORT);
setFlag(&flags, ACTION_DETECTED);
- if(txBufPtr == NULL) signalFailure(5);
if(call PacketSend.send(txBufPtr, txLen) == SUCCESS) {
- storeOldState(51);
- } else {
- storeOldState(52);
- signalFailure(6);
+ // sdDebug(151);
+ }
+ else {
+ // sdDebug(152);
}
}
else if(macState == TX_ACK) {
if(call PacketSend.send(&ackMsg, 0) == SUCCESS) {
- storeOldState(53);
+ // sdDebug(153);
} else {
- storeOldState(54);
- signalFailure(6);
+ // sdDebug(154);
}
}
else {
- storeOldState(55);
- signalFailure(7);
+ // sdDebug(155);
}
}
}
async event void RadioModes.SleepModeDone() {
- storeOldState(60);
- if(!isFlagSet(&flags, SWITCHING)) signalFailure(8);
+ // sdDebug(160);
atomic {
clearFlag(&flags, SWITCHING);
if(isFlagSet(&flags, ACTION_DETECTED)) {
} else {
if(congestionLevel > 0) congestionLevel--;
}
- if((macState == SLEEP) && (!call Timer.isRunning())) {
- if(isFlagSet(&flags, RESUME_BACKOFF)) {
- storeOldState(61);
- clearFlag(&flags, RESUME_BACKOFF);
- call Timer.start(restLaufzeit);
- restLaufzeit = 0;
- }
- else {
- storeOldState(62);
- checkSend();
+ // if(congestionLevel > 3) // sdDebug(2000 + congestionLevel);
+ if(macState == SLEEP) {
+ // sdDebug(161);
+ if(!call Timer.isRunning()) {
+ // sdDebug(162);
+ if(isFlagSet(&flags, RESUME_BACKOFF)) {
+ // sdDebug(164);
+ clearFlag(&flags, RESUME_BACKOFF);
+ call Timer.start(restLaufzeit);
+ restLaufzeit = 0;
+ }
+ else {
+ // sdDebug(165);
+ checkSend();
+ }
}
}
- else if(macState == INIT) {
- storeOldState(63);
- post StartDoneTask();
- }
else if(macState == STOP) {
- storeOldState(64);
+ // sdDebug(168);
post StopDoneTask();
}
signal ChannelCongestion.congestionEvent(congestionLevel);
atomic {
if((shortRetryCounter == 0) && (txBufPtr == NULL)) {
clearFlag(&flags, MESSAGE_PREPARED);
- storeOldState(65);
+ // sdDebug(5000 + getHeader(msg)->type);
shortRetryCounter = 1;
longRetryCounter = 1;
txBufPtr = msg;
txLen = len + sizeof(red_mac_header_t);
seqNo++;
if(seqNo >= TOKEN_ACK_FLAG) seqNo = 1;
+#ifdef REDMAC_PERFORMANCE
+ txStat.payloadLength = txLen;
+ txStat.interfaceTime = call LocalTime32kHz.get();
+#endif
}
else {
- storeOldState(66);
+ // sdDebug(171);
err = EBUSY;
}
}
error_t err = FAIL;
atomic {
if(msg == txBufPtr) {
+ // sdDebug(320);
setFlag(&flags, CANCEL_SEND);
shortRetryCounter = MAX_SHORT_RETRY + 2;
longRetryCounter = MAX_LONG_RETRY + 2;
- if(macState == SLEEP) signalSendDone(ECANCEL);
+ if(macState == SLEEP) {
+ // sdDebug(321);
+ signalSendDone(ECANCEL);
+ }
+ else {
+ // sdDebug(322);
+ }
+ // sdDebug(1000 + macState);
err = SUCCESS;
}
+ else {
+ // sdDebug(323);
+ // sdDebug(1100 + macState);
+ }
}
return err;
}
async event void PacketReceive.receiveDetected() {
rssiValue = INVALID_SNR;
setFlag(&flags, ACTION_DETECTED);
+ call ChannelMonitor.rxSuccess();
if(macState <= CCA_ACK) {
- if(macState == CCA) computeBackoff();
+ if(macState == CCA) {
+ computeBackoff();
+#ifdef REDMAC_PERFORMANCE
+ call Performance.macDetectedOnCca();
+#endif
+ }
if(macState != RX_ACK) {
macState = RX_P;
} else {
}
}
else if(macState == INIT) {
- storeOldState(72);
- if(isFlagSet(&flags, UNHANDLED_PACKET)) signalFailure(9);
+ // sdDebug(180);
setFlag(&flags, UNHANDLED_PACKET);
}
}
uint32_t nav = 0;
uint8_t level = 0;
bool isCnt;
-
- storeOldState(80);
+#ifdef REDMAC_PERFORMANCE
+ rxStat.duplicate = PERF_UNKNOWN;
+ rxStat.repCounter = 0xff;
+#endif
+ // sdDebug(190);
if(macState == RX_P) {
- storeOldState(81);
+ // sdDebug(191);
if(error == SUCCESS) {
- storeOldState(82);
+ // sdDebug(192);
isCnt = isControl(msg);
if(msgIsForMe(msg)) {
if(!isCnt) {
- storeOldState(83);
+ // sdDebug(193);
if(isNewMsg(msg)) {
- storeOldState(84);
- if(rssiValue != INVALID_SNR) {
- (getMetadata(m))->strength = rssiValue;
- }
- else {
- if(call RssiAdcResource.isOwner()) {
- (getMetadata(m))->strength = call ChannelMonitorData.readSnr();
- }
- else {
- (getMetadata(m))->strength = 1;
- }
- }
- (getMetadata(msg))->time = calcGeneratedTime((red_mac_header_t*) payload);
+#ifdef REDMAC_PERFORMANCE
+ rxStat.duplicate = PERF_NEW_MSG;
+#endif
+ // sdDebug(194);
+ storeStrength(msg);
+#ifdef DELTATIMEDEBUG
+ dTrace.sender = getHeader(msg)->src;
+#endif
+ getMetadata(msg)->sfdtime = rxTime;
+ getMetadata(msg)->time = calcGeneratedTime((red_mac_header_t*) payload);
+ getMetadata(msg)->ack = WAS_NOT_ACKED;
m = signal MacReceive.receiveDone(msg);
// assume a buffer swap -- if buffer is not swapped, assume that the
// message was not successfully delivered to upper layers
if(m != msg) {
- storeOldState(85);
+ // sdDebug(195);
rememberMsg(msg);
} else {
- storeOldState(86);
+ // sdDebug(196);
action = RX;
+#ifdef REDMAC_PERFORMANCE
+ call Performance.macQueueFull();
+#endif
}
}
+ else {
+#ifdef REDMAC_PERFORMANCE
+ rxStat.duplicate = PERF_REPEATED_MSG;
+#endif
+ }
if(needsAckRx(msg, &level) && (action != RX)) {
- storeOldState(87);
action = CCA_ACK;
+ if(level == 2) {
+ getMetadata(msg)->ack = WAS_ACKED;
+ }
}
else {
- storeOldState(88);
+ // sdDebug(198);
if(action != RX) {
nav = ((red_mac_header_t*)payload)->repetitionCounter *
(SUB_HEADER_TIME + getHeader(msg)->length*BYTE_TIME +
}
}
else {
- storeOldState(89);
+ // sdDebug(199);
action = RX;
}
}
else {
- storeOldState(90);
+ // sdDebug(200);
action = SLEEP;
if(!isCnt) {
nav = ((red_mac_header_t*)payload)->repetitionCounter *
}
}
else {
- storeOldState(91);
- action = RX;
+ // sdDebug(201);
+ action = SLEEP;
}
}
else if(macState == RX_ACK_P) {
if(error == SUCCESS) {
if(ackIsForMe(msg)) {
- storeOldState(92);
- if(rssiValue != INVALID_SNR) {
- (getMetadata(txBufPtr))->strength = rssiValue;
- }
- else {
- if(call RssiAdcResource.isOwner()) {
- (getMetadata(txBufPtr))->strength = call ChannelMonitorData.readSnr();
- }
- else {
- (getMetadata(txBufPtr))->strength = 1;
- }
- }
- (getMetadata(txBufPtr))->ack = WAS_ACKED;
- if(isFlagSet(&flags, TEAMGEIST_ACTIVE) && (getHeader(txBufPtr)->type == teamgeistType)) {
+ // sdDebug(202);
+ getMetadata(txBufPtr)->ack = WAS_ACKED;
+ getMetadata(txBufPtr)->repetitions = txMacHdr->repetitionCounter;
+ if(isFlagSet(&flags, TEAMGEIST_ACTIVE) &&
+ (getHeader(txBufPtr)->type == teamgeistType))
+ {
signal Teamgeist.gotAck(txBufPtr, getHeader(msg)->src,
getMetadata(txBufPtr)->strength);
}
+ // sdDebug(203);
signalSendDone(SUCCESS);
+ // sdDebug(30000 + getHeader(msg)->src);
action = SLEEP;
}
else {
- updateLongRetryCounters();
- action = RX;
+ // sdDebug(203);
+ updateLongRetryCounters(); // this will eventually schedule the right backoff
+ macState = SLEEP; // so much traffic is going on -- take a nap
+ setSleepMode();
+ action = INIT; // a difficult way to say: do nothing
}
}
else {
if(call Timer.isRunning()) {
- storeOldState(94);
+ // sdDebug(204);
action = RX_ACK;
}
else {
+ // sdDebug(205);
updateLongRetryCounters();
action = RX;
}
}
}
else {
- storeOldState(96);
+ // sdDebug(206);
action = INIT;
}
if(action == CCA_ACK) {
- prepareAck(msg);
macState = CCA_ACK;
- if(call Random.rand16() & 4) {
- call Timer.start(RX_SETUP_TIME - TX_SETUP_TIME + (ADDED_DELAY>>level));
- call UartPhyControl.setNumPreambles(PREAMBLE_SHORT);
+ if(call Random.rand16() & 2) {
+ call Timer.start(RX_SETUP_TIME - TX_SETUP_TIME + 16 - level*8 + ADDED_DELAY);
}
else {
- call Timer.start(RX_SETUP_TIME - TX_SETUP_TIME);
- call UartPhyControl.setNumPreambles(PREAMBLE_LONG);
+ macState = TX_ACK;
+ call Timer.start(RX_SETUP_TIME - TX_SETUP_TIME + 16);
}
+ prepareAck(msg);
}
else if(action == RX_ACK) {
macState = RX_ACK;
}
else if(action == SLEEP) {
macState = SLEEP;
- setSleepMode();
if(isFlagSet(&flags, RESUME_BACKOFF)) {
+ nav = nav*(uint32_t)ADD_NAV/(uint32_t)NAV_FACTOR;
if(nav > restLaufzeit) restLaufzeit += nav;
}
else {
setFlag(&flags, RESUME_BACKOFF);
- restLaufzeit = nav + backoff(longRetryCounter);
+ restLaufzeit = call Random.rand16() & ZERO_BACKOFF_MASK;
}
+ setSleepMode();
}
else if(action == INIT) {
- if(!isFlagSet(&flags, UNHANDLED_PACKET)) signalFailure(11);
clearFlag(&flags, UNHANDLED_PACKET);
}
else {
- storeOldState(94);
- signalFailure(11);
+ // sdDebug(207);
+ }
+#ifdef REDMAC_PERFORMANCE
+ if(error == SUCCESS) {
+ rxStat.type = getHeader(msg)->type;
+ rxStat.from = getHeader(msg)->src;
+ rxStat.to = getHeader(msg)->dest;
+ rxStat.token = getHeader(msg)->token;
+ if(!isControl(msg)) rxStat.repCounter = ((red_mac_header_t*)payload)->repetitionCounter;
+ rxStat.payloadLength = len;
+ rxStat.strength = rssiValue;
+ rxStat.creationTime = getMetadata(msg)->time;
+ call Performance.macRxStats(&rxStat);
}
+#endif
return m;
}
async event void PacketSend.sendDone(message_t* msg, error_t error) {
if(macState == TX) {
- storeOldState(97);
- if(msg != txBufPtr) signalFailure(12);
- storeOldState(99);
macState = RX_ACK;
setRxMode();
call Timer.start(RX_ACK_TIMEOUT);
+ // sdDebug(220);
checkCounter = 0;
}
else if(macState == TX_ACK) {
checkCounter = 0;
- macState = RX;
- setRxMode();
- }
- else {
- signalFailure(13);
+ macState = SLEEP;
+ setSleepMode();
+ // macState = RX;
+ // setRxMode();
+ // sdDebug(221);
+#ifdef REDMAC_DEBUG
+ // sdDebug(40000U + repCounter);
+#endif
}
}
async event void RadioTimeStamping.receivedSFD( uint16_t time ) {
if(call RssiAdcResource.isOwner()) call ChannelMonitorData.getSnr();
if(macState == RX_P) {
- rxTime = call LocalTime32khz.get();
+ rxTime = call LocalTime32kHz.get();
call ChannelMonitor.rxSuccess();
}
}
async event void RadioTimeStamping.transmittedSFD( uint16_t time, message_t* p_msg ) {
- uint32_t now;
- uint32_t mTime;
if((macState == TX) && (p_msg == txBufPtr)) {
- now = call LocalTime32khz.get();
- mTime = getMetadata(p_msg)->time;
- if(now >= mTime) {
- txMacHdr->time = now - mTime;
- }
- else {
- // assume a clock wrap here
- txMacHdr->time = MAX_TIME_VALUE - mTime + now;
- }
- }
- }
-
- async command uint32_t LocalTime32khz.get() {
- ui32parts_t time;
- atomic {
- time.lo = call Counter32khz16.get();
- time.hi = counter2sec;
+#ifdef DELTATIMEDEBUG
+ dTrace.now = call LocalTime32kHz.get();
+ dTrace.msgTime = getMetadata(p_msg)->time;
+ dTrace.delta = call TimeDiff32.computeDelta(dTrace.now, dTrace.msgTime);
+ txMacHdr->time = dTrace.delta;
+ call DeltaTrace.traceTx(&dTrace);
+ getMetadata(p_msg)->sfdtime = dTrace.now;
+#else
+ getMetadata(p_msg)->sfdtime = call LocalTime32kHz.get();
+ txMacHdr->time =
+ call TimeDiff32.computeDelta(getMetadata(p_msg)->sfdtime,
+ getMetadata(p_msg)->time);
+#endif
}
- return time.op;
- }
-
- async event void Counter32khz16.overflow() {
- counter2sec++;
}
-
-
/****** Timer ******************************/
if((macState == RX) || (macState == CCA) || (macState == CCA_ACK)) {
if(macState == CCA) {
computeBackoff();
+#ifdef REDMAC_PERFORMANCE
+ call Performance.macBusyOnCca();
+#endif
}
requestAdc();
- storeOldState(150);
+ // sdDebug(230);
macState = RX;
checkCounter = 0;
call Timer.start(TX_GAP_TIME>>1);
if(macState == RX) {
checkCounter++;
if(checkCounter >= 3) {
- storeOldState(153);
+ // sdDebug(240);
macState = SLEEP;
setSleepMode();
}
else {
- storeOldState(154);
- call Timer.start(TX_GAP_TIME>>1);
+ // sdDebug(241);
+ call Timer.start(TX_GAP_TIME >> 1);
requestAdc();
}
}
else if(macState == CCA) {
checkCounter++;
if(checkCounter < 3) {
- storeOldState(158);
- call Timer.start((TX_GAP_TIME + backoff(0))>>1);
+ // sdDebug(242);
+ call Timer.start(TX_GAP_TIME >> 1);
requestAdc();
}
else {
- storeOldState(159);
+ // sdDebug(243);
macState = TX;
setTxMode();
+#ifdef REDMAC_PERFORMANCE
+ call Performance.macIdleOnCca();
+ txStat.txModeTime = call LocalTime32kHz.get();
+#endif
}
}
else if(macState == CCA_ACK) {
- storeOldState(160);
+ // sdDebug(244);
macState = TX_ACK;
setTxMode();
+ // sdDebug(20000 + getHeader(&ackMsg)->dest);
+#ifdef REDMAC_PERFORMANCE
+ call Performance.macTxAckStats(getHeader(&ackMsg)->type,
+ getHeader(&ackMsg)->dest,
+ getHeader(&ackMsg)->token);
+#endif
}
}
async event void Timer.fired() {
- storeOldState(100);
+ // sdDebug(250);
if((macState == RX) || (macState == CCA) || (macState == CCA_ACK)) {
- if(isFlagSet(&flags, SWITCHING)) signalFailure(14);
if((!call RssiAdcResource.isOwner()) || (call ChannelMonitor.start() != SUCCESS)) {
if(call UartPhyControl.isBusy()) {
- storeOldState(101);
+ // sdDebug(251);
checkOnBusy();
}
else {
- storeOldState(102);
+ // sdDebug(252);
checkOnIdle();
}
}
}
else if(macState == RX_ACK) {
if(prepareRepetition()) {
- storeOldState(156);
+ // sdDebug(253);
macState = TX;
setTxMode();
}
else {
if(needsAckTx(txBufPtr)) {
- storeOldState(157);
+ // sdDebug(254);
+#ifdef REDMAC_PERFORMANCE
+ call Performance.macAckTimeout();
+#endif
updateLongRetryCounters();
}
else {
- storeOldState(158);
+ // sdDebug(255);
signalSendDone(SUCCESS);
}
macState = SLEEP;
setSleepMode();
}
}
+ else if(macState == TX_ACK) {
+ setTxMode();
+ // sdDebug(10000 + getHeader(&ackMsg)->dest);
+ }
else if(macState == SLEEP) {
if(isFlagSet(&flags, SWITCHING)) {
- storeOldState(106);
- call Timer.start(backoff(0));
+ // sdDebug(256);
+ call Timer.start(call Random.rand16() & 0x0f);
}
else {
- storeOldState(107);
- checkSend();
+ if(isFlagSet(&flags, RESUME_BACKOFF)) {
+ // sdDebug(261);
+ clearFlag(&flags, RESUME_BACKOFF);
+ call Timer.start(restLaufzeit);
+ restLaufzeit = 0;
+ }
+ else {
+ // sdDebug(262);
+ checkSend();
+ }
}
}
else if((macState == RX_ACK_P) || (macState == RX_P)) {
- storeOldState(108);
+ // sdDebug(258);
}
else if(macState == INIT) {
- storeOldState(109);
+ // sdDebug(259);
post StartDoneTask();
}
else {
- storeOldState(110);
- signalFailure(15);
- }
- }
-
- /****** SampleTimer ******************************/
-
- task void ageMsgsTask() {
- unsigned i;
- atomic {
- for(i = 0; i < MSG_TABLE_ENTRIES; i++) {
- if(knownMsgTable[i].age <= MAX_AGE) ++knownMsgTable[i].age;
- }
+ // sdDebug(260);
}
}
+ /****** SampleTimer ******************************/
async event void SampleTimer.fired() {
- call SampleTimer.start(sleepTime);
- storeOldState(111);
+ call SampleTimer.start(localSleeptime);
+ // sdDebug(270);
if((macState == SLEEP) && (!isFlagSet(&flags, SWITCHING))) {
clearFlag(&flags, ACTION_DETECTED);
interruptBackoffTimer();
macState = RX;
- storeOldState(112);
+ // sdDebug(271);
setRxMode();
call Timer.stop();
}
- post ageMsgsTask();
}
- /***** SleepTime **********************************/
- async command void SleepTime.setSleepTime(uint16_t sT) {
+ /***** Sleeptime **********************************/
+ async command void Sleeptime.setLocalSleeptime(uint16_t sT) {
+ atomic localSleeptime = sT;
+ }
+
+ async command uint16_t Sleeptime.getLocalSleeptime() {
+ uint16_t st;
+ atomic st = localSleeptime;
+ return st;
+ }
+
+ async command void Sleeptime.setNetworkSleeptime(uint16_t sT) {
atomic {
- sleepTime = sT;
+ networkSleeptime = sT;
for(MIN_BACKOFF_MASK = 1; MIN_BACKOFF_MASK < sT; ) {
MIN_BACKOFF_MASK = (MIN_BACKOFF_MASK << 1) + 1;
}
}
}
- async command uint16_t SleepTime.getSleepTime() {
+ async command uint16_t Sleeptime.getNetworkSleeptime() {
uint16_t st;
- atomic st = sleepTime;
+ atomic st = networkSleeptime;
return st;
}
/****** ChannelMonitor events *********************/
async event void ChannelMonitor.channelBusy() {
- storeOldState(120);
+ // sdDebug(280);
checkOnBusy();
}
async event void ChannelMonitor.channelIdle() {
- storeOldState(121);
+ // sdDebug(281);
checkOnIdle();
}
event void ChannelMonitorControl.updateNoiseFloorDone() {
if(macState == INIT) {
- storeOldState(130);
- call Timer.start(call Random.rand16() % DEFAULT_SLEEP_TIME);
+ // sdDebug(290);
+ call Timer.start(call Random.rand16() % localSleeptime);
setSleepMode();
} else {
- storeOldState(131);
- signalFailure(16);
+ // sdDebug(291);
}
}
/***** ChannelMonitorData events ******************/
async event void ChannelMonitorData.getSnrDone(int16_t data) {
- storeOldState(140);
atomic if((macState == RX_P) || (macState == RX_ACK_P)) rssiValue = data;
}
macState_t ms;
atomic ms = macState;
if(ms < SLEEP) {
- storeOldState(144);
+ // sdDebug(300);
}
else if(ms == INIT) {
- storeOldState(145);
+ // sdDebug(301);
call ChannelMonitorControl.updateNoiseFloor();
}
else {
- storeOldState(146);
+ // sdDebug(302);
post ReleaseAdcTask();
}
}
}
default async event void ChannelCongestion.congestionEvent(uint8_t level) {}
+
+ /***** Mac Eval *******************************************/
+#ifdef MAC_EVAL
+ async command void MacEval.setBackoffMask(uint16_t mask) {
+ atomic MIN_BACKOFF_MASK = mask;
+ }
+ async command void MacEval.increaseBackoff(bool value) {
+ atomic INCREASE_BACKOFF = value;
+ }
+ async command void MacEval.addNav(uint8_t value) {
+ atomic ADD_NAV = value;
+ }
+ async command void MacEval.setLongRetry(uint8_t lr) {
+ atomic MAX_LONG_RETRY = lr;
+ }
+ async command void MacEval.setShortRetry(uint8_t sr) {
+ atomic MAX_SHORT_RETRY = sr;
+ }
+#endif
/***** unused Radio Modes events **************************/
-
async event void RadioModes.TimerModeDone() {}
async event void RadioModes.SelfPollingModeDone() {}
async event void RadioModes.PWDDDInterrupt() {}