AbstractRadio Class Reference

#include <AbstractRadio.h>

Inheritance diagram for AbstractRadio:

ChannelAccess BasicModule INotifiable GenericRadio Ieee80211Radio

List of all members.


Detailed Description

Abstract base class for radio modules. Radio modules deal with the transmission of frames over a wireless medium (the radio channel). See the Radio module's NED documentation for an overview of radio modules.

This class implements common functionality of the radio, and abstracts out specific parts into two interfaces, IReceptionModel and IRadioModel. The reception model is responsible for modelling path loss, interference and antenna gain. The radio model is responsible for calculating frame duration, and modelling modulation scheme and possible forward error correction. Subclasses have to redefine the createReceptionModel() and createRadioModel() methods to create and return appropriate reception model and radio model objects.

History

The implementation is largely based on the Mobility Framework's SnrEval and Decider modules. They have been merged into a single module, multi-channel support, runtime channel and bitrate switching capability added, and all code specific to the physical channel and radio characteristics have been factored out into the IReceptionModel and IRadioModel classes.

Author:
Andras Varga, Levente Meszaros

Public Member Functions

 AbstractRadio ()
virtual ~AbstractRadio ()

Protected Types

typedef std::map< AirFrame
*, double > 
RecvBuff

Protected Member Functions

virtual void initialize (int stage)
 Register with ChannelControl and subscribe to hostPos.
virtual void finish ()
virtual void handleMessage (cMessage *msg)
virtual void handleUpperMsg (AirFrame *)
virtual void handleSelfMsg (cMessage *)
virtual void handleCommand (int msgkind, cPolymorphic *ctrl)
virtual void handleLowerMsgStart (AirFrame *airframe)
 Buffer the frame and update noise levels and snr information.
virtual void handleLowerMsgEnd (AirFrame *airframe)
 Unbuffer the frame and update noise levels and snr information.
virtual void bufferMsg (AirFrame *airframe)
 Buffers message for 'transmission time'.
virtual AirFrame * unbufferMsg (cMessage *msg)
 Unbuffers a message after 'transmission time'.
virtual void sendUp (AirFrame *airframe)
virtual void sendDown (AirFrame *airframe)
virtual AirFrame * encapsulatePacket (cPacket *msg)
virtual void setRadioState (RadioState::State newState)
virtual int getChannelNumber () const
virtual void addNewSnr ()
virtual AirFrame * createAirFrame ()
virtual void changeChannel (int channel)
virtual void setBitrate (double bitrate)
virtual IReceptionModelcreateReceptionModel ()=0
virtual IRadioModelcreateRadioModel ()=0

Protected Attributes

IRadioModelradioModel
IReceptionModelreceptionModel
double transmitterPower
SnrStruct snrInfo
RecvBuff recvBuff
RadioState rs
int newChannel
double newBitrate
double noiseLevel
double carrierFrequency
double thermalNoise
double sensitivity
Gate Ids


int uppergateOut
int uppergateIn

Classes

struct  SnrStruct

Member Typedef Documentation

typedef std::map<AirFrame*,double> AbstractRadio::RecvBuff [protected]

Typedef used to store received messages together with receive power.


Constructor & Destructor Documentation

AbstractRadio::AbstractRadio (  ) 

00030                              : rs(this->getId())
00031 {
00032     radioModel = NULL;
00033     receptionModel = NULL;
00034 }

AbstractRadio::~AbstractRadio (  )  [virtual]

00107 {
00108     delete radioModel;
00109     delete receptionModel;
00110 
00111     // delete messages being received
00112     for (RecvBuff::iterator it = recvBuff.begin(); it!=recvBuff.end(); ++it)
00113         delete it->first;
00114 }


Member Function Documentation

void AbstractRadio::initialize ( int  stage  )  [protected, virtual]

Register with ChannelControl and subscribe to hostPos.

Upon initialization ChannelAccess registers the nic parent module to have all its connections handled by ChannelControl

Reimplemented from ChannelAccess.

00037 {
00038     ChannelAccess::initialize(stage);
00039 
00040     EV << "Initializing AbstractRadio, stage=" << stage << endl;
00041 
00042     if (stage == 0)
00043     {
00044         gate("radioIn")->setDeliverOnReceptionStart(true);
00045 
00046         uppergateIn = findGate("uppergateIn");
00047         uppergateOut = findGate("uppergateOut");
00048 
00049         // read parameters
00050         transmitterPower = par("transmitterPower");
00051         if (transmitterPower > (double) (cc->par("pMax")))
00052             error("transmitterPower cannot be bigger than pMax in ChannelControl!");
00053         rs.setBitrate(par("bitrate"));
00054         rs.setChannelNumber(par("channelNumber"));
00055         thermalNoise = FWMath::dBm2mW(par("thermalNoise"));
00056         carrierFrequency = cc->par("carrierFrequency");  // taken from ChannelControl
00057         sensitivity = FWMath::dBm2mW(par("sensitivity"));
00058 
00059         // initialize noiseLevel
00060         noiseLevel = thermalNoise;
00061 
00062         EV << "Initialized channel with noise: " << noiseLevel << " sensitivity: " << sensitivity <<
00063             endl;
00064 
00065         // initialize the pointer of the snrInfo with NULL to indicate
00066         // that currently no message is received
00067         snrInfo.ptr = NULL;
00068 
00069         // no channel switch pending
00070         newChannel = -1;
00071 
00072         // Initialize radio state. If thermal noise is already to high, radio
00073         // state has to be initialized as RECV
00074         rs.setState(RadioState::IDLE);
00075         if (noiseLevel >= sensitivity)
00076             rs.setState(RadioState::RECV);
00077 
00078         WATCH(noiseLevel);
00079         WATCH(rs);
00080 
00081         receptionModel = createReceptionModel();
00082         receptionModel->initializeFrom(this);
00083 
00084         radioModel = createRadioModel();
00085         radioModel->initializeFrom(this);
00086     }
00087     else if (stage == 1)
00088     {
00089         // tell initial values to MAC; must be done in stage 1, because they
00090         // subscribe in stage 0
00091         nb->fireChangeNotification(NF_RADIOSTATE_CHANGED, &rs);
00092         nb->fireChangeNotification(NF_RADIO_CHANNEL_CHANGED, &rs);
00093     }
00094     else if (stage == 2)
00095     {
00096         // tell initial channel number to ChannelControl; should be done in
00097         // stage==2 or later, because base class initializes myHostRef in that stage
00098         cc->updateHostChannel(myHostRef, rs.getChannelNumber());
00099     }
00100 }

void AbstractRadio::finish (  )  [protected, virtual]

00103 {
00104 }

void AbstractRadio::handleMessage ( cMessage *  msg  )  [protected, virtual]

The basic handle message function.

Depending on the gate a message arrives handleMessage just calls different handle*Msg functions to further process the message.

Messages from the channel are also buffered here in order to simulate a transmission delay

You should not make any changes in this function but implement all your functionality into the handle*Msg functions called from here.

See also:
handleUpperMsg, handleLowerMsgStart, handleLowerMsgEnd, handleSelfMsg
00132 {
00133     // handle commands
00134     if (msg->getArrivalGateId()==uppergateIn && !msg->isPacket() /*FIXME XXX ENSURE REALLY PLAIN cMessage ARE SENT AS COMMANDS!!! && msg->getBitLength()==0*/)
00135     {
00136         cPolymorphic *ctrl = msg->removeControlInfo();
00137         if (msg->getKind()==0)
00138             error("Message '%s' with length==0 is supposed to be a command, but msg kind is also zero", msg->getName());
00139         handleCommand(msg->getKind(), ctrl);
00140         delete msg;
00141         return;
00142     }
00143 
00144     if (msg->getArrivalGateId() == uppergateIn)
00145     {
00146         AirFrame *airframe = encapsulatePacket(PK(msg));
00147         handleUpperMsg(airframe);
00148     }
00149     else if (msg->isSelfMessage())
00150     {
00151         handleSelfMsg(msg);
00152     }
00153     else if (check_and_cast<AirFrame *>(msg)->getChannelNumber() == getChannelNumber())
00154     {
00155         // must be an AirFrame
00156         AirFrame *airframe = (AirFrame *) msg;
00157         handleLowerMsgStart(airframe);
00158         bufferMsg(airframe);
00159     }
00160     else
00161     {
00162         EV << "listening to different channel when receiving message -- dropping it\n";
00163         delete msg;
00164     }
00165 }

void AbstractRadio::handleUpperMsg ( AirFrame *  airframe  )  [protected, virtual]

If a message is already being transmitted, an error is raised.

Otherwise the RadioState is set to TRANSMIT and a timer is started. When this timer expires the RadioState will be set back to RECV (or IDLE respectively) again.

If the host is receiving a packet this packet is from now on only considered as noise.

Referenced by handleMessage().

00244 {
00245     if (rs.getState() == RadioState::TRANSMIT)
00246         error("Trying to send a message while already transmitting -- MAC should "
00247               "take care this does not happen");
00248 
00249     // if a packet was being received, it is corrupted now as should be treated as noise
00250     if (snrInfo.ptr != NULL)
00251     {
00252         EV << "Sending a message while receiving another. The received one is now corrupted.\n";
00253 
00254         // remove the snr information stored for the message currently being
00255         // received. This message is treated as noise now and the
00256         // receive power has to be added to the noiseLevel
00257 
00258         // delete the pointer to indicate that no message is being received
00259         snrInfo.ptr = NULL;
00260         // clear the snr list
00261         snrInfo.sList.clear();
00262         // add the receive power to the noise level
00263         noiseLevel += snrInfo.rcvdPower;
00264     }
00265 
00266     // now we are done with all the exception handling and can take care
00267     // about the "real" stuff
00268 
00269     // change radio status
00270     EV << "sending, changing RadioState to TRANSMIT\n";
00271     setRadioState(RadioState::TRANSMIT);
00272 
00273     cMessage *timer = new cMessage(NULL, MK_TRANSMISSION_OVER);
00274     scheduleAt(simTime() + airframe->getDuration(), timer);
00275     sendDown(airframe);
00276 }

void AbstractRadio::handleSelfMsg ( cMessage *  msg  )  [protected, virtual]

Referenced by handleMessage().

00322 {
00323     if (msg->getKind()==MK_RECEPTION_COMPLETE)
00324     {
00325         EV << "frame is completely received now\n";
00326 
00327         // unbuffer the message
00328         AirFrame *airframe = unbufferMsg(msg);
00329 
00330         handleLowerMsgEnd(airframe);
00331     }
00332     else if (msg->getKind() == MK_TRANSMISSION_OVER)
00333     {
00334         // Transmission has completed. The RadioState has to be changed
00335         // to IDLE or RECV, based on the noise level on the channel.
00336         // If the noise level is bigger than the sensitivity switch to receive mode,
00337         // otherwise to idle mode.
00338         if (noiseLevel < sensitivity)
00339         {
00340             // set the RadioState to IDLE
00341             EV << "transmission over, switch to idle mode (state:IDLE)\n";
00342             setRadioState(RadioState::IDLE);
00343         }
00344         else
00345         {
00346             // set the RadioState to RECV
00347             EV << "transmission over but noise level too high, switch to recv mode (state:RECV)\n";
00348             setRadioState(RadioState::RECV);
00349         }
00350 
00351         // delete the timer
00352         delete msg;
00353 
00354         // switch channel if it needs be
00355         if (newChannel!=-1)
00356         {
00357             changeChannel(newChannel);
00358             newChannel = -1;
00359         }
00360     }
00361     else
00362     {
00363         error("Internal error: unknown self-message `%s'", msg->getName());
00364     }
00365 }

void AbstractRadio::handleCommand ( int  msgkind,
cPolymorphic *  ctrl 
) [protected, virtual]

Referenced by handleMessage().

00279 {
00280     if (msgkind==PHY_C_CONFIGURERADIO)
00281     {
00282         // extract new channel number
00283         PhyControlInfo *phyCtrl = check_and_cast<PhyControlInfo *>(ctrl);
00284         int newChannel = phyCtrl->getChannelNumber();
00285         double newBitrate = phyCtrl->getBitrate();
00286         delete ctrl;
00287 
00288         if (newChannel!=-1)
00289         {
00290             EV << "Command received: change to channel #" << newChannel << "\n";
00291 
00292             // do it
00293             if (rs.getChannelNumber()==newChannel)
00294                 EV << "Right on that channel, nothing to do\n"; // fine, nothing to do
00295             else if (rs.getState()==RadioState::TRANSMIT) {
00296                 EV << "We're transmitting right now, remembering to change after it's completed\n";
00297                 this->newChannel = newChannel;
00298             } else
00299                 changeChannel(newChannel); // change channel right now
00300         }
00301         if (newBitrate!=-1)
00302         {
00303             EV << "Command received: change bitrate to " << (newBitrate/1e6) << "Mbps\n";
00304 
00305             // do it
00306             if (rs.getBitrate()==newBitrate)
00307                 EV << "Right at that bitrate, nothing to do\n"; // fine, nothing to do
00308             else if (rs.getState()==RadioState::TRANSMIT) {
00309                 EV << "We're transmitting right now, remembering to change after it's completed\n";
00310                 this->newBitrate = newBitrate;
00311             } else
00312                 setBitrate(newBitrate); // change bitrate right now
00313         }
00314     }
00315     else
00316     {
00317         error("unknown command (msgkind=%d)", msgkind);
00318     }
00319 }

void AbstractRadio::handleLowerMsgStart ( AirFrame *  airframe  )  [protected, virtual]

Buffer the frame and update noise levels and snr information.

This function is called right after a packet arrived, i.e. right before it is buffered for 'transmission time'.

First the receive power of the packet has to be calculated and is stored in the recvBuff. Afterwards it has to be decided whether the packet is just noise or a "real" packet that needs to be received.

The message is not treated as noise if all of the following conditions apply:

  1. the power of the received signal is higher than the sensitivity.
  2. the host is currently not sending a message
  3. no other packet is already being received

If all conditions apply a new SnrList is created and the RadioState is changed to RECV.

If the packet is just noise the receive power is added to the noise Level of the channel. Additionally the snr information of the currently being received message (if any) has to be updated as well as the RadioState.

Referenced by changeChannel(), and handleMessage().

00392 {
00393     // Calculate the receive power of the message
00394 
00395     // calculate distance
00396     const Coord& myPos = getMyPosition();
00397     const Coord& framePos = airframe->getSenderPos();
00398     double distance = myPos.distance(framePos);
00399 
00400     // calculate receive power
00401     double rcvdPower = receptionModel->calculateReceivedPower(airframe->getPSend(), carrierFrequency, distance);
00402 
00403     // store the receive power in the recvBuff
00404     recvBuff[airframe] = rcvdPower;
00405 
00406     // if receive power is bigger than sensitivity and if not sending
00407     // and currently not receiving another message and the message has
00408     // arrived in time
00409     // NOTE: a message may have arrival time in the past here when we are
00410     // processing ongoing transmissions during a channel change
00411     if (airframe->getArrivalTime() == simTime() && rcvdPower >= sensitivity && rs.getState() != RadioState::TRANSMIT && snrInfo.ptr == NULL)
00412     {
00413         EV << "receiving frame " << airframe->getName() << endl;
00414 
00415         // Put frame and related SnrList in receive buffer
00416         SnrList snrList;
00417         snrInfo.ptr = airframe;
00418         snrInfo.rcvdPower = rcvdPower;
00419         snrInfo.sList = snrList;
00420 
00421         // add initial snr value
00422         addNewSnr();
00423 
00424         if (rs.getState() != RadioState::RECV)
00425         {
00426             // publish new RadioState
00427             EV << "publish new RadioState:RECV\n";
00428             setRadioState(RadioState::RECV);
00429         }
00430     }
00431     // receive power is too low or another message is being sent or received
00432     else
00433     {
00434         EV << "frame " << airframe->getName() << " is just noise\n";
00435         //add receive power to the noise level
00436         noiseLevel += rcvdPower;
00437 
00438         // if a message is being received add a new snr value
00439         if (snrInfo.ptr != NULL)
00440         {
00441             // update snr info for currently being received message
00442             EV << "adding new snr value to snr list of message being received\n";
00443             addNewSnr();
00444         }
00445 
00446         // update the RadioState if the noiseLevel exceeded the threshold
00447         // and the radio is currently not in receive or in send mode
00448         if (noiseLevel >= sensitivity && rs.getState() == RadioState::IDLE)
00449         {
00450             EV << "setting radio state to RECV\n";
00451             setRadioState(RadioState::RECV);
00452         }
00453     }
00454 }

void AbstractRadio::handleLowerMsgEnd ( AirFrame *  airframe  )  [protected, virtual]

Unbuffer the frame and update noise levels and snr information.

This function is called right after the transmission is over, i.e. right after unbuffering. The noise level of the channel and the snr information of the buffered messages have to be updated.

Additionally the RadioState has to be updated.

If the corresponding AirFrame was not only noise the corresponding SnrList and the AirFrame are sent to the decider.

Referenced by handleSelfMsg().

00468 {
00469     // check if message has to be send to the decider
00470     if (snrInfo.ptr == airframe)
00471     {
00472         EV << "reception of frame over, preparing to send packet to upper layer\n";
00473         // get Packet and list out of the receive buffer:
00474         SnrList list;
00475         list = snrInfo.sList;
00476 
00477         // delete the pointer to indicate that no message is currently
00478         // being received and clear the list
00479         snrInfo.ptr = NULL;
00480         snrInfo.sList.clear();
00481 
00482         // delete the frame from the recvBuff
00483         recvBuff.erase(airframe);
00484 
00485         //XXX send up the frame:
00486         //if (radioModel->isReceivedCorrectly(airframe, list))
00487         //    sendUp(airframe);
00488         //else
00489         //    delete airframe;
00490         if (!radioModel->isReceivedCorrectly(airframe, list))
00491         {
00492             airframe->getEncapsulatedMsg()->setKind(list.size()>1 ? COLLISION : BITERROR);
00493             airframe->setName(list.size()>1 ? "COLLISION" : "BITERROR");
00494         }
00495         sendUp(airframe);
00496     }
00497     // all other messages are noise
00498     else
00499     {
00500         EV << "reception of noise message over, removing recvdPower from noiseLevel....\n";
00501         // get the rcvdPower and subtract it from the noiseLevel
00502         noiseLevel -= recvBuff[airframe];
00503 
00504         // delete message from the recvBuff
00505         recvBuff.erase(airframe);
00506 
00507         // update snr info for message currently being received if any
00508         if (snrInfo.ptr != NULL)
00509         {
00510             addNewSnr();
00511         }
00512 
00513         // message should be deleted
00514         delete airframe;
00515         EV << "message deleted\n";
00516     }
00517 
00518     // check the RadioState and update if necessary
00519     // change to idle if noiseLevel smaller than threshold and state was
00520     // not idle before
00521     // do not change state if currently sending or receiving a message!!!
00522     if (noiseLevel < sensitivity && rs.getState() == RadioState::RECV && snrInfo.ptr == NULL)
00523     {
00524         // publish the new RadioState:
00525         EV << "new RadioState is IDLE\n";
00526         setRadioState(RadioState::IDLE);
00527     }
00528 }

void AbstractRadio::bufferMsg ( AirFrame *  airframe  )  [protected, virtual]

Buffers message for 'transmission time'.

The packet is put in a buffer for the time the transmission would last in reality. A timer indicates when the transmission is complete. So, look at unbufferMsg to see what happens when the transmission is complete..

Referenced by changeChannel(), and handleMessage().

00173                                                        : add explicit simtime_t atTime arg?
00174 {
00175     // set timer to indicate transmission is complete
00176     cMessage *endRxTimer = new cMessage("endRx", MK_RECEPTION_COMPLETE);
00177     endRxTimer->setContextPointer(airframe);
00178     airframe->setContextPointer(endRxTimer);
00179 
00180     // NOTE: use arrivalTime instead of simTime, because we might be calling this
00181     // function during a channel change, when we're picking up ongoing transmissions
00182     // on the channel -- and then the message's arrival time is in the past!
00183     scheduleAt(airframe->getArrivalTime() + airframe->getDuration(), endRxTimer);
00184 }

AirFrame * AbstractRadio::unbufferMsg ( cMessage *  msg  )  [protected, virtual]

Unbuffers a message after 'transmission time'.

Get the context pointer to the now completely received AirFrame and delete the self message

Referenced by handleSelfMsg().

00225 {
00226     AirFrame *airframe = (AirFrame *) msg->getContextPointer();
00227     //delete the self message
00228     delete msg;
00229 
00230     return airframe;
00231 }

void AbstractRadio::sendUp ( AirFrame *  airframe  )  [protected, virtual]

Sends a message to the upper layer

Referenced by handleLowerMsgEnd().

00208 {
00209     cPacket *frame = airframe->decapsulate();
00210     delete airframe;
00211     EV << "sending up frame " << frame->getName() << endl;
00212     send(frame, uppergateOut);
00213 }

void AbstractRadio::sendDown ( AirFrame *  airframe  )  [protected, virtual]

Sends a message to the channel

Referenced by handleUpperMsg().

00216 {
00217     sendToChannel(airframe);
00218 }

AirFrame * AbstractRadio::encapsulatePacket ( cPacket *  msg  )  [protected, virtual]

Encapsulates a MAC frame into an Air Frame

Referenced by handleMessage().

00187 {
00188     PhyControlInfo *ctrl = dynamic_cast<PhyControlInfo *>(frame->removeControlInfo());
00189     ASSERT(!ctrl || ctrl->getChannelNumber()==-1); // per-packet channel switching not supported
00190 
00191     // Note: we don't set length() of the AirFrame, because duration will be used everywhere instead
00192     AirFrame *airframe = createAirFrame();
00193     airframe->setName(frame->getName());
00194     airframe->setPSend(transmitterPower);
00195     airframe->setChannelNumber(getChannelNumber());
00196     airframe->encapsulate(frame);
00197     airframe->setBitrate(ctrl ? ctrl->getBitrate() : rs.getBitrate());
00198     airframe->setDuration(radioModel->calculateDuration(airframe));
00199     airframe->setSenderPos(getMyPosition());
00200     delete ctrl;
00201 
00202     EV << "Frame (" << frame->getClassName() << ")" << frame->getName()
00203        << " will be transmitted at " << (airframe->getBitrate()/1e6) << "Mbps\n";
00204     return airframe;
00205 }

void AbstractRadio::setRadioState ( RadioState::State  newState  )  [protected, virtual]

Sets the radio state, and also fires change notification

Referenced by handleLowerMsgEnd(), handleLowerMsgStart(), handleSelfMsg(), and handleUpperMsg().

00636 {
00637     rs.setState(newState);
00638     nb->fireChangeNotification(NF_RADIOSTATE_CHANGED, &rs);
00639 }

virtual int AbstractRadio::getChannelNumber (  )  const [inline, protected, virtual]

Returns the current channel the radio is tuned to

Referenced by encapsulatePacket(), and handleMessage().

00099 {return rs.getChannelNumber();}

void AbstractRadio::addNewSnr (  )  [protected, virtual]

Updates the SNR information of the relevant AirFrame

Referenced by handleLowerMsgEnd(), and handleLowerMsgStart().

00531 {
00532     SnrListEntry listEntry;     // create a new entry
00533     listEntry.time = simTime();
00534     listEntry.snr = snrInfo.rcvdPower / noiseLevel;
00535     snrInfo.sList.push_back(listEntry);
00536 }

virtual AirFrame* AbstractRadio::createAirFrame (  )  [inline, protected, virtual]

Create a new AirFrame

Referenced by encapsulatePacket().

00105 {return new AirFrame();}

void AbstractRadio::changeChannel ( int  channel  )  [protected, virtual]

Change transmitter and receiver to a new channel. This method throws an error if the radio state is transmit. Messages that are already sent to the new channel and would reach us in the future - thus they are on the air - will be received correctly.

Referenced by handleCommand(), and handleSelfMsg().

00539 {
00540     if (channel == rs.getChannelNumber())
00541         return;
00542     if (channel < 0 || channel >= cc->getNumChannels())
00543         error("changeChannel(): channel number %d is out of range (hint: numChannels is a parameter of ChannelControl)", channel);
00544     if (rs.getState() == RadioState::TRANSMIT)
00545         error("changing channel while transmitting is not allowed");
00546 
00547     // if we are currently receiving, must clean that up before moving to different channel
00548     if (rs.getState() == RadioState::RECV)
00549     {
00550         // delete messages being received, and cancel associated self-messages
00551         for (RecvBuff::iterator it = recvBuff.begin(); it!=recvBuff.end(); ++it)
00552         {
00553             AirFrame *airframe = it->first;
00554             cMessage *endRxTimer = (cMessage *)airframe->getContextPointer();
00555             delete airframe;
00556             delete cancelEvent(endRxTimer);
00557         }
00558         recvBuff.clear();
00559     }
00560 
00561     // clear snr info
00562     snrInfo.ptr = NULL;
00563     snrInfo.sList.clear();
00564 
00565     // do channel switch
00566     EV << "Changing to channel #" << channel << "\n";
00567 
00568     rs.setChannelNumber(channel);
00569     cc->updateHostChannel(myHostRef, channel);
00570     ChannelControl::TransmissionList tl = cc->getOngoingTransmissions(channel);
00571 
00572     cModule *myHost = findHost();
00573     cGate *radioGate = myHost->gate("radioIn");
00574 
00575     // pick up ongoing transmissions on the new channel
00576     EV << "Picking up ongoing transmissions on new channel:\n";
00577     for (ChannelControl::TransmissionList::const_iterator it = tl.begin(); it != tl.end(); ++it)
00578     {
00579         AirFrame *airframe = *it;
00580         // time for the message to reach us
00581         double distance = myHostRef->pos.distance(airframe->getSenderPos());
00582         simtime_t propagationDelay = distance / LIGHT_SPEED;
00583 
00584         // if this transmission is on our new channel and it would reach us in the future, then schedule it
00585         if (channel == airframe->getChannelNumber())
00586         {
00587             EV << " - (" << airframe->getClassName() << ")" << airframe->getName() << ": ";
00588 
00589             // if there is a message on the air which will reach us in the future
00590             if (airframe->getTimestamp() + propagationDelay >= simTime())
00591             {
00592                  EV << "will arrive in the future, scheduling it\n";
00593 
00594                  // we need to send to each radioIn[] gate of this host
00595                  for (int i = 0; i < radioGate->size(); i++)
00596                      sendDirect(airframe->dup(), airframe->getTimestamp() + propagationDelay - simTime(), airframe->getDuration(), myHost, radioGate->getId() + i);
00597             }
00598             // if we hear some part of the message
00599             else if (airframe->getTimestamp() + airframe->getDuration() + propagationDelay > simTime())
00600             {
00601                  EV << "missed beginning of frame, processing it as noise\n";
00602 
00603                  AirFrame *frameDup = airframe->dup();
00604                  frameDup->setArrivalTime(airframe->getTimestamp() + propagationDelay);
00605                  handleLowerMsgStart(frameDup);
00606                  bufferMsg(frameDup);
00607             }
00608             else
00609             {
00610                 EV << "in the past\n";
00611             }
00612         }
00613     }
00614 
00615     // notify other modules about the channel switch; and actually, radio state has changed too
00616     nb->fireChangeNotification(NF_RADIO_CHANNEL_CHANGED, &rs);
00617     nb->fireChangeNotification(NF_RADIOSTATE_CHANGED, &rs);
00618 }

void AbstractRadio::setBitrate ( double  bitrate  )  [protected, virtual]

Change the bitrate to the given value. This method throws an error if the radio state is transmit.

Referenced by handleCommand().

00621 {
00622     if (rs.getBitrate() == bitrate)
00623         return;
00624     if (bitrate < 0)
00625         error("setBitrate(): bitrate cannot be negative (%g)", bitrate);
00626     if (rs.getState() == RadioState::TRANSMIT)
00627         error("changing the bitrate while transmitting is not allowed");
00628 
00629     EV << "Setting bitrate to " << (bitrate/1e6) << "Mbps\n";
00630     rs.setBitrate(bitrate);
00631 
00632     //XXX fire some notification?
00633 }

virtual IReceptionModel* AbstractRadio::createReceptionModel (  )  [protected, pure virtual]

To be defined to provide a reception model. The reception model is responsible for modelling path loss, interference and antenna gain.

Implemented in GenericRadio, and Ieee80211Radio.

Referenced by initialize().

virtual IRadioModel* AbstractRadio::createRadioModel (  )  [protected, pure virtual]

To be defined to provide a radio model. The radio model is responsible for calculating frame duration, and modelling modulation scheme and possible forward error correction.

Implemented in GenericRadio, and Ieee80211Radio.

Referenced by initialize().


Member Data Documentation

double AbstractRadio::transmitterPower [protected]

Power used to transmit messages

Referenced by encapsulatePacket(), and initialize().

int AbstractRadio::uppergateOut [protected]

Referenced by initialize(), and sendUp().

int AbstractRadio::uppergateIn [protected]

Referenced by handleMessage(), and initialize().

State: SnrInfo stores the snrList and the the recvdPower for the message currently being received, together with a pointer to the message.

Referenced by addNewSnr(), changeChannel(), handleLowerMsgEnd(), handleLowerMsgStart(), handleUpperMsg(), and initialize().

State: A buffer to store a pointer to a message and the related receive power.

Referenced by changeChannel(), handleLowerMsgEnd(), handleLowerMsgStart(), and ~AbstractRadio().

int AbstractRadio::newChannel [protected]

State: if not -1, we have to switch to that channel once we finished transmitting

Referenced by handleCommand(), handleSelfMsg(), and initialize().

double AbstractRadio::newBitrate [protected]

State: if not -1, we have to switch to that bitrate once we finished transmitting

Referenced by handleCommand().

double AbstractRadio::noiseLevel [protected]

State: the current noise level of the channel.

Referenced by addNewSnr(), handleLowerMsgEnd(), handleLowerMsgStart(), handleSelfMsg(), handleUpperMsg(), and initialize().

double AbstractRadio::carrierFrequency [protected]

Configuration: The carrier frequency used. It is read from the ChannelControl module.

Referenced by handleLowerMsgStart(), and initialize().

double AbstractRadio::thermalNoise [protected]

Configuration: Thermal noise on the channel. Can be specified in omnetpp.ini. Default: -100 dBm

Referenced by initialize().

double AbstractRadio::sensitivity [protected]

Configuration: Defines up to what Power level (in dBm) a message can be understood. If the level of a received packet is lower, it is only treated as noise. Can be specified in omnetpp.ini. Default: -85 dBm

Referenced by handleLowerMsgEnd(), handleLowerMsgStart(), handleSelfMsg(), and initialize().


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

Generated on Fri Mar 20 18:51:18 2009 for INET Framework for OMNeT++/OMNEST by  doxygen 1.5.5