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