From Didier Gautheron:
[obnox/wireshark/wip.git] / plugins / wimax / wimax_harq_map_decoder.c
1 /* wimax_harq_map_decoder.c
2  * WiMax HARQ Map Message 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 /* 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
39 extern guint wimax_compact_dlmap_ie_decoder(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, guint offset, guint nibble_offset);
40 extern guint wimax_compact_ulmap_ie_decoder(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, guint offset, guint nibble_offset);
41
42
43 extern gint proto_wimax;
44
45 /* forward reference */
46 void dissector_wimax_harq_map_decoder(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
47
48 static gint proto_wimax_harq_map_decoder = -1;
49 static gint ett_wimax_harq_map_decoder = -1;
50
51 /* MASKs */
52 #define LSB_NIBBLE_MASK      0x0F
53
54 /* HARQ MAP masks */
55 #define WIMAX_HARQ_MAP_INDICATOR_MASK    0xE00000
56 #define WIMAX_HARQ_UL_MAP_APPENDED_MASK  0x100000
57 #define WIMAX_HARQ_MAP_RESERVED_MASK     0x080000
58 #define WIMAX_HARQ_MAP_MSG_LENGTH_MASK   0x07FC00
59 #define WIMAX_HARQ_MAP_DL_IE_COUNT_MASK  0x0003F0
60 #define WIMAX_HARQ_MAP_MSG_LENGTH_SHIFT  10
61 #define WIMAX_HARQ_MAP_DL_IE_COUNT_SHIFT 4
62
63 /* HARQ MAP display indexies */
64 static gint hf_harq_map_indicator = -1;
65 static gint hf_harq_ul_map_appended = -1;
66 static gint hf_harq_map_reserved = -1;
67 static gint hf_harq_map_msg_length = -1;
68 static gint hf_harq_dl_ie_count = -1;
69 static gint hf_harq_map_msg_crc = -1;
70
71
72 /* HARQ MAP message decoder */
73 void dissector_wimax_harq_map_decoder(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
74 {
75         guint i, offset = 0;
76         guint tvb_len, length, dl_ie_count;
77         guint ie_length;
78         proto_item *harq_map_item = NULL;
79         proto_tree *harq_map_tree = NULL;
80         guint nibble_offset;
81         proto_item *parent_item = NULL;
82         proto_item *it = NULL;
83         guint ulmap_appended;
84         guint32 harq_map_msg_crc, calculated_crc;
85         guint32 first_24bits;
86
87         /* check the tvb reported length */
88         tvb_len = tvb_reported_length(tvb);
89         if(!tvb_len)
90         {       /* do nothing if tvb is empty */
91                 return;
92         }
93         /* Ensure the right payload type */
94         first_24bits = tvb_get_ntoh24(tvb, offset);
95         if((first_24bits & WIMAX_HARQ_MAP_INDICATOR_MASK) != WIMAX_HARQ_MAP_INDICATOR_MASK)
96         {       /* do nothing if tvb is not a HARQ MAP message */
97                 return;
98         }
99         /* update the info column */
100         if (check_col(pinfo->cinfo, COL_INFO))
101         {
102                 col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "HARQ-MAP Message: ");
103         }
104         if (tree)
105         {       /* we are being asked for details */
106                 /* get the parent */
107                 parent_item = proto_tree_get_parent(tree);
108                 /* display HARQ-MAP Message and create subtree */
109                 harq_map_item = proto_tree_add_protocol_format(tree, proto_wimax_harq_map_decoder, tvb, offset, tvb_len, "HARQ-MAP Message (%u bytes)", tvb_len);
110                 harq_map_tree = proto_item_add_subtree(harq_map_item, ett_wimax_harq_map_decoder);
111                 /* display the HARQ MAP Indicator */
112                 proto_tree_add_item(harq_map_tree, hf_harq_map_indicator, tvb, offset, 3, FALSE);
113                 /* display the HARQ MAp UL-MAP Appended */
114                 proto_tree_add_item(harq_map_tree, hf_harq_ul_map_appended, tvb, offset, 3, FALSE);
115                 /* display the reserved bit */
116                 proto_tree_add_item(harq_map_tree, hf_harq_map_reserved, tvb, offset, 3, FALSE);
117                 /* display the HARQ MAP message length */
118                 proto_tree_add_item(harq_map_tree, hf_harq_map_msg_length, tvb, offset, 3, FALSE);
119                 /* display the DL IE count */
120                 proto_tree_add_item(harq_map_tree, hf_harq_dl_ie_count, tvb, offset, 3, FALSE);
121                 /* get the message length */
122                 length = ((first_24bits & WIMAX_HARQ_MAP_MSG_LENGTH_MASK) >> WIMAX_HARQ_MAP_MSG_LENGTH_SHIFT);
123                 /* get the DL IE count */
124                 dl_ie_count = ((first_24bits & WIMAX_HARQ_MAP_DL_IE_COUNT_MASK) >> WIMAX_HARQ_MAP_DL_IE_COUNT_SHIFT);
125                 /* get the UL MAP appended */
126                 ulmap_appended = (first_24bits & WIMAX_HARQ_UL_MAP_APPENDED_MASK);
127                 if (parent_item == NULL || PITEM_FINFO(parent_item) == NULL)
128                 {
129                         parent_item = harq_map_item; /* Prevent crash */
130                 }
131                 /* set the offsets to Compact DL-MAP IEs */
132                 offset += 2;
133                 nibble_offset = 1;
134                 /* process the compact dl_map ies */
135                 for(i=0; i<dl_ie_count; i++)
136                 {       /* add the DL-MAp IEs info */
137                         proto_item_append_text(parent_item, " - DL-MAP IEs");
138                         /* decode Compact DL-MAP IEs */
139                         ie_length = wimax_compact_dlmap_ie_decoder(harq_map_tree, pinfo, tvb, offset, nibble_offset);
140                         offset += ((nibble_offset + ie_length) >> 1);
141                         nibble_offset = ((nibble_offset + ie_length) & 1);
142                 }
143                 /* check if there exist the compact ul_map IEs */
144                 if (ulmap_appended)
145                 {       /* add the UL-MAp IEs info */
146                         proto_item_append_text(parent_item, ",UL-MAP IEs");
147                         /* process the compact ul_map ies */
148                         while(offset < (length - sizeof(harq_map_msg_crc)))
149                         {       /* decode Compact UL-MAP IEs */
150                                 ie_length = wimax_compact_ulmap_ie_decoder(harq_map_tree, pinfo, tvb, offset, nibble_offset);
151                                 /* Prevent endless loop with erroneous data. */
152                                 if (ie_length < 2)
153                                         ie_length = 2;
154                                 offset += ((nibble_offset + ie_length) >> 1);
155                                 nibble_offset = ((nibble_offset + ie_length) & 1);
156                         }
157                 }
158                 /* handle the padding */
159                 if(nibble_offset)
160                 {
161                         /* add the Padding info */
162                         proto_item_append_text(parent_item, ",Padding");
163                         proto_tree_add_protocol_format(harq_map_tree, proto_wimax_harq_map_decoder, tvb, offset, 1, "Padding Nibble: 0x%x", (tvb_get_guint8(tvb, offset) & LSB_NIBBLE_MASK));
164                 }
165                 /* add the CRC info */
166                 proto_item_append_text(parent_item, ",CRC");
167                 /* get the CRC */
168                 harq_map_msg_crc = tvb_get_ntohl(tvb, length - sizeof(harq_map_msg_crc));
169                 /* calculate the HARQ MAM Message CRC */
170                 calculated_crc = wimax_mac_calc_crc32(tvb_get_ptr(tvb, 0, length - sizeof(harq_map_msg_crc)), length - sizeof(harq_map_msg_crc));
171                 /* display the CRC */
172                 it = proto_tree_add_item(harq_map_tree, hf_harq_map_msg_crc, tvb, length - sizeof(harq_map_msg_crc), sizeof(harq_map_msg_crc), FALSE);
173                 /* verify the CRC */
174                 if (harq_map_msg_crc != calculated_crc)
175                 {
176                         proto_item_append_text(it, " - incorrect! (should be: 0x%x)", calculated_crc);
177                 }
178         }
179 }
180
181 /* Register Wimax HARQ MAP Protocol */
182 void proto_register_wimax_harq_map(void)
183 {
184         /* HARQ MAP display */
185         static hf_register_info hf_harq_map[] =
186         {
187                 {
188                         &hf_harq_map_indicator,
189                         {"HARQ MAP Indicator", "wmx.harq_map.indicator", FT_UINT24, BASE_HEX, NULL, WIMAX_HARQ_MAP_INDICATOR_MASK, NULL, HFILL}
190                 },
191                 {
192                         &hf_harq_ul_map_appended,
193                         {"HARQ UL-MAP Appended", "wmx.harq_map.ul_map_appended", FT_UINT24, BASE_HEX, NULL, WIMAX_HARQ_UL_MAP_APPENDED_MASK, NULL, HFILL}
194                 },
195                 {
196                         &hf_harq_map_reserved,
197                         {"Reserved", "wmx.harq_map.reserved", FT_UINT24, BASE_HEX, NULL, WIMAX_HARQ_MAP_RESERVED_MASK, NULL, HFILL}
198                 },
199                 {
200                         &hf_harq_map_msg_length,
201                         {"Map Message Length", "wmx.harq_map.msg_length", FT_UINT24, BASE_DEC, NULL, WIMAX_HARQ_MAP_MSG_LENGTH_MASK, NULL, HFILL}
202                 },
203                 {
204                         &hf_harq_dl_ie_count,
205                         {"DL IE Count", "wmx.harq_map.dl_ie_count", FT_UINT24, BASE_DEC, NULL, WIMAX_HARQ_MAP_DL_IE_COUNT_MASK, NULL, HFILL}
206                 },
207                 {
208                         &hf_harq_map_msg_crc,
209                         {"HARQ MAP Message CRC", "wmx.harq_map.msg_crc", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL}
210                 }
211         };
212
213         /* Setup protocol subtree array */
214         static gint *ett[] =
215                 {
216                         &ett_wimax_harq_map_decoder,
217                 };
218
219         proto_wimax_harq_map_decoder = proto_wimax;
220
221         proto_register_subtree_array(ett, array_length(ett));
222         proto_register_field_array(proto_wimax_harq_map_decoder, hf_harq_map, array_length(hf_harq_map));
223 }