#include <AbstractRadio.h>
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 () |
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 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 std::map<AirFrame*,double> AbstractRadio::RecvBuff [protected] |
Typedef used to store received messages together with receive power.
AbstractRadio::AbstractRadio | ( | ) |
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 }
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::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.
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:
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] |
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().
IRadioModel* AbstractRadio::radioModel [protected] |
Referenced by AbstractRadio(), encapsulatePacket(), handleLowerMsgEnd(), initialize(), and ~AbstractRadio().
IReceptionModel* AbstractRadio::receptionModel [protected] |
Referenced by AbstractRadio(), handleLowerMsgStart(), initialize(), and ~AbstractRadio().
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().
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.
Referenced by addNewSnr(), changeChannel(), handleLowerMsgEnd(), handleLowerMsgStart(), handleUpperMsg(), and initialize().
RecvBuff AbstractRadio::recvBuff [protected] |
State: A buffer to store a pointer to a message and the related receive power.
Referenced by changeChannel(), handleLowerMsgEnd(), handleLowerMsgStart(), and ~AbstractRadio().
RadioState AbstractRadio::rs [protected] |
State: the current RadioState of the NIC; includes channel number
Referenced by changeChannel(), encapsulatePacket(), handleCommand(), handleLowerMsgEnd(), handleLowerMsgStart(), handleUpperMsg(), initialize(), setBitrate(), and setRadioState().
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().