|
INET Framework for OMNeT++/OMNEST
|
00001 /* -*- mode:c++ -*- ******************************************************** 00002 * file: GilbertElliotSnr.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 "GilbertElliotSnr.h" 00022 00023 00024 Define_Module(GilbertElliotSnr); 00025 00026 GilbertElliotSnr::GilbertElliotSnr() 00027 { 00028 stateChange = NULL; 00029 } 00030 00031 GilbertElliotSnr::~GilbertElliotSnr() 00032 { 00033 cancelAndDelete(stateChange); 00034 } 00035 00040 void GilbertElliotSnr::initialize(int stage) 00041 { 00042 SnrEval::initialize(stage); 00043 00044 if (stage == 0) 00045 { 00046 meanGood = par("meanGood"); 00047 meanBad = par("meanBad"); 00048 stateChange = new cMessage(); 00049 stateChange->setKind(38); 00050 state = GOOD; 00051 scheduleAt(simTime() + exponential(meanGood, 0), stateChange); 00052 EV << "GE state will change at: " << stateChange->getArrivalTime() << endl; 00053 } 00054 } 00055 00066 void GilbertElliotSnr::handleSelfMsg(cMessage *msg) 00067 { 00068 if (msg->getKind() == TRANSM_OVER) 00069 { 00070 00071 if (noiseLevel < sensitivity) 00072 { 00073 // set the RadioState to IDLE 00074 rs.setState(RadioState::IDLE); 00075 EV << "transmission over, switch to idle mode (state:IDLE)\n"; 00076 nb->fireChangeNotification(NF_RADIOSTATE_CHANGED, &rs); 00077 } 00078 else 00079 { 00080 // set the RadioState to RECV 00081 rs.setState(RadioState::RECV); 00082 EV << "transmission over but noise level to high, switch to recv mode (state:RECV)\n"; 00083 nb->fireChangeNotification(NF_RADIOSTATE_CHANGED, &rs); 00084 } 00085 00086 // delete the timer 00087 delete msg; 00088 } 00089 else if (msg == stateChange) 00090 { 00091 EV << "GilbertElliot state changed!\n"; 00092 if (state == GOOD) 00093 { 00094 state = BAD; 00095 for (RecvBuff::iterator it = recvBuff.begin(); it != recvBuff.end(); it++) 00096 (it->first)->setBitError(true); 00097 scheduleAt(simTime() + exponential(meanBad, 0), stateChange); 00098 } 00099 else if (state == BAD) 00100 { 00101 state = GOOD; 00102 scheduleAt(simTime() + exponential(meanGood, 0), stateChange); 00103 } 00104 } 00105 else 00106 error("Internal error: unknown self-message `%s'", msg->getName()); 00107 } 00108 00109 00135 void GilbertElliotSnr::handleLowerMsgStart(AirFrame * frame) 00136 { 00137 // Calculate the receive power of the message 00138 00139 // calculate distance 00140 const Coord& myPos = getMyPosition(); 00141 const Coord& framePos = frame->getSenderPos(); 00142 double distance = myPos.distance(framePos); 00143 00144 // receive power 00145 double rcvdPower = calcRcvdPower(frame->getPSend(), distance); 00146 00147 if (state == BAD) 00148 frame->setBitError(true); 00149 00150 // store the receive power in the recvBuff 00151 recvBuff[frame] = rcvdPower; 00152 00153 // if receive power is bigger than sensitivity and if not sending 00154 // and currently not receiving another message 00155 if (rcvdPower >= sensitivity && rs.getState() != RadioState::TRANSMIT && snrInfo.ptr == NULL) 00156 { 00157 EV << "receiving frame\n"; 00158 00159 // Put frame and related SnrList in receive buffer 00160 SnrList snrList; //defined in SnrList.h!! 00161 snrInfo.ptr = frame; 00162 snrInfo.rcvdPower = rcvdPower; 00163 snrInfo.sList = snrList; 00164 00165 // add initial snr value 00166 addNewSnr(); 00167 00168 if (rs.getState() != RadioState::RECV) 00169 { 00170 // publish new RadioState 00171 rs.setState(RadioState::RECV); 00172 EV << "publish new RadioState:RECV\n"; 00173 nb->fireChangeNotification(NF_RADIOSTATE_CHANGED, &rs); 00174 } 00175 } 00176 // receive power is to low or another message is being send or received 00177 else 00178 { 00179 EV << "frame is just noise\n"; 00180 //add receive power to the noise level 00181 noiseLevel += rcvdPower; 00182 00183 // if a message is being received add a new snr value 00184 if (snrInfo.ptr != NULL) 00185 { 00186 // update snr info for currently being received message 00187 EV << "add new snr value to snr list of message being received\n"; 00188 addNewSnr(); 00189 } 00190 00191 // update the RadioState if the noiseLevel exceeded the threshold 00192 // and the radio is currently not in receive or in send mode 00193 if (noiseLevel >= sensitivity && rs.getState() == RadioState::IDLE) 00194 { 00195 // publish new RadioState 00196 rs.setState(RadioState::RECV); 00197 EV << "publish new RadioState:RECV\n"; 00198 nb->fireChangeNotification(NF_RADIOSTATE_CHANGED, &rs); 00199 } 00200 } 00201 } 00202 00203 00215 void GilbertElliotSnr::handleLowerMsgEnd(AirFrame * frame) 00216 { 00217 00218 //check state again: 00219 if (state == BAD) 00220 frame->setBitError(true); 00221 00222 // check if message has to be send to the decider 00223 if (snrInfo.ptr == frame) 00224 { 00225 EV << "reception of frame over, preparing to send packet to upper layer\n"; 00226 // get Packet and list out of the receive buffer: 00227 SnrList list; 00228 list = snrInfo.sList; 00229 00230 // delete the pointer to indicate that no message is currently 00231 // being received and clear the list 00232 snrInfo.ptr = NULL; 00233 snrInfo.sList.clear(); 00234 00235 // delete the frame from the recvBuff 00236 recvBuff.erase(frame); 00237 00238 //Don't forget to send: 00239 sendUp(frame, list); 00240 EV << "packet sent to the decider\n"; 00241 } 00242 // all other messages are noise 00243 else 00244 { 00245 EV << "reception of noise message over, removing recvdPower from noiseLevel....\n"; 00246 // get the rcvdPower and subtract it from the noiseLevel 00247 noiseLevel -= recvBuff[frame]; 00248 00249 // delete message from the recvBuff 00250 recvBuff.erase(frame); 00251 00252 // update snr info for message currently being received if any 00253 if (snrInfo.ptr != NULL) 00254 { 00255 addNewSnr(); 00256 } 00257 00258 // message should be deleted 00259 delete frame; 00260 EV << "message deleted\n"; 00261 } 00262 00263 // check the RadioState and update if necessary 00264 // change to idle if noiseLevel smaller than threshold and state was 00265 // not idle before 00266 // do not change state if currently sending or receiving a message!!! 00267 if (noiseLevel < sensitivity && rs.getState() == RadioState::RECV && snrInfo.ptr == NULL) 00268 { 00269 // publish the new RadioState: 00270 EV << "new RadioState is IDLE\n"; 00271 rs.setState(RadioState::IDLE); 00272 nb->fireChangeNotification(NF_RADIOSTATE_CHANGED, &rs); 00273 } 00274 }