Classes | Public Types | Public Member Functions | Protected Types | Protected Member Functions | Protected Attributes

BaseDecider Class Reference
[decider - decider modulesbaseModules - base module classes of MiXiM]

Provides some base functionality for most common deciders. More...

#include <BaseDecider.h>

Inherits Decider.

Inherited by Decider80211, Decider802154Narrow, and SNRThresholdDecider.

Collaboration diagram for BaseDecider:
Collaboration graph
[legend]

List of all members.

Classes

struct  CSRInfo
 Data about an currently ongoing ChannelSenseRequest. More...

Public Types

enum  BaseDeciderControlKinds { PACKET_DROPPED = 22100, LAST_BASE_DECIDER_CONTROL_KIND }
 

The kinds of ControlMessages this Decider sends.

More...

Public Member Functions

 BaseDecider (DeciderToPhyInterface *phy, double sensitivity, int myIndex, bool debug)
 Initializes the decider with the passed values.
virtual simtime_t processSignal (AirFrame *frame)
 Processes an AirFrame given by the PhyLayer.
virtual ChannelState getChannelState ()
 A function that returns information about the channel state.
virtual simtime_t handleChannelSenseRequest (ChannelSenseRequest *request)
 This function is called by the PhyLayer to hand over a ChannelSenseRequest.

Protected Types

enum  SignalState { NEW, EXPECT_HEADER, EXPECT_END }
 

The current state of processing for a signal.

More...
typedef std::pair< AirFrame
*, int > 
ReceivedSignal
 Pair of a AirFrame and the state it is in.

Protected Member Functions

virtual simtime_t processNewSignal (AirFrame *frame)
 Processes a new Signal. Returns the time it wants to handle the signal again.
virtual simtime_t processSignalHeader (AirFrame *frame)
 Processes the end of the header of a received Signal.
virtual simtime_t processSignalEnd (AirFrame *frame)
 Processes the end of a received Signal.
virtual simtime_t processUnknownSignal (AirFrame *frame)
 Processes any Signal for which no state could be found. (is an error case).
virtual int getSignalState (AirFrame *frame)
 Returns the SignalState for the passed AirFrame.
virtual simtime_t handleNewSenseRequest (ChannelSenseRequest *request)
 Handles a new incoming ChannelSenseRequest and returns the next (or latest) time to handle the request again.
virtual void handleSenseRequestEnd (CSRInfo &requestInfo)
 Handles the timeout or end of a ChannelSenseRequest by calculating the ChannelState and returning the request to the mac layer.
virtual void setChannelIdleStatus (bool isIdle)
 Changes the "isIdle"-status to the passed value.
virtual simtime_t canAnswerCSR (const CSRInfo &requestInfo)
 Returns point in time when the ChannelSenseRequest of the passed CSRInfo can be answered (e.g. because channel state changed or timeout is reached).
virtual double calcChannelSenseRSSI (simtime_t start, simtime_t end)
 Calculates the RSSI value for the passed interval.
virtual void answerCSR (CSRInfo &requestInfo)
 Answers the ChannelSenseRequest (CSR) from the passed CSRInfo.
virtual void channelStateChanged ()
 Checks if the changed channel state enables us to answer any ongoing ChannelSenseRequests.
virtual void getChannelInfo (simtime_t start, simtime_t end, AirFrameVector &out)
 Collects the AirFrame on the channel during the passed interval.
virtual MappingcalculateSnrMapping (AirFrame *frame)
 Calculates a SNR-Mapping for a Signal.
virtual MappingcalculateRSSIMapping (simtime_t start, simtime_t end, AirFrame *exclude=0)
 Calculates a RSSI-Mapping (or Noise-Strength-Mapping) for a Signal.

Protected Attributes

double sensitivity
 sensitivity value for receiving an AirFrame
ReceivedSignal currentSignal
 pointer to the currently received AirFrame
bool isChannelIdle
 Stores the idle state of the channel.
CSRInfo currentChannelSenseRequest
 pointer to the currently running ChannelSenseRequest and its start-time
int myIndex
 index for this Decider-instance given by Phy-Layer (mostly Host-index)
bool debug
 toggles display of debugging messages

Detailed Description

Provides some base functionality for most common deciders.

Forwards the AirFrame from "processSignal" to "processNewSignal", "processSignalHeader" or "processSignalEnd" depending on the state for that AirFrame returned by "getSignalState".

Provides answering of ChannelSenseRequests (instantaneous and over time).

Subclasses should define when they consider the channel as idle by calling "setChannelIdleStatus" because BaseDecider uses that to answer ChannelSenseRequests.

If a subclassing Decider only tries to receive one signal at a time it can use BaseDeciders "currentSignal" member which is a pair of the signal to receive and the state for that signal. The state is then used by BaseDeciders "getSignalState" to decide to which "process***" method to forward the signal. If a subclassing Decider needs states for more than one Signal it has to store these states by itself and should probably override the "getSignalState" method.

Definition at line 40 of file BaseDecider.h.


Member Enumeration Documentation

The kinds of ControlMessages this Decider sends.

Sub-classing decider should begin their own kind enumeration at the value of "LAST_BASE_DECIDER_CONTROL_KIND".

Enumerator:
PACKET_DROPPED 

The phy has recognized a bit error in the packet.

LAST_BASE_DECIDER_CONTROL_KIND 

Sub-classing decider should begin their own kinds at this value.

Definition at line 48 of file BaseDecider.h.

enum BaseDecider::SignalState [protected]

The current state of processing for a signal.

Enumerator:
NEW 

Signal is received the first time.

EXPECT_HEADER 

Waiting for the header of the signal.

EXPECT_END 

Waiting for the end of the signal.

Definition at line 59 of file BaseDecider.h.

                   {
    NEW,
    EXPECT_HEADER,
    EXPECT_END,
  };


Constructor & Destructor Documentation

BaseDecider::BaseDecider ( DeciderToPhyInterface phy,
double  sensitivity,
int  myIndex,
bool  debug 
) [inline]

Initializes the decider with the passed values.

Needs a pointer to its physical layer, the sensitivity, the index of the host and the debug flag.

Definition at line 112 of file BaseDecider.h.

References currentChannelSenseRequest, and currentSignal.


Member Function Documentation

void BaseDecider::answerCSR ( CSRInfo requestInfo  )  [protected, virtual]

Answers the ChannelSenseRequest (CSR) from the passed CSRInfo.

Calculates the rssi value and the channel idle state and sends the CSR together with the result back to the mac layer.

Reimplemented in SNRThresholdDecider.

Definition at line 203 of file BaseDecider.cc.

References calcChannelSenseRSSI(), DeciderToPhyInterface::getSimTime(), isChannelIdle, Decider::phy, and DeciderToPhyInterface::sendControlMsg().

Referenced by channelStateChanged(), handleNewSenseRequest(), and handleSenseRequestEnd().

                                                {

  double rssiValue = calcChannelSenseRSSI(requestInfo.second, phy->getSimTime());

  // put the sensing-result to the request and
  // send it to the Mac-Layer as Control-message (via Interface)
  requestInfo.first->setResult( ChannelState(isChannelIdle, rssiValue) );
  phy->sendControlMsg(requestInfo.first);

  requestInfo.first = 0;
  requestInfo.second = -1;
  requestInfo.canAnswerAt = -1;
}

double BaseDecider::calcChannelSenseRSSI ( simtime_t  start,
simtime_t  end 
) [protected, virtual]

Calculates the RSSI value for the passed interval.

This method is called by BaseDecider when it answers a ChannelSenseRequest or calculates the channel state. Can be overridden by sub classing Deciders.

Default implementation returns the maximum RSSI value inside the passed interval.

Reimplemented in Decider80211.

Definition at line 188 of file BaseDecider.cc.

References calculateRSSIMapping(), and MappingUtils::findMax().

Referenced by answerCSR(), SNRThresholdDecider::getChannelState(), getChannelState(), and Decider802154Narrow::processSignalEnd().

                                                                       {
  Mapping* rssiMap = calculateRSSIMapping(start, end);

  // the sensed RSSI-value is the maximum value between (and including) the interval-borders
  double rssi = MappingUtils::findMax(*rssiMap, Argument(start), Argument(end));

  //"findMax()" returns "-DBL_MAX" on empty mappings
  if (rssi < 0)
    rssi = 0;

  delete rssiMap;

  return rssi;
}

Mapping * BaseDecider::calculateRSSIMapping ( simtime_t  start,
simtime_t  end,
AirFrame *  exclude = 0 
) [protected, virtual]

Calculates a RSSI-Mapping (or Noise-Strength-Mapping) for a Signal.

This method can be used to calculate a RSSI-Mapping in case the parameter exclude is omitted OR to calculate a Noise-Strength-Mapping in case the AirFrame of the received Signal is passed as parameter exclude.

Definition at line 245 of file BaseDecider.cc.

References MappingUtils::createMapping(), getChannelInfo(), Signal::getReceivingPower(), Signal::getSignalLength(), Signal::getSignalStart(), DeciderToPhyInterface::getThermalNoise(), Decider::phy, and DimensionSet::timeDomain.

Referenced by Decider80211::calcChannelSenseRSSI(), calcChannelSenseRSSI(), calculateSnrMapping(), and SNRThresholdDecider::canAnswerCSR().

{
  if(exclude)
    deciderEV << "Creating RSSI map excluding AirFrame with id " << exclude->getId() << endl;
  else
    deciderEV << "Creating RSSI map." << endl;

  AirFrameVector airFrames;

  // collect all AirFrames that intersect with [start, end]
  getChannelInfo(start, end, airFrames);

  //TODO: create a "MappingUtils:createMappingFrom()"-method and use it here instead
  //of abusing the add method
  // create an empty mapping
  Mapping* resultMap = MappingUtils::createMapping(0.0, DimensionSet::timeDomain);

  //add thermal noise
  ConstMapping* thermalNoise = phy->getThermalNoise(start, end);
  if(thermalNoise) {
    Mapping* tmp = resultMap;
    resultMap = MappingUtils::add(*resultMap, *thermalNoise);
    delete tmp;
  }

  // otherwise, iterate over all AirFrames (except exclude)
  // and sum up their receiving-power-mappings
  AirFrameVector::iterator it;
  for (it = airFrames.begin(); it != airFrames.end(); it++)
  {
    // the vector should not contain pointers to 0
    assert (*it != 0);

    // if iterator points to exclude (that includes the default-case 'exclude == 0')
    // then skip this AirFrame
    if ( *it == exclude ) continue;

    // otherwise get the Signal and its receiving-power-mapping
    Signal& signal = (*it)->getSignal();

    // backup pointer to result map
    // Mapping* resultMapOld = resultMap;

    // TODO1.1: for testing purposes, for now we don't specify an interval
    // and add the Signal's receiving-power-mapping to resultMap in [start, end],
    // the operation Mapping::add returns a pointer to a new Mapping

    ConstMapping* recvPowerMap = signal.getReceivingPower();
    assert(recvPowerMap);

    // Mapping* resultMapNew = Mapping::add( *(signal.getReceivingPower()), *resultMap, start, end );

    deciderEV << "Adding mapping of Airframe with ID " << (*it)->getId()
        << ". Starts at " << signal.getSignalStart()
        << " and ends at " << signal.getSignalStart() + signal.getSignalLength() << endl;

    Mapping* resultMapNew = MappingUtils::add( *recvPowerMap, *resultMap, 0.0 );

    // discard old mapping
    delete resultMap;
    resultMap = resultMapNew;
    resultMapNew = 0;
  }

  return resultMap;
}

Mapping * BaseDecider::calculateSnrMapping ( AirFrame *  frame  )  [protected, virtual]

Calculates a SNR-Mapping for a Signal.

A Noise-Strength-Mapping is calculated (by using the "calculateRSSIMapping()"-method) for the time-interval of the Signal and the Signal-Strength-Mapping is divided by the Noise-Strength-Mapping.

Note: 'divided' means here the special element-wise operation on mappings.

Definition at line 217 of file BaseDecider.cc.

References calculateRSSIMapping(), Signal::getReceivingPower(), Signal::getSignalLength(), and Signal::getSignalStart().

Referenced by Decider80211::checkIfSignalOk(), SNRThresholdDecider::processSignalEnd(), and Decider802154Narrow::processSignalEnd().

{
  /* calculate Noise-Strength-Mapping */
  Signal& signal = frame->getSignal();

  simtime_t start = signal.getSignalStart();
  simtime_t end = start + signal.getSignalLength();

  Mapping* noiseMap = calculateRSSIMapping(start, end, frame);
  assert(noiseMap);
  ConstMapping* recvPowerMap = signal.getReceivingPower();
  assert(recvPowerMap);

  //TODO: handle noise of zero (must not devide with zero!)
  Mapping* snrMap = MappingUtils::divide( *recvPowerMap, *noiseMap, 0.0 );

  delete noiseMap;
  noiseMap = 0;

  return snrMap;
}

void BaseDecider::channelStateChanged (  )  [protected, virtual]

Checks if the changed channel state enables us to answer any ongoing ChannelSenseRequests.

This method is ment to update only an already ongoing ChannelSenseRequests it can't handle a new one.

Definition at line 136 of file BaseDecider.cc.

References answerCSR(), canAnswerCSR(), DeciderToPhyInterface::cancelScheduledMessage(), currentChannelSenseRequest, DeciderToPhyInterface::getSimTime(), Decider::phy, and DeciderToPhyInterface::rescheduleMessage().

Referenced by Decider80211MultiChannel::channelChanged(), SNRThresholdDecider::processNewSignal(), and setChannelIdleStatus().

{
  if(!currentChannelSenseRequest.getRequest())
    return;

  //check if the point in time when we can answer the request has changed
  simtime_t canAnswerAt = canAnswerCSR(currentChannelSenseRequest);

  //check if answer time has changed
  if(canAnswerAt != currentChannelSenseRequest.canAnswerAt) {
    //can we answer it now?
    if(canAnswerAt == phy->getSimTime()) {
      phy->cancelScheduledMessage(currentChannelSenseRequest.getRequest());
      answerCSR(currentChannelSenseRequest);
    } else {
      phy->rescheduleMessage(currentChannelSenseRequest.getRequest(),
                   canAnswerAt);
      currentChannelSenseRequest.canAnswerAt = canAnswerAt;
    }
  }
}

void BaseDecider::getChannelInfo ( simtime_t  start,
simtime_t  end,
AirFrameVector out 
) [protected, virtual]

Collects the AirFrame on the channel during the passed interval.

Forwards to DeciderToPhyInterfaces "getChannelInfo" method. Subclassing deciders can override this method to filter the returned AirFrames for their own criteria, for example by removing AirFrames on another not interferring channel.

Parameters:
start The start of the interval to collect AirFrames from.
end The end of the interval to collect AirFrames from.
out The output vector in which to put the AirFrames.

Reimplemented in Decider80211MultiChannel.

Definition at line 239 of file BaseDecider.cc.

References DeciderToPhyInterface::getChannelInfo(), and Decider::phy.

Referenced by calculateRSSIMapping().

{
  phy->getChannelInfo(start, end, out);
}

ChannelState BaseDecider::getChannelState (  )  [virtual]

A function that returns information about the channel state.

It is an alternative for the MACLayer in order to obtain information immediately (in contrast to sending a ChannelSenseRequest, i.e. sending a cMessage over the OMNeT-control-channel)

Reimplemented from Decider.

Reimplemented in SNRThresholdDecider.

Definition at line 72 of file BaseDecider.cc.

References calcChannelSenseRSSI(), DeciderToPhyInterface::getSimTime(), isChannelIdle, and Decider::phy.

                                          {

  simtime_t now = phy->getSimTime();
  double rssiValue = calcChannelSenseRSSI(now, now);

  return ChannelState(isChannelIdle, rssiValue);
}

int BaseDecider::getSignalState ( AirFrame *  frame  )  [protected, virtual]

Returns the SignalState for the passed AirFrame.

The default implementation checks if the passed AirFrame is the "currentSignal" and returns its state or if not "NEW".

Definition at line 129 of file BaseDecider.cc.

References currentSignal.

Referenced by processSignal().

                                               {
  if(frame == currentSignal.first)
    return currentSignal.second;

  return NEW;
}

simtime_t BaseDecider::handleChannelSenseRequest ( ChannelSenseRequest *  request  )  [virtual]

This function is called by the PhyLayer to hand over a ChannelSenseRequest.

The MACLayer is able to send a ChannelSenseRequest to the PhyLayer that calls this function with it and is returned a time point when to re-call this function with the specific ChannelSenseRequest.

The Decider puts the result (ChannelState) to the ChannelSenseRequest and "answers" by calling the "sendControlMsg"-function on the DeciderToPhyInterface, i.e. telling the PhyLayer to send it back.

Reimplemented from Decider.

Definition at line 81 of file BaseDecider.cc.

References currentChannelSenseRequest, handleNewSenseRequest(), handleSenseRequestEnd(), and Decider::notAgain.

                                                                             {

  assert(request);

  if (currentChannelSenseRequest.first == 0)
  {
    return handleNewSenseRequest(request);
  }

  if (currentChannelSenseRequest.first != request) {
    opp_error("Got a new ChannelSenseRequest while already handling another one!");
    return notAgain;
  }

  handleSenseRequestEnd(currentChannelSenseRequest);

  // say that we don't want to have it again
  return notAgain;
}

void BaseDecider::handleSenseRequestEnd ( CSRInfo requestInfo  )  [protected, virtual]

Handles the timeout or end of a ChannelSenseRequest by calculating the ChannelState and returning the request to the mac layer.

If this handler is reached the decider has to be able to answer the request. Either because the timeout is reached or because the channel state changed accordingly.

Definition at line 124 of file BaseDecider.cc.

References answerCSR(), canAnswerCSR(), DeciderToPhyInterface::getSimTime(), and Decider::phy.

Referenced by handleChannelSenseRequest().

                                                            {
  assert(canAnswerCSR(requestInfo) == phy->getSimTime());
  answerCSR(requestInfo);
}

simtime_t BaseDecider::processNewSignal ( AirFrame *  frame  )  [protected, virtual]

Processes a new Signal. Returns the time it wants to handle the signal again.

Default implementation checks if the signals receiving power is above the sensitivity of the radio and we are not already trying to receive another AirFrame. If thats the case it waits for the end of the signal.

Reimplemented in Decider80211, Decider80211MultiChannel, Decider802154Narrow, and SNRThresholdDecider.

Definition at line 27 of file BaseDecider.cc.

References currentSignal, Signal::getReceivingPower(), Signal::getSignalLength(), Signal::getSignalStart(), Decider::notAgain, sensitivity, and setChannelIdleStatus().

Referenced by processSignal().

                                                       {
  if(currentSignal.first != 0) {
    deciderEV << "Already receiving another AirFrame!" << endl;
    return notAgain;
  }

  // get the receiving power of the Signal at start-time
  Signal& signal = frame->getSignal();
  double recvPower = signal.getReceivingPower()->getValue(Argument(signal.getSignalStart()));

  // check whether signal is strong enough to receive
  if ( recvPower < sensitivity )
  {
    deciderEV << "Signal is to weak (" << recvPower << " < " << sensitivity
        << ") -> do not receive." << endl;
    // Signal too weak, we can't receive it, tell PhyLayer that we don't want it again
    return notAgain;
  }

  // Signal is strong enough, receive this Signal and schedule it
  deciderEV << "Signal is strong enough (" << recvPower << " > " << sensitivity
      << ") -> Trying to receive AirFrame." << endl;

  currentSignal.first = frame;
  currentSignal.second = EXPECT_END;

  //channel turned busy
  setChannelIdleStatus(false);

  return ( signal.getSignalStart() + signal.getSignalLength() );
}

simtime_t BaseDecider::processSignal ( AirFrame *  frame  )  [virtual]

Processes an AirFrame given by the PhyLayer.

Returns the time point when the decider wants to be given the AirFrame again.

Reimplemented from Decider.

Definition at line 10 of file BaseDecider.cc.

References EXPECT_END, EXPECT_HEADER, getSignalState(), NEW, processNewSignal(), processSignalEnd(), processSignalHeader(), and processUnknownSignal().

                                                    {

  assert(frame);
  deciderEV << "Processing AirFrame..." << endl;

  switch(getSignalState(frame)) {
  case NEW:
    return processNewSignal(frame);
  case EXPECT_HEADER:
    return processSignalHeader(frame);
  case EXPECT_END:
    return processSignalEnd(frame);
  default:
    return processUnknownSignal(frame);
  }
}

simtime_t BaseDecider::processSignalEnd ( AirFrame *  frame  )  [protected, virtual]

Processes the end of a received Signal.

Returns the time it wants to handle the signal again (most probably notAgain).

Default implementation just decides every signal as correct and passes it to the upper layer.

Reimplemented in Decider80211, Decider802154Narrow, and SNRThresholdDecider.

Definition at line 59 of file BaseDecider.cc.

References currentSignal, Decider::notAgain, Decider::phy, DeciderToPhyInterface::sendUp(), and setChannelIdleStatus().

Referenced by processSignal().

                                                       {
  deciderEV << "packet was received correctly, it is now handed to upper layer...\n";
  phy->sendUp(frame, new DeciderResult(true));

  // we have processed this AirFrame and we prepare to receive the next one
  currentSignal.first = 0;

  //channel is idle now
  setChannelIdleStatus(true);

  return notAgain;
}

virtual simtime_t BaseDecider::processSignalHeader ( AirFrame *  frame  )  [inline, protected, virtual]

Processes the end of the header of a received Signal.

Returns the time it wants to handle the signal again.

Default implementation does not handle signal headers.

Reimplemented in Decider802154Narrow.

Definition at line 182 of file BaseDecider.h.

References Decider::notAgain.

Referenced by processSignal().

                                                         {
    opp_error("BaseDecider does not handle Signal headers!");
    return notAgain;
  }

void BaseDecider::setChannelIdleStatus ( bool  isIdle  )  [protected, virtual]

Changes the "isIdle"-status to the passed value.

This method further checks if there are any ChannelSenseRequests which can be answered because of the idle state changed.

Reimplemented in Decider80211Battery.

Definition at line 158 of file BaseDecider.cc.

References channelStateChanged(), and isChannelIdle.

Referenced by Decider80211::processNewSignal(), processNewSignal(), Decider802154Narrow::processSignalEnd(), Decider80211::processSignalEnd(), processSignalEnd(), and Decider802154Narrow::processSignalHeader().


The documentation for this class was generated from the following files: