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