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