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