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
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; } }
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(); } }
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
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"); } }
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); }
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; } }
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