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