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  * Authors: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
20  *          Mirko Banchi <mk.banchi@gmail.com>
21  */
22 
23 #include "ns3/nstime.h"
24 #include "ns3/address-utils.h"
25 #include "wifi-mac-header.h"
26 
27 namespace ns3 {
28 
29 NS_OBJECT_ENSURE_REGISTERED (WifiMacHeader);
30 
31 /// type enumeration
32 enum
33 {
34   TYPE_MGT = 0,
35   TYPE_CTL  = 1,
36   TYPE_DATA = 2
37 };
38 
39 /// subtype enumeration
40 enum
41 {
42   //Reserved: 0 - 1
43   SUBTYPE_CTL_TRIGGER = 2,
44   //Reserved: 3
45   SUBTYPE_CTL_BEAMFORMINGRPOLL = 4,
46   SUBTYPE_CTL_NDPANNOUNCE = 5,
47   SUBTYPE_CTL_CTLFRAMEEXT = 6,
48   SUBTYPE_CTL_CTLWRAPPER = 7,
49   SUBTYPE_CTL_BACKREQ = 8,
50   SUBTYPE_CTL_BACKRESP = 9,
51   SUBTYPE_CTL_RTS = 11,
52   SUBTYPE_CTL_CTS = 12,
53   SUBTYPE_CTL_ACK = 13,
54   SUBTYPE_CTL_END = 14,
55   SUBTYPE_CTL_END_ACK = 15
56 };
57 
WifiMacHeader()58 WifiMacHeader::WifiMacHeader ()
59   : m_ctrlMoreFrag (0),
60     m_ctrlRetry (0),
61     m_ctrlMoreData (0),
62     m_ctrlWep (0),
63     m_ctrlOrder (0),
64     m_duration (0),
65     m_seqFrag (0),
66     m_seqSeq (0),
67     m_qosEosp (0),
68     m_qosAckPolicy (0),  // Normal Ack
69     m_amsduPresent (0)
70 {
71 }
72 
WifiMacHeader(WifiMacType type)73 WifiMacHeader::WifiMacHeader (WifiMacType type)
74   : WifiMacHeader ()
75 {
76   SetType (type);
77 }
78 
~WifiMacHeader()79 WifiMacHeader::~WifiMacHeader ()
80 {
81 }
82 
83 void
SetDsFrom(void)84 WifiMacHeader::SetDsFrom (void)
85 {
86   m_ctrlFromDs = 1;
87 }
88 
89 void
SetDsNotFrom(void)90 WifiMacHeader::SetDsNotFrom (void)
91 {
92   m_ctrlFromDs = 0;
93 }
94 
95 void
SetDsTo(void)96 WifiMacHeader::SetDsTo (void)
97 {
98   m_ctrlToDs = 1;
99 }
100 
101 void
SetDsNotTo(void)102 WifiMacHeader::SetDsNotTo (void)
103 {
104   m_ctrlToDs = 0;
105 }
106 
107 void
SetAddr1(Mac48Address address)108 WifiMacHeader::SetAddr1 (Mac48Address address)
109 {
110   m_addr1 = address;
111 }
112 
113 void
SetAddr2(Mac48Address address)114 WifiMacHeader::SetAddr2 (Mac48Address address)
115 {
116   m_addr2 = address;
117 }
118 
119 void
SetAddr3(Mac48Address address)120 WifiMacHeader::SetAddr3 (Mac48Address address)
121 {
122   m_addr3 = address;
123 }
124 
125 void
SetAddr4(Mac48Address address)126 WifiMacHeader::SetAddr4 (Mac48Address address)
127 {
128   m_addr4 = address;
129 }
130 
131 void
SetType(WifiMacType type,bool resetToDsFromDs)132 WifiMacHeader::SetType (WifiMacType type, bool resetToDsFromDs)
133 {
134   switch (type)
135     {
136     case WIFI_MAC_CTL_TRIGGER:
137       m_ctrlType = TYPE_CTL;
138       m_ctrlSubtype = SUBTYPE_CTL_TRIGGER;
139       break;
140     case WIFI_MAC_CTL_CTLWRAPPER:
141       m_ctrlType = TYPE_CTL;
142       m_ctrlSubtype = SUBTYPE_CTL_CTLWRAPPER;
143       break;
144     case WIFI_MAC_CTL_BACKREQ:
145       m_ctrlType = TYPE_CTL;
146       m_ctrlSubtype = SUBTYPE_CTL_BACKREQ;
147       break;
148     case WIFI_MAC_CTL_BACKRESP:
149       m_ctrlType = TYPE_CTL;
150       m_ctrlSubtype = SUBTYPE_CTL_BACKRESP;
151       break;
152     case WIFI_MAC_CTL_RTS:
153       m_ctrlType = TYPE_CTL;
154       m_ctrlSubtype = SUBTYPE_CTL_RTS;
155       break;
156     case WIFI_MAC_CTL_CTS:
157       m_ctrlType = TYPE_CTL;
158       m_ctrlSubtype = SUBTYPE_CTL_CTS;
159       break;
160     case WIFI_MAC_CTL_ACK:
161       m_ctrlType = TYPE_CTL;
162       m_ctrlSubtype = SUBTYPE_CTL_ACK;
163       break;
164     case WIFI_MAC_CTL_END:
165       m_ctrlType = TYPE_CTL;
166       m_ctrlSubtype = SUBTYPE_CTL_END;
167       break;
168     case WIFI_MAC_CTL_END_ACK:
169       m_ctrlType = TYPE_CTL;
170       m_ctrlSubtype = SUBTYPE_CTL_END_ACK;
171       break;
172     case WIFI_MAC_MGT_ASSOCIATION_REQUEST:
173       m_ctrlType = TYPE_MGT;
174       m_ctrlSubtype = 0;
175       break;
176     case WIFI_MAC_MGT_ASSOCIATION_RESPONSE:
177       m_ctrlType = TYPE_MGT;
178       m_ctrlSubtype = 1;
179       break;
180     case WIFI_MAC_MGT_REASSOCIATION_REQUEST:
181       m_ctrlType = TYPE_MGT;
182       m_ctrlSubtype = 2;
183       break;
184     case WIFI_MAC_MGT_REASSOCIATION_RESPONSE:
185       m_ctrlType = TYPE_MGT;
186       m_ctrlSubtype = 3;
187       break;
188     case WIFI_MAC_MGT_PROBE_REQUEST:
189       m_ctrlType = TYPE_MGT;
190       m_ctrlSubtype = 4;
191       break;
192     case WIFI_MAC_MGT_PROBE_RESPONSE:
193       m_ctrlType = TYPE_MGT;
194       m_ctrlSubtype = 5;
195       break;
196     case WIFI_MAC_MGT_BEACON:
197       m_ctrlType = TYPE_MGT;
198       m_ctrlSubtype = 8;
199       break;
200     case WIFI_MAC_MGT_DISASSOCIATION:
201       m_ctrlType = TYPE_MGT;
202       m_ctrlSubtype = 10;
203       break;
204     case WIFI_MAC_MGT_AUTHENTICATION:
205       m_ctrlType = TYPE_MGT;
206       m_ctrlSubtype = 11;
207       break;
208     case WIFI_MAC_MGT_DEAUTHENTICATION:
209       m_ctrlType = TYPE_MGT;
210       m_ctrlSubtype = 12;
211       break;
212     case WIFI_MAC_MGT_ACTION:
213       m_ctrlType = TYPE_MGT;
214       m_ctrlSubtype = 13;
215       break;
216     case WIFI_MAC_MGT_ACTION_NO_ACK:
217       m_ctrlType = TYPE_MGT;
218       m_ctrlSubtype = 14;
219       break;
220     case WIFI_MAC_MGT_MULTIHOP_ACTION:
221       m_ctrlType = TYPE_MGT;
222       m_ctrlSubtype = 15;
223       break;
224     case WIFI_MAC_DATA:
225       m_ctrlType = TYPE_DATA;
226       m_ctrlSubtype = 0;
227       break;
228     case WIFI_MAC_DATA_CFACK:
229       m_ctrlType = TYPE_DATA;
230       m_ctrlSubtype = 1;
231       break;
232     case WIFI_MAC_DATA_CFPOLL:
233       m_ctrlType = TYPE_DATA;
234       m_ctrlSubtype = 2;
235       break;
236     case WIFI_MAC_DATA_CFACK_CFPOLL:
237       m_ctrlType = TYPE_DATA;
238       m_ctrlSubtype = 3;
239       break;
240     case WIFI_MAC_DATA_NULL:
241       m_ctrlType = TYPE_DATA;
242       m_ctrlSubtype = 4;
243       break;
244     case WIFI_MAC_DATA_NULL_CFACK:
245       m_ctrlType = TYPE_DATA;
246       m_ctrlSubtype = 5;
247       break;
248     case WIFI_MAC_DATA_NULL_CFPOLL:
249       m_ctrlType = TYPE_DATA;
250       m_ctrlSubtype = 6;
251       break;
252     case WIFI_MAC_DATA_NULL_CFACK_CFPOLL:
253       m_ctrlType = TYPE_DATA;
254       m_ctrlSubtype = 7;
255       break;
256     case WIFI_MAC_QOSDATA:
257       m_ctrlType = TYPE_DATA;
258       m_ctrlSubtype = 8;
259       break;
260     case WIFI_MAC_QOSDATA_CFACK:
261       m_ctrlType = TYPE_DATA;
262       m_ctrlSubtype = 9;
263       break;
264     case WIFI_MAC_QOSDATA_CFPOLL:
265       m_ctrlType = TYPE_DATA;
266       m_ctrlSubtype = 10;
267       break;
268     case WIFI_MAC_QOSDATA_CFACK_CFPOLL:
269       m_ctrlType = TYPE_DATA;
270       m_ctrlSubtype = 11;
271       break;
272     case WIFI_MAC_QOSDATA_NULL:
273       m_ctrlType = TYPE_DATA;
274       m_ctrlSubtype = 12;
275       break;
276     case WIFI_MAC_QOSDATA_NULL_CFPOLL:
277       m_ctrlType = TYPE_DATA;
278       m_ctrlSubtype = 14;
279       break;
280     case WIFI_MAC_QOSDATA_NULL_CFACK_CFPOLL:
281       m_ctrlType = TYPE_DATA;
282       m_ctrlSubtype = 15;
283       break;
284     }
285   if (resetToDsFromDs)
286     {
287       m_ctrlToDs = 0;
288       m_ctrlFromDs = 0;
289     }
290 }
291 
292 void
SetRawDuration(uint16_t duration)293 WifiMacHeader::SetRawDuration (uint16_t duration)
294 {
295   NS_ASSERT (duration <= 32768);
296   m_duration = duration;
297 }
298 
299 void
SetDuration(Time duration)300 WifiMacHeader::SetDuration (Time duration)
301 {
302   int64_t duration_us = static_cast<int64_t> (ceil (static_cast<double> (duration.GetNanoSeconds ()) / 1000));
303   NS_ASSERT (duration_us >= 0 && duration_us <= 0x7fff);
304   m_duration = static_cast<uint16_t> (duration_us);
305 }
306 
SetId(uint16_t id)307 void WifiMacHeader::SetId (uint16_t id)
308 {
309   m_duration = id;
310 }
311 
SetSequenceNumber(uint16_t seq)312 void WifiMacHeader::SetSequenceNumber (uint16_t seq)
313 {
314   m_seqSeq = seq;
315 }
316 
SetFragmentNumber(uint8_t frag)317 void WifiMacHeader::SetFragmentNumber (uint8_t frag)
318 {
319   m_seqFrag = frag;
320 }
321 
SetNoMoreFragments(void)322 void WifiMacHeader::SetNoMoreFragments (void)
323 {
324   m_ctrlMoreFrag = 0;
325 }
326 
SetMoreFragments(void)327 void WifiMacHeader::SetMoreFragments (void)
328 {
329   m_ctrlMoreFrag = 1;
330 }
331 
SetOrder(void)332 void WifiMacHeader::SetOrder (void)
333 {
334   m_ctrlOrder = 1;
335 }
336 
SetNoOrder(void)337 void WifiMacHeader::SetNoOrder (void)
338 {
339   m_ctrlOrder = 0;
340 }
341 
SetRetry(void)342 void WifiMacHeader::SetRetry (void)
343 {
344   m_ctrlRetry = 1;
345 }
346 
SetNoRetry(void)347 void WifiMacHeader::SetNoRetry (void)
348 {
349   m_ctrlRetry = 0;
350 }
351 
SetQosTid(uint8_t tid)352 void WifiMacHeader::SetQosTid (uint8_t tid)
353 {
354   m_qosTid = tid;
355 }
356 
SetQosEosp()357 void WifiMacHeader::SetQosEosp ()
358 {
359   m_qosEosp = 1;
360 }
361 
SetQosNoEosp()362 void WifiMacHeader::SetQosNoEosp ()
363 {
364   m_qosEosp = 0;
365 }
366 
SetQosAckPolicy(QosAckPolicy policy)367 void WifiMacHeader::SetQosAckPolicy (QosAckPolicy policy)
368 {
369   switch (policy)
370     {
371     case NORMAL_ACK:
372       m_qosAckPolicy = 0;
373       break;
374     case NO_ACK:
375       m_qosAckPolicy = 1;
376       break;
377     case NO_EXPLICIT_ACK:
378       m_qosAckPolicy = 2;
379       break;
380     case BLOCK_ACK:
381       m_qosAckPolicy = 3;
382       break;
383     }
384 }
385 
SetQosAmsdu(void)386 void WifiMacHeader::SetQosAmsdu (void)
387 {
388   m_amsduPresent = 1;
389 }
390 
SetQosNoAmsdu(void)391 void WifiMacHeader::SetQosNoAmsdu (void)
392 {
393   m_amsduPresent = 0;
394 }
395 
SetQosTxopLimit(uint8_t txop)396 void WifiMacHeader::SetQosTxopLimit (uint8_t txop)
397 {
398   m_qosStuff = txop;
399 }
400 
401 void
SetQosQueueSize(uint8_t size)402 WifiMacHeader::SetQosQueueSize (uint8_t size)
403 {
404   m_qosEosp = 1;
405   m_qosStuff = size;
406 }
407 
SetQosMeshControlPresent(void)408 void WifiMacHeader::SetQosMeshControlPresent (void)
409 {
410   //Mark bit 0 of this variable instead of bit 8, since m_qosStuff is
411   //shifted by one byte when serialized
412   m_qosStuff = m_qosStuff | 0x01; //bit 8 of QoS Control Field
413 }
414 
SetQosNoMeshControlPresent()415 void WifiMacHeader::SetQosNoMeshControlPresent ()
416 {
417   //Clear bit 0 of this variable instead of bit 8, since m_qosStuff is
418   //shifted by one byte when serialized
419   m_qosStuff = m_qosStuff & 0xfe; //bit 8 of QoS Control Field
420 }
421 
422 
423 Mac48Address
GetAddr1(void) const424 WifiMacHeader::GetAddr1 (void) const
425 {
426   return m_addr1;
427 }
428 
429 Mac48Address
GetAddr2(void) const430 WifiMacHeader::GetAddr2 (void) const
431 {
432   return m_addr2;
433 }
434 
435 Mac48Address
GetAddr3(void) const436 WifiMacHeader::GetAddr3 (void) const
437 {
438   return m_addr3;
439 }
440 
441 Mac48Address
GetAddr4(void) const442 WifiMacHeader::GetAddr4 (void) const
443 {
444   return m_addr4;
445 }
446 
447 WifiMacType
GetType(void) const448 WifiMacHeader::GetType (void) const
449 {
450   switch (m_ctrlType)
451     {
452     case TYPE_MGT:
453       switch (m_ctrlSubtype)
454         {
455         case 0:
456           return WIFI_MAC_MGT_ASSOCIATION_REQUEST;
457         case 1:
458           return WIFI_MAC_MGT_ASSOCIATION_RESPONSE;
459         case 2:
460           return WIFI_MAC_MGT_REASSOCIATION_REQUEST;
461         case 3:
462           return WIFI_MAC_MGT_REASSOCIATION_RESPONSE;
463         case 4:
464           return WIFI_MAC_MGT_PROBE_REQUEST;
465         case 5:
466           return WIFI_MAC_MGT_PROBE_RESPONSE;
467         case 8:
468           return WIFI_MAC_MGT_BEACON;
469         case 10:
470           return WIFI_MAC_MGT_DISASSOCIATION;
471         case 11:
472           return WIFI_MAC_MGT_AUTHENTICATION;
473         case 12:
474           return WIFI_MAC_MGT_DEAUTHENTICATION;
475         case 13:
476           return WIFI_MAC_MGT_ACTION;
477         case 14:
478           return WIFI_MAC_MGT_ACTION_NO_ACK;
479         case 15:
480           return WIFI_MAC_MGT_MULTIHOP_ACTION;
481         }
482       break;
483     case TYPE_CTL:
484       switch (m_ctrlSubtype)
485         {
486         case SUBTYPE_CTL_TRIGGER:
487           return WIFI_MAC_CTL_TRIGGER;
488         case SUBTYPE_CTL_BACKREQ:
489           return WIFI_MAC_CTL_BACKREQ;
490         case SUBTYPE_CTL_BACKRESP:
491           return WIFI_MAC_CTL_BACKRESP;
492         case SUBTYPE_CTL_RTS:
493           return WIFI_MAC_CTL_RTS;
494         case SUBTYPE_CTL_CTS:
495           return WIFI_MAC_CTL_CTS;
496         case SUBTYPE_CTL_ACK:
497           return WIFI_MAC_CTL_ACK;
498         case SUBTYPE_CTL_END:
499           return WIFI_MAC_CTL_END;
500         case SUBTYPE_CTL_END_ACK:
501           return WIFI_MAC_CTL_END_ACK;
502         }
503       break;
504     case TYPE_DATA:
505       switch (m_ctrlSubtype)
506         {
507         case 0:
508           return WIFI_MAC_DATA;
509         case 1:
510           return WIFI_MAC_DATA_CFACK;
511         case 2:
512           return WIFI_MAC_DATA_CFPOLL;
513         case 3:
514           return WIFI_MAC_DATA_CFACK_CFPOLL;
515         case 4:
516           return WIFI_MAC_DATA_NULL;
517         case 5:
518           return WIFI_MAC_DATA_NULL_CFACK;
519         case 6:
520           return WIFI_MAC_DATA_NULL_CFPOLL;
521         case 7:
522           return WIFI_MAC_DATA_NULL_CFACK_CFPOLL;
523         case 8:
524           return WIFI_MAC_QOSDATA;
525         case 9:
526           return WIFI_MAC_QOSDATA_CFACK;
527         case 10:
528           return WIFI_MAC_QOSDATA_CFPOLL;
529         case 11:
530           return WIFI_MAC_QOSDATA_CFACK_CFPOLL;
531         case 12:
532           return WIFI_MAC_QOSDATA_NULL;
533         case 14:
534           return WIFI_MAC_QOSDATA_NULL_CFPOLL;
535         case 15:
536           return WIFI_MAC_QOSDATA_NULL_CFACK_CFPOLL;
537         }
538       break;
539     }
540   // NOTREACHED
541   NS_ASSERT (false);
542   return (WifiMacType) - 1;
543 }
544 
545 bool
IsFromDs(void) const546 WifiMacHeader::IsFromDs (void) const
547 {
548   return m_ctrlFromDs == 1;
549 }
550 
551 bool
IsToDs(void) const552 WifiMacHeader::IsToDs (void) const
553 {
554   return m_ctrlToDs == 1;
555 }
556 
557 bool
IsData(void) const558 WifiMacHeader::IsData (void) const
559 {
560   return (m_ctrlType == TYPE_DATA);
561 
562 }
563 
564 bool
IsQosData(void) const565 WifiMacHeader::IsQosData (void) const
566 {
567   return (m_ctrlType == TYPE_DATA && (m_ctrlSubtype & 0x08));
568 }
569 
570 bool
IsCtl(void) const571 WifiMacHeader::IsCtl (void) const
572 {
573   return (m_ctrlType == TYPE_CTL);
574 }
575 
576 bool
IsMgt(void) const577 WifiMacHeader::IsMgt (void) const
578 {
579   return (m_ctrlType == TYPE_MGT);
580 }
581 
582 bool
IsCfPoll(void) const583 WifiMacHeader::IsCfPoll (void) const
584 {
585   switch (GetType ())
586     {
587     case WIFI_MAC_DATA_CFPOLL:
588     case WIFI_MAC_DATA_CFACK_CFPOLL:
589     case WIFI_MAC_DATA_NULL_CFPOLL:
590     case WIFI_MAC_DATA_NULL_CFACK_CFPOLL:
591     case WIFI_MAC_QOSDATA_CFPOLL:
592     case WIFI_MAC_QOSDATA_CFACK_CFPOLL:
593     case WIFI_MAC_QOSDATA_NULL_CFPOLL:
594     case WIFI_MAC_QOSDATA_NULL_CFACK_CFPOLL:
595       return true;
596     default:
597       return false;
598     }
599 }
600 
601 bool
IsCfEnd(void) const602 WifiMacHeader::IsCfEnd (void) const
603 {
604   switch (GetType ())
605     {
606     case WIFI_MAC_CTL_END:
607     case WIFI_MAC_CTL_END_ACK:
608       return true;
609     default:
610       return false;
611     }
612 }
613 
614 bool
IsCfAck(void) const615 WifiMacHeader::IsCfAck (void) const
616 {
617   switch (GetType ())
618     {
619     case WIFI_MAC_DATA_CFACK:
620     case WIFI_MAC_DATA_CFACK_CFPOLL:
621     case WIFI_MAC_DATA_NULL_CFACK:
622     case WIFI_MAC_DATA_NULL_CFACK_CFPOLL:
623     case WIFI_MAC_CTL_END_ACK:
624       return true;
625     default:
626       return false;
627       break;
628     }
629 }
630 
631 bool
HasData(void) const632 WifiMacHeader::HasData (void) const
633 {
634   switch (GetType ())
635     {
636     case WIFI_MAC_DATA:
637     case WIFI_MAC_DATA_CFACK:
638     case WIFI_MAC_DATA_CFPOLL:
639     case WIFI_MAC_DATA_CFACK_CFPOLL:
640     case WIFI_MAC_QOSDATA:
641     case WIFI_MAC_QOSDATA_CFACK:
642     case WIFI_MAC_QOSDATA_CFPOLL:
643     case WIFI_MAC_QOSDATA_CFACK_CFPOLL:
644       return true;
645     default:
646       return false;
647     }
648 }
649 
650 bool
IsRts(void) const651 WifiMacHeader::IsRts (void) const
652 {
653   return (GetType () == WIFI_MAC_CTL_RTS);
654 }
655 
656 bool
IsCts(void) const657 WifiMacHeader::IsCts (void) const
658 {
659   return (GetType () == WIFI_MAC_CTL_CTS);
660 }
661 
662 bool
IsAck(void) const663 WifiMacHeader::IsAck (void) const
664 {
665   return (GetType () == WIFI_MAC_CTL_ACK);
666 }
667 
668 bool
IsAssocReq(void) const669 WifiMacHeader::IsAssocReq (void) const
670 {
671   return (GetType () == WIFI_MAC_MGT_ASSOCIATION_REQUEST);
672 }
673 
674 bool
IsAssocResp(void) const675 WifiMacHeader::IsAssocResp (void) const
676 {
677   return (GetType () == WIFI_MAC_MGT_ASSOCIATION_RESPONSE);
678 }
679 
680 bool
IsReassocReq(void) const681 WifiMacHeader::IsReassocReq (void) const
682 {
683   return (GetType () == WIFI_MAC_MGT_REASSOCIATION_REQUEST);
684 }
685 
686 bool
IsReassocResp(void) const687 WifiMacHeader::IsReassocResp (void) const
688 {
689   return (GetType () == WIFI_MAC_MGT_REASSOCIATION_RESPONSE);
690 }
691 
692 bool
IsProbeReq(void) const693 WifiMacHeader::IsProbeReq (void) const
694 {
695   return (GetType () == WIFI_MAC_MGT_PROBE_REQUEST);
696 }
697 
698 bool
IsProbeResp(void) const699 WifiMacHeader::IsProbeResp (void) const
700 {
701   return (GetType () == WIFI_MAC_MGT_PROBE_RESPONSE);
702 }
703 
704 bool
IsBeacon(void) const705 WifiMacHeader::IsBeacon (void) const
706 {
707   return (GetType () == WIFI_MAC_MGT_BEACON);
708 }
709 
710 bool
IsDisassociation(void) const711 WifiMacHeader::IsDisassociation (void) const
712 {
713   return (GetType () == WIFI_MAC_MGT_DISASSOCIATION);
714 }
715 
716 bool
IsAuthentication(void) const717 WifiMacHeader::IsAuthentication (void) const
718 {
719   return (GetType () == WIFI_MAC_MGT_AUTHENTICATION);
720 }
721 
722 bool
IsDeauthentication(void) const723 WifiMacHeader::IsDeauthentication (void) const
724 {
725   return (GetType () == WIFI_MAC_MGT_DEAUTHENTICATION);
726 }
727 
728 bool
IsAction(void) const729 WifiMacHeader::IsAction (void) const
730 {
731   return (GetType () == WIFI_MAC_MGT_ACTION);
732 }
733 
734 bool
IsMultihopAction(void) const735 WifiMacHeader::IsMultihopAction (void) const
736 {
737   return (GetType () == WIFI_MAC_MGT_MULTIHOP_ACTION);
738 }
739 
740 bool
IsBlockAckReq(void) const741 WifiMacHeader::IsBlockAckReq (void) const
742 {
743   return (GetType () == WIFI_MAC_CTL_BACKREQ) ? true : false;
744 }
745 
746 bool
IsBlockAck(void) const747 WifiMacHeader::IsBlockAck (void) const
748 {
749   return (GetType () == WIFI_MAC_CTL_BACKRESP) ? true : false;
750 }
751 
752 bool
IsTrigger(void) const753 WifiMacHeader::IsTrigger (void) const
754 {
755   return (GetType () == WIFI_MAC_CTL_TRIGGER) ? true : false;
756 }
757 
758 uint16_t
GetRawDuration(void) const759 WifiMacHeader::GetRawDuration (void) const
760 {
761   return m_duration;
762 }
763 
764 Time
GetDuration(void) const765 WifiMacHeader::GetDuration (void) const
766 {
767   return MicroSeconds (m_duration);
768 }
769 
770 uint16_t
GetSequenceControl(void) const771 WifiMacHeader::GetSequenceControl (void) const
772 {
773   return (m_seqSeq << 4) | m_seqFrag;
774 }
775 
776 uint16_t
GetSequenceNumber(void) const777 WifiMacHeader::GetSequenceNumber (void) const
778 {
779   return m_seqSeq;
780 }
781 
782 uint8_t
GetFragmentNumber(void) const783 WifiMacHeader::GetFragmentNumber (void) const
784 {
785   return m_seqFrag;
786 }
787 
788 bool
IsRetry(void) const789 WifiMacHeader::IsRetry (void) const
790 {
791   return (m_ctrlRetry == 1);
792 }
793 
794 bool
IsMoreFragments(void) const795 WifiMacHeader::IsMoreFragments (void) const
796 {
797   return (m_ctrlMoreFrag == 1);
798 }
799 
800 bool
IsQosBlockAck(void) const801 WifiMacHeader::IsQosBlockAck (void) const
802 {
803   NS_ASSERT (IsQosData ());
804   return (m_qosAckPolicy == 3);
805 }
806 
807 bool
IsQosNoAck(void) const808 WifiMacHeader::IsQosNoAck (void) const
809 {
810   NS_ASSERT (IsQosData ());
811   return (m_qosAckPolicy == 1);
812 }
813 
814 bool
IsQosAck(void) const815 WifiMacHeader::IsQosAck (void) const
816 {
817   NS_ASSERT (IsQosData ());
818   return (m_qosAckPolicy == 0);
819 }
820 
821 bool
IsQosEosp(void) const822 WifiMacHeader::IsQosEosp (void) const
823 {
824   NS_ASSERT (IsQosData ());
825   return (m_qosEosp == 1);
826 }
827 
828 WifiMacHeader::QosAckPolicy
GetQosAckPolicy(void) const829 WifiMacHeader::GetQosAckPolicy (void) const
830 {
831   NS_ASSERT (IsQosData ());
832   QosAckPolicy policy;
833 
834   switch (m_qosAckPolicy)
835     {
836     case 0:
837       policy = NORMAL_ACK;
838       break;
839     case 1:
840       policy = NO_ACK;
841       break;
842     case 2:
843       policy = NO_EXPLICIT_ACK;
844       break;
845     case 3:
846       policy = BLOCK_ACK;
847       break;
848     default:
849       NS_ABORT_MSG ("Unknown QoS Ack policy");
850     }
851   return policy;
852 }
853 
854 bool
IsQosAmsdu(void) const855 WifiMacHeader::IsQosAmsdu (void) const
856 {
857   NS_ASSERT (IsQosData ());
858   return (m_amsduPresent == 1);
859 }
860 
861 uint8_t
GetQosTid(void) const862 WifiMacHeader::GetQosTid (void) const
863 {
864   NS_ASSERT (IsQosData ());
865   return m_qosTid;
866 }
867 
868 uint8_t
GetQosQueueSize(void) const869 WifiMacHeader::GetQosQueueSize (void) const
870 {
871   NS_ASSERT (m_qosEosp == 1);
872   return m_qosStuff;
873 }
874 
875 uint16_t
GetFrameControl(void) const876 WifiMacHeader::GetFrameControl (void) const
877 {
878   uint16_t val = 0;
879   val |= (m_ctrlType << 2) & (0x3 << 2);
880   val |= (m_ctrlSubtype << 4) & (0xf << 4);
881   val |= (m_ctrlToDs << 8) & (0x1 << 8);
882   val |= (m_ctrlFromDs << 9) & (0x1 << 9);
883   val |= (m_ctrlMoreFrag << 10) & (0x1 << 10);
884   val |= (m_ctrlRetry << 11) & (0x1 << 11);
885   val |= (m_ctrlMoreData << 13) & (0x1 << 13);
886   val |= (m_ctrlWep << 14) & (0x1 << 14);
887   val |= (m_ctrlOrder << 15) & (0x1 << 15);
888   return val;
889 }
890 
891 uint16_t
GetQosControl(void) const892 WifiMacHeader::GetQosControl (void) const
893 {
894   uint16_t val = 0;
895   val |= m_qosTid;
896   val |= m_qosEosp << 4;
897   val |= m_qosAckPolicy << 5;
898   val |= m_amsduPresent << 7;
899   val |= m_qosStuff << 8;
900   return val;
901 }
902 
903 void
SetFrameControl(uint16_t ctrl)904 WifiMacHeader::SetFrameControl (uint16_t ctrl)
905 {
906   m_ctrlType = (ctrl >> 2) & 0x03;
907   m_ctrlSubtype = (ctrl >> 4) & 0x0f;
908   m_ctrlToDs = (ctrl >> 8) & 0x01;
909   m_ctrlFromDs = (ctrl >> 9) & 0x01;
910   m_ctrlMoreFrag = (ctrl >> 10) & 0x01;
911   m_ctrlRetry = (ctrl >> 11) & 0x01;
912   m_ctrlMoreData = (ctrl >> 13) & 0x01;
913   m_ctrlWep = (ctrl >> 14) & 0x01;
914   m_ctrlOrder = (ctrl >> 15) & 0x01;
915 }
916 void
SetSequenceControl(uint16_t seq)917 WifiMacHeader::SetSequenceControl (uint16_t seq)
918 {
919   m_seqFrag = seq & 0x0f;
920   m_seqSeq = (seq >> 4) & 0x0fff;
921 }
922 void
SetQosControl(uint16_t qos)923 WifiMacHeader::SetQosControl (uint16_t qos)
924 {
925   m_qosTid = qos & 0x000f;
926   m_qosEosp = (qos >> 4) & 0x0001;
927   m_qosAckPolicy = (qos >> 5) & 0x0003;
928   m_amsduPresent = (qos >> 7) & 0x0001;
929   m_qosStuff = (qos >> 8) & 0x00ff;
930 }
931 
932 uint32_t
GetSize(void) const933 WifiMacHeader::GetSize (void) const
934 {
935   uint32_t size = 0;
936   switch (m_ctrlType)
937     {
938     case TYPE_MGT:
939       size = 2 + 2 + 6 + 6 + 6 + 2;
940       break;
941     case TYPE_CTL:
942       switch (m_ctrlSubtype)
943         {
944         case SUBTYPE_CTL_RTS:
945         case SUBTYPE_CTL_BACKREQ:
946         case SUBTYPE_CTL_BACKRESP:
947         case SUBTYPE_CTL_TRIGGER:
948         case SUBTYPE_CTL_END:
949         case SUBTYPE_CTL_END_ACK:
950           size = 2 + 2 + 6 + 6;
951           break;
952         case SUBTYPE_CTL_CTS:
953         case SUBTYPE_CTL_ACK:
954           size = 2 + 2 + 6;
955           break;
956         case SUBTYPE_CTL_CTLWRAPPER:
957           size = 2 + 2 + 6 + 2 + 4;
958           break;
959         }
960       break;
961     case TYPE_DATA:
962       size = 2 + 2 + 6 + 6 + 6 + 2;
963       if (m_ctrlToDs && m_ctrlFromDs)
964         {
965           size += 6;
966         }
967       if (m_ctrlSubtype & 0x08)
968         {
969           size += 2;
970         }
971       break;
972     }
973   return size;
974 }
975 
976 const char *
GetTypeString(void) const977 WifiMacHeader::GetTypeString (void) const
978 {
979 #define FOO(x) \
980 case WIFI_MAC_ ## x: \
981   return # x; \
982   break;
983 
984   switch (GetType ())
985     {
986       FOO (CTL_RTS);
987       FOO (CTL_CTS);
988       FOO (CTL_ACK);
989       FOO (CTL_BACKREQ);
990       FOO (CTL_BACKRESP);
991       FOO (CTL_END);
992       FOO (CTL_END_ACK);
993       FOO (CTL_TRIGGER);
994 
995       FOO (MGT_BEACON);
996       FOO (MGT_ASSOCIATION_REQUEST);
997       FOO (MGT_ASSOCIATION_RESPONSE);
998       FOO (MGT_DISASSOCIATION);
999       FOO (MGT_REASSOCIATION_REQUEST);
1000       FOO (MGT_REASSOCIATION_RESPONSE);
1001       FOO (MGT_PROBE_REQUEST);
1002       FOO (MGT_PROBE_RESPONSE);
1003       FOO (MGT_AUTHENTICATION);
1004       FOO (MGT_DEAUTHENTICATION);
1005       FOO (MGT_ACTION);
1006       FOO (MGT_ACTION_NO_ACK);
1007       FOO (MGT_MULTIHOP_ACTION);
1008 
1009       FOO (DATA);
1010       FOO (DATA_CFACK);
1011       FOO (DATA_CFPOLL);
1012       FOO (DATA_CFACK_CFPOLL);
1013       FOO (DATA_NULL);
1014       FOO (DATA_NULL_CFACK);
1015       FOO (DATA_NULL_CFPOLL);
1016       FOO (DATA_NULL_CFACK_CFPOLL);
1017       FOO (QOSDATA);
1018       FOO (QOSDATA_CFACK);
1019       FOO (QOSDATA_CFPOLL);
1020       FOO (QOSDATA_CFACK_CFPOLL);
1021       FOO (QOSDATA_NULL);
1022       FOO (QOSDATA_NULL_CFPOLL);
1023       FOO (QOSDATA_NULL_CFACK_CFPOLL);
1024     default:
1025       return "ERROR";
1026     }
1027 #undef FOO
1028 #ifndef _WIN32
1029   // needed to make gcc 4.0.1 ppc darwin happy.
1030   return "BIG_ERROR";
1031 #endif
1032 }
1033 
1034 TypeId
GetTypeId(void)1035 WifiMacHeader::GetTypeId (void)
1036 {
1037   static TypeId tid = TypeId ("ns3::WifiMacHeader")
1038     .SetParent<Header> ()
1039     .SetGroupName ("Wifi")
1040     .AddConstructor<WifiMacHeader> ()
1041   ;
1042   return tid;
1043 }
1044 
1045 TypeId
GetInstanceTypeId(void) const1046 WifiMacHeader::GetInstanceTypeId (void) const
1047 {
1048   return GetTypeId ();
1049 }
1050 
1051 void
PrintFrameControl(std::ostream & os) const1052 WifiMacHeader::PrintFrameControl (std::ostream &os) const
1053 {
1054   os << "ToDS=" << std::hex << (int) m_ctrlToDs << ", FromDS=" << std::hex << (int) m_ctrlFromDs
1055      << ", MoreFrag=" <<  std::hex << (int) m_ctrlMoreFrag << ", Retry=" << std::hex << (int) m_ctrlRetry
1056      << ", MoreData=" <<  std::hex << (int) m_ctrlMoreData << std::dec
1057   ;
1058 }
1059 
1060 void
Print(std::ostream & os) const1061 WifiMacHeader::Print (std::ostream &os) const
1062 {
1063   os << GetTypeString () << " ";
1064   switch (GetType ())
1065     {
1066     case WIFI_MAC_CTL_RTS:
1067     case WIFI_MAC_CTL_TRIGGER:
1068       os << "Duration/ID=" << m_duration << "us"
1069          << ", RA=" << m_addr1 << ", TA=" << m_addr2;
1070       break;
1071     case WIFI_MAC_CTL_CTS:
1072     case WIFI_MAC_CTL_ACK:
1073       os << "Duration/ID=" << m_duration << "us"
1074          << ", RA=" << m_addr1;
1075       break;
1076     case WIFI_MAC_MGT_BEACON:
1077     case WIFI_MAC_MGT_ASSOCIATION_REQUEST:
1078     case WIFI_MAC_MGT_ASSOCIATION_RESPONSE:
1079     case WIFI_MAC_MGT_DISASSOCIATION:
1080     case WIFI_MAC_MGT_REASSOCIATION_REQUEST:
1081     case WIFI_MAC_MGT_REASSOCIATION_RESPONSE:
1082     case WIFI_MAC_MGT_PROBE_REQUEST:
1083     case WIFI_MAC_MGT_PROBE_RESPONSE:
1084     case WIFI_MAC_MGT_AUTHENTICATION:
1085     case WIFI_MAC_MGT_DEAUTHENTICATION:
1086       PrintFrameControl (os);
1087       os << " Duration/ID=" << m_duration << "us"
1088          << ", DA=" << m_addr1 << ", SA=" << m_addr2
1089          << ", BSSID=" << m_addr3 << ", FragNumber=" << std::hex << (int) m_seqFrag << std::dec
1090          << ", SeqNumber=" << m_seqSeq;
1091       break;
1092     case WIFI_MAC_MGT_ACTION:
1093     case WIFI_MAC_MGT_ACTION_NO_ACK:
1094       PrintFrameControl (os);
1095       os << " Duration/ID=" << m_duration << "us"
1096          << ", DA=" << m_addr1 << ", SA=" << m_addr2 << ", BSSID=" << m_addr3
1097          << ", FragNumber=" << std::hex << (int) m_seqFrag << std::dec << ", SeqNumber=" << m_seqSeq;
1098       break;
1099     case WIFI_MAC_MGT_MULTIHOP_ACTION:
1100       os << " Duration/ID=" << m_duration << "us"
1101          << ", RA=" << m_addr1 << ", TA=" << m_addr2 << ", DA=" << m_addr3
1102          << ", FragNumber=" << std::hex << (int) m_seqFrag << std::dec << ", SeqNumber=" << m_seqSeq;
1103       break;
1104     case WIFI_MAC_DATA:
1105       PrintFrameControl (os);
1106       os << " Duration/ID=" << m_duration << "us";
1107       if (!m_ctrlToDs && !m_ctrlFromDs)
1108         {
1109           os << ", DA=" << m_addr1 << ", SA=" << m_addr2 << ", BSSID=" << m_addr3;
1110         }
1111       else if (!m_ctrlToDs && m_ctrlFromDs)
1112         {
1113           os << ", DA=" << m_addr1 << ", SA=" << m_addr3 << ", BSSID=" << m_addr2;
1114         }
1115       else if (m_ctrlToDs && !m_ctrlFromDs)
1116         {
1117           os << ", DA=" << m_addr3 << ", SA=" << m_addr2 << ", BSSID=" << m_addr1;
1118         }
1119       else if (m_ctrlToDs && m_ctrlFromDs)
1120         {
1121           os << ", DA=" << m_addr3 << ", SA=" << m_addr4 << ", RA=" << m_addr1 << ", TA=" << m_addr2;
1122         }
1123       else
1124         {
1125           NS_FATAL_ERROR ("Impossible ToDs and FromDs flags combination");
1126         }
1127       os << ", FragNumber=" << std::hex << (int) m_seqFrag << std::dec
1128          << ", SeqNumber=" << m_seqSeq;
1129       break;
1130     case WIFI_MAC_CTL_BACKREQ:
1131     case WIFI_MAC_CTL_BACKRESP:
1132     case WIFI_MAC_CTL_CTLWRAPPER:
1133     case WIFI_MAC_CTL_END:
1134     case WIFI_MAC_CTL_END_ACK:
1135     case WIFI_MAC_DATA_CFACK:
1136     case WIFI_MAC_DATA_CFPOLL:
1137     case WIFI_MAC_DATA_CFACK_CFPOLL:
1138     case WIFI_MAC_DATA_NULL:
1139     case WIFI_MAC_DATA_NULL_CFACK:
1140     case WIFI_MAC_DATA_NULL_CFPOLL:
1141     case WIFI_MAC_DATA_NULL_CFACK_CFPOLL:
1142     case WIFI_MAC_QOSDATA:
1143     case WIFI_MAC_QOSDATA_CFACK:
1144     case WIFI_MAC_QOSDATA_CFPOLL:
1145     case WIFI_MAC_QOSDATA_CFACK_CFPOLL:
1146     case WIFI_MAC_QOSDATA_NULL:
1147     case WIFI_MAC_QOSDATA_NULL_CFPOLL:
1148     case WIFI_MAC_QOSDATA_NULL_CFACK_CFPOLL:
1149     default:
1150       break;
1151     }
1152 }
1153 
1154 uint32_t
GetSerializedSize(void) const1155 WifiMacHeader::GetSerializedSize (void) const
1156 {
1157   return GetSize ();
1158 }
1159 
1160 void
Serialize(Buffer::Iterator i) const1161 WifiMacHeader::Serialize (Buffer::Iterator i) const
1162 {
1163   i.WriteHtolsbU16 (GetFrameControl ());
1164   i.WriteHtolsbU16 (m_duration);
1165   WriteTo (i, m_addr1);
1166   switch (m_ctrlType)
1167     {
1168     case TYPE_MGT:
1169       WriteTo (i, m_addr2);
1170       WriteTo (i, m_addr3);
1171       i.WriteHtolsbU16 (GetSequenceControl ());
1172       break;
1173     case TYPE_CTL:
1174       switch (m_ctrlSubtype)
1175         {
1176         case SUBTYPE_CTL_RTS:
1177         case SUBTYPE_CTL_TRIGGER:
1178         case SUBTYPE_CTL_BACKREQ:
1179         case SUBTYPE_CTL_BACKRESP:
1180         case SUBTYPE_CTL_END:
1181         case SUBTYPE_CTL_END_ACK:
1182           WriteTo (i, m_addr2);
1183           break;
1184         case SUBTYPE_CTL_CTS:
1185         case SUBTYPE_CTL_ACK:
1186           break;
1187         default:
1188           //NOTREACHED
1189           NS_ASSERT (false);
1190           break;
1191         }
1192       break;
1193     case TYPE_DATA:
1194       {
1195         WriteTo (i, m_addr2);
1196         WriteTo (i, m_addr3);
1197         i.WriteHtolsbU16 (GetSequenceControl ());
1198         if (m_ctrlToDs && m_ctrlFromDs)
1199           {
1200             WriteTo (i, m_addr4);
1201           }
1202         if (m_ctrlSubtype & 0x08)
1203           {
1204             i.WriteHtolsbU16 (GetQosControl ());
1205           }
1206       } break;
1207     default:
1208       //NOTREACHED
1209       NS_ASSERT (false);
1210       break;
1211     }
1212 }
1213 
1214 uint32_t
Deserialize(Buffer::Iterator start)1215 WifiMacHeader::Deserialize (Buffer::Iterator start)
1216 {
1217   Buffer::Iterator i = start;
1218   uint16_t frame_control = i.ReadLsbtohU16 ();
1219   SetFrameControl (frame_control);
1220   m_duration = i.ReadLsbtohU16 ();
1221   ReadFrom (i, m_addr1);
1222   switch (m_ctrlType)
1223     {
1224     case TYPE_MGT:
1225       ReadFrom (i, m_addr2);
1226       ReadFrom (i, m_addr3);
1227       SetSequenceControl (i.ReadLsbtohU16 ());
1228       break;
1229     case TYPE_CTL:
1230       switch (m_ctrlSubtype)
1231         {
1232         case SUBTYPE_CTL_RTS:
1233         case SUBTYPE_CTL_TRIGGER:
1234         case SUBTYPE_CTL_BACKREQ:
1235         case SUBTYPE_CTL_BACKRESP:
1236         case SUBTYPE_CTL_END:
1237         case SUBTYPE_CTL_END_ACK:
1238           ReadFrom (i, m_addr2);
1239           break;
1240         case SUBTYPE_CTL_CTS:
1241         case SUBTYPE_CTL_ACK:
1242           break;
1243         }
1244       break;
1245     case TYPE_DATA:
1246       ReadFrom (i, m_addr2);
1247       ReadFrom (i, m_addr3);
1248       SetSequenceControl (i.ReadLsbtohU16 ());
1249       if (m_ctrlToDs && m_ctrlFromDs)
1250         {
1251           ReadFrom (i, m_addr4);
1252         }
1253       if (m_ctrlSubtype & 0x08)
1254         {
1255           SetQosControl (i.ReadLsbtohU16 ());
1256         }
1257       break;
1258     }
1259   return i.GetDistanceFrom (start);
1260 }
1261 
1262 } //namespace ns3
1263