00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "ns2ext-wifi-phy-state-helper.h"
00022 #include "ns3/log.h"
00023 #include "ns3/simulator.h"
00024 #include "ns3/trace-source-accessor.h"
00025
00026 NS_LOG_COMPONENT_DEFINE ("Ns2ExtWifiPhyStateHelper");
00027
00028 namespace ns3 {
00029
00030 NS_OBJECT_ENSURE_REGISTERED (Ns2ExtWifiPhyStateHelper);
00031
00032 TypeId
00033 Ns2ExtWifiPhyStateHelper::GetTypeId (void)
00034 {
00035 static TypeId tid = TypeId ("ns3::Ns2ExtWifiPhyStateHelper")
00036 .SetParent<Object> ()
00037 .AddConstructor<Ns2ExtWifiPhyStateHelper> ()
00038 .AddTraceSource ("State",
00039 "The state of the PHY layer",
00040 MakeTraceSourceAccessor (&Ns2ExtWifiPhyStateHelper::m_stateLogger))
00041 .AddTraceSource ("RxStart",
00042 "Reception of a packet has started successfully.",
00043 MakeTraceSourceAccessor (&Ns2ExtWifiPhyStateHelper::m_rxStartTrace))
00044 .AddTraceSource ("RxOk",
00045 "A packet has been received successfully.",
00046 MakeTraceSourceAccessor (&Ns2ExtWifiPhyStateHelper::m_rxOkTrace))
00047 .AddTraceSource ("RxError",
00048 "A packet has been received unsuccessfully.",
00049 MakeTraceSourceAccessor (&Ns2ExtWifiPhyStateHelper::m_rxErrorTrace))
00050 .AddTraceSource ("Tx", "Packet transmission is starting.",
00051 MakeTraceSourceAccessor (&Ns2ExtWifiPhyStateHelper::m_txTrace))
00052 ;
00053 return tid;
00054 }
00055
00056 Ns2ExtWifiPhyStateHelper::Ns2ExtWifiPhyStateHelper ()
00057 : m_rxing (false),
00058 m_endTx (Seconds (0)),
00059 m_endRx (Seconds (0)),
00060 m_endCcaBusy (Seconds (0)),
00061 m_startTx (Seconds (0)),
00062 m_startRx (Seconds (0)),
00063 m_startCcaBusy (Seconds (0)),
00064 m_previousStateChangeTime (Seconds (0))
00065 {
00066 NS_LOG_FUNCTION (this);
00067 }
00068
00069 void
00070 Ns2ExtWifiPhyStateHelper::SetReceiveOkCallback (WifiPhy::RxOkCallback callback)
00071 {
00072 m_rxOkCallback = callback;
00073 }
00074 void
00075 Ns2ExtWifiPhyStateHelper::SetReceiveErrorCallback (WifiPhy::RxErrorCallback callback)
00076 {
00077 m_rxErrorCallback = callback;
00078 }
00079 void
00080 Ns2ExtWifiPhyStateHelper::RegisterListener (WifiPhyListener *listener)
00081 {
00082 m_listeners.push_back (listener);
00083 }
00084
00085 bool
00086 Ns2ExtWifiPhyStateHelper::IsStateCcaBusy (void)
00087 {
00088 return (GetState () == WifiPhy::CCA_BUSY);
00089 }
00090
00091 bool
00092 Ns2ExtWifiPhyStateHelper::IsStateIdle (void)
00093 {
00094 return (GetState () == WifiPhy::IDLE);
00095 }
00096 bool
00097 Ns2ExtWifiPhyStateHelper::IsStateBusy (void)
00098 {
00099 return (GetState () != WifiPhy::IDLE);
00100 }
00101 bool
00102 Ns2ExtWifiPhyStateHelper::IsStateSyncing (void)
00103 {
00104 return (GetState () == WifiPhy::SYNCING);
00105 }
00106 bool
00107 Ns2ExtWifiPhyStateHelper::IsStateRx (void)
00108 {
00109 return (GetState () == WifiPhy::RX);
00110 }
00111 bool
00112 Ns2ExtWifiPhyStateHelper::IsStateTx (void)
00113 {
00114 return (GetState () == WifiPhy::TX);
00115 }
00116
00117 Time
00118 Ns2ExtWifiPhyStateHelper::GetStateDuration (void)
00119 {
00120 return Simulator::Now () - m_previousStateChangeTime;
00121 }
00122
00123 Time
00124 Ns2ExtWifiPhyStateHelper::GetDelayUntilIdle (void)
00125 {
00126 Time retval;
00127
00128 switch (GetState ()) {
00129 case WifiPhy::RX:
00130 retval = m_endRx - Simulator::Now ();
00131 break;
00132 case WifiPhy::TX:
00133 retval = m_endTx - Simulator::Now ();
00134 break;
00135 case WifiPhy::CCA_BUSY:
00136 retval = m_endCcaBusy - Simulator::Now ();
00137 break;
00138 case WifiPhy::IDLE:
00139 retval = Seconds (0);
00140 break;
00141 default:
00142 NS_ASSERT (false);
00143
00144 retval = Seconds (0);
00145 break;
00146 }
00147 retval = Max (retval, Seconds (0));
00148 return retval;
00149 }
00150
00151 Time
00152 Ns2ExtWifiPhyStateHelper::GetLastRxStartTime (void) const
00153 {
00154 return m_startRx;
00155 }
00156
00157 enum WifiPhy::State
00158 Ns2ExtWifiPhyStateHelper::GetState (void)
00159 {
00160 if (m_endTx > Simulator::Now ())
00161 {
00162 return WifiPhy::TX;
00163 }
00164 else if (m_rxing)
00165 {
00166 return WifiPhy::RX;
00167 }
00168 else if (m_endCcaBusy > Simulator::Now ())
00169 {
00170 return WifiPhy::CCA_BUSY;
00171 }
00172 else
00173 {
00174 return WifiPhy::IDLE;
00175 }
00176 }
00177
00178
00179 void
00180 Ns2ExtWifiPhyStateHelper::NotifyTxStart (Time duration)
00181 {
00182 for (Listeners::const_iterator i = m_listeners.begin (); i != m_listeners.end (); i++) {
00183 (*i)->NotifyTxStart (duration);
00184 }
00185 }
00186 void
00187 Ns2ExtWifiPhyStateHelper::NotifyRxStart (Time duration)
00188 {
00189 for (Listeners::const_iterator i = m_listeners.begin (); i != m_listeners.end (); i++) {
00190 (*i)->NotifyRxStart (duration);
00191 }
00192 }
00193 void
00194 Ns2ExtWifiPhyStateHelper::NotifyRxEndOk (void)
00195 {
00196 for (Listeners::const_iterator i = m_listeners.begin (); i != m_listeners.end (); i++) {
00197 (*i)->NotifyRxEndOk ();
00198 }
00199 }
00200 void
00201 Ns2ExtWifiPhyStateHelper::NotifyRxEndError (void)
00202 {
00203 for (Listeners::const_iterator i = m_listeners.begin (); i != m_listeners.end (); i++) {
00204 (*i)->NotifyRxEndError ();
00205 }
00206 }
00207 void
00208 Ns2ExtWifiPhyStateHelper::NotifyMaybeCcaBusyStart (Time duration)
00209 {
00210 for (Listeners::const_iterator i = m_listeners.begin (); i != m_listeners.end (); i++) {
00211 (*i)->NotifyMaybeCcaBusyStart (duration);
00212 }
00213 }
00214
00215 void
00216 Ns2ExtWifiPhyStateHelper::LogPreviousIdleAndCcaBusyStates (void)
00217 {
00218 Time now = Simulator::Now ();
00219 Time idleStart = Max (m_endCcaBusy, m_endRx);
00220 idleStart = Max (idleStart, m_endTx);
00221 NS_ASSERT (idleStart <= now);
00222 if (m_endCcaBusy > m_endRx &&
00223 m_endCcaBusy > m_endTx) {
00224 Time ccaBusyStart = Max (m_endTx, m_endRx);
00225 ccaBusyStart = Max (ccaBusyStart, m_startCcaBusy);
00226 m_stateLogger (ccaBusyStart, idleStart - ccaBusyStart, WifiPhy::CCA_BUSY);
00227 }
00228 m_stateLogger (idleStart, now - idleStart, WifiPhy::IDLE);
00229 }
00230
00231 void
00232 Ns2ExtWifiPhyStateHelper::SwitchToTx (Ptr<const Packet> packet, Time txDuration)
00233 {
00234 m_txTrace (packet);
00235 NotifyTxStart (txDuration);
00236 Time now = Simulator::Now ();
00237 switch (GetState ()) {
00238 case WifiPhy::RX:
00239
00240
00241
00242 m_rxing = false;
00243 m_stateLogger (m_startRx, now - m_startRx, WifiPhy::RX);
00244 m_endRx = now;
00245 break;
00246 case WifiPhy::CCA_BUSY: {
00247 Time ccaStart = Max (m_endRx, m_endTx);
00248 ccaStart = Max (ccaStart, m_startCcaBusy);
00249 m_stateLogger (ccaStart, now - ccaStart, WifiPhy::CCA_BUSY);
00250 } break;
00251 case WifiPhy::IDLE:
00252 LogPreviousIdleAndCcaBusyStates ();
00253 break;
00254 default:
00255 NS_ASSERT (false);
00256 break;
00257 }
00258 m_stateLogger (now, txDuration, WifiPhy::TX);
00259 m_previousStateChangeTime = now;
00260 m_endTx = now + txDuration;
00261 m_startTx = now;
00262 }
00263 void
00264 Ns2ExtWifiPhyStateHelper::SwitchToRx (Time rxDuration)
00265 {
00266 NS_ASSERT (IsStateIdle () || IsStateCcaBusy ());
00267 NS_ASSERT (!m_rxing);
00268 NotifyRxStart (rxDuration);
00269 Time now = Simulator::Now ();
00270 switch (GetState ()) {
00271 case WifiPhy::IDLE:
00272 LogPreviousIdleAndCcaBusyStates ();
00273 break;
00274 case WifiPhy::CCA_BUSY: {
00275 Time ccaStart = Max (m_endRx, m_endTx);
00276 ccaStart = Max (ccaStart, m_startCcaBusy);
00277 m_stateLogger (ccaStart, now - ccaStart, WifiPhy::CCA_BUSY);
00278 } break;
00279 case WifiPhy::RX:
00280 case WifiPhy::TX:
00281 default:
00282 NS_ASSERT (false);
00283 break;
00284 }
00285 m_previousStateChangeTime = now;
00286 m_rxing = true;
00287 m_startRx = now;
00288 m_endRx = now + rxDuration;
00289 NS_ASSERT (IsStateRx ());
00290 }
00291 void
00292 Ns2ExtWifiPhyStateHelper::SwitchFromRxEndOk (Ptr<Packet> packet)
00293 {
00294 m_rxOkTrace (packet);
00295 NotifyRxEndOk ();
00296 DoSwitchFromRx ();
00297 if (!m_rxOkCallback.IsNull ())
00298 {
00299 m_rxOkCallback (packet);
00300 }
00301 }
00302 void
00303 Ns2ExtWifiPhyStateHelper::SwitchFromRxEndError (Ptr<const Packet> packet)
00304 {
00305 m_rxErrorTrace (packet, WifiPhy::RXERROR_BAD_SIGNAL);
00306 NotifyRxEndError ();
00307 DoSwitchFromRx ();
00308 if (!m_rxErrorCallback.IsNull ())
00309 {
00310 m_rxErrorCallback (packet);
00311 }
00312 }
00313
00314 void
00315 Ns2ExtWifiPhyStateHelper::DoSwitchFromRx (void)
00316 {
00317 NS_ASSERT (IsStateRx ());
00318 NS_ASSERT (m_rxing);
00319
00320 Time now = Simulator::Now ();
00321 m_stateLogger (m_startRx, now - m_startRx, WifiPhy::RX);
00322 m_previousStateChangeTime = now;
00323 m_rxing = false;
00324
00325 NS_ASSERT (IsStateIdle () || IsStateCcaBusy ());
00326 }
00327 void
00328 Ns2ExtWifiPhyStateHelper::SwitchMaybeToCcaBusy (Time duration)
00329 {
00330 NotifyMaybeCcaBusyStart (duration);
00331 Time now = Simulator::Now ();
00332 switch (GetState ()) {
00333 case WifiPhy::IDLE:
00334 LogPreviousIdleAndCcaBusyStates ();
00335 break;
00336 case WifiPhy::CCA_BUSY:
00337 break;
00338 case WifiPhy::RX:
00339 break;
00340 case WifiPhy::TX:
00341 break;
00342 default:
00343 NS_ASSERT (false);
00344 break;
00345 }
00346 m_startCcaBusy = now;
00347 m_endCcaBusy = std::max (m_endCcaBusy, now + duration);
00348 }
00349
00350 void
00351 Ns2ExtWifiPhyStateHelper::CallRxStartTrace (Ptr<const Packet> packet, const WifiPhyRxTag& rxTag)
00352 {
00353 m_rxStartTrace(packet, rxTag);
00354 }
00355
00356 void
00357 Ns2ExtWifiPhyStateHelper::CallRxErrorTrace (Ptr<const Packet> packet, WifiPhy::RxErrorReason rxErrorReason)
00358 {
00359 m_rxErrorTrace(packet, rxErrorReason);
00360 }
00361
00362 }