A Discrete-Event Network Simulator
Home
Tutorials ▼
English
Portuguese
Docs ▼
Wiki
Manual
Models
Develop ▼
API
Bugs
API
Main Page
Related Pages
Modules
Namespaces
Classes
Files
File List
File Members
All
Classes
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Properties
Friends
Macros
Groups
Pages
ctrl-headers.cc
Go to the documentation of this file.
1
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2
/*
3
* Copyright (c) 2009 MIRKO BANCHI
4
*
5
* This program is free software; you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License version 2 as
7
* published by the Free Software Foundation;
8
*
9
* This program is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
* GNU General Public License for more details.
13
*
14
* You should have received a copy of the GNU General Public License
15
* along with this program; if not, write to the Free Software
16
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
*
18
* Author: Mirko Banchi <mk.banchi@gmail.com>
19
*/
20
#include "ns3/fatal-error.h"
21
22
#include "
ctrl-headers.h
"
23
24
namespace
ns3 {
25
26
/***********************************
27
* Block ack request
28
***********************************/
29
30
NS_OBJECT_ENSURE_REGISTERED
(CtrlBAckRequestHeader);
31
32
CtrlBAckRequestHeader::CtrlBAckRequestHeader
()
33
: m_barAckPolicy (false),
34
m_multiTid (false),
35
m_compressed (false)
36
{
37
}
38
39
CtrlBAckRequestHeader::~CtrlBAckRequestHeader
()
40
{
41
}
42
43
TypeId
44
CtrlBAckRequestHeader::GetTypeId
(
void
)
45
{
46
static
TypeId
tid =
TypeId
(
"ns3::CtrlBAckRequestHeader"
)
47
.
SetParent
<
Header
> ()
48
.AddConstructor<CtrlBAckRequestHeader> ()
49
;
50
return
tid;
51
}
52
53
TypeId
54
CtrlBAckRequestHeader::GetInstanceTypeId
(
void
)
const
55
{
56
return
GetTypeId
();
57
}
58
59
void
60
CtrlBAckRequestHeader::Print
(std::ostream &os)
const
61
{
62
os <<
"TID_INFO="
<<
m_tidInfo
<<
", StartingSeq="
<< std::hex <<
m_startingSeq
;
63
}
64
65
uint32_t
66
CtrlBAckRequestHeader::GetSerializedSize
()
const
67
{
68
uint32_t size = 0;
69
size += 2;
//Bar control
70
if
(!
m_multiTid
)
71
{
72
size += 2;
//Starting sequence control
73
}
74
else
75
{
76
if
(
m_compressed
)
77
{
78
size += (2 + 2) * (
m_tidInfo
+ 1);
//Multi-tid block ack
79
}
80
else
81
{
82
NS_FATAL_ERROR
(
"Reserved configuration."
);
83
}
84
}
85
return
size;
86
}
87
88
void
89
CtrlBAckRequestHeader::Serialize
(
Buffer::Iterator
start
)
const
90
{
91
Buffer::Iterator
i =
start
;
92
i.
WriteHtolsbU16
(
GetBarControl
());
93
if
(!
m_multiTid
)
94
{
95
i.
WriteHtolsbU16
(
GetStartingSequenceControl
());
96
}
97
else
98
{
99
if
(
m_compressed
)
100
{
101
NS_FATAL_ERROR
(
"Multi-tid block ack is not supported."
);
102
}
103
else
104
{
105
NS_FATAL_ERROR
(
"Reserved configuration."
);
106
}
107
}
108
}
109
110
uint32_t
111
CtrlBAckRequestHeader::Deserialize
(
Buffer::Iterator
start
)
112
{
113
Buffer::Iterator
i =
start
;
114
SetBarControl
(i.
ReadLsbtohU16
());
115
if
(!
m_multiTid
)
116
{
117
SetStartingSequenceControl
(i.
ReadLsbtohU16
());
118
}
119
else
120
{
121
if
(
m_compressed
)
122
{
123
NS_FATAL_ERROR
(
"Multi-tid block ack is not supported."
);
124
}
125
else
126
{
127
NS_FATAL_ERROR
(
"Reserved configuration."
);
128
}
129
}
130
return
i.
GetDistanceFrom
(start);
131
}
132
133
uint16_t
134
CtrlBAckRequestHeader::GetBarControl
(
void
)
const
135
{
136
uint16_t res = 0;
137
if
(
m_barAckPolicy
)
138
{
139
res |= 0x1;
140
}
141
if
(
m_multiTid
)
142
{
143
res |= (0x1 << 1);
144
}
145
if
(
m_compressed
)
146
{
147
res |= (0x1 << 2);
148
}
149
res |= (
m_tidInfo
<< 12) & (0xf << 12);
150
return
res;
151
}
152
153
void
154
CtrlBAckRequestHeader::SetBarControl
(uint16_t bar)
155
{
156
m_barAckPolicy
= ((bar & 0x01) == 1) ?
true
:
false
;
157
m_multiTid
= (((bar >> 1) & 0x01) == 1) ?
true
:
false
;
158
m_compressed
= (((bar >> 2) & 0x01) == 1) ?
true
:
false
;
159
m_tidInfo
= (bar >> 12) & 0x0f;
160
}
161
162
uint16_t
163
CtrlBAckRequestHeader::GetStartingSequenceControl
(
void
)
const
164
{
165
return
(
m_startingSeq
<< 4) & 0xfff0;
166
}
167
168
void
169
CtrlBAckRequestHeader::SetStartingSequenceControl
(uint16_t seqControl)
170
{
171
m_startingSeq
= (seqControl >> 4) & 0x0fff;
172
}
173
174
void
175
CtrlBAckRequestHeader::SetHtImmediateAck
(
bool
immediateAck)
176
{
177
m_barAckPolicy
= immediateAck;
178
}
179
180
void
181
CtrlBAckRequestHeader::SetType
(
enum
BlockAckType
type)
182
{
183
switch
(type)
184
{
185
case
BASIC_BLOCK_ACK
:
186
m_multiTid
=
false
;
187
m_compressed
=
false
;
188
break
;
189
case
COMPRESSED_BLOCK_ACK
:
190
m_multiTid
=
false
;
191
m_compressed
=
true
;
192
break
;
193
case
MULTI_TID_BLOCK_ACK
:
194
m_multiTid
=
true
;
195
m_compressed
=
true
;
196
break
;
197
default
:
198
NS_FATAL_ERROR
(
"Invalid variant type"
);
199
break
;
200
}
201
}
202
203
void
204
CtrlBAckRequestHeader::SetTidInfo
(uint8_t tid)
205
{
206
m_tidInfo
=
static_cast<
uint16_t
>
(tid);
207
}
208
209
void
210
CtrlBAckRequestHeader::SetStartingSequence
(uint16_t seq)
211
{
212
m_startingSeq
= seq;
213
}
214
215
bool
216
CtrlBAckRequestHeader::MustSendHtImmediateAck
(
void
)
const
217
{
218
return
m_barAckPolicy
;
219
}
220
221
uint8_t
222
CtrlBAckRequestHeader::GetTidInfo
(
void
)
const
223
{
224
uint8_t tid =
static_cast<
uint8_t
>
(
m_tidInfo
);
225
return
tid;
226
}
227
228
uint16_t
229
CtrlBAckRequestHeader::GetStartingSequence
(
void
)
const
230
{
231
return
m_startingSeq
;
232
}
233
234
bool
235
CtrlBAckRequestHeader::IsBasic
(
void
)
const
236
{
237
return
(!
m_multiTid
&& !
m_compressed
) ?
true
:
false
;
238
}
239
240
bool
241
CtrlBAckRequestHeader::IsCompressed
(
void
)
const
242
{
243
return
(!
m_multiTid
&&
m_compressed
) ?
true
:
false
;
244
}
245
246
bool
247
CtrlBAckRequestHeader::IsMultiTid
(
void
)
const
248
{
249
return
(
m_multiTid
&&
m_compressed
) ?
true
:
false
;
250
}
251
252
/***********************************
253
* Block ack response
254
***********************************/
255
256
NS_OBJECT_ENSURE_REGISTERED
(
CtrlBAckResponseHeader
);
257
258
CtrlBAckResponseHeader::CtrlBAckResponseHeader
()
259
: m_baAckPolicy (false),
260
m_multiTid (false),
261
m_compressed (false)
262
{
263
memset (&
bitmap
, 0,
sizeof
(
bitmap
));
264
}
265
266
CtrlBAckResponseHeader::~CtrlBAckResponseHeader
()
267
{
268
}
269
270
TypeId
271
CtrlBAckResponseHeader::GetTypeId
(
void
)
272
{
273
static
TypeId
tid =
TypeId
(
"ns3::CtrlBAckResponseHeader"
)
274
.
SetParent
<
Header
> ()
275
.AddConstructor<CtrlBAckResponseHeader> ()
276
;
277
return
tid;
278
}
279
280
TypeId
281
CtrlBAckResponseHeader::GetInstanceTypeId
(
void
)
const
282
{
283
return
GetTypeId
();
284
}
285
286
void
287
CtrlBAckResponseHeader::Print
(std::ostream &os)
const
288
{
289
os <<
"TID_INFO="
<<
m_tidInfo
<<
", StartingSeq="
<< std::hex <<
m_startingSeq
;
290
}
291
292
uint32_t
293
CtrlBAckResponseHeader::GetSerializedSize
(
void
)
const
294
{
295
uint32_t size = 0;
296
size += 2;
//Bar control
297
if
(!
m_multiTid
)
298
{
299
if
(!
m_compressed
)
300
{
301
size += (2 + 128);
//Basic block ack
302
}
303
else
304
{
305
size += (2 + 8);
//Compressed block ack
306
}
307
}
308
else
309
{
310
if
(
m_compressed
)
311
{
312
size += (2 + 2 + 8) * (
m_tidInfo
+ 1);
//Multi-tid block ack
313
}
314
else
315
{
316
NS_FATAL_ERROR
(
"Reserved configuration."
);
317
}
318
}
319
return
size;
320
}
321
322
void
323
CtrlBAckResponseHeader::Serialize
(
Buffer::Iterator
start
)
const
324
{
325
Buffer::Iterator
i =
start
;
326
i.
WriteHtolsbU16
(
GetBaControl
());
327
if
(!
m_multiTid
)
328
{
329
i.
WriteHtolsbU16
(
GetStartingSequenceControl
());
330
i =
SerializeBitmap
(i);
331
}
332
else
333
{
334
if
(
m_compressed
)
335
{
336
NS_FATAL_ERROR
(
"Multi-tid block ack is not supported."
);
337
}
338
else
339
{
340
NS_FATAL_ERROR
(
"Reserved configuration."
);
341
}
342
}
343
}
344
345
uint32_t
346
CtrlBAckResponseHeader::Deserialize
(
Buffer::Iterator
start
)
347
{
348
Buffer::Iterator
i =
start
;
349
SetBaControl
(i.
ReadLsbtohU16
());
350
if
(!
m_multiTid
)
351
{
352
SetStartingSequenceControl
(i.
ReadLsbtohU16
());
353
i =
DeserializeBitmap
(i);
354
}
355
else
356
{
357
if
(
m_compressed
)
358
{
359
NS_FATAL_ERROR
(
"Multi-tid block ack is not supported."
);
360
}
361
else
362
{
363
NS_FATAL_ERROR
(
"Reserved configuration."
);
364
}
365
}
366
return
i.
GetDistanceFrom
(start);
367
}
368
369
void
370
CtrlBAckResponseHeader::SetHtImmediateAck
(
bool
immediateAck)
371
{
372
m_baAckPolicy
= immediateAck;
373
}
374
375
void
376
CtrlBAckResponseHeader::SetType
(
enum
BlockAckType
type)
377
{
378
switch
(type)
379
{
380
case
BASIC_BLOCK_ACK
:
381
m_multiTid
=
false
;
382
m_compressed
=
false
;
383
break
;
384
case
COMPRESSED_BLOCK_ACK
:
385
m_multiTid
=
false
;
386
m_compressed
=
true
;
387
break
;
388
case
MULTI_TID_BLOCK_ACK
:
389
m_multiTid
=
true
;
390
m_compressed
=
true
;
391
break
;
392
default
:
393
NS_FATAL_ERROR
(
"Invalid variant type"
);
394
break
;
395
}
396
}
397
398
void
399
CtrlBAckResponseHeader::SetTidInfo
(uint8_t tid)
400
{
401
m_tidInfo
=
static_cast<
uint16_t
>
(tid);
402
}
403
404
void
405
CtrlBAckResponseHeader::SetStartingSequence
(uint16_t seq)
406
{
407
m_startingSeq
= seq;
408
}
409
410
bool
411
CtrlBAckResponseHeader::MustSendHtImmediateAck
(
void
)
const
412
{
413
return
(
m_baAckPolicy
) ?
true
:
false
;
414
}
415
416
uint8_t
417
CtrlBAckResponseHeader::GetTidInfo
(
void
)
const
418
{
419
uint8_t tid =
static_cast<
uint8_t
>
(
m_tidInfo
);
420
return
tid;
421
}
422
423
uint16_t
424
CtrlBAckResponseHeader::GetStartingSequence
(
void
)
const
425
{
426
return
m_startingSeq
;
427
}
428
429
bool
430
CtrlBAckResponseHeader::IsBasic
(
void
)
const
431
{
432
return
(!
m_multiTid
&& !
m_compressed
) ?
true
:
false
;
433
}
434
435
bool
436
CtrlBAckResponseHeader::IsCompressed
(
void
)
const
437
{
438
return
(!
m_multiTid
&&
m_compressed
) ?
true
:
false
;
439
}
440
441
bool
442
CtrlBAckResponseHeader::IsMultiTid
(
void
)
const
443
{
444
return
(
m_multiTid
&&
m_compressed
) ?
true
:
false
;
445
}
446
447
uint16_t
448
CtrlBAckResponseHeader::GetBaControl
(
void
)
const
449
{
450
uint16_t res = 0;
451
if
(
m_baAckPolicy
)
452
{
453
res |= 0x1;
454
}
455
if
(
m_multiTid
)
456
{
457
res |= (0x1 << 1);
458
}
459
if
(
m_compressed
)
460
{
461
res |= (0x1 << 2);
462
}
463
res |= (
m_tidInfo
<< 12) & (0xf << 12);
464
return
res;
465
}
466
467
void
468
CtrlBAckResponseHeader::SetBaControl
(uint16_t ba)
469
{
470
m_baAckPolicy
= ((ba & 0x01) == 1) ?
true
:
false
;
471
m_multiTid
= (((ba >> 1) & 0x01) == 1) ?
true
:
false
;
472
m_compressed
= (((ba >> 2) & 0x01) == 1) ?
true
:
false
;
473
m_tidInfo
= (ba >> 12) & 0x0f;
474
}
475
476
uint16_t
477
CtrlBAckResponseHeader::GetStartingSequenceControl
(
void
)
const
478
{
479
return
(
m_startingSeq
<< 4) & 0xfff0;
480
}
481
482
void
483
CtrlBAckResponseHeader::SetStartingSequenceControl
(uint16_t seqControl)
484
{
485
m_startingSeq
= (seqControl >> 4) & 0x0fff;
486
}
487
488
Buffer::Iterator
489
CtrlBAckResponseHeader::SerializeBitmap
(
Buffer::Iterator
start
)
const
490
{
491
Buffer::Iterator
i =
start
;
492
if
(!
m_multiTid
)
493
{
494
if
(!
m_compressed
)
495
{
496
for
(uint32_t j = 0; j < 64; j++)
497
{
498
i.
WriteHtolsbU16
(
bitmap
.m_bitmap[j]);
499
}
500
}
501
else
502
{
503
i.
WriteHtolsbU64
(
bitmap
.m_compressedBitmap);
504
}
505
}
506
else
507
{
508
if
(
m_compressed
)
509
{
510
NS_FATAL_ERROR
(
"Multi-tid block ack is not supported."
);
511
}
512
else
513
{
514
NS_FATAL_ERROR
(
"Reserved configuration."
);
515
}
516
}
517
return
i;
518
}
519
520
Buffer::Iterator
521
CtrlBAckResponseHeader::DeserializeBitmap
(
Buffer::Iterator
start
)
522
{
523
Buffer::Iterator
i =
start
;
524
if
(!
m_multiTid
)
525
{
526
if
(!
m_compressed
)
527
{
528
for
(uint32_t j = 0; j < 64; j++)
529
{
530
bitmap
.m_bitmap[j] = i.
ReadLsbtohU16
();
531
}
532
}
533
else
534
{
535
bitmap
.m_compressedBitmap = i.
ReadLsbtohU64
();
536
}
537
}
538
else
539
{
540
if
(
m_compressed
)
541
{
542
NS_FATAL_ERROR
(
"Multi-tid block ack is not supported."
);
543
}
544
else
545
{
546
NS_FATAL_ERROR
(
"Reserved configuration."
);
547
}
548
}
549
return
i;
550
}
551
552
void
553
CtrlBAckResponseHeader::SetReceivedPacket
(uint16_t seq)
554
{
555
if
(!
IsInBitmap
(seq))
556
{
557
return
;
558
}
559
if
(!
m_multiTid
)
560
{
561
if
(!
m_compressed
)
562
{
563
/* To set correctly basic block ack bitmap we need fragment number too.
564
So if it's not specified, we consider packet not fragmented. */
565
bitmap
.m_bitmap[
IndexInBitmap
(seq)] |= 0x0001;
566
}
567
else
568
{
569
bitmap
.m_compressedBitmap |= (uint64_t (0x0000000000000001) <<
IndexInBitmap
(seq));
570
}
571
}
572
else
573
{
574
if
(
m_compressed
)
575
{
576
NS_FATAL_ERROR
(
"Multi-tid block ack is not supported."
);
577
}
578
else
579
{
580
NS_FATAL_ERROR
(
"Reserved configuration."
);
581
}
582
}
583
}
584
585
void
586
CtrlBAckResponseHeader::SetReceivedFragment
(uint16_t seq, uint8_t frag)
587
{
588
NS_ASSERT
(frag < 16);
589
if
(!
IsInBitmap
(seq))
590
{
591
return
;
592
}
593
if
(!
m_multiTid
)
594
{
595
if
(!
m_compressed
)
596
{
597
bitmap
.m_bitmap[
IndexInBitmap
(seq)] |= (0x0001 << frag);
598
}
599
else
600
{
601
/* We can ignore this...compressed block ack doesn't support
602
acknowledgement of single fragments */
603
}
604
}
605
else
606
{
607
if
(
m_compressed
)
608
{
609
NS_FATAL_ERROR
(
"Multi-tid block ack is not supported."
);
610
}
611
else
612
{
613
NS_FATAL_ERROR
(
"Reserved configuration."
);
614
}
615
}
616
}
617
618
bool
619
CtrlBAckResponseHeader::IsPacketReceived
(uint16_t seq)
const
620
{
621
if
(!
IsInBitmap
(seq))
622
{
623
return
false
;
624
}
625
if
(!
m_multiTid
)
626
{
627
if
(!
m_compressed
)
628
{
629
/*It's impossible to say if an entire packet was correctly received. */
630
return
false
;
631
}
632
else
633
{
634
uint64_t mask = uint64_t (0x0000000000000001);
635
return
(((
bitmap
.m_compressedBitmap >>
IndexInBitmap
(seq)) & mask) == 1) ?
true
:
false
;
636
}
637
}
638
else
639
{
640
if
(
m_compressed
)
641
{
642
NS_FATAL_ERROR
(
"Multi-tid block ack is not supported."
);
643
}
644
else
645
{
646
NS_FATAL_ERROR
(
"Reserved configuration."
);
647
}
648
}
649
return
false
;
650
}
651
652
bool
653
CtrlBAckResponseHeader::IsFragmentReceived
(uint16_t seq, uint8_t frag)
const
654
{
655
NS_ASSERT
(frag < 16);
656
if
(!
IsInBitmap
(seq))
657
{
658
return
false
;
659
}
660
if
(!
m_multiTid
)
661
{
662
if
(!
m_compressed
)
663
{
664
return
((
bitmap
.m_bitmap[
IndexInBitmap
(seq)] & (0x0001 << frag)) != 0x0000) ?
true
:
false
;
665
}
666
else
667
{
668
/* Although this could make no sense, if packet with sequence number
669
equal to <i>seq</i> was correctly received, also all of its fragments
670
were correctly received. */
671
uint64_t mask = uint64_t (0x0000000000000001);
672
return
(((
bitmap
.m_compressedBitmap >>
IndexInBitmap
(seq)) & mask) == 1) ?
true
:
false
;
673
}
674
}
675
else
676
{
677
if
(
m_compressed
)
678
{
679
NS_FATAL_ERROR
(
"Multi-tid block ack is not supported."
);
680
}
681
else
682
{
683
NS_FATAL_ERROR
(
"Reserved configuration."
);
684
}
685
}
686
return
false
;
687
}
688
689
uint8_t
690
CtrlBAckResponseHeader::IndexInBitmap
(uint16_t seq)
const
691
{
692
uint8_t index;
693
if
(seq >=
m_startingSeq
)
694
{
695
index = seq -
m_startingSeq
;
696
}
697
else
698
{
699
index = 4096 -
m_startingSeq
+ seq;
700
}
701
NS_ASSERT
(index <= 63);
702
return
index;
703
}
704
705
bool
706
CtrlBAckResponseHeader::IsInBitmap
(uint16_t seq)
const
707
{
708
return
(seq -
m_startingSeq
+ 4096) % 4096 < 64;
709
}
710
711
const
uint16_t*
712
CtrlBAckResponseHeader::GetBitmap
(
void
)
const
713
{
714
return
bitmap
.m_bitmap;
715
}
716
717
uint64_t
718
CtrlBAckResponseHeader::GetCompressedBitmap
(
void
)
const
719
{
720
return
bitmap
.m_compressedBitmap;
721
}
722
723
void
724
CtrlBAckResponseHeader::ResetBitmap
(
void
)
725
{
726
memset (&
bitmap
, 0,
sizeof
(
bitmap
));
727
}
728
729
}
// namespace ns3
src
wifi
model
ctrl-headers.cc
Generated on Tue Nov 13 2012 10:32:24 for ns-3 by
1.8.1.2