예제 #1
0
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");
        }
    }
}
예제 #2
0
파일: PhyUser.cpp 프로젝트: openwns/wimac
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);
}
예제 #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();

    }
}
예제 #4
0
파일: PhyUser.cpp 프로젝트: openwns/lte
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);
}
예제 #5
0
파일: HopCount.hpp 프로젝트: openwns/lte
	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);
	    }
	}
예제 #6
0
파일: RACH.cpp 프로젝트: openwns/lte
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");

}
예제 #7
0
파일: RTSCTS.cpp 프로젝트: openwns/wifimac
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);
}
예제 #8
0
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 );
}
예제 #9
0
파일: RTSCTS.cpp 프로젝트: openwns/wifimac
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();
    }
}
예제 #10
0
void BSRelayMapper::processOutgoing( const wns::ldk::CompoundPtr& compound )
{
    RelayMapperCommand* command = dynamic_cast<RelayMapperCommand*>
        (getFUN()->getProxy()->activateCommand( compound->getCommandPool(), this ));

    command->peer.direction_ =
        RelayMapperCommand::Down;
}
예제 #11
0
파일: RTSCTS.cpp 프로젝트: openwns/wifimac
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;
    }
}
예제 #12
0
파일: PhyUser.cpp 프로젝트: openwns/wimac
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();
}
예제 #13
0
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);
}
예제 #14
0
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.");
}
예제 #15
0
파일: PhyUser.cpp 프로젝트: openwns/lte
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
예제 #16
0
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);
    }
}
예제 #17
0
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;
    }
}
예제 #18
0
	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
예제 #19
0
파일: RTSCTS.cpp 프로젝트: openwns/wifimac
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);
}
예제 #20
0
파일: Manager.cpp 프로젝트: openwns/wimemac
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");
    }
}
예제 #21
0
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); 
}
예제 #22
0
파일: PhyUser.cpp 프로젝트: openwns/wimac
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);
}
예제 #23
0
파일: eNB.cpp 프로젝트: openwns/lte
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
예제 #24
0
파일: RTSCTS.cpp 프로젝트: openwns/wifimac
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;
    }
}
예제 #25
0
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(&lte::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!");
}
예제 #26
0
파일: PhyUser.cpp 프로젝트: openwns/wimac
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;
}
예제 #27
0
파일: eNB.cpp 프로젝트: openwns/lte
void
ENBRLC::processIncoming(const wns::ldk::CompoundPtr& compound)
{
    lte::rlc::RLCCommand* command = getCommand(compound->getCommandPool());
    command->rang.flowID =  friends.flowswitching->getFlowIDout(command->peer.flowID);
} // processIncoming
예제 #28
0
bool
FilterTxOPType::filter(const wns::ldk::CompoundPtr& compound) const
{
    return(this->commandReader->readCommand<wimemac::IKnowsFrameTypeCommand>(compound->getCommandPool())->getCompoundType() == this->acceptingTxOPType);
}
예제 #29
0
파일: PhyUser.cpp 프로젝트: openwns/lte
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
예제 #30
0
파일: RTSCTS.cpp 프로젝트: openwns/wifimac
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");
            }
        }
    }
}