Update bit_offset whether calling MAC dissector or not.
[obnox/wireshark/wip.git] / epan / dissectors / packet-umts_fp.c
1 /* Routines for UMTS FP disassembly
2  *
3  * Martin Mathieson
4  *
5  * $Id$
6  *
7  * Wireshark - Network traffic analyzer
8  * By Gerald Combs <gerald@wireshark.org>
9  * Copyright 1998 Gerald Combs
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
24  */
25
26 #ifdef HAVE_CONFIG_H
27 # include "config.h"
28 #endif
29
30 #include <epan/packet.h>
31 #include <epan/expert.h>
32 #include <epan/prefs.h>
33
34 #include "packet-umts_fp.h"
35
36 /* The Frame Protocol (FP) is described in:
37  * 3GPP TS 25.427 (for dedicated channels)
38  * 3GPP TS 25.435 (for common/shared channels)
39  *
40  * TODO:
41  *  - IUR interface-specific formats
42  *  - verify header & payload CRCs
43  *  - do CRC verification before further parsing
44  */
45
46 /* Initialize the protocol and registered fields. */
47 int proto_fp = -1;
48
49 static int hf_fp_channel_type = -1;
50 static int hf_fp_division = -1;
51 static int hf_fp_direction = -1;
52 static int hf_fp_header_crc = -1;
53 static int hf_fp_ft = -1;
54 static int hf_fp_cfn = -1;
55 static int hf_fp_pch_cfn = -1;
56 static int hf_fp_pch_toa = -1;
57 static int hf_fp_cfn_control = -1;
58 static int hf_fp_toa = -1;
59 static int hf_fp_tfi = -1;
60 static int hf_fp_usch_tfi = -1;
61 static int hf_fp_cpch_tfi = -1;
62 static int hf_fp_propagation_delay = -1;
63 static int hf_fp_tb = -1;
64 static int hf_fp_chan_zero_tbs = -1;
65 static int hf_fp_received_sync_ul_timing_deviation = -1;
66 static int hf_fp_pch_pi = -1;
67 static int hf_fp_pch_tfi = -1;
68 static int hf_fp_fach_tfi = -1;
69 static int hf_fp_transmit_power_level = -1;
70 static int hf_fp_paging_indication_bitmap = -1;
71 static int hf_fp_pdsch_set_id = -1;
72 static int hf_fp_rx_timing_deviation = -1;
73 static int hf_fp_dch_e_rucch_flag = -1;
74 static int hf_fp_dch_control_frame_type = -1;
75 static int hf_fp_dch_rx_timing_deviation = -1;
76 static int hf_fp_quality_estimate = -1;
77 static int hf_fp_payload_crc = -1;
78 static int hf_fp_edch_header_crc = -1;
79 static int hf_fp_edch_fsn = -1;
80 static int hf_fp_edch_subframe = -1;
81 static int hf_fp_edch_number_of_subframes = -1;
82 static int hf_fp_edch_harq_retransmissions = -1;
83 static int hf_fp_edch_subframe_number = -1;
84 static int hf_fp_edch_number_of_mac_es_pdus = -1;
85 static int hf_fp_edch_ddi = -1;
86 static int hf_fp_edch_subframe_header = -1;
87 static int hf_fp_edch_number_of_mac_d_pdus = -1;
88 static int hf_fp_edch_pdu_padding = -1;
89 static int hf_fp_edch_tsn = -1;
90 static int hf_fp_edch_mac_es_pdu = -1;
91 static int hf_fp_frame_seq_nr = -1;
92 static int hf_fp_hsdsch_pdu_block_header = -1;
93 static int hf_fp_hsdsch_pdu_block = -1;
94 static int hf_fp_flush = -1;
95 static int hf_fp_fsn_drt_reset = -1;
96 static int hf_fp_drt_indicator = -1;
97 static int hf_fp_fach_indicator = -1;
98 static int hf_fp_total_pdu_blocks = -1;
99 static int hf_fp_drt = -1;
100 static int hf_fp_hrnti = -1;
101 static int hf_fp_rach_measurement_result = -1;
102 static int hf_fp_lchid = -1;
103 static int hf_fp_pdu_length_in_block = -1;
104 static int hf_fp_pdus_in_block = -1;
105 static int hf_fp_cmch_pi = -1;
106 static int hf_fp_user_buffer_size = -1;
107 static int hf_fp_hsdsch_credits = -1;
108 static int hf_fp_hsdsch_max_macd_pdu_len = -1;
109 static int hf_fp_hsdsch_max_macdc_pdu_len = -1;
110 static int hf_fp_hsdsch_interval = -1;
111 static int hf_fp_hsdsch_calculated_rate = -1;
112 static int hf_fp_hsdsch_unlimited_rate = -1;
113 static int hf_fp_hsdsch_repetition_period = -1;
114 static int hf_fp_hsdsch_data_padding = -1;
115 static int hf_fp_hsdsch_new_ie_flags = -1;
116 static int hf_fp_hsdsch_new_ie_flag[8] = {-1, -1, -1, -1, -1, -1, -1, -1};
117 static int hf_fp_hsdsch_drt = -1;
118 static int hf_fp_hsdsch_entity = -1;
119 static int hf_fp_timing_advance = -1;
120 static int hf_fp_num_of_pdu = -1;
121 static int hf_fp_mac_d_pdu_len = -1;
122 static int hf_fp_mac_d_pdu = -1;
123 static int hf_fp_data = -1;
124 static int hf_fp_crcis = -1;
125 static int hf_fp_crci[8] = {-1, -1, -1, -1, -1, -1, -1, -1};
126 static int hf_fp_common_control_frame_type = -1;
127 static int hf_fp_t1 = -1;
128 static int hf_fp_t2 = -1;
129 static int hf_fp_t3 = -1;
130 static int hf_fp_ul_sir_target = -1;
131 static int hf_fp_pusch_set_id = -1;
132 static int hf_fp_activation_cfn = -1;
133 static int hf_fp_duration = -1;
134 static int hf_fp_power_offset = -1;
135 static int hf_fp_code_number = -1;
136 static int hf_fp_spreading_factor = -1;
137 static int hf_fp_mc_info = -1;
138
139 static int hf_fp_rach_new_ie_flags = -1;
140 static int hf_fp_rach_new_ie_flag_unused[7] = {-1, -1, -1, -1, -1, -1, -1 };
141 static int hf_fp_rach_ext_propagation_delay_present = -1;
142 static int hf_fp_rach_cell_portion_id_present = -1;
143 static int hf_fp_rach_angle_of_arrival_present = -1;
144 static int hf_fp_rach_ext_rx_sync_ul_timing_deviation_present = -1;
145 static int hf_fp_rach_ext_rx_timing_deviation_present = -1;
146
147 static int hf_fp_cell_portion_id = -1;
148 static int hf_fp_ext_propagation_delay = -1;
149 static int hf_fp_angle_of_arrival = -1;
150 static int hf_fp_ext_received_sync_ul_timing_deviation = -1;
151
152 static int hf_fp_radio_interface_parameter_update_flag[5] = {-1, -1, -1, -1, -1};
153 static int hf_fp_dpc_mode = -1;
154 static int hf_fp_tpc_po = -1;
155 static int hf_fp_multiple_rl_set_indicator = -1;
156 static int hf_fp_max_ue_tx_pow = -1;
157 static int hf_fp_congestion_status = -1;
158 static int hf_fp_e_rucch_present = -1;
159 static int hf_fp_extended_bits_present = -1;
160 static int hf_fp_extended_bits = -1;
161 static int hf_fp_spare_extension = -1;
162
163 /* Subtrees. */
164 static int ett_fp = -1;
165 static int ett_fp_data = -1;
166 static int ett_fp_crcis = -1;
167 static int ett_fp_edch_subframe_header = -1;
168 static int ett_fp_edch_subframe = -1;
169 static int ett_fp_hsdsch_new_ie_flags = -1;
170 static int ett_fp_rach_new_ie_flags = -1;
171 static int ett_fp_hsdsch_pdu_block_header = -1;
172
173 static dissector_handle_t mac_fdd_dch_handle;
174 static dissector_handle_t mac_fdd_rach_handle;
175 static dissector_handle_t mac_fdd_fach_handle;
176 static dissector_handle_t mac_fdd_pch_handle;
177 static dissector_handle_t mac_fdd_edch_handle;
178 static dissector_handle_t mac_fdd_hsdsch_handle;
179
180 static proto_tree *top_level_tree = NULL;
181
182 /* Variables used for preferences */
183 static gboolean preferences_call_mac_dissectors = TRUE;
184
185
186 /* E-DCH channel header information */
187 struct subframe_info
188 {
189     guint8  subframe_number;
190     guint8  number_of_mac_es_pdus;
191     guint8  ddi[64];
192     guint16 number_of_mac_d_pdus[64];
193 };
194
195 static const value_string channel_type_vals[] =
196 {
197     { CHANNEL_RACH_FDD,     "RACH_FDD" },
198     { CHANNEL_RACH_TDD,     "RACH_TDD" },
199     { CHANNEL_FACH_FDD,     "FACH_FDD" },
200     { CHANNEL_FACH_TDD,     "FACH_TDD" },
201     { CHANNEL_DSCH_FDD,     "DSCH_FDD" },
202     { CHANNEL_DSCH_TDD,     "DSCH_TDD" },
203     { CHANNEL_USCH_TDD_384, "USCH_TDD_384" },
204     { CHANNEL_USCH_TDD_128, "USCH_TDD_128" },
205     { CHANNEL_PCH,          "PCH" },
206     { CHANNEL_CPCH,         "CPCH" },
207     { CHANNEL_BCH,          "BCH" },
208     { CHANNEL_DCH,          "DCH" },
209     { CHANNEL_HSDSCH,       "HSDSCH" },
210     { CHANNEL_IUR_CPCHF,    "IUR CPCHF" },
211     { CHANNEL_IUR_FACH,     "IUR FACH" },
212     { CHANNEL_IUR_DSCH,     "IUR DSCH" },
213     { CHANNEL_EDCH,         "EDCH" },
214     { CHANNEL_RACH_TDD_128, "RACH_TDD_128" },
215     { 0, NULL }
216 };
217
218 static const value_string division_vals[] =
219 {
220     { Division_FDD,      "FDD"},
221     { Division_TDD_384,  "TDD-384"},
222     { Division_TDD_128,  "TDD-128"},
223     { Division_TDD_768,  "TDD-768"},
224     { 0, NULL }
225 };
226
227
228 static const value_string data_control_vals[] = {
229     { 0,   "Data" },
230     { 1,   "Control" },
231     { 0,   NULL },
232 };
233
234 static const value_string direction_vals[] = {
235     { 0,   "Downlink" },
236     { 1,   "Uplink" },
237     { 0,   NULL },
238 };
239
240 static const value_string crci_vals[] = {
241     { 0,   "Correct" },
242     { 1,   "Not correct" },
243     { 0,   NULL },
244 };
245
246 static const value_string paging_indication_vals[] = {
247     { 0,   "no PI-bitmap in payload" },
248     { 1,   "PI-bitmap in payload" },
249     { 0,   NULL },
250 };
251
252 static const value_string spreading_factor_vals[] = {
253     {0,    "4"},
254     {1,    "8"},
255     {2,    "16"},
256     {3,    "32"},
257     {4,    "64"},
258     {5,    "128"},
259     {6,    "256"},
260     {0,    NULL }
261 };
262
263 static const value_string congestion_status_vals[] = {
264     {0,    "No TNL congestion"},
265     {1,    "Reserved for future use"},
266     {2,    "TNL congestion - detected by delay build-up"},
267     {3,    "TNL congestion - detected by frame loss"},
268     {0,    NULL }
269 };
270
271 static const value_string e_rucch_flag_vals[] = {
272     { 0,   "Conventional E-RUCCH reception" },
273     { 1,   "TA Request reception" },
274     { 0,   NULL }
275 };
276
277 static const value_string hsdshc_mac_entity_vals[] = {
278     { entity_not_specified,    "Unspecified (assume MAC-hs)" },
279     { hs,                      "MAC-hs" },
280     { ehs,                     "MAC-ehs" },
281     { 0,   NULL }
282 };
283
284
285 /* Dedicated control types */
286 #define DCH_OUTER_LOOP_POWER_CONTROL            1
287 #define DCH_TIMING_ADJUSTMENT                   2
288 #define DCH_DL_SYNCHRONISATION                  3
289 #define DCH_UL_SYNCHRONISATION                  4
290
291 #define DCH_DL_NODE_SYNCHRONISATION             6
292 #define DCH_UL_NODE_SYNCHRONISATION             7
293 #define DCH_RX_TIMING_DEVIATION                 8
294 #define DCH_RADIO_INTERFACE_PARAMETER_UPDATE    9
295 #define DCH_TIMING_ADVANCE                      10
296 #define DCH_TNL_CONGESTION_INDICATION           11
297
298 static const value_string dch_control_frame_type_vals[] = {
299     { DCH_OUTER_LOOP_POWER_CONTROL,         "OUTER LOOP POWER CONTROL" },
300     { DCH_TIMING_ADJUSTMENT,                "TIMING ADJUSTMENT" },
301     { DCH_DL_SYNCHRONISATION,               "DL SYNCHRONISATION" },
302     { DCH_UL_SYNCHRONISATION,               "UL SYNCHRONISATION" },
303     { 5,                                    "Reserved Value" },
304     { DCH_DL_NODE_SYNCHRONISATION,          "DL NODE SYNCHRONISATION" },
305     { DCH_UL_NODE_SYNCHRONISATION,          "UL NODE SYNCHRONISATION" },
306     { DCH_RX_TIMING_DEVIATION,              "RX TIMING DEVIATION" },
307     { DCH_RADIO_INTERFACE_PARAMETER_UPDATE, "RADIO INTERFACE PARAMETER UPDATE" },
308     { DCH_TIMING_ADVANCE,                   "TIMING ADVANCE" },
309     { DCH_TNL_CONGESTION_INDICATION,        "TNL CONGESTION INDICATION" },
310     { 0,   NULL },
311 };
312
313
314 /* Common channel control types */
315 #define COMMON_OUTER_LOOP_POWER_CONTROL                1
316 #define COMMON_TIMING_ADJUSTMENT                       2
317 #define COMMON_DL_SYNCHRONISATION                      3
318 #define COMMON_UL_SYNCHRONISATION                      4
319                                                        
320 #define COMMON_DL_NODE_SYNCHRONISATION                 6
321 #define COMMON_UL_NODE_SYNCHRONISATION                 7
322 #define COMMON_DYNAMIC_PUSCH_ASSIGNMENT                8
323 #define COMMON_TIMING_ADVANCE                          9
324 #define COMMON_HS_DSCH_Capacity_Request                10
325 #define COMMON_HS_DSCH_Capacity_Allocation             11
326 #define COMMON_HS_DSCH_Capacity_Allocation_Type_2      12
327
328 static const value_string common_control_frame_type_vals[] = {
329     { COMMON_OUTER_LOOP_POWER_CONTROL,            "OUTER LOOP POWER CONTROL" },
330     { COMMON_TIMING_ADJUSTMENT,                   "TIMING ADJUSTMENT" },
331     { COMMON_DL_SYNCHRONISATION,                  "DL SYNCHRONISATION" },
332     { COMMON_UL_SYNCHRONISATION,                  "UL SYNCHRONISATION" },
333     { 5,                                          "Reserved Value" },
334     { COMMON_DL_NODE_SYNCHRONISATION,             "DL NODE SYNCHRONISATION" },
335     { COMMON_UL_NODE_SYNCHRONISATION,             "UL NODE SYNCHRONISATION" },
336     { COMMON_DYNAMIC_PUSCH_ASSIGNMENT,            "DYNAMIC PUSCH ASSIGNMENT" },
337     { COMMON_TIMING_ADVANCE,                      "TIMING ADVANCE" },
338     { COMMON_HS_DSCH_Capacity_Request,            "HS-DSCH Capacity Request" },
339     { COMMON_HS_DSCH_Capacity_Allocation,         "HS-DSCH Capacity Allocation" },
340     { COMMON_HS_DSCH_Capacity_Allocation_Type_2,  "HS-DSCH Capacity Allocation Type 2" },
341     { 0,   NULL },
342 };
343
344 /* Dissect message parts */
345 static int dissect_tb_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
346                            int offset, struct fp_info *p_fp_info,
347                            dissector_handle_t *data_handle);
348 static int dissect_macd_pdu_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
349                                  int offset, guint16 length, guint16 number_of_pdus);
350 static int dissect_macd_pdu_data_type_2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
351                                         int offset, guint16 length, guint16 number_of_pdus);
352
353 static int dissect_crci_bits(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
354                              fp_info *p_fp_info, int offset);
355 static void dissect_spare_extension_and_crc(tvbuff_t *tvb, packet_info *pinfo,
356                                             proto_tree *tree, guint8 dch_crc_present,
357                                             int offset);
358
359 /* Dissect common control messages */
360 static int dissect_common_outer_loop_power_control(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb,
361                                                    int offset, struct fp_info *p_fp_info);
362 static int dissect_common_timing_adjustment(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb,
363                                             int offset, struct fp_info *p_fp_info);
364 static int dissect_common_dl_node_synchronisation(packet_info *pinfo, proto_tree *tree,
365                                                   tvbuff_t *tvb, int offset);
366 static int dissect_common_ul_node_synchronisation(packet_info *pinfo, proto_tree *tree,
367                                                   tvbuff_t *tvb, int offset);
368 static int dissect_common_dl_synchronisation(packet_info *pinfo, proto_tree *tree,
369                                             tvbuff_t *tvb, int offset,
370                                             struct fp_info *p_fp_info);
371 static int dissect_common_ul_synchronisation(packet_info *pinfo, proto_tree *tree,
372                                             tvbuff_t *tvb, int offset,
373                                             struct fp_info *p_fp_info);
374 static int dissect_common_timing_advance(packet_info *pinfo, proto_tree *tree,
375                                          tvbuff_t *tvb, int offset);
376 static int dissect_hsdpa_capacity_request(packet_info *pinfo, proto_tree *tree,
377                                           tvbuff_t *tvb, int offset);
378 static int dissect_hsdpa_capacity_allocation(packet_info *pinfo, proto_tree *tree,
379                                              tvbuff_t *tvb, int offset,
380                                              struct fp_info *p_fp_info);
381 static int dissect_hsdpa_capacity_allocation_type_2(packet_info *pinfo, proto_tree *tree,
382                                                     tvbuff_t *tvb, int offset);
383 static void dissect_common_control(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
384                                    int offset, struct fp_info *p_fp_info);
385 static int dissect_common_dynamic_pusch_assignment(packet_info *pinfo, proto_tree *tree,
386                                                    tvbuff_t *tvb, int offset);
387
388 /* Dissect common channel types */
389 static void dissect_rach_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
390                                       int offset, struct fp_info *p_fp_info);
391 static void dissect_fach_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
392                                       int offset, struct fp_info *p_fp_info);
393 static void dissect_dsch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
394                                       int offset, struct fp_info *p_fp_info);
395 static void dissect_usch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
396                                       int offset, struct fp_info *p_fp_info);
397 static void dissect_pch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
398                                      int offset, struct fp_info *p_fp_info);
399 static void dissect_cpch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
400                                       int offset, struct fp_info *p_fp_info);
401 static void dissect_bch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
402                                      int offset, struct fp_info *p_fp_info);
403 static void dissect_iur_dsch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
404                                           int offset, struct fp_info *p_fp_info _U_);
405 static void dissect_hsdsch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
406                                         int offset, struct fp_info *p_fp_info);
407 static void dissect_hsdsch_type_2_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
408                                                int offset, struct fp_info *p_fp_info);
409
410
411 /* Dissect DCH control messages */
412 static int dissect_dch_timing_adjustment(proto_tree *tree, packet_info *pinfo,
413                                          tvbuff_t *tvb, int offset);
414 static int dissect_dch_rx_timing_deviation(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset,
415                                            struct fp_info *p_fp_info);
416 static int dissect_dch_dl_synchronisation(proto_tree *tree, packet_info *pinfo,
417                                           tvbuff_t *tvb, int offset);
418 static int dissect_dch_ul_synchronisation(proto_tree *tree, packet_info *pinfo,
419                                           tvbuff_t *tvb, int offset);
420 static int dissect_dch_outer_loop_power_control(proto_tree *tree, packet_info *pinfo,
421                                                 tvbuff_t *tvb, int offset);
422 static int dissect_dch_dl_node_synchronisation(proto_tree *tree, packet_info *pinfo,
423                                                tvbuff_t *tvb, int offset);
424 static int dissect_dch_ul_node_synchronisation(proto_tree *tree, packet_info *pinfo,
425                                                tvbuff_t *tvb, int offset);
426 static int dissect_dch_radio_interface_parameter_update(proto_tree *tree, packet_info *pinfo,
427                                                         tvbuff_t *tvb, int offset);
428 static int dissect_dch_timing_advance(proto_tree *tree, packet_info *pinfo,
429                                       tvbuff_t *tvb, int offset, struct fp_info *p_fp_info);
430 static int dissect_dch_tnl_congestion_indication(proto_tree *tree, packet_info *pinfo,
431                                                  tvbuff_t *tvb, int offset);
432
433
434 static void dissect_dch_control_frame(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb,
435                                       int offset, struct fp_info *p_fp_info);
436
437
438 /* Dissect a DCH channel */
439 static void dissect_dch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
440                                      int offset, struct fp_info *p_fp_info);
441
442 /* Dissect dedicated channels */
443 static void dissect_e_dch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
444                                        int offset, struct fp_info *p_fp_info);
445
446 /* Main dissection function */
447 static void dissect_fp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
448
449 /* Protocol registration */
450 void proto_register_fp(void);
451 void proto_reg_handoff_fp(void);
452
453
454 static int get_tb_count(struct fp_info *p_fp_info)
455 {
456     int chan, tb_count = 0;
457     for (chan = 0; chan < p_fp_info->num_chans; chan++) {
458         tb_count += p_fp_info->chan_num_tbs[chan];
459     }
460     return tb_count;
461 }
462
463 /* Dissect the TBs of a data frame */
464 static int dissect_tb_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
465                            int offset, struct fp_info *p_fp_info,
466                            dissector_handle_t *data_handle)
467 {
468     int chan, num_tbs = 0;
469     int bit_offset = 0;
470     guint data_bits = 0;
471     proto_item *tree_ti = NULL;
472     proto_tree *data_tree = NULL;
473     gboolean dissected = FALSE;
474
475     if (tree)
476     {
477         /* Add data subtree */
478         tree_ti =  proto_tree_add_item(tree, hf_fp_data, tvb, offset, -1, FALSE);
479         proto_item_set_text(tree_ti, "TB data for %u chans", p_fp_info->num_chans);
480         data_tree = proto_item_add_subtree(tree_ti, ett_fp_data);
481     }
482
483     /* Now for the TB data */
484     for (chan=0; chan < p_fp_info->num_chans; chan++)
485     {
486         int n;
487
488         /* Clearly show channels with no TBs */
489         if (p_fp_info->chan_num_tbs[chan] == 0)
490         {
491             proto_item *no_tb_ti = proto_tree_add_uint(data_tree, hf_fp_chan_zero_tbs, tvb,
492                                                        offset+(bit_offset/8),
493                                                        0, chan+1);
494             proto_item_append_text(no_tb_ti, " (of size %d)",
495                                    p_fp_info->chan_tf_size[chan]);
496             PROTO_ITEM_SET_GENERATED(no_tb_ti);
497         }
498
499         /* Show TBs from non-empty channels */
500         pinfo->fd->subnum = chan; /* set subframe number to current TB */
501         for (n=0; n < p_fp_info->chan_num_tbs[chan]; n++)
502         {
503             proto_item *ti;
504             if (data_tree)
505             {
506                 tvbuff_t *next_tvb;
507                 ti = proto_tree_add_item(data_tree, hf_fp_tb, tvb,
508                                          offset + (bit_offset/8),
509                                          ((bit_offset % 8) + p_fp_info->chan_tf_size[chan] + 7) / 8,
510                                          FALSE);
511                 proto_item_set_text(ti, "TB (chan %u, tb %u, %u bits)",
512                                     chan+1, n+1, p_fp_info->chan_tf_size[chan]);
513                 if (preferences_call_mac_dissectors && data_handle &&
514                     p_fp_info->chan_tf_size[chan] > 0) {
515
516                         next_tvb = tvb_new_subset(tvb, offset + bit_offset/8,
517                                 ((bit_offset % 8) + p_fp_info->chan_tf_size[chan] + 7) / 8, -1);
518                         /* TODO: maybe this decision can be based only on info available in fp_info */
519                         call_dissector(*data_handle, next_tvb, pinfo, top_level_tree);
520                         dissected = TRUE;
521                 }
522             }
523             num_tbs++;
524
525             /* Advance bit offset */
526             bit_offset += p_fp_info->chan_tf_size[chan];
527             data_bits += p_fp_info->chan_tf_size[chan];
528
529             /* Pad out to next byte */
530             if (bit_offset % 8)
531             {
532                 bit_offset += (8 - (bit_offset % 8));
533             }
534         }
535     }
536
537     if (dissected == FALSE) {
538         col_append_fstr(pinfo->cinfo, COL_INFO, "(%u bits in %u tbs)",
539                         data_bits, num_tbs);
540     }
541
542     /* Data tree should cover entire length */
543     if (data_tree) {
544         proto_item_set_len(tree_ti, bit_offset/8);
545         proto_item_append_text(tree_ti, " (%u bits in %u tbs)", data_bits, num_tbs);
546     }
547
548     /* Move offset past TBs (we know its already padded out to next byte) */
549     offset += (bit_offset / 8);
550
551     return offset;
552 }
553
554
555 /* Dissect the MAC-d PDUs of an HS-DSCH (type 1) frame.
556    Length is in bits, and payload is offset by 4 bits of padding */
557 static int dissect_macd_pdu_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
558                                  int offset, guint16 length, guint16 number_of_pdus)
559 {
560     int pdu;
561     int bit_offset = 0;
562     proto_item *pdus_ti = NULL;
563     proto_tree *data_tree = NULL;
564     gboolean dissected = FALSE;
565
566     /* Add data subtree */
567     if (tree)
568     {
569         pdus_ti =  proto_tree_add_item(tree, hf_fp_data, tvb, offset, -1, FALSE);
570         proto_item_set_text(pdus_ti, "%u MAC-d PDUs of %u bits", number_of_pdus, length);
571         data_tree = proto_item_add_subtree(pdus_ti, ett_fp_data);
572     }
573
574     /* Now for the PDUs */
575     for (pdu=0; pdu < number_of_pdus; pdu++) {
576         proto_item *pdu_ti;
577
578         if (data_tree) {
579             /* Show 4 bits padding at start of PDU */
580             proto_tree_add_item(data_tree, hf_fp_hsdsch_data_padding, tvb, offset+(bit_offset/8), 1, FALSE);
581         }
582         bit_offset += 4;
583
584         /* Data bytes! */
585         if (data_tree) {
586             tvbuff_t *next_tvb;
587             pinfo->fd->subnum = pdu; /* set subframe number to current TB */
588             pdu_ti = proto_tree_add_item(data_tree, hf_fp_mac_d_pdu, tvb,
589                                          offset + (bit_offset/8),
590                                          ((bit_offset % 8) + length + 7) / 8,
591                                          FALSE);
592             proto_item_set_text(pdu_ti, "MAC-d PDU (PDU %u)", pdu+1);
593             if (preferences_call_mac_dissectors) {
594                 next_tvb = tvb_new_subset(tvb, offset + bit_offset/8,
595                     ((bit_offset % 8) + length + 7)/8, -1);
596                 call_dissector(mac_fdd_hsdsch_handle, next_tvb, pinfo, top_level_tree);
597                 dissected = TRUE;
598             }
599         }
600
601         /* Advance bit offset */
602         bit_offset += length;
603
604         /* Pad out to next byte */
605         if (bit_offset % 8)
606         {
607             bit_offset += (8 - (bit_offset % 8));
608         }
609     }
610
611     /* Data tree should cover entire length */
612     proto_item_set_len(pdus_ti, bit_offset/8);
613
614     /* Move offset past PDUs (we know its already padded out to next byte) */
615     offset += (bit_offset / 8);
616
617     /* Show summary in info column */
618     if (dissected == FALSE) {
619         col_append_fstr(pinfo->cinfo, COL_INFO, "   %u PDUs of %u bits",
620                         number_of_pdus, length);
621     }
622
623     return offset;
624 }
625
626
627 /* Dissect the MAC-d PDUs of an HS-DSCH (type 2) frame.
628    Length is in bytes, and payload is byte-aligned (no padding) */
629 static int dissect_macd_pdu_data_type_2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
630                                         int offset, guint16 length, guint16 number_of_pdus)
631 {
632     int pdu;
633     proto_item *pdus_ti = NULL;
634     proto_tree *data_tree = NULL;
635     int first_offset = offset;
636
637     /* Add data subtree */
638     if (tree)
639     {
640         pdus_ti =  proto_tree_add_item(tree, hf_fp_data, tvb, offset, -1, FALSE);
641         proto_item_set_text(pdus_ti, "%u MAC-d PDUs of %u bytes", number_of_pdus, length);
642         data_tree = proto_item_add_subtree(pdus_ti, ett_fp_data);
643     }
644
645     /* Now for the PDUs */
646     for (pdu=0; pdu < number_of_pdus; pdu++)
647     {
648         proto_item *pdu_ti;
649
650         /* Data bytes! */
651         if (data_tree)
652         {
653             pdu_ti = proto_tree_add_item(data_tree, hf_fp_mac_d_pdu, tvb,
654                                          offset, length, FALSE);
655             proto_item_set_text(pdu_ti, "MAC-d PDU (PDU %u)", pdu+1);
656         }
657
658         /* Advance offset */
659         offset += length;
660     }
661
662     /* Data tree should cover entire length */
663     proto_item_set_len(pdus_ti, offset-first_offset);
664
665     /* Show summary in info column */
666     col_append_fstr(pinfo->cinfo, COL_INFO, "   %u PDUs of %u bits",
667                     number_of_pdus, length*8);
668
669     return offset;
670 }
671
672 /* Dissect CRCI bits (uplink) */
673 static int dissect_crci_bits(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
674                              fp_info *p_fp_info, int offset)
675 {
676     int n, num_tbs;
677     proto_item *ti = NULL;
678     proto_tree *crcis_tree = NULL;
679     guint errors = 0;
680
681     num_tbs = get_tb_count(p_fp_info);
682
683     /* Add CRCIs subtree */
684     if (tree)
685     {
686         ti =  proto_tree_add_item(tree, hf_fp_crcis, tvb, offset, (num_tbs+7)/8, FALSE);
687         proto_item_set_text(ti, "CRCI bits for %u tbs", num_tbs);
688         crcis_tree = proto_item_add_subtree(ti, ett_fp_crcis);
689     }
690
691     /* CRCIs */
692     for (n=0; n < num_tbs; n++)
693     {
694         int bit = (tvb_get_guint8(tvb, offset+(n/8)) >> (7-(n%8))) & 0x01;
695         proto_tree_add_item(crcis_tree, hf_fp_crci[n%8], tvb, offset+(n/8),
696                             1, FALSE);
697
698         if (bit == 1)
699         {
700             errors++;
701             expert_add_info_format(pinfo, ti,
702                                    PI_CHECKSUM, PI_WARN,
703                                    "CRCI error bit set for TB");
704         }
705     }
706
707     if (tree)
708     {
709         /* Highlight range of bytes covered by indicator bits */
710         proto_item_set_len(ti, (num_tbs+7) / 8);
711
712         /* Show error count in root text */
713         proto_item_append_text(ti, " (%u errors)", errors);
714     }
715
716     offset += ((num_tbs+7) / 8);
717     return offset;
718 }
719
720
721 static void dissect_spare_extension_and_crc(tvbuff_t *tvb, packet_info *pinfo,
722                                             proto_tree *tree, guint8 dch_crc_present,
723                                             int offset)
724 {
725     int crc_size = 0;
726     int remain = tvb_length_remaining(tvb, offset);
727     proto_item *ti = NULL;
728
729     /* Payload CRC (optional) */
730     if (dch_crc_present == 1 || (dch_crc_present == 2 && remain >= 2))
731     {
732         crc_size = 2;
733     }
734
735     if (remain > crc_size)
736     {
737         ti = proto_tree_add_item(tree, hf_fp_spare_extension, tvb,
738                                  offset, remain-crc_size, FALSE);
739         proto_item_append_text(ti, " (%u octets)", remain-crc_size);
740         expert_add_info_format(pinfo, ti,
741                                PI_UNDECODED, PI_WARN,
742                                "Spare Extension present (%u bytes)", remain-crc_size);
743         offset += remain-crc_size;
744     }
745
746     if (crc_size)
747     {
748         proto_tree_add_item(tree, hf_fp_payload_crc, tvb, offset, crc_size,
749                             FALSE);
750     }
751 }
752
753
754
755 /***********************************************************/
756 /* Common control message types                            */
757
758 int dissect_common_outer_loop_power_control(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb,
759                                             int offset, struct fp_info *p_fp_info _U_)
760 {
761     return dissect_dch_outer_loop_power_control(tree, pinfo, tvb, offset);
762 }
763
764
765 int dissect_common_timing_adjustment(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb,
766                                      int offset, struct fp_info *p_fp_info)
767 {
768     if (p_fp_info->channel != CHANNEL_PCH)
769     {
770         guint8 cfn;
771         gint16 toa;
772
773         /* CFN control */
774         cfn = tvb_get_guint8(tvb, offset);
775         proto_tree_add_item(tree, hf_fp_cfn_control, tvb, offset, 1, FALSE);
776         offset++;
777
778         /* ToA */
779         toa = tvb_get_ntohs(tvb, offset);
780         proto_tree_add_item(tree, hf_fp_toa, tvb, offset, 2, FALSE);
781         offset += 2;
782
783         col_append_fstr(pinfo->cinfo, COL_INFO, "   CFN=%u, ToA=%d", cfn, toa);
784     }
785     else
786     {
787         guint16 cfn;
788         gint32 toa;
789
790         /* PCH CFN is 12 bits */
791         cfn = (tvb_get_ntohs(tvb, offset) >> 4);
792         proto_tree_add_item(tree, hf_fp_pch_cfn, tvb, offset, 2, FALSE);
793         offset += 2;
794
795         /* 4 bits of padding follow... */
796
797         /* 20 bits of ToA (followed by 4 padding bits) */
798         toa = ((int)(tvb_get_ntoh24(tvb, offset) << 8)) / 4096;
799         proto_tree_add_int(tree, hf_fp_pch_toa, tvb, offset, 3, toa);
800         offset += 3;
801
802         col_append_fstr(pinfo->cinfo, COL_INFO, "   CFN=%u, ToA=%d", cfn, toa);
803     }
804     return offset;
805 }
806
807 static int dissect_common_dl_node_synchronisation(packet_info *pinfo, proto_tree *tree,
808                                                   tvbuff_t *tvb, int offset)
809 {
810     /* T1 (3 bytes) */
811     guint32 t1 = tvb_get_ntoh24(tvb, offset);
812     proto_tree_add_item(tree, hf_fp_t1, tvb, offset, 3, FALSE);
813     offset += 3;
814
815     col_append_fstr(pinfo->cinfo, COL_INFO, "   T1=%u", t1);
816
817     return offset;
818 }
819
820 static int dissect_common_ul_node_synchronisation(packet_info *pinfo, proto_tree *tree,
821                                                   tvbuff_t *tvb, int offset)
822 {
823     guint32 t1, t2, t3;
824
825     /* T1 (3 bytes) */
826     t1 = tvb_get_ntoh24(tvb, offset);
827     proto_tree_add_item(tree, hf_fp_t1, tvb, offset, 3, FALSE);
828     offset += 3;
829
830     /* T2 (3 bytes) */
831     t2 = tvb_get_ntoh24(tvb, offset);
832     proto_tree_add_item(tree, hf_fp_t2, tvb, offset, 3, FALSE);
833     offset += 3;
834
835     /* T3 (3 bytes) */
836     t3 = tvb_get_ntoh24(tvb, offset);
837     proto_tree_add_item(tree, hf_fp_t3, tvb, offset, 3, FALSE);
838     offset += 3;
839
840     col_append_fstr(pinfo->cinfo, COL_INFO, "   T1=%u T2=%u, T3=%u",
841                     t1, t2, t3);
842
843     return offset;
844 }
845
846 static int dissect_common_dl_synchronisation(packet_info *pinfo, proto_tree *tree,
847                                              tvbuff_t *tvb, int offset, struct fp_info *p_fp_info)
848 {
849     guint16 cfn;
850
851     if (p_fp_info->channel != CHANNEL_PCH)
852     {
853         /* CFN control */
854         cfn = tvb_get_guint8(tvb, offset);
855         proto_tree_add_item(tree, hf_fp_cfn_control, tvb, offset, 1, FALSE);
856         offset++;
857     }
858     else
859     {
860         /* PCH CFN is 12 bits */
861         cfn = (tvb_get_ntohs(tvb, offset) >> 4);
862         proto_tree_add_item(tree, hf_fp_pch_cfn, tvb, offset, 2, FALSE);
863
864         /* 4 bits of padding follow... */
865         offset += 2;
866     }
867
868     col_append_fstr(pinfo->cinfo, COL_INFO, "   CFN=%u", cfn);
869
870     return offset;
871 }
872
873 static int dissect_common_ul_synchronisation(packet_info *pinfo, proto_tree *tree,
874                                              tvbuff_t *tvb, int offset, struct fp_info *p_fp_info)
875 {
876     return dissect_common_timing_adjustment(pinfo, tree, tvb, offset, p_fp_info);
877 }
878
879 static int dissect_common_timing_advance(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
880 {
881     guint8 cfn;
882     guint16 timing_advance;
883
884     /* CFN control */
885     cfn = tvb_get_guint8(tvb, offset);
886     proto_tree_add_item(tree, hf_fp_cfn_control, tvb, offset, 1, FALSE);
887     offset++;
888
889     /* Timing Advance */
890     timing_advance = (tvb_get_guint8(tvb, offset) & 0x3f) * 4;
891     proto_tree_add_uint(tree, hf_fp_timing_advance, tvb, offset, 1, timing_advance);
892     offset++;
893
894     col_append_fstr(pinfo->cinfo, COL_INFO, " CFN = %u, TA = %u",
895                     cfn, timing_advance);
896
897     return offset;
898 }
899
900 static int dissect_hsdpa_capacity_request(packet_info *pinfo, proto_tree *tree,
901                                           tvbuff_t *tvb, int offset)
902 {
903     guint8 priority;
904     guint16 user_buffer_size;
905
906     /* CmCH-PI */
907     priority = (tvb_get_guint8(tvb, offset) & 0x0f);
908     proto_tree_add_item(tree, hf_fp_cmch_pi, tvb, offset, 1, FALSE);
909     offset++;
910
911     /* User buffer size */
912     user_buffer_size = tvb_get_ntohs(tvb, offset);
913     proto_tree_add_item(tree, hf_fp_user_buffer_size, tvb, offset, 2, FALSE);
914     offset += 2;
915
916     col_append_fstr(pinfo->cinfo, COL_INFO, "      CmCH-PI=%u  User-Buffer-Size=%u",
917                     priority, user_buffer_size);
918
919     return offset;
920 }
921
922 static int dissect_hsdpa_capacity_allocation(packet_info *pinfo, proto_tree *tree,
923                                              tvbuff_t *tvb, int offset,
924                                              struct fp_info *p_fp_info)
925 {
926     proto_item *ti;
927     proto_item *rate_ti;
928     guint16 max_pdu_length;
929     guint8  repetition_period;
930     guint8  interval;
931     guint64 credits;
932
933     /* Congestion status (introduced sometime during R6...) */
934     if ((p_fp_info->release == 6) || (p_fp_info->release == 7))
935     {
936         proto_tree_add_bits_item(tree, hf_fp_congestion_status, tvb,
937                                  offset*8 + 2, 2, FALSE);
938     }
939
940     /* CmCH-PI */
941     proto_tree_add_item(tree, hf_fp_cmch_pi, tvb, offset, 1, FALSE);
942     offset++;
943
944     /* Max MAC-d PDU length (13 bits) */
945     max_pdu_length = tvb_get_ntohs(tvb, offset) >> 3;
946     proto_tree_add_item(tree, hf_fp_hsdsch_max_macd_pdu_len, tvb, offset, 2, FALSE);
947     offset++;
948
949     /* HS-DSCH credits (11 bits) */
950     ti = proto_tree_add_bits_ret_val(tree, hf_fp_hsdsch_credits, tvb,
951                                      offset*8 + 5, 11, &credits, FALSE);
952     offset += 2;
953
954     /* Interesting values */
955     if (credits == 0)
956     {
957         proto_item_append_text(ti, " (stop transmission)");
958         expert_add_info_format(pinfo, ti,
959                                PI_RESPONSE_CODE, PI_NOTE,
960                                "Stop HSDPA transmission");
961     }
962     if (credits == 2047)
963     {
964         proto_item_append_text(ti, " (unlimited)");
965     }
966
967     /* HS-DSCH Interval */
968     interval = tvb_get_guint8(tvb, offset);
969     ti = proto_tree_add_uint(tree, hf_fp_hsdsch_interval, tvb, offset, 1, interval*10);
970     offset++;
971     if (interval == 0)
972     {
973         proto_item_append_text(ti, " (none of the credits shall be used)");
974     }
975
976     /* HS-DSCH Repetition period */
977     repetition_period = tvb_get_guint8(tvb, offset);
978     ti = proto_tree_add_item(tree, hf_fp_hsdsch_repetition_period, tvb, offset, 1, FALSE);
979     offset++;
980     if (repetition_period == 0)
981     {
982         proto_item_append_text(ti, " (unlimited repetition period)");
983     }
984
985     /* Calculated and show effective rate enabled */
986     if (credits == 2047)
987     {
988         rate_ti = proto_tree_add_item(tree, hf_fp_hsdsch_unlimited_rate, tvb, 0, 0, FALSE);
989         PROTO_ITEM_SET_GENERATED(rate_ti);
990     }
991     else
992     {
993         if (interval != 0)
994         {
995             /* Cast on credits is safe, since we know it won't exceed 10^11 */
996             rate_ti = proto_tree_add_uint(tree, hf_fp_hsdsch_calculated_rate, tvb, 0, 0,
997                                           (guint16)credits * max_pdu_length * (1000 / (interval*10)));
998             PROTO_ITEM_SET_GENERATED(rate_ti);
999         }
1000     }
1001
1002     col_append_fstr(pinfo->cinfo, COL_INFO,
1003                     "   Max-PDU-len=%u  Credits=%u  Interval=%u  Rep-Period=%u",
1004                     max_pdu_length, (guint16)credits, interval, repetition_period);
1005
1006     return offset;
1007 }
1008
1009 static int dissect_hsdpa_capacity_allocation_type_2(packet_info *pinfo, proto_tree *tree,
1010                                                     tvbuff_t *tvb, int offset)
1011 {
1012     proto_item *ti;
1013     proto_item *rate_ti;
1014     guint16    max_pdu_length;
1015     guint8     repetition_period;
1016     guint8     interval;
1017     guint16    credits;
1018
1019     /* Congestion status */
1020     proto_tree_add_bits_item(tree, hf_fp_congestion_status, tvb,
1021                             offset*8 + 2, 2, FALSE);
1022
1023     /* CmCH-PI */
1024     proto_tree_add_item(tree, hf_fp_cmch_pi, tvb, offset, 1, FALSE);
1025     offset++;
1026
1027     /* 5 spare bits follow here */
1028
1029     /* Max MAC-d/c PDU length (11 bits) */
1030     max_pdu_length = tvb_get_ntohs(tvb, offset) & 0x7ff;
1031     proto_tree_add_item(tree, hf_fp_hsdsch_max_macdc_pdu_len, tvb, offset, 2, FALSE);
1032     offset += 2;
1033
1034     /* HS-DSCH credits (16 bits) */
1035     credits = (tvb_get_ntohs(tvb, offset));
1036     ti = proto_tree_add_uint(tree, hf_fp_hsdsch_credits, tvb,
1037                              offset, 2, credits);
1038     offset += 2;
1039
1040     /* Interesting values */
1041     if (credits == 0)
1042     {
1043         proto_item_append_text(ti, " (stop transmission)");
1044         expert_add_info_format(pinfo, ti,
1045                                PI_RESPONSE_CODE, PI_NOTE,
1046                                "Stop HSDPA transmission");
1047     }
1048     if (credits == 65535)
1049     {
1050         proto_item_append_text(ti, " (unlimited)");
1051     }
1052
1053     /* HS-DSCH Interval */
1054     interval = tvb_get_guint8(tvb, offset);
1055     ti = proto_tree_add_uint(tree, hf_fp_hsdsch_interval, tvb, offset, 1, interval*10);
1056     offset++;
1057     if (interval == 0)
1058     {
1059         proto_item_append_text(ti, " (none of the credits shall be used)");
1060     }
1061
1062     /* HS-DSCH Repetition period */
1063     repetition_period = tvb_get_guint8(tvb, offset);
1064     ti = proto_tree_add_item(tree, hf_fp_hsdsch_repetition_period, tvb, offset, 1, FALSE);
1065     offset++;
1066     if (repetition_period == 0)
1067     {
1068         proto_item_append_text(ti, " (unlimited repetition period)");
1069     }
1070
1071     /* Calculated and show effective rate enabled */
1072     if (credits == 65535)
1073     {
1074         rate_ti = proto_tree_add_item(tree, hf_fp_hsdsch_unlimited_rate, tvb, 0, 0, FALSE);
1075         PROTO_ITEM_SET_GENERATED(rate_ti);
1076     }
1077     else
1078     {
1079         if (interval != 0)
1080         {
1081             rate_ti = proto_tree_add_uint(tree, hf_fp_hsdsch_calculated_rate, tvb, 0, 0,
1082                                           credits * max_pdu_length * (1000 / (interval*10)));
1083             PROTO_ITEM_SET_GENERATED(rate_ti);
1084         }
1085     }
1086
1087     col_append_fstr(pinfo->cinfo, COL_INFO,
1088                     "   Max-PDU-len=%u  Credits=%u  Interval=%u  Rep-Period=%u",
1089                     max_pdu_length, credits, interval, repetition_period);
1090
1091     return offset;
1092 }
1093
1094
1095
1096 static int dissect_common_dynamic_pusch_assignment(packet_info *pinfo, proto_tree *tree,
1097                                                    tvbuff_t *tvb, int offset)
1098 {
1099     guint8 pusch_set_id;
1100     guint8 activation_cfn;
1101     guint8 duration;
1102
1103     /* PUSCH Set Id */
1104     pusch_set_id = tvb_get_guint8(tvb, offset);
1105     proto_tree_add_item(tree, hf_fp_pusch_set_id, tvb, offset, 1, FALSE);
1106     offset++;
1107
1108     /* Activation CFN */
1109     activation_cfn = tvb_get_guint8(tvb, offset);
1110     proto_tree_add_item(tree, hf_fp_activation_cfn, tvb, offset, 1, FALSE);
1111     offset++;
1112
1113     /* Duration */
1114     duration = tvb_get_guint8(tvb, offset) * 10;
1115     proto_tree_add_uint(tree, hf_fp_duration, tvb, offset, 1, duration);
1116     offset++;
1117
1118     col_append_fstr(pinfo->cinfo, COL_INFO,
1119                     "   PUSCH Set Id=%u  Activation CFN=%u  Duration=%u",
1120                     pusch_set_id, activation_cfn, duration);
1121
1122     return offset;
1123 }
1124
1125
1126
1127
1128
1129 /* Dissect the control part of a common channel message */
1130 static void dissect_common_control(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1131                                   int offset, struct fp_info *p_fp_info)
1132 {
1133     /* Common control frame type */
1134     guint8 control_frame_type = tvb_get_guint8(tvb, offset);
1135     proto_tree_add_item(tree, hf_fp_common_control_frame_type, tvb, offset, 1, FALSE);
1136     offset++;
1137
1138     col_append_str(pinfo->cinfo, COL_INFO,
1139                    val_to_str(control_frame_type, common_control_frame_type_vals, "Unknown"));
1140
1141     /* Frame-type specific dissection */
1142     switch (control_frame_type)
1143     {
1144         case COMMON_OUTER_LOOP_POWER_CONTROL:
1145             offset = dissect_common_outer_loop_power_control(pinfo, tree, tvb, offset, p_fp_info);
1146             break;
1147         case COMMON_TIMING_ADJUSTMENT:
1148             offset = dissect_common_timing_adjustment(pinfo, tree, tvb, offset, p_fp_info);
1149             break;
1150         case COMMON_DL_SYNCHRONISATION:
1151             offset = dissect_common_dl_synchronisation(pinfo, tree, tvb, offset, p_fp_info);
1152             break;
1153         case COMMON_UL_SYNCHRONISATION:
1154             offset = dissect_common_ul_synchronisation(pinfo, tree, tvb, offset, p_fp_info);
1155             break;
1156         case COMMON_DL_NODE_SYNCHRONISATION:
1157             offset = dissect_common_dl_node_synchronisation(pinfo, tree, tvb, offset);
1158             break;
1159         case COMMON_UL_NODE_SYNCHRONISATION:
1160             offset = dissect_common_ul_node_synchronisation(pinfo, tree, tvb, offset);
1161             break;
1162         case COMMON_DYNAMIC_PUSCH_ASSIGNMENT:
1163             offset = dissect_common_dynamic_pusch_assignment(pinfo, tree, tvb, offset);
1164             break;
1165         case COMMON_TIMING_ADVANCE:
1166             offset = dissect_common_timing_advance(pinfo, tree, tvb, offset);
1167             break;
1168         case COMMON_HS_DSCH_Capacity_Request:
1169             offset = dissect_hsdpa_capacity_request(pinfo, tree, tvb, offset);
1170             break;
1171         case COMMON_HS_DSCH_Capacity_Allocation:
1172             offset = dissect_hsdpa_capacity_allocation(pinfo, tree, tvb, offset, p_fp_info);
1173             break;
1174         case COMMON_HS_DSCH_Capacity_Allocation_Type_2:
1175             offset = dissect_hsdpa_capacity_allocation_type_2(pinfo, tree, tvb, offset);
1176             break;
1177
1178         default:
1179             break;
1180     }
1181
1182     /* Spare Extension */
1183     dissect_spare_extension_and_crc(tvb, pinfo, tree, 0, offset);
1184 }
1185
1186
1187
1188 /**************************/
1189 /* Dissect a RACH channel */
1190 static void dissect_rach_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1191                                       int offset, struct fp_info *p_fp_info)
1192 {
1193     gboolean is_control_frame;
1194
1195     /* Header CRC */
1196     proto_tree_add_item(tree, hf_fp_header_crc, tvb, offset, 1, FALSE);
1197
1198     /* Frame Type */
1199     is_control_frame = tvb_get_guint8(tvb, offset) & 0x01;
1200     proto_tree_add_item(tree, hf_fp_ft, tvb, offset, 1, FALSE);
1201     offset++;
1202
1203     col_append_str(pinfo->cinfo, COL_INFO, is_control_frame ? " [Control] " : " [Data] ");
1204
1205     if (is_control_frame)
1206     {
1207         dissect_common_control(tvb, pinfo, tree, offset, p_fp_info);
1208     }
1209     else
1210     {
1211         guint8 cfn;
1212         guint32 propagation_delay = 0;
1213         proto_item *propagation_delay_ti = NULL;
1214         guint32 received_sync_ul_timing_deviation = 0;
1215         proto_item *received_sync_ul_timing_deviation_ti = NULL;
1216         proto_item *rx_timing_deviation_ti = NULL;
1217         guint16     rx_timing_deviation = 0;
1218
1219         /* DATA */
1220
1221         /* CFN */
1222         cfn = tvb_get_guint8(tvb, offset);
1223         proto_tree_add_item(tree, hf_fp_cfn, tvb, offset, 1, FALSE);
1224         offset++;
1225
1226         col_append_fstr(pinfo->cinfo, COL_INFO, "CFN=%03u ", cfn);
1227
1228         /* TFI */
1229         proto_tree_add_item(tree, hf_fp_tfi, tvb, offset, 1, FALSE);
1230         offset++;
1231
1232         if (p_fp_info->channel == CHANNEL_RACH_FDD)
1233         {
1234             /* Propagation delay */
1235             propagation_delay = tvb_get_guint8(tvb, offset);
1236             propagation_delay_ti = proto_tree_add_uint(tree, hf_fp_propagation_delay, tvb, offset, 1,
1237                                                        propagation_delay*3);
1238             offset++;
1239         }
1240
1241         /* Should be TDD 3.84 or 7.68 */
1242         if (p_fp_info->channel == CHANNEL_RACH_TDD)
1243         {
1244             /* Rx Timing Deviation */
1245             rx_timing_deviation = tvb_get_guint8(tvb, offset);
1246             rx_timing_deviation_ti = proto_tree_add_item(tree, hf_fp_rx_timing_deviation, tvb, offset, 1, FALSE);
1247             offset++;
1248         }
1249
1250         if (p_fp_info->channel == CHANNEL_RACH_TDD_128)
1251         {
1252             /* Received SYNC UL Timing Deviation */
1253             received_sync_ul_timing_deviation = tvb_get_guint8(tvb, offset);
1254             received_sync_ul_timing_deviation_ti =
1255                  proto_tree_add_item(tree, hf_fp_received_sync_ul_timing_deviation, tvb, offset, 1, FALSE);
1256             offset++;
1257         }
1258
1259         /* TB data */
1260         offset = dissect_tb_data(tvb, pinfo, tree, offset, p_fp_info, &mac_fdd_rach_handle);
1261
1262         /* CRCIs */
1263         offset = dissect_crci_bits(tvb, pinfo, tree, p_fp_info, offset);
1264
1265         /* Info introduced in R6 */
1266         /* only check if it looks as if they are present */
1267         if (((p_fp_info->release == 6) || (p_fp_info->release == 7)) &&
1268             tvb_length_remaining(tvb, offset) > 2)
1269         {
1270             int n;
1271             guint8 flags;
1272             guint8 flag_bytes = 0;
1273
1274             gboolean cell_portion_id_present = FALSE;
1275             gboolean ext_propagation_delay_present = FALSE;
1276             gboolean angle_of_arrival_present = FALSE;
1277             gboolean ext_rx_sync_ul_timing_deviation_present = FALSE;
1278             gboolean ext_rx_timing_deviation_present = FALSE;
1279
1280             /* New IE flags (assume mandatory for now) */
1281             do
1282             {
1283                 proto_item *new_ie_flags_ti;
1284                 proto_tree *new_ie_flags_tree;
1285                 guint ies_found = 0;
1286
1287                 /* Add new IE flags subtree */
1288                 new_ie_flags_ti = proto_tree_add_string_format(tree, hf_fp_rach_new_ie_flags, tvb, offset, 1,
1289                                                               "", "New IE flags");
1290                 new_ie_flags_tree = proto_item_add_subtree(new_ie_flags_ti, ett_fp_rach_new_ie_flags);
1291
1292                 /* Read next byte */
1293                 flags = tvb_get_guint8(tvb, offset);
1294                 flag_bytes++;
1295
1296                 /* Dissect individual bits */
1297                 for (n=0; n < 8; n++)
1298                 {
1299                     switch (n) {
1300                         case 6:
1301                             switch (p_fp_info->division)
1302                             {
1303                                 case Division_FDD:
1304                                     /* Ext propagation delay */
1305                                     ext_propagation_delay_present = TRUE;
1306                                     proto_tree_add_item(new_ie_flags_tree, hf_fp_rach_ext_propagation_delay_present,
1307                                                         tvb, offset, 1, FALSE);
1308                                     break;
1309                                 case Division_TDD_128:
1310                                     /* Ext Rx Sync UL Timing */
1311                                     ext_rx_sync_ul_timing_deviation_present = TRUE;
1312                                     proto_tree_add_item(new_ie_flags_tree, hf_fp_rach_ext_rx_sync_ul_timing_deviation_present,
1313                                                         tvb, offset, 1, FALSE);
1314         
1315                                     break;
1316                                 default:
1317                                     /* Not defined */
1318                                     proto_tree_add_item(new_ie_flags_tree, hf_fp_rach_new_ie_flag_unused[n],
1319                                                         tvb, offset, 1, FALSE);
1320                                     break;
1321                             }
1322                             break;
1323                         case 7:
1324                             switch (p_fp_info->division)
1325                             {
1326                                 case Division_FDD:
1327                                     /* Cell Portion ID */
1328                                     cell_portion_id_present = TRUE;
1329                                     proto_tree_add_item(new_ie_flags_tree, hf_fp_rach_cell_portion_id_present,
1330                                                         tvb, offset, 1, FALSE);
1331                                     break;
1332                                 case Division_TDD_128:
1333                                     /* AOA */
1334                                     angle_of_arrival_present = TRUE;
1335                                     proto_tree_add_item(new_ie_flags_tree, hf_fp_rach_angle_of_arrival_present,
1336                                                         tvb, offset, 1, FALSE);
1337                                     break;
1338                                 case Division_TDD_384:
1339                                 case Division_TDD_768:
1340                                     /* Extended Rx Timing Deviation */
1341                                     ext_rx_timing_deviation_present = TRUE;
1342                                     proto_tree_add_item(new_ie_flags_tree, hf_fp_rach_ext_rx_timing_deviation_present,
1343                                                         tvb, offset, 1, FALSE);
1344                                     break;
1345                             }
1346                             break;
1347
1348                         default:
1349                             /* No defined meanings */
1350                             proto_tree_add_item(new_ie_flags_tree, hf_fp_rach_new_ie_flag_unused[n],
1351                                                 tvb, offset, 1, FALSE);
1352                             break;
1353                     }
1354                     if ((flags >> (7-n)) & 0x01)
1355                     {
1356                         ies_found++;
1357                     }
1358                 }
1359                 offset++;
1360
1361                 proto_item_append_text(new_ie_flags_ti, " (%u IEs found)", ies_found);
1362
1363                 /* Last bit set will indicate another flags byte follows... */
1364             } while (0); /*((flags & 0x01) && (flag_bytes < 31));*/
1365
1366             /* Cell Portion ID */
1367             if (cell_portion_id_present) {
1368                     proto_tree_add_item(tree, hf_fp_cell_portion_id, tvb, offset, 1, FALSE);
1369                     offset++;
1370             }
1371
1372             /* Ext Rx Timing Deviation */
1373             if (ext_rx_timing_deviation_present)
1374             {
1375                 guint8 extra_bits;
1376                 guint bits_to_extend;
1377                 switch (p_fp_info->division)
1378                 {
1379                     case Division_TDD_384:
1380                         bits_to_extend = 1;
1381                         break;
1382                     case Division_TDD_768:
1383                         bits_to_extend = 2;
1384                         break;
1385     
1386                     default:
1387                         /* TODO: report unexpected division type */
1388                         bits_to_extend = 1;
1389                         break;
1390                 }
1391                 extra_bits = tvb_get_guint8(tvb, offset) &
1392                                  ((bits_to_extend == 1) ? 0x01 : 0x03);
1393                 rx_timing_deviation = (extra_bits << 8) | (rx_timing_deviation);
1394                 proto_item_append_text(rx_timing_deviation_ti,
1395                                        " (extended to 0x%x)",
1396                                        rx_timing_deviation);
1397                 proto_tree_add_bits_item(tree, hf_fp_extended_bits, tvb,
1398                                          offset*8 + (8-bits_to_extend), bits_to_extend, FALSE);
1399                 offset++;
1400             }
1401
1402             /* Ext propagation delay. */
1403             if (ext_propagation_delay_present)
1404             {
1405                 guint16 extra_bits = tvb_get_ntohs(tvb, offset) & 0x03ff;
1406                 proto_tree_add_item(tree, hf_fp_ext_propagation_delay, tvb, offset, 2, FALSE);
1407
1408                 /* Adding 10 bits to original 8 */
1409                 proto_item_append_text(propagation_delay_ti, " (extended to %u)",
1410                                        ((extra_bits << 8) | propagation_delay) * 3);
1411                 offset += 2;
1412             }
1413
1414             /* Angle of Arrival (AOA) */
1415             if (angle_of_arrival_present)
1416             {
1417                 proto_tree_add_item(tree, hf_fp_angle_of_arrival, tvb, offset, 2, FALSE);
1418                 offset += 2;
1419             }
1420
1421             /* Ext. Rx Sync UL Timing Deviation */
1422             if (ext_rx_sync_ul_timing_deviation_present) {
1423                 guint16 extra_bits;
1424
1425                 /* Ext received Sync UL Timing Deviation */
1426                 extra_bits = tvb_get_ntohs(tvb, offset) & 0x1fff;
1427                 proto_tree_add_item(tree, hf_fp_ext_received_sync_ul_timing_deviation, tvb, offset, 2, FALSE);
1428
1429                 /* Adding 13 bits to original 8 */
1430                 proto_item_append_text(received_sync_ul_timing_deviation_ti, " (extended to %u)",
1431                                        (extra_bits << 8) | received_sync_ul_timing_deviation);
1432                 offset += 2;
1433             }
1434         }
1435
1436         /* Spare Extension and Payload CRC */
1437         dissect_spare_extension_and_crc(tvb, pinfo, tree, 1, offset);
1438     }
1439 }
1440
1441
1442 /**************************/
1443 /* Dissect a FACH channel */
1444 static void dissect_fach_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1445                                       int offset, struct fp_info *p_fp_info)
1446 {
1447     gboolean is_control_frame;
1448
1449     /* Header CRC */
1450     proto_tree_add_item(tree, hf_fp_header_crc, tvb, offset, 1, FALSE);
1451
1452     /* Frame Type */
1453     is_control_frame = tvb_get_guint8(tvb, offset) & 0x01;
1454     proto_tree_add_item(tree, hf_fp_ft, tvb, offset, 1, FALSE);
1455     offset++;
1456
1457     col_append_str(pinfo->cinfo, COL_INFO, is_control_frame ? " [Control] " : " [Data] ");
1458
1459     if (is_control_frame)
1460     {
1461         dissect_common_control(tvb, pinfo, tree, offset, p_fp_info);
1462     }
1463     else
1464     {
1465         guint8 cfn;
1466
1467         /* DATA */
1468
1469         /* CFN */
1470         cfn = tvb_get_guint8(tvb, offset);
1471         proto_tree_add_item(tree, hf_fp_cfn, tvb, offset, 1, FALSE);
1472         offset++;
1473
1474         col_append_fstr(pinfo->cinfo, COL_INFO, "CFN=%03u ", cfn);
1475
1476         /* TFI */
1477         proto_tree_add_item(tree, hf_fp_fach_tfi, tvb, offset, 1, FALSE);
1478         offset++;
1479
1480         /* Transmit power level */
1481         proto_tree_add_float(tree, hf_fp_transmit_power_level, tvb, offset, 1,
1482                              (float)(int)(tvb_get_guint8(tvb, offset)) / 10);
1483         offset++;
1484
1485         /* TB data */
1486         offset = dissect_tb_data(tvb, pinfo, tree, offset, p_fp_info, &mac_fdd_fach_handle);
1487
1488         /* New IE flags (if it looks as though they are present) */
1489         if ((p_fp_info->release == 7) &&
1490             (tvb_length_remaining(tvb, offset) > 2))
1491         {
1492             guint8 flags = tvb_get_guint8(tvb, offset);
1493             guint8 aoa_present = flags & 0x01;
1494             offset++;
1495
1496             if (aoa_present)
1497             {
1498                 proto_tree_add_item(tree, hf_fp_angle_of_arrival, tvb, offset, 2, FALSE);
1499                 offset += 2;
1500             }
1501         }
1502
1503         /* Spare Extension and Payload CRC */
1504         dissect_spare_extension_and_crc(tvb, pinfo, tree, 1, offset);
1505     }
1506 }
1507
1508
1509 /**************************/
1510 /* Dissect a DSCH channel */
1511 static void dissect_dsch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1512                                       int offset, struct fp_info *p_fp_info)
1513 {
1514     gboolean is_control_frame;
1515
1516     /* Header CRC */
1517     proto_tree_add_item(tree, hf_fp_header_crc, tvb, offset, 1, FALSE);
1518
1519     /* Frame Type */
1520     is_control_frame = tvb_get_guint8(tvb, offset) & 0x01;
1521     proto_tree_add_item(tree, hf_fp_ft, tvb, offset, 1, FALSE);
1522     offset++;
1523
1524     col_append_str(pinfo->cinfo, COL_INFO, is_control_frame ? " [Control] " : " [Data] ");
1525
1526     if (is_control_frame)
1527     {
1528         dissect_common_control(tvb, pinfo, tree, offset, p_fp_info);
1529     }
1530     else
1531     {
1532         guint8 cfn;
1533
1534         /* DATA */
1535
1536         /* CFN */
1537         cfn = tvb_get_guint8(tvb, offset);
1538         proto_tree_add_item(tree, hf_fp_cfn, tvb, offset, 1, FALSE);
1539         offset++;
1540
1541         col_append_fstr(pinfo->cinfo, COL_INFO, "CFN=%03u ", cfn);
1542
1543         /* TFI */
1544         proto_tree_add_item(tree, hf_fp_tfi, tvb, offset, 1, FALSE);
1545         offset++;
1546
1547
1548         /* Other fields depend upon release & FDD/TDD settings */
1549         if (((p_fp_info->release == 99) || (p_fp_info->release == 4)) &&
1550              (p_fp_info->channel == CHANNEL_DSCH_FDD))
1551         {
1552             /* Power offset */
1553             proto_tree_add_float(tree, hf_fp_power_offset, tvb, offset, 1,
1554                                  (float)(-32.0) +
1555                                   ((float)(int)(tvb_get_guint8(tvb, offset)) * (float)(0.25)));
1556             offset++;
1557
1558             /* Code number */
1559             proto_tree_add_item(tree, hf_fp_code_number, tvb, offset, 1, FALSE);
1560             offset++;
1561
1562             /* Spreading Factor (3 bits) */
1563             proto_tree_add_item(tree, hf_fp_spreading_factor, tvb, offset, 1, FALSE);
1564
1565             /* MC info (4 bits)*/
1566             proto_tree_add_item(tree, hf_fp_mc_info, tvb, offset, 1, FALSE);
1567
1568             /* Last bit of this byte is spare */
1569             offset++;
1570         }
1571         else
1572         {
1573             /* Normal case */
1574
1575             /* PDSCH Set Id */
1576             proto_tree_add_item(tree, hf_fp_pdsch_set_id, tvb, offset, 1, FALSE);
1577             offset++;
1578
1579             /* Transmit power level */
1580             proto_tree_add_float(tree, hf_fp_transmit_power_level, tvb, offset, 1,
1581                                  (float)(int)(tvb_get_guint8(tvb, offset)) / 10);
1582             offset++;
1583         }
1584
1585         /* TB data */
1586         offset = dissect_tb_data(tvb, pinfo, tree, offset, p_fp_info, NULL);
1587
1588         /* Spare Extension and Payload CRC */
1589         dissect_spare_extension_and_crc(tvb, pinfo, tree, 1, offset);
1590     }
1591 }
1592
1593
1594 /**************************/
1595 /* Dissect a USCH channel */
1596 static void dissect_usch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1597                                       int offset, struct fp_info *p_fp_info)
1598 {
1599     gboolean is_control_frame;
1600
1601     /* Header CRC */
1602     proto_tree_add_item(tree, hf_fp_header_crc, tvb, offset, 1, FALSE);
1603
1604     /* Frame Type */
1605     is_control_frame = tvb_get_guint8(tvb, offset) & 0x01;
1606     proto_tree_add_item(tree, hf_fp_ft, tvb, offset, 1, FALSE);
1607     offset++;
1608
1609     col_append_str(pinfo->cinfo, COL_INFO, is_control_frame ? " [Control] " : " [Data] ");
1610
1611     if (is_control_frame)
1612     {
1613         dissect_common_control(tvb, pinfo, tree, offset, p_fp_info);
1614     }
1615     else
1616     {
1617         guint cfn;
1618         guint16 rx_timing_deviation;
1619         proto_item *rx_timing_deviation_ti;
1620
1621         /* DATA */
1622
1623         /* CFN */
1624         cfn = tvb_get_guint8(tvb, offset);
1625         proto_tree_add_item(tree, hf_fp_cfn, tvb, offset, 1, FALSE);
1626         offset++;
1627
1628         col_append_fstr(pinfo->cinfo, COL_INFO, "CFN=%03u ", cfn);
1629
1630         /* TFI */
1631         proto_tree_add_item(tree, hf_fp_usch_tfi, tvb, offset, 1, FALSE);
1632         offset++;
1633
1634         /* Rx Timing Deviation */
1635         rx_timing_deviation = tvb_get_guint8(tvb, offset);
1636         rx_timing_deviation_ti = proto_tree_add_item(tree, hf_fp_rx_timing_deviation,
1637                                                      tvb, offset, 1, FALSE);
1638         offset++;
1639
1640         /* TB data */
1641         offset = dissect_tb_data(tvb, pinfo, tree, offset, p_fp_info, NULL);
1642
1643         /* QE */
1644         proto_tree_add_item(tree, hf_fp_quality_estimate, tvb, offset, 1, FALSE);
1645         offset++;
1646
1647         /* CRCIs */
1648         offset = dissect_crci_bits(tvb, pinfo, tree, p_fp_info, offset);
1649
1650         /* New IEs */
1651         if ((p_fp_info->release == 7) &&
1652             (tvb_length_remaining(tvb, offset) > 2))
1653         {
1654             guint8 flags = tvb_get_guint8(tvb, offset);
1655             guint8 bits_extended = flags & 0x01;
1656             offset++;
1657
1658             if (bits_extended)
1659             {
1660                 guint8 extra_bits = tvb_get_guint8(tvb, offset) & 0x03;
1661                 proto_item_append_text(rx_timing_deviation_ti,
1662                                        " (extended to %u)",
1663                                        (rx_timing_deviation << 2) | extra_bits);
1664             }
1665             offset++;
1666         }
1667
1668         /* Spare Extension and Payload CRC */
1669         dissect_spare_extension_and_crc(tvb, pinfo, tree, 1, offset);
1670     }
1671 }
1672
1673
1674
1675 /**************************/
1676 /* Dissect a PCH channel  */
1677 static void dissect_pch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1678                                      int offset, struct fp_info *p_fp_info)
1679 {
1680     gboolean is_control_frame;
1681     guint16  pch_cfn;
1682     gboolean paging_indication;
1683
1684     /* Header CRC */
1685     proto_tree_add_item(tree, hf_fp_header_crc, tvb, offset, 1, FALSE);
1686
1687     /* Frame Type */
1688     is_control_frame = tvb_get_guint8(tvb, offset) & 0x01;
1689     proto_tree_add_item(tree, hf_fp_ft, tvb, offset, 1, FALSE);
1690     offset++;
1691
1692     col_append_str(pinfo->cinfo, COL_INFO, is_control_frame ? " [Control] " : " [Data] ");
1693
1694     if (is_control_frame)
1695     {
1696         dissect_common_control(tvb, pinfo, tree, offset, p_fp_info);
1697     }
1698     else
1699     {
1700         /* DATA */
1701
1702         /* 12-bit CFN value */
1703         proto_tree_add_item(tree, hf_fp_pch_cfn, tvb, offset, 2, FALSE);
1704         pch_cfn = (tvb_get_ntohs(tvb, offset) & 0xfff0) >> 4;
1705         offset++;
1706
1707         col_append_fstr(pinfo->cinfo, COL_INFO, "CFN=%04u ", pch_cfn);
1708
1709         /* Paging indication */
1710         proto_tree_add_item(tree, hf_fp_pch_pi, tvb, offset, 1, FALSE);
1711         paging_indication = tvb_get_guint8(tvb, offset) & 0x01;
1712         offset++;
1713
1714         /* 5-bit TFI */
1715         proto_tree_add_item(tree, hf_fp_pch_tfi, tvb, offset, 1, FALSE);
1716         offset++;
1717
1718         /* Optional paging indications */
1719         if (paging_indication)
1720         {
1721             proto_item *ti;
1722             ti = proto_tree_add_item(tree, hf_fp_paging_indication_bitmap, tvb,
1723                                      offset,
1724                                      (p_fp_info->paging_indications+7) / 8,
1725                                      FALSE);
1726             proto_item_append_text(ti, " (%u bits)", p_fp_info->paging_indications);
1727             offset += ((p_fp_info->paging_indications+7) / 8);
1728         }
1729
1730         /* TB data */
1731         offset = dissect_tb_data(tvb, pinfo, tree, offset, p_fp_info, &mac_fdd_pch_handle);
1732
1733         /* Spare Extension and Payload CRC */
1734         dissect_spare_extension_and_crc(tvb, pinfo, tree, 1, offset);
1735     }
1736 }
1737
1738
1739 /**************************/
1740 /* Dissect a CPCH channel */
1741 static void dissect_cpch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1742                                       int offset, struct fp_info *p_fp_info)
1743 {
1744     gboolean is_control_frame;
1745
1746     /* Header CRC */
1747     proto_tree_add_item(tree, hf_fp_header_crc, tvb, offset, 1, FALSE);
1748
1749     /* Frame Type */
1750     is_control_frame = tvb_get_guint8(tvb, offset) & 0x01;
1751     proto_tree_add_item(tree, hf_fp_ft, tvb, offset, 1, FALSE);
1752     offset++;
1753
1754     col_append_str(pinfo->cinfo, COL_INFO, is_control_frame ? " [Control] " : " [Data] ");
1755
1756     if (is_control_frame)
1757     {
1758         dissect_common_control(tvb, pinfo, tree, offset, p_fp_info);
1759     }
1760     else
1761     {
1762         guint cfn;
1763
1764         /* DATA */
1765
1766         /* CFN */
1767         cfn = tvb_get_guint8(tvb, offset);
1768         proto_tree_add_item(tree, hf_fp_cfn, tvb, offset, 1, FALSE);
1769         offset++;
1770
1771         col_append_fstr(pinfo->cinfo, COL_INFO, "CFN=%03u ", cfn);
1772
1773         /* TFI */
1774         proto_tree_add_item(tree, hf_fp_cpch_tfi, tvb, offset, 1, FALSE);
1775         offset++;
1776
1777         /* Propagation delay */
1778         proto_tree_add_uint(tree, hf_fp_propagation_delay, tvb, offset, 1,
1779                             tvb_get_guint8(tvb, offset) * 3);
1780         offset++;
1781
1782         /* TB data */
1783         offset = dissect_tb_data(tvb, pinfo, tree, offset, p_fp_info, NULL);
1784
1785         /* CRCIs */
1786         offset = dissect_crci_bits(tvb, pinfo, tree, p_fp_info, offset);
1787
1788         /* Spare Extension and Payload CRC */
1789         dissect_spare_extension_and_crc(tvb, pinfo, tree, 1, offset);
1790     }
1791 }
1792
1793
1794 /**************************/
1795 /* Dissect a BCH channel  */
1796 static void dissect_bch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1797                                      int offset, struct fp_info *p_fp_info)
1798 {
1799     gboolean is_control_frame;
1800
1801     /* Header CRC */
1802     proto_tree_add_item(tree, hf_fp_header_crc, tvb, offset, 1, FALSE);
1803
1804     /* Frame Type */
1805     is_control_frame = tvb_get_guint8(tvb, offset) & 0x01;
1806     proto_tree_add_item(tree, hf_fp_ft, tvb, offset, 1, FALSE);
1807     offset++;
1808
1809     col_append_str(pinfo->cinfo, COL_INFO, is_control_frame ? " [Control] " : " [Data] ");
1810
1811     if (is_control_frame)
1812     {
1813         dissect_common_control(tvb, pinfo, tree, offset, p_fp_info);
1814     }
1815 }
1816
1817
1818 /********************************/
1819 /* Dissect an IUR DSCH channel  */
1820 static void dissect_iur_dsch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1821                                           int offset, struct fp_info *p_fp_info _U_)
1822 {
1823     gboolean is_control_frame;
1824
1825     /* Header CRC */
1826     proto_tree_add_item(tree, hf_fp_header_crc, tvb, offset, 1, FALSE);
1827
1828     /* Frame Type */
1829     is_control_frame = tvb_get_guint8(tvb, offset) & 0x01;
1830     proto_tree_add_item(tree, hf_fp_ft, tvb, offset, 1, FALSE);
1831     offset++;
1832
1833     col_append_str(pinfo->cinfo, COL_INFO, is_control_frame ? " [Control] " : " [Data] ");
1834
1835     if (is_control_frame)
1836     {
1837         dissect_common_control(tvb, pinfo, tree, offset, p_fp_info);
1838     }
1839     else
1840     {
1841         /* TODO: DATA */
1842     }
1843 }
1844
1845
1846
1847
1848 /************************/
1849 /* DCH control messages */
1850
1851 static int dissect_dch_timing_adjustment(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, int offset)
1852 {
1853     guint8 control_cfn;
1854     gint16 toa;
1855
1856     /* CFN control */
1857     control_cfn = tvb_get_guint8(tvb, offset);
1858     proto_tree_add_item(tree, hf_fp_cfn_control, tvb, offset, 1, FALSE);
1859     offset++;
1860
1861     /* ToA */
1862     toa = tvb_get_ntohs(tvb, offset);
1863     proto_tree_add_item(tree, hf_fp_toa, tvb, offset, 2, FALSE);
1864     offset += 2;
1865
1866     col_append_fstr(pinfo->cinfo, COL_INFO,
1867                     " CFN = %u, ToA = %d", control_cfn, toa);
1868
1869     return offset;
1870 }
1871
1872 static int dissect_dch_rx_timing_deviation(packet_info *pinfo, proto_tree *tree,
1873                                            tvbuff_t *tvb, int offset,
1874                                            struct fp_info *p_fp_info)
1875 {
1876     guint16 timing_deviation = 0;
1877     gint timing_deviation_chips = 0;
1878     proto_item *timing_deviation_ti = NULL;
1879
1880     /* CFN control */
1881     proto_tree_add_item(tree, hf_fp_cfn_control, tvb, offset, 1, FALSE);
1882     offset++;
1883
1884     /* Rx Timing Deviation */
1885     timing_deviation = tvb_get_guint8(tvb, offset);
1886     timing_deviation_ti = proto_tree_add_item(tree, hf_fp_dch_rx_timing_deviation, tvb, offset, 1, FALSE);
1887     offset++;
1888
1889     /* May be extended in R7, but in this case there are at least 2 bytes remaining */
1890     if ((p_fp_info->release == 7) &&
1891         (tvb_length_remaining(tvb, offset) >= 2))
1892     {
1893         /* New IE flags */
1894         guint64 extended_bits_present;
1895         guint64 e_rucch_present;
1896
1897         /* Read flags */
1898         proto_tree_add_bits_ret_val(tree, hf_fp_e_rucch_present, tvb,
1899                                     offset*8 + 6, 1, &e_rucch_present, FALSE);
1900         proto_tree_add_bits_ret_val(tree, hf_fp_extended_bits_present, tvb,
1901                                     offset*8 + 7, 1, &extended_bits_present, FALSE);
1902         offset++;
1903
1904         /* Optional E-RUCCH */
1905         if (e_rucch_present)
1906         {
1907             /* Value of bit_offset depends upon division type */
1908             int bit_offset;
1909
1910             switch (p_fp_info->division)
1911             {
1912                 case Division_TDD_384:
1913                     bit_offset = 6;
1914                     break;
1915                 case Division_TDD_768:
1916                     bit_offset = 5;
1917                     break;
1918                 default:
1919                     {
1920                         proto_item *ti = proto_tree_add_text(tree, tvb, 0, 0,
1921                                                              "Error: expecting TDD-384 or TDD-768");
1922                         PROTO_ITEM_SET_GENERATED(ti);
1923                         expert_add_info_format(pinfo, ti,
1924                                                PI_MALFORMED, PI_NOTE,
1925                                                "Error: expecting TDD-384 or TDD-768");
1926                         bit_offset = 6;
1927                     }
1928                     
1929             }
1930
1931             proto_tree_add_item(tree, hf_fp_dch_e_rucch_flag, tvb, offset, 1, FALSE);
1932             proto_tree_add_bits_item(tree, hf_fp_dch_e_rucch_flag, tvb,
1933                                      offset*8 + bit_offset, 1, FALSE);
1934         }
1935
1936         /* Timing deviation may be extended by another:
1937            - 1 bits (3.84 TDD)    OR
1938            - 2 bits (7.68 TDD)
1939         */
1940         if (extended_bits_present)
1941         {
1942             guint8 extra_bits;
1943             guint bits_to_extend;
1944             switch (p_fp_info->division)
1945             {
1946                 case Division_TDD_384:
1947                     bits_to_extend = 1;
1948                     break;
1949                 case Division_TDD_768:
1950                     bits_to_extend = 2;
1951                     break;
1952
1953                 default:
1954                     /* TODO: report unexpected division type */
1955                     bits_to_extend = 1;
1956                     break;
1957             }
1958             extra_bits = tvb_get_guint8(tvb, offset) &
1959                              ((bits_to_extend == 1) ? 0x01 : 0x03);
1960             timing_deviation = (extra_bits << 8) | (timing_deviation);
1961             proto_item_append_text(timing_deviation_ti,
1962                                    " (extended to 0x%x)",
1963                                    timing_deviation);
1964             proto_tree_add_bits_item(tree, hf_fp_extended_bits, tvb,
1965                                      offset*8 + (8-bits_to_extend), bits_to_extend, FALSE);
1966             offset++;
1967         }
1968     }
1969
1970     timing_deviation_chips = (timing_deviation*4) - 1024;
1971     proto_item_append_text(timing_deviation_ti, " (%d chips)",
1972                            timing_deviation_chips);
1973
1974     col_append_fstr(pinfo->cinfo, COL_INFO, " deviation = %u (%d chips)",
1975                     timing_deviation, timing_deviation_chips);
1976
1977     return offset;
1978 }
1979
1980 static int dissect_dch_dl_synchronisation(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, int offset)
1981 {
1982     /* CFN control */
1983     guint cfn = tvb_get_guint8(tvb, offset);
1984     proto_tree_add_item(tree, hf_fp_cfn_control, tvb, offset, 1, FALSE);
1985     offset++;
1986
1987     col_append_fstr(pinfo->cinfo, COL_INFO, " CFN = %u", cfn);
1988
1989     return offset;
1990 }
1991
1992 static int dissect_dch_ul_synchronisation(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, int offset)
1993 {
1994     guint8 cfn;
1995     gint16 toa;
1996
1997     /* CFN control */
1998     cfn = tvb_get_guint8(tvb, offset);
1999     proto_tree_add_item(tree, hf_fp_cfn_control, tvb, offset, 1, FALSE);
2000     offset++;
2001
2002     /* ToA */
2003     toa = tvb_get_ntohs(tvb, offset);
2004     proto_tree_add_item(tree, hf_fp_toa, tvb, offset, 2, FALSE);
2005     offset += 2;
2006
2007     col_append_fstr(pinfo->cinfo, COL_INFO, " CFN = %u, ToA = %d",
2008                     cfn, toa);
2009
2010     return offset;
2011 }
2012
2013 static int dissect_dch_outer_loop_power_control(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, int offset)
2014 {
2015     /* UL SIR target */
2016     float target = (float)-8.2 + ((float)0.1 * (float)(int)(tvb_get_guint8(tvb, offset)));
2017     proto_tree_add_float(tree, hf_fp_ul_sir_target, tvb, offset, 1, target);
2018     offset++;
2019
2020     col_append_fstr(pinfo->cinfo, COL_INFO, " UL SIR Target = %f", target);
2021
2022     return offset;
2023 }
2024
2025 static int dissect_dch_dl_node_synchronisation(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, int offset)
2026 {
2027     return dissect_common_dl_node_synchronisation(pinfo, tree, tvb, offset);
2028 }
2029
2030 static int dissect_dch_ul_node_synchronisation(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, int offset)
2031 {
2032     return dissect_common_ul_node_synchronisation(pinfo, tree, tvb, offset);
2033 }
2034
2035 static int dissect_dch_radio_interface_parameter_update(proto_tree *tree, packet_info *pinfo _U_, tvbuff_t *tvb, int offset)
2036 {
2037     int n;
2038     guint8 cfn;
2039     guint8 value;
2040
2041     /* Show defined flags in these 2 bytes */
2042     for (n=4; n >= 0; n--)
2043     {
2044         proto_tree_add_item(tree, hf_fp_radio_interface_parameter_update_flag[n], tvb, offset, 2, FALSE);
2045     }
2046     offset += 2;
2047
2048     /* CFN  */
2049     cfn = tvb_get_guint8(tvb, offset);
2050     proto_tree_add_item(tree, hf_fp_cfn, tvb, offset, 1, FALSE);
2051     offset++;
2052
2053     /* DPC mode */
2054     proto_tree_add_item(tree, hf_fp_dpc_mode, tvb, offset, 1, FALSE);
2055
2056     /* TPC PO */
2057     proto_tree_add_item(tree, hf_fp_tpc_po, tvb, offset, 1, FALSE);
2058     offset++;
2059
2060     /* Multiple RL sets indicator */
2061     proto_tree_add_item(tree, hf_fp_multiple_rl_set_indicator, tvb, offset, 1, FALSE);
2062     offset += 2;
2063
2064     /* MAX_UE_TX_POW */
2065     value = (tvb_get_guint8(tvb, offset) & 0x7f);
2066     proto_tree_add_int(tree, hf_fp_max_ue_tx_pow, tvb, offset, 1, -55 + value);
2067     offset++;
2068
2069     return offset;
2070 }
2071
2072 static int dissect_dch_timing_advance(proto_tree *tree, packet_info *pinfo,
2073                                       tvbuff_t *tvb, int offset, struct fp_info *p_fp_info)
2074 {
2075     guint8 cfn;
2076     guint16 timing_advance;
2077     proto_item *timing_advance_ti;
2078
2079     /* CFN control */
2080     cfn = tvb_get_guint8(tvb, offset);
2081     proto_tree_add_item(tree, hf_fp_cfn_control, tvb, offset, 1, FALSE);
2082     offset++;
2083
2084     /* Timing Advance */
2085     timing_advance = (tvb_get_guint8(tvb, offset) & 0x3f) * 4;
2086     timing_advance_ti = proto_tree_add_uint(tree, hf_fp_timing_advance, tvb, offset, 1, timing_advance);
2087     offset++;
2088
2089     if ((p_fp_info->release == 7) &&
2090         (tvb_length_remaining(tvb, offset) > 0))
2091     {
2092         /* New IE flags */
2093         guint8 flags = tvb_get_guint8(tvb, offset);
2094         guint8 extended_bits = flags & 0x01;
2095         offset++;
2096
2097         if (extended_bits)
2098         {
2099             guint8 extra_bit = tvb_get_guint8(tvb, offset) & 0x01;
2100             proto_item_append_text(timing_advance_ti, " (extended to %u)",
2101                                    (timing_advance << 1) | extra_bit);
2102         }
2103         offset++;
2104     }
2105
2106
2107     col_append_fstr(pinfo->cinfo, COL_INFO, " CFN = %u, TA = %u",
2108                     cfn, timing_advance);
2109
2110     return offset;
2111 }
2112
2113 static int dissect_dch_tnl_congestion_indication(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, int offset)
2114 {
2115     guint64 status;
2116
2117     /* Congestion status */
2118     proto_tree_add_bits_ret_val(tree, hf_fp_congestion_status, tvb,
2119                                 offset*8 + 6, 2, &status, FALSE);
2120     offset++;
2121
2122     col_append_fstr(pinfo->cinfo, COL_INFO, " status = %s",
2123                     val_to_str((guint16)status, congestion_status_vals, "unknown"));
2124
2125     return offset;
2126 }
2127
2128
2129
2130
2131 /* DCH control frame */
2132 static void dissect_dch_control_frame(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, int offset,
2133                                       struct fp_info *p_fp_info)
2134 {
2135     /* Control frame type */
2136     guint8 control_frame_type = tvb_get_guint8(tvb, offset);
2137     proto_tree_add_item(tree, hf_fp_dch_control_frame_type, tvb, offset, 1, FALSE);
2138     offset++;
2139
2140     col_append_str(pinfo->cinfo, COL_INFO,
2141                    val_to_str(control_frame_type,
2142                               dch_control_frame_type_vals, "Unknown"));
2143
2144     switch (control_frame_type)
2145     {
2146         case DCH_TIMING_ADJUSTMENT:
2147             offset = dissect_dch_timing_adjustment(tree, pinfo, tvb, offset);
2148             break;
2149         case DCH_RX_TIMING_DEVIATION:
2150             offset = dissect_dch_rx_timing_deviation(pinfo, tree, tvb, offset, p_fp_info);
2151             break;
2152         case DCH_DL_SYNCHRONISATION:
2153             offset = dissect_dch_dl_synchronisation(tree, pinfo, tvb, offset);
2154             break;
2155         case DCH_UL_SYNCHRONISATION:
2156             offset = dissect_dch_ul_synchronisation(tree, pinfo, tvb, offset);
2157             break;
2158         case DCH_OUTER_LOOP_POWER_CONTROL:
2159             offset = dissect_dch_outer_loop_power_control(tree, pinfo, tvb, offset);
2160             break;
2161         case DCH_DL_NODE_SYNCHRONISATION:
2162             offset = dissect_dch_dl_node_synchronisation(tree, pinfo, tvb, offset);
2163             break;
2164         case DCH_UL_NODE_SYNCHRONISATION:
2165             offset = dissect_dch_ul_node_synchronisation(tree, pinfo, tvb, offset);
2166             break;
2167         case DCH_RADIO_INTERFACE_PARAMETER_UPDATE:
2168             offset = dissect_dch_radio_interface_parameter_update(tree, pinfo, tvb, offset);
2169             break;
2170         case DCH_TIMING_ADVANCE:
2171             offset = dissect_dch_timing_advance(tree, pinfo, tvb, offset, p_fp_info);
2172             break;
2173         case DCH_TNL_CONGESTION_INDICATION:
2174             offset = dissect_dch_tnl_congestion_indication(tree, pinfo, tvb, offset);
2175             break;
2176     }
2177
2178     /* Spare Extension */
2179     dissect_spare_extension_and_crc(tvb, pinfo, tree, 0, offset);
2180 }
2181
2182 /*******************************/
2183 /* Dissect a DCH channel       */
2184 static void dissect_dch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2185                                      int offset, struct fp_info *p_fp_info)
2186 {
2187     gboolean is_control_frame;
2188     guint8   cfn;
2189
2190     /* Header CRC */
2191     proto_tree_add_item(tree, hf_fp_header_crc, tvb, offset, 1, FALSE);
2192
2193     /* Frame Type */
2194     is_control_frame = tvb_get_guint8(tvb, offset) & 0x01;
2195     proto_tree_add_item(tree, hf_fp_ft, tvb, offset, 1, FALSE);
2196     offset++;
2197
2198     col_append_str(pinfo->cinfo, COL_INFO,
2199                    is_control_frame ? " [Control] " :
2200                                       ((p_fp_info->is_uplink) ? " [ULData] " :
2201                                                                 " [DLData] " ));
2202
2203     if (is_control_frame)
2204     {
2205         /* DCH control frame */
2206         dissect_dch_control_frame(tree, pinfo, tvb, offset, p_fp_info);
2207     }
2208     else
2209     {
2210         /************************/
2211         /* DCH data here        */
2212         int chan;
2213
2214         /* CFN */
2215         proto_tree_add_item(tree, hf_fp_cfn, tvb, offset, 1, FALSE);
2216         cfn = tvb_get_guint8(tvb, offset);
2217         offset++;
2218
2219         col_append_fstr(pinfo->cinfo, COL_INFO, "CFN=%03u ", cfn);
2220
2221         /* One TFI for each channel */
2222         for (chan=0; chan < p_fp_info->num_chans; chan++)
2223         {
2224             proto_tree_add_item(tree, hf_fp_tfi, tvb, offset, 1, FALSE);
2225             offset++;
2226         }
2227
2228         /* Dissect TB data */
2229         offset = dissect_tb_data(tvb, pinfo, tree, offset, p_fp_info, &mac_fdd_dch_handle);
2230
2231         /* QE (uplink only) */
2232         if (p_fp_info->is_uplink)
2233         {
2234             proto_tree_add_item(tree, hf_fp_quality_estimate, tvb, offset, 1, FALSE);
2235             offset++;
2236         }
2237
2238         /* CRCI bits (uplink only) */
2239         if (p_fp_info->is_uplink)
2240         {
2241             offset = dissect_crci_bits(tvb, pinfo, tree, p_fp_info, offset);
2242         }
2243
2244         /* Spare extension and payload CRC (optional) */
2245         dissect_spare_extension_and_crc(tvb, pinfo, tree,
2246                                         p_fp_info->dch_crc_present, offset);
2247     }
2248 }
2249
2250
2251
2252 /**********************************/
2253 /* Dissect an E-DCH channel       */
2254 static void dissect_e_dch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2255                                        int offset, struct fp_info *p_fp_info)
2256 {
2257     gboolean is_control_frame;
2258     guint8   number_of_subframes;
2259     guint8   cfn;
2260     int      n;
2261     struct   subframe_info subframes[16];
2262
2263     /* Header CRC */
2264     proto_tree_add_item(tree, hf_fp_edch_header_crc, tvb, offset, 2, FALSE);
2265
2266     /* Frame Type */
2267     is_control_frame = tvb_get_guint8(tvb, offset) & 0x01;
2268     proto_tree_add_item(tree, hf_fp_ft, tvb, offset, 1, FALSE);
2269     offset++;
2270
2271     col_append_str(pinfo->cinfo, COL_INFO, is_control_frame ? " [Control] " : " [Data] ");
2272
2273     if (is_control_frame)
2274     {
2275         /* DCH control frame */
2276         dissect_dch_control_frame(tree, pinfo, tvb, offset, p_fp_info);
2277     }
2278     else
2279     {
2280         /********************************/
2281         /* E-DCH data here              */
2282
2283         guint  bit_offset = 0;
2284         guint  total_pdus = 0;
2285         guint  total_bits = 0;
2286         gboolean dissected = FALSE;
2287
2288         /* FSN */
2289         proto_tree_add_item(tree, hf_fp_edch_fsn, tvb, offset, 1, FALSE);
2290         offset++;
2291
2292         /* Number of subframes.
2293            This was 3 bits in early releases, is 4 bits offset by 1 in later releases  */
2294         if ((p_fp_info->release >= 6) &&
2295             ((p_fp_info->release_year > 2005) ||
2296              (p_fp_info->release_year == 2005 && p_fp_info->release_month >= 9)))
2297         {
2298             /* Use 4 bits plus offset of 1 */
2299             number_of_subframes = (tvb_get_guint8(tvb, offset) & 0x0f) + 1;
2300         }
2301         else
2302         {
2303             /* Use 3 bits only */
2304             number_of_subframes = (tvb_get_guint8(tvb, offset) & 0x07);
2305         }
2306         proto_tree_add_uint(tree, hf_fp_edch_number_of_subframes, tvb, offset, 1,
2307                             number_of_subframes);
2308
2309         offset++;
2310
2311         /* CFN */
2312         cfn = tvb_get_guint8(tvb, offset);
2313         proto_tree_add_item(tree, hf_fp_cfn, tvb, offset, 1, FALSE);
2314         offset++;
2315
2316         /* EDCH subframe header list */
2317         for (n=0; n < number_of_subframes; n++)
2318         {
2319             int i;
2320             int start_offset = offset;
2321             proto_item *subframe_header_ti;
2322             proto_tree *subframe_header_tree;
2323
2324             /* Add subframe header subtree */
2325             subframe_header_ti = proto_tree_add_string_format(tree, hf_fp_edch_subframe_header, tvb, offset, 0,
2326                                                               "", "Subframe");
2327             subframe_header_tree = proto_item_add_subtree(subframe_header_ti, ett_fp_edch_subframe_header);
2328
2329             /* Number of HARQ Retransmissions */
2330             proto_tree_add_item(subframe_header_tree, hf_fp_edch_harq_retransmissions, tvb,
2331                                 offset, 1, FALSE);
2332
2333             /* Subframe number */
2334             subframes[n].subframe_number = (tvb_get_guint8(tvb, offset) & 0x07);
2335             proto_tree_add_item(subframe_header_tree, hf_fp_edch_subframe_number, tvb,
2336                                 offset, 1, FALSE);
2337             offset++;
2338
2339             /* Number of MAC-es PDUs */
2340             subframes[n].number_of_mac_es_pdus = (tvb_get_guint8(tvb, offset) & 0xf0) >> 4;
2341             proto_tree_add_item(subframe_header_tree, hf_fp_edch_number_of_mac_es_pdus,
2342                                 tvb, offset, 1, FALSE);
2343             bit_offset = 4;
2344
2345             proto_item_append_text(subframe_header_ti, " %u header (%u MAC-es PDUs)",
2346                                    subframes[n].subframe_number,
2347                                    subframes[n].number_of_mac_es_pdus);
2348
2349             /* Details of each MAC-es PDU */
2350             for (i=0; i < subframes[n].number_of_mac_es_pdus; i++)
2351             {
2352                 guint64 ddi;
2353                 int     ddi_offset;
2354                 guint64 n_pdus;
2355                 int     n_pdus_offset;
2356
2357                 /* DDI (6 bits) */
2358                 ddi_offset = offset + (bit_offset / 8);
2359
2360                 proto_tree_add_bits_ret_val(subframe_header_tree, hf_fp_edch_ddi, tvb,
2361                                             offset*8 + bit_offset, 6, &ddi, FALSE);
2362
2363                 subframes[n].ddi[i] = (guint8)ddi;
2364                 bit_offset += 6;
2365
2366                 /* Number of MAC-d PDUs (6 bits) */
2367                 n_pdus_offset = offset + (bit_offset / 8);
2368
2369                 proto_tree_add_bits_ret_val(subframe_header_tree, hf_fp_edch_number_of_mac_d_pdus, tvb,
2370                                             offset*8 + bit_offset, 6, &n_pdus, FALSE);
2371
2372                 subframes[n].number_of_mac_d_pdus[i] = (guint8)n_pdus;
2373                 bit_offset += 6;
2374             }
2375
2376             offset += ((bit_offset+7)/8);
2377
2378             /* Tree should cover entire subframe header */
2379             proto_item_set_len(subframe_header_ti, offset - start_offset);
2380         }
2381
2382         /* EDCH subframes */
2383         bit_offset = 0;
2384         for (n=0; n < number_of_subframes; n++)
2385         {
2386             int i;
2387             proto_item *subframe_ti;
2388             proto_tree *subframe_tree;
2389             guint bits_in_subframe = 0;
2390             guint mac_d_pdus_in_subframe = 0;
2391
2392             bit_offset = 0;
2393
2394             /* Add subframe subtree */
2395             subframe_ti = proto_tree_add_string_format(tree, hf_fp_edch_subframe, tvb, offset, 0,
2396                                                        "", "Subframe %u data", subframes[n].subframe_number);
2397             subframe_tree = proto_item_add_subtree(subframe_ti, ett_fp_edch_subframe);
2398
2399             for (i=0; i < subframes[n].number_of_mac_es_pdus; i++)
2400             {
2401                 int         m;
2402                 guint16     size = 0;
2403                 guint8      tsn;
2404                 guint       send_size;
2405                 proto_item  *ti;
2406                 int         macd_idx;
2407
2408                 /* Look up mac-d pdu size for this ddi */
2409                 for (m=0; m < p_fp_info->no_ddi_entries; m++)
2410                 {
2411                     if (subframes[n].ddi[i] == p_fp_info->edch_ddi[m])
2412                     {
2413                         size = p_fp_info->edch_macd_pdu_size[m];
2414                         break;
2415                     }
2416                 }
2417
2418                 if (m == p_fp_info->no_ddi_entries)
2419                 {
2420                     /* Not found.  Oops */
2421                     return;
2422                 }
2423
2424                 /* Send MAC-dd PDUs together as one MAC-es PDU */
2425                 send_size = size * subframes[n].number_of_mac_d_pdus[i];
2426
2427                 /* 2 bits spare */
2428                 proto_tree_add_item(subframe_tree, hf_fp_edch_pdu_padding, tvb,
2429                                     offset + (bit_offset/8),
2430                                     1, FALSE);
2431                 bit_offset += 2;
2432
2433                 /* TSN */
2434                 tsn = (tvb_get_guint8(tvb, offset + (bit_offset/8)) & 0x3f);
2435                 proto_tree_add_item(subframe_tree, hf_fp_edch_tsn, tvb,
2436                                     offset + (bit_offset/8),
2437                                     1, FALSE);
2438                 bit_offset += 6;
2439
2440                 /* PDU */
2441                 if (subframe_tree)
2442                 {
2443                     ti = proto_tree_add_item(subframe_tree, hf_fp_edch_mac_es_pdu, tvb,
2444                                              offset + (bit_offset/8),
2445                                              ((bit_offset % 8) + send_size + 7) / 8,
2446                                              FALSE);
2447                     proto_item_append_text(ti, " (%u * %u = %u bits, subframe %d)",
2448                                            size, subframes[n].number_of_mac_d_pdus[i],
2449                                            send_size, n);
2450                 }
2451                 for (macd_idx = 0; macd_idx < subframes[n].number_of_mac_d_pdus[i]; macd_idx++) {
2452                     tvbuff_t *next_tvb;
2453                     pinfo->fd->subnum = macd_idx; /* set subframe number to current TB */
2454                     if (preferences_call_mac_dissectors) {
2455                         /* create new TVB and pass further on */
2456                         next_tvb = tvb_new_subset(tvb, offset + bit_offset/8,
2457                                 ((bit_offset % 8) + size + 7) / 8, -1);
2458                         call_dissector(mac_fdd_edch_handle, next_tvb, pinfo, top_level_tree);
2459                         dissected = TRUE;
2460                     }
2461                     bit_offset += size;
2462                 }
2463
2464                 bits_in_subframe += send_size;
2465                 mac_d_pdus_in_subframe += subframes[n].number_of_mac_d_pdus[i];
2466
2467                 /* Pad out to next byte */
2468                 if (bit_offset % 8)
2469                 {
2470                     bit_offset += (8 - (bit_offset % 8));
2471                 }
2472             }
2473
2474             if (tree)
2475             {
2476                 /* Tree should cover entire subframe */
2477                 proto_item_set_len(subframe_ti, bit_offset/8);
2478                 /* Append summary info to subframe label */
2479                 proto_item_append_text(subframe_ti, " (%u bits in %u MAC-d PDUs)",
2480                                        bits_in_subframe, mac_d_pdus_in_subframe);
2481             }
2482             total_pdus += mac_d_pdus_in_subframe;
2483             total_bits += bits_in_subframe;
2484
2485             offset += (bit_offset/8);
2486         }
2487
2488         /* Report number of subframes in info column
2489          * do this only if no other dissector was called */
2490         if (dissected == FALSE)
2491         {
2492             col_append_fstr(pinfo->cinfo, COL_INFO,
2493                             " CFN = %03u   (%u bits in %u pdus in %u subframes)",
2494                             cfn, total_bits, total_pdus, number_of_subframes);
2495         }
2496
2497         /* Spare extension and payload CRC (optional) */
2498         dissect_spare_extension_and_crc(tvb, pinfo, tree,
2499                                         p_fp_info->dch_crc_present, offset);
2500     }
2501 }
2502
2503
2504 /**********************************************************/
2505 /* Dissect an HSDSCH channel                              */
2506 /* The data format corresponds to the format              */
2507 /* described in R5 and R6, and frame type 1 in Release 7. */
2508 static void dissect_hsdsch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2509                                         int offset, struct fp_info *p_fp_info)
2510 {
2511     gboolean is_control_frame;
2512
2513     /* Header CRC */
2514     proto_tree_add_item(tree, hf_fp_header_crc, tvb, offset, 1, FALSE);
2515
2516     /* Frame Type */
2517     is_control_frame = tvb_get_guint8(tvb, offset) & 0x01;
2518     proto_tree_add_item(tree, hf_fp_ft, tvb, offset, 1, FALSE);
2519     offset++;
2520
2521     col_append_str(pinfo->cinfo, COL_INFO, is_control_frame ? " [Control] " : " [Data] ");
2522
2523     if (is_control_frame)
2524     {
2525         dissect_common_control(tvb, pinfo, tree, offset, p_fp_info);
2526     }
2527     else
2528     {
2529         guint8 number_of_pdus;
2530         guint16 pdu_length;
2531         guint16 user_buffer_size;
2532
2533         /**************************************/
2534         /* HS-DCH data here (type 1 in R7)    */
2535
2536         /* Frame Seq Nr */
2537         if ((p_fp_info->release == 6) ||
2538             (p_fp_info->release == 7))
2539         {
2540             guint8 frame_seq_no = (tvb_get_guint8(tvb, offset) & 0xf0) >> 4;
2541             proto_tree_add_item(tree, hf_fp_frame_seq_nr, tvb, offset, 1, FALSE);
2542
2543             col_append_fstr(pinfo->cinfo, COL_INFO, "  seqno=%u", frame_seq_no);
2544         }
2545
2546         /* CmCH-PI */
2547         proto_tree_add_item(tree, hf_fp_cmch_pi, tvb, offset, 1, FALSE);
2548         offset++;
2549
2550         /* MAC-d PDU Length (13 bits) */
2551         pdu_length = (tvb_get_ntohs(tvb, offset) >> 3);
2552         proto_tree_add_item(tree, hf_fp_mac_d_pdu_len, tvb, offset, 2, FALSE);
2553         offset += 2;
2554
2555         if ((p_fp_info->release == 6) ||
2556             (p_fp_info->release == 7))
2557         {
2558             /* Flush bit */
2559             proto_tree_add_item(tree, hf_fp_flush, tvb, offset-1, 1, FALSE);
2560
2561             /* FSN/DRT reset bit */
2562             proto_tree_add_item(tree, hf_fp_fsn_drt_reset, tvb, offset-1, 1, FALSE);
2563         }
2564
2565
2566         /* Num of PDUs */
2567         number_of_pdus = tvb_get_guint8(tvb, offset);
2568         proto_tree_add_item(tree, hf_fp_num_of_pdu, tvb, offset, 1, FALSE);
2569         offset++;
2570
2571         /* User buffer size */
2572         user_buffer_size = tvb_get_ntohs(tvb, offset);
2573         proto_tree_add_item(tree, hf_fp_user_buffer_size, tvb, offset, 2, FALSE);
2574         offset += 2;
2575
2576         /* MAC-d PDUs */
2577         offset = dissect_macd_pdu_data(tvb, pinfo, tree, offset, pdu_length,
2578                                        number_of_pdus);
2579
2580         col_append_fstr(pinfo->cinfo, COL_INFO, "  %ux%u-bit PDUs  User-Buffer-Size=%u",
2581                         number_of_pdus, pdu_length, user_buffer_size);
2582
2583         /* Extra IEs (if there is room for them) */
2584         if (((p_fp_info->release == 6) ||
2585              (p_fp_info->release == 7)) &&
2586             (tvb_length_remaining(tvb, offset) > 2))
2587         {
2588             int n;
2589             guint8 flags;
2590             guint8 flag_bytes = 0;
2591
2592             /* New IE flags */
2593             do
2594             {
2595                 proto_item *new_ie_flags_ti;
2596                 proto_tree *new_ie_flags_tree;
2597                 guint ies_found = 0;
2598
2599                 /* Add new IE flags subtree */
2600                 new_ie_flags_ti = proto_tree_add_string_format(tree, hf_fp_hsdsch_new_ie_flags, tvb, offset, 1,
2601                                                               "", "New IE flags");
2602                 new_ie_flags_tree = proto_item_add_subtree(new_ie_flags_ti, ett_fp_hsdsch_new_ie_flags);
2603
2604                 /* Read next byte */
2605                 flags = tvb_get_guint8(tvb, offset);
2606                 flag_bytes++;
2607
2608                 /* Dissect individual bits */
2609                 for (n=0; n < 8; n++)
2610                 {
2611                     proto_tree_add_item(new_ie_flags_tree, hf_fp_hsdsch_new_ie_flag[n], tvb, offset, 1, FALSE);
2612                     if ((flags >> (7-n)) & 0x01)
2613                     {
2614                         ies_found++;
2615                     }
2616                 }
2617                 offset++;
2618
2619                 proto_item_append_text(new_ie_flags_ti, " (%u IEs found)", ies_found);
2620
2621                 /* Last bit set will indicate another flags byte follows... */
2622             } while (0); /*((flags & 0x01) && (flag_bytes < 31));*/
2623
2624             if (1) /*(flags & 0x8) */
2625             {
2626                 /* DRT is shown as mandatory in the diagram (3GPP TS 25.435 V6.3.0),
2627                    but the description below it states that
2628                    it should depend upon the first bit.  The detailed description of
2629                    New IE flags doesn't agree, so treat as mandatory for now... */
2630                 proto_tree_add_item(tree, hf_fp_hsdsch_drt, tvb, offset, 2, FALSE);
2631                 offset += 2;
2632             }
2633         }
2634
2635         /* Spare Extension and Payload CRC */
2636         dissect_spare_extension_and_crc(tvb, pinfo, tree, 1, offset);
2637     }
2638 }
2639
2640
2641 /******************************************/
2642 /* Dissect an HSDSCH type 2 channel       */
2643 /* (introduced in Release 7)              */
2644 /* N.B. there is currently no support for */
2645 /* frame type 3 (IuR only?)               */
2646 static void dissect_hsdsch_type_2_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2647                                                int offset, struct fp_info *p_fp_info)
2648 {
2649     gboolean is_control_frame;
2650
2651     /* Header CRC */
2652     proto_tree_add_item(tree, hf_fp_header_crc, tvb, offset, 1, FALSE);
2653
2654     /* Frame Type */
2655     is_control_frame = tvb_get_guint8(tvb, offset) & 0x01;
2656     proto_tree_add_item(tree, hf_fp_ft, tvb, offset, 1, FALSE);
2657     offset++;
2658
2659     col_append_str(pinfo->cinfo, COL_INFO, is_control_frame ? " [Control] " : " [Data] ");
2660
2661     if (is_control_frame)
2662     {
2663         dissect_common_control(tvb, pinfo, tree, offset, p_fp_info);
2664     }
2665     else
2666     {
2667         guint8 number_of_pdu_blocks;
2668         gboolean drt_present = FALSE;
2669         gboolean fach_present = FALSE;
2670         guint16 user_buffer_size;
2671         int n;
2672
2673         #define MAX_PDU_BLOCKS 31
2674         guint64 lchid[MAX_PDU_BLOCKS];
2675         guint64 pdu_length[MAX_PDU_BLOCKS];
2676         guint64 no_of_pdus[MAX_PDU_BLOCKS];
2677
2678         /********************************/
2679         /* HS-DCH type 2 data here      */
2680
2681         col_append_str(pinfo->cinfo, COL_INFO, "(ehs)");
2682
2683         /* Frame Seq Nr (4 bits) */
2684         if ((p_fp_info->release == 6) ||
2685             (p_fp_info->release == 7))
2686         {
2687             guint8 frame_seq_no = (tvb_get_guint8(tvb, offset) & 0xf0) >> 4;
2688             proto_tree_add_item(tree, hf_fp_frame_seq_nr, tvb, offset, 1, FALSE);
2689
2690             col_append_fstr(pinfo->cinfo, COL_INFO, "  seqno=%u", frame_seq_no);
2691         }
2692
2693         /* CmCH-PI (4 bits) */
2694         proto_tree_add_item(tree, hf_fp_cmch_pi, tvb, offset, 1, FALSE);
2695         offset++;
2696
2697         /* Total number of PDU blocks (5 bits) */
2698         number_of_pdu_blocks = (tvb_get_guint8(tvb, offset) >> 3);
2699         proto_tree_add_item(tree, hf_fp_total_pdu_blocks, tvb, offset, 1, FALSE);
2700
2701         if (p_fp_info->release == 7)
2702         {
2703             /* Flush bit */
2704             proto_tree_add_item(tree, hf_fp_flush, tvb, offset, 1, FALSE);
2705
2706             /* FSN/DRT reset bit */
2707             proto_tree_add_item(tree, hf_fp_fsn_drt_reset, tvb, offset, 1, FALSE);
2708
2709             /* DRT Indicator */
2710             drt_present = tvb_get_guint8(tvb, offset) & 0x01;
2711             proto_tree_add_item(tree, hf_fp_drt_indicator, tvb, offset, 1, FALSE);
2712         }
2713         offset++;
2714
2715         /* FACH Indicator flag */
2716         fach_present = (tvb_get_guint8(tvb, offset) & 0x08) >> 7;
2717         proto_tree_add_item(tree, hf_fp_fach_indicator, tvb, offset, 1, FALSE);
2718         offset++;
2719
2720         /* User buffer size */
2721         user_buffer_size = tvb_get_ntohs(tvb, offset);
2722         proto_tree_add_item(tree, hf_fp_user_buffer_size, tvb, offset, 2, FALSE);
2723         offset += 2;
2724
2725         col_append_fstr(pinfo->cinfo, COL_INFO, "  User-Buffer-Size=%u", user_buffer_size);
2726
2727
2728         /********************************************************************/
2729         /* Now read number_of_pdu_blocks header entries                     */
2730         for (n=0; n < number_of_pdu_blocks; n++)
2731         {
2732             proto_item *pdu_block_header_ti;
2733             proto_tree *pdu_block_header_tree;
2734
2735             /* Add PDU block header subtree */
2736             pdu_block_header_ti = proto_tree_add_string_format(tree, hf_fp_hsdsch_pdu_block_header,
2737                                                                tvb, offset, 0,
2738                                                                "",
2739                                                                "PDU Block Header");
2740             pdu_block_header_tree = proto_item_add_subtree(pdu_block_header_ti,
2741                                                            ett_fp_hsdsch_pdu_block_header);
2742
2743             /* MAC-d/c PDU length in this block (11 bits) */
2744             proto_tree_add_bits_ret_val(pdu_block_header_tree, hf_fp_pdu_length_in_block, tvb,
2745                                         (offset*8) + ((n % 2) ? 4 : 0), 11,
2746                                         &pdu_length[n], FALSE);
2747             if ((n % 2) == 0)
2748                 offset++;
2749             else
2750                 offset += 2;
2751
2752
2753             /* # PDUs in this block (4 bits) */
2754             proto_tree_add_bits_ret_val(pdu_block_header_tree, hf_fp_pdus_in_block, tvb,
2755                                         (offset*8) + ((n % 2) ? 0 : 4), 4,
2756                                         &no_of_pdus[n], FALSE);
2757             if ((n % 2) == 0)
2758                 offset++;
2759
2760             /* Logical channel ID in block (4 bits) */
2761             proto_tree_add_bits_ret_val(pdu_block_header_tree, hf_fp_lchid, tvb,
2762                                         (offset*8) + ((n % 2) ? 4 : 0), 4,
2763                                         &lchid[n], FALSE);
2764             if ((n % 2) == 1)
2765                 offset++;
2766             else {
2767                 if (n == (number_of_pdu_blocks-1)) {
2768                     /* Byte is padded out for last block */
2769                     offset++;
2770                 }
2771             }
2772
2773             /* Append summary to header tree root */
2774             proto_item_append_text(pdu_block_header_ti,
2775                                    " (lch:%u, %u pdus of %u bytes)",
2776                                    (guint16)lchid[n],
2777                                    (guint16)no_of_pdus[n],
2778                                    (guint16)pdu_length[n]);
2779         }
2780
2781
2782         /**********************************************/
2783         /* Optional fields indicated by earlier flags */
2784         if (drt_present)
2785         {
2786             /* DRT */
2787             proto_tree_add_item(tree, hf_fp_drt, tvb, offset, 2, FALSE);
2788             offset += 2;
2789         }
2790
2791         if (fach_present)
2792         {
2793             /* H-RNTI: */
2794             proto_tree_add_item(tree, hf_fp_hrnti, tvb, offset, 2, FALSE);
2795             offset += 2;
2796
2797             /* RACH Measurement Result */
2798             proto_tree_add_item(tree, hf_fp_rach_measurement_result, tvb, offset, 2, FALSE);
2799             offset++;
2800         }
2801
2802
2803         /********************************************************************/
2804         /* Now read the MAC-d/c PDUs for each block using info from headers */
2805         for (n=0; n < number_of_pdu_blocks; n++)
2806         {
2807             /* Add PDU block header subtree */
2808             offset = dissect_macd_pdu_data_type_2(tvb, pinfo, tree, offset,
2809                                                   (guint16)pdu_length[n],
2810                                                   (guint16)no_of_pdus[n]);
2811         }
2812
2813         /* Spare Extension and Payload CRC */
2814         dissect_spare_extension_and_crc(tvb, pinfo, tree, 1, offset);
2815     }
2816 }
2817
2818 static gboolean heur_dissect_fp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2819 {
2820     struct fp_info *p_fp_info;
2821
2822     p_fp_info = p_get_proto_data(pinfo->fd, proto_fp);
2823
2824     /* if no FP info is present, assume this is not FP over UDP */
2825     if (!p_fp_info) return FALSE;
2826
2827     /* if FP info is present, check that it really is an ethernet link */
2828     if (p_fp_info->link_type != FP_Link_Ethernet) {
2829         return FALSE;
2830     }
2831
2832     /* remember 'lower' UDP layer port information */
2833     if (!p_fp_info->srcport || !p_fp_info->destport) {
2834         p_fp_info->srcport = pinfo->srcport;
2835         p_fp_info->destport = pinfo->destport;
2836     }    
2837
2838     /* discriminate 'lower' UDP layer from 'user data' UDP layer
2839      * (i.e. if an FP over UDP packet contains a user UDP packet */
2840     if (p_fp_info->srcport != pinfo->srcport ||
2841         p_fp_info->destport != pinfo->destport)
2842         return FALSE;
2843
2844     /* assume this is FP */
2845     dissect_fp(tvb, pinfo, tree);
2846     return TRUE;
2847 }
2848
2849
2850 /*****************************/
2851 /* Main dissection function. */
2852 void dissect_fp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2853 {
2854     proto_tree       *fp_tree;
2855     proto_item       *ti;
2856     gint             offset = 0;
2857     struct fp_info   *p_fp_info;
2858
2859     /* Append this protocol name rather than replace. */
2860     col_set_str(pinfo->cinfo, COL_PROTOCOL, "FP");
2861
2862     /* Create fp tree. */
2863     ti = proto_tree_add_item(tree, proto_fp, tvb, offset, -1, FALSE);
2864     fp_tree = proto_item_add_subtree(ti, ett_fp);
2865
2866     top_level_tree = tree;
2867
2868     /* Look for packet info! */
2869     p_fp_info = p_get_proto_data(pinfo->fd, proto_fp);
2870
2871     /* Can't dissect anything without it... */
2872     if (p_fp_info == NULL)
2873     {
2874         ti = proto_tree_add_text(fp_tree, tvb, offset, -1,
2875                                 "Can't dissect FP frame because no per-frame info was attached!");
2876         PROTO_ITEM_SET_GENERATED(ti);
2877         return;
2878     }
2879
2880     /* Show channel type in info column, tree */
2881     col_add_str(pinfo->cinfo, COL_INFO,
2882                 val_to_str(p_fp_info->channel,
2883                            channel_type_vals,
2884                            "Unknown channel type"));
2885     proto_item_append_text(ti, " (%s)",
2886                            val_to_str(p_fp_info->channel,
2887                                       channel_type_vals,
2888                                       "Unknown channel type"));
2889
2890     /* Add channel type as a generated field */
2891     ti = proto_tree_add_uint(fp_tree, hf_fp_channel_type, tvb, 0, 0, p_fp_info->channel);
2892     PROTO_ITEM_SET_GENERATED(ti);
2893
2894     /* Add division type as a generated field */
2895     if (p_fp_info->release == 7)
2896     {
2897         ti = proto_tree_add_uint(fp_tree, hf_fp_division, tvb, 0, 0, p_fp_info->division);
2898         PROTO_ITEM_SET_GENERATED(ti);
2899     }
2900
2901     /* Add link direction as a generated field */
2902     ti = proto_tree_add_uint(fp_tree, hf_fp_direction, tvb, 0, 0, p_fp_info->is_uplink);
2903     PROTO_ITEM_SET_GENERATED(ti);
2904
2905     /* Don't currently handle IuR-specific formats, but its useful to even see
2906        the channel type and direction */
2907     if (p_fp_info->iface_type == IuR_Interface)
2908     {
2909         return;
2910     }
2911
2912     /*************************************/
2913     /* Dissect according to channel type */
2914     switch (p_fp_info->channel)
2915     {
2916         case CHANNEL_RACH_TDD:
2917         case CHANNEL_RACH_TDD_128:
2918         case CHANNEL_RACH_FDD:
2919              dissect_rach_channel_info(tvb, pinfo, fp_tree, offset, p_fp_info);
2920             break;
2921         case CHANNEL_DCH:
2922             dissect_dch_channel_info(tvb, pinfo, fp_tree, offset, p_fp_info);
2923             break;
2924         case CHANNEL_FACH_FDD:
2925         case CHANNEL_FACH_TDD:
2926             dissect_fach_channel_info(tvb, pinfo, fp_tree, offset, p_fp_info);
2927             break;
2928         case CHANNEL_DSCH_FDD:
2929         case CHANNEL_DSCH_TDD:
2930             dissect_dsch_channel_info(tvb, pinfo, fp_tree, offset, p_fp_info);
2931             break;
2932         case CHANNEL_USCH_TDD_128:
2933         case CHANNEL_USCH_TDD_384:
2934             dissect_usch_channel_info(tvb, pinfo, fp_tree, offset, p_fp_info);
2935             break;
2936         case CHANNEL_PCH:
2937             dissect_pch_channel_info(tvb, pinfo, fp_tree, offset, p_fp_info);
2938             break;
2939         case CHANNEL_CPCH:
2940             dissect_cpch_channel_info(tvb, pinfo, fp_tree, offset, p_fp_info);
2941             break;
2942         case CHANNEL_BCH:
2943             dissect_bch_channel_info(tvb, pinfo, fp_tree, offset, p_fp_info);
2944             break;
2945         case CHANNEL_HSDSCH:
2946             /* Show configured MAC HS-DSCH entity in use */
2947             if (fp_tree)
2948             {
2949                 proto_item *entity_ti;
2950                 entity_ti = proto_tree_add_uint(fp_tree, hf_fp_hsdsch_entity,
2951                                                 tvb, 0, 0,
2952                                                 p_fp_info->hsdsch_entity);
2953                 PROTO_ITEM_SET_GENERATED(entity_ti);
2954             }
2955             switch (p_fp_info->hsdsch_entity) {
2956                 case entity_not_specified:
2957                 case hs:
2958                     /* This is the pre-R7 default */
2959                     dissect_hsdsch_channel_info(tvb, pinfo, fp_tree, offset, p_fp_info);
2960                     break;
2961                 case ehs:
2962                     dissect_hsdsch_type_2_channel_info(tvb, pinfo, fp_tree, offset, p_fp_info);
2963                     break;
2964                 default:
2965                     /* TODO: dissector error */
2966                     break;
2967             }
2968             break;
2969         case CHANNEL_IUR_CPCHF:
2970             /* TODO: */
2971             break;
2972         case CHANNEL_IUR_FACH:
2973             /* TODO: */
2974             break;
2975         case CHANNEL_IUR_DSCH:
2976             dissect_iur_dsch_channel_info(tvb, pinfo, fp_tree, offset, p_fp_info);
2977             break;
2978         case CHANNEL_EDCH:
2979             dissect_e_dch_channel_info(tvb, pinfo, fp_tree, offset, p_fp_info);
2980             break;
2981
2982         default:
2983             break;
2984     }
2985 }
2986
2987
2988 void proto_register_fp(void)
2989 {
2990     static hf_register_info hf[] =
2991     {
2992         { &hf_fp_channel_type,
2993             { "Channel Type",
2994               "fp.channel-type", FT_UINT8, BASE_HEX, VALS(channel_type_vals), 0x0,
2995               NULL, HFILL
2996             }
2997         },
2998         { &hf_fp_division,
2999             { "Division",
3000               "fp.division", FT_UINT8, BASE_HEX, VALS(division_vals), 0x0,
3001               "Radio division type", HFILL
3002             }
3003         },
3004         { &hf_fp_direction,
3005             { "Direction",
3006               "fp.direction", FT_UINT8, BASE_HEX, VALS(direction_vals), 0x0,
3007               "Link direction", HFILL
3008             }
3009         },
3010         { &hf_fp_header_crc,
3011             { "Header CRC",
3012               "fp.header-crc", FT_UINT8, BASE_HEX, NULL, 0xfe,
3013               NULL, HFILL
3014             }
3015         },
3016         { &hf_fp_ft,
3017             { "Frame Type",
3018               "fp.ft", FT_UINT8, BASE_HEX, VALS(data_control_vals), 0x01,
3019               NULL, HFILL
3020             }
3021         },
3022         { &hf_fp_cfn,
3023             { "CFN",
3024               "fp.cfn", FT_UINT8, BASE_DEC, NULL, 0x0,
3025               "Connection Frame Number", HFILL
3026             }
3027         },
3028         { &hf_fp_pch_cfn,
3029             { "CFN (PCH)",
3030               "fp.pch.cfn", FT_UINT16, BASE_DEC, NULL, 0xfff0,
3031               "PCH Connection Frame Number", HFILL
3032             }
3033         },
3034         { &hf_fp_pch_toa,
3035             { "ToA (PCH)",
3036               "fp.pch.toa", FT_INT24, BASE_DEC, NULL, 0x0,
3037               "PCH Time of Arrival", HFILL
3038             }
3039         },
3040         { &hf_fp_cfn_control,
3041             { "CFN control",
3042               "fp.cfn-control", FT_UINT8, BASE_DEC, NULL, 0x0,
3043               "Connection Frame Number Control", HFILL
3044             }
3045         },
3046         { &hf_fp_toa,
3047             { "ToA",
3048               "fp.cfn-control", FT_INT16, BASE_DEC, NULL, 0x0,
3049               "Time of arrival (units are 125 microseconds)", HFILL
3050             }
3051         },
3052         { &hf_fp_tb,
3053             { "TB",
3054               "fp.tb", FT_BYTES, BASE_NONE, NULL, 0x0,
3055               "Transport Block", HFILL
3056             }
3057         },
3058         { &hf_fp_chan_zero_tbs,
3059             { "No TBs for channel",
3060               "fp.channel-with-zero-tbs", FT_UINT32, BASE_DEC, NULL, 0x0,
3061               "Channel with 0 TBs", HFILL
3062             }
3063         },
3064         { &hf_fp_tfi,
3065             { "TFI",
3066               "fp.tfi", FT_UINT8, BASE_DEC, NULL, 0x0,
3067               "Transport Format Indicator", HFILL
3068             }
3069         },
3070         { &hf_fp_usch_tfi,
3071             { "TFI",
3072               "fp.usch.tfi", FT_UINT8, BASE_DEC, NULL, 0x1f,
3073               "USCH Transport Format Indicator", HFILL
3074             }
3075         },
3076         { &hf_fp_cpch_tfi,
3077             { "TFI",
3078               "fp.cpch.tfi", FT_UINT8, BASE_DEC, NULL, 0x1f,
3079               "CPCH Transport Format Indicator", HFILL
3080             }
3081         },
3082         { &hf_fp_propagation_delay,
3083             { "Propagation Delay",
3084               "fp.propagation-delay", FT_UINT8, BASE_DEC, NULL, 0x0,
3085               NULL, HFILL
3086             }
3087         },
3088         { &hf_fp_dch_control_frame_type,
3089             { "Control Frame Type",
3090               "fp.dch.control.frame-type", FT_UINT8, BASE_HEX, VALS(dch_control_frame_type_vals), 0x0,
3091               "DCH Control Frame Type", HFILL
3092             }
3093         },
3094         { &hf_fp_dch_rx_timing_deviation,
3095             { "Rx Timing Deviation",
3096               "fp.dch.control.rx-timing-deviation", FT_UINT8, BASE_DEC, 0, 0x0,
3097               "DCH Rx Timing Deviation", HFILL
3098             }
3099         },
3100         { &hf_fp_quality_estimate,
3101             { "Quality Estimate",
3102               "fp.dch.quality-estimate", FT_UINT8, BASE_DEC, 0, 0x0,
3103               NULL, HFILL
3104             }
3105         },
3106         { &hf_fp_payload_crc,
3107             { "Payload CRC",
3108               "fp.payload-crc", FT_UINT16, BASE_HEX, 0, 0x0,
3109               NULL, HFILL
3110             }
3111         },
3112         { &hf_fp_common_control_frame_type,
3113             { "Control Frame Type",
3114               "fp.common.control.frame-type", FT_UINT8, BASE_HEX, VALS(common_control_frame_type_vals), 0x0,
3115               "Common Control Frame Type", HFILL
3116             }
3117         },
3118         { &hf_fp_crci[0],
3119             { "CRCI",
3120               "fp.crci", FT_UINT8, BASE_HEX, VALS(crci_vals), 0x80,
3121               "CRC correctness indicator", HFILL
3122             }
3123         },
3124         { &hf_fp_crci[1],
3125             { "CRCI",
3126               "fp.crci", FT_UINT8, BASE_HEX, VALS(crci_vals), 0x40,
3127               "CRC correctness indicator", HFILL
3128             }
3129         },
3130         { &hf_fp_crci[2],
3131             { "CRCI",
3132               "fp.crci", FT_UINT8, BASE_HEX, VALS(crci_vals), 0x20,
3133               "CRC correctness indicator", HFILL
3134             }
3135         },
3136         { &hf_fp_crci[3],
3137             { "CRCI",
3138               "fp.crci", FT_UINT8, BASE_HEX, VALS(crci_vals), 0x10,
3139               "CRC correctness indicator", HFILL
3140             }
3141         },
3142         { &hf_fp_crci[4],
3143             { "CRCI",
3144               "fp.crci", FT_UINT8, BASE_HEX, VALS(crci_vals), 0x08,
3145               "CRC correctness indicator", HFILL
3146             }
3147         },
3148         { &hf_fp_crci[5],
3149             { "CRCI",
3150               "fp.crci", FT_UINT8, BASE_HEX, VALS(crci_vals), 0x04,
3151               "CRC correctness indicator", HFILL
3152             }
3153         },
3154         { &hf_fp_crci[6],
3155             { "CRCI",
3156               "fp.crci", FT_UINT8, BASE_HEX, VALS(crci_vals), 0x02,
3157               "CRC correctness indicator", HFILL
3158             }
3159         },
3160         { &hf_fp_crci[7],
3161             { "CRCI",
3162               "fp.crci", FT_UINT8, BASE_HEX, VALS(crci_vals), 0x01,
3163               "CRC correctness indicator", HFILL
3164             }
3165         },
3166         { &hf_fp_received_sync_ul_timing_deviation,
3167             { "Received SYNC UL Timing Deviation",
3168               "fp.rx-sync-ul-timing-deviation", FT_UINT8, BASE_DEC, 0, 0x0,
3169               NULL, HFILL
3170             }
3171         },
3172         { &hf_fp_pch_pi,
3173             { "Paging Indication",
3174               "fp.pch.pi", FT_UINT8, BASE_DEC, VALS(paging_indication_vals), 0x01,
3175               "Indicates if the PI Bitmap is present", HFILL
3176             }
3177         },
3178         { &hf_fp_pch_tfi,
3179             { "TFI",
3180               "fp.pch.tfi", FT_UINT8, BASE_DEC, 0, 0x1f,
3181               "PCH Transport Format Indicator", HFILL
3182             }
3183         },
3184         { &hf_fp_fach_tfi,
3185             { "TFI",
3186               "fp.fach.tfi", FT_UINT8, BASE_DEC, 0, 0x1f,
3187               "FACH Transport Format Indicator", HFILL
3188             }
3189         },
3190         { &hf_fp_transmit_power_level,
3191             { "Transmit Power Level",
3192               "fp.transmit-power-level", FT_FLOAT, BASE_NONE, 0, 0x0,
3193               "Transmit Power Level (dB)", HFILL
3194             }
3195         },
3196         { &hf_fp_pdsch_set_id,
3197             { "PDSCH Set Id",
3198               "fp.pdsch-set-id", FT_UINT8, BASE_DEC, 0, 0x0,
3199               "A pointer to the PDSCH Set which shall be used to transmit", HFILL
3200             }
3201         },
3202         { &hf_fp_paging_indication_bitmap,
3203             { "Paging Indications bitmap",
3204               "fp.pch.pi-bitmap", FT_NONE, BASE_NONE, NULL, 0x0,
3205               "Paging Indication bitmap", HFILL
3206             }
3207         },
3208         { &hf_fp_rx_timing_deviation,
3209             { "Rx Timing Deviation",
3210               "fp.common.control.rx-timing-deviation", FT_UINT8, BASE_DEC, 0, 0x0,
3211               "Common Rx Timing Deviation", HFILL
3212             }
3213         },
3214         { &hf_fp_dch_e_rucch_flag,
3215             { "E-RUCCH Flag",
3216               "fp.common.control.e-rucch-flag", FT_UINT8, BASE_DEC, VALS(e_rucch_flag_vals), 0x0,
3217               NULL, HFILL
3218             }
3219         },
3220         { &hf_fp_edch_header_crc,
3221             { "E-DCH Header CRC",
3222               "fp.edch.header-crc", FT_UINT16, BASE_HEX, 0, 0xfef,
3223               NULL, HFILL
3224             }
3225         },
3226         { &hf_fp_edch_fsn,
3227             { "FSN",
3228               "fp.edch.fsn", FT_UINT8, BASE_DEC, 0, 0x0f,
3229               "E-DCH Frame Sequence Number", HFILL
3230             }
3231         },
3232         { &hf_fp_edch_number_of_subframes,
3233             { "No of subframes",
3234               "fp.edch.no-of-subframes", FT_UINT8, BASE_DEC, 0, 0x0f,
3235               "E-DCH Number of subframes", HFILL
3236             }
3237         },
3238         { &hf_fp_edch_harq_retransmissions,
3239             { "No of HARQ Retransmissions",
3240               "fp.edch.no-of-harq-retransmissions", FT_UINT8, BASE_DEC, 0, 0x78,
3241               "E-DCH Number of HARQ retransmissions", HFILL
3242             }
3243         },
3244         { &hf_fp_edch_subframe_number,
3245             { "Subframe number",
3246               "fp.edch.subframe-number", FT_UINT8, BASE_DEC, 0, 0x07,
3247               "E-DCH Subframe number", HFILL
3248             }
3249         },
3250         { &hf_fp_edch_number_of_mac_es_pdus,
3251             { "Number of Mac-es PDUs",
3252               "fp.edch.number-of-mac-es-pdus", FT_UINT8, BASE_DEC, 0, 0xf0,
3253               NULL, HFILL
3254             }
3255         },
3256         { &hf_fp_edch_ddi,
3257             { "DDI",
3258               "fp.edch.ddi", FT_UINT8, BASE_DEC, 0, 0x0,
3259               "E-DCH Data Description Indicator", HFILL
3260             }
3261         },
3262         { &hf_fp_edch_subframe,
3263             { "Subframe",
3264               "fp.edch.subframe", FT_STRING, BASE_NONE, NULL, 0x0,
3265               "EDCH Subframe", HFILL
3266             }
3267         },
3268         { &hf_fp_edch_subframe_header,
3269             { "Subframe header",
3270               "fp.edch.subframe-header", FT_STRING, BASE_NONE, NULL, 0x0,
3271               "EDCH Subframe header", HFILL
3272             }
3273         },
3274         { &hf_fp_edch_number_of_mac_d_pdus,
3275             { "Number of Mac-d PDUs",
3276               "fp.edch.number-of-mac-d-pdus", FT_UINT8, BASE_DEC, 0, 0x0,
3277               NULL, HFILL
3278             }
3279         },
3280         { &hf_fp_edch_pdu_padding,
3281             { "Padding",
3282               "fp.edch-data-padding", FT_UINT8, BASE_DEC, 0, 0xc0,
3283               "E-DCH padding before PDU", HFILL
3284             }
3285         },
3286         { &hf_fp_edch_tsn,
3287             { "TSN",
3288               "fp.edch-tsn", FT_UINT8, BASE_DEC, 0, 0x3f,
3289               "E-DCH Transmission Sequence Number", HFILL
3290             }
3291         },
3292         { &hf_fp_edch_mac_es_pdu,
3293             { "MAC-es PDU",
3294               "fp.edch.mac-es-pdu", FT_NONE, BASE_NONE, NULL, 0x0,
3295               NULL, HFILL
3296             }
3297         },
3298         { &hf_fp_frame_seq_nr,
3299             { "Frame Seq Nr",
3300               "fp.frame-seq-nr", FT_UINT8, BASE_DEC, 0, 0xf0,
3301               "Frame Sequence Number", HFILL
3302             }
3303         },
3304         { &hf_fp_hsdsch_pdu_block_header,
3305             { "PDU block header",
3306               "fp.hsdsch.pdu-block-header", FT_STRING, BASE_NONE, NULL, 0x0,
3307               "HS-DSCH type 2 PDU block header", HFILL
3308             }
3309         },
3310         { &hf_fp_hsdsch_pdu_block,
3311             { "PDU block",
3312               "fp.hsdsch.pdu-block", FT_STRING, BASE_NONE, NULL, 0x0,
3313               "HS-DSCH type 2 PDU block data", HFILL
3314             }
3315         },
3316         { &hf_fp_flush,
3317             { "Flush",
3318               "fp.flush", FT_UINT8, BASE_DEC, 0, 0x04,
3319               "Whether all PDUs for this priority queue should be removed", HFILL
3320             }
3321         },
3322         { &hf_fp_fsn_drt_reset,
3323             { "FSN-DRT reset",
3324               "fp.fsn-drt-reset", FT_UINT8, BASE_DEC, 0, 0x02,
3325               "FSN/DRT Reset Flag", HFILL
3326             }
3327         },
3328         { &hf_fp_drt_indicator,
3329             { "DRT Indicator",
3330               "fp.drt-indicator", FT_UINT8, BASE_DEC, 0, 0x01,
3331               NULL, HFILL
3332             }
3333         },
3334         { &hf_fp_fach_indicator,
3335             { "FACH Indicator",
3336               "fp.fach-indicator", FT_UINT8, BASE_DEC, 0, 0x80,
3337               NULL, HFILL
3338             }
3339         },
3340         { &hf_fp_total_pdu_blocks,
3341             { "PDU Blocks",
3342               "fp.pdu_blocks", FT_UINT8, BASE_DEC, 0, 0xf8,
3343               "Total number of PDU blocks", HFILL
3344             }
3345         },
3346         { &hf_fp_drt,
3347             { "DRT",
3348               "fp.drt", FT_UINT16, BASE_DEC, 0, 0x0,
3349               NULL, HFILL
3350             }
3351         },
3352         { &hf_fp_hrnti,
3353             { "HRNTI",
3354               "fp.hrnti", FT_UINT16, BASE_DEC, 0, 0x0,
3355               NULL, HFILL
3356             }
3357         },
3358         { &hf_fp_rach_measurement_result,
3359             { "RACH Measurement Result",
3360               "fp.rach-measurement-result", FT_UINT16, BASE_DEC, 0, 0x0,
3361               NULL, HFILL
3362             }
3363         },
3364         { &hf_fp_lchid,
3365             { "Logical Channel ID",
3366               "fp.lchid", FT_UINT8, BASE_DEC, 0, 0x0,
3367               NULL, HFILL
3368             }
3369         },
3370         { &hf_fp_pdu_length_in_block,
3371             { "PDU length in block",
3372               "fp.pdu-length-in-block", FT_UINT8, BASE_DEC, 0, 0x0,
3373               "Length of each PDU in this block in bytes", HFILL
3374             }
3375         },
3376         { &hf_fp_pdus_in_block,
3377             { "PDUs in block",
3378               "fp.no-pdus-in-block", FT_UINT8, BASE_DEC, 0, 0x0,
3379               "Number of PDUs in block", HFILL
3380             }
3381         },
3382         { &hf_fp_cmch_pi,
3383             { "CmCH-PI",
3384               "fp.cmch-pi", FT_UINT8, BASE_DEC, 0, 0x0f,
3385               "Common Transport Channel Priority Indicator", HFILL
3386             }
3387         },
3388         { &hf_fp_user_buffer_size,
3389             { "User buffer size",
3390               "fp.user-buffer-size", FT_UINT16, BASE_DEC, 0, 0x0,
3391               "User buffer size in octets", HFILL
3392             }
3393         },
3394         { &hf_fp_hsdsch_credits,
3395             { "HS-DSCH Credits",
3396               "fp.hsdsch-credits", FT_UINT16, BASE_DEC, 0, 0x0,
3397               NULL, HFILL
3398             }
3399         },
3400         { &hf_fp_hsdsch_max_macd_pdu_len,
3401             { "Max MAC-d PDU Length",
3402               "fp.hsdsch.max-macd-pdu-len", FT_UINT16, BASE_DEC, 0, 0xfff8,
3403               "Maximum MAC-d PDU Length in bits", HFILL
3404             }
3405         },
3406         { &hf_fp_hsdsch_max_macdc_pdu_len,
3407             { "Max MAC-d/c PDU Length",
3408               "fp.hsdsch.max-macdc-pdu-len", FT_UINT16, BASE_DEC, 0, 0x07ff,
3409               "Maximum MAC-d/c PDU Length in bits", HFILL
3410             }
3411         },
3412         { &hf_fp_hsdsch_interval,
3413             { "HS-DSCH Interval in milliseconds",
3414               "fp.hsdsch-interval", FT_UINT8, BASE_DEC, 0, 0x0,
3415               NULL, HFILL
3416             }
3417         },
3418         { &hf_fp_hsdsch_calculated_rate,
3419             { "Calculated rate allocation (bps)",
3420               "fp.hsdsch-calculated-rate", FT_UINT32, BASE_DEC, 0, 0x0,
3421               "Calculated rate RNC is allowed to send in bps", HFILL
3422             }
3423         },
3424         { &hf_fp_hsdsch_unlimited_rate,
3425             { "Unlimited rate",
3426               "fp.hsdsch-unlimited-rate", FT_NONE, BASE_NONE, 0, 0x0,
3427               "No restriction on rate at which date may be sent", HFILL
3428             }
3429         },
3430         { &hf_fp_hsdsch_repetition_period,
3431             { "HS-DSCH Repetition Period",
3432               "fp.hsdsch-repetition-period", FT_UINT8, BASE_DEC, 0, 0x0,
3433               "HS-DSCH Repetition Period in milliseconds", HFILL
3434             }
3435         },
3436         { &hf_fp_hsdsch_data_padding,
3437             { "Padding",
3438               "fp.hsdsch-data-padding", FT_UINT8, BASE_DEC, 0, 0xf0,
3439               "HS-DSCH Repetition Period in milliseconds", HFILL
3440             }
3441         },
3442         { &hf_fp_hsdsch_new_ie_flags,
3443             { "New IEs flags",
3444               "fp.hsdsch.new-ie-flags", FT_STRING, BASE_NONE, 0, 0x0,
3445               NULL, HFILL
3446             }
3447         },
3448         { &hf_fp_hsdsch_new_ie_flag[0],
3449             { "DRT IE present",
3450               "fp.hsdsch.new-ie-flag", FT_UINT8, BASE_DEC, 0, 0x80,
3451               NULL, HFILL
3452             }
3453         },
3454         { &hf_fp_hsdsch_new_ie_flag[1],
3455             { "New IE present",
3456               "fp.hsdsch.new-ie-flag", FT_UINT8, BASE_DEC, 0, 0x40,
3457               NULL, HFILL
3458             }
3459         },
3460         { &hf_fp_hsdsch_new_ie_flag[2],
3461             { "New IE present",
3462               "fp.hsdsch.new-ie-flag", FT_UINT8, BASE_DEC, 0, 0x20,
3463               NULL, HFILL
3464             }
3465         },
3466         { &hf_fp_hsdsch_new_ie_flag[3],
3467             { "New IE present",
3468               "fp.hsdsch.new-ie-flag", FT_UINT8, BASE_DEC, 0, 0x10,
3469               NULL, HFILL
3470             }
3471         },
3472         { &hf_fp_hsdsch_new_ie_flag[4],
3473             { "New IE present",
3474               "fp.hsdsch.new-ie-flag", FT_UINT8, BASE_DEC, 0, 0x08,
3475               NULL, HFILL
3476             }
3477         },
3478         { &hf_fp_hsdsch_new_ie_flag[5],
3479             { "New IE present",
3480               "fp.hsdsch.new-ie-flag", FT_UINT8, BASE_DEC, 0, 0x04,
3481               NULL, HFILL
3482             }
3483         },
3484         { &hf_fp_hsdsch_new_ie_flag[6],
3485             { "New IE present",
3486               "fp.hsdsch.new-ie-flag", FT_UINT8, BASE_DEC, 0, 0x02,
3487               NULL, HFILL
3488             }
3489         },
3490         { &hf_fp_hsdsch_new_ie_flag[7],
3491             { "Another new IE flags byte",
3492               "fp.hsdsch.new-ie-flags-byte", FT_UINT8, BASE_DEC, 0, 0x01,
3493               "Another new IE flagsbyte", HFILL
3494             }
3495         },
3496         { &hf_fp_hsdsch_drt,
3497             { "DRT",
3498               "fp.hsdsch.drt", FT_UINT8, BASE_DEC, 0, 0xf0,
3499               "Delay Reference Time", HFILL
3500             }
3501         },
3502         { &hf_fp_hsdsch_entity,
3503             { "HS-DSCH Entity",
3504               "fp.hsdsch.entity", FT_UINT8, BASE_DEC, VALS(hsdshc_mac_entity_vals), 0x0,
3505               "Type of MAC entity for this HS-DSCH channel", HFILL
3506             }
3507         },
3508         { &hf_fp_timing_advance,
3509             { "Timing advance",
3510               "fp.timing-advance", FT_UINT8, BASE_DEC, 0, 0x3f,
3511               "Timing advance in chips", HFILL
3512             }
3513         },
3514         { &hf_fp_num_of_pdu,
3515             { "Number of PDUs",
3516               "fp.hsdsch.num-of-pdu", FT_UINT8, BASE_DEC, 0, 0x0,
3517               "Number of PDUs in the payload", HFILL
3518             }
3519         },
3520         { &hf_fp_mac_d_pdu_len,
3521             { "MAC-d PDU Length",
3522               "fp.hsdsch.mac-d-pdu-len", FT_UINT16, BASE_DEC, 0, 0xfff8,
3523               "MAC-d PDU Length in bits", HFILL
3524             }
3525         },
3526         { &hf_fp_mac_d_pdu,
3527             { "MAC-d PDU",
3528               "fp.mac-d-pdu", FT_BYTES, BASE_NONE, NULL, 0x0,
3529               NULL, HFILL
3530             }
3531         },
3532         { &hf_fp_data,
3533             { "Data",
3534               "fp.data", FT_BYTES, BASE_NONE, NULL, 0x0,
3535               NULL, HFILL
3536             }
3537         },
3538         { &hf_fp_crcis,
3539             { "CRCIs",
3540               "fp.crcis", FT_BYTES, BASE_NONE, NULL, 0x0,
3541               "CRC Indicators for uplink TBs", HFILL
3542             }
3543         },
3544         { &hf_fp_t1,
3545             { "T1",
3546               "fp.t1", FT_UINT24, BASE_DEC, NULL, 0x0,
3547               "RNC frame number indicating time it sends frame", HFILL
3548             }
3549         },
3550         { &hf_fp_t2,
3551             { "T2",
3552               "fp.t2", FT_UINT24, BASE_DEC, NULL, 0x0,
3553               "NodeB frame number indicating time it received DL Sync", HFILL
3554             }
3555         },
3556         { &hf_fp_t3,
3557             { "T3",
3558               "fp.t3", FT_UINT24, BASE_DEC, NULL, 0x0,
3559               "NodeB frame number indicating time it sends frame", HFILL
3560             }
3561         },
3562         { &hf_fp_ul_sir_target,
3563             { "UL_SIR_TARGET",
3564               "fp.ul-sir-target", FT_FLOAT, BASE_NONE, 0, 0x0,
3565               "Value (in dB) of the SIR target to be used by the UL inner loop power control", HFILL
3566             }
3567         },
3568         { &hf_fp_pusch_set_id,
3569             { "PUSCH Set Id",
3570               "fp.pusch-set-id", FT_UINT8, BASE_DEC, NULL, 0x0,
3571               "Identifies PUSCH Set from those configured in NodeB", HFILL
3572             }
3573         },
3574         { &hf_fp_activation_cfn,
3575             { "Activation CFN",
3576               "fp.activation-cfn", FT_UINT8, BASE_DEC, NULL, 0x0,
3577               "Activation Connection Frame Number", HFILL
3578             }
3579         },
3580         { &hf_fp_duration,
3581             { "Duration (ms)",
3582               "fp.pusch-set-id", FT_UINT8, BASE_DEC, NULL, 0x0,
3583               "Duration of the activation period of the PUSCH Set", HFILL
3584             }
3585         },
3586         { &hf_fp_power_offset,
3587             { "Power offset",
3588               "fp.power-offset", FT_FLOAT, BASE_NONE, NULL, 0x0,
3589               "Power offset (in dB)", HFILL
3590             }
3591         },
3592         { &hf_fp_code_number,
3593             { "Code number",
3594               "fp.code-number", FT_UINT8, BASE_DEC, NULL, 0x0,
3595               NULL, HFILL
3596             }
3597         },
3598         { &hf_fp_spreading_factor,
3599             { "Spreading factor",
3600               "fp.spreading-factor", FT_UINT8, BASE_DEC, VALS(spreading_factor_vals), 0xf0,
3601               NULL, HFILL
3602             }
3603         },
3604         { &hf_fp_mc_info,
3605             { "MC info",
3606               "fp.mc-info", FT_UINT8, BASE_DEC, NULL, 0x0e,
3607               NULL, HFILL
3608             }
3609         },
3610         { &hf_fp_rach_new_ie_flags,
3611             { "New IEs flags",
3612               "fp.rach.new-ie-flags", FT_STRING, BASE_NONE, 0, 0x0,
3613               NULL, HFILL
3614             }
3615         },
3616         { &hf_fp_rach_new_ie_flag_unused[0],
3617             { "New IE present",
3618               "fp.rach.new-ie-flag", FT_UINT8, BASE_DEC, 0, 0x80,
3619               NULL, HFILL
3620             }
3621         },
3622         { &hf_fp_rach_new_ie_flag_unused[1],
3623             { "New IE present",
3624               "fp.rach.new-ie-flag", FT_UINT8, BASE_DEC, 0, 0x40,
3625               NULL, HFILL
3626             }
3627         },
3628         { &hf_fp_rach_new_ie_flag_unused[2],
3629             { "New IE present",
3630               "fp.rach.new-ie-flag", FT_UINT8, BASE_DEC, 0, 0x20,
3631               "New IE present (unused)", HFILL
3632             }
3633         },
3634         { &hf_fp_rach_new_ie_flag_unused[3],
3635             { "New IE present",
3636               "fp.rach.new-ie-flag", FT_UINT8, BASE_DEC, 0, 0x10,
3637               "New IE present (unused)", HFILL
3638             }
3639         },
3640         { &hf_fp_rach_new_ie_flag_unused[4],
3641             { "New IE present",
3642               "fp.rach.new-ie-flag", FT_UINT8, BASE_DEC, 0, 0x08,
3643               "New IE present (unused)", HFILL
3644             }
3645         },
3646         { &hf_fp_rach_new_ie_flag_unused[5],
3647             { "New IE present",
3648               "fp.rach.new-ie-flag", FT_UINT8, BASE_DEC, 0, 0x04,
3649               "New IE present (unused)", HFILL
3650             }
3651         },
3652         { &hf_fp_rach_new_ie_flag_unused[6],
3653             { "New IE present",
3654               "fp.rach.new-ie-flag", FT_UINT8, BASE_DEC, 0, 0x02,
3655               "New IE present (unused)", HFILL
3656             }
3657         },
3658         { &hf_fp_rach_cell_portion_id_present,
3659             { "Cell portion ID present",
3660               "fp.rach.cell-portion-id-present", FT_UINT8, BASE_DEC, 0, 0x01,
3661               NULL, HFILL
3662             }
3663         },
3664         { &hf_fp_rach_angle_of_arrival_present,
3665             { "Angle of arrival present",
3666               "fp.rach.angle-of-arrival-present", FT_UINT8, BASE_DEC, 0, 0x01,
3667               NULL, HFILL
3668             }
3669         },
3670         { &hf_fp_rach_ext_propagation_delay_present,
3671             { "Ext Propagation Delay Present",
3672               "fp.rach.ext-propagation-delay-present", FT_UINT8, BASE_DEC, 0, 0x02,
3673               NULL, HFILL
3674             }
3675         },
3676         { &hf_fp_rach_ext_rx_sync_ul_timing_deviation_present,
3677             { "Ext Received Sync UL Timing Deviation present",
3678               "fp.rach.ext-rx-sync-ul-timing-deviation-present", FT_UINT8, BASE_DEC, 0, 0x02,
3679               NULL, HFILL
3680             }
3681         },
3682         { &hf_fp_rach_ext_rx_timing_deviation_present,
3683             { "Ext Rx Timing Deviation present",
3684               "fp.rach.ext-rx-timing-deviation-present", FT_UINT8, BASE_DEC, 0, 0x01,
3685               NULL, HFILL
3686             }
3687         },
3688         { &hf_fp_cell_portion_id,
3689             { "Cell Portion ID",
3690               "fp.cell-portion-id", FT_UINT8, BASE_DEC, NULL, 0x3f,
3691               NULL, HFILL
3692             }
3693         },
3694         { &hf_fp_ext_propagation_delay,
3695             { "Ext Propagation Delay",
3696               "fp.ext-propagation-delay", FT_UINT16, BASE_DEC, NULL, 0x03ff,
3697               NULL, HFILL
3698             }
3699         },
3700         { &hf_fp_angle_of_arrival,
3701             { "Angle of Arrival",
3702               "fp.angle-of-arrival", FT_UINT16, BASE_DEC, NULL, 0x03ff,
3703               NULL, HFILL
3704             }
3705         },
3706         { &hf_fp_ext_received_sync_ul_timing_deviation,
3707             { "Ext Received SYNC UL Timing Deviation",
3708               "fp.ext-received-sync-ul-timing-deviation", FT_UINT16, BASE_DEC, NULL, 0x1fff,
3709               NULL, HFILL
3710             }
3711         },
3712
3713
3714         { &hf_fp_radio_interface_parameter_update_flag[0],
3715             { "CFN valid",
3716               "fp.radio-interface-param.cfn-valid", FT_UINT16, BASE_DEC, 0, 0x0001,
3717               NULL, HFILL
3718             }
3719         },
3720         { &hf_fp_radio_interface_parameter_update_flag[1],
3721             { "TPC PO valid",
3722               "fp.radio-interface-param.tpc-po-valid", FT_UINT16, BASE_DEC, 0, 0x0002,
3723               NULL, HFILL
3724             }
3725         },
3726         { &hf_fp_radio_interface_parameter_update_flag[2],
3727             { "DPC mode valid",
3728               "fp.radio-interface-param.dpc-mode-valid", FT_UINT16, BASE_DEC, 0, 0x0004,
3729               NULL, HFILL
3730             }
3731         },
3732         { &hf_fp_radio_interface_parameter_update_flag[3],
3733             { "RL sets indicator valid",
3734               "fp.radio-interface_param.rl-sets-indicator-valid", FT_UINT16, BASE_DEC, 0, 0x0020,
3735               NULL, HFILL
3736             }
3737         },
3738         { &hf_fp_radio_interface_parameter_update_flag[4],
3739             { "MAX_UE_TX_POW valid",
3740               "fp.radio-interface-param.max-ue-tx-pow-valid", FT_UINT16, BASE_DEC, 0, 0x0040,
3741               "MAX UE TX POW valid", HFILL
3742             }
3743         },
3744         { &hf_fp_dpc_mode,
3745             { "DPC Mode",
3746               "fp.dpc-mode", FT_UINT8, BASE_DEC, NULL, 0x20,
3747               "DPC Mode to be applied in the uplink", HFILL
3748             }
3749         },
3750         { &hf_fp_tpc_po,
3751             { "TPC PO",
3752               "fp.tpc-po", FT_UINT8, BASE_DEC, NULL, 0x1f,
3753               NULL, HFILL
3754             }
3755         },
3756         { &hf_fp_multiple_rl_set_indicator,
3757             { "Multiple RL sets indicator",
3758               "fp.multiple-rl-sets-indicator", FT_UINT8, BASE_DEC, NULL, 0x80,
3759               NULL, HFILL
3760             }
3761         },
3762         { &hf_fp_max_ue_tx_pow,
3763             { "MAX_UE_TX_POW",
3764               "fp.max-ue-tx-pow", FT_INT8, BASE_DEC, NULL, 0x0,
3765               "Max UE TX POW (dBm)", HFILL
3766             }
3767         },
3768         { &hf_fp_congestion_status,
3769             { "Congestion Status",
3770               "fp.congestion-status", FT_UINT8, BASE_DEC, VALS(congestion_status_vals), 0x0,
3771               NULL, HFILL
3772             }
3773         },
3774         { &hf_fp_e_rucch_present,
3775             { "E-RUCCH Present",
3776               "fp.erucch-present", FT_UINT8, BASE_DEC, NULL, 0x0,
3777               NULL, HFILL
3778             }
3779         },
3780         { &hf_fp_extended_bits_present,
3781             { "Extended Bits Present",
3782               "fp.extended-bits-present", FT_UINT8, BASE_DEC, NULL, 0x0,
3783               NULL, HFILL
3784             }
3785         },
3786         { &hf_fp_extended_bits,
3787             { "Extended Bits",
3788               "fp.extended-bits", FT_UINT8, BASE_HEX, NULL, 0x0,
3789               NULL, HFILL
3790             }
3791         },
3792         { &hf_fp_spare_extension,
3793             { "Spare Extension",
3794               "fp.spare-extension", FT_NONE, BASE_NONE, NULL, 0x0,
3795               NULL, HFILL
3796             }
3797         },
3798
3799     };
3800
3801
3802     static gint *ett[] =
3803     {
3804         &ett_fp,
3805         &ett_fp_data,
3806         &ett_fp_crcis,
3807         &ett_fp_edch_subframe_header,
3808         &ett_fp_edch_subframe,
3809         &ett_fp_hsdsch_new_ie_flags,
3810         &ett_fp_rach_new_ie_flags,
3811         &ett_fp_hsdsch_pdu_block_header
3812     };
3813
3814     module_t *fp_module;
3815
3816     /* Register protocol. */
3817     proto_fp = proto_register_protocol("FP", "FP", "fp");
3818     proto_register_field_array(proto_fp, hf, array_length(hf));
3819     proto_register_subtree_array(ett, array_length(ett));
3820
3821     /* Allow other dissectors to find this one by name. */
3822     register_dissector("fp", dissect_fp, proto_fp);
3823
3824     /* Preferences */
3825     fp_module = prefs_register_protocol(proto_fp, NULL);
3826
3827     /* Determines whether MAC dissector should be called for payloads */
3828     prefs_register_bool_preference(fp_module, "call_mac",
3829                                    "Call MAC dissector for payloads",
3830                                    "Call MAC dissector for payloads",
3831                                    &preferences_call_mac_dissectors);
3832
3833 }
3834
3835
3836 void proto_reg_handoff_fp(void)
3837 {
3838     mac_fdd_rach_handle = find_dissector("mac.fdd.rach");
3839     mac_fdd_fach_handle = find_dissector("mac.fdd.fach");
3840     mac_fdd_pch_handle = find_dissector("mac.fdd.pch");
3841     mac_fdd_dch_handle = find_dissector("mac.fdd.dch");
3842     mac_fdd_edch_handle = find_dissector("mac.fdd.edch");
3843     mac_fdd_hsdsch_handle = find_dissector("mac.fdd.hsdsch");
3844
3845     heur_dissector_add("udp", heur_dissect_fp, proto_fp);
3846 }
3847