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