#include "PacketAck.h"
#include "RedMac.h"
+#ifdef DELTATIMEDEBUG
+#include "DeltaTrace.h"
+#endif
+
module RedMacP {
provides {
interface Init;
interface Sleeptime;
interface Teamgeist;
interface ChannelCongestion;
+#ifdef MAC_EVAL
+ interface MacEval;
+#endif
}
uses {
interface StdControl as CcaStdControl;
interface LocalTime<T32khz> as LocalTime32kHz;
interface Duplicate;
+ interface TimeDiff16;
+ interface TimeDiff32;
async command am_addr_t amAddress();
/*
#ifdef REDMAC_PERFORMANCE
interface Performance;
#endif
-
+#ifdef DELTATIMEDEBUG
+ interface DeltaTrace;
+#endif
}
}
implementation
#endif
#ifdef REDMAC_PERFORMANCE
- macTxStat_t txStat;
- macRxStat_t rxStat;
+ PfmTxMsg_t txStat;
+ PfmRxMsg_t rxStat;
#endif
/**************** Module Global Constants *****************/
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
- BYTE_TIME=21, // byte at 23405 kBit/s, 4b6b encoded
- PREAMBLE_BYTE_TIME=14, // byte at 23405 kBit/s, no coding
- PHY_HEADER_TIME=84, // 6 Phy Preamble at 23405 bits/s
- TIME_CORRECTION=16, // difference between txSFD and rxSFD: 475us
-
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,
- // DEFAULT_SLEEP_TIME=3250,
- // DEFAULT_SLEEP_TIME=6500,
+#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=32768U,
// DEFAULT_SLEEP_TIME=65535U,
+#endif
DATA_DETECT_TIME=17,
RX_SETUP_TIME=102, // time to set up receiver
TX_SETUP_TIME=58, // time to set up transmitter
TX_GAP_TIME = RX_ACK_TIMEOUT + TX_SETUP_TIME + 33,
// the duration of a send ACK
ACK_DURATION = SUB_HEADER_TIME + SUB_FOOTER_TIME,
+ 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,
INVALID_SNR = 0xffff,
// 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 *****************/
/* flags */
typedef enum {
uint32_t backoff(uint8_t counter) {
uint32_t rVal = call Random.rand16() & MIN_BACKOFF_MASK;
+ if(!INCREASE_BACKOFF) counter = 1;
return (rVal << counter) + ZERO_BACKOFF_MASK;
}
if(isFlagSet(&flags, TEAMGEIST_ACTIVE) &&
(getHeader(msg)->type == teamgeistType)) {
if(rssiValue != INVALID_SNR) snr = rssiValue;
- rVal = signal Teamgeist.needsAck(msg, getHeader(msg)->src, getHeader(msg)->dest, snr);
*level = 2;
+ rVal = signal Teamgeist.needsAck(msg, getHeader(msg)->src, getHeader(msg)->dest, snr);
}
}
}
sT = networkSleeptime;
}
if(msg == NULL) return;
- macHdr = (red_mac_header_t *)call SubPacket.getPayload(msg, sizeof(red_mac_header_t) + length);
+ 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 {
call Timer.start((call Random.rand16() >> 3) & ZERO_BACKOFF_MASK);
}
else {
+ sdDebug(332);
+ sdDebug(macHdr->repetitionCounter);
call Timer.start(backoff(longRetryCounter));
}
}
void storeStrength(message_t *m) {
if(rssiValue != INVALID_SNR) {
- (getMetadata(txBufPtr))->strength = rssiValue;
+ (getMetadata(m))->strength = rssiValue;
}
else {
if(call RssiAdcResource.isOwner()) {
- (getMetadata(txBufPtr))->strength = call ChannelMonitorData.readSnr();
+ (getMetadata(m))->strength = call ChannelMonitorData.readSnr();
}
else {
- (getMetadata(txBufPtr))->strength = 1;
+ (getMetadata(m))->strength = 1;
}
}
}
}
void interruptBackoffTimer() {
- uint16_t now;
if(call Timer.isRunning()) {
- restLaufzeit = call Timer.getAlarm();
- call Timer.stop();
- now = call Timer.getNow();
- if(restLaufzeit >= now) {
- restLaufzeit = restLaufzeit - now;
- }
- else {
- restLaufzeit = (uint16_t)(-1) - restLaufzeit + now;
- }
+ restLaufzeit = call TimeDiff16.computeDelta(call Timer.getAlarm(), call Timer.getNow());
+ call Timer.stop();
if(restLaufzeit > MIN_BACKOFF_MASK << MAX_LONG_RETRY) {
restLaufzeit = call Random.rand16() & ZERO_BACKOFF_MASK;
}
}
bool isNewMsg(message_t* msg) {
- return call Duplicate.isNew(getHeader(msg)->src, (getHeader(msg)->token) & TOKEN_ACK_MASK);
+ return call Duplicate.isNew(getHeader(msg)->src,
+ getHeader(msg)->dest,
+ (getHeader(msg)->token) & TOKEN_ACK_MASK);
}
void rememberMsg(message_t* msg) {
- call Duplicate.remember(getHeader(msg)->src, (getHeader(msg)->token) & TOKEN_ACK_MASK);
+ call Duplicate.remember(getHeader(msg)->src, getHeader(msg)->dest,
+ (getHeader(msg)->token) & TOKEN_ACK_MASK);
}
void prepareAck(message_t* msg) {
}
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(){
if(call RssiAdcResource.isOwner()) call ChannelMonitorData.getSnr();
}
else if(macState == RX_ACK) {
- // if(call RssiAdcResource.isOwner()) call ChannelMonitor.start();
- // sdDebug(132);
}
else if(macState == RX_ACK_P) {
}
#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);
#endif
}
}
-#ifdef REDMAC_PERFORMANCE
else {
+#ifdef REDMAC_PERFORMANCE
rxStat.duplicate = PERF_REPEATED_MSG;
+#endif
}
-#endif
if(needsAckRx(msg, &level) && (action != RX)) {
- // sdDebug(197);
action = CCA_ACK;
+ if(level == 2) {
+ getMetadata(msg)->ack = WAS_ACKED;
+ }
}
else {
// sdDebug(198);
else if(action == SLEEP) {
macState = SLEEP;
if(isFlagSet(&flags, RESUME_BACKOFF)) {
+ nav = nav*(uint32_t)ADD_NAV/(uint32_t)NAV_FACTOR;
if(nav > restLaufzeit) restLaufzeit += nav;
}
else {
}
else if(macState == TX_ACK) {
checkCounter = 0;
- macState = RX;
- setRxMode();
+ macState = SLEEP;
+ setSleepMode();
+ // macState = RX;
+ // setRxMode();
// sdDebug(221);
#ifdef REDMAC_DEBUG
// sdDebug(40000U + repCounter);
}
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 = (uint32_t)(-1) - mTime + now;
- }
+#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
}
}
// sdDebug(260);
}
}
-
+
/****** SampleTimer ******************************/
-
async event void SampleTimer.fired() {
call SampleTimer.start(localSleeptime);
// sdDebug(270);
default async event void ChannelCongestion.congestionEvent(uint8_t level) {}
- /***** unused Radio Modes events **************************/
+ /***** 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() {}