INET Framework for OMNeT++/OMNEST
GilbertElliotSnr.cc
Go to the documentation of this file.
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 }