00001 /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ 00002 /* 00003 * Copyright (c) 2005,2006 INRIA 00004 * 00005 * This program is free software; you can redistribute it and/or modify 00006 * it under the terms of the GNU General Public License version 2 as 00007 * published by the Free Software Foundation; 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software 00016 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00017 * 00018 * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr> 00019 */ 00020 00021 #ifndef WIFI_PHY_H 00022 #define WIFI_PHY_H 00023 00024 #include <stdint.h> 00025 #include "ns3/callback.h" 00026 #include "ns3/packet.h" 00027 #include "ns3/object.h" 00028 #include "ns3/nstime.h" 00029 #include "ns3/ptr.h" 00030 #include "ns3/tag.h" 00031 #include "wifi-mode.h" 00032 #include "wifi-preamble.h" 00033 #include "wifi-phy-standard.h" 00034 00035 00036 namespace ns3 { 00037 00038 class WifiChannel; 00039 class NetDevice; 00040 00041 /** 00042 * \brief receive notifications about phy events. 00043 */ 00044 class WifiPhyListener { 00045 public: 00046 virtual ~WifiPhyListener (); 00047 00048 /** 00049 * \param duration the expected duration of the packet reception. 00050 * 00051 * We have received the first bit of a packet. We decided 00052 * that we could synchronize on this packet. It does not mean 00053 * we will be able to successfully receive completely the 00054 * whole packet. It means that we will report a BUSY status until 00055 * one of the following happens: 00056 * - NotifyRxEndOk 00057 * - NotifyExEndError 00058 * - NotifyTxStart 00059 */ 00060 virtual void NotifyRxStart (Time duration) = 0; 00061 /** 00062 * We have received the last bit of a packet for which 00063 * NotifyRxStart was invoked first and, the packet has 00064 * been successfully received. 00065 */ 00066 virtual void NotifyRxEndOk (void) = 0; 00067 /** 00068 * We have received the last bit of a packet for which 00069 * NotifyRxStart was invoked first and, the packet has 00070 * _not_ been successfully received. 00071 */ 00072 virtual void NotifyRxEndError (void) = 0; 00073 /** 00074 * \param duration the expected transmission duration. 00075 * 00076 * We are about to send the first bit of the packet. 00077 * We do not send any event to notify the end of 00078 * transmission. Listeners should assume that the 00079 * channel implicitely reverts to the idle state 00080 * unless they have received a cca busy report. 00081 */ 00082 virtual void NotifyTxStart (Time duration) = 0; 00083 /** 00084 * \param duration the expected busy duration. 00085 * 00086 * This method does not really report a real state 00087 * change as opposed to the other methods in this class. 00088 * It merely reports that, unless the medium is reported 00089 * busy through NotifyTxStart or NotifyRxStart/End, 00090 * it will be busy as defined by the currently selected 00091 * CCA mode. 00092 * 00093 * Typical client code which wants to have a clear picture 00094 * of the CCA state will need to keep track of the time at 00095 * which the last NotifyCcaBusyStart method is called and 00096 * what duration it reported. 00097 */ 00098 virtual void NotifyMaybeCcaBusyStart (Time duration) = 0; 00099 }; 00100 00101 /** 00102 * \brief Annotate a packet sent through a WifiPhy with transmission parameters 00103 * and information. 00104 * 00105 * The class was started to export more information to the trace 00106 * callbacks. Trace callback templates had too few parameters. 00107 */ 00108 class WifiPhyTxTag : public Tag 00109 { 00110 public: 00111 WifiPhyTxTag (); 00112 WifiPhyTxTag (WifiPreamble wifiPreamble, WifiMode wifiMode, uint8_t powerId, double powerDbm, Time duration); 00113 00114 WifiPreamble GetWifiPreamble () const; 00115 WifiMode GetWifiMode () const; 00116 uint8_t GetPowerId () const; 00117 double GetPowerDbm() const; 00118 Time GetDuration () const; 00119 00120 static TypeId GetTypeId (); 00121 virtual TypeId GetInstanceTypeId () const; 00122 virtual uint32_t GetSerializedSize () const; 00123 virtual void Serialize (TagBuffer i) const; 00124 virtual void Deserialize (TagBuffer i); 00125 virtual void Print (std::ostream &os) const; 00126 private: 00127 WifiPreamble m_wifiPreamble; 00128 WifiMode m_wifiMode; 00129 uint8_t m_powerId; 00130 double m_powerDbm; 00131 Time m_duration; 00132 }; 00133 00134 /** 00135 * \brief Annotate a packet received through a WifiPhy with reception 00136 * parameters and information. 00137 * 00138 * The class was started to export more information to the trace 00139 * callbacks. Trace callback templates had too few parameters. 00140 */ 00141 class WifiPhyRxTag : public Tag 00142 { 00143 public: 00144 WifiPhyRxTag (); 00145 WifiPhyRxTag (double powerDbm, double snr, double per); 00146 00147 double GetPowerDbm () const; 00148 double GetSnr() const; 00149 double GetPer() const; 00150 00151 static TypeId GetTypeId (); 00152 virtual TypeId GetInstanceTypeId () const; 00153 virtual uint32_t GetSerializedSize () const; 00154 virtual void Serialize (TagBuffer i) const; 00155 virtual void Deserialize (TagBuffer i); 00156 virtual void Print (std::ostream &os) const; 00157 private: 00158 double m_powerDbm; 00159 double m_snr; 00160 double m_per; 00161 }; 00162 00163 /** 00164 * \brief 802.11 PHY layer model 00165 * 00166 */ 00167 class WifiPhy : public Object 00168 { 00169 public: 00170 /** 00171 * The state of the PHY layer. 00172 */ 00173 enum State { 00174 /** 00175 * The PHY layer is IDLE. 00176 */ 00177 IDLE, 00178 /** 00179 * The PHY layer has sense the medium busy through the CCA mechanism 00180 */ 00181 CCA_BUSY, 00182 /** 00183 * The PHY layer is sending a packet. 00184 */ 00185 TX, 00186 /** 00187 * The PHY layer is synchronizing upon a new packet. Currently not used. 00188 */ 00189 SYNCING, 00190 /** 00191 * The PHY layer is receiving a packet. 00192 */ 00193 RX 00194 }; 00195 00196 /** 00197 * arg1: packet received successfully 00198 * arg2: snr of packet 00199 * arg3: mode of packet 00200 * arg4: type of preamble used for packet. 00201 */ 00202 typedef Callback< void, Ptr<Packet> > RxOkCallback; 00203 /** 00204 * arg1: packet received unsuccessfully 00205 * arg2: snr of packet 00206 */ 00207 typedef Callback< void, Ptr<const Packet> > RxErrorCallback; 00208 00209 static TypeId GetTypeId (void); 00210 00211 WifiPhy (); 00212 virtual ~WifiPhy (); 00213 00214 virtual double GetTxPowerStart (void) const = 0; 00215 virtual double GetTxPowerEnd (void) const = 0; 00216 /** 00217 * \returns the number of tx power levels available for this PHY. 00218 */ 00219 virtual uint32_t GetNTxPower (void) const = 0; 00220 00221 /** 00222 * \param callback the callback to invoke 00223 * upon successful packet reception. 00224 */ 00225 virtual void SetReceiveOkCallback (RxOkCallback callback) = 0; 00226 /** 00227 * \param callback the callback to invoke 00228 * upon erronous packet reception. 00229 */ 00230 virtual void SetReceiveErrorCallback (RxErrorCallback callback) = 0; 00231 00232 /** 00233 * \param packet the packet to send 00234 * \param mode the transmission mode to use to send this packet 00235 * \param preamble the type of preamble to use to send this packet. 00236 * \param txPowerLevel a power level to use to send this packet. The real 00237 * transmission power is calculated as txPowerMin + txPowerLevel * (txPowerMax - txPowerMin) / nTxLevels 00238 */ 00239 virtual void SendPacket (Ptr<const Packet> packet, WifiMode mode, enum WifiPreamble preamble, uint8_t txPowerLevel) = 0; 00240 00241 /** 00242 * \param listener the new listener 00243 * 00244 * Add the input listener to the list of objects to be notified of 00245 * PHY-level events. 00246 */ 00247 virtual void RegisterListener (WifiPhyListener *listener) = 0; 00248 00249 /** 00250 * \returns true of the current state of the PHY layer is WifiPhy::CCA_BUSY, false otherwise. 00251 */ 00252 virtual bool IsStateCcaBusy (void) = 0; 00253 /** 00254 * \returns true of the current state of the PHY layer is WifiPhy::IDLE, false otherwise. 00255 */ 00256 virtual bool IsStateIdle (void) = 0; 00257 /** 00258 * \returns true of the current state of the PHY layer is not WifiPhy::IDLE, false otherwise. 00259 */ 00260 virtual bool IsStateBusy (void) = 0; 00261 /** 00262 * \returns true of the current state of the PHY layer is WifiPhy::SYNCING, false otherwise. 00263 */ 00264 virtual bool IsStateSyncing (void) = 0; 00265 /** 00266 * \returns true of the current state of the PHY layer is WifiPhy::RX, false otherwise. 00267 */ 00268 virtual bool IsStateRx (void) = 0; 00269 /** 00270 * \returns true of the current state of the PHY layer is WifiPhy::TX, false otherwise. 00271 */ 00272 virtual bool IsStateTx (void) = 0; 00273 /** 00274 * \returns the amount of time since the current state has started. 00275 */ 00276 virtual Time GetStateDuration (void) = 0; 00277 /** 00278 * \returns the predicted delay until this PHY can become WifiPhy::IDLE. 00279 * 00280 * The PHY will never become WifiPhy::IDLE _before_ the delay returned by 00281 * this method but it could become really idle later. 00282 */ 00283 virtual Time GetDelayUntilIdle (void) = 0; 00284 00285 virtual Time GetLastRxStartTime (void) const = 0; 00286 00287 /** 00288 * As long as the state enum is in the WifiPhy class, this belongs here. 00289 * \returns a stringified name of the state 00290 */ 00291 static const char* StateToString (enum State state); 00292 00293 /** 00294 * \param size the number of bytes in the packet to send 00295 * \param payloadMode the transmission mode to use for this packet 00296 * \param preamble the type of preamble to use for this packet. 00297 * \returns the total amount of time this PHY will stay busy for 00298 * the transmission of these bytes. 00299 */ 00300 virtual Time CalculateTxDuration (uint32_t size, WifiMode payloadMode, enum WifiPreamble preamble) const = 0; 00301 00302 /** 00303 * \returns the number of transmission modes supported by this PHY. 00304 */ 00305 virtual uint32_t GetNModes (void) const = 0; 00306 /** 00307 * \param mode index in array of supported modes 00308 * \returns the mode whose index is specified. 00309 */ 00310 virtual WifiMode GetMode (uint32_t mode) const = 0; 00311 /** 00312 * \param txMode the transmission mode 00313 * \param ber the probability of bit error rate 00314 * \returns the minimum snr which is required to achieve 00315 * the requested ber for the specified transmission mode. (W/W) 00316 */ 00317 virtual double CalculateSnr (WifiMode txMode, double ber) const = 0; 00318 00319 virtual Ptr<WifiChannel> GetChannel (void) const = 0; 00320 00321 static WifiMode Get6mba (void); 00322 static WifiMode Get9mba (void); 00323 static WifiMode Get12mba (void); 00324 static WifiMode Get18mba (void); 00325 static WifiMode Get24mba (void); 00326 static WifiMode Get36mba (void); 00327 static WifiMode Get48mba (void); 00328 static WifiMode Get54mba (void); 00329 00330 /** 00331 * Enumeration of reasons a packet was dropped. Used in trace callbacks for 00332 * debugging purposes. Common for all WifiPhys. 00333 */ 00334 enum RxErrorReason { 00335 00336 /** 00337 * Packet dropped because received signal was not strong enough for the 00338 * complete duration. Detected at end of RX period. 00339 */ 00340 RXERROR_BAD_SIGNAL, 00341 00342 /** 00343 * Packet dropped because PHY was already in RX state on a different 00344 * packet. 00345 */ 00346 RXERROR_ALREADY_RXING, 00347 00348 /** 00349 * Packet dropped because PHY was is TX state on a different packet. 00350 */ 00351 RXERROR_IN_TX, 00352 00353 /** 00354 * Packet dropped because received signal was below PHY's detection 00355 * threshold. 00356 */ 00357 RXERROR_LOW_SIGNAL, 00358 }; 00359 00360 /** 00361 * \returns the drop reason as a short reason string. 00362 */ 00363 static const char* RxErrorReasonToString (enum RxErrorReason rxErrorReason); 00364 }; 00365 00366 } // namespace ns3 00367 00368 00369 #endif /* WIFI_PHY_H */