A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
wifi-mac-header.cc
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 #include "ns3/assert.h"
23 #include "ns3/address-utils.h"
24 #include "wifi-mac-header.h"
25 
26 namespace ns3 {
27 
28 NS_OBJECT_ENSURE_REGISTERED (WifiMacHeader);
29 
30 enum
31 {
32  TYPE_MGT = 0,
33  TYPE_CTL = 1,
34  TYPE_DATA = 2
35 };
36 
37 enum
38 {
39  SUBTYPE_CTL_BACKREQ = 8,
40  SUBTYPE_CTL_BACKRESP = 9,
41  SUBTYPE_CTL_RTS = 11,
42  SUBTYPE_CTL_CTS = 12,
43  SUBTYPE_CTL_ACK = 13
44 };
45 
46 WifiMacHeader::WifiMacHeader ()
47  : m_ctrlPwrMgt (0),
48  m_ctrlMoreData (0),
49  m_ctrlWep (0),
50  m_ctrlOrder (1),
51  m_amsduPresent (0)
52 {
53 }
54 WifiMacHeader::~WifiMacHeader ()
55 {
56 }
57 
58 void
59 WifiMacHeader::SetDsFrom (void)
60 {
61  m_ctrlFromDs = 1;
62 }
63 void
64 WifiMacHeader::SetDsNotFrom (void)
65 {
66  m_ctrlFromDs = 0;
67 }
68 void
69 WifiMacHeader::SetDsTo (void)
70 {
71  m_ctrlToDs = 1;
72 }
73 void
74 WifiMacHeader::SetDsNotTo (void)
75 {
76  m_ctrlToDs = 0;
77 }
78 
79 void
80 WifiMacHeader::SetAddr1 (Mac48Address address)
81 {
82  m_addr1 = address;
83 }
84 void
85 WifiMacHeader::SetAddr2 (Mac48Address address)
86 {
87  m_addr2 = address;
88 }
89 void
90 WifiMacHeader::SetAddr3 (Mac48Address address)
91 {
92  m_addr3 = address;
93 }
94 void
95 WifiMacHeader::SetAddr4 (Mac48Address address)
96 {
97  m_addr4 = address;
98 }
99 void
100 WifiMacHeader::SetAssocReq (void)
101 {
102  m_ctrlType = TYPE_MGT;
103  m_ctrlSubtype = 0;
104 }
105 void
106 WifiMacHeader::SetAssocResp (void)
107 {
108  m_ctrlType = TYPE_MGT;
109  m_ctrlSubtype = 1;
110 }
111 void
112 WifiMacHeader::SetProbeReq (void)
113 {
114  m_ctrlType = TYPE_MGT;
115  m_ctrlSubtype = 4;
116 }
117 void
118 WifiMacHeader::SetProbeResp (void)
119 {
120  m_ctrlType = TYPE_MGT;
121  m_ctrlSubtype = 5;
122 }
123 void
124 WifiMacHeader::SetBeacon (void)
125 {
126  m_ctrlType = TYPE_MGT;
127  m_ctrlSubtype = 8;
128 }
129 void
130 WifiMacHeader::SetBlockAckReq (void)
131 {
132  m_ctrlType = TYPE_CTL;
133  m_ctrlSubtype = 8;
134 }
135 void
136 WifiMacHeader::SetBlockAck (void)
137 {
138  m_ctrlType = TYPE_CTL;
139  m_ctrlSubtype = 9;
140 }
141 
142 void
143 WifiMacHeader::SetTypeData (void)
144 {
145  m_ctrlType = TYPE_DATA;
146  m_ctrlSubtype = 0;
147 }
148 void
149 WifiMacHeader::SetAction (void)
150 {
151  m_ctrlType = TYPE_MGT;
152  m_ctrlSubtype = 0x0D;
153 }
154 void
155 WifiMacHeader::SetMultihopAction (void)
156 {
157  m_ctrlType = TYPE_MGT;
158  m_ctrlSubtype = 0x0F;
159 }
160 void
161 WifiMacHeader::SetType (enum WifiMacType type)
162 {
163  switch (type)
164  {
165  case WIFI_MAC_CTL_BACKREQ:
166  m_ctrlType = TYPE_CTL;
167  m_ctrlSubtype = SUBTYPE_CTL_BACKREQ;
168  break;
169  case WIFI_MAC_CTL_BACKRESP:
170  m_ctrlType = TYPE_CTL;
171  m_ctrlSubtype = SUBTYPE_CTL_BACKRESP;
172  break;
173  case WIFI_MAC_CTL_RTS:
174  m_ctrlType = TYPE_CTL;
175  m_ctrlSubtype = SUBTYPE_CTL_RTS;
176  break;
177  case WIFI_MAC_CTL_CTS:
178  m_ctrlType = TYPE_CTL;
179  m_ctrlSubtype = SUBTYPE_CTL_CTS;
180  break;
181  case WIFI_MAC_CTL_ACK:
182  m_ctrlType = TYPE_CTL;
183  m_ctrlSubtype = SUBTYPE_CTL_ACK;
184  break;
185  case WIFI_MAC_MGT_ASSOCIATION_REQUEST:
186  m_ctrlType = TYPE_MGT;
187  m_ctrlSubtype = 0;
188  break;
189  case WIFI_MAC_MGT_ASSOCIATION_RESPONSE:
190  m_ctrlType = TYPE_MGT;
191  m_ctrlSubtype = 1;
192  break;
193  case WIFI_MAC_MGT_REASSOCIATION_REQUEST:
194  m_ctrlType = TYPE_MGT;
195  m_ctrlSubtype = 2;
196  break;
197  case WIFI_MAC_MGT_REASSOCIATION_RESPONSE:
198  m_ctrlType = TYPE_MGT;
199  m_ctrlSubtype = 3;
200  break;
201  case WIFI_MAC_MGT_PROBE_REQUEST:
202  m_ctrlType = TYPE_MGT;
203  m_ctrlSubtype = 4;
204  break;
205  case WIFI_MAC_MGT_PROBE_RESPONSE:
206  m_ctrlType = TYPE_MGT;
207  m_ctrlSubtype = 5;
208  break;
209  case WIFI_MAC_MGT_BEACON:
210  m_ctrlType = TYPE_MGT;
211  m_ctrlSubtype = 8;
212  break;
213  case WIFI_MAC_MGT_DISASSOCIATION:
214  m_ctrlType = TYPE_MGT;
215  m_ctrlSubtype = 10;
216  break;
217  case WIFI_MAC_MGT_AUTHENTICATION:
218  m_ctrlType = TYPE_MGT;
219  m_ctrlSubtype = 11;
220  break;
221  case WIFI_MAC_MGT_DEAUTHENTICATION:
222  m_ctrlType = TYPE_MGT;
223  m_ctrlSubtype = 12;
224  case WIFI_MAC_MGT_ACTION:
225  m_ctrlType = TYPE_MGT;
226  m_ctrlSubtype = 13;
227  case WIFI_MAC_MGT_ACTION_NO_ACK:
228  m_ctrlType = TYPE_MGT;
229  m_ctrlSubtype = 14;
230  case WIFI_MAC_MGT_MULTIHOP_ACTION:
231  m_ctrlType = TYPE_MGT;
232  m_ctrlSubtype = 15;
233  break;
234 
235  case WIFI_MAC_DATA:
236  m_ctrlType = TYPE_DATA;
237  m_ctrlSubtype = 0;
238  break;
239  case WIFI_MAC_DATA_CFACK:
240  m_ctrlType = TYPE_DATA;
241  m_ctrlSubtype = 1;
242  break;
243  case WIFI_MAC_DATA_CFPOLL:
244  m_ctrlType = TYPE_DATA;
245  m_ctrlSubtype = 2;
246  break;
247  case WIFI_MAC_DATA_CFACK_CFPOLL:
248  m_ctrlType = TYPE_DATA;
249  m_ctrlSubtype = 3;
250  break;
251  case WIFI_MAC_DATA_NULL:
252  m_ctrlType = TYPE_DATA;
253  m_ctrlSubtype = 4;
254  break;
255  case WIFI_MAC_DATA_NULL_CFACK:
256  m_ctrlType = TYPE_DATA;
257  m_ctrlSubtype = 5;
258  break;
259  case WIFI_MAC_DATA_NULL_CFPOLL:
260  m_ctrlType = TYPE_DATA;
261  m_ctrlSubtype = 6;
262  break;
263  case WIFI_MAC_DATA_NULL_CFACK_CFPOLL:
264  m_ctrlType = TYPE_DATA;
265  m_ctrlSubtype = 7;
266  break;
267  case WIFI_MAC_QOSDATA:
268  m_ctrlType = TYPE_DATA;
269  m_ctrlSubtype = 8;
270  break;
271  case WIFI_MAC_QOSDATA_CFACK:
272  m_ctrlType = TYPE_DATA;
273  m_ctrlSubtype = 9;
274  break;
275  case WIFI_MAC_QOSDATA_CFPOLL:
276  m_ctrlType = TYPE_DATA;
277  m_ctrlSubtype = 10;
278  break;
279  case WIFI_MAC_QOSDATA_CFACK_CFPOLL:
280  m_ctrlType = TYPE_DATA;
281  m_ctrlSubtype = 11;
282  break;
283  case WIFI_MAC_QOSDATA_NULL:
284  m_ctrlType = TYPE_DATA;
285  m_ctrlSubtype = 12;
286  break;
287  case WIFI_MAC_QOSDATA_NULL_CFPOLL:
288  m_ctrlType = TYPE_DATA;
289  m_ctrlSubtype = 14;
290  break;
291  case WIFI_MAC_QOSDATA_NULL_CFACK_CFPOLL:
292  m_ctrlType = TYPE_DATA;
293  m_ctrlSubtype = 15;
294  break;
295  }
296  m_ctrlToDs = 0;
297  m_ctrlFromDs = 0;
298 }
299 void
300 WifiMacHeader::SetRawDuration (uint16_t duration)
301 {
302  m_duration = duration;
303 }
304 void
305 WifiMacHeader::SetDuration (Time duration)
306 {
307  int64_t duration_us = duration.GetMicroSeconds ();
308  NS_ASSERT (duration_us >= 0 && duration_us <= 0x7fff);
309  m_duration = static_cast<uint16_t> (duration_us);
310 }
311 
312 void WifiMacHeader::SetId (uint16_t id)
313 {
314  m_duration = id;
315 }
316 void WifiMacHeader::SetSequenceNumber (uint16_t seq)
317 {
318  m_seqSeq = seq;
319 }
320 void WifiMacHeader::SetFragmentNumber (uint8_t frag)
321 {
322  m_seqFrag = frag;
323 }
324 void WifiMacHeader::SetNoMoreFragments (void)
325 {
326  m_ctrlMoreFrag = 0;
327 }
328 void WifiMacHeader::SetMoreFragments (void)
329 {
330  m_ctrlMoreFrag = 1;
331 }
332 void WifiMacHeader::SetRetry (void)
333 {
334  m_ctrlRetry = 1;
335 }
336 void WifiMacHeader::SetNoRetry (void)
337 {
338  m_ctrlRetry = 0;
339 }
340 void WifiMacHeader::SetQosTid (uint8_t tid)
341 {
342  m_qosTid = tid;
343 }
344 void WifiMacHeader::SetQosEosp ()
345 {
346  m_qosEosp = 1;
347 }
348 void WifiMacHeader::SetQosNoEosp ()
349 {
350  m_qosEosp = 0;
351 }
352 void WifiMacHeader::SetQosAckPolicy (enum QosAckPolicy policy)
353 {
354  switch (policy)
355  {
356  case NORMAL_ACK:
357  m_qosAckPolicy = 0;
358  break;
359  case NO_ACK:
360  m_qosAckPolicy = 1;
361  break;
362  case NO_EXPLICIT_ACK:
363  m_qosAckPolicy = 2;
364  break;
365  case BLOCK_ACK:
366  m_qosAckPolicy = 3;
367  break;
368  }
369 }
370 void
371 WifiMacHeader::SetQosNormalAck ()
372 {
373  m_qosAckPolicy = 0;
374 }
375 void
376 WifiMacHeader::SetQosBlockAck ()
377 {
378  m_qosAckPolicy = 3;
379 }
380 void
381 WifiMacHeader::SetQosNoAck ()
382 {
383  m_qosAckPolicy = 1;
384 }
385 void WifiMacHeader::SetQosAmsdu (void)
386 {
387  m_amsduPresent = 1;
388 }
389 void WifiMacHeader::SetQosNoAmsdu (void)
390 {
391  m_amsduPresent = 0;
392 }
393 void WifiMacHeader::SetQosTxopLimit (uint8_t txop)
394 {
395  m_qosStuff = txop;
396 }
397 
398 Mac48Address
399 WifiMacHeader::GetAddr1 (void) const
400 {
401  return m_addr1;
402 }
403 Mac48Address
404 WifiMacHeader::GetAddr2 (void) const
405 {
406  return m_addr2;
407 }
408 Mac48Address
409 WifiMacHeader::GetAddr3 (void) const
410 {
411  return m_addr3;
412 }
413 Mac48Address
414 WifiMacHeader::GetAddr4 (void) const
415 {
416  return m_addr4;
417 }
418 
419 enum WifiMacType
420 WifiMacHeader::GetType (void) const
421 {
422  switch (m_ctrlType)
423  {
424  case TYPE_MGT:
425  switch (m_ctrlSubtype)
426  {
427  case 0:
428  return WIFI_MAC_MGT_ASSOCIATION_REQUEST;
429  break;
430  case 1:
431  return WIFI_MAC_MGT_ASSOCIATION_RESPONSE;
432  break;
433  case 2:
434  return WIFI_MAC_MGT_REASSOCIATION_REQUEST;
435  break;
436  case 3:
437  return WIFI_MAC_MGT_REASSOCIATION_RESPONSE;
438  break;
439  case 4:
440  return WIFI_MAC_MGT_PROBE_REQUEST;
441  break;
442  case 5:
443  return WIFI_MAC_MGT_PROBE_RESPONSE;
444  break;
445  case 8:
446  return WIFI_MAC_MGT_BEACON;
447  break;
448  case 10:
449  return WIFI_MAC_MGT_DISASSOCIATION;
450  break;
451  case 11:
452  return WIFI_MAC_MGT_AUTHENTICATION;
453  break;
454  case 12:
455  return WIFI_MAC_MGT_DEAUTHENTICATION;
456  break;
457  case 13:
458  return WIFI_MAC_MGT_ACTION;
459  break;
460  case 14:
461  return WIFI_MAC_MGT_ACTION_NO_ACK;
462  break;
463  case 15:
464  return WIFI_MAC_MGT_MULTIHOP_ACTION;
465  break;
466 
467  }
468  break;
469  case TYPE_CTL:
470  switch (m_ctrlSubtype)
471  {
472  case SUBTYPE_CTL_BACKREQ:
473  return WIFI_MAC_CTL_BACKREQ;
474  break;
475  case SUBTYPE_CTL_BACKRESP:
476  return WIFI_MAC_CTL_BACKRESP;
477  break;
478  case SUBTYPE_CTL_RTS:
479  return WIFI_MAC_CTL_RTS;
480  break;
481  case SUBTYPE_CTL_CTS:
482  return WIFI_MAC_CTL_CTS;
483  break;
484  case SUBTYPE_CTL_ACK:
485  return WIFI_MAC_CTL_ACK;
486  break;
487  }
488  break;
489  case TYPE_DATA:
490  switch (m_ctrlSubtype)
491  {
492  case 0:
493  return WIFI_MAC_DATA;
494  break;
495  case 1:
496  return WIFI_MAC_DATA_CFACK;
497  break;
498  case 2:
499  return WIFI_MAC_DATA_CFPOLL;
500  break;
501  case 3:
502  return WIFI_MAC_DATA_CFACK_CFPOLL;
503  break;
504  case 4:
505  return WIFI_MAC_DATA_NULL;
506  break;
507  case 5:
508  return WIFI_MAC_DATA_NULL_CFACK;
509  break;
510  case 6:
511  return WIFI_MAC_DATA_NULL_CFPOLL;
512  break;
513  case 7:
514  return WIFI_MAC_DATA_NULL_CFACK_CFPOLL;
515  break;
516  case 8:
517  return WIFI_MAC_QOSDATA;
518  break;
519  case 9:
520  return WIFI_MAC_QOSDATA_CFACK;
521  break;
522  case 10:
523  return WIFI_MAC_QOSDATA_CFPOLL;
524  break;
525  case 11:
526  return WIFI_MAC_QOSDATA_CFACK_CFPOLL;
527  break;
528  case 12:
529  return WIFI_MAC_QOSDATA_NULL;
530  break;
531  case 14:
532  return WIFI_MAC_QOSDATA_NULL_CFPOLL;
533  break;
534  case 15:
535  return WIFI_MAC_QOSDATA_NULL_CFACK_CFPOLL;
536  break;
537 
538  }
539  break;
540  }
541  // NOTREACHED
542  NS_ASSERT (false);
543  return (enum WifiMacType)-1;
544 }
545 bool
546 WifiMacHeader::IsFromDs (void) const
547 {
548  return m_ctrlFromDs == 1;
549 }
550 bool
551 WifiMacHeader::IsToDs (void) const
552 {
553  return m_ctrlToDs == 1;
554 }
555 
556 bool
557 WifiMacHeader::IsData (void) const
558 {
559  return (m_ctrlType == TYPE_DATA);
560 
561 }
562 bool
563 WifiMacHeader::IsQosData (void) const
564 {
565  return (m_ctrlType == TYPE_DATA && (m_ctrlSubtype & 0x08));
566 }
567 bool
568 WifiMacHeader::IsCtl (void) const
569 {
570  return (m_ctrlType == TYPE_CTL);
571 }
572 bool
573 WifiMacHeader::IsMgt (void) const
574 {
575  return (m_ctrlType == TYPE_MGT);
576 }
577 bool
578 WifiMacHeader::IsCfpoll (void) const
579 {
580  switch (GetType ())
581  {
582  case WIFI_MAC_DATA_CFPOLL:
583  case WIFI_MAC_DATA_CFACK_CFPOLL:
584  case WIFI_MAC_DATA_NULL_CFPOLL:
585  case WIFI_MAC_DATA_NULL_CFACK_CFPOLL:
586  case WIFI_MAC_QOSDATA_CFPOLL:
587  case WIFI_MAC_QOSDATA_CFACK_CFPOLL:
588  case WIFI_MAC_QOSDATA_NULL_CFPOLL:
589  case WIFI_MAC_QOSDATA_NULL_CFACK_CFPOLL:
590  return true;
591  break;
592  default:
593  return false;
594  break;
595  }
596 }
597 bool
598 WifiMacHeader::IsRts (void) const
599 {
600  return (GetType () == WIFI_MAC_CTL_RTS);
601 }
602 bool
603 WifiMacHeader::IsCts (void) const
604 {
605  return (GetType () == WIFI_MAC_CTL_CTS);
606 }
607 bool
608 WifiMacHeader::IsAck (void) const
609 {
610  return (GetType () == WIFI_MAC_CTL_ACK);
611 }
612 bool
613 WifiMacHeader::IsAssocReq (void) const
614 {
615  return (GetType () == WIFI_MAC_MGT_ASSOCIATION_REQUEST);
616 }
617 bool
618 WifiMacHeader::IsAssocResp (void) const
619 {
620  return (GetType () == WIFI_MAC_MGT_ASSOCIATION_RESPONSE);
621 }
622 bool
623 WifiMacHeader::IsReassocReq (void) const
624 {
625  return (GetType () == WIFI_MAC_MGT_REASSOCIATION_REQUEST);
626 }
627 bool
628 WifiMacHeader::IsReassocResp (void) const
629 {
630  return (GetType () == WIFI_MAC_MGT_REASSOCIATION_RESPONSE);
631 }
632 bool
633 WifiMacHeader::IsProbeReq (void) const
634 {
635  return (GetType () == WIFI_MAC_MGT_PROBE_REQUEST);
636 }
637 bool
638 WifiMacHeader::IsProbeResp (void) const
639 {
640  return (GetType () == WIFI_MAC_MGT_PROBE_RESPONSE);
641 }
642 bool
643 WifiMacHeader::IsBeacon (void) const
644 {
645  return (GetType () == WIFI_MAC_MGT_BEACON);
646 }
647 bool
648 WifiMacHeader::IsDisassociation (void) const
649 {
650  return (GetType () == WIFI_MAC_MGT_DISASSOCIATION);
651 }
652 bool
653 WifiMacHeader::IsAuthentication (void) const
654 {
655  return (GetType () == WIFI_MAC_MGT_AUTHENTICATION);
656 }
657 bool
658 WifiMacHeader::IsDeauthentication (void) const
659 {
660  return (GetType () == WIFI_MAC_MGT_DEAUTHENTICATION);
661 }
662 bool
663 WifiMacHeader::IsAction (void) const
664 {
665  return (GetType () == WIFI_MAC_MGT_ACTION);
666 }
667 bool
668 WifiMacHeader::IsMultihopAction (void) const
669 {
670  return (GetType () == WIFI_MAC_MGT_MULTIHOP_ACTION);
671 }
672 bool
673 WifiMacHeader::IsBlockAckReq (void) const
674 {
675  return (GetType () == WIFI_MAC_CTL_BACKREQ) ? true : false;
676 }
677 bool
678 WifiMacHeader::IsBlockAck (void) const
679 {
680  return (GetType () == WIFI_MAC_CTL_BACKRESP) ? true : false;
681 }
682 
683 
684 uint16_t
685 WifiMacHeader::GetRawDuration (void) const
686 {
687  return m_duration;
688 }
689 Time
690 WifiMacHeader::GetDuration (void) const
691 {
692  return MicroSeconds (m_duration);
693 }
694 uint16_t
695 WifiMacHeader::GetSequenceControl (void) const
696 {
697  return (m_seqSeq << 4) | m_seqFrag;
698 }
699 uint16_t
700 WifiMacHeader::GetSequenceNumber (void) const
701 {
702  return m_seqSeq;
703 }
704 uint16_t
705 WifiMacHeader::GetFragmentNumber (void) const
706 {
707  return m_seqFrag;
708 }
709 bool
710 WifiMacHeader::IsRetry (void) const
711 {
712  return (m_ctrlRetry == 1);
713 }
714 bool
715 WifiMacHeader::IsMoreFragments (void) const
716 {
717  return (m_ctrlMoreFrag == 1);
718 }
719 bool
720 WifiMacHeader::IsQosBlockAck (void) const
721 {
722  NS_ASSERT (IsQosData ());
723  return (m_qosAckPolicy == 3);
724 }
725 bool
726 WifiMacHeader::IsQosNoAck (void) const
727 {
728  NS_ASSERT (IsQosData ());
729  return (m_qosAckPolicy == 1);
730 }
731 bool
732 WifiMacHeader::IsQosAck (void) const
733 {
734  NS_ASSERT (IsQosData ());
735  return (m_qosAckPolicy == 0);
736 }
737 bool
738 WifiMacHeader::IsQosEosp (void) const
739 {
740  NS_ASSERT (IsQosData ());
741  return (m_qosEosp == 1);
742 }
743 bool
744 WifiMacHeader::IsQosAmsdu (void) const
745 {
746  NS_ASSERT (IsQosData ());
747  return (m_amsduPresent == 1);
748 }
749 uint8_t
750 WifiMacHeader::GetQosTid (void) const
751 {
752  NS_ASSERT (IsQosData ());
753  return m_qosTid;
754 }
755 enum WifiMacHeader::QosAckPolicy
756 WifiMacHeader::GetQosAckPolicy (void) const
757 {
758  switch (m_qosAckPolicy)
759  {
760  case 0:
761  return NORMAL_ACK;
762  break;
763  case 1:
764  return NO_ACK;
765  break;
766  case 2:
767  return NO_EXPLICIT_ACK;
768  break;
769  case 3:
770  return BLOCK_ACK;
771  break;
772  }
773  // NOTREACHED
774  NS_ASSERT (false);
775  return (enum QosAckPolicy)-1;
776 }
777 
778 uint8_t
779 WifiMacHeader::GetQosTxopLimit (void) const
780 {
781  NS_ASSERT (IsQosData ());
782  return m_qosStuff;
783 }
784 
785 uint16_t
786 WifiMacHeader::GetFrameControl (void) const
787 {
788  uint16_t val = 0;
789  val |= (m_ctrlType << 2) & (0x3 << 2);
790  val |= (m_ctrlSubtype << 4) & (0xf << 4);
791  val |= (m_ctrlToDs << 8) & (0x1 << 8);
792  val |= (m_ctrlFromDs << 9) & (0x1 << 9);
793  val |= (m_ctrlMoreFrag << 10) & (0x1 << 10);
794  val |= (m_ctrlRetry << 11) & (0x1 << 11);
795  val |= (m_ctrlMoreData << 13) & (0x1 << 13);
796  val |= (m_ctrlWep << 14) & (0x1 << 14);
797  val |= (m_ctrlOrder << 15) & (0x1 << 15);
798  return val;
799 }
800 
801 uint16_t
802 WifiMacHeader::GetQosControl (void) const
803 {
804  uint16_t val = 0;
805  val |= m_qosTid;
806  val |= m_qosEosp << 4;
807  val |= m_qosAckPolicy << 5;
808  val |= m_amsduPresent << 7;
809  val |= m_qosStuff << 8;
810  return val;
811 }
812 
813 void
814 WifiMacHeader::SetFrameControl (uint16_t ctrl)
815 {
816  m_ctrlType = (ctrl >> 2) & 0x03;
817  m_ctrlSubtype = (ctrl >> 4) & 0x0f;
818  m_ctrlToDs = (ctrl >> 8) & 0x01;
819  m_ctrlFromDs = (ctrl >> 9) & 0x01;
820  m_ctrlMoreFrag = (ctrl >> 10) & 0x01;
821  m_ctrlRetry = (ctrl >> 11) & 0x01;
822  m_ctrlMoreData = (ctrl >> 13) & 0x01;
823  m_ctrlWep = (ctrl >> 14) & 0x01;
824  m_ctrlOrder = (ctrl >> 15) & 0x01;
825 }
826 void
827 WifiMacHeader::SetSequenceControl (uint16_t seq)
828 {
829  m_seqFrag = seq & 0x0f;
830  m_seqSeq = (seq >> 4) & 0x0fff;
831 }
832 void
833 WifiMacHeader::SetQosControl (uint16_t qos)
834 {
835  m_qosTid = qos & 0x000f;
836  m_qosEosp = (qos >> 4) & 0x0001;
837  m_qosAckPolicy = (qos >> 5) & 0x0003;
838  m_amsduPresent = (qos >> 7) & 0x0001;
839  m_qosStuff = (qos >> 8) & 0x00ff;
840 }
841 
842 uint32_t
843 WifiMacHeader::GetSize (void) const
844 {
845  uint32_t size = 0;
846  switch (m_ctrlType)
847  {
848  case TYPE_MGT:
849  size = 2 + 2 + 6 + 6 + 6 + 2;
850  break;
851  case TYPE_CTL:
852  switch (m_ctrlSubtype)
853  {
854  case SUBTYPE_CTL_RTS:
855  size = 2 + 2 + 6 + 6;
856  break;
857  case SUBTYPE_CTL_CTS:
858  case SUBTYPE_CTL_ACK:
859  size = 2 + 2 + 6;
860  break;
861  case SUBTYPE_CTL_BACKREQ:
862  case SUBTYPE_CTL_BACKRESP:
863  size = 2 + 2 + 6 + 6;
864  break;
865  }
866  break;
867  case TYPE_DATA:
868  size = 2 + 2 + 6 + 6 + 6 + 2;
869  if (m_ctrlToDs && m_ctrlFromDs)
870  {
871  size += 6;
872  }
873  if (m_ctrlSubtype & 0x08)
874  {
875  size += 2;
876  }
877  break;
878  }
879  return size;
880 }
881 const char *
882 WifiMacHeader::GetTypeString (void) const
883 {
884 #define FOO(x) \
885 case WIFI_MAC_ ## x: \
886  return # x; \
887  break;
888 
889  switch (GetType ())
890  {
891  FOO (CTL_RTS);
892  FOO (CTL_CTS);
893  FOO (CTL_ACK);
894  FOO (CTL_BACKREQ);
895  FOO (CTL_BACKRESP);
896 
897  FOO (MGT_BEACON);
898  FOO (MGT_ASSOCIATION_REQUEST);
899  FOO (MGT_ASSOCIATION_RESPONSE);
900  FOO (MGT_DISASSOCIATION);
901  FOO (MGT_REASSOCIATION_REQUEST);
902  FOO (MGT_REASSOCIATION_RESPONSE);
903  FOO (MGT_PROBE_REQUEST);
904  FOO (MGT_PROBE_RESPONSE);
905  FOO (MGT_AUTHENTICATION);
906  FOO (MGT_DEAUTHENTICATION);
907  FOO (MGT_ACTION);
908  FOO (MGT_ACTION_NO_ACK);
909  FOO (MGT_MULTIHOP_ACTION);
910 
911  FOO (DATA);
912  FOO (DATA_CFACK);
913  FOO (DATA_CFPOLL);
914  FOO (DATA_CFACK_CFPOLL);
915  FOO (DATA_NULL);
916  FOO (DATA_NULL_CFACK);
917  FOO (DATA_NULL_CFPOLL);
918  FOO (DATA_NULL_CFACK_CFPOLL);
919  FOO (QOSDATA);
920  FOO (QOSDATA_CFACK);
921  FOO (QOSDATA_CFPOLL);
922  FOO (QOSDATA_CFACK_CFPOLL);
923  FOO (QOSDATA_NULL);
924  FOO (QOSDATA_NULL_CFPOLL);
925  FOO (QOSDATA_NULL_CFACK_CFPOLL);
926  default:
927  return "ERROR";
928  }
929 #undef FOO
930  // needed to make gcc 4.0.1 ppc darwin happy.
931  return "BIG_ERROR";
932 }
933 
934 TypeId
935 WifiMacHeader::GetTypeId (void)
936 {
937  static TypeId tid = TypeId ("ns3::WifiMacHeader")
938  .SetParent<Header> ()
939  .AddConstructor<WifiMacHeader> ()
940  ;
941  return tid;
942 }
943 
944 TypeId
946 {
947  return GetTypeId ();
948 }
949 
950 void
951 WifiMacHeader::PrintFrameControl (std::ostream &os) const
952 {
953  os << "ToDS=" << std::hex << (int) m_ctrlToDs << ", FromDS=" << std::hex << (int) m_ctrlFromDs
954  << ", MoreFrag=" << std::hex << (int) m_ctrlMoreFrag << ", Retry=" << std::hex << (int) m_ctrlRetry
955  << ", MoreData=" << std::hex << (int) m_ctrlMoreData << std::dec
956  ;
957 }
958 
959 void
960 WifiMacHeader::Print (std::ostream &os) const
961 {
962  os << GetTypeString () << " ";
963  switch (GetType ())
964  {
965  case WIFI_MAC_CTL_RTS:
966  os << "Duration/ID=" << m_duration << "us"
967  << ", RA=" << m_addr1 << ", TA=" << m_addr2;
968  break;
969  case WIFI_MAC_CTL_CTS:
970  case WIFI_MAC_CTL_ACK:
971  os << "Duration/ID=" << m_duration << "us"
972  << ", RA=" << m_addr1;
973  break;
974  case WIFI_MAC_CTL_BACKREQ:
975  break;
976  case WIFI_MAC_CTL_BACKRESP:
977  break;
978 
979  case WIFI_MAC_MGT_BEACON:
980  case WIFI_MAC_MGT_ASSOCIATION_REQUEST:
981  case WIFI_MAC_MGT_ASSOCIATION_RESPONSE:
982  case WIFI_MAC_MGT_DISASSOCIATION:
983  case WIFI_MAC_MGT_REASSOCIATION_REQUEST:
984  case WIFI_MAC_MGT_REASSOCIATION_RESPONSE:
985  case WIFI_MAC_MGT_PROBE_REQUEST:
986  case WIFI_MAC_MGT_PROBE_RESPONSE:
987  case WIFI_MAC_MGT_AUTHENTICATION:
988  case WIFI_MAC_MGT_DEAUTHENTICATION:
989  PrintFrameControl (os);
990  os << " Duration/ID=" << m_duration << "us"
991  << ", DA=" << m_addr1 << ", SA=" << m_addr2
992  << ", BSSID=" << m_addr3 << ", FragNumber=" << std::hex << (int) m_seqFrag << std::dec
993  << ", SeqNumber=" << m_seqSeq;
994  break;
995  case WIFI_MAC_MGT_ACTION:
996  case WIFI_MAC_MGT_ACTION_NO_ACK:
997  PrintFrameControl (os);
998  os << " Duration/ID=" << m_duration << "us"
999  << "DA=" << m_addr1 << ", SA=" << m_addr2 << ", BSSID=" << m_addr3
1000  << ", FragNumber=" << std::hex << (int) m_seqFrag << std::dec << ", SeqNumber=" << m_seqSeq;
1001  case WIFI_MAC_MGT_MULTIHOP_ACTION:
1002  os << " Duration/ID=" << m_duration << "us"
1003  << "RA=" << m_addr1 << ", TA=" << m_addr2 << ", DA=" << m_addr3
1004  << ", FragNumber=" << std::hex << (int) m_seqFrag << std::dec << ", SeqNumber=" << m_seqSeq;
1005  case WIFI_MAC_DATA:
1006  PrintFrameControl (os);
1007  os << " Duration/ID=" << m_duration << "us";
1008  if (!m_ctrlToDs && !m_ctrlFromDs)
1009  {
1010  os << "DA=" << m_addr1 << ", SA=" << m_addr2 << ", BSSID=" << m_addr3;
1011  }
1012  else if (!m_ctrlToDs && m_ctrlFromDs)
1013  {
1014  os << "DA=" << m_addr1 << ", SA=" << m_addr3 << ", BSSID=" << m_addr2;
1015  }
1016  else if (m_ctrlToDs && !m_ctrlFromDs)
1017  {
1018  os << "DA=" << m_addr3 << ", SA=" << m_addr2 << ", BSSID=" << m_addr1;
1019  }
1020  else if (m_ctrlToDs && m_ctrlFromDs)
1021  {
1022  os << "DA=" << m_addr3 << ", SA=" << m_addr4 << ", RA=" << m_addr1 << ", TA=" << m_addr2;
1023  }
1024  else
1025  {
1026  NS_FATAL_ERROR ("Impossible ToDs and FromDs flags combination");
1027  }
1028  os << ", FragNumber=" << std::hex << (int) m_seqFrag << std::dec
1029  << ", SeqNumber=" << m_seqSeq;
1030  break;
1031  case WIFI_MAC_DATA_CFACK:
1032  case WIFI_MAC_DATA_CFPOLL:
1033  case WIFI_MAC_DATA_CFACK_CFPOLL:
1034  case WIFI_MAC_DATA_NULL:
1035  case WIFI_MAC_DATA_NULL_CFACK:
1036  case WIFI_MAC_DATA_NULL_CFPOLL:
1037  case WIFI_MAC_DATA_NULL_CFACK_CFPOLL:
1038  case WIFI_MAC_QOSDATA:
1039  case WIFI_MAC_QOSDATA_CFACK:
1040  case WIFI_MAC_QOSDATA_CFPOLL:
1041  case WIFI_MAC_QOSDATA_CFACK_CFPOLL:
1042  case WIFI_MAC_QOSDATA_NULL:
1043  case WIFI_MAC_QOSDATA_NULL_CFPOLL:
1044  case WIFI_MAC_QOSDATA_NULL_CFACK_CFPOLL:
1045  break;
1046  }
1047 }
1048 uint32_t
1050 {
1051  return GetSize ();
1052 }
1053 void
1055 {
1056  i.WriteHtolsbU16 (GetFrameControl ());
1057  i.WriteHtolsbU16 (m_duration);
1058  WriteTo (i, m_addr1);
1059  switch (m_ctrlType)
1060  {
1061  case TYPE_MGT:
1062  WriteTo (i, m_addr2);
1063  WriteTo (i, m_addr3);
1064  i.WriteHtolsbU16 (GetSequenceControl ());
1065  break;
1066  case TYPE_CTL:
1067  switch (m_ctrlSubtype)
1068  {
1069  case SUBTYPE_CTL_RTS:
1070  WriteTo (i, m_addr2);
1071  break;
1072  case SUBTYPE_CTL_CTS:
1073  case SUBTYPE_CTL_ACK:
1074  break;
1075  case SUBTYPE_CTL_BACKREQ:
1076  case SUBTYPE_CTL_BACKRESP:
1077  WriteTo (i, m_addr2);
1078  break;
1079  default:
1080  //NOTREACHED
1081  NS_ASSERT (false);
1082  break;
1083  }
1084  break;
1085  case TYPE_DATA:
1086  {
1087  WriteTo (i, m_addr2);
1088  WriteTo (i, m_addr3);
1089  i.WriteHtolsbU16 (GetSequenceControl ());
1090  if (m_ctrlToDs && m_ctrlFromDs)
1091  {
1092  WriteTo (i, m_addr4);
1093  }
1094  if (m_ctrlSubtype & 0x08)
1095  {
1096  i.WriteHtolsbU16 (GetQosControl ());
1097  }
1098  } break;
1099  default:
1100  //NOTREACHED
1101  NS_ASSERT (false);
1102  break;
1103  }
1104 }
1105 uint32_t
1107 {
1108  Buffer::Iterator i = start;
1109  uint16_t frame_control = i.ReadLsbtohU16 ();
1110  SetFrameControl (frame_control);
1111  m_duration = i.ReadLsbtohU16 ();
1112  ReadFrom (i, m_addr1);
1113  switch (m_ctrlType)
1114  {
1115  case TYPE_MGT:
1116  ReadFrom (i, m_addr2);
1117  ReadFrom (i, m_addr3);
1118  SetSequenceControl (i.ReadLsbtohU16 ());
1119  break;
1120  case TYPE_CTL:
1121  switch (m_ctrlSubtype)
1122  {
1123  case SUBTYPE_CTL_RTS:
1124  ReadFrom (i, m_addr2);
1125  break;
1126  case SUBTYPE_CTL_CTS:
1127  case SUBTYPE_CTL_ACK:
1128  break;
1129  case SUBTYPE_CTL_BACKREQ:
1130  case SUBTYPE_CTL_BACKRESP:
1131  ReadFrom (i, m_addr2);
1132  break;
1133  }
1134  break;
1135  case TYPE_DATA:
1136  ReadFrom (i, m_addr2);
1137  ReadFrom (i, m_addr3);
1138  SetSequenceControl (i.ReadLsbtohU16 ());
1139  if (m_ctrlToDs && m_ctrlFromDs)
1140  {
1141  ReadFrom (i, m_addr4);
1142  }
1143  if (m_ctrlSubtype & 0x08)
1144  {
1145  SetQosControl (i.ReadLsbtohU16 ());
1146  }
1147  break;
1148  }
1149  return i.GetDistanceFrom (start);
1150 }
1151 
1152 } // namespace ns3
#define NS_ASSERT(condition)
Definition: assert.h:64
uint32_t GetDistanceFrom(Iterator const &o) const
Definition: buffer.cc:807
#define NS_FATAL_ERROR(msg)
fatal error handling
Definition: fatal-error.h:72
iterator in a Buffer instance
Definition: buffer.h:98
virtual uint32_t GetSerializedSize(void) const
virtual void Print(std::ostream &os) const
virtual TypeId GetInstanceTypeId(void) const
void WriteHtolsbU16(uint16_t data)
Definition: buffer.cc:935
virtual void Serialize(Buffer::Iterator start) const
virtual uint32_t Deserialize(Buffer::Iterator start)
uint16_t ReadLsbtohU16(void)
Definition: buffer.cc:1090
Time MicroSeconds(uint64_t us)
create ns3::Time instances in units of microseconds.
Definition: nstime.h:615