1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2008 INRIA
4  * Copyright (c) 2009 MIRKO BANCHI
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation;
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  *
19  * Authors: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
20  *          Mirko Banchi <mk.banchi@gmail.com>
21  */
22 
23 #ifndef WIFI_HELPER_H
24 #define WIFI_HELPER_H
25 
26 #include "ns3/trace-helper.h"
27 #include "ns3/wifi-phy.h"
28 #include "ns3/qos-utils.h"
29 #include "ns3/deprecated.h"
30 #include "wifi-mac-helper.h"
31 #include <functional>
32 
33 namespace ns3 {
34 
35 class WifiNetDevice;
36 class Node;
37 class RadiotapHeader;
38 class QueueItem;
39 
40 /**
41  * \brief create PHY objects
42  *
43  * This base class must be implemented by new PHY implementation which wish to integrate
44  * with the \ref ns3::WifiHelper class.
45  */
46 class WifiPhyHelper : public PcapHelperForDevice,
47                       public AsciiTraceHelperForDevice
48 {
49 public:
50   WifiPhyHelper ();
51   virtual ~WifiPhyHelper ();
52 
53   /**
54    * \param node the node on which the PHY object will reside
55    * \param device the device within which the PHY object will reside
56    *
57    * \returns a new PHY object.
58    *
59    * Subclasses must implement this method to allow the ns3::WifiHelper class
60    * to create PHY objects from ns3::WifiHelper::Install.
61    *
62    * Typically the device type will be of class WifiNetDevice but the
63    * type of the pointer is generalized so that this method may be used
64    * by other Wifi device variants such as WaveNetDevice.
65    */
66   virtual Ptr<WifiPhy> Create (Ptr<Node> node, Ptr<NetDevice> device) const = 0;
67 
68   /**
69    * \param name the name of the attribute to set
70    * \param v the value of the attribute
71    *
72    * Set an attribute of the underlying PHY object.
73    */
74   void Set (std::string name, const AttributeValue &v);
75   /**
76    * \param name the name of the error rate model to set.
77    * \param n0 the name of the attribute to set
78    * \param v0 the value of the attribute to set
79    * \param n1 the name of the attribute to set
80    * \param v1 the value of the attribute to set
81    * \param n2 the name of the attribute to set
82    * \param v2 the value of the attribute to set
83    * \param n3 the name of the attribute to set
84    * \param v3 the value of the attribute to set
85    * \param n4 the name of the attribute to set
86    * \param v4 the value of the attribute to set
87    * \param n5 the name of the attribute to set
88    * \param v5 the value of the attribute to set
89    * \param n6 the name of the attribute to set
90    * \param v6 the value of the attribute to set
91    * \param n7 the name of the attribute to set
92    * \param v7 the value of the attribute to set
93    *
94    * Set the error rate model and its attributes to use when Install is called.
95    */
96   void SetErrorRateModel (std::string name,
97                           std::string n0 = "", const AttributeValue &v0 = EmptyAttributeValue (),
98                           std::string n1 = "", const AttributeValue &v1 = EmptyAttributeValue (),
99                           std::string n2 = "", const AttributeValue &v2 = EmptyAttributeValue (),
100                           std::string n3 = "", const AttributeValue &v3 = EmptyAttributeValue (),
101                           std::string n4 = "", const AttributeValue &v4 = EmptyAttributeValue (),
102                           std::string n5 = "", const AttributeValue &v5 = EmptyAttributeValue (),
103                           std::string n6 = "", const AttributeValue &v6 = EmptyAttributeValue (),
104                           std::string n7 = "", const AttributeValue &v7 = EmptyAttributeValue ());
105   /**
106    * \param name the name of the frame capture model to set.
107    * \param n0 the name of the attribute to set
108    * \param v0 the value of the attribute to set
109    * \param n1 the name of the attribute to set
110    * \param v1 the value of the attribute to set
111    * \param n2 the name of the attribute to set
112    * \param v2 the value of the attribute to set
113    * \param n3 the name of the attribute to set
114    * \param v3 the value of the attribute to set
115    * \param n4 the name of the attribute to set
116    * \param v4 the value of the attribute to set
117    * \param n5 the name of the attribute to set
118    * \param v5 the value of the attribute to set
119    * \param n6 the name of the attribute to set
120    * \param v6 the value of the attribute to set
121    * \param n7 the name of the attribute to set
122    * \param v7 the value of the attribute to set
123    *
124    * Set the frame capture model and its attributes to use when Install is called.
125    */
126   void SetFrameCaptureModel (std::string name,
127                              std::string n0 = "", const AttributeValue &v0 = EmptyAttributeValue (),
128                              std::string n1 = "", const AttributeValue &v1 = EmptyAttributeValue (),
129                              std::string n2 = "", const AttributeValue &v2 = EmptyAttributeValue (),
130                              std::string n3 = "", const AttributeValue &v3 = EmptyAttributeValue (),
131                              std::string n4 = "", const AttributeValue &v4 = EmptyAttributeValue (),
132                              std::string n5 = "", const AttributeValue &v5 = EmptyAttributeValue (),
133                              std::string n6 = "", const AttributeValue &v6 = EmptyAttributeValue (),
134                              std::string n7 = "", const AttributeValue &v7 = EmptyAttributeValue ());
135   /**
136    * \param name the name of the preamble detection model to set.
137    * \param n0 the name of the attribute to set
138    * \param v0 the value of the attribute to set
139    * \param n1 the name of the attribute to set
140    * \param v1 the value of the attribute to set
141    * \param n2 the name of the attribute to set
142    * \param v2 the value of the attribute to set
143    * \param n3 the name of the attribute to set
144    * \param v3 the value of the attribute to set
145    * \param n4 the name of the attribute to set
146    * \param v4 the value of the attribute to set
147    * \param n5 the name of the attribute to set
148    * \param v5 the value of the attribute to set
149    * \param n6 the name of the attribute to set
150    * \param v6 the value of the attribute to set
151    * \param n7 the name of the attribute to set
152    * \param v7 the value of the attribute to set
153    *
154    * Set the preamble detection model and its attributes to use when Install is called.
155    */
156   void SetPreambleDetectionModel (std::string name,
157                                   std::string n0 = "", const AttributeValue &v0 = EmptyAttributeValue (),
158                                   std::string n1 = "", const AttributeValue &v1 = EmptyAttributeValue (),
159                                   std::string n2 = "", const AttributeValue &v2 = EmptyAttributeValue (),
160                                   std::string n3 = "", const AttributeValue &v3 = EmptyAttributeValue (),
161                                   std::string n4 = "", const AttributeValue &v4 = EmptyAttributeValue (),
162                                   std::string n5 = "", const AttributeValue &v5 = EmptyAttributeValue (),
163                                   std::string n6 = "", const AttributeValue &v6 = EmptyAttributeValue (),
164                                   std::string n7 = "", const AttributeValue &v7 = EmptyAttributeValue ());
165 
166   /**
167    * Disable the preamble detection model.
168    */
169   void DisablePreambleDetectionModel ();
170 
171   /**
172    * An enumeration of the pcap data link types (DLTs) which this helper
173    * supports.  See http://wiki.wireshark.org/Development/LibpcapFileFormat
174    * for more information on these formats.
175    */
176   enum SupportedPcapDataLinkTypes
177   {
178     DLT_IEEE802_11       = PcapHelper::DLT_IEEE802_11,       /**< IEEE 802.11 Wireless LAN headers on packets */
179     DLT_PRISM_HEADER     = PcapHelper::DLT_PRISM_HEADER,     /**< Include Prism monitor mode information */
180     DLT_IEEE802_11_RADIO = PcapHelper::DLT_IEEE802_11_RADIO  /**< Include Radiotap link layer information */
181   };
182 
183   /**
184    * Set the data link type of PCAP traces to be used. This function has to be
185    * called before EnablePcap(), so that the header of the pcap file can be
186    * written correctly.
187    *
188    * \see SupportedPcapDataLinkTypes
189    *
190    * \param dlt The data link type of the pcap file (and packets) to be used
191    */
192   void SetPcapDataLinkType (SupportedPcapDataLinkTypes dlt);
193 
194   /**
195    * Get the data link type of PCAP traces to be used.
196    *
197    * \see SupportedPcapDataLinkTypes
198    *
199    * \returns The data link type of the pcap file (and packets) to be used
200    */
201   PcapHelper::DataLinkType GetPcapDataLinkType (void) const;
202 
203 
204 protected:
205   /**
206    * \param file the pcap file wrapper
207    * \param packet the packet
208    * \param channelFreqMhz the channel frequency
209    * \param txVector the TXVECTOR
210    * \param aMpdu the A-MPDU information
211    * \param staId the STA-ID (only used for MU)
212    *
213    * Handle TX pcap.
214    */
215   static void PcapSniffTxEvent (Ptr<PcapFileWrapper> file,
216                                 Ptr<const Packet> packet,
217                                 uint16_t channelFreqMhz,
218                                 WifiTxVector txVector,
219                                 MpduInfo aMpdu,
220                                 uint16_t staId = SU_STA_ID);
221   /**
222    * \param file the pcap file wrapper
223    * \param packet the packet
224    * \param channelFreqMhz the channel frequency
225    * \param txVector the TXVECTOR
226    * \param aMpdu the A-MPDU information
227    * \param signalNoise the RX signal and noise information
228    * \param staId the STA-ID (only used for MU)
229    *
230    * Handle RX pcap.
231    */
232   static void PcapSniffRxEvent (Ptr<PcapFileWrapper> file,
233                                 Ptr<const Packet> packet,
234                                 uint16_t channelFreqMhz,
235                                 WifiTxVector txVector,
236                                 MpduInfo aMpdu,
237                                 SignalNoiseDbm signalNoise,
238                                 uint16_t staId = SU_STA_ID);
239 
240   ObjectFactory m_phy; ///< PHY object
241   ObjectFactory m_errorRateModel; ///< error rate model
242   ObjectFactory m_frameCaptureModel; ///< frame capture model
243   ObjectFactory m_preambleDetectionModel; ///< preamble detection model
244 
245 
246 private:
247   /**
248    * Get the Radiotap header for a transmitted packet.
249    *
250    * \param header the radiotap header to be filled in
251    * \param packet the packet
252    * \param channelFreqMhz the channel frequency
253    * \param txVector the TXVECTOR
254    * \param aMpdu the A-MPDU information
255    * \param staId the STA-ID
256    */
257   static void GetRadiotapHeader (RadiotapHeader &header,
258                                  Ptr<Packet> packet,
259                                  uint16_t channelFreqMhz,
260                                  WifiTxVector txVector,
261                                  MpduInfo aMpdu,
262                                  uint16_t staId);
263 
264   /**
265    * Get the Radiotap header for a received packet.
266    *
267    * \param header the radiotap header to be filled in
268    * \param packet the packet
269    * \param channelFreqMhz the channel frequency
270    * \param txVector the TXVECTOR
271    * \param aMpdu the A-MPDU information
272    * \param staId the STA-ID
273    * \param signalNoise the rx signal and noise information
274    */
275   static void GetRadiotapHeader (RadiotapHeader &header,
276                                  Ptr<Packet> packet,
277                                  uint16_t channelFreqMhz,
278                                  WifiTxVector txVector,
279                                  MpduInfo aMpdu,
280                                  uint16_t staId,
281                                  SignalNoiseDbm signalNoise);
282 
283   /**
284    * \brief Enable pcap output the indicated net device.
285    *
286    * NetDevice-specific implementation mechanism for hooking the trace and
287    * writing to the trace file.
288    *
289    * \param prefix Filename prefix to use for pcap files.
290    * \param nd Net device for which you want to enable tracing.
291    * \param promiscuous If true capture all possible packets available at the device.
292    * \param explicitFilename Treat the prefix as an explicit filename if true
293    */
294   virtual void EnablePcapInternal (std::string prefix,
295                                    Ptr<NetDevice> nd,
296                                    bool promiscuous,
297                                    bool explicitFilename) override;
298 
299   /**
300    * \brief Enable ASCII trace output on the indicated net device.
301    *
302    * NetDevice-specific implementation mechanism for hooking the trace and
303    * writing to the trace file.
304    *
305    * \param stream The output stream object to use when logging ASCII traces.
306    * \param prefix Filename prefix to use for ASCII trace files.
307    * \param nd Net device for which you want to enable tracing.
308    * \param explicitFilename Treat the prefix as an explicit filename if true
309    */
310   virtual void EnableAsciiInternal (Ptr<OutputStreamWrapper> stream,
311                                     std::string prefix,
312                                     Ptr<NetDevice> nd,
313                                     bool explicitFilename) override;
314 
315   PcapHelper::DataLinkType m_pcapDlt; ///< PCAP data link type
316 };
317 
318 
319 /**
320  * \brief helps to create WifiNetDevice objects
321  *
322  * This class can help to create a large set of similar
323  * WifiNetDevice objects and to configure a large set of
324  * their attributes during creation.
325  */
326 class WifiHelper
327 {
328 public:
329   virtual ~WifiHelper ();
330 
331   /**
332    * Create a Wifi helper in an empty state: all its parameters
333    * must be set before calling ns3::WifiHelper::Install
334    *
335    * The default state is defined as being an Adhoc MAC layer with an ARF rate control algorithm
336    * and both objects using their default attribute values.
337    * By default, configure MAC and PHY for 802.11a.
338    */
339   WifiHelper ();
340 
341   /**
342    * \param type the type of ns3::WifiRemoteStationManager to create.
343    * \param n0 the name of the attribute to set
344    * \param v0 the value of the attribute to set
345    * \param n1 the name of the attribute to set
346    * \param v1 the value of the attribute to set
347    * \param n2 the name of the attribute to set
348    * \param v2 the value of the attribute to set
349    * \param n3 the name of the attribute to set
350    * \param v3 the value of the attribute to set
351    * \param n4 the name of the attribute to set
352    * \param v4 the value of the attribute to set
353    * \param n5 the name of the attribute to set
354    * \param v5 the value of the attribute to set
355    * \param n6 the name of the attribute to set
356    * \param v6 the value of the attribute to set
357    * \param n7 the name of the attribute to set
358    * \param v7 the value of the attribute to set
359    *
360    * All the attributes specified in this method should exist
361    * in the requested station manager.
362    */
363   void SetRemoteStationManager (std::string type,
364                                 std::string n0 = "", const AttributeValue &v0 = EmptyAttributeValue (),
365                                 std::string n1 = "", const AttributeValue &v1 = EmptyAttributeValue (),
366                                 std::string n2 = "", const AttributeValue &v2 = EmptyAttributeValue (),
367                                 std::string n3 = "", const AttributeValue &v3 = EmptyAttributeValue (),
368                                 std::string n4 = "", const AttributeValue &v4 = EmptyAttributeValue (),
369                                 std::string n5 = "", const AttributeValue &v5 = EmptyAttributeValue (),
370                                 std::string n6 = "", const AttributeValue &v6 = EmptyAttributeValue (),
371                                 std::string n7 = "", const AttributeValue &v7 = EmptyAttributeValue ());
372 
373   /**
374    * \param type the type of ns3::ObssPdAlgorithm to create.
375    * \param n0 the name of the attribute to set
376    * \param v0 the value of the attribute to set
377    * \param n1 the name of the attribute to set
378    * \param v1 the value of the attribute to set
379    * \param n2 the name of the attribute to set
380    * \param v2 the value of the attribute to set
381    * \param n3 the name of the attribute to set
382    * \param v3 the value of the attribute to set
383    * \param n4 the name of the attribute to set
384    * \param v4 the value of the attribute to set
385    * \param n5 the name of the attribute to set
386    * \param v5 the value of the attribute to set
387    * \param n6 the name of the attribute to set
388    * \param v6 the value of the attribute to set
389    * \param n7 the name of the attribute to set
390    * \param v7 the value of the attribute to set
391    *
392    * All the attributes specified in this method should exist
393    * in the requested algorithm.
394    */
395   void SetObssPdAlgorithm (std::string type,
396                            std::string n0 = "", const AttributeValue &v0 = EmptyAttributeValue (),
397                            std::string n1 = "", const AttributeValue &v1 = EmptyAttributeValue (),
398                            std::string n2 = "", const AttributeValue &v2 = EmptyAttributeValue (),
399                            std::string n3 = "", const AttributeValue &v3 = EmptyAttributeValue (),
400                            std::string n4 = "", const AttributeValue &v4 = EmptyAttributeValue (),
401                            std::string n5 = "", const AttributeValue &v5 = EmptyAttributeValue (),
402                            std::string n6 = "", const AttributeValue &v6 = EmptyAttributeValue (),
403                            std::string n7 = "", const AttributeValue &v7 = EmptyAttributeValue ());
404 
405   /// Callback invoked to determine the MAC queue selected for a given packet
406   typedef std::function<std::size_t (Ptr<QueueItem>)> SelectQueueCallback;
407 
408   /**
409    * \param f the select queue callback
410    *
411    * Set the select queue callback to set on the NetDevice queue interface aggregated
412    * to the WifiNetDevice, in case RegularWifiMac with QoS enabled is used
413    */
414   void SetSelectQueueCallback (SelectQueueCallback f);
415   /**
416    * \param phy the PHY helper to create PHY objects
417    * \param mac the MAC helper to create MAC objects
418    * \param first lower bound on the set of nodes on which a wifi device must be created
419    * \param last upper bound on the set of nodes on which a wifi device must be created
420    * \returns a device container which contains all the devices created by this method.
421    */
422   NetDeviceContainer
423   virtual Install (const WifiPhyHelper &phy,
424                    const WifiMacHelper &mac,
425                    NodeContainer::Iterator first,
426                    NodeContainer::Iterator last) const;
427   /**
428    * \param phy the PHY helper to create PHY objects
429    * \param mac the MAC helper to create MAC objects
430    * \param c the set of nodes on which a wifi device must be created
431    * \returns a device container which contains all the devices created by this method.
432    */
433   virtual NetDeviceContainer Install (const WifiPhyHelper &phy,
434                                       const WifiMacHelper &mac, NodeContainer c) const;
435   /**
436    * \param phy the PHY helper to create PHY objects
437    * \param mac the MAC helper to create MAC objects
438    * \param node the node on which a wifi device must be created
439    * \returns a device container which contains all the devices created by this method.
440    */
441   virtual NetDeviceContainer Install (const WifiPhyHelper &phy,
442                                       const WifiMacHelper &mac, Ptr<Node> node) const;
443   /**
444    * \param phy the PHY helper to create PHY objects
445    * \param mac the MAC helper to create MAC objects
446    * \param nodeName the name of node on which a wifi device must be created
447    * \returns a device container which contains all the devices created by this method.
448    */
449   virtual NetDeviceContainer Install (const WifiPhyHelper &phy,
450                                       const WifiMacHelper &mac, std::string nodeName) const;
451   /**
452    * \param standard the standard to configure during installation
453    *
454    * This method sets standards-compliant defaults for WifiMac
455    * parameters such as SIFS time, slot time, timeout values, etc.,
456    * based on the standard selected.  It results in
457    * WifiMac::ConfigureStandard(standard) being called on each
458    * installed MAC object.
459    *
460    * The default standard of 802.11a will be applied if SetStandard()
461    * is not called.
462    *
463    * Note that WifiMac::ConfigureStandard () will overwrite certain
464    * defaults in the attribute system, so if a user wants to manipulate
465    * any default values affected by ConfigureStandard() while using this
466    * helper, the user should use a post-install configuration such as
467    * Config::Set() on any objects that this helper creates, such as:
468    * \code
469    * Config::Set ("/NodeList/0/DeviceList/0/$ns3::WifiNetDevice/Mac/Slot", TimeValue (MicroSeconds (slot)));
470    * \endcode
471    *
472    * \sa WifiMac::ConfigureStandard
473    * \sa Config::Set
474    */
475   virtual void SetStandard (WifiStandard standard);
476 
477   /**
478    * Helper to enable all WifiNetDevice log components with one statement
479    */
480   static void EnableLogComponents (void);
481 
482   /**
483   * Assign a fixed random variable stream number to the random variables
484   * used by the PHY and MAC aspects of the Wifi models.  Each device in
485   * container c has fixed stream numbers assigned to its random variables.
486   * The Wifi channel (e.g. propagation loss model) is excluded.
487   * Return the number of streams (possibly zero) that
488   * have been assigned. The Install() method should have previously been
489   * called by the user.
490   *
491   * \param c NetDeviceContainer of the set of net devices for which the
492   *          WifiNetDevice should be modified to use fixed streams
493   * \param stream first stream index to use
494   * \return the number of stream indices assigned by this helper
495   */
496   int64_t AssignStreams (NetDeviceContainer c, int64_t stream);
497 
498 
499 protected:
500   ObjectFactory m_stationManager;            ///< station manager
501   ObjectFactory m_ackPolicySelector[4];      ///< ack policy selector for all ACs
502   WifiStandard m_standard;                   ///< wifi standard
503   SelectQueueCallback m_selectQueueCallback; ///< select queue callback
504   ObjectFactory m_obssPdAlgorithm;           ///< OBSS_PD algorithm
505 };
506 
507 } //namespace ns3
508 
509 #endif /* WIFI_HELPER_H */
510