Use ENC_NA as proto_tree_add_item() encoding arg for FT_ETHER hf[] field type.
[obnox/wireshark/wip.git] / plugins / wimax / msg_rng_req.c
1 /* msg_rng_req.c
2  * WiMax MAC Management RNG-REQ Message decoder
3  *
4  * Copyright (c) 2007 by Intel Corporation.
5  *
6  * Author: John R. Underwood <junderx@yahoo.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 /* Include files */
30
31 #ifdef HAVE_CONFIG_H
32 #include "config.h"
33 #endif
34
35 #include <glib.h>
36 #include <epan/packet.h>
37 #include "crc.h"
38 #include "wimax_tlv.h"
39 #include "wimax_mac.h"
40 #include "wimax_utils.h"
41
42 extern gint proto_wimax;
43 extern gboolean include_cor2_changes;
44
45 extern gint man_ofdma;
46
47 gint proto_mac_mgmt_msg_rng_req_decoder = -1;
48 static gint ett_mac_mgmt_msg_rng_req_decoder = -1;
49
50 /* RNG-REQ fields */
51 static gint hf_rng_req_message_type                          = -1;
52 static gint hf_rng_req_reserved                              = -1;
53 static gint hf_rng_req_dl_burst_profile_diuc                 = -1;
54 static gint hf_rng_req_dl_burst_profile_lsb_ccc              = -1;
55 static gint hf_rng_req_ss_mac_address                        = -1;
56 static gint hf_rng_req_ranging_anomalies_max_power           = -1;
57 static gint hf_rng_req_ranging_anomalies_min_power           = -1;
58 static gint hf_rng_req_ranging_anomalies_timing_adj          = -1;
59 static gint hf_rng_req_aas_broadcast                         = -1;
60 static gint hf_rng_req_serving_bs_id                         = -1;
61 static gint hf_rng_req_ranging_purpose_ho_indication         = -1;
62 static gint hf_rng_req_ranging_purpose_location_update_request = -1;
63 static gint hf_rng_req_ranging_purpose_reserved              = -1;
64 static gint hf_rng_req_ho_id                                 = -1;
65 static gint hf_rng_req_power_down_indicator                  = -1;
66 static gint hf_rng_req_repetition_coding_level               = -1;
67 static gint hf_rng_req_requested_downlink_repetition_coding_level_reserved     = -1;
68 static gint hf_rng_req_cmac_key_count                        = -1;
69 static gint hf_rng_definition_of_power_saving_class_present  = -1;
70 static gint hf_rng_activation_of_power_saving_class          = -1;
71 static gint hf_rng_trf_ind_required                          = -1;
72 static gint hf_rng_power_saving_class_reserved               = -1;
73 static gint hf_rng_power_saving_class_id                     = -1;
74 static gint hf_rng_power_saving_class_type                   = -1;
75 static gint hf_rng_power_saving_first_sleep_window_frame     = -1;
76 static gint hf_rng_power_saving_initial_sleep_window         = -1;
77 static gint hf_rng_power_saving_listening_window             = -1;
78 static gint hf_rng_power_saving_final_sleep_window_base      = -1;
79 static gint hf_rng_power_saving_final_sleep_window_exp       = -1;
80 static gint hf_rng_power_saving_slpid                        = -1;
81 static gint hf_rng_power_saving_included_cid                 = -1;
82 static gint hf_rng_power_saving_mgmt_connection_direction    = -1;
83 static gint hf_tlv_type                                      = -1;
84 static gint hf_rng_invalid_tlv                               = -1;
85
86 /* STRING RESOURCES */
87
88 static const true_false_string tfs_rng_req_aas_broadcast = {
89     "SS cannot receive broadcast messages",
90     "SS can receive broadcast messages"
91 };
92
93 static const value_string vals_rng_req_ranging_purpose_location_update_request[] = {
94         {1,     "MS action of Idle Mode Location Update Process"},
95         {0,     NULL}
96 };
97
98 static const value_string vals_rng_req_repetition_coding_level[] = {
99         {0,     "No repetition"},
100         {1,     "Repetition coding of 2"},
101         {2,     "Repetition coding of 4"},
102         {3,     "Repetition coding of 6"},
103         {0,     NULL}
104 };
105
106 static const true_false_string tfs_rng_activate = {
107     "Activate",
108     "Deactivate"
109 };
110
111 static const true_false_string tfs_rng_max_power = {
112     "SS is already at maximum power",
113     "SS is not at maximum power"
114 };
115
116 static const true_false_string tfs_rng_min_power = {
117     "SS is already at minimum power",
118     "SS is not at minimum power"
119 };
120
121 static const true_false_string tfs_rng_timing_adj = {
122     "Sum of commanded timing adjustments is too large",
123     "Sum of commanded timing adjustments is within bounds"
124 };
125
126 /* Decode RNG Power Saving Class parameters (Sub TLV's). */
127 void dissect_power_saving_class(proto_tree *rng_req_tree, gint tlv_type, tvbuff_t *tvb, guint compound_tlv_len, packet_info *pinfo, guint offset)
128 {
129         proto_item *tlv_item = NULL;
130         proto_tree *tlv_tree = NULL;
131         proto_tree *power_saving_class_tree = NULL;
132         guint tlv_len;
133         guint tlv_offset;
134         tlv_info_t tlv_info;
135
136         /* Add a subtree for the power saving class parameters */
137         tlv_item = proto_tree_add_protocol_format(rng_req_tree, proto_mac_mgmt_msg_rng_req_decoder, tvb, offset, compound_tlv_len, "Power saving class parameters (%u bytes)", compound_tlv_len);
138         power_saving_class_tree = proto_item_add_subtree(tlv_item, ett_mac_mgmt_msg_rng_req_decoder);
139
140         /* Update the compound_tlv_len to include the offset */
141         compound_tlv_len += offset;
142
143         while(offset < compound_tlv_len)
144         {
145                 /* Get the TLV data. */
146                 init_tlv_info(&tlv_info, tvb, offset);
147                 /* get the TLV type */
148                 tlv_type = get_tlv_type(&tlv_info);
149                 /* get the TLV length */
150                 tlv_len = get_tlv_length(&tlv_info);
151                 if(tlv_type == -1 || tlv_len > MAX_TLV_LEN || tlv_len < 1)
152                 {       /* invalid tlv info */
153                         col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "RNG-REQ TLV error");
154                         proto_tree_add_item(power_saving_class_tree, hf_rng_invalid_tlv, tvb, offset, (compound_tlv_len - offset), ENC_NA);
155                         break;
156                 }
157                 /* get the offset to the TLV data */
158                 tlv_offset = offset + get_tlv_value_offset(&tlv_info);
159
160                 switch (tlv_type) {
161                         case RNG_POWER_SAVING_CLASS_FLAGS:
162                                 /* display Power Saving Class Flags */
163                                 /* add subtree */
164                                 tlv_tree = add_protocol_subtree(&tlv_info, ett_mac_mgmt_msg_rng_req_decoder, power_saving_class_tree, proto_mac_mgmt_msg_rng_req_decoder, tvb, tlv_offset, tlv_len, "Power Saving Class (%u byte)", tlv_len);
165                                 proto_tree_add_item(tlv_tree, hf_rng_definition_of_power_saving_class_present, tvb, tlv_offset, 1, ENC_BIG_ENDIAN);
166                                 proto_tree_add_item(tlv_tree, hf_rng_activation_of_power_saving_class, tvb, tlv_offset, 1, ENC_BIG_ENDIAN);
167                                 proto_tree_add_item(tlv_tree, hf_rng_trf_ind_required, tvb, tlv_offset, 1, ENC_BIG_ENDIAN);
168                                 proto_tree_add_item(tlv_tree, hf_rng_power_saving_class_reserved, tvb, tlv_offset, 1, ENC_BIG_ENDIAN);
169                                 break;
170                         case RNG_POWER_SAVING_CLASS_ID:
171                                 tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_rng_req_decoder, power_saving_class_tree, hf_rng_power_saving_class_id, tvb, tlv_offset, 1, FALSE);
172                                 proto_tree_add_item(tlv_tree, hf_rng_power_saving_class_id, tvb, tlv_offset, 1, ENC_BIG_ENDIAN);
173                                 break;
174                         case RNG_POWER_SAVING_CLASS_TYPE:
175                                 tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_rng_req_decoder, power_saving_class_tree, hf_rng_power_saving_class_type, tvb, tlv_offset, 1, FALSE);
176                                 proto_tree_add_item(tlv_tree, hf_rng_power_saving_class_type, tvb, tlv_offset, 1, ENC_BIG_ENDIAN);
177                                 break;
178                         case RNG_START_FRAME_NUMBER:
179                                 tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_rng_req_decoder, power_saving_class_tree, hf_rng_power_saving_first_sleep_window_frame, tvb, tlv_offset, 1, FALSE);
180                                 proto_tree_add_item(tlv_tree, hf_rng_power_saving_first_sleep_window_frame, tvb, tlv_offset, 1, ENC_BIG_ENDIAN);
181                                 break;
182                         case RNG_INITIAL_SLEEP_WINDOW:
183                                 tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_rng_req_decoder, power_saving_class_tree, hf_rng_power_saving_initial_sleep_window, tvb, tlv_offset, 1, FALSE);
184                                 proto_tree_add_item(tlv_tree, hf_rng_power_saving_initial_sleep_window, tvb, tlv_offset, 1, ENC_BIG_ENDIAN);
185                                 break;
186                         case RNG_LISTENING_WINDOW:
187                                 tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_rng_req_decoder, power_saving_class_tree, hf_rng_power_saving_listening_window, tvb, tlv_offset, 1, FALSE);
188                                 proto_tree_add_item(tlv_tree, hf_rng_power_saving_listening_window, tvb, tlv_offset, 1, ENC_BIG_ENDIAN);
189                                 break;
190                         case RNG_FINAL_SLEEP_WINDOW_BASE:
191                                 tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_rng_req_decoder, power_saving_class_tree, hf_rng_power_saving_final_sleep_window_base, tvb, tlv_offset, 1, FALSE);
192                                 proto_tree_add_item(tlv_tree, hf_rng_power_saving_final_sleep_window_base, tvb, tlv_offset, 1, ENC_BIG_ENDIAN);
193                                 break;
194                         case RNG_FINAL_SLEEP_WINDOW_EXPONENT:
195                                 tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_rng_req_decoder, power_saving_class_tree, hf_rng_power_saving_final_sleep_window_exp, tvb, tlv_offset, 1, FALSE);
196                                 proto_tree_add_item(tlv_tree, hf_rng_power_saving_final_sleep_window_exp, tvb, tlv_offset, 1, ENC_BIG_ENDIAN);
197                                 break;
198                         case RNG_SLPID:
199                                 tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_rng_req_decoder, power_saving_class_tree, hf_rng_power_saving_slpid, tvb, tlv_offset, 1, FALSE);
200                                 proto_tree_add_item(tlv_tree, hf_rng_power_saving_slpid, tvb, tlv_offset, 1, ENC_BIG_ENDIAN);
201                                 break;
202                         case RNG_CID:
203                                 tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_rng_req_decoder, power_saving_class_tree, hf_rng_power_saving_included_cid, tvb, tlv_offset, 2, FALSE);
204                                 proto_tree_add_item(tlv_tree, hf_rng_power_saving_included_cid, tvb, tlv_offset, 2, ENC_BIG_ENDIAN);
205                                 break;
206                         case RNG_DIRECTION:
207                                 tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_rng_req_decoder, power_saving_class_tree, hf_rng_power_saving_mgmt_connection_direction, tvb, tlv_offset, 1, FALSE);
208                                 proto_tree_add_item(tlv_tree, hf_rng_power_saving_mgmt_connection_direction, tvb, tlv_offset, 1, ENC_BIG_ENDIAN);
209                                 break;
210                         default:
211                                 tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_rng_req_decoder, power_saving_class_tree, hf_tlv_type, tvb, tlv_offset, tlv_len, FALSE);
212                                 proto_tree_add_item(tlv_tree, hf_tlv_type, tvb, tlv_offset, tlv_len, ENC_NA);
213                                 break;
214                 }
215                 /* update the offset */
216                 offset = tlv_len + tlv_offset;
217         }       /* end of TLV process while loop */
218 }
219
220
221 /* Decode RNG-REQ messages. */
222 void dissect_mac_mgmt_msg_rng_req_decoder(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
223 {
224         guint offset = 0;
225         guint tlv_offset;
226         guint tvb_len, payload_type;
227         proto_item *rng_req_item = NULL;
228         proto_tree *rng_req_tree = NULL;
229         proto_tree *tlv_tree = NULL;
230         tlv_info_t tlv_info;
231         gint tlv_type;
232         gint tlv_len;
233
234         /* Ensure the right payload type */
235         payload_type = tvb_get_guint8(tvb, offset);
236         if(payload_type != MAC_MGMT_MSG_RNG_REQ)
237         {
238                 return;
239         }
240
241         if (tree)
242         {       /* we are being asked for details */
243
244                 /* Get the tvb reported length */
245                 tvb_len =  tvb_reported_length(tvb);
246                 /* display MAC payload type RNG-REQ */
247                 rng_req_item = proto_tree_add_protocol_format(tree, proto_mac_mgmt_msg_rng_req_decoder, tvb, offset, tvb_len, "MAC Management Message, RNG-REQ (4)");
248                 /* add MAC RNG-REQ subtree */
249                 rng_req_tree = proto_item_add_subtree(rng_req_item, ett_mac_mgmt_msg_rng_req_decoder);
250                 /* display the Message Type */
251                 proto_tree_add_item(rng_req_tree, hf_rng_req_message_type, tvb, offset, 1, ENC_BIG_ENDIAN);
252                 proto_tree_add_item(rng_req_tree, hf_rng_req_reserved, tvb, 1, 1, ENC_BIG_ENDIAN);
253                 offset += 2;
254
255                 while(offset < tvb_len)
256                 {
257                         /* Get the TLV data. */
258                         init_tlv_info(&tlv_info, tvb, offset);
259                         /* get the TLV type */
260                         tlv_type = get_tlv_type(&tlv_info);
261                         /* get the TLV length */
262                         tlv_len = get_tlv_length(&tlv_info);
263                         if(tlv_type == -1 || tlv_len > MAX_TLV_LEN || tlv_len < 1)
264                         {       /* invalid tlv info */
265                                 col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "RNG-REQ TLV error");
266                                 proto_tree_add_item(rng_req_tree, hf_rng_invalid_tlv, tvb, offset, (tvb_len - offset), ENC_NA);
267                                 break;
268                         }
269                         /* get the offset to the TLV data */
270                         tlv_offset = offset + get_tlv_value_offset(&tlv_info);
271
272                         switch (tlv_type) {
273                                 case RNG_REQ_DL_BURST_PROFILE:
274                                         /* add TLV subtree */
275                                         tlv_tree = add_protocol_subtree(&tlv_info, ett_mac_mgmt_msg_rng_req_decoder, rng_req_tree, proto_mac_mgmt_msg_rng_req_decoder, tvb, tlv_offset, tlv_len, "Requested Downlink Burst Profile 0x%02x", tvb_get_guint8(tvb, tlv_offset));
276                                         proto_tree_add_item(tlv_tree, hf_rng_req_dl_burst_profile_diuc, tvb, tlv_offset, 1, ENC_BIG_ENDIAN);
277                                         proto_tree_add_item(tlv_tree, hf_rng_req_dl_burst_profile_lsb_ccc, tvb, tlv_offset, 1, ENC_BIG_ENDIAN);
278                                         break;
279                                 case RNG_REQ_SS_MAC_ADDRESS:
280                                         tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_rng_req_decoder, rng_req_tree, hf_rng_req_ss_mac_address, tvb, tlv_offset, 6, FALSE);
281                                         proto_tree_add_item(tlv_tree, hf_rng_req_ss_mac_address, tvb, tlv_offset, 6, ENC_NA);
282                                         break;
283                                 case RNG_REQ_RANGING_ANOMALIES:
284                                         /* add TLV subtree */
285                                         tlv_tree = add_protocol_subtree(&tlv_info, ett_mac_mgmt_msg_rng_req_decoder, rng_req_tree, proto_mac_mgmt_msg_rng_req_decoder, tvb, tlv_offset, tlv_len, "Ranging Anomalies %d", tvb_get_guint8(tvb, tlv_offset));
286                                         proto_tree_add_item(tlv_tree, hf_rng_req_ranging_anomalies_max_power, tvb, tlv_offset, 1, ENC_BIG_ENDIAN);
287                                         proto_tree_add_item(tlv_tree, hf_rng_req_ranging_anomalies_min_power, tvb, tlv_offset, 1, ENC_BIG_ENDIAN);
288                                         proto_tree_add_item(tlv_tree, hf_rng_req_ranging_anomalies_timing_adj, tvb, tlv_offset, 1, ENC_BIG_ENDIAN);
289                                         break;
290                                 case RNG_REQ_AAS_BROADCAST:
291                                         tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_rng_req_decoder, rng_req_tree, hf_rng_req_aas_broadcast, tvb, tlv_offset, 1, FALSE);
292                                         proto_tree_add_item(tlv_tree, hf_rng_req_aas_broadcast, tvb, tlv_offset, 1, ENC_BIG_ENDIAN);
293                                         break;
294                                 case RNG_REQ_SERVING_BS_ID:
295                                         tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_rng_req_decoder, rng_req_tree, hf_rng_req_serving_bs_id, tvb, tlv_offset, 6, FALSE);
296                                         proto_tree_add_item(tlv_tree, hf_rng_req_serving_bs_id, tvb, tlv_offset, 6, ENC_NA);
297                                         break;
298                                 case RNG_REQ_RANGING_PURPOSE_INDICATION:
299                                         /* display the Ranging Purpose Flags */
300                                         /* add subtree */
301                                         tlv_tree = add_protocol_subtree(&tlv_info, ett_mac_mgmt_msg_rng_req_decoder, rng_req_tree, proto_mac_mgmt_msg_rng_req_decoder, tvb, tlv_offset, tlv_len, "Ranging Purpose Flags (%u byte(s))", tlv_len);
302                                         proto_tree_add_item(tlv_tree, hf_rng_req_ranging_purpose_ho_indication, tvb, tlv_offset, 1, ENC_BIG_ENDIAN);
303                                         proto_tree_add_item(tlv_tree, hf_rng_req_ranging_purpose_location_update_request, tvb, tlv_offset, 1, ENC_BIG_ENDIAN);
304                                         proto_tree_add_item(tlv_tree, hf_rng_req_ranging_purpose_reserved, tvb, tlv_offset, 1, ENC_BIG_ENDIAN);
305                                         break;
306                                 case RNG_REQ_HO_ID:
307                                         tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_rng_req_decoder, rng_req_tree, hf_rng_req_ho_id, tvb, tlv_offset, 1, FALSE);
308                                         proto_tree_add_item(tlv_tree, hf_rng_req_ho_id, tvb, tlv_offset, 1, ENC_BIG_ENDIAN);
309                                         break;
310                                 case RNG_REQ_POWER_DOWN_INDICATOR:
311                                         tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_rng_req_decoder, rng_req_tree, hf_rng_req_power_down_indicator, tvb, tlv_offset, 1, FALSE);
312                                         proto_tree_add_item(tlv_tree, hf_rng_req_power_down_indicator, tvb, tlv_offset, 1, ENC_BIG_ENDIAN);
313                                         break;
314                                 case RNG_REQ_REQUESTED_DNLK_REP_CODING_LEVEL:
315                                         /* add subtree */
316                                         tlv_tree = add_protocol_subtree(&tlv_info, ett_mac_mgmt_msg_rng_req_decoder, rng_req_tree, proto_mac_mgmt_msg_rng_req_decoder, tvb, tlv_offset, tlv_len, "Requested downlink repetition coding level (%u byte(s))", tlv_len);
317                                         proto_tree_add_item(tlv_tree, hf_rng_req_repetition_coding_level, tvb, tlv_offset, 1, ENC_BIG_ENDIAN);
318                                         proto_tree_add_item(tlv_tree, hf_rng_req_requested_downlink_repetition_coding_level_reserved, tvb, tlv_offset, 1, ENC_BIG_ENDIAN);
319                                         break;
320                                 case RNG_REQ_CMAC_KEY_COUNT:
321                                         if (include_cor2_changes) {
322                                                 tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_rng_req_decoder, rng_req_tree, hf_rng_req_cmac_key_count, tvb, tlv_offset, tlv_len, FALSE);
323                                                 proto_tree_add_item(tlv_tree, hf_rng_req_cmac_key_count, tvb, tlv_offset, 2, ENC_BIG_ENDIAN);
324                                         } else {
325                                                 /* Unknown TLV type */
326                                                 tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_rng_req_decoder, rng_req_tree, hf_tlv_type, tvb, tlv_offset, tlv_len, FALSE);
327                                                 proto_tree_add_item(tlv_tree, hf_tlv_type, tvb, tlv_offset, tlv_len, ENC_NA);
328                                         }
329                                         break;
330                                 case SHORT_HMAC_TUPLE:
331                                 case SHORT_HMAC_TUPLE_COR2:
332                                         if ((!include_cor2_changes && (tlv_type == SHORT_HMAC_TUPLE)) ||
333                                                 (include_cor2_changes && (tlv_type == SHORT_HMAC_TUPLE_COR2))) {
334                                                 /* decode and display the Short HMAC Tuple */
335                                                 tlv_tree = add_protocol_subtree(&tlv_info, ett_mac_mgmt_msg_rng_req_decoder, rng_req_tree, proto_mac_mgmt_msg_rng_req_decoder, tvb, tlv_offset, tlv_len, "Short HMAC Tuple (%u byte(s))", tlv_len);
336                                                 wimax_short_hmac_tuple_decoder(tlv_tree, tvb, tlv_offset, tvb_len - offset);
337                                         } else {
338                                                 /* Unknown TLV Type */
339                                                 tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_rng_req_decoder, rng_req_tree, hf_tlv_type, tvb, tlv_offset, tlv_len, FALSE);
340                                                 proto_tree_add_item(tlv_tree, hf_tlv_type, tvb, tlv_offset, tlv_len, ENC_NA);
341                                         }
342                                         break;
343                                 case MAC_VERSION_ENCODING:
344                                         offset += wimax_common_tlv_encoding_decoder(tvb_new_subset(tvb, offset, (tvb_len - offset), (tvb_len - offset)), pinfo, rng_req_tree);
345                                         continue;
346                                         break;
347                                 case RNG_REQ_POWER_SAVING_CLASS_PARAMETERS:
348                                         tlv_tree = add_protocol_subtree(&tlv_info, ett_mac_mgmt_msg_rng_req_decoder, rng_req_tree, proto_mac_mgmt_msg_rng_req_decoder, tvb, tlv_offset, tlv_len, "Power Saving Class Parameters (%u byte(s))", tlv_len);
349                                         dissect_power_saving_class(tlv_tree, tlv_type, tvb, tlv_len, pinfo, tlv_offset);
350                                         break;
351                                 default:
352                                         tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_rng_req_decoder, rng_req_tree, hf_tlv_type, tvb, tlv_offset, tlv_len, FALSE);
353                                         proto_tree_add_item(tlv_tree, hf_tlv_type, tvb, tlv_offset, tlv_len, ENC_NA);
354                                         break;
355                         }
356                         /* update the offset */
357                         offset = tlv_len + tlv_offset;
358                 }       /* end of TLV process while loop */
359         }
360 }
361
362 /* Register Wimax Mac Payload Protocol and Dissector */
363 void proto_register_mac_mgmt_msg_rng_req(void)
364 {
365         /* RNG-REQ fields display */
366         static hf_register_info hf[] =
367         {
368                 {
369                         &hf_rng_activation_of_power_saving_class,
370                         {
371                                 "Activation of Power Saving Class (Types 1 and 2 only)", "wmx.rng.power_save.activate",
372                                 FT_BOOLEAN, 8, TFS(&tfs_rng_activate), 0x02, NULL, HFILL
373                         }
374                 },
375                 {
376                         &hf_rng_power_saving_class_id,
377                         {
378                                 "Power Saving Class ID", "wmx.rng.power_save.class_id",
379                                 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL
380                         }
381                 },
382                 {
383                         &hf_rng_power_saving_class_type,
384                         {
385                                 "Power Saving Class Type", "wmx.rng.power_save.class_type",
386                                 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL
387                         }
388                 },
389                 {
390                         &hf_rng_definition_of_power_saving_class_present,
391                         {
392                                 "Definition of Power Saving Class present", "wmx.rng.power_save.definition_present",
393                                 FT_UINT8, BASE_DEC, NULL, 0x01, NULL, HFILL
394                         }
395                 },
396                 {
397                         &hf_rng_power_saving_final_sleep_window_base,
398                         {
399                                 "Final-sleep window base (measured in frames)", "wmx.rng.power_save.final_sleep_window_base",
400                                 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL
401                         }
402                 },
403                 {
404                         &hf_rng_power_saving_final_sleep_window_exp,
405                         {
406                                 "Final-sleep window exponent (measured in frames)", "wmx.rng.power_save.final_sleep_window_exp",
407                                 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL
408                         }
409                 },
410                 {
411                         &hf_rng_power_saving_first_sleep_window_frame,
412                         {
413                                 "Start frame number for first sleep window", "wmx.rng.power_save.first_sleep_window_frame",
414                                 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL
415                         }
416                 },
417                 {
418                         &hf_rng_power_saving_included_cid,
419                         {
420                                 "CID of connection to be included into the Power Saving Class.", "wmx.rng.power_save.included_cid",
421                                 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL
422                         }
423                 },
424                 {
425                         &hf_rng_power_saving_initial_sleep_window,
426                         {
427                                 "Initial-sleep window", "wmx.rng.power_save.initial_sleep_window",
428                                 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL
429                         }
430                 },
431                 {
432                         &hf_rng_power_saving_listening_window,
433                         {
434                                 "Listening window duration (measured in frames)", "wmx.rng.power_save.listening_window",
435                                 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL
436                         }
437                 },
438                 {
439                         &hf_rng_power_saving_mgmt_connection_direction,
440                         {
441                                 "Direction for management connection added to Power Saving Class", "wmx.rng.power_save.mgmt_connection_direction",
442                                 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL
443                         }
444                 },
445                 {
446                         &hf_rng_power_saving_class_reserved,
447                         {
448                                 "Reserved", "wmx.rng.power_save.reserved",
449                                 FT_UINT8, BASE_DEC, NULL, 0xF8, NULL, HFILL
450                         }
451                 },
452                 {
453                         &hf_rng_power_saving_slpid,
454                         {
455                                 "SLPID assigned by the BS whenever an MS is instructed to enter sleep mode", "wmx.rng.power_save.slpid",
456                                 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL
457                         }
458                 },
459                 {
460                         &hf_rng_trf_ind_required,
461                         {
462                                 "BS shall transmit at least one TRF-IND message during each listening window of the Power Saving Class", "wmx.rng.power_save.trf_ind_required",
463                                 FT_BOOLEAN, 8, TFS(&tfs_rng_activate), 0x04, NULL, HFILL
464                         }
465                 },
466                 {
467                         &hf_rng_req_message_type,
468                         {
469                                 "MAC Management Message Type", "wmx.macmgtmsgtype.rng_req",
470                                 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL
471                         }
472                 },
473                 {
474                         &hf_rng_req_aas_broadcast,
475                         {
476                                 "AAS broadcast capability", "wmx.rng_req.aas_broadcast",
477                                 FT_BOOLEAN, BASE_NONE, TFS(&tfs_rng_req_aas_broadcast), 0x0, NULL, HFILL
478                         }
479                 },
480                 {
481                         &hf_rng_req_ranging_anomalies_max_power,
482                         {
483                                 "Meaning", "wmx.rng_req.anomalies.max_power",
484                                 FT_BOOLEAN, 8, TFS(&tfs_rng_max_power), 0x04, NULL, HFILL
485                         }
486                 },
487                 {
488                         &hf_rng_req_ranging_anomalies_min_power,
489                         {
490                                 "Meaning", "wmx.rng_req.anomalies.min_power",
491                                 FT_BOOLEAN, 8, TFS(&tfs_rng_min_power), 0x02, NULL, HFILL
492                         }
493                 },
494                 {
495                         &hf_rng_req_ranging_anomalies_timing_adj,
496                         {
497                                 "Meaning", "wmx.rng_req.anomalies.timing_adj",
498                                 FT_BOOLEAN, 8, TFS(&tfs_rng_timing_adj), 0x01, NULL, HFILL
499                         }
500                 },
501                 {
502                         &hf_rng_req_cmac_key_count,
503                         {
504                                 "CMAC Key Count", "wmx.rng_req.cmac_key_count",
505                                 FT_UINT16, BASE_DEC, NULL, 0x00, NULL, HFILL
506                         }
507                 },
508                 {
509                         &hf_rng_req_dl_burst_profile_lsb_ccc,
510                         {
511                                 "LSB of CCC of DCD associated with DIUC", "wmx.rng_req.dl_burst_profile.ccc",
512                                 FT_UINT8, BASE_DEC, NULL, 0xF0, NULL, HFILL
513                         }
514                 },
515                 {
516                         &hf_rng_req_dl_burst_profile_diuc,
517                         {
518                                 "DIUC", "wmx.rng_req.dl_burst_profile.diuc",
519                                 FT_UINT8, BASE_DEC, NULL, 0x0F, NULL, HFILL
520                         }
521                 },
522                 {
523                         &hf_tlv_type,
524                         {
525                                 "Unknown TLV Type", "wmx.rng_req.unknown_tlv_type",
526                                 FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL
527                         }
528                 },
529                 {
530                         &hf_rng_invalid_tlv,
531                         {
532                                 "Invalid TLV", "wmx.rng_req.invalid_tlv",
533                                 FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL
534                         }
535                 },
536                 {
537                         &hf_rng_req_ho_id,
538                         {
539                                 "ID from the target BS for use in initial ranging during MS handover to it", "wmx.rng_req.ho_id",
540                                 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL
541                         }
542                 },
543                 {
544                         &hf_rng_req_power_down_indicator,
545                         {
546                                 "Power down Indicator", "wmx.rng_req.power_down_indicator",
547                                 FT_UINT8, BASE_DEC, NULL, 0x00, NULL, HFILL
548                         }
549                 },
550                 {
551                         &hf_rng_req_ranging_purpose_ho_indication,
552                         {
553                                 "MS HO indication", "wmx.rng_req.ranging_purpose.ho_indication",
554                                 FT_UINT8, BASE_DEC, NULL, 0x01, NULL, HFILL
555                         }
556                 },
557                 {
558                         &hf_rng_req_ranging_purpose_reserved,
559                         {
560                                 "Reserved", "wmx.rng_req.ranging_purpose.reserved",
561                                 FT_UINT8, BASE_DEC, NULL, 0xFC, NULL, HFILL
562                         }
563                 },
564                 {
565                         &hf_rng_req_ranging_purpose_location_update_request,
566                         {
567                                 "Location Update Request", "wmx.rng_req.ranging_purpose.loc_update_req",
568                                 FT_UINT8, BASE_DEC, VALS(vals_rng_req_ranging_purpose_location_update_request), 0x02, NULL, HFILL
569                         }
570                 },
571                 {
572                         &hf_rng_req_repetition_coding_level,
573                         {
574                                 "Repetition coding level", "wmx.rng_req.repetition_coding_level",
575                                 FT_UINT8, BASE_DEC, VALS(vals_rng_req_repetition_coding_level), 0x03, NULL, HFILL
576                         }
577                 },
578                 {
579                         &hf_rng_req_requested_downlink_repetition_coding_level_reserved,
580                         {
581                                 "Reserved", "wmx.rng_req.reserved",
582                                 FT_UINT8, BASE_DEC, NULL, 0xFC, NULL, HFILL
583                         }
584                 },
585                 {
586                         &hf_rng_req_reserved,
587                         {
588                                 "Reserved", "wmx.rng_req.reserved",
589                                 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL
590                         }
591                 },
592                 {
593                         &hf_rng_req_serving_bs_id,
594                         {
595                                 "Former serving BS ID", "wmx.rng_req.serving_bs_id",
596                                 FT_ETHER, BASE_NONE, NULL, 0x00, NULL, HFILL
597                         }
598                 },
599                 {
600                         &hf_rng_req_ss_mac_address,
601                         {
602                                 "SS MAC Address", "wmx.rng_req.ss_mac_address",
603                                 FT_ETHER, BASE_NONE, NULL, 0x00, NULL, HFILL
604                         }
605                 }
606         };
607
608         /* Setup protocol subtree array */
609         static gint *ett[] =
610                 {
611                         &ett_mac_mgmt_msg_rng_req_decoder,
612                 };
613
614         proto_mac_mgmt_msg_rng_req_decoder = proto_register_protocol (
615                 "WiMax RNG-REQ/RSP Messages", /* name       */
616                 "WiMax RNG-REQ/RSP (rng)",    /* short name */
617                 "wmx.rng"                     /* abbrev     */
618                 );
619
620         proto_register_field_array(proto_mac_mgmt_msg_rng_req_decoder, hf, array_length(hf));
621         proto_register_subtree_array(ett, array_length(ett));
622 }