📄 speckmacdp.nc
字号:
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)) { repeat = txMacHdr->repetitionCounter = 0; } else { repeat = txMacHdr->repetitionCounter; txMacHdr->repetitionCounter--; } } return repeat; } void signalSendDone(error_t error) { message_t *m; error_t e = error; atomic { m = txBufPtr; txBufPtr = NULL; txLen = 0;#ifdef SPECKMAC_PERFORMANCE txStat.repCounter = txMacHdr->repetitionCounter; txStat.longRetry = longRetryCounter; txStat.shortRetry = shortRetryCounter;#endif longRetryCounter = 0; shortRetryCounter = 0; storeStrength(m); if(isFlagSet(&flags, CANCEL_SEND)) { e = ECANCEL; } clearFlag(&flags, MESSAGE_PREPARED); clearFlag(&flags, CANCEL_SEND); } signal MacSend.sendDone(m, e);#ifdef SPECKMAC_PERFORMANCE txStat.success = e; txStat.strength = getMetadata(m)->strength; call Performance.macTxMsgStats(&txStat);#endif } void updateRetryCounters() { shortRetryCounter++; if(shortRetryCounter > MAX_SHORT_RETRY) { longRetryCounter++; shortRetryCounter = 1; if(longRetryCounter > MAX_LONG_RETRY) { signalSendDone(FAIL); } } } void updateLongRetryCounters() { atomic { clearFlag(&flags, MESSAGE_PREPARED); longRetryCounter++; shortRetryCounter = 1; if(longRetryCounter > MAX_LONG_RETRY) { signalSendDone(FAIL); } else { post PrepareMsgTask(); } } } 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; } void interruptBackoffTimer() { if(call Timer.isRunning()) { 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; } setFlag(&flags, RESUME_BACKOFF); } } void computeBackoff() { if(!isFlagSet(&flags, RESUME_BACKOFF)) { setFlag(&flags, RESUME_BACKOFF); restLaufzeit = backoff(longRetryCounter); updateRetryCounters(); } } bool msgIsForMe(message_t* msg) { if(getHeader(msg)->dest == AM_BROADCAST_ADDR) return TRUE; if(getHeader(msg)->dest == call amAddress()) return TRUE; if(getHeader(msg)->dest >= RELIABLE_MCAST_MIN_ADDR) return TRUE; return FALSE; } bool isControl(message_t* m) { uint8_t token = getHeader(m)->token; return isFlagSet(&token, TOKEN_ACK_FLAG); } bool isNewMsg(message_t* msg) { 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)->dest, (getHeader(msg)->token) & TOKEN_ACK_MASK); } 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;#ifdef SPECKMAC_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; } /**************** Init ************************/ command error_t Init.init(){ atomic { macState = INIT; seqNo = call Random.rand16() % TOKEN_ACK_FLAG; for(MIN_BACKOFF_MASK = 1; MIN_BACKOFF_MASK < networkSleeptime; ) { MIN_BACKOFF_MASK = (MIN_BACKOFF_MASK << 1) + 1; } MIN_BACKOFF_MASK >>= 2; }#ifdef SPECKMAC_DEBUG call SerialDebug.putShortDesc("SpeckMacP");#endif return SUCCESS; } /**************** SplitControl *****************/ task void StartDoneTask() { atomic { call SampleTimer.start(localSleeptime); macState = SLEEP; sdDebug(60); } signal SplitControl.startDone(SUCCESS); } command error_t SplitControl.start() { call CcaStdControl.start(); atomic { macState = INIT; setRxMode(); } sdDebug(10); return SUCCESS; } task void StopDoneTask() { call Init.init(); signal SplitControl.stopDone(SUCCESS); } command error_t SplitControl.stop() { call CcaStdControl.stop(); call Timer.stop(); call SampleTimer.stop(); atomic { if((macState == SLEEP) && isFlagSet(&flags, SWITCHING)) { macState = STOP; } else { macState = STOP; setSleepMode(); } } 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) - sizeof(red_mac_header_t); } command void Packet.setPayloadLength(message_t* msg, uint8_t len) { call SubPacket.setPayloadLength(msg,len + sizeof(red_mac_header_t)); } command uint8_t Packet.maxPayloadLength() { 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 + sizeof(red_mac_header_t)); return (void*)(payload + sizeof(red_mac_header_t)); } /****** Radio(Mode) events *************************/ async event void RadioModes.RssiStable() { setFlag(&flags, RSSI_STABLE); if((macState == RX) || (macState == CCA)) { call Timer.start(DATA_DETECT_TIME); } else if(macState == RX_P) { if(call RssiAdcResource.isOwner()) call ChannelMonitorData.getSnr(); } else if(macState == RX_ACK) { // if(call RssiAdcResource.isOwner()) call ChannelMonitor.start(); } else if(macState == RX_ACK_P) { } else if(macState == INIT) { if(call RssiAdcResource.isOwner()) { sdDebug(20); call ChannelMonitorControl.updateNoiseFloor(); } else { sdDebug(21); call RssiAdcResource.request(); } } else if(macState == STOP) { } else { } } async event void RadioModes.RxModeDone() { atomic { clearFlag(&flags, SWITCHING); if((macState == RX) || (macState == RX_ACK) || (macState == CCA) || (macState == INIT) || (macState == STOP)) { if(macState != RX_ACK) requestAdc(); } else { } } } async event void RadioModes.TxModeDone() { atomic { clearFlag(&flags, SWITCHING); if(macState == TX) { setFlag(&flags, ACTION_DETECTED); if(call PacketSend.send(txBufPtr, txLen) == SUCCESS) { } else { } } else if(macState == TX_ACK) { if(call PacketSend.send(&ackMsg, 0) == SUCCESS) { } else { } } else { } } } async event void RadioModes.SleepModeDone() { atomic { clearFlag(&flags, SWITCHING); if(isFlagSet(&flags, ACTION_DETECTED)) { if(congestionLevel < 5) congestionLevel++; } else { if(congestionLevel > 0) congestionLevel--; } if(macState == SLEEP) { if(!call Timer.isRunning()) { if(isFlagSet(&flags, RESUME_BACKOFF)) { clearFlag(&flags, RESUME_BACKOFF); call Timer.start(restLaufzeit); restLaufzeit = 0; } else { checkSend(); } } } else if(macState == STOP) { post StopDoneTask(); } signal ChannelCongestion.congestionEvent(congestionLevel); } } /****** MacSend events *************************/ async command error_t MacSend.send(message_t* msg, uint8_t len) { error_t err = SUCCESS; atomic { if((shortRetryCounter == 0) && (txBufPtr == NULL)) { clearFlag(&flags, MESSAGE_PREPARED); shortRetryCounter = 1; longRetryCounter = 1; txBufPtr = msg; txLen = len + sizeof(red_mac_header_t); seqNo++; if(seqNo >= TOKEN_ACK_FLAG) seqNo = 1;#ifdef SPECKMAC_PERFORMANCE txStat.payloadLength = txLen; txStat.interfaceTime = call LocalTime32kHz.get();#endif } else { err = EBUSY; } } if(err == SUCCESS) { post PrepareMsgTask(); } return err; } async command error_t MacSend.cancel(message_t* msg) { error_t err = FAIL; atomic { if(msg == txBufPtr) { setFlag(&flags, CANCEL_SEND); shortRetryCounter = MAX_SHORT_RETRY + 2; longRetryCounter = MAX_LONG_RETRY + 2; if(macState == SLEEP) { signalSendDone(ECANCEL); } else { } err = SUCCESS; } else { } } return err; } /****** PacketSerializer events **********************/ async event void PacketReceive.receiveDetected() { rssiValue = INVALID_SNR; setFlag(&flags, ACTION_DETECTED); call ChannelMonitor.rxSuccess(); if(macState <= CCA_ACK) { if(macState == CCA) { computeBackoff();#ifdef SPECKMAC_PERFORMANCE call Performance.macDetectedOnCca();#endif } if(macState != RX_ACK) { macState = RX_P; } else { macState = RX_ACK_P; } } else if(macState == INIT) { setFlag(&flags, UNHANDLED_PACKET); } } async event message_t* PacketReceive.receiveDone(message_t* msg, void* payload, uint8_t len, error_t error) { message_t *m = msg; macState_t action = STOP; uint32_t nav = 0; bool isCnt;#ifdef SPECKMAC_PERFORMANCE rxStat.duplicate = PERF_UNKNOWN;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -