#include <AbstractRadio.h>
Inheritance diagram for AbstractRadio:
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.
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'. | |
AirFrame * | unbufferMsg (cMessage *msg) |
Unbuffers a message after 'transmission time'. | |
void | sendUp (AirFrame *airframe) |
void | sendDown (AirFrame *airframe) |
virtual AirFrame * | encapsulatePacket (cMessage *msg) |
void | setRadioState (RadioState::State newState) |
virtual int | channelNumber () const |
void | addNewSnr () |
virtual AirFrame * | createAirFrame () |
void | changeChannel (int channel) |
void | setBitrate (double bitrate) |
virtual IReceptionModel * | createReceptionModel ()=0 |
virtual IRadioModel * | createRadioModel ()=0 |
Protected Attributes | |
IRadioModel * | radioModel |
IReceptionModel * | receptionModel |
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 |
|
Typedef used to store received messages together with receive power. |
|
00031 : rs(this->id()) 00032 { 00033 radioModel = NULL; 00034 receptionModel = NULL; 00035 }
|
|
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 }
|
|
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 }
|
|
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 }
|
|
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 }
|
|
Returns the current channel the radio is tuned to 00100 {return rs.getChannelNumber();}
|
|
Create a new AirFrame 00106 {return new AirFrame();}
|
|
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. |
|
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. |
|
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 }
|
|
00102 { 00103 }
|
|
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 }
|
|
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 }
|
|
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:
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 }
|
|
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.
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 }
|
|
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 }
|
|
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 }
|
|
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 }
|
|
Sends a message to the channel 00215 { 00216 sendToChannel(airframe); 00217 }
|
|
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 }
|
|
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 }
|
|
Sets the radio state, and also fires change notification 00635 { 00636 rs.setState(newState); 00637 nb->fireChangeNotification(NF_RADIOSTATE_CHANGED, &rs); 00638 }
|
|
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 }
|
|
Configuration: The carrier frequency used. It is read from the ChannelControl module. |
|
State: if not -1, we have to switch to that bitrate once we finished transmitting |
|
State: if not -1, we have to switch to that channel once we finished transmitting |
|
State: the current noise level of the channel. |
|
|
|
|
|
State: A buffer to store a pointer to a message and the related receive power. |
|
State: the current RadioState of the NIC; includes channel number |
|
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 |
|
State: SnrInfo stores the snrList and the the recvdPower for the message currently being received, together with a pointer to the message. |
|
Configuration: Thermal noise on the channel. Can be specified in omnetpp.ini. Default: -100 dBm |
|
Power used to transmit messages |
|
|
|
|