void DuplicateFilter::doOnData(const wns::ldk::CompoundPtr& compound) { // retransmission, check sequence number DuplicateFilterCommand* command = getCommand(compound); if(not lastReceivedSN.knows(friends.manager->getTransmitterAddress(compound->getCommandPool()))) { // first compound from source MESSAGE_SINGLE(NORMAL, logger, "Received first frame from " << friends.manager->getTransmitterAddress(compound->getCommandPool()) << " -> deliver"); lastReceivedSN.insert(friends.manager->getTransmitterAddress(compound->getCommandPool()), command->peer.sn); getDeliverer()->getAcceptor(compound)->onData(compound); } else { if(lastReceivedSN.find(friends.manager->getTransmitterAddress(compound->getCommandPool())) != command->peer.sn) { // compound has different sn MESSAGE_SINGLE(NORMAL, logger, "Received frame from " << friends.manager->getTransmitterAddress(compound->getCommandPool()) << " with unknown sn -> deliver"); getDeliverer()->getAcceptor(compound)->onData(compound); lastReceivedSN.update(friends.manager->getTransmitterAddress(compound->getCommandPool()), command->peer.sn); } else { MESSAGE_SINGLE(NORMAL, logger, "Received duplicate frame from " << friends.manager->getTransmitterAddress(compound->getCommandPool()) << " -> drop"); } } }
void PhyUser::doOnData(const wns::ldk::CompoundPtr& compound) { assure(compound, "doOnData called with an invalid compound."); PhyUserCommand* puCommand = getCommand( compound->getCommandPool() ); LOG_INFO( getFUN()->getName(), ": doOnData source: ", puCommand->peer.source_->getName(), " C/I = ", puCommand->local.rxPower_, " / ", puCommand->local.interference_, " = ", getCommand( compound->getCommandPool() )->magic.rxMeasurement->getSINR() ); if(puCommand->peer.estimatedCQI.interference.get_mW() > 0) { LOG_INFO( "estimated C/I = ", puCommand->peer.estimatedCQI.carrier, " / ", puCommand->peer.estimatedCQI.interference, " = " , puCommand->peer.estimatedCQI.carrier / puCommand->peer.estimatedCQI.interference, "\n estimated intra-cell interference: ", puCommand->getEstimatedIintra() ); double delta_SINR = (getCommand( compound->getCommandPool() )->magic.rxMeasurement->getSINR().get_factor()) - (puCommand->peer.estimatedCQI.carrier / puCommand->peer.estimatedCQI.interference).get_factor(); if(abs(delta_SINR) > 0.001) { LOG_INFO( "Delta C / I: ", delta_SINR); }else{ LOG_INFO("abs(Delta C / I) < 0.001 "); } } else{ LOG_INFO( "estimated C/I = ", puCommand->peer.estimatedCQI.carrier, " / ", puCommand->peer.estimatedCQI.interference, "\n estimated intra-cell interference: ", puCommand->getEstimatedIintra() ); } getDeliverer()->getAcceptor(compound)->onData(compound); }
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 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 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 PhyUser::traceIncoming(wns::ldk::CompoundPtr compound, wns::service::phy::power::PowerMeasurementPtr rxPowerMeasurement) { wns::probe::bus::json::Object objdoc; PhyCommand* myCommand = getCommand(compound->getCommandPool()); objdoc["Transmission"]["ReceiverID"] = wns::probe::bus::json::String(getFUN()->getLayer()->getNodeName()); objdoc["Transmission"]["SenderID"] = wns::probe::bus::json::String(myCommand->magic.source->getName()); objdoc["Transmission"]["SourceID"] = wns::probe::bus::json::String(myCommand->magic.source->getName()); if(myCommand->magic.destination == NULL) { objdoc["Transmission"]["DestinationID"] = wns::probe::bus::json::String("Broadcast"); } else { objdoc["Transmission"]["DestinationID"] = wns::probe::bus::json::String(myCommand->magic.destination->getName()); } objdoc["Transmission"]["Start"] = wns::probe::bus::json::Number(myCommand->local.start); objdoc["Transmission"]["Stop"] = wns::probe::bus::json::Number(myCommand->local.stop); objdoc["Transmission"]["Subchannel"] = wns::probe::bus::json::Number(myCommand->local.subBand); objdoc["Transmission"]["TxPower"] = wns::probe::bus::json::Number(myCommand->magic.txp.get_dBm()); objdoc["Transmission"]["RxPower"] = wns::probe::bus::json::Number(rxPowerMeasurement->getRxPower().get_dBm()); objdoc["Transmission"]["InterferencePower"] = wns::probe::bus::json::Number(rxPowerMeasurement->getInterferencePower().get_dBm()); if (myCommand->magic.estimatedSINR.carrier != wns::Power() && myCommand->magic.estimatedSINR.interference != wns::Power()) { objdoc["SINREst"]["C"] = wns::probe::bus::json::Number(myCommand->magic.estimatedSINR.carrier.get_dBm()); objdoc["SINREst"]["I"] = wns::probe::bus::json::Number(myCommand->magic.estimatedSINR.interference.get_dBm()); } if (schedulerCommandReader_->commandIsActivated(compound->getCommandPool())) { // Now we have a look at the scheduling time slot lte::timing::SchedulerCommand* schedCommand = schedulerCommandReader_->readCommand<lte::timing::SchedulerCommand>(compound->getCommandPool()); wns::scheduler::SchedulingTimeSlotPtr ts = schedCommand->magic.schedulingTimeSlotPtr; wns::probe::bus::json::Array a; for (wns::scheduler::PhysicalResourceBlockVector::iterator it= ts->physicalResources.begin(); it != ts->physicalResources.end(); ++it) { wns::probe::bus::json::Object pr; pr["NetBits"] = wns::probe::bus::json::Number(it->getNetBlockSizeInBits()); a.Insert(pr); } objdoc["SchedulingTimeSlot"]["PhysicalResources"] = a; objdoc["SchedulingTimeSlot"]["HARQ"]["enabled"] = wns::probe::bus::json::Boolean(ts->isHARQEnabled()); objdoc["SchedulingTimeSlot"]["HARQ"]["ProcessID"] = wns::probe::bus::json::Number(ts->harq.processID); objdoc["SchedulingTimeSlot"]["HARQ"]["NDI"] = wns::probe::bus::json::Boolean(ts->harq.NDI); objdoc["SchedulingTimeSlot"]["HARQ"]["TransportBlockID"] = wns::probe::bus::json::Number(ts->harq.transportBlockID); objdoc["SchedulingTimeSlot"]["HARQ"]["RetryCounter"] = wns::probe::bus::json::Number(ts->harq.retryCounter); } wns::probe::bus::json::probeJSON(jsonTracingCC_, objdoc); }
virtual void doVisit(wns::probe::bus::IContext& c, const wns::ldk::CompoundPtr& compound) const { assure(compound, "Received NULL CompoundPtr"); if (macgCommandReader->commandIsActivated(compound->getCommandPool()) == true) { int hopCount = macgCommandReader->readCommand<lte::macg::MACgCommand>(compound->getCommandPool())->magic.hopCount; assure(hopCount >= 1, "number of hops must be >=1, but it is " << hopCount); assure(hopCount <= 2, "number of hops must be <=2, but it is " << hopCount); c.insertInt(this->key, hopCount); } }
wns::ldk::CompoundPtr RTSCTS::prepareCTS(const wns::ldk::CompoundPtr& rts) { wns::ldk::CommandPool* rtsCP = rts->getCommandPool(); // calculate nav from rts wns::simulator::Time nav = friends.manager->getFrameExchangeDuration(rtsCP) - sifsDuration - maximumCTSDuration; wns::ldk::CompoundPtr cts = friends.manager->createCompound(friends.manager->getReceiverAddress(rtsCP), friends.manager->getTransmitterAddress(rtsCP), ACK, nav, sifsDuration + preambleProcessingDelay); friends.manager->setPhyMode(cts->getCommandPool(), rtsctsPhyMode); RTSCTSCommand* rtsctsC = this->activateCommand(cts->getCommandPool()); rtsctsC->peer.isRTS = false; MESSAGE_BEGIN(NORMAL, this->logger, m, "Prepare CTS frame"); m << " to " << friends.manager->getTransmitterAddress(rtsCP); m << " with NAV " << nav; MESSAGE_END(); this->ctsPrepared = wns::simulator::getEventScheduler()->getTime(); return(cts); }
void RACHUT::doSendData(const wns::ldk::CompoundPtr& compound) { // set PhyUser Command lte::macr::PhyCommand* phyCommand = dynamic_cast<lte::macr::PhyCommand*>( getFUN()->getProxy()->activateCommand( compound->getCommandPool(), friends.phyUser )); simTimeType startTime = wns::simulator::getEventScheduler()->getTime(); // now phyCommand->local.beamforming = false; phyCommand->local.pattern = wns::service::phy::ofdma::PatternPtr(); // NULL Pointer phyCommand->local.start = startTime; phyCommand->local.stop = stopTime; phyCommand->local.subBand = subBandCounter++; phyCommand->local.modeRxTx = lte::macr::PhyCommand::Tx; phyCommand->local.phyModePtr = phyModePtr; phyCommand->magic.destination = NULL; phyCommand->magic.source = getFUN()->getLayer<dll::ILayer2*>()->getNode(); phyCommand->magic.txp = txPower; if (getConnector()->hasAcceptor(compound)){ assure(phyModePtr->dataRateIsValid(),"invalid PhyMode dataRate"); MESSAGE_SINGLE(NORMAL, logger, "sent RACH compound ("<< *phyModePtr <<")"); getConnector()->getAcceptor(compound)->sendData(compound); } else assure(false, "Lower FU is not accepting scheduled PDU but is supposed to do so"); }
void FrameHeadCollector::doOnData( const wns::ldk::CompoundPtr& compound ) { FrameHeadCommand* command = getCommand( compound->getCommandPool() ); LOG_INFO( getFUN()->getLayer()->getName(), ": received FCH from station:",command->peer.baseStationID); if(channelQualityObserver_) { PhyUserCommand* phyCommand = phyUser_->getCommand(compound->getCommandPool()); channelQualityObserver_->storeMeasurement(command->peer.baseStationID, phyCommand->magic.rxMeasurement); } getFrameBuilder()->getTimingControl()->finishedPhase( this ); }
void BSRelayMapper::processOutgoing( const wns::ldk::CompoundPtr& compound ) { RelayMapperCommand* command = dynamic_cast<RelayMapperCommand*> (getFUN()->getProxy()->activateCommand( compound->getCommandPool(), this )); command->peer.direction_ = RelayMapperCommand::Down; }
void RTSCTS::onTxEnd(const wns::ldk::CompoundPtr& compound) { if(this->pendingMPDU and (getFUN()->getProxy()->commandIsActivated(compound->getCommandPool(), this)) and (getCommand(compound->getCommandPool())->peer.isRTS) and (state == transmitRTS)) { state = waitForCTS; setNewTimeout(ctsTimeout); MESSAGE_BEGIN(NORMAL, logger, m, "RTS to "); m << friends.manager->getReceiverAddress(compound->getCommandPool()); m << " is sent, waiting for CTS for "; m << ctsTimeout; MESSAGE_END(); } }
void DuplicateFilter::doSendData(const wns::ldk::CompoundPtr& compound) { // add duplicate filter command DuplicateFilterCommand* command = activateCommand(compound->getCommandPool()); command->peer.sn = nextSN; ++nextSN; getConnector()->getAcceptor(compound)->sendData(compound); }
void PhyUser::doSendData(const wns::ldk::CompoundPtr& compound) { COMMANDTYPE* command = getCommand( compound->getCommandPool() ); LOG_INFO( getFUN()->getName(), ": doSendData" ); (*command->local.pAFunc_.get())( this, compound ); int macaddr = address.getInteger(); }
void RSRelayMapper::processOutgoing( const wns::ldk::CompoundPtr& #ifndef NDEBUG compound #endif ) { assure(getFUN()->getProxy()->commandIsActivated(compound->getCommandPool(), this), "RelayMapper Command should be activated for outgoing compounds."); }
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 BeaconBuilder::doOnData( const wns::ldk::CompoundPtr& compound ) { wns::ldk::CommandPool* commandPool = compound->getCommandPool(); wns::service::dll::UnicastAddress iam = getFUN()->findFriend<dll::UpperConvergence*>("upperConvergence")->getMACAddress(); dll::UpperCommand* uc = friends.keyReader->readCommand<dll::UpperCommand>(commandPool); wns::service::dll::UnicastAddress tx = uc->peer.sourceMACAddress; //evaluate beacon, only Beacon Command is necessary if(tx != iam) { BeaconEvaluator::BeaconExamination(tx, iam, getCommand(compound->getCommandPool()),logger); } }
bool HARQReceiverProcess::decodeReceivedTransportBlock(wns::ldk::CompoundPtr transportBlockRedundancyVersion, imtaphy::interface::TransmissionStatusPtr status) { ltea::mac::DownlinkControlInformation* dci = entity_->getDCIReader()->readCommand<ltea::mac::DownlinkControlInformation>(transportBlockRedundancyVersion->getCommandPool()); MESSAGE_BEGIN(NORMAL, logger_, m, "HarqReceiverProcess::receive processID = " << processID_); m << ", RV = " << dci->peer.rv << ", TransmissionAttempt=" << dci->magic.transmissionAttempts << " NDI= " << dci->peer.NDI; MESSAGE_END(); if (dci->peer.NDI) { receptionBuffer_.clear(); } if (dci->magic.ackCallback.empty()) { std::cout << "Tried to decode resource block with empty ack callback" << std::endl; exit(1); } if (dci->magic.nackCallback.empty()) { std::cout << "Tried to decode resource block with empty nack callback" << std::endl; exit(1); } receptionBuffer_.push_back(std::make_pair<wns::ldk::CompoundPtr, imtaphy::interface::TransmissionStatusPtr>(transportBlockRedundancyVersion, status)); if(entity_->getDecoder()->canDecode(receptionBuffer_)) { MESSAGE_SINGLE(NORMAL, logger_, "HARQReceiver processID=" << processID_ << " sucessful decoded"); receptionBuffer_.clear(); // send magic ACK feedback to sending process dci->magic.ackCallback(); return true; } else { MESSAGE_SINGLE(NORMAL, logger_, "HARQReceiver processID=" << processID_ << " failed to decode" << " Transmission attempt: " << dci->magic.transmissionAttempts); // send magic NACK feedback to sending process dci->magic.nackCallback(); return false; } }
wns::ldk::CompoundPtr SelectiveRepeatFSMTest::createACKFrame(wns::ldk::CompoundPtr receivedCompound) { SelectiveRepeatCommand* receivedPCI = arq->getCommand(receivedCompound->getCommandPool()); wns::ldk::CompoundPtr compound(fun->createCompound()); SelectiveRepeatCommand* command = arq->activateCommand(compound->getCommandPool()); command->peer.type = SelectiveRepeatCommand::ACK; command->peer.NS = receivedPCI->peer.NS; return compound; } // createACKFrame
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; } }
RadioBearerID::RadioBearerID(const RadioBearerIDBuilder* factory, const wns::ldk::CompoundPtr& compound) { wns::ldk::CommandPool* commandPool = compound->getCommandPool(); dll::UpperCommand* pdcpCommand = factory->friends.pdcpReader->readCommand<dll::UpperCommand>(commandPool); // TODO: move pdcpCommand to own class that includes a EPS/radio bearer size_t hash = 0; // the hash value (ID) should be the same regardless of the direction -> min/max boost::hash_combine(hash, std::min(pdcpCommand->peer.sourceMACAddress.getInteger(), pdcpCommand->peer.targetMACAddress.getInteger())); boost::hash_combine(hash, std::max(pdcpCommand->peer.sourceMACAddress.getInteger(), pdcpCommand->peer.targetMACAddress.getInteger())); // basically casting unsigned to signed int but as long as it is still unique // negative flowIDs should not make a difference radioBearerID = -static_cast<wns::service::dll::FlowID>(hash); }
void PhyUser::traceIncoming(wns::ldk::CompoundPtr compound, wns::service::phy::power::PowerMeasurementPtr rxPowerMeasurement) { wns::probe::bus::json::Object objdoc; PhyUserCommand* myCommand = getCommand(compound->getCommandPool()); objdoc["Transmission"]["ReceiverID"] = wns::probe::bus::json::String(getFUN()->getLayer()->getNodeName()); objdoc["Transmission"]["SenderID"] = wns::probe::bus::json::String(myCommand->peer.source_->getName()); objdoc["Transmission"]["SourceID"] = wns::probe::bus::json::String(myCommand->peer.source_->getName()); if(myCommand->peer.destination_ == NULL) { objdoc["Transmission"]["DestinationID"] = wns::probe::bus::json::String("Broadcast"); } else { objdoc["Transmission"]["DestinationID"] = wns::probe::bus::json::String(myCommand->peer.destination_->getName()); } objdoc["Transmission"]["Start"] = wns::probe::bus::json::Number(myCommand->local.pAFunc_->transmissionStart_); objdoc["Transmission"]["Stop"] = wns::probe::bus::json::Number(myCommand->local.pAFunc_->transmissionStop_); objdoc["Transmission"]["Subchannel"] = wns::probe::bus::json::Number(myCommand->local.pAFunc_->subBand_); objdoc["Transmission"]["TxPower"] = wns::probe::bus::json::Number(rxPowerMeasurement->getTxPower().get_dBm()); objdoc["Transmission"]["RxPower"] = wns::probe::bus::json::Number(rxPowerMeasurement->getRxPower().get_dBm()); objdoc["Transmission"]["InterferencePower"] = wns::probe::bus::json::Number(rxPowerMeasurement->getInterferencePower().get_dBm()); if (myCommand->peer.estimatedCQI.carrier != wns::Power() && myCommand->peer.estimatedCQI.interference != wns::Power()) { objdoc["SINREst"]["C"] = wns::probe::bus::json::Number(myCommand->peer.estimatedCQI.carrier.get_dBm()); objdoc["SINREst"]["I"] = wns::probe::bus::json::Number(myCommand->peer.estimatedCQI.interference.get_dBm()); } wns::probe::bus::json::probeJSON(probes_.jsonTracing, objdoc); }
void ENBRLC::processOutgoing(const wns::ldk::CompoundPtr& compound) { assure(upperConvergenceReader, "No reader for upper convergence set!"); dll::UpperCommand* upper = upperConvergenceReader->readCommand<dll::UpperCommand>(compound->getCommandPool()); assure(upper, "Erroneous Upper Convergence Command!"); RLCCommand* command = activateCommand(compound->getCommandPool()); wns::service::dll::FlowID flowID = friends.flowswitching->getFlowIDin(upper->local.dllFlowID /* RANG-to-BS */); wns::service::qos::QoSClass qosClass = friends.flowswitching->getQoSClassForBSFlowID(flowID); command->local.direction = PacketDirection::DOWNLINK(); command->peer.source = getFUN()->getLayer<dll::ILayer2*>()->getDLLAddress(); command->peer.destination = upper->peer.targetMACAddress; MESSAGE_SINGLE(NORMAL, logger, "processOutgoing(): incoming FlowID(DL)="<<upper->local.dllFlowID<<", outgoing FlowID="<<flowID<<", QoS="<<lte::helper::QoSClasses::toString(qosClass)); command->peer.qosClass = qosClass; command->peer.flowID = flowID; command->rang.flowID = 0; } // processOutgoing
bool Manager::doIsAccepting(const wns::ldk::CompoundPtr& compound) const { wns::ldk::CompoundPtr compound2send = compound->copy(); // The command has to be activated to be considered in the createReply chain ManagerCommand* mc = activateCommand(compound2send->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>(compound2send->getCommandPool()) ->peer.targetMACAddress; //int masNumber_ = this->getMASNumber(wns::simulator::getEventScheduler()->getTime()); //mc->peer.phyMode = friends.drpScheduler->getPhyMode(rx, masNumber_); mc->peer.phyMode = friends.drpScheduler->getPhyMode(rx, -1); //return getConnector()->hasAcceptor(compound2send); return (wns::ldk::Processor<Manager>::doIsAccepting(compound2send)); }
void AssociationHandlerBS::doOnData(const wns::ldk::CompoundPtr& compound) { lte::controlplane::associationHandler::AssociationCommand* incomingCommand = getCommand(compound->getCommandPool()); wns::service::dll::UnicastAddress sendingTo = incomingCommand->peer.dst; if (!(sendingTo == layer2->getDLLAddress())) return; wns::service::dll::UnicastAddress comingFrom = incomingCommand->peer.src; if(incomingCommand->peer.myCompoundType == CompoundType::association_req()) { MESSAGE_BEGIN(NORMAL, logger, m, "Received "); m << incomingCommand->peer.mode << separator << "association_req from " << layer2->getStationManager()->getStationByMAC(incomingCommand->peer.src)->getName(); MESSAGE_END(); //safe the new users duplex group duplexGroups[incomingCommand->peer.user] = incomingCommand->peer.duplexGroup; MESSAGE_SINGLE(NORMAL, logger, "Stored duplex group=" << duplexGroups[incomingCommand->peer.user] << " for user="******"received "); m << incomingCommand->peer.mode << separator << "disassociation_req from DLL address " << incomingCommand->peer.src; MESSAGE_END(); bool preserve = false; if ((incomingCommand->peer.targetRAP).isValid()) preserve = associationsProxy->inMyREC(incomingCommand->peer.targetRAP); // inform AssociationsProxy associationsProxy->disassociatedPerMode(incomingCommand->peer.user, incomingCommand->peer.targetRAP, incomingCommand->peer.mode); if(incomingCommand->peer.user == comingFrom) // UT to BS (directly) { // directly dll::ILayer2* ut = layer2->getStationManager()->getStationByMAC(incomingCommand->peer.user); //dll::ILayer2* ut = layer2->getStationManager()->getStationByMAC(incomingCommand->peer.user); associationService->releaseClient(ut); boost::function<void()> callback; callback = boost::bind(<e::controlplane::associationHandler::AssociationHandler::notifyOnDisassociated, this, incomingCommand->peer.user, layer2->getDLLAddress()); connector->activate(friends.cpDispatcher); createDisassociation_ack(comingFrom, incomingCommand->peer.user, preserve, mode, callback); } else // forwarded via a RN (UT->RN->BS) { // notify observers notifyOnDisassociated(incomingCommand->peer.user, comingFrom); boost::function<void()> callback; connector->activate(friends.cpDispatcher); createDisassociation_ack(comingFrom, incomingCommand->peer.user, preserve, incomingCommand->peer.mode, callback); } } else assure(false, "received association compound with wrong type!"); }
bool PhyUser::filter( const wns::ldk::CompoundPtr& compound) { PhyUserCommand* phyCommand = getCommand( compound->getCommandPool() ); // reject own compounds if ( phyCommand->peer.source_ == friends_.layer->getNode() ) return false; // SS should receive all broadcasts if( friends_.layer->getStationType() != wns::service::dll::StationTypes::AP() ) { ConnectionIdentifier::Ptr rngCI; rngCI = friends_.connectionManager->getConnectionWithID(0); if(rngCI == NULL) { if(phyCommand->magic.frameHead_) { // Receive frame head from other BSs while not associated return true; } else { // Do not receive other broadcasts like MAPs return false; } } if ( !phyCommand->peer.destination_ //broadcast && ( phyCommand->magic.sourceComponent_->getID() == rngCI->baseStation_ ) // from our BaseStation ) { return true; } } // Receive all compounds for us if ( phyCommand->peer.destination_ ) //no broadcast { if ( phyCommand->peer.destination_ == friends_.layer->getNode() ) //for us { // return true; wns::ldk::ClassifierCommand* cCommand; cCommand = friends_.connectionClassifier->getCommand(compound->getCommandPool()); if( (friends_.connectionManager->getConnectionWithID(cCommand->peer.id)) || (cCommand->peer.id == 0) ) { //Only receive compounds for a registered CID ///ToDo: (gra) This isn't a good behavoir and the wrong ///place for it. Compounds for an outdated / delted ///ConnectionIdentifier shouldn't be sent. ///It could happen, if the subscriber station does a ///reset and delete all ConnectionIdentifier. The base ///station doesn't know it and sends compounds on the old ///ConnectionIdentifiers. return true; } } else // probe interference in BS { // Currently only OFDM is supported so only subChannel 0 is used if(friends_.layer->getStationType() == wns::service::dll::StationTypes::AP() && phyCommand->local.pAFunc_->timeSlot_ >= 0 && phyCommand->local.pAFunc_->subBand_ == 0) { int slot = phyCommand->local.pAFunc_->timeSlot_; wns::Power rxPower = phyCommand->magic.rxMeasurement->getRxPower(); if(slot != lastInterferenceSlot) { if(lastInterferenceSlot >= 0) { LOG_INFO( "Storing interference for slot: ", lastInterferenceSlot, " ", interferenceForSlot); friends_.layer->getManagementService<service::InterferenceCache>( "interferenceCache")->storeInterference(friends_.layer->getNode(), interferenceForSlot, service::InterferenceCache::Local, lastInterferenceSlot); } lastInterferenceSlot = slot; interferenceForSlot = wns::Power::from_dBm(-200.0); } interferenceForSlot += rxPower; LOG_INFO( "Added interference from: ", phyCommand->peer.source_->getName(), " ", rxPower, " total in slot ", slot, " is ", interferenceForSlot); } } } return false; }
bool FilterTxOPType::filter(const wns::ldk::CompoundPtr& compound) const { return(this->commandReader->readCommand<wimemac::IKnowsFrameTypeCommand>(compound->getCommandPool())->getCompoundType() == this->acceptingTxOPType); }
void RTSCTS::doOnData(const wns::ldk::CompoundPtr& compound) { if(not getFUN()->getProxy()->commandIsActivated(compound->getCommandPool(), this)) { // deliver frame MESSAGE_SINGLE(NORMAL, this->logger, "Received frame -> deliver"); getDeliverer()->getAcceptor(compound)->onData(compound); return; } // no RTSCTS command if(getCommand(compound->getCommandPool())->peer.isRTS) { if(nav) { if(friends.manager->getTransmitterAddress(compound->getCommandPool()) == navSetter) { MESSAGE_BEGIN(NORMAL, this->logger, m, "Incoming RTS from "); m << friends.manager->getTransmitterAddress(compound->getCommandPool()); m << ", nav busy from " << navSetter; m << " -> reply with CTS"; MESSAGE_END(); assure(this->pendingCTS == wns::ldk::CompoundPtr(), "Old pending CTS not transmitted"); this->pendingCTS = this->prepareCTS(compound); } else { MESSAGE_BEGIN(NORMAL, this->logger, m, "Incoming RTS from "); m << friends.manager->getTransmitterAddress(compound->getCommandPool()); m << ", nav busy from " << navSetter; m << " -> Drop"; MESSAGE_END(); return; } } else { MESSAGE_SINGLE(NORMAL, this->logger, "Incoming RTS, nav idle -> reply with CTS"); assure(this->pendingCTS == wns::ldk::CompoundPtr(), "Old pending CTS not transmitted"); this->pendingCTS = this->prepareCTS(compound); } // try to send CTS assure(this->pendingCTS, "CTS should be pending now"); if(getConnector()->hasAcceptor(this->pendingCTS)) { getConnector()->getAcceptor(this->pendingCTS)->sendData(this->pendingCTS); this->pendingCTS = wns::ldk::CompoundPtr(); } else { throw wns::Exception("pending CTS is not accepted"); } } // is RTS else { // received CTS on transmitted RTS --> successfully reserved the channel // for data assure(this->pendingMPDU, "Received CTS, but no pending MPDU"); if(state != receptionFinished) { MESSAGE_BEGIN(NORMAL, this->logger, m, "received CTS although state is not receptionFinished, now: "); m << wns::simulator::getEventScheduler()->getTime(); m << ", last timeout: " << this->lastTimeout << "\n"; if(state == transmitRTS) m << "state is transmitRTS\n"; if(state == waitForCTS) m << "state is waitForCTS\n"; if(state == receiveCTS) m << "state is receiveCTS\n"; if(state == idle) m << "state is idle\n"; MESSAGE_END(); } assure(state == receptionFinished, "received CTS although state is idle, now: " << wns::simulator::getEventScheduler()->getTime() << ", last timeout: " << this->lastTimeout); if(friends.manager->getTransmitterAddress(compound->getCommandPool()) != friends.manager->getReceiverAddress(this->pendingMPDU->getCommandPool())) { MESSAGE_SINGLE(NORMAL, this->logger, "Incoming CTS does not match the receiver's address on the pending MPDU -> do nothing"); return; } else { assure(this->pendingMPDU, "Received CTS, but no pendingMPDU"); MESSAGE_SINGLE(NORMAL, this->logger, "Received CTS, sending MPDU to "<< friends.manager->getReceiverAddress(this->pendingMPDU->getCommandPool())); rtsSuccessProbe->put(this->pendingMPDU, 1); state = idle; if(this->hasTimeoutSet()) { this->cancelTimeout(); } if(getConnector()->hasAcceptor(this->pendingMPDU)) { getConnector()->getAcceptor(this->pendingMPDU)->sendData(this->pendingMPDU->copy()); this->pendingMPDU = wns::ldk::CompoundPtr(); // ready for new MPDU getReceptor()->wakeup(); } else { throw wns::Exception("pending MPDU is not accepted"); } } } }