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 ()
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.
void bufferMsg (AirFrame *airframe)
 Buffers message for 'transmission time'.
AirFrameunbufferMsg (cMessage *msg)
 Unbuffers a message after 'transmission time'.
void sendUp (AirFrame *airframe)
void sendDown (AirFrame *airframe)
virtual AirFrameencapsulatePacket (cMessage *msg)
void setRadioState (RadioState::State newState)
virtual int channelNumber () const
void addNewSnr ()
virtual AirFramecreateAirFrame ()
void changeChannel (int channel)
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 (  ) 

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

AbstractRadio::~AbstractRadio (  )  [virtual]

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


Member Function Documentation

void AbstractRadio::addNewSnr (  )  [protected]

Updates the SNR information of the relevant AirFrame

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

void AbstractRadio::bufferMsg ( AirFrame airframe  )  [protected]

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..

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

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

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.

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

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

Returns the current channel the radio is tuned to

00100 {return rs.getChannelNumber();}

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

Create a new AirFrame

00106 {return new AirFrame();}

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.

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.

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

Encapsulates a MAC frame into an Air Frame

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

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

00102 {
00103 }

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

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

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.

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

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.

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

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

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
00131 {
00132     // handle commands
00133     if (msg->arrivalGateId()==uppergateIn && msg->length()==0)
00134     {
00135         cPolymorphic *ctrl = msg->removeControlInfo();
00136         if (msg->kind()==0)
00137             error("Message '%s' with length==0 is supposed to be a command, but msg kind is also zero", msg->name());
00138         handleCommand(msg->kind(), ctrl);
00139         delete msg;
00140         return;
00141     }
00142 
00143     if (msg->arrivalGateId() == uppergateIn)
00144     {
00145         AirFrame *airframe = encapsulatePacket(msg);
00146         handleUpperMsg(airframe);
00147     }
00148     else if (msg->isSelfMessage())
00149     {
00150         handleSelfMsg(msg);
00151     }
00152     else if (check_and_cast<AirFrame *>(msg)->getChannelNumber() == channelNumber())
00153     {
00154         // must be an AirFrame
00155         AirFrame *airframe = (AirFrame *) msg;
00156         handleLowerMsgStart(airframe);
00157         bufferMsg(airframe);
00158     }
00159     else
00160     {
00161         EV << "listening to different channel when receiving message -- dropping it\n";
00162         delete msg;
00163     }
00164 }

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

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

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.

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

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.

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

void AbstractRadio::sendDown ( AirFrame airframe  )  [protected]

Sends a message to the channel

00215 {
00216     sendToChannel(airframe);
00217 }

void AbstractRadio::sendUp ( AirFrame airframe  )  [protected]

Sends a message to the upper layer

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

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

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

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

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

Sets the radio state, and also fires change notification

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

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

Unbuffers a message after 'transmission time'.

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

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


Member Data Documentation

double AbstractRadio::carrierFrequency [protected]

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

double AbstractRadio::newBitrate [protected]

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

int AbstractRadio::newChannel [protected]

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

double AbstractRadio::noiseLevel [protected]

State: the current noise level of the channel.

IRadioModel* AbstractRadio::radioModel [protected]

IReceptionModel* AbstractRadio::receptionModel [protected]

RecvBuff AbstractRadio::recvBuff [protected]

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

RadioState AbstractRadio::rs [protected]

State: the current RadioState of the NIC; includes channel number

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

SnrStruct AbstractRadio::snrInfo [protected]

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

double AbstractRadio::thermalNoise [protected]

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

double AbstractRadio::transmitterPower [protected]

Power used to transmit messages

int AbstractRadio::uppergateIn [protected]

int AbstractRadio::uppergateOut [protected]


The documentation for this class was generated from the following files:
Generated on Wed Apr 4 13:20:19 2007 for INET Framework for OMNeT++/OMNEST by  doxygen 1.4.7