redmacp.nc

来自「tinyos-2.x.rar」· NC 代码 · 共 1,354 行 · 第 1/3 页

NC
1,354
字号
        message_t *m;
        error_t e = error;
        // 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;
            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() {
        shortRetryCounter++;
        if(shortRetryCounter > MAX_SHORT_RETRY) {
            longRetryCounter++;
            shortRetryCounter = 1;
            if(longRetryCounter > MAX_LONG_RETRY) {
                // sdDebug(60);
                signalSendDone(FAIL);
            }
        }
    }

    void updateLongRetryCounters() {
        atomic {
            clearFlag(&flags, MESSAGE_PREPARED);
            longRetryCounter++;
            shortRetryCounter = 1;
            if(longRetryCounter > MAX_LONG_RETRY) {
                // sdDebug(70);
                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 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) {
        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(){
        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 REDMAC_DEBUG
        call SerialDebug.putShortDesc("RedMacP");
#endif
        return SUCCESS;
    }

    /****************  SplitControl  *****************/

    task void StartDoneTask() {
        // sdDebug(90);
        atomic  {
            call SampleTimer.start(localSleeptime);
            macState = SLEEP;
            setFlag(&flags, TEAMGEIST_ACTIVE);
            teamgeistType = signal Teamgeist.observedAMType();
        }
        signal SplitControl.startDone(SUCCESS);        
    }
    
    command error_t SplitControl.start() {
        call CcaStdControl.start();
        atomic {
            macState = INIT;
            setRxMode();
            // sdDebug(100);
        }
        return SUCCESS;
    }
    
    task void StopDoneTask() {
        call Init.init();
        // sdDebug(110);
        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;
                // sdDebug(120);
            }
            else {
                macState = STOP;
                setSleepMode();
                // sdDebug(121);
            }
        }
        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);
            // sdDebug(130);
        }
        else if(macState == RX_P) {
            // sdDebug(131);
            if(call RssiAdcResource.isOwner()) call ChannelMonitorData.getSnr();
        }
        else if(macState == RX_ACK) {
        }
        else if(macState == RX_ACK_P) {
        }
        else if(macState == INIT) {
            // sdDebug(133);
            if(call RssiAdcResource.isOwner()) {
                call ChannelMonitorControl.updateNoiseFloor();
            } else {
                call RssiAdcResource.request();
            }
        }
        else if(macState == STOP) {
            // sdDebug(134);
        }
        else {
            // sdDebug(135);
        }
    }
    
    async event void RadioModes.RxModeDone() {
        atomic {
            clearFlag(&flags, SWITCHING);
            if((macState == RX) || (macState == RX_ACK) || (macState == CCA) ||
               (macState == INIT) || (macState == STOP)) {
                // sdDebug(140);
                if(macState != RX_ACK) requestAdc();
            }
            else {
                // sdDebug(141);
            }
        }
    }
    
    async event void RadioModes.TxModeDone() {
        // sdDebug(150);
        atomic {
            clearFlag(&flags, SWITCHING);
            if(macState == TX) {
                setFlag(&flags, ACTION_DETECTED);
                if(call PacketSend.send(txBufPtr, txLen) == SUCCESS) {
                    // sdDebug(151);
                }
                else {
                    // sdDebug(152);
                }
            }
            else if(macState == TX_ACK) {
                if(call PacketSend.send(&ackMsg, 0) == SUCCESS) {
                    // sdDebug(153);
                } else {
                    // sdDebug(154);
                }
            }
            else {
                // sdDebug(155);
            }
        }
    }

    async event void RadioModes.SleepModeDone() {
        // sdDebug(160);
        atomic {
            clearFlag(&flags, SWITCHING);
            if(isFlagSet(&flags, ACTION_DETECTED)) {
                if(congestionLevel < 5) congestionLevel++;
            } else {
                if(congestionLevel > 0) congestionLevel--;
            }
            // 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 == STOP) {
                // sdDebug(168);
                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);
                // 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 {
                // sdDebug(171);
                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) {
                // sdDebug(320);
                setFlag(&flags, CANCEL_SEND);
                shortRetryCounter = MAX_SHORT_RETRY + 2;
                longRetryCounter  = MAX_LONG_RETRY + 2;
                if(macState == SLEEP) {
                    // sdDebug(321);
                    signalSendDone(ECANCEL);
                }
                else {
                    // sdDebug(322);
                }
                // sdDebug(1000 + macState);
                err = SUCCESS;
            }
            else {
                // sdDebug(323);
                // sdDebug(1100 + macState);
            }
        }
        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 REDMAC_PERFORMANCE
                call Performance.macDetectedOnCca();
#endif
            }
            if(macState != RX_ACK) {
                macState = RX_P;
            } else {
                macState = RX_ACK_P;
            }
        }
        else if(macState == INIT) {
            // sdDebug(180);
            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;
        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(error == SUCCESS) {
                // sdDebug(192);
                isCnt = isControl(msg);
                if(msgIsForMe(msg)) {
                    if(!isCnt) {
                        // sdDebug(193);
                        if(isNewMsg(msg)) {
#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) {
                                // sdDebug(195);
                                rememberMsg(msg);
                            } else {
                                // 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)) {

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?