#include <SnrEval.h>
Inheritance diagram for SnrEval:

This module keeps track of the noise level of the channel.
When receiving a packet this module updates the noise level of the channel. Based on the receive power of the packet it is processed and handed to upper layers or just treated as noise.
After the packet is completely received the snir information is attached and it is handed to the deceider module.
The snir information is a SnrList that lists all different snr levels together with the point of time (simTime()) when they started.
On top of that this module manages the RadioState, and posts notifications on NotificationBoard whenever it changes. The radio state gives information about whether this module is sending a packet, receiving a packet or idle. This information can be accessed via the NotificationBoard by other modules, e.g. a CSMAMacLayer.
Protected Types | |
| typedef std::map< AirFrame *, double > | cRecvBuff |
| Typedef used to store received messages together with receive power. | |
| enum | { TRANSM_OVER } |
| Enum to store self message kind()s. More... | |
Protected Member Functions | |
| virtual void | initialize (int) |
| Initialize variables and publish the radio status. | |
| virtual void | finish () |
| virtual void | handleUpperMsg (AirFrame *) |
| virtual void | handleSelfMsg (cMessage *) |
| virtual void | handleLowerMsgStart (AirFrame *) |
| Buffer the frame and update noise levels and snr information... | |
| virtual void | handleLowerMsgEnd (AirFrame *) |
| Unbuffer the frame and update noise levels and snr information. | |
| double | calcRcvdPower (double pSend, double distance) |
| Calculates the power with which a packet is received. | |
| void | addNewSnr () |
| updates the snr information of the relevant AirFrames | |
Protected Attributes | |
| SnrStruct | snrInfo |
| SnrInfo stores the snrList and the the recvdPower for the message currently being received together with a pointer to the message. | |
| cRecvBuff | recvBuff |
| A buffer to store a pointer to a message and the related receive power. | |
| RadioState | rs |
| Actual RadioState of the nic. | |
| double | noiseLevel |
| The noise level of the channel. | |
| double | carrierFrequency |
| The carrier frequency used.Can be specified in the omnetpp.ini file. If not it is read from the ChannelControl module. | |
| double | thermalNoise |
| Thermal noise on the channel. Can be specified in omnetpp.ini. Default: -100 dBm. | |
| double | sensitivity |
| 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. | |
| double | pathLossAlpha |
| Path loss coefficient. Can be specified in omnetpp.ini. If not it is read from the ChannelControl module. This value CANNOT be smaller than the one specified in the ChannelControl module. The simulation will exit with an error! | |
Classes | |
| struct | SnrStruct |
| Struct to store a pointer to the mesage, rcvdPower AND a SnrList, needed in SnrEval::addNewSnr. More... | |
|
|
Typedef used to store received messages together with receive power.
|
|
|
Enum to store self message kind()s.
00081 {
00083 TRANSM_OVER
00084 };
|
|
|
updates the snr information of the relevant AirFrames The Snr information of the buffered message is updated.... 00328 {
00329 //print("NoiseLevel: "<<noiseLevel<<" recvPower: "<<snrInfo.rcvdPower);
00330
00331 SnrListEntry listEntry; //create a new entry
00332 listEntry.time = simTime();
00333 listEntry.snr = snrInfo.rcvdPower / noiseLevel;
00334 snrInfo.sList.push_back(listEntry);
00335 //print("New Snr added: "<<listEntry.snr<<" at time:"<<simTime());
00336 }
|
|
||||||||||||
|
Calculates the power with which a packet is received. This function simply calculates with how much power the signal arrives "here". If a different way of computing the path loss is required this function can be redefined. 00345 {
00346 double speedOfLight = 300000000.0;
00347 double waveLength = speedOfLight / carrierFrequency;
00348 return (pSend * waveLength * waveLength / (16 * M_PI * M_PI * pow(distance, pathLossAlpha)));
00349 }
|
|
|
delete the RadioState 00090 {
00091 BasicSnrEval::finish();
00092 }
|
|
|
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. Reimplemented from BasicSnrEval. Reimplemented in GilbertElliotSnr. 00268 {
00269 // check if message has to be send to the decider
00270 if (snrInfo.ptr == frame)
00271 {
00272 EV << "reception of frame over, preparing to send packet to upper layer\n";
00273 // get Packet and list out of the receive buffer:
00274 SnrList list;
00275 list = snrInfo.sList;
00276
00277 // delete the pointer to indicate that no message is currently
00278 // being received and clear the list
00279 snrInfo.ptr = NULL;
00280 snrInfo.sList.clear();
00281
00282 // delete the frame from the recvBuff
00283 recvBuff.erase(frame);
00284
00285 //Don't forget to send:
00286 sendUp(frame, list);
00287 EV << "packet sent to the decider\n";
00288 }
00289 // all other messages are noise
00290 else
00291 {
00292 EV << "reception of noise message over, removing recvdPower from noiseLevel....\n";
00293 // get the rcvdPower and subtract it from the noiseLevel
00294 noiseLevel -= recvBuff[frame];
00295
00296 // delete message from the recvBuff
00297 recvBuff.erase(frame);
00298
00299 // update snr info for message currently being received if any
00300 if (snrInfo.ptr != NULL)
00301 {
00302 addNewSnr();
00303 }
00304
00305 // message should be deleted
00306 delete frame;
00307 EV << "message deleted\n";
00308 }
00309
00310 // check the RadioState and update if necessary
00311 // change to idle if noiseLevel smaller than threshold and state was
00312 // not idle before
00313 // do not change state if currently sending or receiving a message!!!
00314 if (noiseLevel < sensitivity && rs.getState() == RadioState::RECV && snrInfo.ptr == NULL)
00315 {
00316 // publish the new RadioState:
00317 EV << "new RadioState is IDLE\n";
00318 rs.setState(RadioState::IDLE);
00319 nb->fireChangeNotification(NF_RADIOSTATE_CHANGED, &rs);
00320 }
00321 }
|
|
|
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 follwoing 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. Reimplemented from BasicSnrEval. Reimplemented in GilbertElliotSnr. 00192 {
00193 // Calculate the receive power of the message
00194
00195 // calculate distance
00196 const Coord& myPos = myPosition();
00197 const Coord& framePos = frame->getSenderPos();
00198 double distance = myPos.distance(framePos);
00199
00200 // calculate receive power
00201 double rcvdPower = calcRcvdPower(frame->getPSend(), distance);
00202
00203 // store the receive power in the recvBuff
00204 recvBuff[frame] = rcvdPower;
00205
00206 // if receive power is bigger than sensitivity and if not sending
00207 // and currently not receiving another message
00208 if (rcvdPower >= sensitivity && rs.getState() != RadioState::TRANSMIT && snrInfo.ptr == NULL)
00209 {
00210 EV << "receiving frame " << frame->name() << endl;
00211
00212 // Put frame and related SnrList in receive buffer
00213 SnrList snrList; //defined in SnrList.h!!
00214 snrInfo.ptr = frame;
00215 snrInfo.rcvdPower = rcvdPower;
00216 snrInfo.sList = snrList;
00217
00218 // add initial snr value
00219 addNewSnr();
00220
00221 if (rs.getState() != RadioState::RECV)
00222 {
00223 // publish new RadioState
00224 rs.setState(RadioState::RECV);
00225 EV << "publish new RadioState:RECV\n";
00226 nb->fireChangeNotification(NF_RADIOSTATE_CHANGED, &rs);
00227 }
00228 }
00229 // receive power is to low or another message is being send or received
00230 else
00231 {
00232 EV << "frame " << frame->name() << "is just noise\n";
00233 //add receive power to the noise level
00234 noiseLevel += rcvdPower;
00235
00236 // if a message is being received add a new snr value
00237 if (snrInfo.ptr != NULL)
00238 {
00239 // update snr info for currently being received message
00240 EV << "add new snr value to snr list of message being received\n";
00241 addNewSnr();
00242 }
00243
00244 // update the RadioState if the noiseLevel exceeded the threshold
00245 // and the radio is currently not in receive or in send mode
00246 if (noiseLevel >= sensitivity && rs.getState() == RadioState::IDLE)
00247 {
00248 // publish new RadioState
00249 rs.setState(RadioState::RECV);
00250 EV << "publish new RadioState:RECV\n";
00251 nb->fireChangeNotification(NF_RADIOSTATE_CHANGED, &rs);
00252 }
00253 }
00254 }
|
|
|
The only self message that can arrive is a timer to indicate that sending of a message is completed. The RadioState has to be changed based on the noise level on the channel. If the noise level is bigger than the sensitivity switch to receive mode odtherwise to idle mode. Reimplemented from BasicSnrEval. Reimplemented in GilbertElliotSnr. 00140 {
00141 if (msg->kind() == TRANSM_OVER)
00142 {
00143
00144 if (noiseLevel < sensitivity)
00145 {
00146 // set the RadioState to IDLE
00147 rs.setState(RadioState::IDLE);
00148 EV << "transmission over, switch to idle mode (state:IDLE)\n";
00149 nb->fireChangeNotification(NF_RADIOSTATE_CHANGED, &rs);
00150 }
00151 else
00152 {
00153 // set the RadioState to RECV
00154 rs.setState(RadioState::RECV);
00155 EV << "transmission over but noise level to high, switch to recv mode (state:RECV)\n";
00156 nb->fireChangeNotification(NF_RADIOSTATE_CHANGED, &rs);
00157 }
00158
00159 // delete the timer
00160 delete msg;
00161 }
00162 else
00163 error("unknown selfMsg erhalten.....");
00164 }
|
|
|
If a message is already being send the newly arrived one is deletetd and a warning is printed. Otherwise the RadioState is set to TRANSMIT and a timer is started. When this timer expires the RadioState is 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. Reimplemented from BasicSnrEval. 00106 {
00107 if (rs.getState() == RadioState::TRANSMIT)
00108 error("Trying to send a message although already sending -- MAC should "
00109 "take care this does not happen");
00110
00111 // if a packet was being received, it is corrupted now (treated as
00112 // noise). print a warning
00113 if (snrInfo.ptr != NULL)
00114 error("Trying to send a message although already receiving -- this would "
00115 "corrupt received frame, and MAC should take care this does not happen");
00116
00117 // now we are done with all the exception handling and can take care
00118 // about the "real" stuff
00119
00120 //change radio status
00121 rs.setState(RadioState::TRANSMIT);
00122 EV << "sending, changing RadioState to TRANSMIT\n";
00123 nb->fireChangeNotification(NF_RADIOSTATE_CHANGED, &rs);
00124
00125 cMessage *timer = new cMessage(NULL, TRANSM_OVER);
00126 scheduleAt(simTime() + frame->getDuration(), timer);
00127 sendDown(frame);
00128 }
|
|
|
Initialize variables and publish the radio status. All values not present in the ned file will be read from the ChannelControl module or assigned default values. Reimplemented from BasicSnrEval. Reimplemented in GilbertElliotSnr, and SnrEval80211. 00032 {
00033 BasicSnrEval::initialize(stage);
00034
00035 if (stage == 0)
00036 {
00037 if (hasPar("thermalNoise"))
00038 thermalNoise = FWMath::dBm2mW(par("thermalNoise"));
00039 else
00040 thermalNoise = FWMath::dBm2mW(-100);
00041
00042 if (hasPar("carrierFrequency"))
00043 carrierFrequency = par("carrierFrequency");
00044 else
00045 carrierFrequency = cc->par("carrierFrequency");
00046
00047 if (hasPar("sensitivity"))
00048 sensitivity = FWMath::dBm2mW(par("sensitivity"));
00049 else
00050 sensitivity = FWMath::dBm2mW(-90);
00051
00052 if (hasPar("pathLossAlpha"))
00053 {
00054 pathLossAlpha = par("pathLossAlpha");
00055 if (pathLossAlpha < (double) (cc->par("alpha")))
00056 error("SnrEval::initialize() pathLossAlpha can't be smaller than in "
00057 "ChannelControl. Please adjust your omnetpp.ini file accordingly");
00058 }
00059 else
00060 pathLossAlpha = cc->par("alpha");
00061
00062 // initialize noiseLevel
00063 noiseLevel = thermalNoise;
00064
00065 EV << "Initialized channel with noise: " << noiseLevel << " sensitivity: " << sensitivity <<
00066 endl;
00067
00068 // initialize the pointer of the snrInfo with NULL to indicate
00069 // that currently no message is received
00070 snrInfo.ptr = NULL;
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 else if (stage == 1)
00079 {
00080 // tell initial value to MAC; must be done in stage 1, because they
00081 // subscribe in stage 0
00082 nb->fireChangeNotification(NF_RADIOSTATE_CHANGED, &rs);
00083 }
00084 }
|
|
|
The carrier frequency used.Can be specified in the omnetpp.ini file. If not it is read from the ChannelControl module.
|
|
|
The noise level of the channel.
|
|
|
Path loss coefficient. Can be specified in omnetpp.ini. If not it is read from the ChannelControl module. This value CANNOT be smaller than the one specified in the ChannelControl module. The simulation will exit with an error!
|
|
|
A buffer to store a pointer to a message and the related receive power.
|
|
|
Actual RadioState of the nic.
|
|
|
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.
|
|
|
SnrInfo stores the snrList and the the recvdPower for the message currently being received together with a pointer to the message.
|
|
|
Thermal noise on the channel. Can be specified in omnetpp.ini. Default: -100 dBm.
|
1.4.1