00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "PhyLayerBattery.h"
00017 #include "Decider80211MultiChannel.h"
00018
00019 Define_Module(PhyLayerBattery);
00020
00021 void PhyLayerBattery::initialize(int stage) {
00022 PhyLayer::initialize(stage);
00023 if (stage == 0) {
00024 numActivities = hasPar("numActivities") ? par("numActivities").longValue() : 5;
00025
00026
00027
00028
00029
00030
00031 sleepCurrent = rxCurrent = decodingCurrentDelta = txCurrent = 0;
00032 setupRxCurrent = setupTxCurrent = rxTxCurrent = txRxCurrent = 0;
00033 sleepCurrent = getParentModule()->par( "sleepCurrent" );
00034 rxCurrent = getParentModule()->par( "rxCurrent" );
00035 decodingCurrentDelta = getParentModule()->par( "decodingCurrentDelta" );
00036 txCurrent = getParentModule()->par( "txCurrent" );
00037 setupRxCurrent = getParentModule()->par( "setupRxCurrent" );
00038 setupTxCurrent = getParentModule()->par( "setupTxCurrent" );
00039 rxTxCurrent = getParentModule()->par( "rxTxCurrent" );
00040 txRxCurrent = getParentModule()->par( "txRxCurrent" );
00041 } else {
00042 registerWithBattery("physical layer", numActivities);
00043 setRadioCurrent(radio->getCurrentState());
00044
00045 }
00046 }
00047
00048 Decider* PhyLayerBattery::getDeciderFromName(std::string name, ParameterMap& params) {
00049 if(name == "Decider80211Battery") {
00050 return initializeDecider80211Battery(params);
00051 }
00052 else if(name == "Decider80211MultiChannel") {
00053 return initializeDecider80211MultiChannel(params);
00054 }
00055
00056 return PhyLayer::getDeciderFromName(name, params);
00057 }
00058
00059 Decider* PhyLayerBattery::initializeDecider80211Battery(ParameterMap& params) {
00060 double threshold = params["threshold"];
00061 return new Decider80211Battery(this,
00062 threshold,
00063 sensitivity,
00064 radio->getCurrentChannel(),
00065 decodingCurrentDelta,
00066 findHost()->getIndex(),
00067 coreDebug);
00068 }
00069
00070 Decider* PhyLayerBattery
00071 ::initializeDecider80211MultiChannel(ParameterMap& params)
00072 {
00073 double threshold = params["threshold"];
00074 return new Decider80211MultiChannel(this,
00075 threshold,
00076 sensitivity,
00077 decodingCurrentDelta,
00078 radio->getCurrentChannel(),
00079 findHost()->getIndex(),
00080 coreDebug);
00081 }
00082
00083 void PhyLayerBattery::drawCurrent(double amount, int activity) {
00084 if(radio->getCurrentState() == Radio::RX) {
00085 if(amount != 0.0) {
00086 BatteryAccess::drawCurrent(rxCurrent + amount, DECIDER_ACCT + activity);
00087 } else {
00088 BatteryAccess::drawCurrent(rxCurrent, RX_ACCT);
00089 }
00090 } else {
00091 opp_warning("Decider wanted to change power consumption while radio not in state RX.");
00092 }
00093 }
00094
00095 void PhyLayerBattery::handleUpperMessage(cMessage* msg) {
00096 if (utility->getHostState().get() == HostState::FAILED) {
00097 coreEV<< "host has FAILED, dropping msg " << msg->getName() << endl;
00098 delete msg;
00099 return;
00100 }
00101
00102 MacPkt* pkt = static_cast<MacPkt*>(msg);
00103 MacToPhyControlInfo* cInfo = static_cast<MacToPhyControlInfo*>(pkt->getControlInfo());
00104
00105 double current = calcTXCurrentForPacket(pkt, cInfo);
00106
00107 if(current > 0) {
00108 BatteryAccess::drawCurrent(current, TX_ACCT);
00109 }
00110
00111 PhyLayer::handleUpperMessage(msg);
00112 }
00113
00114 void PhyLayerBattery::handleAirFrame(cMessage* msg) {
00115 if (utility->getHostState().get() == HostState::FAILED) {
00116 coreEV<< "host has FAILED, dropping msg " << msg->getName() << endl;
00117 delete msg;
00118 return;
00119 }
00120
00121 PhyLayer::handleAirFrame(msg);
00122
00123
00124 }
00125
00126 void PhyLayerBattery::handleHostState(const HostState& state) {
00127
00128
00129 HostState::States hostState = state.get();
00130
00131 switch (hostState) {
00132 case HostState::FAILED:
00133 EV<< "t = " << simTime() << " host state FAILED" << endl;
00134
00135 break;
00136 default:
00137 break;
00138 }
00139 }
00140
00141 void PhyLayerBattery::finishRadioSwitching() {
00142 PhyLayer::finishRadioSwitching();
00143
00144 setRadioCurrent(radio->getCurrentState());
00145 }
00146
00147 void PhyLayerBattery::setSwitchingCurrent(int from, int to) {
00148 int act = SWITCHING_ACCT;
00149 double current = 0;
00150
00151 switch(from) {
00152 case Radio::RX:
00153 switch(to) {
00154 case Radio::SLEEP:
00155 current = rxCurrent;
00156 break;
00157 case Radio::TX:
00158 current = rxTxCurrent;
00159 break;
00160 default:
00161 opp_error("Unknown radio switch! From RX to %d", to);
00162 }
00163 break;
00164
00165 case Radio::TX:
00166 switch(to) {
00167 case Radio::SLEEP:
00168 current = txCurrent;
00169 break;
00170 case Radio::RX:
00171 current = txRxCurrent;
00172 break;
00173 default:
00174 opp_error("Unknown radio switch! From TX to %d", to);
00175 }
00176 break;
00177
00178 case Radio::SLEEP:
00179 switch(to) {
00180 case Radio::TX:
00181 current = setupTxCurrent;
00182 break;
00183 case Radio::RX:
00184 current = setupRxCurrent;
00185 break;
00186 default:
00187 opp_error("Unknown radio switch! From SLEEP to %d", to);
00188 }
00189 break;
00190
00191 default:
00192 opp_error("Unknown radio state: %d", from);
00193 }
00194
00195 BatteryAccess::drawCurrent(current, act);
00196 }
00197
00198 void PhyLayerBattery::setRadioCurrent(int rs) {
00199 switch(rs) {
00200 case Radio::RX:
00201 BatteryAccess::drawCurrent(rxCurrent, RX_ACCT);
00202 break;
00203 case Radio::TX:
00204 BatteryAccess::drawCurrent(txCurrent, TX_ACCT);
00205 break;
00206 case Radio::SLEEP:
00207 BatteryAccess::drawCurrent(sleepCurrent, SLEEP_ACCT);
00208 break;
00209 default:
00210 opp_error("Unknown radio state: %d", rs);
00211 break;
00212 }
00213 }
00214
00215 simtime_t PhyLayerBattery::setRadioState(int rs) {
00216 Enter_Method_Silent();
00217 int prevState = radio->getCurrentState();
00218
00219 simtime_t endSwitch = PhyLayer::setRadioState(rs);
00220
00221 if(endSwitch > 0) {
00222
00223 if(radio->getCurrentState() == Radio::SWITCHING) {
00224 setSwitchingCurrent(prevState, rs);
00225 } else {
00226 setRadioCurrent(radio->getCurrentState());
00227 }
00228 }
00229
00230 return endSwitch;
00231 }