wifi: (fixes #2809) Stop wifi devices when energy is depleted
This commit is contained in:
@@ -39,6 +39,7 @@ Bugs fixed
|
||||
- Bug 2766 - core: Modify logging for int64x64 to avoid stack overflow
|
||||
- Bug 2768 - lte: LteUeNetDevice has a null MAC address
|
||||
- Bug 2807 - energy: GetTotalEnergyConsumption is not updated correctly
|
||||
- Bug 2809 - wifi: Wifi doesn't fully stop when energy is depleted
|
||||
- Bug 2820 - wifi: segmentation fault when Rrpaa wifi manager is used
|
||||
- Bug 2824 - ICMP opcode fr fragment timeout drop is wrong
|
||||
- Bug 2828 - OLSR simple P2P example produces wrong results
|
||||
|
||||
@@ -162,6 +162,7 @@ BasicEnergySource::UpdateEnergySource (void)
|
||||
|
||||
m_energyUpdateEvent.Cancel ();
|
||||
|
||||
double remainingEnergy = m_remainingEnergyJ;
|
||||
CalculateRemainingEnergy ();
|
||||
|
||||
m_lastUpdateTime = Simulator::Now ();
|
||||
@@ -171,12 +172,15 @@ BasicEnergySource::UpdateEnergySource (void)
|
||||
m_depleted = true;
|
||||
HandleEnergyDrainedEvent ();
|
||||
}
|
||||
|
||||
if (m_depleted && m_remainingEnergyJ > m_highBatteryTh * m_initialEnergyJ)
|
||||
else if (m_depleted && m_remainingEnergyJ > m_highBatteryTh * m_initialEnergyJ)
|
||||
{
|
||||
m_depleted = false;
|
||||
HandleEnergyRechargedEvent ();
|
||||
}
|
||||
else if (m_remainingEnergyJ != remainingEnergy)
|
||||
{
|
||||
NotifyEnergyChanged ();
|
||||
}
|
||||
|
||||
m_energyUpdateEvent = Simulator::Schedule (m_energyUpdateInterval,
|
||||
&BasicEnergySource::UpdateEnergySource,
|
||||
@@ -223,19 +227,11 @@ BasicEnergySource::CalculateRemainingEnergy (void)
|
||||
NS_LOG_FUNCTION (this);
|
||||
double totalCurrentA = CalculateTotalCurrent ();
|
||||
Time duration = Simulator::Now () - m_lastUpdateTime;
|
||||
NS_ASSERT (duration.GetSeconds () >= 0);
|
||||
NS_ASSERT (duration.IsPositive ());
|
||||
// energy = current * voltage * time
|
||||
double energyToDecreaseJ = totalCurrentA * m_supplyVoltageV * duration.GetSeconds ();
|
||||
|
||||
if (m_remainingEnergyJ < energyToDecreaseJ)
|
||||
{
|
||||
m_remainingEnergyJ = 0; // energy never goes below 0
|
||||
}
|
||||
else
|
||||
{
|
||||
m_remainingEnergyJ -= energyToDecreaseJ;
|
||||
}
|
||||
|
||||
double energyToDecreaseJ = (totalCurrentA * m_supplyVoltageV * duration.GetNanoSeconds ()) / 1e9;
|
||||
NS_ASSERT (m_remainingEnergyJ >= energyToDecreaseJ);
|
||||
m_remainingEnergyJ -= energyToDecreaseJ;
|
||||
NS_LOG_DEBUG ("BasicEnergySource:Remaining energy = " << m_remainingEnergyJ);
|
||||
}
|
||||
|
||||
|
||||
@@ -99,6 +99,12 @@ public:
|
||||
*/
|
||||
virtual void HandleEnergyRecharged (void) = 0;
|
||||
|
||||
/**
|
||||
* This function is called by the EnergySource object when energy stored in
|
||||
* the energy source is changed. Should be implemented by child classes.
|
||||
*/
|
||||
virtual void HandleEnergyChanged (void) = 0;
|
||||
|
||||
|
||||
private:
|
||||
/**
|
||||
|
||||
@@ -212,6 +212,18 @@ EnergySource::NotifyEnergyRecharged (void)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
EnergySource::NotifyEnergyChanged (void)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
// notify all device energy models installed on node
|
||||
DeviceEnergyModelContainer::Iterator i;
|
||||
for (i = m_models.Begin (); i != m_models.End (); i++)
|
||||
{
|
||||
(*i)->HandleEnergyChanged ();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
EnergySource::BreakDeviceEnergyModelRefCycle (void)
|
||||
{
|
||||
|
||||
@@ -228,6 +228,12 @@ protected:
|
||||
*/
|
||||
void NotifyEnergyRecharged (void);
|
||||
|
||||
/**
|
||||
* This function notifies all DeviceEnergyModel of energy changed event. It
|
||||
* is called by the child EnergySource class when energy source is changed.
|
||||
*/
|
||||
void NotifyEnergyChanged (void);
|
||||
|
||||
/**
|
||||
* This function is called to break reference cycle between EnergySource and
|
||||
* DeviceEnergyModel. Child of the EnergySource base class must call this
|
||||
|
||||
@@ -103,6 +103,15 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Handles energy changed.
|
||||
*
|
||||
* Not implemented
|
||||
*/
|
||||
virtual void HandleEnergyChanged (void)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* \param current the current draw of device.
|
||||
*
|
||||
|
||||
@@ -288,6 +288,14 @@ AcousticModemEnergyModel::HandleEnergyRecharged (void)
|
||||
SetMicroModemState(UanPhy::IDLE);
|
||||
}
|
||||
|
||||
void
|
||||
AcousticModemEnergyModel::HandleEnergyChanged (void)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
//Not implemented
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Private functions start here.
|
||||
*/
|
||||
|
||||
@@ -175,16 +175,21 @@ public:
|
||||
virtual void ChangeState (int newState);
|
||||
|
||||
/**
|
||||
* Handles energy depletion.
|
||||
* \brief Handles energy depletion.
|
||||
*/
|
||||
virtual void HandleEnergyDepletion (void);
|
||||
|
||||
/**
|
||||
* \brief Handles energy recharged.
|
||||
*/
|
||||
virtual void HandleEnergyRecharged (void);
|
||||
|
||||
/**
|
||||
* \brief Handles energy changed.
|
||||
*
|
||||
* Not implemented
|
||||
*/
|
||||
virtual void HandleEnergyRecharged (void);
|
||||
virtual void HandleEnergyChanged (void);
|
||||
|
||||
|
||||
private:
|
||||
|
||||
@@ -99,32 +99,32 @@ WifiRadioEnergyModelHelper::DoInstall (Ptr<NetDevice> device,
|
||||
Ptr<Node> node = device->GetNode ();
|
||||
Ptr<WifiRadioEnergyModel> model = m_radioEnergy.Create ()->GetObject<WifiRadioEnergyModel> ();
|
||||
NS_ASSERT (model != NULL);
|
||||
// set energy source pointer
|
||||
model->SetEnergySource (source);
|
||||
|
||||
// set energy depletion callback
|
||||
// if none is specified, make a callback to WifiPhy::SetSleepMode
|
||||
// if none is specified, make a callback to WifiPhy::SetOffMode
|
||||
Ptr<WifiNetDevice> wifiDevice = DynamicCast<WifiNetDevice> (device);
|
||||
Ptr<WifiPhy> wifiPhy = wifiDevice->GetPhy ();
|
||||
wifiPhy->SetWifiRadioEnergyModel (model);
|
||||
if (m_depletionCallback.IsNull ())
|
||||
{
|
||||
model->SetEnergyDepletionCallback (MakeCallback (&WifiPhy::SetSleepMode, wifiPhy));
|
||||
model->SetEnergyDepletionCallback (MakeCallback (&WifiPhy::SetOffMode, wifiPhy));
|
||||
}
|
||||
else
|
||||
{
|
||||
model->SetEnergyDepletionCallback (m_depletionCallback);
|
||||
}
|
||||
// set energy recharged callback
|
||||
// if none is specified, make a callback to WifiPhy::ResumeFromSleep
|
||||
if (m_rechargedCallback.IsNull ())
|
||||
{
|
||||
model->SetEnergyRechargedCallback (MakeCallback (&WifiPhy::ResumeFromSleep, wifiPhy));
|
||||
}
|
||||
else
|
||||
// if none is specified, make a callback to WifiPhy::ResumeFromOff
|
||||
//TODO: ResumeFromOff not supported yet
|
||||
//model->SetEnergyRechargedCallback (MakeCallback (&WifiPhy::ResumeFromOff, wifiPhy));
|
||||
if (!m_rechargedCallback.IsNull ())
|
||||
{
|
||||
model->SetEnergyRechargedCallback (m_rechargedCallback);
|
||||
}
|
||||
// add model to device model list in energy source
|
||||
source->AppendDeviceEnergyModel (model);
|
||||
// set energy source pointer
|
||||
model->SetEnergySource (source);
|
||||
// create and register energy model phy listener
|
||||
wifiPhy->RegisterListener (model->GetPhyListener ());
|
||||
//
|
||||
|
||||
@@ -460,6 +460,12 @@ MacLow::StartTransmission (Ptr<const Packet> packet,
|
||||
MacLowTransmissionParameters params,
|
||||
Ptr<DcaTxop> dca)
|
||||
{
|
||||
if (m_phy->IsStateOff ())
|
||||
{
|
||||
NS_LOG_DEBUG ("Cannot start TX because device is OFF");
|
||||
return;
|
||||
}
|
||||
|
||||
NS_LOG_FUNCTION (this << packet << hdr << params << dca);
|
||||
/* m_currentPacket is not NULL because someone started
|
||||
* a transmission and was interrupted before one of:
|
||||
@@ -572,8 +578,8 @@ MacLow::StartTransmission (Ptr<const Packet> packet,
|
||||
}
|
||||
}
|
||||
|
||||
/* When this method completes, we have taken ownership of the medium. */
|
||||
NS_ASSERT (m_phy->IsStateTx ());
|
||||
/* When this method completes, either we have taken ownership of the medium or the device switched off in the meantime. */
|
||||
NS_ASSERT (m_phy->IsStateTx () || m_phy->IsStateOff ());
|
||||
}
|
||||
|
||||
bool
|
||||
|
||||
@@ -40,7 +40,7 @@ WifiPhyTag::GetInstanceTypeId (void) const
|
||||
uint32_t
|
||||
WifiPhyTag::GetSerializedSize (void) const
|
||||
{
|
||||
return (sizeof (WifiTxVector) + 2);
|
||||
return (sizeof (WifiTxVector) + 2 + 1);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -48,6 +48,7 @@ WifiPhyTag::Serialize (TagBuffer i) const
|
||||
{
|
||||
i.Write ((uint8_t *)&m_wifiTxVector, sizeof (WifiTxVector));
|
||||
i.WriteU16 (m_mpduType);
|
||||
i.WriteU8 (m_frameComplete);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -55,20 +56,22 @@ WifiPhyTag::Deserialize (TagBuffer i)
|
||||
{
|
||||
i.Read ((uint8_t *)&m_wifiTxVector, sizeof (WifiTxVector));
|
||||
m_mpduType = static_cast<MpduType> (i.ReadU16 ());
|
||||
m_frameComplete = i.ReadU8 ();
|
||||
}
|
||||
void
|
||||
WifiPhyTag::Print (std::ostream &os) const
|
||||
{
|
||||
os << m_wifiTxVector << " " << m_mpduType;
|
||||
os << m_wifiTxVector << " " << m_mpduType << " " << m_frameComplete;
|
||||
}
|
||||
|
||||
WifiPhyTag::WifiPhyTag ()
|
||||
{
|
||||
}
|
||||
|
||||
WifiPhyTag::WifiPhyTag (WifiTxVector txVector, MpduType mpdutype)
|
||||
WifiPhyTag::WifiPhyTag (WifiTxVector txVector, MpduType mpdutype, uint8_t frameComplete)
|
||||
: m_wifiTxVector (txVector),
|
||||
m_mpduType (mpdutype)
|
||||
m_mpduType (mpdutype),
|
||||
m_frameComplete (frameComplete)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -84,4 +87,10 @@ WifiPhyTag::GetMpduType (void) const
|
||||
return m_mpduType;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
WifiPhyTag::GetFrameComplete (void) const
|
||||
{
|
||||
return m_frameComplete;
|
||||
}
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
@@ -50,8 +50,9 @@ public:
|
||||
* Constructor
|
||||
* \param txVector the WifiTxVector
|
||||
* \param mpdutype the mpduType
|
||||
* \param frameComplete the frameComplete
|
||||
*/
|
||||
WifiPhyTag (WifiTxVector txVector, MpduType mpdutype);
|
||||
WifiPhyTag (WifiTxVector txVector, MpduType mpdutype, uint8_t frameComplete);
|
||||
/**
|
||||
* Getter for WifiTxVector parameter
|
||||
* \return the WifiTxVector
|
||||
@@ -62,6 +63,11 @@ public:
|
||||
* \return mpduType the mpduType
|
||||
*/
|
||||
MpduType GetMpduType (void) const;
|
||||
/**
|
||||
* Getter for frameComplete parameter
|
||||
* \return the frameComplete parameter, i.e. 0 if the frame is not complete, 1 otherwise.
|
||||
*/
|
||||
uint8_t GetFrameComplete (void) const;
|
||||
|
||||
// From class Tag
|
||||
uint32_t GetSerializedSize (void) const;
|
||||
@@ -73,6 +79,7 @@ public:
|
||||
private:
|
||||
WifiTxVector m_wifiTxVector; ///< wifi transmit vector
|
||||
MpduType m_mpduType; ///< MPDU type
|
||||
uint8_t m_frameComplete; ///< Used to indicate that TX stopped sending before the end of the frame
|
||||
};
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include "ampdu-tag.h"
|
||||
#include "wifi-utils.h"
|
||||
#include "frame-capture-model.h"
|
||||
#include "wifi-radio-energy-model.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
@@ -372,7 +373,8 @@ WifiPhy::WifiPhy ()
|
||||
m_initialChannelNumber (0),
|
||||
m_totalAmpduSize (0),
|
||||
m_totalAmpduNumSymbols (0),
|
||||
m_currentEvent (0)
|
||||
m_currentEvent (0),
|
||||
m_wifiRadioEnergyModel (0)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
m_random = CreateObject<UniformRandomVariable> ();
|
||||
@@ -705,6 +707,12 @@ WifiPhy::GetFrameCaptureModel (void) const
|
||||
{
|
||||
return m_frameCaptureModel;
|
||||
}
|
||||
|
||||
void
|
||||
WifiPhy::SetWifiRadioEnergyModel (const Ptr<WifiRadioEnergyModel> wifiRadioEnergyModel)
|
||||
{
|
||||
m_wifiRadioEnergyModel = wifiRadioEnergyModel;
|
||||
}
|
||||
|
||||
double
|
||||
WifiPhy::GetPowerDbm (uint8_t power) const
|
||||
@@ -1598,6 +1606,28 @@ WifiPhy::SetSleepMode (void)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
WifiPhy::SetOffMode (void)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
switch (m_state->GetState ())
|
||||
{
|
||||
case WifiPhy::RX:
|
||||
m_endPlcpRxEvent.Cancel ();
|
||||
m_endRxEvent.Cancel ();
|
||||
case WifiPhy::TX:
|
||||
case WifiPhy::SWITCHING:
|
||||
case WifiPhy::CCA_BUSY:
|
||||
case WifiPhy::IDLE:
|
||||
case WifiPhy::SLEEP:
|
||||
m_state->SwitchToOff ();
|
||||
break;
|
||||
default:
|
||||
NS_ASSERT (false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
WifiPhy::ResumeFromSleep (void)
|
||||
{
|
||||
@@ -2328,7 +2358,17 @@ WifiPhy::SendPacket (Ptr<const Packet> packet, WifiTxVector txVector, MpduType m
|
||||
Ptr<Packet> newPacket = packet->Copy (); // obtain non-const Packet
|
||||
WifiPhyTag oldtag;
|
||||
newPacket->RemovePacketTag (oldtag);
|
||||
WifiPhyTag tag (txVector, mpdutype);
|
||||
if (m_state->GetState () == WifiPhy::OFF)
|
||||
{
|
||||
NS_LOG_DEBUG ("Transmission canceled because device is OFF");
|
||||
return;
|
||||
}
|
||||
uint8_t isFrameComplete = 1;
|
||||
if (m_wifiRadioEnergyModel != 0 && m_wifiRadioEnergyModel->GetMaximumTimeInState (WifiPhy::TX) < txDuration)
|
||||
{
|
||||
isFrameComplete = 0;
|
||||
}
|
||||
WifiPhyTag tag (txVector, mpdutype, isFrameComplete);
|
||||
newPacket->AddPacketTag (tag);
|
||||
|
||||
StartTx (newPacket, txVector, txDuration);
|
||||
@@ -2339,6 +2379,12 @@ WifiPhy::StartReceivePreambleAndHeader (Ptr<Packet> packet, double rxPowerW, Tim
|
||||
{
|
||||
//This function should be later split to check separately whether plcp preamble and plcp header can be successfully received.
|
||||
//Note: plcp preamble reception is not yet modeled.
|
||||
if (m_state->GetState () == WifiPhy::OFF)
|
||||
{
|
||||
NS_LOG_DEBUG ("Cannot start RX because device is OFF");
|
||||
return;
|
||||
}
|
||||
|
||||
NS_LOG_FUNCTION (this << packet << WToDbm (rxPowerW) << rxDuration);
|
||||
Time endRx = Simulator::Now () + rxDuration;
|
||||
|
||||
@@ -2350,6 +2396,14 @@ WifiPhy::StartReceivePreambleAndHeader (Ptr<Packet> packet, double rxPowerW, Tim
|
||||
return;
|
||||
}
|
||||
|
||||
if (tag.GetFrameComplete () == 0)
|
||||
{
|
||||
NS_LOG_DEBUG ("drop packet because of incomplete frame");
|
||||
NotifyRxDrop (packet);
|
||||
m_plcpSuccess = false;
|
||||
return;
|
||||
}
|
||||
|
||||
WifiTxVector txVector = tag.GetWifiTxVector ();
|
||||
|
||||
if (txVector.GetMode ().GetModulationClass () == WIFI_MOD_CLASS_HT
|
||||
@@ -3493,47 +3547,53 @@ WifiPhy::GetMcs (uint8_t mcs) const
|
||||
}
|
||||
|
||||
bool
|
||||
WifiPhy::IsStateCcaBusy (void)
|
||||
WifiPhy::IsStateCcaBusy (void) const
|
||||
{
|
||||
return m_state->IsStateCcaBusy ();
|
||||
}
|
||||
|
||||
bool
|
||||
WifiPhy::IsStateIdle (void)
|
||||
WifiPhy::IsStateIdle (void) const
|
||||
{
|
||||
return m_state->IsStateIdle ();
|
||||
}
|
||||
|
||||
bool
|
||||
WifiPhy::IsStateBusy (void)
|
||||
WifiPhy::IsStateBusy (void) const
|
||||
{
|
||||
return m_state->IsStateBusy ();
|
||||
}
|
||||
|
||||
bool
|
||||
WifiPhy::IsStateRx (void)
|
||||
WifiPhy::IsStateRx (void) const
|
||||
{
|
||||
return m_state->IsStateRx ();
|
||||
}
|
||||
|
||||
bool
|
||||
WifiPhy::IsStateTx (void)
|
||||
WifiPhy::IsStateTx (void) const
|
||||
{
|
||||
return m_state->IsStateTx ();
|
||||
}
|
||||
|
||||
bool
|
||||
WifiPhy::IsStateSwitching (void)
|
||||
WifiPhy::IsStateSwitching (void) const
|
||||
{
|
||||
return m_state->IsStateSwitching ();
|
||||
}
|
||||
|
||||
bool
|
||||
WifiPhy::IsStateSleep (void)
|
||||
WifiPhy::IsStateSleep (void) const
|
||||
{
|
||||
return m_state->IsStateSleep ();
|
||||
}
|
||||
|
||||
bool
|
||||
WifiPhy::IsStateOff (void) const
|
||||
{
|
||||
return m_state->IsStateOff ();
|
||||
}
|
||||
|
||||
Time
|
||||
WifiPhy::GetStateDuration (void)
|
||||
{
|
||||
|
||||
@@ -49,6 +49,11 @@ class WifiPhyStateHelper;
|
||||
*/
|
||||
class FrameCaptureModel;
|
||||
|
||||
/**
|
||||
* WifiRadioEnergyModel class
|
||||
*/
|
||||
class WifiRadioEnergyModel;
|
||||
|
||||
/**
|
||||
* This enumeration defines the type of an MPDU.
|
||||
*/
|
||||
@@ -312,35 +317,44 @@ public:
|
||||
* Resume from sleep mode.
|
||||
*/
|
||||
void ResumeFromSleep (void);
|
||||
/**
|
||||
* Put in off mode.
|
||||
*/
|
||||
void SetOffMode (void);
|
||||
|
||||
/**
|
||||
* \return true of the current state of the PHY layer is WifiPhy::IDLE, false otherwise.
|
||||
*/
|
||||
bool IsStateIdle (void);
|
||||
bool IsStateIdle (void) const;
|
||||
/**
|
||||
* \return true of the current state of the PHY layer is WifiPhy::CCA_BUSY, false otherwise.
|
||||
*/
|
||||
bool IsStateCcaBusy (void);
|
||||
bool IsStateCcaBusy (void) const;
|
||||
/**
|
||||
* \return true of the current state of the PHY layer is not WifiPhy::IDLE, false otherwise.
|
||||
*/
|
||||
bool IsStateBusy (void);
|
||||
bool IsStateBusy (void) const;
|
||||
/**
|
||||
* \return true of the current state of the PHY layer is WifiPhy::RX, false otherwise.
|
||||
*/
|
||||
bool IsStateRx (void);
|
||||
bool IsStateRx (void) const;
|
||||
/**
|
||||
* \return true of the current state of the PHY layer is WifiPhy::TX, false otherwise.
|
||||
*/
|
||||
bool IsStateTx (void);
|
||||
bool IsStateTx (void) const;
|
||||
/**
|
||||
* \return true of the current state of the PHY layer is WifiPhy::SWITCHING, false otherwise.
|
||||
*/
|
||||
bool IsStateSwitching (void);
|
||||
bool IsStateSwitching (void) const;
|
||||
/**
|
||||
* \return true if the current state of the PHY layer is WifiPhy::SLEEP, false otherwise.
|
||||
*/
|
||||
bool IsStateSleep (void);
|
||||
bool IsStateSleep (void) const;
|
||||
/**
|
||||
* \return true if the current state of the PHY layer is WifiPhy::OFF, false otherwise.
|
||||
*/
|
||||
bool IsStateOff (void) const ;
|
||||
|
||||
/**
|
||||
* \return the amount of time since the current state has started.
|
||||
*/
|
||||
@@ -1609,6 +1623,13 @@ public:
|
||||
*/
|
||||
Ptr<FrameCaptureModel> GetFrameCaptureModel (void) const;
|
||||
|
||||
/**
|
||||
* Sets the wifi radio energy model.
|
||||
*
|
||||
* \param wifiRadioEnergyModel the wifi radio energy model
|
||||
*/
|
||||
void SetWifiRadioEnergyModel (const Ptr<WifiRadioEnergyModel> wifiRadioEnergyModel);
|
||||
|
||||
/**
|
||||
* \return the channel width
|
||||
*/
|
||||
@@ -1965,6 +1986,7 @@ private:
|
||||
|
||||
Ptr<InterferenceHelper::Event> m_currentEvent; //!< Hold the current event
|
||||
Ptr<FrameCaptureModel> m_frameCaptureModel; //!< Frame capture model
|
||||
Ptr<WifiRadioEnergyModel> m_wifiRadioEnergyModel; //!< Wifi radio energy model
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -113,6 +113,9 @@ WifiRadioEnergyModel::SetEnergySource (const Ptr<EnergySource> source)
|
||||
NS_LOG_FUNCTION (this << source);
|
||||
NS_ASSERT (source != NULL);
|
||||
m_source = source;
|
||||
m_switchToOffEvent.Cancel ();
|
||||
Time durationToOff = GetMaximumTimeInState (m_currentState);
|
||||
m_switchToOffEvent = Simulator::Schedule (durationToOff, &WifiRadioEnergyModel::ChangeState, this, WifiPhy::OFF);
|
||||
}
|
||||
|
||||
double
|
||||
@@ -146,6 +149,9 @@ WifiRadioEnergyModel::GetTotalEnergyConsumption (void) const
|
||||
case WifiPhy::SLEEP:
|
||||
energyToDecrease = duration.GetSeconds () * m_sleepCurrentA * supplyVoltage;
|
||||
break;
|
||||
case WifiPhy::OFF:
|
||||
energyToDecrease = 0;
|
||||
break;
|
||||
default:
|
||||
NS_FATAL_ERROR ("WifiRadioEnergyModel:Undefined radio state: " << m_currentState);
|
||||
}
|
||||
@@ -286,6 +292,38 @@ WifiRadioEnergyModel::SetTxCurrentFromModel (double txPowerDbm)
|
||||
}
|
||||
}
|
||||
|
||||
Time
|
||||
WifiRadioEnergyModel::GetMaximumTimeInState (int state) const
|
||||
{
|
||||
Time remainingTime;
|
||||
double remainingEnergy = m_source->GetRemainingEnergy();
|
||||
double supplyVoltage = m_source->GetSupplyVoltage ();
|
||||
switch (state)
|
||||
{
|
||||
case WifiPhy::IDLE:
|
||||
remainingTime = NanoSeconds (1e9 * (remainingEnergy / (m_idleCurrentA * supplyVoltage)));
|
||||
break;
|
||||
case WifiPhy::CCA_BUSY:
|
||||
remainingTime = NanoSeconds (1e9 * (remainingEnergy / (m_ccaBusyCurrentA * supplyVoltage)));
|
||||
break;
|
||||
case WifiPhy::TX:
|
||||
remainingTime = NanoSeconds (1e9 * (remainingEnergy / (m_txCurrentA * supplyVoltage)));
|
||||
break;
|
||||
case WifiPhy::RX:
|
||||
remainingTime = NanoSeconds (1e9 * (remainingEnergy / (m_rxCurrentA * supplyVoltage)));
|
||||
break;
|
||||
case WifiPhy::SWITCHING:
|
||||
remainingTime = NanoSeconds (1e9 * (remainingEnergy / (m_switchingCurrentA * supplyVoltage)));
|
||||
break;
|
||||
case WifiPhy::SLEEP:
|
||||
remainingTime = NanoSeconds (1e9 * (remainingEnergy / (m_sleepCurrentA * supplyVoltage)));
|
||||
break;
|
||||
default:
|
||||
NS_FATAL_ERROR ("WifiRadioEnergyModel: undefined radio state " << state);
|
||||
}
|
||||
return remainingTime;
|
||||
}
|
||||
|
||||
void
|
||||
WifiRadioEnergyModel::ChangeState (int newState)
|
||||
{
|
||||
@@ -293,6 +331,20 @@ WifiRadioEnergyModel::ChangeState (int newState)
|
||||
|
||||
m_nPendingChangeState++;
|
||||
|
||||
if (m_nPendingChangeState > 1 && newState == WifiPhy::OFF)
|
||||
{
|
||||
SetWifiRadioState ((WifiPhy::State) newState);
|
||||
m_nPendingChangeState--;
|
||||
return;
|
||||
}
|
||||
|
||||
if (newState != WifiPhy::OFF)
|
||||
{
|
||||
m_switchToOffEvent.Cancel ();
|
||||
Time durationToOff = GetMaximumTimeInState (newState);
|
||||
m_switchToOffEvent = Simulator::Schedule (durationToOff, &WifiRadioEnergyModel::ChangeState, this, WifiPhy::OFF);
|
||||
}
|
||||
|
||||
Time duration = Simulator::Now () - m_lastUpdateTime;
|
||||
NS_ASSERT (duration.IsPositive ()); // check if duration is valid
|
||||
|
||||
@@ -328,6 +380,7 @@ WifiRadioEnergyModel::ChangeState (int newState)
|
||||
|
||||
// update total energy consumption
|
||||
m_totalEnergyConsumption += energyToDecrease;
|
||||
NS_ASSERT (m_totalEnergyConsumption <= m_source->GetInitialEnergy ());
|
||||
|
||||
// update last update time stamp
|
||||
m_lastUpdateTime = Simulator::Now ();
|
||||
@@ -342,7 +395,7 @@ WifiRadioEnergyModel::ChangeState (int newState)
|
||||
// by the previous instance is erroneously the final state stored in m_currentState. The check below
|
||||
// ensures that previous instances do not change m_currentState.
|
||||
|
||||
if (m_nPendingChangeState <= 1)
|
||||
if (m_nPendingChangeState <= 1 && m_currentState != WifiPhy::OFF)
|
||||
{
|
||||
// update current state & last update time stamp
|
||||
SetWifiRadioState ((WifiPhy::State) newState);
|
||||
@@ -379,6 +432,19 @@ WifiRadioEnergyModel::HandleEnergyRecharged (void)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
WifiRadioEnergyModel::HandleEnergyChanged (void)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
NS_LOG_DEBUG ("WifiRadioEnergyModel:Energy is changed!");
|
||||
if (m_currentState != WifiPhy::OFF)
|
||||
{
|
||||
m_switchToOffEvent.Cancel ();
|
||||
Time durationToOff = GetMaximumTimeInState (m_currentState);
|
||||
m_switchToOffEvent = Simulator::Schedule (durationToOff, &WifiRadioEnergyModel::ChangeState, this, WifiPhy::OFF);
|
||||
}
|
||||
}
|
||||
|
||||
WifiRadioEnergyModelPhyListener *
|
||||
WifiRadioEnergyModel::GetPhyListener (void)
|
||||
{
|
||||
|
||||
@@ -354,6 +354,13 @@ public:
|
||||
*/
|
||||
void ChangeState (int newState);
|
||||
|
||||
/**
|
||||
* \param state the wifi state
|
||||
*
|
||||
* \returns the time the radio can stay in that state based on the remaining energy.
|
||||
*/
|
||||
Time GetMaximumTimeInState (int state) const;
|
||||
|
||||
/**
|
||||
* \brief Handles energy depletion.
|
||||
*
|
||||
@@ -368,6 +375,13 @@ public:
|
||||
*/
|
||||
void HandleEnergyRecharged (void);
|
||||
|
||||
/**
|
||||
* \brief Handles energy changed.
|
||||
*
|
||||
* Implements DeviceEnergyModel::HandleEnergyChanged
|
||||
*/
|
||||
void HandleEnergyChanged (void);
|
||||
|
||||
/**
|
||||
* \returns Pointer to the PHY listener.
|
||||
*/
|
||||
@@ -420,6 +434,8 @@ private:
|
||||
|
||||
/// WifiPhy listener
|
||||
WifiRadioEnergyModelPhyListener *m_listener;
|
||||
|
||||
EventId m_switchToOffEvent; ///< switch to off event
|
||||
};
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
@@ -113,7 +113,7 @@ SpectrumWifiPhyBasicTest::MakeSignal (double txPowerWatts)
|
||||
|
||||
pkt->AddHeader (hdr);
|
||||
pkt->AddTrailer (trailer);
|
||||
WifiPhyTag tag (txVector, mpdutype);
|
||||
WifiPhyTag tag (txVector, mpdutype, 1);
|
||||
pkt->AddPacketTag (tag);
|
||||
Ptr<SpectrumValue> txPowerSpectrum = WifiSpectrumValueHelper::CreateOfdmTxPowerSpectralDensity (FREQUENCY, CHANNEL_WIDTH, txPowerWatts, GUARD_WIDTH);
|
||||
Ptr<WifiSpectrumSignalParameters> txParams = Create<WifiSpectrumSignalParameters> ();
|
||||
|
||||
Reference in New Issue
Block a user