interface MacReceive;
interface Packet;
interface LocalTime<T32khz> as LocalTime32khz;
- interface SleepTime;
+ interface Sleeptime;
interface Teamgeist;
interface ChannelCongestion;
}
#ifdef REDMAC_DEBUG
interface SerialDebug;
#endif
+#ifdef REDMAC_PERFORMANCE
+ interface Performance;
+#endif
+
}
}
implementation
void sdDebug(uint16_t p) {};
#endif
+#ifdef REDMAC_PERFORMANCE
+ macTxStat_t txStat;
+ macRxStat_t rxStat;
+#endif
+
/**************** Module Global Constants *****************/
enum {
} 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;
-
- message_t *txBufPtr;
- uint16_t txLen;
- red_mac_header_t *txMacHdr;
+ 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;
- uint16_t seqNo;
- message_t ackMsg;
+ uint16_t counter2sec = 127;
+ uint32_t rxTime = 0;
+
+ am_id_t teamgeistType = 0;
- uint16_t counter2sec;
- uint32_t rxTime;
+ uint8_t congestionLevel = 0;
- am_id_t teamgeistType;
+ message_t *txBufPtr = NULL;
+ uint16_t txLen = 0;
+ red_mac_header_t *txMacHdr = NULL;
+ uint16_t seqNo;
+ message_t ackMsg;
- uint8_t congestionLevel;
uint16_t MIN_BACKOFF_MASK;
/****** Secure switching of radio modes ***/
if(call RadioModes.RxMode() == FAIL) {
post SetRxModeTask();
}
+ else {
+#ifdef REDMAC_PERFORMANCE
+ call Performance.macRxMode();
+#endif
+ }
requestAdc();
}
if(call RadioModes.SleepMode() == FAIL) {
post SetSleepModeTask();
}
+ else {
+#ifdef REDMAC_PERFORMANCE
+ call Performance.macSleepMode();
+#endif
+ }
}
task void SetSleepModeTask() {
if(call RadioModes.TxMode() == FAIL) {
post SetTxModeTask();
}
+ else {
+#ifdef REDMAC_PERFORMANCE
+ call Performance.macTxMode();
+#endif
+ }
}
task void SetTxModeTask() {
atomic {
msg = txBufPtr;
length = txLen;
- sT = sleepTime;
+ sT = networkSleeptime;
}
if(msg == NULL) return;
macHdr = (red_mac_header_t *)call SubPacket.getPayload(msg, NULL);
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
}
}
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) {
// 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() {
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;
- shortRetryCounter = 0;
- longRetryCounter = 0;
- counter2sec = 127;
- rxTime = 0;
- teamgeistType = 0;
}
#ifdef REDMAC_DEBUG
call SerialDebug.putShortDesc("RedMacP");
task void StartDoneTask() {
// sdDebug(90);
atomic {
- call SampleTimer.start(sleepTime);
+ call SampleTimer.start(localSleeptime);
macState = SLEEP;
setFlag(&flags, TEAMGEIST_ACTIVE);
teamgeistType = signal Teamgeist.observedAMType();
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 {
// sdDebug(171);
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 {
uint32_t nav = 0;
uint8_t level = 0;
bool isCnt;
-
+#ifdef REDMAC_PERFORMANCE
+ rxStat.duplicate = PERF_UNKNOWN;
+ rxStat.repCounter = 0xff;
+#endif
// sdDebug(190);
if(macState == RX_P) {
// sdDebug(191);
if(!isCnt) {
// sdDebug(193);
if(isNewMsg(msg)) {
+#ifdef REDMAC_PERFORMANCE
+ rxStat.duplicate = PERF_NEW_MSG;
+#endif
// sdDebug(194);
if(rssiValue != INVALID_SNR) {
(getMetadata(m))->strength = rssiValue;
} else {
// sdDebug(196);
action = RX;
+#ifdef REDMAC_PERFORMANCE
+ call Performance.macQueueFull();
+#endif
}
}
if(needsAckRx(msg, &level) && (action != RX)) {
else {
// sdDebug(199);
action = RX;
+#ifdef REDMAC_PERFORMANCE
+ rxStat.duplicate = PERF_REPEATED_MSG;
+#endif
}
}
else {
else {
// 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;
}
if((macState == RX) || (macState == CCA) || (macState == CCA_ACK)) {
if(macState == CCA) {
computeBackoff();
+#ifdef REDMAC_PERFORMANCE
+ call Performance.macBusyOnCca();
+#endif
}
requestAdc();
// sdDebug(230);
// sdDebug(243);
macState = TX;
setTxMode();
+#ifdef REDMAC_PERFORMANCE
+ call Performance.macIdleOnCca();
+ txStat.txModeTime = call LocalTime32khz.get();
+#endif
}
}
else if(macState == CCA_ACK) {
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
}
}
else {
if(needsAckTx(txBufPtr)) {
sdDebug(254);
+#ifdef REDMAC_PERFORMANCE
+ call Performance.macAckTimeout();
+#endif
updateLongRetryCounters();
}
else {
}
async event void SampleTimer.fired() {
- call SampleTimer.start(sleepTime);
+ call SampleTimer.start(localSleeptime);
// sdDebug(270);
if((macState == SLEEP) && (!isFlagSet(&flags, SWITCHING))) {
clearFlag(&flags, ACTION_DETECTED);
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;
}
event void ChannelMonitorControl.updateNoiseFloorDone() {
if(macState == INIT) {
// sdDebug(290);
- call Timer.start(call Random.rand16() % DEFAULT_SLEEP_TIME);
+ call Timer.start(call Random.rand16() % localSleeptime);
setSleepMode();
} else {
// sdDebug(291);
+++ /dev/null
-/* -*- mode:c++; indent-tabs-mode: nil -*-
- * Copyright (c) 2006, Technische Universitaet Berlin
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * - Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * - Neither the name of the Technische Universitaet Berlin nor the names
- * of its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
- * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
- * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-/**
- * Interface to control the duty cycle of the MAC
- * @author Andreas Koepke (koepke at tkn.tu-berlin.de)
- */
-interface SleepTime {
- /**
- * set the sleep time of the MAC in units of a 32kHz clock, the setting
- * takes effect on the next wakeup. To avoid synchroninization of the wake
- * up times, some additional randomization can be necessary, esp. when
- * switching from shorter to longer sleep times.
- */
- async command void setSleepTime(uint16_t sT);
-
- /**
- * which sleep time is in effect?
- */
- async command uint16_t getSleepTime();
-}
--- /dev/null
+/* -*- mode:c++; indent-tabs-mode: nil -*-
+ * Copyright (c) 2006, Technische Universitaet Berlin
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * - Neither the name of the Technische Universitaet Berlin nor the names
+ * of its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/**
+ * Interface to control the duty cycle of the MAC
+ * @author Andreas Koepke (koepke at tkn.tu-berlin.de)
+ */
+interface Sleeptime {
+ /**
+ * set the sleep time of the MAC in units of a 32kHz clock, the setting
+ * takes effect on the next wakeup.
+ *
+ * Caution 1: To avoid synchroninization of the wake up times, some
+ * additional randomization can be necessary, esp. when
+ * switching from shorter to longer sleep times.
+ * Caution 2: The local sleep time must be equal or shorter than the
+ * network sleep time
+ */
+ async command void setLocalSleeptime(uint16_t sT);
+
+ /**
+ * which sleep time is in effect?
+ */
+ async command uint16_t getLocalSleeptime();
+
+ /**
+ * set the expected sleep time of the network -- this defines how long this
+ * node will attempt to wake up a remote node.
+ * Caution: The local sleep time must be equal or shorter than the
+ * network sleep time
+ */
+ async command void setNetworkSleeptime(uint16_t sT);
+
+ /**
+ * how long do we expect our neighbors to sleep?
+ */
+ async command uint16_t getNetworkSleeptime();
+
+}