interface Resource as RssiAdcResource;
interface Random;
+
+ interface Timer<TMilli> as ReRxTimer;
+ interface Duplicate;
interface Alarm<T32khz, uint16_t> as Timer;
async command am_addr_t amAddress();
{
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=35, // 4 Phy Preamble at 38400
+ 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
+
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
+ SUB_FOOTER_TIME=2*BYTE_TIME, // 2 bytes crc
MAXTIMERVALUE=0xFFFF, // helps to compute backoff
DATA_DETECT_TIME=17,
- RX_SETUP_TIME=111, // time to set up receiver
- TX_SETUP_TIME=69, // time to set up transmitter
+ 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 + 4 + 3*ADDED_DELAY,
- TX_GAP_TIME=RX_ACK_TIMEOUT + TX_SETUP_TIME + 11,
- MIN_BACKOFF_MASK=0x3F, // about txrx_turnaround time
+ 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,
- MSG_TABLE_ENTRIES=5,
- MAX_AGE=2*MAX_LONG_RETRY*MAX_SHORT_RETRY,
+ INVALID_SNR = 0xffff
};
/**************** Module Global Variables *****************/
uint8_t flags;
uint8_t seqNo;
- uint16_t slotMask;
uint16_t restLaufzeit;
- /* duplicate suppression */
- typedef struct knownMessage_t {
- am_addr_t src;
- uint8_t token;
- uint8_t age;
- } knownMessage_t;
+ uint16_t rssiValue = 0;
- knownMessage_t knownMsgTable[MSG_TABLE_ENTRIES];
-
- task void ageMsgsTask() {
- unsigned i;
- atomic {
- for(i = 0; i < MSG_TABLE_ENTRIES; i++) {
- if(knownMsgTable[i].age <= MAX_AGE) ++knownMsgTable[i].age;
- }
- }
- }
-
/****** debug vars & defs & functions ***********************/
#ifdef MACM_DEBUG
#define HISTORY_ENTRIES 100
}
void setRxMode() {
+ rssiValue = INVALID_SNR;
if(call RadioModes.RxMode() == FAIL) {
post SetRxModeTask();
}
}
/**************** Helper functions ********/
+
+ task void postponeReRx() {
+ call ReRxTimer.startOneShot(5000);
+ }
+
uint16_t backoff(uint8_t counter) {
- uint16_t mask = MIN_BACKOFF_MASK;
- unsigned i;
- for(i = 0; i < counter; i++) {
- mask = (mask << 1) + 1;
- }
+ uint16_t mask = BACKOFF_MASK >> (MAX_LONG_RETRY - counter);
return (call Random.rand16() & mask);
}
restLaufzeit = restLaufzeit - now;
}
else {
- restLaufzeit += MAXTIMERVALUE - now;
+ restLaufzeit = (uint16_t)(-1) - restLaufzeit + now;
+ }
+ 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;
if(isFlagSet(&flags, CANCEL_SEND)) {
e = ECANCEL;
}
+ storeStrength(m);
clearFlag(&flags, CANCEL_SEND);
}
signal MacSend.sendDone(m, e);
}
bool isNewMsg(message_t* msg) {
- 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;
- return FALSE;
- }
- }
- return TRUE;
- }
-
- 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)->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)->token) & TOKEN_ACK_MASK);
}
void checkSend() {
/**************** Init ************************/
command error_t Init.init(){
- unsigned i;
atomic {
txBufPtr = NULL;
macState = INIT;
shortRetryCounter = 0;
longRetryCounter = 0;
flags = 0;
- slotMask = MIN_BACKOFF_MASK;
- for(i = 0; i < MSG_TABLE_ENTRIES; i++) {
- knownMsgTable[i].age = MAX_AGE;
- }
#ifdef MACM_DEBUG
histIndex = 0;
#endif
return call SubPacket.maxPayloadLength();
}
- command void* Packet.getPayload(message_t* msg, uint8_t* len) {
+ command void* Packet.getPayload(message_t* msg, uint8_t len) {
return call SubPacket.getPayload(msg, len);
}
}
async event void RadioModes.RxModeDone() {
+ post postponeReRx();
atomic {
if(macState == SW_RX) {
storeOldState(21);
}
async event void RadioModes.TxModeDone() {
+ post postponeReRx();
atomic {
if(macState == SW_TX) {
storeOldState(30);
/****** PacketSerializer events **********************/
async event void PacketReceive.receiveDetected() {
- if(macState <= RX_ACK) {
+ rssiValue = INVALID_SNR;
+ if(macState <= RX_ACK) {
storeOldState(60);
interruptBackoffTimer();
if(macState == CCA) computeBackoff();
}
if(macState <= RX) {
- post ReleaseAdcTask();
- storeOldState(61);
+ storeOldState(61);
macState = RX_P;
signalMacState();
}
else if(macState <= RX_ACK) {
- post ReleaseAdcTask();
storeOldState(62);
macState = RX_ACK_P;
signalMacState();
macState_t action = RX;
if(macState == RX_P) {
if(error == SUCCESS) {
- post ageMsgsTask();
storeOldState(82);
isCnt = isControl(msg);
if(msgIsForMe(msg)) {
if(!isCnt) {
- (getMetadata(m))->strength = 10;
+ storeStrength(msg);
if(isNewMsg(m)) {
m = signal MacReceive.receiveDone(msg);
rememberMsg(m);
if(error == SUCCESS) {
if(ackIsForMe(msg)) {
storeOldState(92);
- (getMetadata(txBufPtr))->strength = 10;
(getMetadata(txBufPtr))->ack = WAS_ACKED;
signalSendDone(SUCCESS);
}
/***** ChannelMonitorData events ******************/
async event void ChannelMonitorData.getSnrDone(int16_t 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) call ChannelMonitor.rxSuccess();
}