#include <BasicSnrEval.h>
The BasicSnrEval module provides functionality like en- and decapsulation of messages. If you use the standard message formats everything should work fine. Before a packet is sent some information, e.g. transmission power, can be written to the AirFrame header. If you write your own snrEval, just subclass and redefine the handleUpperMsg function (see description of the function). After receiving a message it can be processed in handleLowerMsgStart. Then it is buffered for the time the transmission would last in reality, and then can be handled again. Again you can redefine the 1. handleLowerMsgStart and 2. handleLowerMsgEnd for your own needs (see description). So, the call of these functions represent the following events: 1. received a message (i.e. transmission startet) 2. message will be handed on to the upper layer (i.e. transmission time is over)
This supports a single radio channel only
Protected Member Functions | |
virtual void | initialize (int) |
Initialization of the module and some variables. | |
virtual void | handleMessage (cMessage *) |
Called every time a message arrives. | |
virtual double | calcDuration (cPacket *) |
This function calculates the duration of the AirFrame. | |
virtual int | getChannelNumber () const |
Returns the channel we're listening on. This version always returns 0 (single radio channel supported). | |
Handle Messages | |
Functions to redefine by the programmer | |
virtual void | handleUpperMsg (AirFrame *) |
Fill the header fields, redefine for your own needs... | |
virtual void | handleSelfMsg (cMessage *msg) |
Handle self messages such as timer... | |
virtual void | handleLowerMsgStart (AirFrame *) |
Calculate Snr Information before buffering. | |
virtual void | handleLowerMsgEnd (AirFrame *) |
Calculate SnrInfo after buffering and add the PhySnrList to the message. | |
Convenience Functions | |
Functions for convenience - NOT to be modified
These are functions taking care of message encapsulation and message sending. Normally you should not need to alter these but should use them to handle message encasulation and sending. They will wirte all necessary information into packet headers and add or strip the appropriate headers for each layer. | |
virtual void | bufferMsg (AirFrame *frame) |
Buffers message for 'transmission time'. | |
virtual AirFrame * | unbufferMsg (cMessage *msg) |
Unbuffers a message after 'transmission time'. | |
virtual void | sendUp (AirFrame *, SnrList &) |
Sends a message to the upper layer. | |
virtual void | sendDown (AirFrame *msg) |
Sends a message to the channel. | |
virtual AirFrame * | encapsMsg (cPacket *msg) |
Encapsulates a MAC frame into an Air Frame. | |
Abstraction layer | |
Factory function to create AirFrame into which a MAC frame is encapsulated. SnrEval authors should be able to use their own SnrEval packets. The framework does not need to know about them, but must be able to produce new ones. Both goals can be reached by using a factory method.
Overwrite this function in derived classes to use your own AirFrames | |
virtual AirFrame * | createCapsulePkt () |
Create a new AirFrame. | |
Protected Attributes | |
double | bitrate |
a parameter that has to be read in from omnetpp.ini | |
int | headerLength |
a parameter that has to be read in from omnetpp.ini | |
double | transmitterPower |
power used to transmit messages | |
int | uppergateOut |
gate id | |
int | uppergateIn |
void BasicSnrEval::initialize | ( | int | stage | ) | [protected, virtual] |
Initialization of the module and some variables.
First we have to initialize the module from which we derived ours, in this case ChannelAccess.
Then we have to intialize the gates and - if necessary - some own variables.
If you want to use your own AirFrames you have to redefine createCapsulePkt function.
Reimplemented from ChannelAccess.
Reimplemented in GilbertElliotSnr, SnrEval, and SnrEval80211.
Referenced by SnrEval::initialize().
00041 { 00042 ChannelAccess::initialize(stage); 00043 00044 coreEV << "Initializing BasicSnrEval, stage=" << stage << endl; 00045 00046 if (stage == 0) 00047 { 00048 gate("radioIn")->setDeliverOnReceptionStart(true); 00049 00050 uppergateIn = findGate("uppergateIn"); 00051 uppergateOut = findGate("uppergateOut"); 00052 00053 headerLength = par("headerLength"); 00054 bitrate = par("bitrate"); 00055 00056 transmitterPower = par("transmitterPower"); 00057 00058 // transmitter power CANNOT be greater than in ChannelControl 00059 if (transmitterPower > (double) (cc->par("pMax"))) 00060 error("transmitterPower cannot be bigger than pMax in ChannelControl!"); 00061 } 00062 }
void BasicSnrEval::handleMessage | ( | cMessage * | msg | ) | [protected, virtual] |
Called every time a message arrives.
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.
Reimplemented in SnrEval.
Referenced by SnrEval::handleMessage().
00080 { 00081 if (msg->getArrivalGateId() == uppergateIn) 00082 { 00083 AirFrame *frame = encapsMsg(PK(msg)); 00084 handleUpperMsg(frame); 00085 } 00086 else if (msg->isSelfMessage()) 00087 { 00088 if (dynamic_cast<TransmComplete *>(msg) != 0) 00089 { 00090 coreEV << "frame is completely received now\n"; 00091 00092 // unbuffer the message 00093 AirFrame *frame = unbufferMsg(msg); 00094 00095 handleLowerMsgEnd(frame); 00096 } 00097 else 00098 handleSelfMsg(msg); 00099 } 00100 else if (check_and_cast<AirFrame *>(msg)->getChannelNumber() == getChannelNumber()) 00101 { 00102 // must be an AirFrame 00103 AirFrame *frame = (AirFrame *) msg; 00104 handleLowerMsgStart(frame); 00105 bufferMsg(frame); 00106 } 00107 else 00108 { 00109 EV << "listening to different channel when receiving message -- dropping it\n"; 00110 delete msg; 00111 } 00112 }
void BasicSnrEval::handleUpperMsg | ( | AirFrame * | frame | ) | [protected, virtual] |
Fill the header fields, redefine for your own needs...
Redefine this function if you want to process messages from upper layers before they are send to the channel.
The MAC frame is already encapsulated in an AirFrame and all standard header fields are set.
To forward the message to lower layers after processing it please use sendDown. It will take care of decapsulation and anything else needed
Reimplemented in SnrEval.
Referenced by handleMessage().
00222 { 00223 sendDown(frame); 00224 }
virtual void BasicSnrEval::handleSelfMsg | ( | cMessage * | msg | ) | [inline, protected, virtual] |
Handle self messages such as timer...
Define this function if you want to process timer or other kinds of self messages
Reimplemented in GilbertElliotSnr, and SnrEval.
Referenced by handleMessage().
void BasicSnrEval::handleLowerMsgStart | ( | AirFrame * | frame | ) | [protected, virtual] |
Calculate Snr Information before buffering.
Redefine this function if you want to process messages from the channel before they are forwarded to upper layers
This function is called right after a message is received, i.e. right before it is buffered for 'transmission time'.
Here you should decide whether the message is "really" received or whether it's receive power is so low that it is just treated as noise.
If the energy of the message is high enough to really receive it you should create an snr list (SnrList) to be able to store sn(i)r information for that message. Every time a new message arrives you can add a new snr value together with a timestamp to that list. Make sure to store a pointer to the mesage together with the snr information to be able to retrieve it later.
In this function also an initial SNR value can be calculated for this message.
Please take a look at SnrEval to see a "real" example.
Reimplemented in GilbertElliotSnr, and SnrEval.
Referenced by handleMessage().
00295 { 00296 coreEV << "in handleLowerMsgStart, receiving frame " << frame->getName() << endl; 00297 00298 //calculate the receive power 00299 00300 // calculate snr information, like snr=pSend/noise or whatever.... 00301 00302 // if receive power is actually high enough to be able to read the 00303 // message and no other message is currently being received, store 00304 // the snr information for the message someweher where you can find 00305 // it in handleLowerMsgEnd 00306 }
void BasicSnrEval::handleLowerMsgEnd | ( | AirFrame * | frame | ) | [protected, virtual] |
Calculate SnrInfo after buffering and add the PhySnrList to the message.
Redefine this function if you want to process messages from the channel before they are forwarded to upper layers
This function is called right before a packet is handed on to the upper layer, i.e. right after unbufferMsg. Again you can caluculate some more SNR information if you want.
You have to copy / create the SnrList related to the message and pass it to sendUp() if you want to pass the message to the decider.
Do not forget to send the message to the upper layer with sendUp()
For a "real" implementaion take a look at SnrEval
Reimplemented in GilbertElliotSnr, and SnrEval.
Referenced by handleMessage().
00244 { 00245 coreEV << "in handleLowerMsgEnd\n"; 00246 00247 // We need to create a "dummy" snr list that we can pass together 00248 // with the message to the decider module so that also the 00249 // BasicSnrEval is able to work. 00250 SnrList snrList; 00251 00252 // However you can take this as a reference how to create your own 00253 // snr entries. 00254 00255 // Everytime you want to add something to the snr information list 00256 // it has to look like this: 00257 // 1. create a list entry and fill the fields 00258 SnrListEntry listEntry; 00259 listEntry.time = simTime(); 00260 listEntry.snr = 3; //just a senseless example 00261 00262 // 2. add an entry to the SnrList 00263 snrList.push_back(listEntry); 00264 00265 // 3. pass the message together with the list to the decider 00266 sendUp(frame, snrList); 00267 }
void BasicSnrEval::bufferMsg | ( | AirFrame * | frame | ) | [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 SnrEval::changeChannel(), and handleMessage().
00120 : add explicit simtime_t atTime arg? 00121 { 00122 // set timer to indicate transmission is complete 00123 TransmComplete *endRxTimer = new TransmComplete(NULL); 00124 endRxTimer->setContextPointer(frame); 00125 frame->setContextPointer(endRxTimer); 00126 // NOTE: use arrivalTime instead of simTime, because we might be calling this 00127 // function during a channel change, when we're picking up ongoing transmissions 00128 // on the channel -- and then the message's arrival time is in the past! 00129 scheduleAt(frame->getArrivalTime() + frame->getDuration(), endRxTimer); 00130 }
AirFrame * BasicSnrEval::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 handleMessage().
00202 { 00203 AirFrame *frame = (AirFrame *) msg->getContextPointer(); 00204 //delete the self message 00205 delete msg; 00206 00207 return frame; 00208 }
void BasicSnrEval::sendUp | ( | AirFrame * | msg, | |
SnrList & | list | |||
) | [protected, virtual] |
Sends a message to the upper layer.
Attach control info to the message and send message to the upper layer.
msg | AirFrame to pass to the decider | |
list | Snr list to attach as control info |
Referenced by SnrEval::handleLowerMsgEnd(), GilbertElliotSnr::handleLowerMsgEnd(), and handleLowerMsgEnd().
00176 { 00177 // create ControlInfo 00178 SnrControlInfo *cInfo = new SnrControlInfo; 00179 // attach the list to cInfo 00180 cInfo->setSnrList(list); 00181 // attach the cInfo to the AirFrame 00182 msg->setControlInfo(cInfo); 00183 00184 send(msg, uppergateOut); 00185 }
void BasicSnrEval::sendDown | ( | AirFrame * | msg | ) | [protected, virtual] |
Sends a message to the channel.
Referenced by SnrEval::handleUpperMsg(), and handleUpperMsg().
00193 { 00194 sendToChannel(msg); 00195 }
AirFrame * BasicSnrEval::encapsMsg | ( | cPacket * | msg | ) | [protected, virtual] |
Encapsulates a MAC frame into an Air Frame.
This function encapsulates messages from the upper layer into an AirFrame, copies the type and channel fields, adds the headerLength, sets the pSend (transmitterPower) and returns the AirFrame.
Referenced by handleMessage().
00139 { 00140 AirFrame *frame = createCapsulePkt(); 00141 frame->setName(msg->getName()); 00142 frame->setPSend(transmitterPower); 00143 frame->setBitLength(headerLength); 00144 frame->setChannelNumber(getChannelNumber()); 00145 frame->encapsulate(msg); 00146 frame->setDuration(calcDuration(frame)); 00147 frame->setSenderPos(getMyPosition()); 00148 return frame; 00149 }
double BasicSnrEval::calcDuration | ( | cPacket * | af | ) | [protected, virtual] |
This function calculates the duration of the AirFrame.
Usually the duration is just the frame length divided by the bitrate. However there may be cases (like 802.11) where the header has a different modulation (and thus a different bitrate) than the rest of the message.
Just redefine this function in such a case!
Reimplemented in SnrEval80211.
Referenced by encapsMsg().
00160 { 00161 double duration; 00162 duration = (double) af->getBitLength() / (double) bitrate; 00163 return duration; 00164 }
virtual int BasicSnrEval::getChannelNumber | ( | ) | const [inline, protected, virtual] |
Returns the channel we're listening on. This version always returns 0 (single radio channel supported).
Reimplemented in SnrEval.
Referenced by encapsMsg(), and handleMessage().
virtual AirFrame* BasicSnrEval::createCapsulePkt | ( | ) | [inline, protected, virtual] |
double BasicSnrEval::bitrate [protected] |
a parameter that has to be read in from omnetpp.ini
Referenced by SnrEval80211::calcDuration(), calcDuration(), SnrEval80211::initialize(), and initialize().
int BasicSnrEval::headerLength [protected] |
a parameter that has to be read in from omnetpp.ini
Referenced by SnrEval80211::calcDuration(), encapsMsg(), SnrEval80211::initialize(), and initialize().
double BasicSnrEval::transmitterPower [protected] |
int BasicSnrEval::uppergateOut [protected] |
int BasicSnrEval::uppergateIn [protected] |
Referenced by SnrEval::handleMessage(), handleMessage(), and initialize().