1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2006, 2009 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  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
20  * Author: Mirko Banchi <mk.banchi@gmail.com>
21  */
22 
23 #ifndef WIFI_MAC_HEADER_H
24 #define WIFI_MAC_HEADER_H
25 
26 #include "ns3/header.h"
27 #include "ns3/mac48-address.h"
28 
29 namespace ns3 {
30 
31 class Time;
32 
33 /**
34  * Combination of valid MAC header type/subtype.
35  */
36 enum WifiMacType
37 {
38   WIFI_MAC_CTL_TRIGGER = 0,
39   WIFI_MAC_CTL_CTLWRAPPER,
40   WIFI_MAC_CTL_RTS,
41   WIFI_MAC_CTL_CTS,
42   WIFI_MAC_CTL_ACK,
43   WIFI_MAC_CTL_BACKREQ,
44   WIFI_MAC_CTL_BACKRESP,
45   WIFI_MAC_CTL_END,
46   WIFI_MAC_CTL_END_ACK,
47 
48   WIFI_MAC_MGT_BEACON,
49   WIFI_MAC_MGT_ASSOCIATION_REQUEST,
50   WIFI_MAC_MGT_ASSOCIATION_RESPONSE,
51   WIFI_MAC_MGT_DISASSOCIATION,
52   WIFI_MAC_MGT_REASSOCIATION_REQUEST,
53   WIFI_MAC_MGT_REASSOCIATION_RESPONSE,
54   WIFI_MAC_MGT_PROBE_REQUEST,
55   WIFI_MAC_MGT_PROBE_RESPONSE,
56   WIFI_MAC_MGT_AUTHENTICATION,
57   WIFI_MAC_MGT_DEAUTHENTICATION,
58   WIFI_MAC_MGT_ACTION,
59   WIFI_MAC_MGT_ACTION_NO_ACK,
60   WIFI_MAC_MGT_MULTIHOP_ACTION,
61 
62   WIFI_MAC_DATA,
63   WIFI_MAC_DATA_CFACK,
64   WIFI_MAC_DATA_CFPOLL,
65   WIFI_MAC_DATA_CFACK_CFPOLL,
66   WIFI_MAC_DATA_NULL,
67   WIFI_MAC_DATA_NULL_CFACK,
68   WIFI_MAC_DATA_NULL_CFPOLL,
69   WIFI_MAC_DATA_NULL_CFACK_CFPOLL,
70   WIFI_MAC_QOSDATA,
71   WIFI_MAC_QOSDATA_CFACK,
72   WIFI_MAC_QOSDATA_CFPOLL,
73   WIFI_MAC_QOSDATA_CFACK_CFPOLL,
74   WIFI_MAC_QOSDATA_NULL,
75   WIFI_MAC_QOSDATA_NULL_CFPOLL,
76   WIFI_MAC_QOSDATA_NULL_CFACK_CFPOLL,
77 };
78 
79 /**
80  * \ingroup wifi
81  *
82  * Implements the IEEE 802.11 MAC header
83  */
84 class WifiMacHeader : public Header
85 {
86 public:
87   /**
88    * Ack policy for QoS frames.
89    */
90   enum QosAckPolicy
91   {
92     NORMAL_ACK = 0,
93     NO_ACK = 1,
94     NO_EXPLICIT_ACK = 2,
95     BLOCK_ACK = 3,
96   };
97 
98   /**
99    * Address types.
100    */
101   enum AddressType
102   {
103     ADDR1,
104     ADDR2,
105     ADDR3,
106     ADDR4
107   };
108 
109   WifiMacHeader ();
110   /**
111    * Construct a MAC header of the given type
112    *
113    * \param type the MAC header type
114    */
115   WifiMacHeader (WifiMacType type);
116   virtual ~WifiMacHeader ();
117 
118   /**
119    * \brief Get the type ID.
120    * \return the object TypeId
121    */
122   static TypeId GetTypeId (void);
123 
124   TypeId GetInstanceTypeId (void) const override;
125   void Print (std::ostream &os) const override;
126   uint32_t GetSerializedSize (void) const override;
127   void Serialize (Buffer::Iterator start) const override;
128   uint32_t Deserialize (Buffer::Iterator start) override;
129 
130   /**
131    * Set the From DS bit in the Frame Control field.
132    */
133   void SetDsFrom (void);
134   /**
135    * Un-set the From DS bit in the Frame Control field.
136    */
137   void SetDsNotFrom (void);
138   /**
139    * Set the To DS bit in the Frame Control field.
140    */
141   void SetDsTo (void);
142   /**
143    * Un-set the To DS bit in the Frame Control field.
144    */
145   void SetDsNotTo (void);
146   /**
147    * Fill the Address 1 field with the given address.
148    *
149    * \param address the address to be used in the Address 1 field
150    */
151   void SetAddr1 (Mac48Address address);
152   /**
153    * Fill the Address 2 field with the given address.
154    *
155    * \param address the address to be used in the Address 2 field
156    */
157   void SetAddr2 (Mac48Address address);
158   /**
159    * Fill the Address 3 field with the given address.
160    *
161    * \param address the address to be used in the Address 3 field
162    */
163   void SetAddr3 (Mac48Address address);
164   /**
165    * Fill the Address 4 field with the given address.
166    *
167    * \param address the address to be used in the Address 4 field
168    */
169   void SetAddr4 (Mac48Address address);
170   /**
171    * Set Type/Subtype values with the correct values depending
172    * on the given type.
173    *
174    * \param type the WifiMacType for the header
175    * \param resetToDsFromDs whether the ToDs and FromDs flags
176    *        should be reset.
177    */
178   void SetType (WifiMacType type, bool resetToDsFromDs = true);
179   /**
180    * Set the Duration/ID field with the given raw uint16_t value.
181    *
182    * \param duration the raw duration in uint16_t
183    */
184   void SetRawDuration (uint16_t duration);
185   /**
186    * Set the Duration/ID field with the given duration (Time object).
187    * The method converts the given time to microseconds.
188    *
189    * \param duration the duration (Time object)
190    */
191   void SetDuration (Time duration);
192   /**
193    * Set the Duration/ID field with the given ID.
194    *
195    * \param id the ID
196    */
197   void SetId (uint16_t id);
198   /**
199    * Set the sequence number of the header.
200    *
201    * \param seq the given sequence number
202    */
203   void SetSequenceNumber (uint16_t seq);
204   /**
205    * Set the fragment number of the header.
206    *
207    * \param frag the given fragment number
208    */
209   void SetFragmentNumber (uint8_t frag);
210   /**
211    * Un-set the More Fragment bit in the Frame Control Field
212    */
213   void SetNoMoreFragments (void);
214   /**
215    * Set the More Fragment bit in the Frame Control field
216    */
217   void SetMoreFragments (void);
218   /**
219    * Set the Retry bit in the Frame Control field.
220    */
221   void SetRetry (void);
222   /**
223    * Un-set the Retry bit in the Frame Control field.
224    */
225   void SetNoRetry (void);
226   /**
227    * Set the TID for the QoS header.
228    *
229    * \param tid the TID for the QoS header
230    */
231   void SetQosTid (uint8_t tid);
232   /**
233    * Set the end of service period (EOSP) bit in the QoS control field.
234    */
235   void SetQosEosp ();
236   /**
237    * Un-set the end of service period (EOSP) bit in the QoS control field.
238    */
239   void SetQosNoEosp ();
240   /**
241    * Set the QoS Ack policy in the QoS control field.
242    *
243    * \param policy the Qos Ack policy
244    */
245   void SetQosAckPolicy (QosAckPolicy policy);
246   /**
247    * Set that A-MSDU is present.
248    */
249   void SetQosAmsdu (void);
250   /**
251    * Set that A-MSDU is not present.
252    */
253   void SetQosNoAmsdu (void);
254   /**
255    * Set TXOP limit in the QoS control field.
256    *
257    * \param txop the TXOP limit
258    */
259   void SetQosTxopLimit (uint8_t txop);
260   /**
261    * Set the Queue Size subfield in the QoS control field.
262    *
263    * \param size the value for the Queue Size subfield
264    */
265   void SetQosQueueSize (uint8_t size);
266   /**
267    * Set the Mesh Control Present flag for the QoS header.
268    */
269   void SetQosMeshControlPresent ();
270   /**
271    * Clear the Mesh Control Present flag for the QoS header.
272    */
273   void SetQosNoMeshControlPresent ();
274   /**
275    * Set order bit in the frame control field.
276    */
277   void SetOrder (void);
278   /**
279    * Unset order bit in the frame control field.
280    */
281   void SetNoOrder (void);
282 
283   /**
284    * Return the address in the Address 1 field.
285    *
286    * \return the address in the Address 1 field
287    */
288   Mac48Address GetAddr1 (void) const;
289   /**
290    * Return the address in the Address 2 field.
291    *
292    * \return the address in the Address 2 field
293    */
294   Mac48Address GetAddr2 (void) const;
295   /**
296    * Return the address in the Address 3 field.
297    *
298    * \return the address in the Address 3 field
299    */
300   Mac48Address GetAddr3 (void) const;
301   /**
302    * Return the address in the Address 4 field.
303    *
304    * \return the address in the Address 4 field
305    */
306   Mac48Address GetAddr4 (void) const;
307   /**
308    * Return the type (enum WifiMacType)
309    *
310    * \return the type (enum WifiMacType)
311    */
312   WifiMacType GetType (void) const;
313   /**
314    * \return true if From DS bit is set, false otherwise
315    */
316   bool IsFromDs (void) const;
317   /**
318    * \return true if To DS bit is set, false otherwise
319    */
320   bool IsToDs (void) const;
321   /**
322    * Return true if the Type is DATA.  The method does
323    * not check the Subtype field. (e.g. the header may be
324    * Data with QoS)
325    *
326    * \return true if Type is DATA, false otherwise
327    */
328   bool IsData (void) const;
329   /**
330    * Return true if the Type is DATA and Subtype is one of the
331    * possible values for QoS Data.
332    *
333    * \return true if Type is QoS DATA, false otherwise
334    */
335   bool IsQosData (void) const;
336   /**
337    * Return true if the header type is DATA and is not DATA_NULL.
338    *
339    * \return true if the header type is DATA and is not DATA_NULL,
340    *         false otherwise
341    */
342   bool HasData (void) const;
343   /**
344    * Return true if the Type is Control.
345    *
346    * \return true if Type is Control, false otherwise
347    */
348   bool IsCtl (void) const;
349   /**
350    * Return true if the Type is Management.
351    *
352    * \return true if Type is Management, false otherwise
353    */
354   bool IsMgt (void) const;
355   /**
356    * Return true if the Type/Subtype is one of the possible CF-Poll headers.
357    *
358    * \return true if the Type/Subtype is one of the possible CF-Poll headers, false otherwise
359    */
360   bool IsCfPoll (void) const;
361   /**
362    * Return true if the header is a CF-Ack header.
363    *
364    * \return true if the header is a CF-Ack header, false otherwise
365    */
366   bool IsCfAck (void) const;
367   /**
368    * Return true if the header is a CF-End header.
369    *
370    * \return true if the header is a CF-End header, false otherwise
371    */
372   bool IsCfEnd (void) const;
373   /**
374    * Return true if the header is a RTS header.
375    *
376    * \return true if the header is a RTS header, false otherwise
377    */
378   bool IsRts (void) const;
379   /**
380    * Return true if the header is a CTS header.
381    *
382    * \return true if the header is a CTS header, false otherwise
383    */
384   bool IsCts (void) const;
385   /**
386    * Return true if the header is an Ack header.
387    *
388    * \return true if the header is an Ack header, false otherwise
389    */
390   bool IsAck (void) const;
391   /**
392    * Return true if the header is a BlockAckRequest header.
393    *
394    * \return true if the header is a BlockAckRequest header, false otherwise
395    */
396   bool IsBlockAckReq (void) const;
397   /**
398    * Return true if the header is a BlockAck header.
399    *
400    * \return true if the header is a BlockAck header, false otherwise
401    */
402   bool IsBlockAck (void) const;
403   /**
404    * Return true if the header is a Trigger header.
405    *
406    * \return true if the header is a Trigger header, false otherwise
407    */
408   bool IsTrigger (void) const;
409   /**
410    * Return true if the header is an Association Request header.
411    *
412    * \return true if the header is an Association Request header, false otherwise
413    */
414   bool IsAssocReq (void) const;
415   /**
416    * Return true if the header is an Association Response header.
417    *
418    * \return true if the header is an Association Response header, false otherwise
419    */
420   bool IsAssocResp (void) const;
421   /**
422    * Return true if the header is a Reassociation Request header.
423    *
424    * \return true if the header is a Reassociation Request header, false otherwise
425    */
426   bool IsReassocReq (void) const;
427   /**
428    * Return true if the header is a Reassociation Response header.
429    *
430    * \return true if the header is a Reassociation Response header, false otherwise
431    */
432   bool IsReassocResp (void) const;
433   /**
434    * Return true if the header is a Probe Request header.
435    *
436    * \return true if the header is a Probe Request header, false otherwise
437    */
438   bool IsProbeReq (void) const;
439   /**
440    * Return true if the header is a Probe Response header.
441    *
442    * \return true if the header is a Probe Response header, false otherwise
443    */
444   bool IsProbeResp (void) const;
445   /**
446    * Return true if the header is a Beacon header.
447    *
448    * \return true if the header is a Beacon header, false otherwise
449    */
450   bool IsBeacon (void) const;
451   /**
452    * Return true if the header is a Disassociation header.
453    *
454    * \return true if the header is a Disassociation header, false otherwise
455    */
456   bool IsDisassociation (void) const;
457   /**
458    * Return true if the header is an Authentication header.
459    *
460    * \return true if the header is an Authentication header, false otherwise
461    */
462   bool IsAuthentication (void) const;
463   /**
464    * Return true if the header is a Deauthentication header.
465    *
466    * \return true if the header is a Deauthentication header, false otherwise
467    */
468   bool IsDeauthentication (void) const;
469   /**
470    * Return true if the header is an Action header.
471    *
472    * \return true if the header is an Action header, false otherwise
473    */
474   bool IsAction (void) const;
475   /**
476    * Check if the header is a Multihop action header.
477    *
478    * \return true if the header is a Multihop action header,
479    *         false otherwise
480    */
481   bool IsMultihopAction (void) const;
482   /**
483    * Return the raw duration from the Duration/ID field.
484    *
485    * \return the raw duration from the Duration/ID field
486    */
487   uint16_t GetRawDuration (void) const;
488   /**
489    * Return the duration from the Duration/ID field (Time object).
490    *
491    * \return the duration from the Duration/ID field (Time object)
492    */
493   Time GetDuration (void) const;
494   /**
495    * Return the raw Sequence Control field.
496    *
497    * \return the raw Sequence Control field
498    */
499   uint16_t GetSequenceControl (void) const;
500   /**
501    * Return the sequence number of the header.
502    *
503    * \return the sequence number of the header
504    */
505   uint16_t GetSequenceNumber (void) const;
506   /**
507    * Return the fragment number of the header.
508    *
509    * \return the fragment number of the header
510    */
511   uint8_t GetFragmentNumber (void) const;
512   /**
513    * Return if the Retry bit is set.
514    *
515    * \return true if the Retry bit is set, false otherwise
516    */
517   bool IsRetry (void) const;
518   /**
519    * Return if the More Fragment bit is set.
520    *
521    * \return true if the More Fragment bit is set, false otherwise
522    */
523   bool IsMoreFragments (void) const;
524   /**
525    * Return if the QoS Ack policy is Block Ack.
526    *
527    * \return true if the QoS Ack policy is Block Ack, false otherwise
528    */
529   bool IsQosBlockAck (void) const;
530   /**
531    * Return if the QoS Ack policy is No Ack.
532    *
533    * \return true if the QoS Ack policy is No Ack, false otherwise
534    */
535   bool IsQosNoAck (void) const;
536   /**
537    * Return if the QoS Ack policy is Normal Ack.
538    *
539    * \return true if the QoS Ack policy is No Ack, false otherwise
540    */
541   bool IsQosAck (void) const;
542   /**
543    * Return if the end of service period (EOSP) is set.
544    *
545    * \return true if the end of service period (EOSP) is set, false otherwise
546    */
547   bool IsQosEosp (void) const;
548   /**
549    * Check if the A-MSDU present bit is set in the QoS control field.
550    *
551    * \return true if the A-MSDU present bit is set,
552    *         false otherwise
553    */
554   bool IsQosAmsdu (void) const;
555   /**
556    * Return the Traffic ID of a QoS header.
557    *
558    * \return the Traffic ID of a QoS header
559    */
560   uint8_t GetQosTid (void) const;
561   /**
562    * Return the QoS Ack policy in the QoS control field.
563    *
564    * \return the QoS Ack policy in the QoS control field
565    */
566   QosAckPolicy GetQosAckPolicy (void) const;
567   /**
568    * Get the Queue Size subfield in the QoS control field.
569    *
570    * \return the value of the Queue Size subfield
571    */
572   uint8_t GetQosQueueSize (void) const;
573   /**
574    * Return the size of the WifiMacHeader in octets.
575    * GetSerializedSize calls this function.
576    *
577    * \return the size of the WifiMacHeader in octets
578    */
579   uint32_t GetSize (void) const;
580   /**
581    * Return a string corresponds to the header type.
582    *
583    * \returns a string corresponds to the header type.
584    */
585   const char * GetTypeString (void) const;
586 
587   /**
588    * TracedCallback signature for WifiMacHeader
589    *
590    * \param [in] header The header
591    */
592   typedef void (* TracedCallback)(const WifiMacHeader &header);
593 
594 
595 private:
596   /**
597    * Return the raw Frame Control field.
598    *
599    * \return the raw Frame Control field
600    */
601   uint16_t GetFrameControl (void) const;
602   /**
603    * Return the raw QoS Control field.
604    *
605    * \return the raw QoS Control field
606    */
607   uint16_t GetQosControl (void) const;
608   /**
609    * Set the Frame Control field with the given raw value.
610    *
611    * \param control the raw Frame Control field value
612    */
613   void SetFrameControl (uint16_t control);
614   /**
615    * Set the Sequence Control field with the given raw value.
616    *
617    * \param seq the raw Sequence Control field value
618    */
619   void SetSequenceControl (uint16_t seq);
620   /**
621    * Set the QoS Control field with the given raw value.
622    *
623    * \param qos the raw QoS Control field value
624    */
625   void SetQosControl (uint16_t qos);
626   /**
627    * Print the Frame Control field to the output stream.
628    *
629    * \param os the output stream to print to
630    */
631   void PrintFrameControl (std::ostream &os) const;
632 
633   uint8_t m_ctrlType;     ///< control type
634   uint8_t m_ctrlSubtype;  ///< control subtype
635   uint8_t m_ctrlToDs;     ///< control to DS
636   uint8_t m_ctrlFromDs;   ///< control from DS
637   uint8_t m_ctrlMoreFrag; ///< control more fragments
638   uint8_t m_ctrlRetry;    ///< control retry
639   uint8_t m_ctrlMoreData; ///< control more data
640   uint8_t m_ctrlWep;      ///< control WEP
641   uint8_t m_ctrlOrder;    ///< control order (set to 1 for QoS Data and Management frames to signify that HT/VHT/HE control field is present, knowing that the latter are not implemented yet)
642   uint16_t m_duration;    ///< duration
643   Mac48Address m_addr1;   ///< address 1
644   Mac48Address m_addr2;   ///< address 2
645   Mac48Address m_addr3;   ///< address 3
646   uint8_t m_seqFrag;      ///< sequence fragment
647   uint16_t m_seqSeq;      ///< sequence sequence
648   Mac48Address m_addr4;   ///< address 4
649   uint8_t m_qosTid;       ///< QoS TID
650   uint8_t m_qosEosp;      ///< QoS EOSP
651   uint8_t m_qosAckPolicy; ///< QoS Ack policy
652   uint8_t m_amsduPresent; ///< A-MSDU present
653   uint8_t m_qosStuff;     ///< QoS stuff
654 };
655 
656 } //namespace ns3
657 
658 #endif /* WIFI_MAC_HEADER_H */
659