Fix gcc 4.6 "set but not used [-Wunused-but-set-variable]" warnings.
[obnox/wireshark/wip.git] / plugins / wimax / mac_hd_generic_decoder.c
1 /* mac_hd_generic_decoder.c
2  * WiMax Generic MAC Header decoder
3  *
4  * Copyright (c) 2007 by Intel Corporation.
5  *
6  * Author: Lu Pan <lu.pan@intel.com>
7  *
8  * $Id$
9  *
10  * Wireshark - Network traffic analyzer
11  * By Gerald Combs <gerald@wireshark.org>
12  * Copyright 1999 Gerald Combs
13  *
14  * This program is free software; you can redistribute it and/or
15  * modify it under the terms of the GNU General Public License
16  * as published by the Free Software Foundation; either version 2
17  * of the License, or (at your option) any later version.
18  *
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU General Public License for more details.
23  *
24  * You should have received a copy of the GNU General Public License
25  * along with this program; if not, write to the Free Software
26  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
27  */
28
29 /* TODO:  Add FT_UINT24 and FT_INT24 cases to gtk_widget_get_toplevel()
30  * to prevent having to make all the changes from BASE_DEC to BASE_HEX
31  * made to this file today: 10/20/06.
32  */
33
34 /* Include files */
35
36 #ifdef HAVE_CONFIG_H
37 #include "config.h"
38 #endif
39
40 /*
41 #define DEBUG
42 */
43
44 #include <string.h>
45 #include <glib.h>
46 #include <epan/packet.h>
47 #include <epan/address.h>
48 #include <epan/reassemble.h>
49 #include "crc.h"
50 #include "wimax_utils.h"
51
52 extern gint proto_wimax;
53
54 extern gint seen_a_service_type;
55 extern gboolean first_gmh;                      /* defined in wimax_pdu_decoder.c */
56
57 extern gint8 arq_enabled;                       /* declared in packet-wmx.c */
58 extern gint  scheduling_service_type;           /* declared in packet-wmx.c */
59 extern gint  mac_sdu_length;                    /* declared in packet-wmx.c */
60
61 extern address bs_address;                      /* declared in packet-wmx.c */
62 extern guint max_logical_bands;                 /* declared in wimax_compact_dlmap_ie_decoder.c */
63 extern gboolean is_down_link(packet_info *pinfo);/* declared in packet-wmx.c */
64 extern void proto_register_mac_mgmt_msg(void);  /* defined in macmgmtmsgdecoder.c */
65 extern void init_wimax_globals(void);           /* defined in msg_ulmap.c */
66
67 extern void dissect_mac_mgmt_msg_decoder(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
68
69 /* global variables */
70 gboolean include_cor2_changes = FALSE;
71
72 /* Well-known CIDs */
73 guint cid_initial_ranging  = 0x0000;
74 guint global_cid_max_basic = 320;
75 guint cid_max_primary      = 640;
76 guint cid_aas_ranging      = 0xFeFF;
77 guint cid_normal_multicast = 0xFFFa;
78 guint cid_sleep_multicast  = 0xFFFb;
79 guint cid_idle_multicast   = 0xFFFc;
80 guint cid_frag_broadcast   = 0xFFFd;
81 guint cid_padding          = 0xFFFe;
82 guint cid_broadcast        = 0xFFFF;
83
84 /* Maximum number of CID's */
85 #define MAX_CID 64
86
87 /* forward reference */
88 static gint extended_subheader_decoder(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
89 static gint arq_feedback_payload_decoder(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *parent_item);
90
91 /* Static variables */
92 static GHashTable *payload_frag_table = NULL;
93
94 gint proto_mac_header_generic_decoder = -1;
95 static gint ett_mac_header_generic_decoder = -1;
96 /* static gint ett_mac_subheader_decoder = -1; */
97 static gint ett_mac_mesh_subheader_decoder = -1;
98 static gint ett_mac_frag_subheader_decoder = -1;
99 static gint ett_mac_grant_mgmt_subheader_decoder = -1;
100 static gint ett_mac_pkt_subheader_decoder = -1;
101 static gint ett_mac_fast_fb_subheader_decoder = -1;
102 static gint ett_mac_ext_subheader_decoder = -1;
103 static gint ett_mac_ext_subheader_dl_decoder = -1;
104 static gint ett_mac_ext_subheader_ul_decoder = -1;
105 static gint ett_mac_arq_fb_payload_decoder = -1;
106 static gint ett_mac_data_pdu_decoder = -1;
107 static gint hf_mac_header_generic_value_bytes = -1;
108
109 static guint frag_type, frag_len;
110 static guint extended_type, arq_fb_payload, seq_number;
111
112 static guint cid_adjust[MAX_CID];  /* Must not start with 0 */
113 static guint cid_vernier[MAX_CID];
114 static guint cid_adj_array_size = 0;
115 static guint *cid_adj_array = NULL;
116 static guint8 *frag_num_array = NULL;
117
118 static address save_src;
119 static address save_dst;
120
121 #define WIMAX_MAC_HEADER_SIZE      6
122 #define IP_HEADER_BYTE 0x45
123
124 #define EXTENDED_SUB_HEADER_RSV_MASK   0x80
125 #define EXTENDED_SUB_HEADER_TYPE_MASK  0x7F
126
127 /* WIMAX GENERIC MAC HEADER FIELDS (figure 19) */
128 /* 1st to 3rd bytes */
129 #define WIMAX_MAC_HEADER_GENERIC_HT           0x800000
130 #define WIMAX_MAC_HEADER_GENERIC_EC           0x400000
131 #define WIMAX_MAC_HEADER_GENERIC_TYPE_5       0x200000
132 #define WIMAX_MAC_HEADER_GENERIC_TYPE_4       0x100000
133 #define WIMAX_MAC_HEADER_GENERIC_TYPE_3       0x080000
134 #define WIMAX_MAC_HEADER_GENERIC_TYPE_2       0x040000
135 #define WIMAX_MAC_HEADER_GENERIC_TYPE_1       0x020000
136 #define WIMAX_MAC_HEADER_GENERIC_TYPE_0       0x010000
137 #define WIMAX_MAC_HEADER_GENERIC_ESF          0x008000
138 #define WIMAX_MAC_HEADER_GENERIC_CI           0x004000
139 #define WIMAX_MAC_HEADER_GENERIC_EKS          0x003000
140 #define WIMAX_MAC_HEADER_GENERIC_RSV          0x000800
141 #define WIMAX_MAC_HEADER_GENERIC_LEN          0x0007FF
142
143 /* WIMAX GENERIC MAC HEADER 1st byte masks */
144 #define WIMAX_MAC_HEADER_GENERIC_HT_MASK     0x80
145 #define WIMAX_MAC_HEADER_GENERIC_EC_MASK     0x40
146 #define WIMAX_MAC_HEADER_GENERIC_TYPE_MASK   0x3F
147 /* WiMax Generic MAC Header Sub Type Masks */
148 #define GENERIC_SUB_TYPE_0         0x01
149 #define GENERIC_SUB_TYPE_1         0x02
150 #define GENERIC_SUB_TYPE_2         0x04
151 #define GENERIC_SUB_TYPE_3         0x08
152 #define GENERIC_SUB_TYPE_4         0x10
153 #define GENERIC_SUB_TYPE_5         0x20
154
155 /* WIMAX GENERIC MAC HEADER 2nd byte masks */
156 #define WIMAX_MAC_HEADER_GENERIC_ESF_MASK    0x80
157 #define WIMAX_MAC_HEADER_GENERIC_CI_MASK     0x40
158 #define WIMAX_MAC_HEADER_GENERIC_EKS_MASK    0x30
159 #define WIMAX_MAC_HEADER_GENERIC_LEN_MASK    0x07
160
161 static int hf_mac_header_generic_ht = -1;
162 static int hf_mac_header_generic_ec = -1;
163 static int hf_mac_header_generic_type_0 = -1;
164 static int hf_mac_header_generic_type_1 = -1;
165 static int hf_mac_header_generic_type_2 = -1;
166 static int hf_mac_header_generic_type_3 = -1;
167 static int hf_mac_header_generic_type_4 = -1;
168 static int hf_mac_header_generic_type_5 = -1;
169 static int hf_mac_header_generic_esf = -1;
170 static int hf_mac_header_generic_ci = -1;
171 static int hf_mac_header_generic_eks = -1;
172 static int hf_mac_header_generic_rsv = -1;
173 static int hf_mac_header_generic_len = -1;
174 static int hf_mac_header_generic_cid = -1;
175 static int hf_mac_header_generic_hcs = -1;
176 static int hf_mac_header_generic_crc = -1;
177
178 /* MAC Header types */
179 static const value_string ht_msgs[] =
180 {
181         { 0, "Generic" },
182         { 1, "Signaling" },
183         { 0,  NULL}
184 };
185
186 /* Encryption Controls */
187 static const value_string ec_msgs[] =
188 {
189         { 0, "Not encrypted" },
190         { 1, "Encrypted" },
191         { 0,  NULL}
192 };
193
194 /* ESF messages */
195 static const value_string esf_msgs[] =
196 {
197         { 0, "Extended subheader is absent" },
198         { 1, "Extended subheader is present" },
199         { 0,  NULL}
200 };
201
202 /* CRC Indicator messages */
203 static const value_string ci_msgs[] =
204 {
205         { 0, "No CRC is included" },
206         { 1, "CRC is included" },
207         { 0,  NULL}
208 };
209
210 /* Sub-Type message 0 */
211 static const value_string type_msg0[] =
212 {
213         { 0, "Fast-feedback allocation subheader(DL)/Grant management subheader(UL) is absent" },
214         { 1, "Fast-feedback allocation subheader(DL)/Grant management subheader(UL) is present" },
215         { 0,  NULL}
216 };
217
218 /* Sub-Type message 1 */
219 static const value_string type_msg1[] =
220 {
221         { 0, "Packing subheader is absent" },
222         { 1, "Packing Subheader is present" },
223         { 0,  NULL}
224 };
225
226 /* Sub-Type message 2 */
227 static const value_string type_msg2[] =
228 {
229         { 0, "Fragmentation subheader is absent" },
230         { 1, "Fragmentation subheader is present" },
231         { 0,  NULL}
232 };
233
234 /* Sub-Type message 3 */
235 static const value_string type_msg3[] =
236 {
237         { 0, "The subheader is not extended" },
238         { 1, "The subheader is extended" },
239         { 0,  NULL}
240 };
241
242 /* Sub-Type message 4 */
243 static const value_string type_msg4[] =
244 {
245         { 0, "ARQ feedback payload is absent" },
246         { 1, "ARQ feedback payload is present" },
247         { 0,  NULL}
248 };
249
250 /* Sub-Type message 5 */
251 static const value_string type_msg5[] =
252 {
253         { 0, "Mesh subheader is absent" },
254         { 1, "Mesh subheader is present" },
255         { 0,  NULL}
256 };
257
258 /* Fast-Feedback Feedback Types */
259 static const value_string fast_fb_types[] =
260 {
261         { 0, "Fast DL measurement" },
262         { 1, "Fast MIMO Feedback, Antenna #0" },
263         { 2, "Fast MIMO Feedback, Antenna #1" },
264         { 3, "MIMO Mode and Permutation Mode Feedback" },
265         { 0,  NULL}
266 };
267
268 /* Extended sub-headers */
269 /* DL sub-header types */
270 enum
271 {
272 SDU_SN,
273 DL_SLEEP_CONTROL,
274 FEEDBACK_REQ,
275 SN_REQ,
276 PDU_SN_SHORT_DL,
277 PDU_SN_LONG_DL
278 } DL_EXT_SUBHEADER;
279
280 static const value_string dl_ext_sub_header_type[] =
281 {
282         {0, "SDU_SN"},
283         {1, "DL Sleep Control"},
284         {2, "Feedback Request"},
285         {3, "SN Request"},
286         {4, "PDU SN (short)"},
287         {5, "PDU SN (long)"},
288         {0,  NULL}
289 };
290
291 /* DL Sleep Control Extended Subheader field masks (table 13e) */
292 #define DL_SLEEP_CONTROL_POWER_SAVING_CLASS_ID_MASK       0xFC0000      /*0x00003F*/
293 #define DL_SLEEP_CONTROL_OPERATION_MASK                   0x020000      /*0x000040*/
294 #define DL_SLEEP_CONTROL_FINAL_SLEEP_WINDOW_EXPONENT_MASK 0x01C000      /*0x000380*/
295 #define DL_SLEEP_CONTROL_FINAL_SLEEP_WINDOW_BASE_MASK     0x003FF0      /*0x0FFC00*/
296 #define DL_SLEEP_CONTROL_RESERVED_MASK                    0x00000F      /*0xF00000*/
297
298 /* Feedback Request Extended Subheader field masks (table 13f) */
299 #define FEEDBACK_REQUEST_UIUC_MASK                        0xF00000      /*0x00000F*/
300 #define FEEDBACK_REQUEST_FEEDBACK_TYPE_MASK               0x0F0000      /*0x0000F0*/
301 #define FEEDBACK_REQUEST_OFDMA_SYMBOL_OFFSET_MASK         0x00FC00      /*0x003F00*/
302 #define FEEDBACK_REQUEST_SUBCHANNEL_OFFSET_MASK           0x0003F0      /*0x0FC000*/
303 #define FEEDBACK_REQUEST_NUMBER_OF_SLOTS_MASK             0x00000E      /*0x700000*/
304 #define FEEDBACK_REQUEST_FRAME_OFFSET_MASK                0x000001      /*0x800000*/
305
306 /* OFDMA UIUC Values ??? */
307 static const value_string uiuc_values[] =
308 {
309         { 0, "Fast-Feedback Channel" },
310         { 1, "Burst Profile 1" },
311         { 2, "Burst Profile 2" },
312         { 3, "Burst Profile 3" },
313         { 4, "Burst Profile 4" },
314         { 5, "Burst Profile 5" },
315         { 6, "Burst Profile 6" },
316         { 7, "Burst Profile 7" },
317         { 8, "Burst Profile 8" },
318         { 9, "Burst Profile 9" },
319         { 10, "Burst Profile 10" },
320         { 11, "Extended UIUC 2 IE" },
321         { 12, "CDMA Bandwidth Request, CDMA Ranging" },
322         { 13, "PAPR Reduction Allocation, Safety Zone" },
323         { 14, "CDMA Allocation IE" },
324         { 15, "Extended UIUC" },
325         { 0,  NULL}
326 };
327
328 /* UL sub-header types */
329 enum
330 {
331 MIMO_MODE_FEEDBACK,
332 UL_TX_POWER_REPORT,
333 MINI_FEEDBACK,
334 PDU_SN_SHORT_UL,
335 PDU_SN_LONG_UL
336 } UL_EXT_SUBHEADER;
337
338 static const value_string ul_ext_sub_header_type[] =
339 {
340         {0, "MIMO Mode Feedback"},
341         {1, "UL TX Power Report"},
342         {2, "Mini-feedback"},
343         {3, "PDU SN (short)"},
344         {4, "PDU SN (long)"},
345         {0,  NULL}
346 };
347
348 /* MIMO Mode Feedback Extended Subheader field masks (table 13g) */
349 #define MIMO_FEEDBACK_TYPE_MASK                  0xC0   /*0x03*/
350 #define MIMO_FEEDBACK_CONTENT_MASK               0x3F   /*0xFC*/
351 /* Mimo Feedback Types ??? */
352 static const value_string mimo_fb_types[] =
353 {
354         { 0, "Fast DL measurement" },
355         { 1, "Default Feedback with Antenna Grouping" },
356         { 2, "Antenna Selection and Reduced Codebook" },
357         { 3, "Quantized Precoding Weight Feedback" },
358         { 0,  NULL}
359 };
360
361 /* MNI-Feedback Extended Subheader field masks (table 13i) */
362 #define MINI_FEEDBACK_TYPE_MASK                  0xF000 /*0x000F*/
363 #define MINI_FEEDBACK_CONTENT_MASK               0x0FFF /*0xFFF0*/
364 /* Feedback Types */
365 static const value_string fb_types[] =
366 {
367         { 0, "CQI and MIMO Feedback" },
368         { 1, "DL average CINR" },
369         { 2, "MIMO Coefficients Feedback" },
370         { 3, "Preferred DL Channel DIUC Feedback" },
371         { 4, "UL Transmission Power" },
372         { 5, "PHY Channel Feedback" },
373         { 6, "AMC Band Indication Bitmap" },
374         { 7, "Life Span of Short-term Precoding Feedback" },
375         { 8, "Multiple Types of Feedback" },
376         { 9, "Long-term Precoding Feedback" },
377         { 10, "Combined DL Average CINR of Active BSs" },
378         { 11, "MIMO Channel Feedback" },
379         { 12, "CINR Feedback" },
380         { 13, "Close-loop MIMO Feedback" },
381         { 14, "Reserved" },
382         { 15, "Reserved" },
383         { 0,  NULL}
384 };
385
386 /* common fields */
387 static gint hf_mac_header_generic_ext_subheader_rsv = -1;
388 /* DL sub-header */
389 static gint hf_mac_header_generic_ext_subheader_type_dl = -1;
390 static gint hf_mac_header_generic_ext_subheader_sdu_sn = -1;
391 static gint hf_mac_header_generic_ext_subheader_dl_sleep_control_pscid = -1;
392 static gint hf_mac_header_generic_ext_subheader_dl_sleep_control_op = -1;
393 static gint hf_mac_header_generic_ext_subheader_dl_sleep_control_fswe = -1;
394 static gint hf_mac_header_generic_ext_subheader_dl_sleep_control_fswb = -1;
395 static gint hf_mac_header_generic_ext_subheader_dl_sleep_control_rsv = -1;
396 static gint hf_mac_header_generic_ext_subheader_fb_req_uiuc = -1;
397 static gint hf_mac_header_generic_ext_subheader_fb_req_fb_type = -1;
398 static gint hf_mac_header_generic_ext_subheader_fb_req_ofdma_symbol_offset = -1;
399 static gint hf_mac_header_generic_ext_subheader_fb_req_subchannel_offset = -1;
400 static gint hf_mac_header_generic_ext_subheader_fb_req_slots = -1;
401 static gint hf_mac_header_generic_ext_subheader_fb_req_frame_offset = -1;
402
403 /* DL Sleep Control Operations */
404 static const value_string dl_sleep_control_ops[] =
405 {
406         { 0, "De-activate Power Saving Class" },
407         { 1, "Activate Power Saving Class" },
408         { 0,  NULL}
409 };
410
411 /* UL sub-header */
412 static gint hf_mac_header_generic_ext_subheader_type_ul = -1;
413 static gint hf_mac_header_generic_ext_subheader_mimo_mode_fb_type = -1;
414 static gint hf_mac_header_generic_ext_subheader_mimo_fb_content = -1;
415 static gint hf_mac_header_generic_ext_subheader_ul_tx_pwr_rep = -1;
416 static gint hf_mac_header_generic_ext_subheader_mini_fb_type = -1;
417 static gint hf_mac_header_generic_ext_subheader_mini_fb_content = -1;
418 /* common fields */
419 static gint hf_mac_header_generic_ext_subheader_pdu_sn_short = -1;
420 static gint hf_mac_header_generic_ext_subheader_pdu_sn_long = -1;
421
422 /* SN Request subheader */
423 #define SN_REQUEST_SUBHEADER_SN_REPORT_INDICATION_1_MASK 0x01
424 #define SN_REQUEST_SUBHEADER_SN_REPORT_INDICATION_2_MASK 0x02
425 #define SN_REQUEST_SUBHEADER_RESERVED_MASK               0xFC
426
427 static gint hf_mac_header_generic_ext_subheader_sn_req_rep_ind_1 = -1;
428 static gint hf_mac_header_generic_ext_subheader_sn_req_rep_ind_2 = -1;
429 static gint hf_mac_header_generic_ext_subheader_sn_req_rsv = -1;
430 /* SN Report Indication message */
431 static const value_string sn_rep_msg[] =
432 {
433         { 0, "" },
434         { 1, "request transmission" },
435         { 0,  NULL}
436 };
437
438 /* Mesh Subheader */
439 static gint hf_mac_header_generic_mesh_subheader = -1;
440
441 /* Fragmentation Subheader (table 8) */
442 #define FRAGMENTATION_SUBHEADER_FC_MASK         0xC000  /*0x0003*/
443 #define FRAGMENTATION_SUBHEADER_BSN_MASK        0x3FF8  /*0x1FFC*/
444 #define FRAGMENTATION_SUBHEADER_RSV_EXT_MASK    0x0007  /*0xE000*/
445 #define FRAGMENTATION_SUBHEADER_FSN_MASK        0x38    /*0x1C*/
446 #define FRAGMENTATION_SUBHEADER_RSV_MASK        0x07    /*0xE0*/
447 #define FRAGMENT_TYPE_MASK  0xC0
448 #define SEQ_NUMBER_MASK     0x38
449 #define SEQ_NUMBER_MASK_11  0x3FF8
450
451 #define NO_FRAG     0
452 #define LAST_FRAG   1
453 #define FIRST_FRAG  2
454 #define MIDDLE_FRAG 3
455
456 static gint hf_mac_header_generic_frag_subhd_fc = -1;
457 static gint hf_mac_header_generic_frag_subhd_fc_ext = -1;
458 static gint hf_mac_header_generic_frag_subhd_bsn = -1;
459 static gint hf_mac_header_generic_frag_subhd_fsn = -1;
460 static gint hf_mac_header_generic_frag_subhd_fsn_ext = -1;
461 static gint hf_mac_header_generic_frag_subhd_rsv = -1;
462 static gint hf_mac_header_generic_frag_subhd_rsv_ext = -1;
463
464 /* Fragment Types */
465 static const value_string frag_types[] =
466 {
467         { 0, "No fragmentation" },
468         { 1, "Last fragment" },
469         { 2, "First fragment" },
470         { 3, "Continuing (middle) fragment" },
471         { 0,  NULL}
472 };
473
474 /* Packing Subheader (table 11) */
475 #define PACKING_SUBHEADER_FC_MASK           0xC00000
476 #define PACKING_SUBHEADER_BSN_MASK          0x3FF800
477 #define PACKING_SUBHEADER_FSN_MASK          0x38
478 #define PACKING_SUBHEADER_LENGTH_MASK       0x07FF
479 #define PACKING_SUBHEADER_LENGTH_EXT_MASK   0x0007FF
480
481 #define FRAG_LENGTH_MASK    0x0007FF00
482
483 static gint hf_mac_header_generic_packing_subhd_fc = -1;
484 static gint hf_mac_header_generic_packing_subhd_fc_ext = -1;
485 static gint hf_mac_header_generic_packing_subhd_bsn = -1;
486 static gint hf_mac_header_generic_packing_subhd_fsn = -1;
487 static gint hf_mac_header_generic_packing_subhd_fsn_ext = -1;
488 static gint hf_mac_header_generic_packing_subhd_len = -1;
489 static gint hf_mac_header_generic_packing_subhd_len_ext = -1;
490
491 /* Fast-feedback Allocation Subheader (table 13) */
492 #define FAST_FEEDBACK_ALLOCATION_OFFSET_MASK 0xFC       /*0x3F*/
493 #define FAST_FEEDBACK_FEEDBACK_TYPE_MASK     0x03       /*0xC0*/
494
495 static gint hf_mac_header_generic_fast_fb_subhd_alloc_offset = -1;
496 static gint hf_mac_header_generic_fast_fb_subhd_fb_type = -1;
497
498 /* Grant Management Subheader (table 9 & 10) */
499 #define GRANT_MGMT_SUBHEADER_UGS_SI_MASK          0x8000        /*0x0001*/
500 #define GRANT_MGMT_SUBHEADER_UGS_PM_MASK          0x4000        /*0x0002*/
501 #define GRANT_MGMT_SUBHEADER_UGS_FLI_MASK         0x2000        /*0x0004*/
502 #define GRANT_MGMT_SUBHEADER_UGS_FL_MASK          0x1E00        /*0x0078*/
503 #define GRANT_MGMT_SUBHEADER_UGS_RSV_MASK         0x01FF        /*0xFF80*/
504 #define GRANT_MGMT_SUBHEADER_EXT_PBR_MASK         0xFFE0        /*0x07FF*/
505 #define GRANT_MGMT_SUBHEADER_EXT_FLI_MASK         0x0010        /*0x0800*/
506 #define GRANT_MGMT_SUBHEADER_EXT_FL_MASK          0x000F        /*0xF000*/
507
508 enum
509 {
510         SCHEDULE_SERVICE_TYPE_RSVD,
511         SCHEDULE_SERVICE_TYPE_UNDEFINED,
512         SCHEDULE_SERVICE_TYPE_BE,
513         SCHEDULE_SERVICE_TYPE_NRTPS,
514         SCHEDULE_SERVICE_TYPE_RTPS,
515         SCHEDULE_SERVICE_TYPE_EXT_RTPS,
516         SCHEDULE_SERVICE_TYPE_UGS
517 } SCHEDULE_SERVICE_TYPE;
518
519 static gint hf_mac_header_generic_grant_mgmt_ugs_tree           = -1;
520 static gint hf_mac_header_generic_grant_mgmt_subhd_ugs_si       = -1;
521 static gint hf_mac_header_generic_grant_mgmt_subhd_ugs_pm       = -1;
522 static gint hf_mac_header_generic_grant_mgmt_subhd_ugs_fli      = -1;
523 static gint hf_mac_header_generic_grant_mgmt_subhd_ugs_fl       = -1;
524 static gint hf_mac_header_generic_grant_mgmt_subhd_ugs_rsv      = -1;
525 static gint hf_mac_header_generic_grant_mgmt_ext_rtps_tree      = -1;
526 static gint hf_mac_header_generic_grant_mgmt_subhd_ext_pbr      = -1;
527 static gint hf_mac_header_generic_grant_mgmt_subhd_ext_fli      = -1;
528 static gint hf_mac_header_generic_grant_mgmt_subhd_ext_fl       = -1;
529 static gint hf_mac_header_generic_grant_mgmt_ext_pbr_tree       = -1;
530 static gint hf_mac_header_generic_grant_mgmt_subhd_pbr          = -1;
531
532 /* Slip Indicators */
533 static const value_string si_msgs[] =
534 {
535         { 0, "No action" },
536         { 1, "A slip of UL grants relative to the UL queue depth" },
537         { 0,  NULL}
538 };
539
540 /* Poll-Me Messages */
541 static const value_string pm_msgs[] =
542 {
543         { 0, "No action" },
544         { 1, "Request a bandwidth poll" },
545         { 0,  NULL}
546 };
547
548 /* Frame Latency Indications */
549 static const value_string fli_msgs[] =
550 {
551         { 0, "Frame latency field disabled" },
552         { 1, "Frame latency field enabled" },
553         { 0,  NULL}
554 };
555
556 /* ARQ Feedback Payload */
557
558 /* ARQ Feedback IE bit masks (table 111) */
559 #define ARQ_FB_IE_LAST_BIT_MASK      0x8000     /*0x0001*/
560 #define ARQ_FB_IE_ACK_TYPE_MASK      0x6000     /*0x0006*/
561 #define ARQ_FB_IE_BSN_MASK           0x1FFC     /*0x3FF8*/
562 #define ARQ_FB_IE_NUM_MAPS_MASK      0x0003     /*0xC000*/
563 #define ARQ_FB_IE_SEQ_FORMAT_MASK    0x8000     /*0x0001*/
564 #define ARQ_FB_IE_SEQ_ACK_MAP_MASK   0x7000     /*0x000E*/
565 #define ARQ_FB_IE_SEQ1_LENGTH_MASK   0x0F00     /*0x00F0*/
566 #define ARQ_FB_IE_SEQ2_LENGTH_MASK   0x00F0     /*0x0F00*/
567 #define ARQ_FB_IE_SEQ3_LENGTH_MASK   0x000F     /*0xF000*/
568 #define ARQ_FB_IE_SEQ_ACK_MAP_2_MASK 0x6000     /*0x0006*/
569 #define ARQ_FB_IE_SEQ1_LENGTH_6_MASK 0x1F80     /*0x01F8*/
570 #define ARQ_FB_IE_SEQ2_LENGTH_6_MASK 0x007E     /*0x7E00*/
571 #define ARQ_FB_IE_RSV_MASK           0x0001     /*0x8000*/
572
573 static gint hf_mac_header_generic_arq_fb_ie_cid = -1;
574 static gint hf_mac_header_generic_arq_fb_ie_last = -1;
575 static gint hf_mac_header_generic_arq_fb_ie_ack_type = -1;
576 static gint hf_mac_header_generic_arq_fb_ie_bsn = -1;
577 static gint hf_mac_header_generic_arq_fb_ie_num_maps = -1;
578 static gint hf_ack_type_reserved = -1;
579 static gint hf_mac_header_generic_arq_fb_ie_sel_ack_map = -1;
580 static gint hf_mac_header_generic_arq_fb_ie_seq_format = -1;
581 static gint hf_mac_header_generic_arq_fb_ie_seq_ack_map = -1;
582 static gint hf_mac_header_generic_arq_fb_ie_seq1_length = -1;
583 static gint hf_mac_header_generic_arq_fb_ie_seq2_length = -1;
584 static gint hf_mac_header_generic_arq_fb_ie_seq3_length = -1;
585 static gint hf_mac_header_generic_arq_fb_ie_seq_ack_map_2 = -1;
586 static gint hf_mac_header_generic_arq_fb_ie_seq1_length_6 = -1;
587 static gint hf_mac_header_generic_arq_fb_ie_seq2_length_6 = -1;
588 static gint hf_mac_header_generic_arq_fb_ie_rsv = -1;
589
590 /* Last IE Indicators */
591 static const value_string last_ie_msgs[] =
592 {
593         { 0, "No" },
594         { 1, "Yes" },
595         { 0,  NULL}
596 };
597
598 /* Register Wimax defrag table init routine. */
599 void wimax_defragment_init(void)
600 {
601         gint i;
602
603         fragment_table_init(&payload_frag_table);
604
605         /* Init fragmentation variables. */
606         for (i = 0; i < MAX_CID; i++)
607         {
608                 cid_adjust[i] = 1;      /* Must not start with 0 */
609                 cid_vernier[i] = 0;
610         }
611         cid_adj_array_size = 0;
612         /* Free the array memory. */
613         if (cid_adj_array) {
614                 g_free(cid_adj_array);
615         }
616         cid_adj_array = NULL;
617         if (frag_num_array) {
618                 g_free(frag_num_array);
619         }
620         frag_num_array = NULL;
621
622         /* Initialize to make sure bs_address gets set in FCH decoder. */
623         bs_address.len = 0;
624
625         /* Initialize the Scheduling Service Type flag */
626         seen_a_service_type = 0;
627
628         max_logical_bands = 12;
629
630         /* Initialize UL_MAP globals. */
631         init_wimax_globals();
632 }
633
634 static guint decode_packing_subheader(tvbuff_t *payload_tvb, packet_info *pinfo, proto_tree *tree, guint payload_length, guint payload_offset, proto_item *parent_item)
635 {
636         proto_item *generic_item = NULL;
637         proto_tree *generic_tree = NULL;
638         guint starting_offset = payload_offset;
639
640         /* update the info column */
641         col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "Packing subhdr");
642         /* add the Packing subheader info */
643         proto_item_append_text(parent_item, ", Packing Subheader");
644         /* display Packing subheader type */
645         generic_item = proto_tree_add_protocol_format(tree, proto_mac_header_generic_decoder, payload_tvb, payload_offset, ((arq_enabled|extended_type)?3:2), "Packing subheader (%u bytes)", ((arq_enabled|extended_type)?3:2));
646         /* add Packing subheader subtree */
647         generic_tree = proto_item_add_subtree(generic_item, ett_mac_pkt_subheader_decoder);
648         /* decode and display the Packing subheader */
649         /* Get the fragment type */
650         frag_type = (tvb_get_guint8(payload_tvb, payload_offset) & FRAGMENT_TYPE_MASK) >> 6;
651         /* if ARQ Feedback payload is present */
652         if (arq_fb_payload)
653         {       /* get the frag length */
654                 frag_len = ((tvb_get_ntohl(payload_tvb, payload_offset) & FRAG_LENGTH_MASK) >> 8);
655                 /* get the sequence number */
656                 seq_number = (tvb_get_ntohs(payload_tvb, payload_offset) & SEQ_NUMBER_MASK_11) >> 3;
657                 proto_tree_add_item(generic_tree, hf_mac_header_generic_packing_subhd_fc_ext, payload_tvb, payload_offset, 3, FALSE);
658                 proto_tree_add_item(generic_tree, hf_mac_header_generic_packing_subhd_bsn, payload_tvb, payload_offset, 3, FALSE);
659                 proto_tree_add_item(generic_tree, hf_mac_header_generic_packing_subhd_len_ext, payload_tvb, payload_offset, 3, FALSE);
660                 /* update the length and offset */
661                 payload_length -= 3;
662                 payload_offset += 3;
663                 frag_len -= 3;
664         }
665         else
666         {
667                 if (extended_type)
668                 {       /* get the frag length */
669                         frag_len = ((tvb_get_ntohl(payload_tvb, payload_offset) & FRAG_LENGTH_MASK) >> 8);
670                         /* get the sequence number */
671                         seq_number = (tvb_get_ntohs(payload_tvb, payload_offset) & SEQ_NUMBER_MASK_11) >> 3;
672                         proto_tree_add_item(generic_tree, hf_mac_header_generic_packing_subhd_fc_ext, payload_tvb, payload_offset, 3, FALSE);
673                         proto_tree_add_item(generic_tree, hf_mac_header_generic_packing_subhd_fsn_ext, payload_tvb, payload_offset, 3, FALSE);
674                         proto_tree_add_item(generic_tree, hf_mac_header_generic_packing_subhd_len_ext, payload_tvb, payload_offset, 3, FALSE);
675                         /* update the length and offset */
676                         payload_length -= 3;
677                         payload_offset += 3;
678                         frag_len -= 3;
679                 }
680                 else
681                 {       /* get the frag length */
682                         frag_len = (tvb_get_ntohs(payload_tvb, payload_offset) & PACKING_SUBHEADER_LENGTH_MASK);
683                         /* get the sequence number */
684                         seq_number = (tvb_get_guint8(payload_tvb, payload_offset) & SEQ_NUMBER_MASK) >> 3;
685                         proto_tree_add_item(generic_tree, hf_mac_header_generic_packing_subhd_fc, payload_tvb, payload_offset, 2, FALSE);
686                         proto_tree_add_item(generic_tree, hf_mac_header_generic_packing_subhd_fsn, payload_tvb, payload_offset, 2, FALSE);
687                         proto_tree_add_item(generic_tree, hf_mac_header_generic_packing_subhd_len, payload_tvb, payload_offset, 2, FALSE);
688                         /* update the length and offset */
689                         payload_length -= 2;
690                         payload_offset += 2;
691                         frag_len -= 2;
692                 }
693         }
694         /* Prevent a crash! */
695         if ((gint)frag_len < 0)
696                 frag_len = 0;
697         /* Return the number of bytes decoded. */
698         return payload_offset - starting_offset;
699 }
700
701
702 void dissect_mac_header_generic_decoder(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
703 {
704         guint offset = 0;
705         guint payload_offset;
706         guint payload_length = 0;
707
708         static guint8 frag_number[MAX_CID];
709         static guint cid_list[MAX_CID];
710         static guint cid_base;
711         static char *reassem_str = "Reassembled Data transport PDU (%u bytes)";
712         static char *data_str = "Data transport PDU (%u bytes)";
713         char *str_ptr;
714         gint length, i, cid_index;
715         guint tvb_len, ret_length, ubyte, new_tvb_len;
716         guint new_payload_len = 0;
717         guint /*mac_ht,*/ mac_ec, mac_esf, mac_ci, /*mac_eks,*/ mac_len, mac_cid, cid;
718         guint ffb_grant_mgmt_subheader, packing_subheader, fragment_subheader;
719         guint mesh_subheader;
720         guint packing_length;
721         guint32 mac_crc, calculated_crc;
722         proto_item *parent_item = NULL;
723         proto_item *generic_item = NULL;
724         proto_tree *generic_tree = NULL;
725         proto_item *child_item = NULL;
726         proto_tree *child_tree = NULL;
727         tvbuff_t *payload_tvb;
728         tvbuff_t *data_pdu_tvb;
729         fragment_data *payload_frag;
730         gboolean first_arq_fb_payload = TRUE;
731
732         dissector_handle_t mac_payload_handle;
733
734         proto_mac_header_generic_decoder = proto_wimax;
735         if (tree)
736         {       /* we are being asked for details */
737 #ifdef DEBUG
738                 /* update the info column */
739                 col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "GMH");
740 #endif
741                 /* Get the frame length */
742                 tvb_len =  tvb_reported_length(tvb);
743                 if (tvb_len < WIMAX_MAC_HEADER_SIZE)
744                 {       /* display the error message */
745                         generic_item = proto_tree_add_protocol_format(tree, proto_mac_header_generic_decoder, tvb, offset, tvb_len, "Error: the size of Generic MAC Header tvb is too small! (%u bytes)", tvb_len);
746                         /* add subtree */
747                         generic_tree = proto_item_add_subtree(generic_item, ett_mac_header_generic_decoder);
748                         /* display the Generic MAC Header in Hex */
749                         proto_tree_add_item(generic_tree, hf_mac_header_generic_value_bytes, tvb, offset, tvb_len, FALSE);
750                         return;
751                 }
752                 /* get the parent */
753                 parent_item = proto_tree_get_parent(tree);
754                 /* add the MAC header info */
755                 proto_item_append_text(parent_item, " - Generic MAC Header");
756                 /* display MAC header message */
757                 generic_item = proto_tree_add_protocol_format(tree, proto_mac_header_generic_decoder, tvb, offset, WIMAX_MAC_HEADER_SIZE, "Generic MAC Header (%u bytes)", WIMAX_MAC_HEADER_SIZE);
758                 /* add MAC header subtree */
759                 generic_tree = proto_item_add_subtree(generic_item, ett_mac_header_generic_decoder);
760                 /* Decode and display the MAC header */
761                 /* Get the first byte */
762                 ubyte = tvb_get_guint8(tvb, offset);
763                 /* get the Header Type (HT) */
764                 /*mac_ht = ((ubyte & WIMAX_MAC_HEADER_GENERIC_HT_MASK)?1:0); XX: not used ?? */
765                 /* get the Encryption Control (EC) */
766                 mac_ec = ((ubyte & WIMAX_MAC_HEADER_GENERIC_EC_MASK)?1:0);
767                 /* get the sub types */
768                 ffb_grant_mgmt_subheader = ((ubyte & GENERIC_SUB_TYPE_0)?1:0);
769                 packing_subheader = ((ubyte & GENERIC_SUB_TYPE_1)?1:0);
770                 fragment_subheader = ((ubyte & GENERIC_SUB_TYPE_2)?1:0);
771                 extended_type = ((ubyte & GENERIC_SUB_TYPE_3)?1:0);
772                 arq_fb_payload = ((ubyte & GENERIC_SUB_TYPE_4)?1:0);
773                 mesh_subheader = ((ubyte & GENERIC_SUB_TYPE_5)?1:0);
774                 /* Get the 2nd byte */
775                 ubyte = tvb_get_guint8(tvb, (offset+1));
776                 /* get the Extended subheader field (ESF) */
777                 mac_esf = ((ubyte & WIMAX_MAC_HEADER_GENERIC_ESF_MASK)?1:0);
778                 /* get the CRC indicator (CI) */
779                 mac_ci = ((ubyte & WIMAX_MAC_HEADER_GENERIC_CI_MASK)?1:0);
780                 /* get the Encryption key sequence (EKS) */
781                 /*mac_eks = ((ubyte & WIMAX_MAC_HEADER_GENERIC_EKS_MASK)>>4); XX: not used ?? */
782                 /* get the MAC length */
783                 mac_len = (tvb_get_ntohs(tvb, (offset+1)) & WIMAX_MAC_HEADER_GENERIC_LEN);
784                 /* get the CID */
785                 mac_cid = tvb_get_ntohs(tvb, (offset+3));
786                 /* display the Header Type (HT) */
787                 proto_tree_add_item(generic_tree, hf_mac_header_generic_ht, tvb, offset, 3, FALSE);
788                 /* display the Encryption Control (EC) */
789                 proto_tree_add_item(generic_tree, hf_mac_header_generic_ec, tvb, offset, 3, FALSE);
790                 /* display the sub-types (Type) */
791                 proto_tree_add_item(generic_tree, hf_mac_header_generic_type_5, tvb, offset, 3, FALSE);
792                 proto_tree_add_item(generic_tree, hf_mac_header_generic_type_4, tvb, offset, 3, FALSE);
793                 proto_tree_add_item(generic_tree, hf_mac_header_generic_type_3, tvb, offset, 3, FALSE);
794                 proto_tree_add_item(generic_tree, hf_mac_header_generic_type_2, tvb, offset, 3, FALSE);
795                 proto_tree_add_item(generic_tree, hf_mac_header_generic_type_1, tvb, offset, 3, FALSE);
796                 proto_tree_add_item(generic_tree, hf_mac_header_generic_type_0, tvb, offset, 3, FALSE);
797                 /* display the Extended sub-header Field (ESF) */
798                 proto_tree_add_item(generic_tree, hf_mac_header_generic_esf, tvb, offset, 3, FALSE);
799                 /* display the CRC Indicator (CI) */
800                 proto_tree_add_item(generic_tree, hf_mac_header_generic_ci, tvb, offset, 3, FALSE);
801                 /* display the Encryption Key Sequence (EKS) */
802                 proto_tree_add_item(generic_tree, hf_mac_header_generic_eks, tvb, offset, 3, FALSE);
803                 /* display the reserved field */
804                 proto_tree_add_item(generic_tree, hf_mac_header_generic_rsv, tvb, offset, 3, FALSE);
805                 /* display the length */
806                 proto_tree_add_item(generic_tree, hf_mac_header_generic_len, tvb, offset, 3, FALSE);
807                 /* Decode and display the CID */
808                 proto_tree_add_item(generic_tree, hf_mac_header_generic_cid, tvb, (offset+3), 2, FALSE);
809                 /* Decode and display the HCS */
810                 proto_tree_add_item(generic_tree, hf_mac_header_generic_hcs, tvb, (offset+5), 1, FALSE);
811                 /* get the frame length without MAC header */
812                 length = mac_len - WIMAX_MAC_HEADER_SIZE;
813 #ifdef DEBUG
814                 proto_item_append_text(parent_item, "tvb length=%u, mac length=%u, frame length=%u,", tvb_len, mac_len, length);
815 #endif
816                 /* set the offset for the frame */
817                 offset += WIMAX_MAC_HEADER_SIZE;
818                 /* the processing of the subheaders is order sensitive */
819                 /* do not change the order */
820
821                 if (mac_ec)
822                 {
823                         if (mac_ci)
824                         {
825                                 if (length >= (gint)sizeof(mac_crc))
826                                 {
827                                         length -= sizeof(mac_crc);
828                                 }
829                         }
830                         generic_item = proto_tree_add_protocol_format(tree, proto_mac_header_generic_decoder, tvb, offset, length, "Encrypted PDU (%u bytes)", length);
831                         /* add payload subtree */
832                         generic_tree = proto_item_add_subtree(generic_item, ett_mac_data_pdu_decoder);
833                         proto_tree_add_item(generic_tree, hf_mac_header_generic_value_bytes, tvb, offset, length, FALSE);
834                         goto check_crc;
835                 }
836
837                 /* if Extended subheader is present */
838                 if (mac_esf)
839                 {       /* add the Extended subheader info */
840                         proto_item_append_text(parent_item, ", Extended Subheader(s)");
841                         ret_length = extended_subheader_decoder(tvb_new_subset(tvb, offset, length, length), pinfo, tree);
842                         /* update the length and offset */
843                         length -= ret_length;
844                         offset += ret_length;
845                 }
846                 /* if Mesh subheader is present */
847                 if (mesh_subheader)
848                 {       /* update the info column */
849                         col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "Mesh subhdr");
850                         /* add the Mesh subheader info */
851                         proto_item_append_text(parent_item, ", Mesh Subheader");
852                         /* display Mesh subheader type */
853                         generic_item = proto_tree_add_protocol_format(tree, proto_mac_header_generic_decoder, tvb, offset, length, "Mesh subheader (2 bytes)");
854                         /* add Mesh subheader subtree */
855                         generic_tree = proto_item_add_subtree(generic_item, ett_mac_mesh_subheader_decoder);
856                         /* decode and display the Mesh subheader */
857                         proto_tree_add_item(generic_tree, hf_mac_header_generic_mesh_subheader, tvb, offset, 2, FALSE);
858                         /* update the length and offset */
859                         length -= 2;
860                         offset += 2;
861                 }
862                 /* if Fast-feedback allocation (DL) subheader or Grant management (UL) subheader is present */
863                 if (ffb_grant_mgmt_subheader)
864                 {       /* check if it is downlink packet */
865                         if (is_down_link(pinfo))
866                         {       /* Fast-feedback allocation (DL) subheader is present */
867                                 /* update the info column */
868                                 col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "Fast-fb subhdr");
869                                 /* add the Fast-feedback subheader info */
870                                 proto_item_append_text(parent_item, ", Fast-feedback Subheader");
871                                 /* display Fast-feedback allocation subheader type */
872                                 generic_item = proto_tree_add_protocol_format(tree, proto_mac_header_generic_decoder, tvb, offset, length, "Fast-feedback allocation (DL) subheader (%u bytes)", length);
873                                 /* add Fast-feedback allocation subheader subtree */
874                                 generic_tree = proto_item_add_subtree(generic_item, ett_mac_fast_fb_subheader_decoder);
875                                 proto_tree_add_item(generic_tree, hf_mac_header_generic_fast_fb_subhd_alloc_offset, tvb, offset, 1, FALSE);
876                                 proto_tree_add_item(generic_tree, hf_mac_header_generic_fast_fb_subhd_fb_type, tvb, offset, 1, FALSE);
877                                 /* update the length and offset */
878                                 length -= 1;
879                                 offset += 1;
880                         }
881                         else    /* Grant management (UL) subheader is present */
882                         {       /* update the info column */
883                                 col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "Grant mgmt subhdr");
884                                 /* add the Grant management subheader info */
885                                 proto_item_append_text(parent_item, ", Grant Management Subheader");
886                                 /* display Grant management subheader type */
887                                 generic_item = proto_tree_add_protocol_format(tree, proto_mac_header_generic_decoder, tvb, offset, 2, "Grant management (UL) subheader (2 bytes)");
888                                 /* add Grant management subheader subtree */
889                                 generic_tree = proto_item_add_subtree(generic_item, ett_mac_grant_mgmt_subheader_decoder);
890                                 scheduling_service_type = get_service_type();
891                                 switch (scheduling_service_type)
892                                 {
893                                 case SCHEDULE_SERVICE_TYPE_UGS:
894                                         proto_item_append_text(generic_item, ": It looks like UGS is the correct Scheduling Service Type");
895                                 break;
896                                 case SCHEDULE_SERVICE_TYPE_EXT_RTPS:
897                                         proto_item_append_text(generic_item, ": It looks like Extended rtPS is the correct Scheduling Service Type");
898                                 break;
899                                 case -1:
900                                         proto_item_append_text(generic_item, ": Cannot determine the correct Scheduling Service Type");
901                                 break;
902                                 default:
903                                         proto_item_append_text(generic_item, ": It looks like Piggyback Request is the correct Scheduling Service Type");
904                                 break;
905                                 }
906                                 /* Create tree for Scheduling Service Type (UGS) */
907                                 child_item = proto_tree_add_item(generic_tree, hf_mac_header_generic_grant_mgmt_ugs_tree, tvb, offset, 2, FALSE);
908                                 child_tree = proto_item_add_subtree(child_item, ett_mac_grant_mgmt_subheader_decoder);
909                                 proto_tree_add_item(child_tree, hf_mac_header_generic_grant_mgmt_subhd_ugs_si, tvb, offset, 2, FALSE);
910                                 proto_tree_add_item(child_tree, hf_mac_header_generic_grant_mgmt_subhd_ugs_pm, tvb, offset, 2, FALSE);
911                                 proto_tree_add_item(child_tree, hf_mac_header_generic_grant_mgmt_subhd_ugs_fli, tvb, offset, 2, FALSE);
912                                 proto_tree_add_item(child_tree, hf_mac_header_generic_grant_mgmt_subhd_ugs_fl, tvb, offset, 2, FALSE);
913                                 proto_tree_add_item(child_tree, hf_mac_header_generic_grant_mgmt_subhd_ugs_rsv, tvb, offset, 2, FALSE);
914
915                                 /* Create tree for Scheduling Service Type (Extended RTPS) */
916                                 child_item = proto_tree_add_item(generic_tree, hf_mac_header_generic_grant_mgmt_ext_rtps_tree, tvb, offset, 2, FALSE);
917                                 child_tree = proto_item_add_subtree(child_item, ett_mac_grant_mgmt_subheader_decoder);
918                                 proto_tree_add_item(child_tree, hf_mac_header_generic_grant_mgmt_subhd_ext_pbr, tvb, offset, 2, FALSE);
919                                 proto_tree_add_item(child_tree, hf_mac_header_generic_grant_mgmt_subhd_ext_fli, tvb, offset, 2, FALSE);
920                                 proto_tree_add_item(child_tree, hf_mac_header_generic_grant_mgmt_subhd_ext_fl, tvb, offset, 2, FALSE);
921
922                                 /* Create tree for Scheduling Service Type (Piggyback Request) */
923                                 child_item = proto_tree_add_item(generic_tree, hf_mac_header_generic_grant_mgmt_ext_pbr_tree, tvb, offset, 2, FALSE);
924                                 child_tree = proto_item_add_subtree(child_item, ett_mac_grant_mgmt_subheader_decoder);
925                                 proto_tree_add_item(child_tree, hf_mac_header_generic_grant_mgmt_subhd_pbr, tvb, offset, 2, FALSE);
926
927                                 /* update the length and offset */
928                                 length -= 2;
929                                 offset += 2;
930                         }
931                 }
932                 /* if Fragmentation subheader is present */
933                 if (fragment_subheader)
934                 {       /* update the info column */
935                         col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "Frag subhdr");
936                         /* add the Fragmentation subheader info */
937                         proto_item_append_text(parent_item, ", Frag Subheader");
938                         /* display Fragmentation subheader type */
939                         generic_item = proto_tree_add_protocol_format(tree, proto_mac_header_generic_decoder, tvb, offset, ((arq_enabled|extended_type)?2:1), "Fragmentation subheader (%u bytes)", ((arq_enabled|extended_type)?2:1));
940                         /* add Fragmentation subheader subtree */
941                         generic_tree = proto_item_add_subtree(generic_item, ett_mac_frag_subheader_decoder);
942                         /* Get the fragment type */
943                         frag_type = (tvb_get_guint8(tvb, offset) & FRAGMENT_TYPE_MASK) >> 6;
944                         if (arq_fb_payload)
945                         {       /* get the sequence number */
946                                 seq_number = (tvb_get_ntohs(tvb, offset) & SEQ_NUMBER_MASK_11) >> 3;
947                                 /* decode and display the header */
948                                 proto_tree_add_item(generic_tree, hf_mac_header_generic_frag_subhd_fc_ext, tvb, offset, 2, FALSE);
949                                 proto_tree_add_item(generic_tree, hf_mac_header_generic_frag_subhd_bsn, tvb, offset, 2, FALSE);
950                                 proto_tree_add_item(generic_tree, hf_mac_header_generic_frag_subhd_rsv_ext, tvb, offset, 2, FALSE);
951                                 /* update the length and offset */
952                                 length -= 2;
953                                 offset += 2;
954                         }
955                         else
956                         {
957                                 if (extended_type)
958                                 {       /* get the sequence number */
959                                         seq_number = (tvb_get_ntohs(tvb, offset) & SEQ_NUMBER_MASK_11) >> 3;
960                                         /* decode and display the header */
961                                         proto_tree_add_item(generic_tree, hf_mac_header_generic_frag_subhd_fc_ext, tvb, offset, 2, FALSE);
962                                         proto_tree_add_item(generic_tree, hf_mac_header_generic_frag_subhd_fsn_ext, tvb, offset, 2, FALSE);
963                                         proto_tree_add_item(generic_tree, hf_mac_header_generic_frag_subhd_rsv_ext, tvb, offset, 2, FALSE);
964                                         /* update the length and offset */
965                                         length -= 2;
966                                         offset += 2;
967                                 }
968                                 else
969                                 {       /* get the sequence number */
970                                         seq_number = (tvb_get_guint8(tvb, offset) & SEQ_NUMBER_MASK) >> 3;
971                                         /* decode and display the header */
972                                         proto_tree_add_item(generic_tree, hf_mac_header_generic_frag_subhd_fc, tvb, offset, 1, FALSE);
973                                         proto_tree_add_item(generic_tree, hf_mac_header_generic_frag_subhd_fsn, tvb, offset, 1, FALSE);
974                                         proto_tree_add_item(generic_tree, hf_mac_header_generic_frag_subhd_rsv, tvb, offset, 1, FALSE);
975                                         /* update the length and offset */
976                                         length -= 1;
977                                         offset += 1;
978                                 }
979                         }
980                         frag_len = length;
981                 }
982                 else    /* ??? default fragment type: no fragment */
983                 {
984                         frag_type = NO_FRAG;
985                 }
986                 /* Decode the MAC payload if there is any */
987                 if (mac_ci)
988                 {
989                         if (length < (gint)sizeof(mac_crc))
990                         {       /* display error message */
991                                 proto_tree_add_protocol_format(tree, proto_mac_header_generic_decoder, tvb, offset, length, "Error - the frame is too short (%u bytes)", length);
992                                 return;
993                         }
994                         length -= sizeof(mac_crc);
995                 }
996                 while (length > 0)
997                 {
998                         frag_len = length; /* Can be changed by Packing subhdr */
999                         if (packing_subheader)
1000                         {
1001                                 packing_length = decode_packing_subheader(tvb, pinfo, tree, length, offset, parent_item);
1002                                 length -= packing_length;
1003                                 offset += packing_length;
1004                                 generic_item = proto_tree_add_protocol_format(tree, proto_mac_header_generic_decoder, tvb, offset, frag_len, "Data transport PDU (%u bytes)", frag_len);
1005                                 /* add payload subtree */
1006                                 generic_tree = proto_item_add_subtree(generic_item, ett_mac_data_pdu_decoder);
1007                                 proto_tree_add_item(generic_tree, hf_mac_header_generic_value_bytes, tvb, offset, frag_len, FALSE);
1008                         }
1009                         /* defragment first if it is fragmented */
1010                         if (frag_type == NO_FRAG)
1011                         {       /* not fragmented payload */
1012                                 payload_tvb =  tvb_new_subset(tvb, offset, frag_len, frag_len);
1013                                 payload_length = frag_len;
1014                                 new_payload_len = frag_len;
1015                         }
1016                         else    /* fragmented payload */
1017                         {       /* add the frag */
1018                                 /* Make sure cid will not match a previous packet with different data */
1019                                 for (i = 0; i < MAX_CID; i++)
1020                                 {
1021                                         if (cid_list[i] == mac_cid)
1022                                         {
1023                                                 cid_base = i * (0xFFFFFFFF / MAX_CID);
1024                                                 break;
1025                                         }
1026                                         if (cid_list[i] == 0)
1027                                         {
1028                                                 cid_list[i] = mac_cid;
1029                                                 cid_base = i * (0xFFFFFFFF / MAX_CID);
1030                                                 break;
1031                                         }
1032                                 }
1033                                 cid_index = i;
1034                                 while (pinfo->fd->num > cid_adj_array_size)
1035                                 {
1036                                         cid_adj_array_size += 1024;
1037                                         cid_adj_array = g_realloc(cid_adj_array, sizeof(guint) * cid_adj_array_size);
1038                                         frag_num_array = g_realloc(frag_num_array, sizeof(guint8) * cid_adj_array_size);
1039                                         /* Clear the added memory */
1040                                         memset(&cid_adj_array[cid_adj_array_size - 1024], 0, sizeof(guint) * 1024);
1041                                 }
1042                                 if (first_gmh)
1043                                 {
1044                                         /* New cid_adjust for each packet with fragment(s) */
1045                                         cid_adjust[cid_index] += cid_vernier[cid_index];
1046                                         /* cid_vernier must always be 0 at start of packet. */
1047                                         cid_vernier[cid_index] = 0;
1048                                 }
1049                                 /* Create artificial sequence numbers. */
1050                                 frag_number[cid_index]++;
1051                                 if (frag_type == FIRST_FRAG)
1052                                 {
1053                                         frag_number[cid_index] = 0;
1054                                 }
1055                                 if (cid_adj_array[pinfo->fd->num])
1056                                 {
1057                                         /* We apparently just clicked on the packet again. */
1058                                         cid_adjust[cid_index] = cid_adj_array[pinfo->fd->num];
1059                                         /* Set the frag_number at start of packet. */
1060                                         if (first_gmh)
1061                                         {
1062                                                 frag_number[cid_index] = frag_num_array[pinfo->fd->num];
1063                                         }
1064                                 } else {
1065                                         /* Save for next time we click on this packet. */
1066                                         cid_adj_array[pinfo->fd->num] = cid_adjust[cid_index];
1067                                         if (first_gmh)
1068                                         {
1069                                                 frag_num_array[pinfo->fd->num] = frag_number[cid_index];
1070                                         }
1071                                 }
1072                                 /* Reset in case we stay in this while() loop to finish the packet. */
1073                                 first_gmh = FALSE;
1074                                 cid = cid_base + cid_adjust[cid_index] + cid_vernier[cid_index];
1075                                 /* Save address pointers. */
1076                                 save_src = pinfo->src;
1077                                 save_dst = pinfo->dst;
1078                                 /* Use dl_src and dl_dst in defrag. */
1079                                 pinfo->src = pinfo->dl_src;
1080                                 pinfo->dst = pinfo->dl_dst;
1081                                 payload_frag = fragment_add_seq(tvb, offset, pinfo, cid, payload_frag_table, frag_number[cid_index], frag_len, ((frag_type==LAST_FRAG)?0:1));
1082                                 /* Restore address pointers. */
1083                                 pinfo->src = save_src;
1084                                 pinfo->dst = save_dst;
1085                                 if (frag_type == LAST_FRAG)
1086                                 {
1087                                         /* Make sure fragment_add_seq() sees next one as a new frame. */
1088                                         cid_vernier[cid_index]++;
1089                                 }
1090                                 /* Don't show reassem packet until last frag. */
1091                                 proto_tree_add_text(tree, tvb, offset, frag_len, "Payload Fragment (%d bytes)", frag_len);
1092
1093                                 if (payload_frag && frag_type == LAST_FRAG)
1094                                 {       /* defragmented completely */
1095                                         payload_length = payload_frag->len;
1096                                         /* create the new tvb for defragmented frame */
1097                                         payload_tvb = tvb_new_child_real_data(tvb, payload_frag->data, payload_length, payload_length);
1098                                         /* add the defragmented data to the data source list */
1099                                         add_new_data_source(pinfo, payload_tvb, "Reassembled WiMax MAC payload");
1100                                         /* save the tvb langth */
1101                                         new_payload_len = payload_length;
1102                                 }
1103                                 else /* error or defragment is not complete */
1104                                 {
1105                                         payload_tvb = NULL;
1106 #ifdef DEBUG    /* for debug only */
1107 /*                                      if (frag_type == LAST_FRAG)*/
1108                                         {       /* error */
1109                                                 /* update the info column */
1110                                                 col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "Dropped the incomplete frame");
1111                                         }
1112 #endif
1113 #if 0
1114                                         if (frag_type == FIRST_FRAG)
1115                                         {       /* Set up to decode the first fragment (even though next fragment not read yet) */
1116                                                 payload_tvb =  tvb_new_subset(tvb, offset, length, length);
1117                                                 payload_length = length;
1118                                                 frag_len = length;
1119                                         }
1120 #endif
1121                                 }
1122                         }
1123                         /* process the defragmented payload */
1124                         if (payload_tvb)
1125                         {       /* reset the payload_offset */
1126                                 payload_offset = 0;
1127                                 /* process the payload */
1128                                 if (payload_length > 0)
1129                                 {
1130                                         if (!new_payload_len)
1131                                                 continue;
1132                                         /* if ARQ Feedback payload is present, it should be the first SDU */
1133                                         if (first_arq_fb_payload && arq_fb_payload)
1134                                         {       /* decode and display the ARQ feedback payload */
1135                                                 first_arq_fb_payload = FALSE;
1136                                                 ret_length = arq_feedback_payload_decoder(tvb_new_subset(payload_tvb, payload_offset, new_payload_len, new_payload_len), pinfo, generic_tree, parent_item);
1137 #ifdef DEBUG /* for debug only */
1138                                                 if (ret_length != new_payload_len)
1139                                                 {       /* error */
1140                                                         /* update the info column */
1141                                                         col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "incorrect ARQ fb payload size");
1142                                                 }
1143 #endif
1144                                         }
1145                                         else    /* decode SDUs */
1146                                         {       /* check the payload type */
1147                                                 if (mac_cid == cid_padding)
1148                                                 {       /* update the info column */
1149                                                         col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "Padding CID");
1150                                                         /* get the parent */
1151                                                         generic_item = proto_tree_get_parent(tree);
1152                                                         /* add the MAC header info */
1153                                                         proto_item_append_text(generic_item, ", Padding CID");
1154                                                         /* display padding CID */
1155                                                         generic_item = proto_tree_add_protocol_format(tree, proto_mac_header_generic_decoder, payload_tvb, payload_offset, new_payload_len, "Padding CID (%u bytes)", new_payload_len);
1156                                                         /* add payload subtree */
1157                                                         generic_tree = proto_item_add_subtree(generic_item, ett_mac_header_generic_decoder);
1158                                                         /* display the Padding CID payload  in Hex */
1159                                                         proto_tree_add_item(generic_tree, hf_mac_header_generic_value_bytes, payload_tvb, payload_offset, new_payload_len, FALSE);
1160                                                 }
1161                                                 else if ((mac_cid <= (2 * global_cid_max_basic)) || (mac_cid == cid_aas_ranging)
1162                                                         || (mac_cid >= cid_normal_multicast))
1163                                                 {       /* MAC management message */
1164                                                         dissect_mac_mgmt_msg_decoder(tvb_new_subset(payload_tvb, payload_offset, new_payload_len, new_payload_len), pinfo, tree);
1165                                                 }
1166                                                 else /* data transport PDU */
1167                                                 {       /* update the info column */
1168                                                         col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "Data");
1169                                                         /* add the MAC payload info */
1170                                                         proto_item_append_text(parent_item, ", Data");
1171                                                         /* display payload info */
1172                                                         if ((new_payload_len + payload_offset) > payload_length)
1173                                                         {
1174                                                                 new_tvb_len = new_payload_len - payload_offset;
1175                                                         }
1176                                                         else
1177                                                         {
1178                                                                 new_tvb_len = new_payload_len;
1179                                                         }
1180                                                         if (frag_type == LAST_FRAG || frag_type == NO_FRAG)
1181                                                         {
1182                                                                 if (frag_type == NO_FRAG)
1183                                                                 {
1184                                                                         str_ptr = data_str;
1185                                                                         new_payload_len = frag_len;
1186                                                                 }
1187                                                                 else
1188                                                                 {
1189                                                                         str_ptr = reassem_str;
1190                                                                 }
1191                                                                 {
1192                                                                 data_pdu_tvb = tvb_new_subset(payload_tvb, payload_offset, new_tvb_len, new_tvb_len);
1193                                                                 generic_item = proto_tree_add_protocol_format(tree, proto_mac_header_generic_decoder, data_pdu_tvb, payload_offset, new_payload_len, str_ptr, new_payload_len);
1194                                                                 /* add payload subtree */
1195                                                                 generic_tree = proto_item_add_subtree(generic_item, ett_mac_data_pdu_decoder);
1196                                                                 /* check the data type */
1197                                                                 if (tvb_get_guint8(payload_tvb, payload_offset) == IP_HEADER_BYTE)
1198                                                                 {
1199                                                                         mac_payload_handle = find_dissector("ip");
1200                                                                         if (mac_payload_handle)
1201                                                                                 call_dissector(mac_payload_handle, tvb_new_subset(payload_tvb, payload_offset, new_tvb_len, new_tvb_len), pinfo, generic_tree);
1202                                                                         else    /* display the Generic MAC Header in Hex */
1203                                                                                 proto_tree_add_item(generic_tree, hf_mac_header_generic_value_bytes, payload_tvb, payload_offset, new_tvb_len, FALSE);
1204                                                                 }
1205                                                                 else    /* display the Generic MAC Header in Hex */
1206                                                                         proto_tree_add_item(generic_tree, hf_mac_header_generic_value_bytes, payload_tvb, payload_offset, new_tvb_len, FALSE);
1207                                                                 }
1208                                                         }
1209                                                 }
1210                                         }
1211                                         payload_length -= new_payload_len;
1212                                         payload_offset += new_payload_len;
1213                                 }       /* end of while loop */
1214                         }       /* end of payload processing */
1215                         length -= frag_len;
1216                         offset += frag_len;
1217                 } /* end of payload decoding */
1218 check_crc:
1219                 /* Decode and display the CRC if it is present */
1220                 if (mac_ci)
1221                 {
1222                         /* add the CRC info */
1223                         proto_item_append_text(parent_item, ", CRC");
1224                         /* check the length */
1225                         if (MIN(tvb_len, tvb_reported_length(tvb)) >= mac_len)
1226                         {       /* get the CRC */
1227                                 mac_crc = tvb_get_ntohl(tvb, mac_len - sizeof(mac_crc));
1228                                 /* calculate the CRC */
1229                     calculated_crc = wimax_mac_calc_crc32(tvb_get_ptr(tvb, 0, mac_len - sizeof(mac_crc)), mac_len - sizeof(mac_crc));
1230                                 /* display the CRC */
1231                                 generic_item = proto_tree_add_item(tree, hf_mac_header_generic_crc, tvb, mac_len - sizeof(mac_crc), sizeof(mac_crc), FALSE);
1232                                 if (mac_crc != calculated_crc)
1233                                 {
1234                                         proto_item_append_text(generic_item, " - incorrect! (should be: 0x%x)", calculated_crc);
1235                                 }
1236                         }
1237                         else
1238                         {       /* display error message */
1239                                 proto_tree_add_protocol_format(tree, proto_mac_header_generic_decoder, tvb, 0, tvb_len, "CRC missing - the frame is too short (%u bytes)", tvb_len);
1240                         }
1241                 }
1242                 else    /* CRC is not included */
1243                 {       /* add the CRC info */
1244                         proto_item_append_text(parent_item, ", No CRC");
1245                         /* display message */
1246                         proto_tree_add_protocol_format(tree, proto_mac_header_generic_decoder, tvb, 0, tvb_len, "CRC is not included in this frame!");
1247                 }
1248         }
1249 }
1250
1251 static gint extended_subheader_decoder(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1252 {
1253         gint offset = 0;
1254         gint length, ext_length, ubyte, i;
1255         proto_item *ti = NULL;
1256         proto_tree *sub_tree = NULL;
1257         proto_tree *ti_tree = NULL;
1258
1259         /* update the info column */
1260         col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "Ext subhdrs");
1261
1262         /* Get the tvb reported length */
1263         length =  tvb_reported_length(tvb);
1264         if (!length)
1265         {       /* display the error message */
1266                 proto_tree_add_protocol_format(tree, proto_mac_header_generic_decoder, tvb, offset, length, "Error: extended subheader tvb is empty ! (%u bytes)", length);
1267                 return length;
1268         }
1269
1270         /* Get the length of the extended subheader group */
1271         ext_length = tvb_get_guint8(tvb, offset);
1272         /* display subheader type */
1273         ti = proto_tree_add_protocol_format(tree, proto_mac_header_generic_decoder, tvb, offset, length, "Extended subheader group (%u bytes)", ext_length);
1274         /* add extended subheader subtree */
1275         sub_tree = proto_item_add_subtree(ti, ett_mac_ext_subheader_decoder);
1276         /* decode and display the extended subheaders */
1277         for (i=1; i<ext_length;)
1278         {       /* Get the extended subheader type */
1279                 ubyte = (tvb_get_guint8(tvb, (offset+i)) & EXTENDED_SUB_HEADER_TYPE_MASK);
1280                 /* decode and display the extended subheader type (MSB) */
1281                 proto_tree_add_item(sub_tree, hf_mac_header_generic_ext_subheader_rsv, tvb, (offset+i), 1, FALSE);
1282                 /* for downlink */
1283                 if (is_down_link(pinfo)) /* for downlink */
1284                 {       /* decode and display the extended subheader type */
1285                         ti = proto_tree_add_item(sub_tree, hf_mac_header_generic_ext_subheader_type_dl, tvb, (offset+i), 1, FALSE);
1286                         /* add subtree */
1287                         ti_tree = proto_item_add_subtree(ti, ett_mac_ext_subheader_dl_decoder);
1288                         i++;
1289                         switch (ubyte)
1290                         {
1291                         case SDU_SN:
1292                                 /* decode and display the extended sdu sn subheader */
1293                                 proto_tree_add_item(ti_tree, hf_mac_header_generic_ext_subheader_sdu_sn, tvb, (offset+i), 1, FALSE);
1294                                 i++;
1295                         break;
1296                         case DL_SLEEP_CONTROL:
1297                                 /* decode and display the extended dl sleep control subheader */
1298                                 proto_tree_add_item(ti_tree, hf_mac_header_generic_ext_subheader_dl_sleep_control_pscid, tvb, (offset+i), 3, FALSE);
1299                                 proto_tree_add_item(ti_tree, hf_mac_header_generic_ext_subheader_dl_sleep_control_op, tvb, (offset+i), 3, FALSE);
1300                                 proto_tree_add_item(ti_tree, hf_mac_header_generic_ext_subheader_dl_sleep_control_fswe, tvb, (offset+i), 3, FALSE);
1301                                 proto_tree_add_item(ti_tree, hf_mac_header_generic_ext_subheader_dl_sleep_control_fswb, tvb, (offset+i), 3, FALSE);
1302                                 proto_tree_add_item(ti_tree, hf_mac_header_generic_ext_subheader_dl_sleep_control_rsv, tvb, (offset+i), 3, FALSE);
1303                                 i += 3;
1304                         break;
1305                         case FEEDBACK_REQ:
1306                                 /* decode and display the extended feedback request subheader */
1307                                 proto_tree_add_item(ti_tree, hf_mac_header_generic_ext_subheader_fb_req_uiuc, tvb, (offset+i), 3, FALSE);
1308                                 proto_tree_add_item(ti_tree, hf_mac_header_generic_ext_subheader_fb_req_fb_type,  tvb, (offset+i), 3, FALSE);
1309                                 proto_tree_add_item(ti_tree, hf_mac_header_generic_ext_subheader_fb_req_ofdma_symbol_offset, tvb, (offset+i), 3, FALSE);
1310                                 proto_tree_add_item(ti_tree, hf_mac_header_generic_ext_subheader_fb_req_subchannel_offset, tvb, (offset+i), 3, FALSE);
1311                                 proto_tree_add_item(ti_tree, hf_mac_header_generic_ext_subheader_fb_req_slots, tvb, (offset+i), 3, FALSE);
1312                                 proto_tree_add_item(ti_tree, hf_mac_header_generic_ext_subheader_fb_req_frame_offset, tvb, (offset+i), 3, FALSE);
1313                                 i += 3;
1314                         break;
1315                         case SN_REQ:
1316                                 /* decode and display the extended SN request subheader */
1317                                 proto_tree_add_item(ti_tree, hf_mac_header_generic_ext_subheader_sn_req_rep_ind_1, tvb, (offset+i), 1, FALSE);
1318                                 proto_tree_add_item(ti_tree, hf_mac_header_generic_ext_subheader_sn_req_rep_ind_2, tvb, (offset+i), 1, FALSE);
1319                                 proto_tree_add_item(ti_tree, hf_mac_header_generic_ext_subheader_sn_req_rsv, tvb, (offset+i), 1, FALSE);
1320                                 i++;
1321                         break;
1322                         case PDU_SN_SHORT_DL:
1323                                 /* decode and display the extended pdu sn (short) subheader */
1324                                 proto_tree_add_item(ti_tree, hf_mac_header_generic_ext_subheader_pdu_sn_short, tvb, (offset+i), 1, FALSE);
1325                                 i++;
1326                         break;
1327                         case PDU_SN_LONG_DL:
1328                                 /* decode and display the extended pdu sn (long) subheader */
1329                                 proto_tree_add_item(ti_tree, hf_mac_header_generic_ext_subheader_pdu_sn_long, tvb, (offset+i), 2, FALSE);
1330                                 i += 2;
1331                         break;
1332                         default: /* reserved */
1333                         break;
1334                         }
1335                 }
1336                 else /* for uplink */
1337                 {       /* decode and display the extended subheader type */
1338                         ti = proto_tree_add_item(sub_tree, hf_mac_header_generic_ext_subheader_type_ul, tvb, (offset+i), 1, FALSE);
1339                         /* add subtree */
1340                         ti_tree = proto_item_add_subtree(ti, ett_mac_ext_subheader_ul_decoder);
1341                         i++;
1342                         switch (ubyte)
1343                         {
1344                         case MIMO_MODE_FEEDBACK:
1345                                 /* decode and display the extended MIMO Mode Feedback subheader */
1346                                 proto_tree_add_item(ti_tree, hf_mac_header_generic_ext_subheader_mimo_mode_fb_type, tvb, (offset+i), 1, FALSE);
1347                                 proto_tree_add_item(ti_tree, hf_mac_header_generic_ext_subheader_mimo_fb_content, tvb, (offset+i), 1, FALSE);
1348                                 i++;
1349                         break;
1350                         case UL_TX_POWER_REPORT:
1351                                 /* decode and display the extended ul tx power report subheader */
1352                                 proto_tree_add_item(ti_tree, hf_mac_header_generic_ext_subheader_ul_tx_pwr_rep, tvb, (offset+i), 1, FALSE);
1353                                 i++;
1354                         break;
1355                         case MINI_FEEDBACK:
1356                                 /* decode and display the extended MINI Feedback subheader */
1357                                 proto_tree_add_item(ti_tree, hf_mac_header_generic_ext_subheader_mini_fb_type, tvb, (offset+i), 2, FALSE);
1358                                 proto_tree_add_item(ti_tree, hf_mac_header_generic_ext_subheader_mini_fb_content, tvb, (offset+i), 2, FALSE);
1359                                 i += 2;
1360                         break;
1361                         case PDU_SN_SHORT_UL:
1362                                 /* decode and display the extended pdu sn (short) subheader */
1363                                 proto_tree_add_item(ti_tree, hf_mac_header_generic_ext_subheader_pdu_sn_short, tvb, (offset+i), 1, FALSE);
1364                                 i++;
1365                         break;
1366                         case PDU_SN_LONG_UL:
1367                                 /* decode and display the extended pdu sn (long) subheader */
1368                                 proto_tree_add_item(ti_tree, hf_mac_header_generic_ext_subheader_pdu_sn_long, tvb, (offset+i), 2, FALSE);
1369                                 i += 2;
1370                         break;
1371                         default: /* reserved */
1372                         break;
1373                         }
1374                 }
1375         }
1376         /* return the extended subheader length */
1377         return ext_length;
1378 }
1379
1380 static gint arq_feedback_payload_decoder(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *parent_item)
1381 {
1382         gint length, i;
1383         gint offset;
1384         gint last_ie = 0;
1385         gint ack_type, num_maps, seq_format;
1386         gint word2, word3;
1387         proto_item *ti = NULL;
1388         proto_item *sub_ti = NULL;
1389         proto_tree *sub_tree = NULL;
1390
1391         /* update the info column */
1392         col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "ARQ feedback payld");
1393
1394         /* add the MAC header info */
1395         proto_item_append_text(parent_item, ", ARQ feedback payload");
1396
1397         /* reset the offset */
1398         offset = 0;
1399
1400         /* Get the tvb reported length */
1401         length =  tvb_reported_length(tvb);
1402         if (!length)
1403         {       /* display the error message */
1404                 proto_tree_add_protocol_format(tree, proto_mac_header_generic_decoder, tvb, offset, length, "Error: ARQ feedback payload tvb is empty ! (%u bytes)", length);
1405                 return length;
1406         }
1407
1408         /* display subheader type */
1409         ti = proto_tree_add_protocol_format(tree, proto_mac_header_generic_decoder, tvb, offset, length, "ARQ feedback payload ");
1410         /* add extended subheader subtree */
1411         sub_tree = proto_item_add_subtree(ti, ett_mac_arq_fb_payload_decoder);
1412         /* decode and display the ARQ Feedback IEs */
1413         while (!last_ie)
1414         {       /* decode and display CID */
1415                 proto_tree_add_item(sub_tree, hf_mac_header_generic_arq_fb_ie_cid, tvb, offset, 2, FALSE);
1416                 /* move to next 16-bit word */
1417                 offset += 2;
1418                 /* Get the 2nd 16-bit */
1419                 word2 = tvb_get_ntohs(tvb, offset);
1420                 /* get the last bit */
1421                 last_ie = (word2 & ARQ_FB_IE_LAST_BIT_MASK);
1422                 /* get the ACK type */
1423                 ack_type = ((word2 & ARQ_FB_IE_ACK_TYPE_MASK) >> 13);
1424                 /* get the number of ACK maps */
1425                 num_maps = (word2 & ARQ_FB_IE_NUM_MAPS_MASK) + 1;
1426                 /* decode and display the 2nd word */
1427                 proto_tree_add_item(sub_tree, hf_mac_header_generic_arq_fb_ie_last, tvb, offset, 2, FALSE);
1428                 proto_tree_add_item(sub_tree, hf_mac_header_generic_arq_fb_ie_ack_type, tvb, offset, 2, FALSE);
1429                 proto_tree_add_item(sub_tree, hf_mac_header_generic_arq_fb_ie_bsn, tvb, offset, 2, FALSE);
1430                 /* decode and display the 3rd word */
1431                 if (ack_type != 1)
1432                 {
1433                         sub_ti = proto_tree_add_item(sub_tree, hf_mac_header_generic_arq_fb_ie_num_maps, tvb, offset, 2, FALSE);
1434                         /* move to next 16-bit word */
1435                         offset += 2;
1436                         proto_item_append_text(sub_ti, " (%d map(s))", num_maps);
1437                         for (i = 0; i < num_maps; i++)
1438                         {
1439                                 if (ack_type != 3)
1440                                 {
1441                                         proto_tree_add_item(sub_tree, hf_mac_header_generic_arq_fb_ie_sel_ack_map, tvb, offset, 2, FALSE);
1442                                 }
1443                                 else
1444                                 {       /* Get the next 16-bit */
1445                                         word3 = tvb_get_ntohs(tvb, offset);
1446                                         /* get the sequence format */
1447                                         seq_format = (word3 & ARQ_FB_IE_SEQ_FORMAT_MASK);
1448                                         /* decode and display the sequence format */
1449                                         proto_tree_add_item(sub_tree, hf_mac_header_generic_arq_fb_ie_seq_format, tvb, offset, 2, FALSE);
1450                                         if (!seq_format)
1451                                         {
1452                                                 proto_tree_add_item(sub_tree, hf_mac_header_generic_arq_fb_ie_seq_ack_map_2, tvb, offset, 2, FALSE);
1453                                                 proto_tree_add_item(sub_tree, hf_mac_header_generic_arq_fb_ie_seq1_length_6, tvb, offset, 2, FALSE);
1454                                                 proto_tree_add_item(sub_tree, hf_mac_header_generic_arq_fb_ie_seq2_length_6, tvb, offset, 2, FALSE);
1455                                                 proto_tree_add_item(sub_tree, hf_mac_header_generic_arq_fb_ie_rsv, tvb, offset, 2, FALSE);
1456                                         }
1457                                         else
1458                                         {
1459                                                 proto_tree_add_item(sub_tree, hf_mac_header_generic_arq_fb_ie_seq_ack_map, tvb, offset, 2, FALSE);
1460                                                 proto_tree_add_item(sub_tree, hf_mac_header_generic_arq_fb_ie_seq1_length, tvb, offset, 2, FALSE);
1461                                                 proto_tree_add_item(sub_tree, hf_mac_header_generic_arq_fb_ie_seq2_length, tvb, offset, 2, FALSE);
1462                                                 proto_tree_add_item(sub_tree, hf_mac_header_generic_arq_fb_ie_seq3_length, tvb, offset, 2, FALSE);
1463                                         }
1464                                 }
1465                                 /* move to next 16-bit word */
1466                                 offset += 2;
1467                         }
1468                 }
1469                 else
1470                 {
1471                         /* Number of ACK Maps bits are reserved when ACK TYPE == 1 */
1472                         proto_tree_add_item(sub_tree, hf_ack_type_reserved, tvb, offset, 2, FALSE);
1473                         /* move to next 16-bit word */
1474                         offset += 2;
1475                 }
1476         }
1477         /* append text */
1478         proto_item_append_text(ti,"(%u bytes)", offset);
1479         /* return the offset */
1480         return offset;
1481 }
1482
1483 /* Register Wimax Generic Mac Header Protocol and Dissector */
1484 void proto_register_mac_header_generic(void)
1485 {
1486         /* Generic MAC header display */
1487         static hf_register_info hf[] =
1488         {
1489                 {
1490                         &hf_mac_header_generic_value_bytes,
1491                         {
1492                                 "Values", "wmx.genericValueBytes",
1493                                 FT_BYTES, BASE_NONE, NULL, 0x0,
1494                                 NULL, HFILL
1495                         }
1496                 },
1497                 {
1498                         &hf_mac_header_generic_ht,
1499                         {
1500                                 "MAC Header Type", "wmx.genericHt",
1501                                 FT_UINT24, BASE_HEX, VALS(ht_msgs), WIMAX_MAC_HEADER_GENERIC_HT,
1502                                 NULL, HFILL
1503                         }
1504                 },
1505                 {
1506                         &hf_mac_header_generic_ec,
1507                         {
1508                                 "MAC Encryption Control", "wmx.genericEc",
1509                                 FT_UINT24, BASE_HEX, VALS(ec_msgs), WIMAX_MAC_HEADER_GENERIC_EC,
1510                                 NULL, HFILL
1511                         }
1512                 },
1513                 {
1514                         &hf_mac_header_generic_type_0,
1515                         {
1516                                 "MAC Sub-type Bit 0", "wmx.genericType0",
1517                                 FT_UINT24, BASE_HEX, VALS(type_msg0), WIMAX_MAC_HEADER_GENERIC_TYPE_0,
1518                                 NULL, HFILL
1519                         }
1520                 },
1521                 {
1522                         &hf_mac_header_generic_type_1,
1523                         {
1524                                 "MAC Sub-type Bit 1", "wmx.genericType1",
1525                                 FT_UINT24, BASE_HEX, VALS(type_msg1), WIMAX_MAC_HEADER_GENERIC_TYPE_1,
1526                                 NULL, HFILL
1527                         }
1528                 },
1529                 {
1530                         &hf_mac_header_generic_type_2,
1531                         {
1532                                 "MAC Sub-type Bit 2", "wmx.genericType2",
1533                                 FT_UINT24, BASE_HEX, VALS(type_msg2), WIMAX_MAC_HEADER_GENERIC_TYPE_2,
1534                                 NULL, HFILL
1535                         }
1536                 },
1537                 {
1538                         &hf_mac_header_generic_type_3,
1539                         {
1540                                 "MAC Sub-type Bit 3", "wmx.genericType3",
1541                                 FT_UINT24, BASE_HEX, VALS(type_msg3), WIMAX_MAC_HEADER_GENERIC_TYPE_3,
1542                                 NULL, HFILL
1543                         }
1544                 },
1545                 {
1546                         &hf_mac_header_generic_type_4,
1547                         {
1548                                 "MAC Sub-type Bit 4", "wmx.genericType4",
1549                                 FT_UINT24, BASE_HEX, VALS(type_msg4), WIMAX_MAC_HEADER_GENERIC_TYPE_4,
1550                                 NULL, HFILL
1551                         }
1552                 },
1553                 {
1554                         &hf_mac_header_generic_type_5,
1555                         {
1556                                 "MAC Sub-type Bit 5", "wmx.genericType5",
1557                                 FT_UINT24, BASE_HEX, VALS(type_msg5), WIMAX_MAC_HEADER_GENERIC_TYPE_5,
1558                                 NULL, HFILL
1559                         }
1560                 },
1561                 {
1562                         &hf_mac_header_generic_esf,
1563                         {
1564                                 "Extended Sub-header Field", "wmx.genericEsf",
1565                                 FT_UINT24, BASE_HEX, VALS(esf_msgs), WIMAX_MAC_HEADER_GENERIC_ESF,
1566                                 NULL, HFILL
1567                         }
1568                 },
1569                 {
1570                         &hf_mac_header_generic_ci,
1571                         {
1572                                 "CRC Indicator", "wmx.genericCi",
1573                                 FT_UINT24, BASE_HEX, VALS(ci_msgs), WIMAX_MAC_HEADER_GENERIC_CI,
1574                                 NULL, HFILL
1575                         }
1576                 },
1577                 {
1578                         &hf_mac_header_generic_eks,
1579                         {
1580                                 "Encryption Key Sequence", "wmx.genericEks",
1581                                 FT_UINT24, BASE_HEX, NULL, WIMAX_MAC_HEADER_GENERIC_EKS,
1582                                 NULL, HFILL
1583                         }
1584                 },
1585                 {
1586                         &hf_mac_header_generic_rsv,
1587                         {
1588                                 "Reserved", "wmx.genericRsv",
1589                                 FT_UINT24, BASE_DEC, NULL, WIMAX_MAC_HEADER_GENERIC_RSV,
1590                                 NULL, HFILL
1591                         }
1592                 },
1593                 {
1594                         &hf_mac_header_generic_len,
1595                         {
1596                                 "Length", "wmx.genericLen",
1597                                 FT_UINT24, BASE_DEC, NULL, WIMAX_MAC_HEADER_GENERIC_LEN,
1598                                 NULL, HFILL
1599                         }
1600                 },
1601                 {
1602                         &hf_mac_header_generic_cid,
1603                         {
1604                                 "Connection ID", "wmx.genericCid",
1605                                 FT_UINT16, BASE_DEC, NULL, 0x0,
1606                                 NULL, HFILL
1607                         }
1608                 },
1609                 {
1610                         &hf_mac_header_generic_hcs,
1611                         {
1612                                 "Header Check Sequence", "wmx.genericHcs",
1613                                 FT_UINT8, BASE_HEX, NULL, 0x0,
1614                                 NULL, HFILL
1615                         }
1616                 },
1617                 {
1618                         &hf_mac_header_generic_crc,
1619                         {
1620                                 "CRC", "wmx.genericCrc",
1621                                 FT_UINT32, BASE_HEX, NULL, 0x0,
1622                                 NULL, HFILL
1623                         }
1624                 }
1625         };
1626
1627         /* Extended Subheader display */
1628         static hf_register_info hf_ext[] =
1629         {
1630                 {
1631                         &hf_mac_header_generic_ext_subheader_rsv,
1632                         {
1633                                 "Reserved", "wmx.genericExtSubhd.Rsv",
1634                                 FT_UINT8, BASE_DEC, NULL, EXTENDED_SUB_HEADER_RSV_MASK,
1635                                 NULL, HFILL
1636                         }
1637                 },
1638                 {
1639                         &hf_mac_header_generic_ext_subheader_type_dl,
1640                         {
1641                                 "DL Extended Subheader Type", "wmx.genericExtSubhd.Dl",
1642                                 FT_UINT8, BASE_DEC, VALS(dl_ext_sub_header_type), EXTENDED_SUB_HEADER_TYPE_MASK,
1643                                 NULL, HFILL
1644                         }
1645                 },
1646                 {
1647                         &hf_mac_header_generic_ext_subheader_type_ul,
1648                         {
1649                                 "UL Extended Subheader Type", "wmx.genericExtSubhd.Ul",
1650                                 FT_UINT8, BASE_DEC, VALS(ul_ext_sub_header_type), EXTENDED_SUB_HEADER_TYPE_MASK,
1651                                 NULL, HFILL
1652                         }
1653                 },
1654                 {
1655                         &hf_mac_header_generic_ext_subheader_sdu_sn,
1656                         {
1657                                 "SDU Sequence Number", "wmx.genericExtSubhd.SduSn",
1658                                 FT_UINT8, BASE_DEC, NULL, 0x0,
1659                                 NULL, HFILL
1660                         }
1661                 },
1662                 {
1663                         &hf_mac_header_generic_ext_subheader_dl_sleep_control_pscid,
1664                         {
1665                                 "Power Saving Class ID", "wmx.genericExtSubhd.DlSleepCtrlPSCID",
1666                                 FT_UINT24, BASE_DEC, NULL, DL_SLEEP_CONTROL_POWER_SAVING_CLASS_ID_MASK,
1667                                 NULL, HFILL
1668                         }
1669                 },
1670                 {
1671                         &hf_mac_header_generic_ext_subheader_dl_sleep_control_op,
1672                         {
1673                                 "Operation", "wmx.genericExtSubhd.DlSleepCtrlOP",
1674                                 FT_UINT24, BASE_HEX, VALS(dl_sleep_control_ops), DL_SLEEP_CONTROL_OPERATION_MASK,
1675                                 NULL, HFILL
1676                         }
1677                 },
1678                 {
1679                         &hf_mac_header_generic_ext_subheader_dl_sleep_control_fswe,
1680                         {
1681                                 "Final Sleep Window Exponent", "wmx.genericExtSubhd.DlSleepCtrlFSWE",
1682                                 FT_UINT24, BASE_DEC, NULL, DL_SLEEP_CONTROL_FINAL_SLEEP_WINDOW_EXPONENT_MASK,
1683                                 NULL, HFILL
1684                         }
1685                 },
1686                 {
1687                         &hf_mac_header_generic_ext_subheader_dl_sleep_control_fswb,
1688                         {
1689                                 "Final Sleep Window Base", "wmx.genericExtSubhd.DlSleepCtrlFSWB",
1690                                 FT_UINT24, BASE_DEC, NULL, DL_SLEEP_CONTROL_FINAL_SLEEP_WINDOW_BASE_MASK,
1691                                 NULL, HFILL
1692                         }
1693                 },
1694                 {
1695                         &hf_mac_header_generic_ext_subheader_dl_sleep_control_rsv,
1696                         {
1697                                 "Reserved", "wmx.genericExtSubhd.DlSleepCtrlRsv",
1698                                 FT_UINT24, BASE_DEC, NULL, DL_SLEEP_CONTROL_RESERVED_MASK,
1699                                 NULL, HFILL
1700                         }
1701                 },
1702                 {
1703                         &hf_mac_header_generic_ext_subheader_fb_req_uiuc,
1704                         {
1705                                 "UIUC", "wmx.genericExtSubhd.FbReqUIUC",
1706                                 FT_UINT24, BASE_HEX, VALS(uiuc_values), FEEDBACK_REQUEST_UIUC_MASK,
1707                                 NULL, HFILL
1708                         }
1709                 },
1710                 {
1711                         &hf_mac_header_generic_ext_subheader_fb_req_fb_type,
1712                         {
1713                                 "Feedback Type", "wmx.genericExtSubhd.FbReqFbType",
1714                                 FT_UINT24, BASE_HEX, VALS(fb_types), FEEDBACK_REQUEST_FEEDBACK_TYPE_MASK,
1715                                 NULL, HFILL
1716                         }
1717                 },
1718                 {
1719                         &hf_mac_header_generic_ext_subheader_fb_req_ofdma_symbol_offset,
1720                         {
1721                                 "OFDMA Symbol Offset", "wmx.genericExtSubhd.FbReqOfdmaSymbolOffset",
1722                                 FT_UINT24, BASE_HEX, NULL, FEEDBACK_REQUEST_OFDMA_SYMBOL_OFFSET_MASK,
1723                                 NULL, HFILL
1724                         }
1725                 },
1726                 {
1727                         &hf_mac_header_generic_ext_subheader_fb_req_subchannel_offset,
1728                         {
1729                                 "Subchannel Offset", "wmx.genericExtSubhd.FbReqSubchannelOffset",
1730                                 FT_UINT24, BASE_HEX, NULL, FEEDBACK_REQUEST_SUBCHANNEL_OFFSET_MASK,
1731                                 NULL, HFILL
1732                         }
1733                 },
1734                 {
1735                         &hf_mac_header_generic_ext_subheader_fb_req_slots,
1736                         {
1737                                 "Number of Slots", "wmx.genericExtSubhd.FbReqSlots",
1738                                 FT_UINT24, BASE_HEX, NULL, FEEDBACK_REQUEST_NUMBER_OF_SLOTS_MASK,
1739                                 NULL, HFILL
1740                         }
1741                 },
1742                 {
1743                         &hf_mac_header_generic_ext_subheader_fb_req_frame_offset,
1744                         {
1745                                 "Frame Offset", "wmx.genericExtSubhd.FbReqFrameOffset",
1746                                 FT_UINT24, BASE_HEX, NULL, FEEDBACK_REQUEST_FRAME_OFFSET_MASK,
1747                                 NULL, HFILL
1748                         }
1749                 },
1750                 {
1751                         &hf_mac_header_generic_ext_subheader_sn_req_rep_ind_1,
1752                         {
1753                                 "First SN Report Indication", "wmx.genericExtSubhd.SnReqRepInd1",
1754                                 FT_UINT8, BASE_DEC, VALS(sn_rep_msg), SN_REQUEST_SUBHEADER_SN_REPORT_INDICATION_1_MASK,
1755                                 NULL, HFILL
1756                         }
1757                 },
1758                 {
1759                         &hf_mac_header_generic_ext_subheader_sn_req_rep_ind_2,
1760                         {
1761                                 "Second SN Report Indication", "wmx.genericExtSubhd.SnReqRepInd2",
1762                                 FT_UINT8, BASE_DEC, VALS(sn_rep_msg), SN_REQUEST_SUBHEADER_SN_REPORT_INDICATION_2_MASK,
1763                                 NULL, HFILL
1764                         }
1765                 },
1766                 {
1767                         &hf_mac_header_generic_ext_subheader_sn_req_rsv,
1768                         {
1769                                 "Reserved", "wmx.genericExtSubhd.SnReqRsv",
1770                                 FT_UINT8, BASE_DEC, NULL, SN_REQUEST_SUBHEADER_RESERVED_MASK,
1771                                 NULL, HFILL
1772                         }
1773                 },
1774                 {
1775                         &hf_mac_header_generic_ext_subheader_mimo_mode_fb_type,
1776                         {
1777                                 "Feedback Type", "wmx.genericExtSubhd.MimoFbType",
1778                                 FT_UINT8, BASE_DEC, VALS(mimo_fb_types), MIMO_FEEDBACK_TYPE_MASK,
1779                                 NULL, HFILL
1780                         }
1781                 },
1782                 {
1783                         &hf_mac_header_generic_ext_subheader_mimo_fb_content,
1784                         {
1785                                 "Feedback Content", "wmx.genericExtSubhd.MimoFbContent",
1786                                 FT_UINT8, BASE_DEC, NULL, MIMO_FEEDBACK_CONTENT_MASK,
1787                                 NULL, HFILL
1788                         }
1789                 },
1790                 {
1791                         &hf_mac_header_generic_ext_subheader_ul_tx_pwr_rep,
1792                         {
1793                                 "UL TX Power", "wmx.genericExtSubhd.UlTxPwr",
1794                                 FT_UINT8, BASE_DEC, NULL, 0x0,
1795                                 NULL, HFILL
1796                         }
1797                 },
1798                 {
1799                         &hf_mac_header_generic_ext_subheader_mini_fb_type,
1800                         {
1801                                 "Feedback Type", "wmx.genericExtSubhd.MiniFbType",
1802                                 FT_UINT16, BASE_DEC, VALS(fb_types), MINI_FEEDBACK_TYPE_MASK,
1803                                 NULL, HFILL
1804                         }
1805                 },
1806                 {
1807                         &hf_mac_header_generic_ext_subheader_mini_fb_content,
1808                         {
1809                                 "Feedback Content", "wmx.genericExtSubhd.MiniFbContent",
1810                                 FT_UINT16, BASE_DEC, NULL, MINI_FEEDBACK_CONTENT_MASK,
1811                                 NULL, HFILL
1812                         }
1813                 },
1814                 {
1815                         &hf_mac_header_generic_ext_subheader_pdu_sn_short,
1816                         {
1817                                 "PDU Sequence Number", "wmx.genericExtSubhd.PduSnShort",
1818                                 FT_UINT8, BASE_DEC, NULL, 0x0,
1819                                 NULL, HFILL
1820                         }
1821                 },
1822                 {
1823                         &hf_mac_header_generic_ext_subheader_pdu_sn_long,
1824                         {
1825                                 "PDU Sequence Number", "wmx.genericExtSubhd.PduSnLong",
1826                                 FT_UINT16, BASE_DEC, NULL, 0x0,
1827                                 NULL, HFILL
1828                         }
1829                 }
1830         };
1831
1832         /* Mesh Subheader display */
1833         static hf_register_info hf_mesh[] =
1834         {
1835                 {
1836                         &hf_mac_header_generic_mesh_subheader,
1837                         {
1838                                 "Xmt Node Id", "wmx.genericMeshSubhd",
1839                                 FT_UINT16, BASE_DEC, NULL, 0x0,
1840                                 NULL, HFILL
1841                         }
1842                 }
1843         };
1844
1845         /* Fragmentation Subheader display */
1846         static hf_register_info hf_frag[] =
1847         {
1848                 {
1849                         &hf_mac_header_generic_frag_subhd_fc,
1850                         {
1851                                 "Fragment Type", "wmx.genericFragSubhd.Fc",
1852                                 FT_UINT8, BASE_DEC, VALS(frag_types), FRAGMENTATION_SUBHEADER_FC_MASK,
1853                                 NULL, HFILL
1854                         }
1855                 },
1856                 {
1857                         &hf_mac_header_generic_frag_subhd_fc_ext,
1858                         {
1859                                 "Fragment Type", "wmx.genericFragSubhd.FcExt",
1860                                 FT_UINT16, BASE_DEC, VALS(frag_types), FRAGMENTATION_SUBHEADER_FC_MASK,
1861                                 NULL, HFILL
1862                         }
1863                 },
1864                 {
1865                         &hf_mac_header_generic_frag_subhd_bsn,
1866                         {
1867                                 "Block Sequence Number (BSN)", "wmx.genericFragSubhd.Bsn",
1868                                 FT_UINT16, BASE_DEC, NULL, FRAGMENTATION_SUBHEADER_BSN_MASK,
1869                                 NULL, HFILL
1870                         }
1871                 },
1872                 {
1873                         &hf_mac_header_generic_frag_subhd_fsn,
1874                         {
1875                                 "Fragment Sequence Number (FSN)", "wmx.genericFragSubhd.Fsn",
1876                                 FT_UINT8, BASE_DEC, NULL, FRAGMENTATION_SUBHEADER_FSN_MASK,
1877                                 NULL, HFILL
1878                         }
1879                 },
1880                 {
1881                         &hf_mac_header_generic_frag_subhd_fsn_ext,
1882                         {
1883                                 "Fragment Sequence Number (FSN)", "wmx.genericFragSubhd.FsnExt",
1884                                 FT_UINT16, BASE_DEC, NULL, FRAGMENTATION_SUBHEADER_BSN_MASK,
1885                                 NULL, HFILL
1886                         }
1887                 },
1888                 {
1889                         &hf_mac_header_generic_frag_subhd_rsv,
1890                         {
1891                                 "Reserved", "wmx.genericFragSubhd.Rsv",
1892                                 FT_UINT8, BASE_DEC, NULL, FRAGMENTATION_SUBHEADER_RSV_MASK,
1893                                 NULL, HFILL
1894                         }
1895                 },
1896                 {
1897                         &hf_mac_header_generic_frag_subhd_rsv_ext,
1898                         {
1899                                 "Reserved", "wmx.genericFragSubhd.RsvExt",
1900                                 FT_UINT16, BASE_DEC, NULL, FRAGMENTATION_SUBHEADER_RSV_EXT_MASK,
1901                                 NULL, HFILL
1902                         }
1903                 }
1904         };
1905
1906         /* Packing Subheader display */
1907         static hf_register_info hf_pack[] =
1908         {
1909                 {
1910                         &hf_mac_header_generic_packing_subhd_fc,
1911                         {
1912                                 "Fragment Type", "wmx.genericPackSubhd.Fc",
1913                                 FT_UINT16, BASE_DEC, VALS(frag_types), PACKING_SUBHEADER_FC_MASK,
1914                                 NULL, HFILL
1915                         }
1916                 },
1917                 {
1918                         &hf_mac_header_generic_packing_subhd_fc_ext,
1919                         {
1920                                 "Fragment Type", "wmx.genericPackSubhd.FcExt",
1921                                 FT_UINT24, BASE_HEX, VALS(frag_types), PACKING_SUBHEADER_FC_MASK,
1922                                 NULL, HFILL
1923                         }
1924                 },
1925                 {
1926                         &hf_mac_header_generic_packing_subhd_bsn,
1927                         {
1928                                 "First Block Sequence Number", "wmx.genericPackSubhd.Bsn",
1929                                 FT_UINT24, BASE_DEC, NULL, PACKING_SUBHEADER_BSN_MASK,
1930                                 NULL, HFILL
1931                         }
1932                 },
1933                 {
1934                         &hf_mac_header_generic_packing_subhd_fsn,
1935                         {
1936                                 "Fragment Number", "wmx.genericPackSubhd.Fsn",
1937                                 FT_UINT16, BASE_DEC, NULL, PACKING_SUBHEADER_FSN_MASK,
1938                                 NULL, HFILL
1939                         }
1940                 },
1941                 {
1942                         &hf_mac_header_generic_packing_subhd_fsn_ext,
1943                         {
1944                                 "Fragment Number", "wmx.genericPackSubhd.FsnExt",
1945                                 FT_UINT24, BASE_DEC, NULL, PACKING_SUBHEADER_BSN_MASK,
1946                                 NULL, HFILL
1947                         }
1948                 },
1949                 {
1950                         &hf_mac_header_generic_packing_subhd_len,
1951                         {
1952                                 "Length", "wmx.genericPackSubhd.Len",
1953                                 FT_UINT16, BASE_DEC, NULL, PACKING_SUBHEADER_LENGTH_MASK,
1954                                 NULL, HFILL
1955                         }
1956                 },
1957                 {
1958                         &hf_mac_header_generic_packing_subhd_len_ext,
1959                         {
1960                                 "Length", "wmx.genericPackSubhd.LenExt",
1961                                 FT_UINT24, BASE_DEC, NULL, PACKING_SUBHEADER_LENGTH_EXT_MASK,
1962                                 NULL, HFILL
1963                         }
1964                 }
1965         };
1966
1967         /* Fast-feedback Allocation Subheader display */
1968         static hf_register_info hf_fast[] =
1969         {
1970                 {
1971                         &hf_mac_header_generic_fast_fb_subhd_alloc_offset,
1972                         {
1973                                 "Allocation Offset", "wmx.genericFastFbSubhd.AllocOffset",
1974                                 FT_UINT8, BASE_DEC, NULL, FAST_FEEDBACK_ALLOCATION_OFFSET_MASK,
1975                                 NULL, HFILL
1976                         }
1977                 },
1978                 {
1979                         &hf_mac_header_generic_fast_fb_subhd_fb_type,
1980                         {
1981                                 "Feedback Type", "wmx.genericFastFbSubhd.FbType",
1982                                 FT_UINT8, BASE_DEC, VALS(fast_fb_types), FAST_FEEDBACK_FEEDBACK_TYPE_MASK,
1983                                 NULL, HFILL
1984                         }
1985                 }
1986         };
1987
1988         /* Grant Management Subheader display */
1989         static hf_register_info hf_grant[] =
1990         {
1991                 {
1992                         &hf_mac_header_generic_grant_mgmt_ext_pbr_tree,
1993                         {
1994                                 "Scheduling Service Type (Default)",
1995                                 "wimax.genericGrantSubhd.Default",
1996                                 FT_UINT16, BASE_DEC, NULL, 0x0,
1997                                 NULL, HFILL
1998                         }
1999                 },
2000                 {
2001                         &hf_mac_header_generic_grant_mgmt_subhd_pbr,
2002                         {
2003                                 "PiggyBack Request", "wmx.genericGrantSubhd.Pbr",
2004                                 FT_UINT16, BASE_DEC, NULL, 0x0,
2005                                 NULL, HFILL
2006                         }
2007                 },
2008                 {
2009                         &hf_mac_header_generic_grant_mgmt_ugs_tree,
2010                         {
2011                                 "Scheduling Service Type (UGS)", "wmx.genericGrantSubhd.UGS",
2012                                 FT_UINT16, BASE_DEC, NULL, 0x0,
2013                                 NULL, HFILL
2014                         }
2015                 },
2016                 {
2017                         &hf_mac_header_generic_grant_mgmt_subhd_ugs_si,
2018                         {
2019                                 "Slip Indicator", "wmx.genericGrantSubhd.Si",
2020                                 FT_UINT16, BASE_DEC, VALS(si_msgs), GRANT_MGMT_SUBHEADER_UGS_SI_MASK,
2021                                 NULL, HFILL
2022                         }
2023                 },
2024                 {
2025                         &hf_mac_header_generic_grant_mgmt_subhd_ugs_pm,
2026                         {
2027                                 "Poll-Me", "wmx.genericGrantSubhd.Pm",
2028                                 FT_UINT16, BASE_DEC, VALS(pm_msgs), GRANT_MGMT_SUBHEADER_UGS_PM_MASK,
2029                                 NULL, HFILL
2030                         }
2031                 },
2032                 {
2033                         &hf_mac_header_generic_grant_mgmt_subhd_ugs_fli,
2034                         {
2035                                 "Frame Latency Indication", "wmx.genericGrantSubhd.Fli",
2036                                 FT_UINT16, BASE_DEC, VALS(fli_msgs), GRANT_MGMT_SUBHEADER_UGS_FLI_MASK,
2037                                 NULL, HFILL
2038                         }
2039                 },
2040                 {
2041                         &hf_mac_header_generic_grant_mgmt_subhd_ugs_fl,
2042                         {
2043                                 "Frame Latency", "wmx.genericGrantSubhd.Fl",
2044                                 FT_UINT16, BASE_DEC, NULL, GRANT_MGMT_SUBHEADER_UGS_FL_MASK,
2045                                 NULL, HFILL
2046                         }
2047                 },
2048                 {
2049                         &hf_mac_header_generic_grant_mgmt_subhd_ugs_rsv,
2050                         {
2051                                 "Reserved", "wmx.genericGrantSubhd.Rsv",
2052                                 FT_UINT16, BASE_DEC, NULL, GRANT_MGMT_SUBHEADER_UGS_RSV_MASK,
2053                                 NULL, HFILL
2054                         }
2055                 },
2056                 {
2057                         &hf_mac_header_generic_grant_mgmt_ext_rtps_tree,
2058                         {
2059                                 "Scheduling Service Type (Extended rtPS)",
2060                                 "wimax.genericGrantSubhd.ExtendedRTPS",
2061                                 FT_UINT16, BASE_DEC, NULL, 0x0,
2062                                 NULL, HFILL
2063                         }
2064                 },
2065                 {
2066                         &hf_mac_header_generic_grant_mgmt_subhd_ext_pbr,
2067                         {
2068                                 "Extended PiggyBack Request", "wmx.genericGrantSubhd.ExtPbr",
2069                                 FT_UINT16, BASE_DEC, NULL, GRANT_MGMT_SUBHEADER_EXT_PBR_MASK,
2070                                 NULL, HFILL
2071                         }
2072                 },
2073                 {
2074                         &hf_mac_header_generic_grant_mgmt_subhd_ext_fli,
2075                         {
2076                                 "Frame Latency Indication", "wmx.genericGrantSubhd.ExtFli",
2077                                 FT_UINT16, BASE_DEC, VALS(fli_msgs), GRANT_MGMT_SUBHEADER_EXT_FLI_MASK,
2078                                 NULL, HFILL
2079                         }
2080                 },
2081                 {
2082                         &hf_mac_header_generic_grant_mgmt_subhd_ext_fl,
2083                         {
2084                                 "Frame Latency", "wmx.genericGrantSubhd.ExtFl",
2085                                 FT_UINT16, BASE_DEC, NULL, GRANT_MGMT_SUBHEADER_EXT_FL_MASK,
2086                                 NULL, HFILL
2087                         }
2088                 }
2089         };
2090
2091         /* ARQ Feedback Payload display */
2092         static hf_register_info hf_arq[] =
2093         {
2094                 {
2095                         &hf_mac_header_generic_arq_fb_ie_cid,
2096                         {
2097                                 "CID", "wmx.genericArq.FbIeCid",
2098                                 FT_UINT16, BASE_DEC, NULL, 0x0,
2099                                 NULL, HFILL
2100                         }
2101                 },
2102                 {
2103                         &hf_mac_header_generic_arq_fb_ie_last,
2104                         {
2105                                 "Last IE", "wmx.genericArq.FbIeLast",
2106                                 FT_UINT16, BASE_DEC, VALS(last_ie_msgs), ARQ_FB_IE_LAST_BIT_MASK,
2107                                 NULL, HFILL
2108                         }
2109                 },
2110                 {
2111                         &hf_mac_header_generic_arq_fb_ie_ack_type,
2112                         {
2113                                 "ACK Type", "wmx.genericArq.FbIeAckType",
2114                                 FT_UINT16, BASE_DEC, NULL, ARQ_FB_IE_ACK_TYPE_MASK,
2115                                 NULL, HFILL
2116                         }
2117                 },
2118                 {
2119                         &hf_mac_header_generic_arq_fb_ie_bsn,
2120                         {
2121                                 "BSN", "wmx.genericArq.FbIeBsn",
2122                                 FT_UINT16, BASE_DEC, NULL, ARQ_FB_IE_BSN_MASK,
2123                                 NULL, HFILL
2124                         }
2125                 },
2126                 {
2127                         &hf_mac_header_generic_arq_fb_ie_num_maps,
2128                         {
2129                                 "Number of ACK Maps", "wmx.genericArq.FbIeMaps",
2130                                 FT_UINT16, BASE_DEC, NULL, ARQ_FB_IE_NUM_MAPS_MASK,
2131                                 NULL, HFILL
2132                         }
2133                 },
2134                 {
2135                         &hf_ack_type_reserved,
2136                         {
2137                                 "Reserved", "wmx.genericArq.FbIeRsvd", FT_UINT16, BASE_DEC, NULL, 0x03, NULL, HFILL
2138                         }
2139                 },
2140                 {
2141                         &hf_mac_header_generic_arq_fb_ie_sel_ack_map,
2142                         {
2143                                 "Selective ACK Map", "wmx.genericArq.FbIeSelAckMap",
2144                                 FT_UINT16, BASE_HEX, NULL, 0x0,
2145                                 NULL, HFILL
2146                         }
2147                 },
2148                 {
2149                         &hf_mac_header_generic_arq_fb_ie_seq_format,
2150                         {
2151                                 "Sequence Format", "wmx.genericArq.FbIeSeqFmt",
2152                                 FT_UINT16, BASE_DEC, NULL, ARQ_FB_IE_SEQ_FORMAT_MASK,
2153                                 NULL, HFILL
2154                         }
2155                 },
2156                 {
2157                         &hf_mac_header_generic_arq_fb_ie_seq_ack_map,
2158                         {
2159                                 "Sequence ACK Map", "wmx.genericArq.FbIeSeqAckMap",
2160                                 FT_UINT16, BASE_HEX, NULL, ARQ_FB_IE_SEQ_ACK_MAP_MASK,
2161                                 NULL, HFILL
2162                         }
2163                 },
2164                 {
2165                         &hf_mac_header_generic_arq_fb_ie_seq1_length,
2166                         {
2167                                 "Sequence 1 Length", "wmx.genericArq.FbIeSeq1Len",
2168                                 FT_UINT16, BASE_DEC, NULL, ARQ_FB_IE_SEQ1_LENGTH_MASK,
2169                                 NULL, HFILL
2170                         }
2171                 },
2172                 {
2173                         &hf_mac_header_generic_arq_fb_ie_seq2_length,
2174                         {
2175                                 "Sequence 2 Length", "wmx.genericArq.FbIeSeq2Len",
2176                                 FT_UINT16, BASE_DEC, NULL, ARQ_FB_IE_SEQ2_LENGTH_MASK,
2177                                 NULL, HFILL
2178                         }
2179                 },
2180                 {
2181                         &hf_mac_header_generic_arq_fb_ie_seq3_length,
2182                         {
2183                                 "Sequence 3 Length", "wmx.genericArq.FbIeSeq3Len",
2184                                 FT_UINT16, BASE_DEC, NULL, ARQ_FB_IE_SEQ3_LENGTH_MASK,
2185                                 NULL, HFILL
2186                         }
2187                 },
2188                 {
2189                         &hf_mac_header_generic_arq_fb_ie_seq_ack_map_2,
2190                         {
2191                                 "Sequence ACK Map", "wmx.genericArq.FbIeSeqAckMap2",
2192                                 FT_UINT16, BASE_HEX, NULL, ARQ_FB_IE_SEQ_ACK_MAP_2_MASK,
2193                                 NULL, HFILL
2194                         }
2195                 },
2196                 {
2197                         &hf_mac_header_generic_arq_fb_ie_seq1_length_6,
2198                         {
2199                                 "Sequence 1 Length", "wmx.genericArq.FbIeSeq1Len",
2200                                 FT_UINT16, BASE_DEC, NULL, ARQ_FB_IE_SEQ1_LENGTH_6_MASK,
2201                                 NULL, HFILL
2202                         }
2203                 },
2204                 {
2205                         &hf_mac_header_generic_arq_fb_ie_seq2_length_6,
2206                         {
2207                                 "Sequence 2 Length", "wmx.genericArq.FbIeSeq2Len",
2208                                 FT_UINT16, BASE_DEC, NULL, ARQ_FB_IE_SEQ2_LENGTH_6_MASK,
2209                                 NULL, HFILL
2210                         }
2211                 },
2212                 {
2213                         &hf_mac_header_generic_arq_fb_ie_rsv,
2214                         {
2215                                 "Reserved", "wmx.genericArq.FbIeRsv",
2216                                 FT_UINT16, BASE_DEC, NULL, ARQ_FB_IE_RSV_MASK,
2217                                 NULL, HFILL
2218                         }
2219                 }
2220         };
2221
2222         /* Setup protocol subtree array */
2223         static gint *ett[] =
2224                 {
2225                         &ett_mac_header_generic_decoder,
2226                         /* &ett_mac_subheader_decoder, */
2227                         &ett_mac_mesh_subheader_decoder,
2228                         &ett_mac_frag_subheader_decoder,
2229                         &ett_mac_grant_mgmt_subheader_decoder,
2230                         &ett_mac_pkt_subheader_decoder,
2231                         &ett_mac_fast_fb_subheader_decoder,
2232                         &ett_mac_ext_subheader_decoder,
2233                         &ett_mac_ext_subheader_dl_decoder,
2234                         &ett_mac_ext_subheader_ul_decoder,
2235                         &ett_mac_arq_fb_payload_decoder,
2236                         &ett_mac_data_pdu_decoder,
2237                 };
2238
2239         proto_mac_header_generic_decoder = proto_register_protocol (
2240                 "WiMax Generic/Type1/Type2 MAC Header Messages", /* name       */
2241                 "WiMax Generic/Type1/Type2 MAC Header (hdr)",    /* short name */
2242                 "wmx.hdr"                                        /* abbrev     */
2243                 );
2244
2245         /* register the field display messages */
2246         proto_register_field_array(proto_mac_header_generic_decoder, hf,       array_length(hf));
2247         proto_register_field_array(proto_mac_header_generic_decoder, hf_ext,   array_length(hf_ext));
2248         proto_register_field_array(proto_mac_header_generic_decoder, hf_mesh,  array_length(hf_mesh));
2249         proto_register_field_array(proto_mac_header_generic_decoder, hf_frag,  array_length(hf_frag));
2250         proto_register_field_array(proto_mac_header_generic_decoder, hf_pack,  array_length(hf_pack));
2251         proto_register_field_array(proto_mac_header_generic_decoder, hf_fast,  array_length(hf_fast));
2252         proto_register_field_array(proto_mac_header_generic_decoder, hf_grant, array_length(hf_grant));
2253         proto_register_field_array(proto_mac_header_generic_decoder, hf_arq,   array_length(hf_arq));
2254         proto_register_subtree_array(ett, array_length(ett));
2255
2256         /* register the generic mac header dissector */
2257         register_dissector("mac_header_generic_handler", dissect_mac_header_generic_decoder, proto_mac_header_generic_decoder);
2258         /* register the mac payload dissector */
2259         proto_register_mac_mgmt_msg();
2260         /* Register the payload fragment table init routine */
2261         register_init_routine(wimax_defragment_init);
2262 }