src/wifi/model/yans-wifi-phy.cc
changeset 10883 d919e7194e23
parent 10801 02d564a4c823
child 10968 2d29fee2b7b8
--- a/src/wifi/model/yans-wifi-phy.cc	Fri Sep 05 15:38:55 2014 -0700
+++ b/src/wifi/model/yans-wifi-phy.cc	Fri Sep 05 16:33:57 2014 -0700
@@ -397,6 +397,9 @@
     case YansWifiPhy::IDLE:
       goto switchChannel;
       break;
+    case YansWifiPhy::SLEEP:
+      NS_LOG_DEBUG ("channel switching ignored in sleep mode");
+      break;
     default:
       NS_ASSERT (false);
       break;
@@ -432,6 +435,59 @@
 }
 
 void
+YansWifiPhy::SetSleepMode (void)
+{
+  NS_LOG_FUNCTION (this);
+  switch (m_state->GetState ())
+    {
+    case YansWifiPhy::TX:
+      NS_LOG_DEBUG ("setting sleep mode postponed until end of current transmission");
+      Simulator::Schedule (GetDelayUntilIdle (), &YansWifiPhy::SetSleepMode, this);
+      break;
+    case YansWifiPhy::RX:
+      NS_LOG_DEBUG ("setting sleep mode postponed until end of current reception");
+      Simulator::Schedule (GetDelayUntilIdle (), &YansWifiPhy::SetSleepMode, this);
+      break;
+    case YansWifiPhy::SWITCHING:
+      NS_LOG_DEBUG ("setting sleep mode postponed until end of channel switching");
+      Simulator::Schedule (GetDelayUntilIdle (), &YansWifiPhy::SetSleepMode, this);
+      break;
+    case YansWifiPhy::CCA_BUSY:
+    case YansWifiPhy::IDLE:
+      NS_LOG_DEBUG ("setting sleep mode");
+      m_state->SwitchToSleep ();
+      break;
+    case YansWifiPhy::SLEEP:
+      NS_LOG_DEBUG ("already in sleep mode");
+      break;
+    default:
+      NS_ASSERT (false);
+      break;
+    }
+}
+
+void
+YansWifiPhy::ResumeFromSleep (void)
+{
+  NS_LOG_FUNCTION (this);
+  switch (m_state->GetState ())
+    {
+    case YansWifiPhy::TX:
+    case YansWifiPhy::RX:
+    case YansWifiPhy::IDLE:
+    case YansWifiPhy::CCA_BUSY:
+    case YansWifiPhy::SWITCHING:
+      NS_LOG_DEBUG ("not in sleep mode, there is nothing to resume");
+      break;
+    case YansWifiPhy::SLEEP:
+      NS_LOG_DEBUG ("resuming from sleep mode");
+      Time delayUntilCcaEnd = m_interference.GetEnergyDuration (m_ccaMode1ThresholdW);
+      m_state->SwitchFromSleep (delayUntilCcaEnd);
+      break;
+    }
+}
+
+void
 YansWifiPhy::SetReceiveOkCallback (RxOkCallback callback)
 {
   m_state->SetReceiveOkCallback (callback);
@@ -535,6 +591,10 @@
           goto maybeCcaBusy;
         }
       break;
+    case YansWifiPhy::SLEEP:
+      NS_LOG_DEBUG ("drop packet because in sleep mode");
+      NotifyRxDrop (packet);
+      break;
     }
 
   return;
@@ -553,9 +613,9 @@
 }
 
 void
-YansWifiPhy::SendPacket (Ptr<const Packet> packet, WifiMode txMode, WifiPreamble preamble, WifiTxVector txVector)
+YansWifiPhy::SendPacket (Ptr<const Packet> packet, WifiTxVector txVector, WifiPreamble preamble)
 {
-  NS_LOG_FUNCTION (this << packet << txMode << preamble << (uint32_t)txVector.GetTxPowerLevel());
+  NS_LOG_FUNCTION (this << packet << txVector.GetMode() << preamble << (uint32_t)txVector.GetTxPowerLevel());
   /* Transmission can happen if:
    *  - we are syncing on a packet. It is the responsability of the
    *    MAC layer to avoid doing this but the PHY does nothing to
@@ -564,6 +624,13 @@
    */
   NS_ASSERT (!m_state->IsStateTx () && !m_state->IsStateSwitching ());
 
+  if (m_state->IsStateSleep ())
+    {
+      NS_LOG_DEBUG ("Dropping packet because in sleep mode");
+      NotifyTxDrop (packet);
+      return;
+    }
+
   Time txDuration = CalculateTxDuration (packet->GetSize (), txVector, preamble);
   if (m_state->IsStateRx ())
     {
@@ -574,7 +641,7 @@
   uint32_t dataRate500KbpsUnits = txVector.GetMode().GetDataRate () * txVector.GetNss() / 500000;
   bool isShortPreamble = (WIFI_PREAMBLE_SHORT == preamble);
   NotifyMonitorSniffTx (packet, (uint16_t)GetChannelFrequencyMhz (), GetChannelNumber (), dataRate500KbpsUnits, isShortPreamble, txVector.GetTxPowerLevel());
-  m_state->SwitchToTx (txDuration, packet, txVector.GetMode(), preamble,  txVector.GetTxPowerLevel());
+  m_state->SwitchToTx (txDuration, packet, GetPowerDbm (txVector.GetTxPowerLevel()), txVector, preamble);
   m_channel->Send (this, packet, GetPowerDbm ( txVector.GetTxPowerLevel()) + m_txGainDb, txVector, preamble);
 }
 
@@ -748,6 +815,11 @@
 {
   return m_state->IsStateSwitching ();
 }
+bool
+YansWifiPhy::IsStateSleep (void)
+{
+  return m_state->IsStateSleep ();
+}
 
 Time
 YansWifiPhy::GetStateDuration (void)