-
Notifications
You must be signed in to change notification settings - Fork 0
/
wimsh_packet.h
491 lines (429 loc) · 16.4 KB
/
wimsh_packet.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
/*
* Copyright (C) 2007 Dip. Ing. dell'Informazione, University of Pisa, Italy
* http://info.iet.unipi.it/~cng/ns2mesh80216/
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA, USA
*/
#ifndef UINT_MAX
#define UINT_MAX 4294967295U
#endif
#ifndef __NS2_WIMSH_PACKET_H
#define __NS2_WIMSH_PACKET_H
#include <list>
#include <wimax_packet.h>
//! MSH-DSCH control message. We assume coordinated message scheduling.
/*!
The maximum size is not enforced while adding new IEs. Thus, all the
functions to add IEs return the size of the available space. Since
IEs cannot be removed (unless you do it "manually" using the returned
list, which you should do), the amount of available space should be
checked before adding IEs using the appropriate functions.
The same discussion on the LinkID of WimaxCid holds also for all the
information elements defined here.
*/
struct WimshMshDsch {
public:
//! Maximum sequence counter value.
enum { MAX_SEQ = 63 };
//! Maximum number of requests.
enum { MAX_REQ = 15 };
//! Maximum number of availabilities.
enum { MAX_AVL = 15 };
//! Maximum number of grants.
enum { MAX_GNT = 63 };
//! Maximum number of advertised neighbors.
enum { MAX_NGH = 255 };
//! Maximum size of the MSH-DSCH message (in bytes).
enum { MAX_SIZE = 96 };
//! Persistence level of availabilities/requests/grants.
enum Persistence {
CANCEL = 0, FRAME1, FRAME2, FRAME4,
FRAME8, FRAME32, FRAME128, FOREVER };
//! Direction for availabilities IEs.
enum Direction { UNAVAILABLE = 0, TX_ONLY, RX_ONLY, AVAILABLE };
//! Request data structure (3 bytes).
struct ReqIE {
//! Destination NodeID (IRL, LinkID - 8 bits).
WimaxNodeId nodeId_;
//! Demand level (8 bits).
unsigned char level_;
//! Demand persistence (3 bits).
Persistence persistence_;
//! Return the size (in bytes) of this IE.
static unsigned int size () { return 3; }
};
//! Availability data structure (4 bytes).
struct AvlIE {
//! Start frame number. IRL = 8 bits. Here we use the full frame number.
unsigned int frame_;
//! Minislot start (8 bits).
unsigned char start_;
//! Minislot range (7 bits).
unsigned char range_;
//! Direction (2 bits).
Direction direction_;
//! Persistence (3 bits).
Persistence persistence_;
//! Channel number (4 bits).
unsigned char channel_;
//! Return the size (in bytes) of this IE.
static unsigned int size () { return 4; }
};
//! Grant data structure (5 bytes).
struct GntIE {
//! Destination NodeID (IRL, LinkID - 8 bits).
WimaxNodeId nodeId_;
//! Start frame number. IRL = 8 bits. Here we use the full frame number.
unsigned int frame_;
//! Minislot start (8 bits).
unsigned char start_;
//! Minislot range (8 bits).
unsigned char range_;
//! Direction (1 bit). True = from requester to granter. Otherwise, false.
bool fromRequester_;
//! Persistence (3 bits).
Persistence persistence_;
//! Channel number (4 bits).
unsigned char channel_;
//! Return the size (in bytes) of this IE.
static unsigned int size () { return 5; }
};
//! Neighbor coordination IE (3 bytes).
struct NghIE {
//! NodeID (8 bits, this field does not exist for information on itself).
WimaxNodeId nodeId_;
//! NextXmtMx (3 bits).
unsigned char nextXmtMx_;
//! XmtHoldoffExponent (5 bits).
unsigned char xmtHoldoffExponent_;
//! Next transmit time, in slots (does not exist IRL).
unsigned int nextXmtTime_;
//! Next transmit time, in seconds (does not exist IRL).
double nextXmtTimeSec_;
//! Return the size (in bytes) of this IE.
static unsigned int size () { return 3; }
};
//! Allocation type.
enum AllocationType { BASIC, CONTIGUOUS };
private:
//! MAC header (always present). MSH-DSCH messages are never fragmented.
WimaxMacHeader hdr_;
//! Mesh subheader = transmitter NodeId (16 bits).
WimaxNodeId src_;
//! Sequence counter (6 bits).
unsigned int nseq_;
//! Number of requests (4 bits).
unsigned int nreq_;
//! Number of availabilities (4 bits).
unsigned int navl_;
//! Number of grants (6 bits).
unsigned int ngnt_;
//! Number of advertised neighbors (8 bits) not including itself.
unsigned int nngh_;
//! List of availabilities.
std::list<AvlIE> avl_;
//! List of requests.
std::list<ReqIE> req_;
//! List of grants.
std::list<GntIE> gnt_;
//! List of neighbors.
std::list<NghIE> ngh_;
//! Information on myself, about the distributed election mechanism.
NghIE myself_;
//! Allocation type. Changed via allocationType(). Default = BASIC.
static AllocationType allocationType_;
public:
//! Create an empty MSH-DSCH message.
WimshMshDsch () {
hdr_.crc() = true;
hdr_.fragmentation() = false;
hdr_.length() = 15; // includes fixed fields
// the hdr_.cid() is set to management values by default
nseq_ = 0;
nreq_ = 0;
navl_ = 0;
ngnt_ = 0;
nngh_ = 0;
}
//! Return the current message size (in bytes).
unsigned int size () { return hdr_.length(); }
//! Return the available space (in bytes).
unsigned int remaining () { return MAX_SIZE - size(); }
//! Return the MAC header.
WimaxMacHeader hdr () { return hdr_; }
//! Return the transmitter NodeID (in the mesh subheader).
WimaxNodeId& src () { return src_; }
//! Add an availabilities IE. Return the available space (in bytes).
unsigned int add (AvlIE x) {
if ( allocationType_ == BASIC ) {
hdr_.length() += AvlIE::size(); avl_.push_front(x);
} else if ( allocationType_ == CONTIGUOUS ) addContiguous (x);
return remaining(); }
//! Add a request IE. Return the available space (in bytes).
unsigned int add (ReqIE x) {
hdr_.length() += ReqIE::size(); req_.push_front(x); return remaining(); }
//! Add a grants IE. Return the available space (in bytes).
unsigned int add (GntIE x) {
if ( allocationType_ == BASIC ) {
hdr_.length() += GntIE::size(); gnt_.push_front(x);
} else if ( allocationType_ == CONTIGUOUS ) addContiguous (x);
return remaining(); }
//! Add a neighbors IE. Return the available space (in bytes).
unsigned int add (NghIE x) {
hdr_.length() += NghIE::size(); ngh_.push_front(x); return remaining(); }
//! Get the distribute election information on myself.
NghIE& myself () { return myself_; }
//! Get the list of availabilities IEs.
std::list<AvlIE>& avl () { return avl_; }
//! Get the list of requests IEs.
std::list<ReqIE>& req () { return req_; }
//! Get the list of grants IEs.
std::list<GntIE>& gnt () { return gnt_; }
//! Get the list of neighbors IEs.
std::list<NghIE>& ngh () { return ngh_; }
//! Convert a number of minislots into a pair <level, persistence> for req.
static void slots2level (unsigned int N, unsigned int minislots,
unsigned char& level, Persistence& persistence);
//! Get/set the allocation type.
static AllocationType& allocationType () { return allocationType_; }
//! Convert the persistence into a number of frames (except FOREVER).
static unsigned int pers2frames (Persistence p) {
return ( p == CANCEL ) ? 0 :
( p == FRAME1 ) ? 1 :
( p == FRAME2 ) ? 2 :
( p == FRAME4 ) ? 4 :
( p == FRAME8 ) ? 8 :
( p == FRAME32 ) ? 32 :
( p == FRAME128 ) ? 128 : UINT_MAX; }
protected:
//! Add a grant IE with contiguous allocation.
void addContiguous (GntIE& x);
//! Add an availability IE with contiguous allocation.
void addContiguous (AvlIE& x);
};
//! MSH-NCFG control message. We assume coordinated message scheduling.
struct WimshMshNcfg {
public:
//! Maximum number of advertised neighbors.
enum { MAX_NGH = 255 };
//! Maximum size of the MSH-NCFG message (in bytes).
enum { MAX_SIZE = 96 };
//! MSH-NCFG message types.
/*!
* The following MSH-NCFG message types are implemented:
* - The NET_ENTRY_OPEN message is sent by the sponsor node in
* response to an MSH-NENT REQUEST message.
* - The CHALLENGE message is sent by the new node to a neighbor
* with which it is trying to establish a logical link.
* - The RESPONSE message is sent by the neighbor in response to
* an MSH-NCFG CHALLENGE message.
* - The ACK message is sent by the new node to a neighbor with which
* it is trying to establish a logical link to complete the procedure.
*/
enum Type { NET_ENTRY_OPEN, CHALLENGE, RESPONSE, ACK };
//! Neighbor coordination IE (3 bytes).
struct NghIE {
//! NodeID (8 bits, this field does not exist for information on itself).
WimaxNodeId nodeId_;
//! NextXmtMx (3 bits).
unsigned char nextXmtMx_;
//! XmtHoldoffExponent (5 bits).
unsigned char xmtHoldoffExponent_;
//! Next transmit time (does not exist IRL).
unsigned int nextXmtTime_;
//! Return the size (in bytes) of this IE.
static unsigned int size () { return 3; }
};
private:
//! MAC header (always present). MSH-NCFG messages are never fragmented.
WimaxMacHeader hdr_;
//! Mesh subheader = transmitter NodeId (16 bits).
WimaxNodeId src_;
//! Number of advertised neighbors (8 bits) not including itself.
unsigned int nngh_;
//! List of neighbors.
std::list<NghIE> ngh_;
//! Information on myself, about the distributed election mechanism.
NghIE myself_;
// MSH-NCFG message type.
Type type_;
public:
//! Create an empty MSH-NCFG message.
WimshMshNcfg () {
hdr_.crc() = true;
hdr_.fragmentation() = false;
hdr_.length() = 20; // includes fixed fields :XXX: fix to the real value
// the hdr_.cid() is set to management values by default
nngh_ = 0;
type_ = NET_ENTRY_OPEN;
}
//! Return the current message size (in bytes).
unsigned int size () { return hdr_.length(); }
//! Return the available space (in bytes).
unsigned int remaining () { return MAX_SIZE - size(); }
//! Return the MAC header.
WimaxMacHeader& hdr () { return hdr_; }
//! Return the transmitter NodeID (in the mesh subheader).
WimaxNodeId& src () { return src_; }
//! Get/set the message type.
Type& type () { return type_; }
//! Add a neighbors IE. Return the available space (in bytes).
unsigned int add (NghIE x) {
hdr_.length() += NghIE::size(); ngh_.push_front(x); return remaining(); }
//! Get the distribute election information on myself.
NghIE& myself () { return myself_; }
//! Get the list of neighbors IEs.
std::list<NghIE>& ngh () { return ngh_; }
};
//! MSH-NENT control message. We assume coordinated message scheduling.
struct WimshMshNent {
public:
//! MSH-NENT message types.
/*!
* The following MSH-NENT message types are implemented:
* - The REQUEST message is sent by a new node to its sponsor node to
* open a sponsor channel.
* - The ACK message is sent by a new node to complete the sponsor channel
* open procedure.
*/
enum Type { REQUEST, ACK };
//! Maximum size of the MSH-NENT message (in bytes).
enum { MAX_SIZE = 96 };
private:
//! MAC header (always present). MSH-NENT messages are never fragmented.
WimaxMacHeader hdr_;
//! Mesh subheader = transmitter NodeId (16 bits).
WimaxNodeId src_;
//! MSH-NENT message type.
Type type_;
public:
//! Create an empty MSH-NENT message.
WimshMshNent () {
hdr_.crc() = true;
hdr_.fragmentation() = false;
hdr_.length() = 20; // includes fixed fields :XXX: fix to the real value
// the hdr_.cid() is set to management values by default
type_ = REQUEST;
}
//! Return the current message size (in bytes).
unsigned int size () { return hdr_.length(); }
//! Return the available space (in bytes).
unsigned int remaining () { return MAX_SIZE - size(); }
//! Return the MAC header.
WimaxMacHeader& hdr () { return hdr_; }
//! Return the transmitter NodeID (in the mesh subheader).
WimaxNodeId& src () { return src_; }
//! Get/set the MSH-NENT message type.
Type& type () { return type_; }
};
//! WiMAX mesh burst of MAC PDUs.
/*!
A burst of PDUs is either a list of MAC PDUs, or a container for one
MSH-DSCH message, according to the burst type.
If you want to copy a burst, then use the copy() function.
On the other hand, the destructor can be used safely to delete a burst.
In any case, the ns2 packets, nor the MSH-DSCH message, are *not* copied.
If you really want to deallocate the ns2 packets, which are encapsulated into
each SDU, you have to do it manually.
The rationale behind this is that we want only *one* copy of each
ns2 packet to travel from the source node to the destination, to save
both memory (a packet) and time (copying a packet).
However, care must be taken to destroy these objects. We assume that
only the final recipient of the communication destroys ns2 packets,
which should be safe enough with unicast communications.
*/
struct WimshBurst {
public:
typedef std::list<WimaxPdu*> List;
private:
//--------------------------------------------------------//
//-- Payload of the burst, depending on the burst type. --//
//--------------------------------------------------------//
//! List of PDUs (if type == wimax::DATA).
List pdus_;
//! Pointer to the MSH-DSCH message (if type == wimax::MSHDSCH).
WimshMshDsch* mshDsch_;
//! Pointer to the MSH-DSCH message (if type == wimax::MSHNCFG).
WimshMshNcfg* mshNcfg_;
//! Pointer to the MSH-DSCH message (if type == wimax::MSHNENT).
WimshMshNent* mshNent_;
//------------------//
//-- Other fields --//
//------------------//
//! Transmission time of this burst (in seconds, including preambles).
double txtime_;
//! True if the whole burst is corrupt.
bool error_;
//! Burst profile.
wimax::BurstProfile profile_;
//! PDU burst type.
wimax::BurstType type_;
//! Size, in bytes.
unsigned int size_;
//! Source node ID.
WimaxNodeId src_;
public:
//! Build an empty burst of PDUs.
WimshBurst () {
error_ = false; size_ = 0; mshDsch_ = 0; mshNcfg_ = 0; mshNent_ = 0;
profile_ = wimax::QPSK_1_2; type_ = wimax::DATA; }
//! Destroy everything ;)
~WimshBurst ();
//! Allocate a copy of this burst and return a pointer to it.
/*!
The ns2 packets (ie. the SDUs' payload) are *not* copied.
On the other hand, the MSH-DSCH message, if any, is copied.
*/
WimshBurst (const WimshBurst& obj);
//! Add a PDU to the burst.
void addData (WimaxPdu* pdu, bool tail = true ) {
if ( tail ) pdus_.push_back (pdu); else pdus_.push_front (pdu);
size_ += pdu->size(); }
//! Remove a PDU from the burst. The PDU must be freed afterwards.
WimaxPdu* pdu () {
if ( pdus_.empty() ) return 0;
WimaxPdu* tmp = pdus_.front(); pdus_.pop_front(); return tmp; }
//! Return the list of PDUs.
List& pdus () { return pdus_; }
//! Return the number of PDUs in the burst.
unsigned int npdus () { return pdus_.size(); }
//! Get a pointer to the MSH-DSCH message, if any.
WimshMshDsch*& mshDsch () { return mshDsch_; }
//! Add an MSH-DSCH message to the burst.
void addMshDsch (WimshMshDsch* m);
//! Get a pointer to the MSH-NCFG message, if any.
WimshMshNcfg*& mshNcfg () { return mshNcfg_; }
//! Add an MSH-NCFG message to the burst.
void addMshNcfg (WimshMshNcfg* m);
//! Get a pointer to the MSH-NENT message, if any.
WimshMshNent*& mshNent () { return mshNent_; }
//! Add an MSH-NENT message to the burst.
void addMshNent (WimshMshNent* m);
//! Get/set the transmission time (in seconds, including preambles).
double& txtime () { return txtime_; }
//! Get/set the error status of the whole burst.
bool& error () { return error_; }
//! Get/set the burst profile.
wimax::BurstProfile& profile () { return profile_; }
//! Get the burst type.
wimax::BurstType& type () { return type_; }
//! Get the burst size (in bytes).
unsigned int size () { return size_; }
//! Get/set the source node.
WimaxNodeId& source () { return src_; }
private:
void operator= (const WimshBurst&);
};
#endif /* __NS2_WIMSH_PACKET_H */