|
INET Framework for OMNeT++/OMNEST
|
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 }