INET Framework for OMNeT++/OMNEST
BasicSnrEval.cc
Go to the documentation of this file.
00001 /***************************************************************************
00002  * file:        BasicSnrEval.cc
00003  *
00004  * author:      Marc Loebbers
00005  *
00006  * copyright:   (C) 2004 Telecommunication Networks Group (TKN) at
00007  *              Technische Universitaet Berlin, Germany.
00008  *
00009  *              This program is free software; you can redistribute it
00010  *              and/or modify it under the terms of the GNU General Public
00011  *              License as published by the Free Software Foundation; either
00012  *              version 2 of the License, or (at your option) any later
00013  *              version.
00014  *              For further information see file COPYING
00015  *              in the top level directory
00016  ***************************************************************************
00017  * part of:     framework implementation developed by tkn
00018  ***************************************************************************/
00019 
00020 
00021 #include "BasicSnrEval.h"
00022 //#include "MacPkt_m.h"
00023 #include "TransmComplete_m.h"
00024 
00025 
00026 #define coreEV (ev.isDisabled()||!coreDebug) ? ev : ev << logName() << "::BasicSnrEval: "
00027 
00028 Define_Module(BasicSnrEval);
00029 
00040 void BasicSnrEval::initialize(int stage)
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 }
00063 
00079 void BasicSnrEval::handleMessage(cMessage *msg)
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 }
00113 
00120 void BasicSnrEval::bufferMsg(AirFrame * frame) //FIXME: 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 }
00131 
00138 AirFrame *BasicSnrEval::encapsMsg(cPacket *msg)
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 }
00150 
00159 double BasicSnrEval::calcDuration(cPacket *af)
00160 {
00161     double duration;
00162     duration = (double) af->getBitLength() / (double) bitrate;
00163     return duration;
00164 }
00165 
00175 void BasicSnrEval::sendUp(AirFrame *msg, SnrList& list)
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 }
00186 
00192 void BasicSnrEval::sendDown(AirFrame *msg)
00193 {
00194     sendToChannel(msg);
00195 }
00196 
00201 AirFrame *BasicSnrEval::unbufferMsg(cMessage *msg)
00202 {
00203     AirFrame *frame = (AirFrame *) msg->getContextPointer();
00204     //delete the self message
00205     delete msg;
00206 
00207     return frame;
00208 }
00209 
00221 void BasicSnrEval::handleUpperMsg(AirFrame * frame)
00222 {
00223     sendDown(frame);
00224 }
00225 
00243 void BasicSnrEval::handleLowerMsgEnd(AirFrame * frame)
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 }
00268 
00294 void BasicSnrEval::handleLowerMsgStart(AirFrame * frame)
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 }