Example #1
0
File: RACH.cpp Project: openwns/lte
bool
RACHUT::doIsAccepting(const wns::ldk::CompoundPtr& compound) const
{
	// Check whether we are outside the RAP phase
	if (accepting == false) return false;

	// how much of the overall RACH duration is left?
	simTimeType duration = stopTime - wns::simulator::getEventScheduler()->getTime();
	assure(duration >= 0, "RACH Timing mismatch.");

	// Check whether the packet can be transmitted in the remaining time of
	// this RACH phase
	assure(phyModePtr->dataRateIsValid(),"!dataRateIsValid");
	int capacity = phyModePtr->getBitCapacityFractional(duration);
	bool compoundFits = (capacity >= compound->getLengthInBits());

	if (compoundFits == true)
	{
		return true;
	}
	else
	{
		MESSAGE_BEGIN(NORMAL, logger, m, "Deferring RACH compound until next RACH phase (not enough capacity left).");
		m << " Capacity needed=" << compound->getLengthInBits();
		m << ", capacity available=" << capacity;
		MESSAGE_END();
		return false;
	}
} // doIsAccepting
Example #2
0
void
RTSCTS::doSendData(const wns::ldk::CompoundPtr& compound)
{
    assure(this->pendingMPDU == wns::ldk::CompoundPtr(),
           "Cannot have two MPDUs");
    assure(this->pendingRTS == wns::ldk::CompoundPtr(),
           "Cannot have two RTSs");

    switch(friends.manager->getFrameType(compound->getCommandPool()))
    {
    case DATA_TXOP:
        if(not this->rtsctsOnTxopData)
        {
            break;
        }
        // fall through to DATA if RTS/CTS during TXOP is activ
    case DATA:
        if(compound->getLengthInBits() < this->rtsctsThreshold)
        {
            MESSAGE_SINGLE(NORMAL, this->logger,
                           "Outgoing DATA with size " << compound->getLengthInBits() << ", below threshold");
        }
        else
        {
            MESSAGE_SINGLE(NORMAL, this->logger,
                           "Outgoing DATA with size " << compound->getLengthInBits() << "-> Save and send RTS");
            this->pendingMPDU = compound;
            this->pendingRTS = this->prepareRTS(this->pendingMPDU);

            // RTS/CTS initializes mini-TXOP for compound, it can be send
            // directly after SIFS
            friends.manager->setFrameType(this->pendingMPDU->getCommandPool(), DATA_TXOP);

            // try to send RTS
            if(getConnector()->hasAcceptor(this->pendingRTS))
            {
                state = transmitRTS;
                getConnector()->getAcceptor(compound)->sendData(this->pendingRTS);
                this->pendingRTS = wns::ldk::CompoundPtr();
            }
            return;
        }
        break;
    default:
        throw wns::Exception("Unknown frame type");
        break;
    }

    // try to send data
    if(getConnector()->hasAcceptor(compound))
    {
        getConnector()->getAcceptor(compound)->sendData(compound);
    }
    else
    {
        this->pendingMPDU = compound;
    }
}
Example #3
0
void
TxDurationSetter::processOutgoing(const wns::ldk::CompoundPtr& compound)
{
    TxDurationSetterCommand* command = activateCommand(compound->getCommandPool());
    wimemac::convergence::PhyMode phyMode = friends.manager->getPhyMode(compound->getCommandPool());

    // calculate tx duration
    wns::simulator::Time preambleTxDuration = friends.manager->getProtocolCalculator()->getDuration()->preamble(phyMode);

    if(friends.manager->isPreamble(compound->getCommandPool()))
    {
        command->local.txDuration = preambleTxDuration;

        MESSAGE_BEGIN(NORMAL, this->logger, m, "Preamble");
        m << ": duration " << command->local.txDuration;
        MESSAGE_END();
    }
    else
    {
        command->local.txDuration = friends.manager->getProtocolCalculator()->getDuration()->PSDU_PPDU(compound->getLengthInBits(), phyMode) - preambleTxDuration;
        //MESSAGE_BEGIN(VERBOSE, this->logger, m, "Outgoing Compound with size ");
        MESSAGE_BEGIN(NORMAL, this->logger, m, "Outgoing Compound with size ");
        m << compound->getLengthInBits();
        m << " with nIBP6S " << phyMode.getInfoBitsPer6Symbols();
        m << " --> duration " << friends.manager->getProtocolCalculator()->getDuration()->PSDU_PPDU(compound->getLengthInBits(), phyMode);
        m << " - " << preambleTxDuration;
        MESSAGE_END();

        MESSAGE_BEGIN(NORMAL, this->logger, m, "Command");
        m << " start " << wns::simulator::getEventScheduler()->getTime();
        m << " stop " << wns::simulator::getEventScheduler()->getTime() + command->local.txDuration;
        MESSAGE_END();

    }
}
Example #4
0
void
PhyUser::doSendData(const wns::ldk::CompoundPtr& compound)
{
    assure(compound, "sendData called with an invalid compound.");
    assure(getFUN()->getProxy()->commandIsActivated( compound->getCommandPool(), this),
           "PhyCommand not specified. PhyUser can not handle this compound!");

    // finally commit CommandPool Size
    this->commitSizes(compound->getCommandPool());

    PhyCommand* myCommand = getCommand(compound->getCommandPool());
    if (myCommand->local.modeRxTx == lte::macr::PhyCommand::Tx)
    {
        MESSAGE_SINGLE(NORMAL, logger,"doSendData(Tx): start="
            << myCommand->local.start <<"s..stop=" 
            << myCommand->local.stop <<"s => d="
            << (myCommand->local.stop-myCommand->local.start) * 1e6
            << "us, subBand=" << myCommand->local.subBand 
            << ", len="<<compound->getLengthInBits() << "bits");

        simTimeType startTime = myCommand->local.start;

        // Will call this->startTransmission at startTime
        es->schedule(StartTxEvent(compound, this), startTime);
        // Inform FUs that have added a callback that the compound is on air now
	    if (!myCommand->local.onAirCallback.empty())
	    {
		    myCommand->local.onAirCallback();
	    }
    }
    else
    { // reception (Rx)
        MESSAGE_SINGLE(NORMAL, logger,"doSendData(Rx): startTime="
            << myCommand->local.start <<", stopTime=" 
            << myCommand->local.stop << ", subBand=" 
            << myCommand->local.subBand << ", len="
            << compound->getLengthInBits() << "bits" 
            << " SHALL NOT OCCUR");

        assure(false,"Tryed to transmit while in RX mode");
    }
    // stamp link to my InterferenceCache into the Command
    myCommand->magic.remoteCache = iCache;
} // doSendData
Example #5
0
void
Manager::processOutgoing(const wns::ldk::CompoundPtr& compound)
{
    assure(getFUN()->getCommandReader(ucName_)
           ->readCommand<dll::UpperCommand>(compound->getCommandPool())
           ->peer.sourceMACAddress == myMACAddress_,
           "Try to tx compound with source address " <<
           getFUN()->getCommandReader(ucName_)
           ->readCommand<dll::UpperCommand>(compound->getCommandPool())
           ->peer.sourceMACAddress <<
           " from transceiver with MAC address " << myMACAddress_ );

    // The command has to be activated to be considered in the createReply chain
    ManagerCommand* mc = activateCommand(compound->getCommandPool());
    mc->peer.CompoundType = DATA;
    mc->peer.hasPayload = true;
    mc->peer.frameExchangeDuration = this->sifsDuration + this->expectedACKDuration;

    // Sets the phymode according to the configuration of the drpscheduler
    wns::service::dll::UnicastAddress rx = getFUN()->getCommandReader(ucName_)
           ->readCommand<dll::UpperCommand>(compound->getCommandPool())
           ->peer.targetMACAddress;
    int masNumber_ = getMASNumber(wns::simulator::getEventScheduler()->getTime());
    mc->peer.phyMode = friends.drpScheduler->getPhyMode(rx, masNumber_);
    mc->peer.psduDuration = protocolCalculator->getDuration()->MSDU_PSDU(compound->getLengthInBits(), mc->peer.phyMode);

    mcsProbe->put(mc->peer.phyMode.getDataRate() );

    if(this->msduLifetimeLimit > 0)
    {
        mc->local.expirationTime =  wns::simulator::getEventScheduler()->getTime() + this->msduLifetimeLimit;
        MESSAGE_SINGLE(NORMAL, logger_, "Outgoing command will expire at " << mc->local.expirationTime);
    }
    else
    {
        mc->local.expirationTime = 0.0;
        MESSAGE_SINGLE(NORMAL, logger_, "Outgoing command, no expiration time");
    }
}
Example #6
0
wns::ldk::CompoundPtr
RTSCTS::prepareRTS(const wns::ldk::CompoundPtr& mpdu)
{
    // Calculate duration of the mpdu for NAV setting

    wns::simulator::Time duration =
        protocolCalculator->getDuration()->MPDU_PPDU(mpdu->getLengthInBits(),
                                                     friends.manager->getPhyMode(mpdu->getCommandPool()));

    wns::simulator::Time nav =
        sifsDuration
        + maximumCTSDuration
        + sifsDuration
        + duration
        + sifsDuration
        + maximumACKDuration;

    wns::ldk::CompoundPtr rts =
        friends.manager->createCompound(friends.manager->getTransmitterAddress(mpdu->getCommandPool()),   // tx address
                                        friends.manager->getReceiverAddress(mpdu->getCommandPool()),      // rx address
                                        friends.manager->getFrameType(mpdu->getCommandPool()),            // frame type
                                        nav,               // NAV
                                        ctsTimeout);  // requires direct reply after timeout

    wns::ldk::CommandPool* rtsCP = rts->getCommandPool();
    friends.manager->setPhyMode(rtsCP, rtsctsPhyMode);
    RTSCTSCommand* rtsctsC = this->activateCommand(rtsCP);
    rtsctsC->peer.isRTS = true;

    /* set the transmission counter to the same value as the mpdu */
    friends.arq->copyTransmissionCounter(mpdu, rts);

    MESSAGE_BEGIN(NORMAL, this->logger, m, "Prepare RTS frame");
    m << " to " << friends.manager->getReceiverAddress(rtsCP);
    m << " with NAV " << nav;
    MESSAGE_END();

    return(rts);
}
Example #7
0
bool
RTSCTS::doIsAccepting(const wns::ldk::CompoundPtr& compound) const
{
    switch(friends.manager->getFrameType(compound->getCommandPool()))
    {
    case DATA_TXOP:
        if(not this->rtsctsOnTxopData)
        {
            return(getConnector()->hasAcceptor(compound));
        }
    case DATA:
        if(compound->getLengthInBits() < this->rtsctsThreshold)
        {
            return(getConnector()->hasAcceptor(compound));
        }
        else
        {
            return (this->pendingMPDU == wns::ldk::CompoundPtr());
        }
    default:
        throw wns::Exception("Unknown frame type");
        break;
    }
}
Example #8
0
void
PhyUser::startTransmission(const wns::ldk::CompoundPtr& compound)
{
    assure(getFUN()->getProxy()->commandIsActivated( compound->getCommandPool(), this),
           "PhyCommand not specified. PhyUser can not handle this compound!");

    PhyCommand* myCommand = getCommand(compound->getCommandPool());

    MESSAGE_SINGLE(NORMAL, logger,"startTransmission(): start="
        << myCommand->local.start 
        << "s..stop=" << myCommand->local.stop 
        << "s => d=" << myCommand->local.stop-myCommand->local.start
        << "s, subBand=" << myCommand->local.subBand);

    wns::Power txPower = myCommand->magic.txp;

    int subBand = myCommand->local.subBand;
    int beam = myCommand->local.beam;
    wns::service::phy::phymode::PhyModeInterfacePtr phyModePtr = myCommand->local.phyModePtr;

    // duration should be multiple of OFDM symbol length
    simTimeType duration = myCommand->local.stop - myCommand->local.start; 

    assure(myCommand->local.start == es->getTime(), "myCommand->local.start is not now");
    assure(phyModePtr->dataRateIsValid(), "!dataRateIsValid for " << *phyModePtr);

    int capacity = phyModePtr->getBitCapacityFractional(duration);

    MESSAGE_SINGLE(NORMAL, logger,"PhyMode=" << *phyModePtr
        << " supports " << phyModePtr->getBitCapacityFractional(1.0)
        << " bit/s/subChannel");

    MESSAGE_BEGIN(NORMAL, logger, m, "startTransmission on subBand=");
        m << subBand
          << ", PhyMode=" << *phyModePtr
          << ", D=" << duration*1e6 << "us"
          << ", " << compound->getLengthInBits() << " bit"
          << ", cap=" << capacity << " bit"
          << ", source=" << myCommand->magic.source->getName()
          << ", dest=" << (myCommand->magic.destination == NULL ? "BROADCAST" : myCommand->magic.destination->getName())
          << ", P=" << txPower;
    MESSAGE_END();

    assure(compound->getLengthInBits() <= capacity , "SDU too long: len="<<compound->getLengthInBits()
        << " <= cap="<<capacity
        << " ("<<phyModePtr->getString()
        << ", D="<<duration<<"s)");

    if (myCommand->magic.destination == 0 || sendAllBroadcast) 
    {
        // no destination, send broadcast
        assure(beam==0,"broadcast is only possible with beam==0, but beam="<<beam);
        transmission->startBroadcast(compound, subBand, txPower, phyModePtr);
    } 
    else 
    {
        // we have a destination, this is not a broadcast
        if (myCommand->local.beamforming == true)
        {
            assure(myCommand->local.pattern, "No Beamforming Pattern set.");
            // call startTransmission method of dataTransmission service
            // which is located in WNS/service/phy/ofdma/Station.cpp: Station::startTransmission
            bfTransmission->startTransmission(compound,
                                              myCommand->magic.destination,
                                              subBand,
                                              myCommand->local.pattern,
                                              txPower,
                                              phyModePtr);
        } 
        else 
        {
            transmission->startUnicast(compound,
                                       myCommand->magic.destination,
                                       subBand,
                                       txPower,
                                       phyModePtr);
        }
    }
    activeSubBands.push_back( std::pair<wns::osi::PDUPtr, int>(compound, subBand) );
    // prepare the stopEvent
    es->schedule(StopTxEvent(compound, subBand, this), myCommand->local.stop-safetyFraction);
} // startTransmission