For proto_tree_add_item(..., proto_xxx, ...)use ENC_NA as the encoding arg.
[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, ENC_NA);
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                                          ENC_NA);
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, ENC_NA);
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, ENC_BIG_ENDIAN);
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                                          ENC_NA);
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, ENC_NA);
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, ENC_NA);
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, ENC_NA);
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, ENC_BIG_ENDIAN);
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, ENC_NA);
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                             ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
859         offset++;
860
861         /* ToA */
862         toa = tvb_get_ntohs(tvb, offset);
863         proto_tree_add_item(tree, hf_fp_toa, tvb, offset, 2, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
1021     }
1022
1023     /* CmCH-PI */
1024     proto_tree_add_item(tree, hf_fp_cmch_pi, tvb, offset, 1, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_NA);
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, ENC_BIG_ENDIAN);
1105
1106     /* CmCH-PI */
1107     proto_tree_add_item(tree, hf_fp_cmch_pi, tvb, offset, 1, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_NA);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
1219     offset++;
1220
1221     col_append_str(pinfo->cinfo, COL_INFO,
1222                    val_to_str_const(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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
1644             offset++;
1645
1646             /* Spreading Factor (3 bits) */
1647             proto_tree_add_item(tree, hf_fp_spreading_factor, tvb, offset, 1, ENC_BIG_ENDIAN);
1648
1649             /* MC info (4 bits)*/
1650             proto_tree_add_item(tree, hf_fp_mc_info, tvb, offset, 1, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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                                      ENC_NA);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
1990         proto_tree_add_bits_ret_val(tree, hf_fp_extended_bits_present, tvb,
1991                                     offset*8 + 7, 1, &extended_bits_present, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
2021             proto_tree_add_bits_item(tree, hf_fp_dch_e_rucch_flag, tvb,
2022                                      offset*8 + bit_offset, 1, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
2089     offset++;
2090
2091     /* ToA */
2092     toa = tvb_get_ntohs(tvb, offset);
2093     proto_tree_add_item(tree, hf_fp_toa, tvb, offset, 2, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
2139     offset++;
2140
2141     /* DPC mode */
2142     proto_tree_add_item(tree, hf_fp_dpc_mode, tvb, offset, 1, ENC_BIG_ENDIAN);
2143
2144     /* TPC PO */
2145     proto_tree_add_item(tree, hf_fp_tpc_po, tvb, offset, 1, ENC_BIG_ENDIAN);
2146     offset++;
2147
2148     /* Multiple RL sets indicator */
2149     proto_tree_add_item(tree, hf_fp_multiple_rl_set_indicator, tvb, offset, 1, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
2208     offset++;
2209
2210     col_append_fstr(pinfo->cinfo, COL_INFO, " status = %s",
2211                     val_to_str_const((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, ENC_BIG_ENDIAN);
2226     offset++;
2227
2228     col_append_str(pinfo->cinfo, COL_INFO,
2229                    val_to_str_const(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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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                                              ENC_NA);
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                                             ENC_NA);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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, ENC_BIG_ENDIAN);
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
2826                 ti = proto_tree_add_item(macis_pdu_tree, hf_fp_edch_macis_sdu, tvb,
2827                                          offset,
2828                                          subframes[n].mac_is_length[pdu_no][sdu_no],
2829                                          ENC_NA);
2830                 proto_item_append_text(ti, " (%s Len=%u): %s",
2831                                        val_to_str_const(subframes[n].mac_is_lchid[pdu_no][sdu_no], lchid_vals, "Unknown"),
2832                                        subframes[n].mac_is_length[pdu_no][sdu_no],
2833                                        tvb_bytes_to_str(tvb, offset, subframes[n].mac_is_length[pdu_no][sdu_no]));
2834
2835                 offset += subframes[n].mac_is_length[pdu_no][sdu_no];
2836                 subframe_bytes += subframes[n].mac_is_length[pdu_no][sdu_no];
2837             }
2838
2839             proto_item_append_text(macis_pdu_ti, " - SS=%u TSN=%u (%u bytes in %u SDUs)",
2840                                    ss, tsn, subframe_bytes, subframes[n].number_of_mac_is_sdus[pdu_no]);
2841
2842             proto_item_set_len(macis_pdu_ti, 1+subframe_bytes);
2843             total_bytes += subframe_bytes;
2844         }
2845     }
2846
2847     /* Add data summary to info column */
2848     col_append_fstr(pinfo->cinfo, COL_INFO, " (%u bytes in %u SDUs in %u MAC-is PDUs in %u subframes)",
2849                     total_bytes, macis_sdus_found, macis_pdus, number_of_subframes);;
2850
2851     /* Spare extension and payload CRC (optional) */
2852     dissect_spare_extension_and_crc(tvb, pinfo, tree,
2853                                     p_fp_info->dch_crc_present, offset);
2854 }
2855
2856
2857 /**********************************************************/
2858 /* Dissect an HSDSCH channel                              */
2859 /* The data format corresponds to the format              */
2860 /* described in R5 and R6, and frame type 1 in Release 7. */
2861 static void dissect_hsdsch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2862                                         int offset, struct fp_info *p_fp_info)
2863 {
2864     gboolean is_control_frame;
2865
2866     /* Header CRC */
2867     proto_tree_add_item(tree, hf_fp_header_crc, tvb, offset, 1, ENC_BIG_ENDIAN);
2868
2869     /* Frame Type */
2870     is_control_frame = tvb_get_guint8(tvb, offset) & 0x01;
2871     proto_tree_add_item(tree, hf_fp_ft, tvb, offset, 1, ENC_BIG_ENDIAN);
2872     offset++;
2873
2874     col_append_str(pinfo->cinfo, COL_INFO, is_control_frame ? " [Control] " : " [Data] ");
2875
2876     if (is_control_frame)
2877     {
2878         dissect_common_control(tvb, pinfo, tree, offset, p_fp_info);
2879     }
2880     else
2881     {
2882         guint8 number_of_pdus;
2883         guint16 pdu_length;
2884         guint16 user_buffer_size;
2885
2886         /**************************************/
2887         /* HS-DCH data here (type 1 in R7)    */
2888
2889         /* Frame Seq Nr */
2890         if ((p_fp_info->release == 6) ||
2891             (p_fp_info->release == 7))
2892         {
2893             guint8 frame_seq_no = (tvb_get_guint8(tvb, offset) & 0xf0) >> 4;
2894             proto_tree_add_item(tree, hf_fp_frame_seq_nr, tvb, offset, 1, ENC_BIG_ENDIAN);
2895
2896             col_append_fstr(pinfo->cinfo, COL_INFO, "  seqno=%u", frame_seq_no);
2897         }
2898
2899         /* CmCH-PI */
2900         proto_tree_add_item(tree, hf_fp_cmch_pi, tvb, offset, 1, ENC_BIG_ENDIAN);
2901         offset++;
2902
2903         /* MAC-d PDU Length (13 bits) */
2904         pdu_length = (tvb_get_ntohs(tvb, offset) >> 3);
2905         proto_tree_add_item(tree, hf_fp_mac_d_pdu_len, tvb, offset, 2, ENC_BIG_ENDIAN);
2906         offset += 2;
2907
2908         if ((p_fp_info->release == 6) ||
2909             (p_fp_info->release == 7))
2910         {
2911             /* Flush bit */
2912             proto_tree_add_item(tree, hf_fp_flush, tvb, offset-1, 1, ENC_BIG_ENDIAN);
2913
2914             /* FSN/DRT reset bit */
2915             proto_tree_add_item(tree, hf_fp_fsn_drt_reset, tvb, offset-1, 1, ENC_BIG_ENDIAN);
2916         }
2917
2918
2919         /* Num of PDUs */
2920         number_of_pdus = tvb_get_guint8(tvb, offset);
2921         proto_tree_add_item(tree, hf_fp_num_of_pdu, tvb, offset, 1, ENC_BIG_ENDIAN);
2922         offset++;
2923
2924         /* User buffer size */
2925         user_buffer_size = tvb_get_ntohs(tvb, offset);
2926         proto_tree_add_item(tree, hf_fp_user_buffer_size, tvb, offset, 2, ENC_BIG_ENDIAN);
2927         offset += 2;
2928
2929         /* MAC-d PDUs */
2930         offset = dissect_macd_pdu_data(tvb, pinfo, tree, offset, pdu_length,
2931                                        number_of_pdus);
2932
2933         col_append_fstr(pinfo->cinfo, COL_INFO, "  %ux%u-bit PDUs  User-Buffer-Size=%u",
2934                         number_of_pdus, pdu_length, user_buffer_size);
2935
2936         /* Extra IEs (if there is room for them) */
2937         if (((p_fp_info->release == 6) ||
2938              (p_fp_info->release == 7)) &&
2939             (tvb_length_remaining(tvb, offset) > 2))
2940         {
2941             int n;
2942             guint8 flags;
2943             /* guint8 flag_bytes = 0; */
2944
2945             /* New IE flags */
2946             do
2947             {
2948                 proto_item *new_ie_flags_ti;
2949                 proto_tree *new_ie_flags_tree;
2950                 guint ies_found = 0;
2951
2952                 /* Add new IE flags subtree */
2953                 new_ie_flags_ti = proto_tree_add_string_format(tree, hf_fp_hsdsch_new_ie_flags, tvb, offset, 1,
2954                                                               "", "New IE flags");
2955                 new_ie_flags_tree = proto_item_add_subtree(new_ie_flags_ti, ett_fp_hsdsch_new_ie_flags);
2956
2957                 /* Read next byte */
2958                 flags = tvb_get_guint8(tvb, offset);
2959                 /* flag_bytes++; */
2960
2961                 /* Dissect individual bits */
2962                 for (n=0; n < 8; n++)
2963                 {
2964                     proto_tree_add_item(new_ie_flags_tree, hf_fp_hsdsch_new_ie_flag[n], tvb, offset, 1, ENC_BIG_ENDIAN);
2965                     if ((flags >> (7-n)) & 0x01)
2966                     {
2967                         ies_found++;
2968                     }
2969                 }
2970                 offset++;
2971
2972                 proto_item_append_text(new_ie_flags_ti, " (%u IEs found)", ies_found);
2973
2974                 /* Last bit set will indicate another flags byte follows... */
2975             } while (0); /*((flags & 0x01) && (flag_bytes < 31));*/
2976
2977             if (1) /*(flags & 0x8) */
2978             {
2979                 /* DRT is shown as mandatory in the diagram (3GPP TS 25.435 V6.3.0),
2980                    but the description below it states that
2981                    it should depend upon the first bit.  The detailed description of
2982                    New IE flags doesn't agree, so treat as mandatory for now... */
2983                 proto_tree_add_item(tree, hf_fp_hsdsch_drt, tvb, offset, 2, ENC_BIG_ENDIAN);
2984                 offset += 2;
2985             }
2986         }
2987
2988         /* Spare Extension and Payload CRC */
2989         dissect_spare_extension_and_crc(tvb, pinfo, tree, 1, offset);
2990     }
2991 }
2992
2993
2994 /******************************************/
2995 /* Dissect an HSDSCH type 2 channel       */
2996 /* (introduced in Release 7)              */
2997 /* N.B. there is currently no support for */
2998 /* frame type 3 (IuR only?)               */
2999 static void dissect_hsdsch_type_2_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
3000                                                int offset, struct fp_info *p_fp_info)
3001 {
3002     gboolean is_control_frame;
3003
3004     /* Header CRC */
3005     proto_tree_add_item(tree, hf_fp_header_crc, tvb, offset, 1, ENC_BIG_ENDIAN);
3006
3007     /* Frame Type */
3008     is_control_frame = tvb_get_guint8(tvb, offset) & 0x01;
3009     proto_tree_add_item(tree, hf_fp_ft, tvb, offset, 1, ENC_BIG_ENDIAN);
3010     offset++;
3011
3012     col_append_str(pinfo->cinfo, COL_INFO, is_control_frame ? " [Control] " : " [Data] ");
3013
3014     if (is_control_frame)
3015     {
3016         dissect_common_control(tvb, pinfo, tree, offset, p_fp_info);
3017     }
3018     else
3019     {
3020         guint8 number_of_pdu_blocks;
3021         gboolean drt_present = FALSE;
3022         gboolean fach_present = FALSE;
3023         guint16 user_buffer_size;
3024         int n;
3025
3026         #define MAX_PDU_BLOCKS 31
3027         guint64 lchid[MAX_PDU_BLOCKS];
3028         guint64 pdu_length[MAX_PDU_BLOCKS];
3029         guint64 no_of_pdus[MAX_PDU_BLOCKS];
3030
3031         /********************************/
3032         /* HS-DCH type 2 data here      */
3033
3034         col_append_str(pinfo->cinfo, COL_INFO, "(ehs)");
3035
3036         /* Frame Seq Nr (4 bits) */
3037         if ((p_fp_info->release == 6) ||
3038             (p_fp_info->release == 7))
3039         {
3040             guint8 frame_seq_no = (tvb_get_guint8(tvb, offset) & 0xf0) >> 4;
3041             proto_tree_add_item(tree, hf_fp_frame_seq_nr, tvb, offset, 1, ENC_BIG_ENDIAN);
3042
3043             col_append_fstr(pinfo->cinfo, COL_INFO, "  seqno=%u", frame_seq_no);
3044         }
3045
3046         /* CmCH-PI (4 bits) */
3047         proto_tree_add_item(tree, hf_fp_cmch_pi, tvb, offset, 1, ENC_BIG_ENDIAN);
3048         offset++;
3049
3050         /* Total number of PDU blocks (5 bits) */
3051         number_of_pdu_blocks = (tvb_get_guint8(tvb, offset) >> 3);
3052         proto_tree_add_item(tree, hf_fp_total_pdu_blocks, tvb, offset, 1, ENC_BIG_ENDIAN);
3053
3054         if (p_fp_info->release == 7)
3055         {
3056             /* Flush bit */
3057             proto_tree_add_item(tree, hf_fp_flush, tvb, offset, 1, ENC_BIG_ENDIAN);
3058
3059             /* FSN/DRT reset bit */
3060             proto_tree_add_item(tree, hf_fp_fsn_drt_reset, tvb, offset, 1, ENC_BIG_ENDIAN);
3061
3062             /* DRT Indicator */
3063             drt_present = tvb_get_guint8(tvb, offset) & 0x01;
3064             proto_tree_add_item(tree, hf_fp_drt_indicator, tvb, offset, 1, ENC_BIG_ENDIAN);
3065         }
3066         offset++;
3067
3068         /* FACH Indicator flag */
3069         fach_present = (tvb_get_guint8(tvb, offset) & 0x80) >> 7;
3070         proto_tree_add_item(tree, hf_fp_fach_indicator, tvb, offset, 1, ENC_BIG_ENDIAN);
3071         offset++;
3072
3073         /* User buffer size */
3074         user_buffer_size = tvb_get_ntohs(tvb, offset);
3075         proto_tree_add_item(tree, hf_fp_user_buffer_size, tvb, offset, 2, ENC_BIG_ENDIAN);
3076         offset += 2;
3077
3078         col_append_fstr(pinfo->cinfo, COL_INFO, "  User-Buffer-Size=%u", user_buffer_size);
3079
3080
3081         /********************************************************************/
3082         /* Now read number_of_pdu_blocks header entries                     */
3083         for (n=0; n < number_of_pdu_blocks; n++)
3084         {
3085             proto_item *pdu_block_header_ti;
3086             proto_tree *pdu_block_header_tree;
3087             int        block_header_start_offset = offset;
3088
3089             /* Add PDU block header subtree */
3090             pdu_block_header_ti = proto_tree_add_string_format(tree, hf_fp_hsdsch_pdu_block_header,
3091                                                                tvb, offset, 0,
3092                                                                "",
3093                                                                "PDU Block Header");
3094             pdu_block_header_tree = proto_item_add_subtree(pdu_block_header_ti,
3095                                                            ett_fp_hsdsch_pdu_block_header);
3096
3097             /* MAC-d/c PDU length in this block (11 bits) */
3098             proto_tree_add_bits_ret_val(pdu_block_header_tree, hf_fp_pdu_length_in_block, tvb,
3099                                         (offset*8) + ((n % 2) ? 4 : 0), 11,
3100                                         &pdu_length[n], ENC_BIG_ENDIAN);
3101             if ((n % 2) == 0)
3102                 offset++;
3103             else
3104                 offset += 2;
3105
3106
3107             /* # PDUs in this block (4 bits) */
3108             proto_tree_add_bits_ret_val(pdu_block_header_tree, hf_fp_pdus_in_block, tvb,
3109                                         (offset*8) + ((n % 2) ? 0 : 4), 4,
3110                                         &no_of_pdus[n], ENC_BIG_ENDIAN);
3111             if ((n % 2) == 0) {
3112                 offset++;
3113             }
3114
3115             /* Logical channel ID in block (4 bits) */
3116             proto_tree_add_bits_ret_val(pdu_block_header_tree, hf_fp_lchid, tvb,
3117                                         (offset*8) + ((n % 2) ? 4 : 0), 4,
3118                                         &lchid[n], ENC_BIG_ENDIAN);
3119             if ((n % 2) == 1) {
3120                 offset++;
3121             }
3122             else {
3123                 if (n == (number_of_pdu_blocks-1)) {
3124                     /* Byte is padded out for last block */
3125                     offset++;
3126                 }
3127             }
3128
3129             /* Append summary to header tree root */
3130             proto_item_append_text(pdu_block_header_ti,
3131                                    " (lch:%u, %u pdus of %u bytes)",
3132                                    (guint16)lchid[n],
3133                                    (guint16)no_of_pdus[n],
3134                                    (guint16)pdu_length[n]);
3135
3136             /* Set length of header tree item */
3137             if (((n % 2) == 0) && (n < (number_of_pdu_blocks-1))) {
3138                 proto_item_set_len(pdu_block_header_ti,
3139                                    offset - block_header_start_offset+1);
3140             }
3141             else {
3142                 proto_item_set_len(pdu_block_header_ti,
3143                                    offset - block_header_start_offset);
3144             }
3145         }
3146
3147
3148         /**********************************************/
3149         /* Optional fields indicated by earlier flags */
3150         if (drt_present)
3151         {
3152             /* DRT */
3153             proto_tree_add_item(tree, hf_fp_drt, tvb, offset, 2, ENC_BIG_ENDIAN);
3154             offset += 2;
3155         }
3156
3157         if (fach_present)
3158         {
3159             /* H-RNTI: */
3160             proto_tree_add_item(tree, hf_fp_hrnti, tvb, offset, 2, ENC_BIG_ENDIAN);
3161             offset += 2;
3162
3163             /* RACH Measurement Result */
3164             proto_tree_add_item(tree, hf_fp_rach_measurement_result, tvb, offset, 2, ENC_BIG_ENDIAN);
3165             offset++;
3166         }
3167
3168
3169         /********************************************************************/
3170         /* Now read the MAC-d/c PDUs for each block using info from headers */
3171         for (n=0; n < number_of_pdu_blocks; n++)
3172         {
3173             /* Add PDU block header subtree */
3174             offset = dissect_macd_pdu_data_type_2(tvb, pinfo, tree, offset,
3175                                                   (guint16)pdu_length[n],
3176                                                   (guint16)no_of_pdus[n]);
3177         }
3178
3179         /* Spare Extension and Payload CRC */
3180         dissect_spare_extension_and_crc(tvb, pinfo, tree, 1, offset);
3181     }
3182 }
3183
3184 static gboolean heur_dissect_fp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
3185 {
3186     struct fp_info *p_fp_info;
3187
3188     p_fp_info = p_get_proto_data(pinfo->fd, proto_fp);
3189
3190     /* if no FP info is present, assume this is not FP over UDP */
3191     if (!p_fp_info) return FALSE;
3192
3193     /* if FP info is present, check that it really is an ethernet link */
3194     if (p_fp_info->link_type != FP_Link_Ethernet) {
3195         return FALSE;
3196     }
3197
3198     /* remember 'lower' UDP layer port information */
3199     if (!p_fp_info->srcport || !p_fp_info->destport) {
3200         p_fp_info->srcport = pinfo->srcport;
3201         p_fp_info->destport = pinfo->destport;
3202     }
3203
3204     /* discriminate 'lower' UDP layer from 'user data' UDP layer
3205      * (i.e. if an FP over UDP packet contains a user UDP packet */
3206     if (p_fp_info->srcport != pinfo->srcport ||
3207         p_fp_info->destport != pinfo->destport)
3208         return FALSE;
3209
3210     /* assume this is FP */
3211     dissect_fp(tvb, pinfo, tree);
3212     return TRUE;
3213 }
3214
3215
3216 /*****************************/
3217 /* Main dissection function. */
3218 void dissect_fp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
3219 {
3220     proto_tree       *fp_tree;
3221     proto_item       *ti;
3222     gint             offset = 0;
3223     struct fp_info   *p_fp_info;
3224
3225     /* Append this protocol name rather than replace. */
3226     col_set_str(pinfo->cinfo, COL_PROTOCOL, "FP");
3227
3228     /* Create fp tree. */
3229     ti = proto_tree_add_item(tree, proto_fp, tvb, offset, -1, ENC_NA);
3230     fp_tree = proto_item_add_subtree(ti, ett_fp);
3231
3232     top_level_tree = tree;
3233
3234     /* Look for packet info! */
3235     p_fp_info = p_get_proto_data(pinfo->fd, proto_fp);
3236
3237     /* Can't dissect anything without it... */
3238     if (p_fp_info == NULL)
3239     {
3240         ti = proto_tree_add_text(fp_tree, tvb, offset, -1,
3241                                 "Can't dissect FP frame because no per-frame info was attached!");
3242         PROTO_ITEM_SET_GENERATED(ti);
3243         return;
3244     }
3245
3246     /* Show release information */
3247     if (preferences_show_release_info) {
3248         proto_item *release_ti;
3249         proto_tree *release_tree;
3250         proto_item *temp_ti;
3251
3252         release_ti = proto_tree_add_item(fp_tree, hf_fp_release, tvb, 0, 0, ENC_NA);
3253         PROTO_ITEM_SET_GENERATED(release_ti);
3254         proto_item_append_text(release_ti, " R%u (%d/%d)",
3255                                p_fp_info->release, p_fp_info->release_year, p_fp_info->release_month);
3256         release_tree = proto_item_add_subtree(release_ti, ett_fp_release);
3257
3258         temp_ti = proto_tree_add_uint(release_tree, hf_fp_release_version, tvb, 0, 0, p_fp_info->release);
3259         PROTO_ITEM_SET_GENERATED(temp_ti);
3260
3261         temp_ti = proto_tree_add_uint(release_tree, hf_fp_release_year, tvb, 0, 0, p_fp_info->release_year);
3262         PROTO_ITEM_SET_GENERATED(temp_ti);
3263
3264         temp_ti = proto_tree_add_uint(release_tree, hf_fp_release_month, tvb, 0, 0, p_fp_info->release_month);
3265         PROTO_ITEM_SET_GENERATED(temp_ti);
3266     }
3267
3268     /* Show channel type in info column, tree */
3269     col_add_str(pinfo->cinfo, COL_INFO,
3270                 val_to_str_const(p_fp_info->channel,
3271                                  channel_type_vals,
3272                                  "Unknown channel type"));
3273     proto_item_append_text(ti, " (%s)",
3274                            val_to_str_const(p_fp_info->channel,
3275                                             channel_type_vals,
3276                                             "Unknown channel type"));
3277
3278     /* Add channel type as a generated field */
3279     ti = proto_tree_add_uint(fp_tree, hf_fp_channel_type, tvb, 0, 0, p_fp_info->channel);
3280     PROTO_ITEM_SET_GENERATED(ti);
3281
3282     /* Add division type as a generated field */
3283     if (p_fp_info->release == 7)
3284     {
3285         ti = proto_tree_add_uint(fp_tree, hf_fp_division, tvb, 0, 0, p_fp_info->division);
3286         PROTO_ITEM_SET_GENERATED(ti);
3287     }
3288
3289     /* Add link direction as a generated field */
3290     ti = proto_tree_add_uint(fp_tree, hf_fp_direction, tvb, 0, 0, p_fp_info->is_uplink);
3291     PROTO_ITEM_SET_GENERATED(ti);
3292
3293     /* Don't currently handle IuR-specific formats, but its useful to even see
3294        the channel type and direction */
3295     if (p_fp_info->iface_type == IuR_Interface)
3296     {
3297         return;
3298     }
3299
3300     /* Show DDI config info */
3301     if (p_fp_info->no_ddi_entries > 0) {
3302         int n;
3303         proto_item *ddi_config_ti;
3304         proto_tree *ddi_config_tree;
3305
3306         ddi_config_ti = proto_tree_add_string_format(fp_tree, hf_fp_ddi_config, tvb, offset, 0,
3307                                                      "", "DDI Config (");
3308         PROTO_ITEM_SET_GENERATED(ddi_config_ti);
3309         ddi_config_tree = proto_item_add_subtree(ddi_config_ti, ett_fp_ddi_config);
3310
3311         /* Add each entry */
3312         for (n=0; n < p_fp_info->no_ddi_entries; n++) {
3313             proto_item_append_text(ddi_config_ti, "%s%u->%ubits",
3314                                    (n==0) ? "" : "  ",
3315                                    p_fp_info->edch_ddi[n], p_fp_info->edch_macd_pdu_size[n]);
3316             ti = proto_tree_add_uint(ddi_config_tree, hf_fp_ddi_config_ddi, tvb, 0, 0,
3317                                 p_fp_info->edch_ddi[n]);
3318             PROTO_ITEM_SET_GENERATED(ti);
3319             ti = proto_tree_add_uint(ddi_config_tree, hf_fp_ddi_config_macd_pdu_size, tvb, 0, 0,
3320                                 p_fp_info->edch_macd_pdu_size[n]);
3321             PROTO_ITEM_SET_GENERATED(ti);
3322
3323         }
3324         proto_item_append_text(ddi_config_ti, ")");
3325     }
3326
3327     /*************************************/
3328     /* Dissect according to channel type */
3329     switch (p_fp_info->channel)
3330     {
3331         case CHANNEL_RACH_TDD:
3332         case CHANNEL_RACH_TDD_128:
3333         case CHANNEL_RACH_FDD:
3334              dissect_rach_channel_info(tvb, pinfo, fp_tree, offset, p_fp_info);
3335             break;
3336         case CHANNEL_DCH:
3337             dissect_dch_channel_info(tvb, pinfo, fp_tree, offset, p_fp_info);
3338             break;
3339         case CHANNEL_FACH_FDD:
3340         case CHANNEL_FACH_TDD:
3341             dissect_fach_channel_info(tvb, pinfo, fp_tree, offset, p_fp_info);
3342             break;
3343         case CHANNEL_DSCH_FDD:
3344         case CHANNEL_DSCH_TDD:
3345             dissect_dsch_channel_info(tvb, pinfo, fp_tree, offset, p_fp_info);
3346             break;
3347         case CHANNEL_USCH_TDD_128:
3348         case CHANNEL_USCH_TDD_384:
3349             dissect_usch_channel_info(tvb, pinfo, fp_tree, offset, p_fp_info);
3350             break;
3351         case CHANNEL_PCH:
3352             dissect_pch_channel_info(tvb, pinfo, fp_tree, offset, p_fp_info);
3353             break;
3354         case CHANNEL_CPCH:
3355             dissect_cpch_channel_info(tvb, pinfo, fp_tree, offset, p_fp_info);
3356             break;
3357         case CHANNEL_BCH:
3358             dissect_bch_channel_info(tvb, pinfo, fp_tree, offset, p_fp_info);
3359             break;
3360         case CHANNEL_HSDSCH:
3361             /* Show configured MAC HS-DSCH entity in use */
3362             if (fp_tree)
3363             {
3364                 proto_item *entity_ti;
3365                 entity_ti = proto_tree_add_uint(fp_tree, hf_fp_hsdsch_entity,
3366                                                 tvb, 0, 0,
3367                                                 p_fp_info->hsdsch_entity);
3368                 PROTO_ITEM_SET_GENERATED(entity_ti);
3369             }
3370             switch (p_fp_info->hsdsch_entity) {
3371                 case entity_not_specified:
3372                 case hs:
3373                     /* This is the pre-R7 default */
3374                     dissect_hsdsch_channel_info(tvb, pinfo, fp_tree, offset, p_fp_info);
3375                     break;
3376                 case ehs:
3377                     dissect_hsdsch_type_2_channel_info(tvb, pinfo, fp_tree, offset, p_fp_info);
3378                     break;
3379                 default:
3380                     /* TODO: dissector error */
3381                     break;
3382             }
3383             break;
3384         case CHANNEL_HSDSCH_COMMON:
3385             /* TODO: */
3386             break;
3387         case CHANNEL_HSDSCH_COMMON_T3:
3388             /* TODO: */
3389             break;
3390         case CHANNEL_IUR_CPCHF:
3391             /* TODO: */
3392             break;
3393         case CHANNEL_IUR_FACH:
3394             /* TODO: */
3395             break;
3396         case CHANNEL_IUR_DSCH:
3397             dissect_iur_dsch_channel_info(tvb, pinfo, fp_tree, offset, p_fp_info);
3398             break;
3399         case CHANNEL_EDCH:
3400         case CHANNEL_EDCH_COMMON:
3401             dissect_e_dch_channel_info(tvb, pinfo, fp_tree, offset, p_fp_info,
3402                                        p_fp_info->channel == CHANNEL_EDCH_COMMON);
3403             break;
3404
3405         default:
3406             break;
3407     }
3408 }
3409
3410
3411 void proto_register_fp(void)
3412 {
3413     static hf_register_info hf[] =
3414     {
3415         { &hf_fp_release,
3416             { "Release",
3417               "fp.release", FT_NONE, BASE_NONE, NULL, 0x0,
3418               "Release information", HFILL
3419             }
3420         },
3421         { &hf_fp_release_version,
3422             { "Release Version",
3423               "fp.release.version", FT_UINT8, BASE_DEC, NULL, 0x0,
3424               "3GPP Release number", HFILL
3425             }
3426         },
3427         { &hf_fp_release_year,
3428             { "Release year",
3429               "fp.release.year", FT_UINT16, BASE_DEC, NULL, 0x0,
3430               NULL, HFILL
3431             }
3432         },
3433         { &hf_fp_release_month,
3434             { "Release month",
3435               "fp.release.month", FT_UINT8, BASE_DEC, NULL, 0x0,
3436               NULL, HFILL
3437             }
3438         },
3439         { &hf_fp_channel_type,
3440             { "Channel Type",
3441               "fp.channel-type", FT_UINT8, BASE_HEX, VALS(channel_type_vals), 0x0,
3442               NULL, HFILL
3443             }
3444         },
3445         { &hf_fp_division,
3446             { "Division",
3447               "fp.division", FT_UINT8, BASE_HEX, VALS(division_vals), 0x0,
3448               "Radio division type", HFILL
3449             }
3450         },
3451         { &hf_fp_direction,
3452             { "Direction",
3453               "fp.direction", FT_UINT8, BASE_HEX, VALS(direction_vals), 0x0,
3454               "Link direction", HFILL
3455             }
3456         },
3457         { &hf_fp_ddi_config,
3458             { "DDI Config",
3459               "fp.ddi-config", FT_STRING, BASE_NONE, NULL, 0x0,
3460               "DDI Config (for E-DCH)", HFILL
3461             }
3462         },
3463         { &hf_fp_ddi_config_ddi,
3464             { "DDI",
3465               "fp.ddi-config.ddi", FT_UINT8, BASE_DEC, NULL, 0x0,
3466               NULL, HFILL
3467             }
3468         },
3469         { &hf_fp_ddi_config_macd_pdu_size,
3470             { "MACd PDU Size",
3471               "fp.ddi-config.macd-pdu-size", FT_UINT16, BASE_DEC, NULL, 0x0,
3472               NULL, HFILL
3473             }
3474         },
3475
3476
3477         { &hf_fp_header_crc,
3478             { "Header CRC",
3479               "fp.header-crc", FT_UINT8, BASE_HEX, NULL, 0xfe,
3480               NULL, HFILL
3481             }
3482         },
3483         { &hf_fp_ft,
3484             { "Frame Type",
3485               "fp.ft", FT_UINT8, BASE_HEX, VALS(data_control_vals), 0x01,
3486               NULL, HFILL
3487             }
3488         },
3489         { &hf_fp_cfn,
3490             { "CFN",
3491               "fp.cfn", FT_UINT8, BASE_DEC, NULL, 0x0,
3492               "Connection Frame Number", HFILL
3493             }
3494         },
3495         { &hf_fp_pch_cfn,
3496             { "CFN (PCH)",
3497               "fp.pch.cfn", FT_UINT16, BASE_DEC, NULL, 0xfff0,
3498               "PCH Connection Frame Number", HFILL
3499             }
3500         },
3501         { &hf_fp_pch_toa,
3502             { "ToA (PCH)",
3503               "fp.pch.toa", FT_INT24, BASE_DEC, NULL, 0x0,
3504               "PCH Time of Arrival", HFILL
3505             }
3506         },
3507         { &hf_fp_cfn_control,
3508             { "CFN control",
3509               "fp.cfn-control", FT_UINT8, BASE_DEC, NULL, 0x0,
3510               "Connection Frame Number Control", HFILL
3511             }
3512         },
3513         { &hf_fp_toa,
3514             { "ToA",
3515               "fp.toa", FT_INT16, BASE_DEC, NULL, 0x0,
3516               "Time of arrival (units are 125 microseconds)", HFILL
3517             }
3518         },
3519         { &hf_fp_tb,
3520             { "TB",
3521               "fp.tb", FT_BYTES, BASE_NONE, NULL, 0x0,
3522               "Transport Block", HFILL
3523             }
3524         },
3525         { &hf_fp_chan_zero_tbs,
3526             { "No TBs for channel",
3527               "fp.channel-with-zero-tbs", FT_UINT32, BASE_DEC, NULL, 0x0,
3528               "Channel with 0 TBs", HFILL
3529             }
3530         },
3531         { &hf_fp_tfi,
3532             { "TFI",
3533               "fp.tfi", FT_UINT8, BASE_DEC, NULL, 0x0,
3534               "Transport Format Indicator", HFILL
3535             }
3536         },
3537         { &hf_fp_usch_tfi,
3538             { "TFI",
3539               "fp.usch.tfi", FT_UINT8, BASE_DEC, NULL, 0x1f,
3540               "USCH Transport Format Indicator", HFILL
3541             }
3542         },
3543         { &hf_fp_cpch_tfi,
3544             { "TFI",
3545               "fp.cpch.tfi", FT_UINT8, BASE_DEC, NULL, 0x1f,
3546               "CPCH Transport Format Indicator", HFILL
3547             }
3548         },
3549         { &hf_fp_propagation_delay,
3550             { "Propagation Delay",
3551               "fp.propagation-delay", FT_UINT8, BASE_DEC, NULL, 0x0,
3552               NULL, HFILL
3553             }
3554         },
3555         { &hf_fp_dch_control_frame_type,
3556             { "Control Frame Type",
3557               "fp.dch.control.frame-type", FT_UINT8, BASE_HEX, VALS(dch_control_frame_type_vals), 0x0,
3558               "DCH Control Frame Type", HFILL
3559             }
3560         },
3561         { &hf_fp_dch_rx_timing_deviation,
3562             { "Rx Timing Deviation",
3563               "fp.dch.control.rx-timing-deviation", FT_UINT8, BASE_DEC, 0, 0x0,
3564               "DCH Rx Timing Deviation", HFILL
3565             }
3566         },
3567         { &hf_fp_quality_estimate,
3568             { "Quality Estimate",
3569               "fp.dch.quality-estimate", FT_UINT8, BASE_DEC, 0, 0x0,
3570               NULL, HFILL
3571             }
3572         },
3573         { &hf_fp_payload_crc,
3574             { "Payload CRC",
3575               "fp.payload-crc", FT_UINT16, BASE_HEX, 0, 0x0,
3576               NULL, HFILL
3577             }
3578         },
3579         { &hf_fp_common_control_frame_type,
3580             { "Control Frame Type",
3581               "fp.common.control.frame-type", FT_UINT8, BASE_HEX, VALS(common_control_frame_type_vals), 0x0,
3582               "Common Control Frame Type", HFILL
3583             }
3584         },
3585         { &hf_fp_crci[0],
3586             { "CRCI",
3587               "fp.crci", FT_UINT8, BASE_HEX, VALS(crci_vals), 0x80,
3588               "CRC correctness indicator", HFILL
3589             }
3590         },
3591         { &hf_fp_crci[1],
3592             { "CRCI",
3593               "fp.crci", FT_UINT8, BASE_HEX, VALS(crci_vals), 0x40,
3594               "CRC correctness indicator", HFILL
3595             }
3596         },
3597         { &hf_fp_crci[2],
3598             { "CRCI",
3599               "fp.crci", FT_UINT8, BASE_HEX, VALS(crci_vals), 0x20,
3600               "CRC correctness indicator", HFILL
3601             }
3602         },
3603         { &hf_fp_crci[3],
3604             { "CRCI",
3605               "fp.crci", FT_UINT8, BASE_HEX, VALS(crci_vals), 0x10,
3606               "CRC correctness indicator", HFILL
3607             }
3608         },
3609         { &hf_fp_crci[4],
3610             { "CRCI",
3611               "fp.crci", FT_UINT8, BASE_HEX, VALS(crci_vals), 0x08,
3612               "CRC correctness indicator", HFILL
3613             }
3614         },
3615         { &hf_fp_crci[5],
3616             { "CRCI",
3617               "fp.crci", FT_UINT8, BASE_HEX, VALS(crci_vals), 0x04,
3618               "CRC correctness indicator", HFILL
3619             }
3620         },
3621         { &hf_fp_crci[6],
3622             { "CRCI",
3623               "fp.crci", FT_UINT8, BASE_HEX, VALS(crci_vals), 0x02,
3624               "CRC correctness indicator", HFILL
3625             }
3626         },
3627         { &hf_fp_crci[7],
3628             { "CRCI",
3629               "fp.crci", FT_UINT8, BASE_HEX, VALS(crci_vals), 0x01,
3630               "CRC correctness indicator", HFILL
3631             }
3632         },
3633         { &hf_fp_received_sync_ul_timing_deviation,
3634             { "Received SYNC UL Timing Deviation",
3635               "fp.rx-sync-ul-timing-deviation", FT_UINT8, BASE_DEC, 0, 0x0,
3636               NULL, HFILL
3637             }
3638         },
3639         { &hf_fp_pch_pi,
3640             { "Paging Indication",
3641               "fp.pch.pi", FT_UINT8, BASE_DEC, VALS(paging_indication_vals), 0x01,
3642               "Indicates if the PI Bitmap is present", HFILL
3643             }
3644         },
3645         { &hf_fp_pch_tfi,
3646             { "TFI",
3647               "fp.pch.tfi", FT_UINT8, BASE_DEC, 0, 0x1f,
3648               "PCH Transport Format Indicator", HFILL
3649             }
3650         },
3651         { &hf_fp_fach_tfi,
3652             { "TFI",
3653               "fp.fach.tfi", FT_UINT8, BASE_DEC, 0, 0x1f,
3654               "FACH Transport Format Indicator", HFILL
3655             }
3656         },
3657         { &hf_fp_transmit_power_level,
3658             { "Transmit Power Level",
3659               "fp.transmit-power-level", FT_FLOAT, BASE_NONE, 0, 0x0,
3660               "Transmit Power Level (dB)", HFILL
3661             }
3662         },
3663         { &hf_fp_pdsch_set_id,
3664             { "PDSCH Set Id",
3665               "fp.pdsch-set-id", FT_UINT8, BASE_DEC, 0, 0x0,
3666               "A pointer to the PDSCH Set which shall be used to transmit", HFILL
3667             }
3668         },
3669         { &hf_fp_paging_indication_bitmap,
3670             { "Paging Indications bitmap",
3671               "fp.pch.pi-bitmap", FT_NONE, BASE_NONE, NULL, 0x0,
3672               "Paging Indication bitmap", HFILL
3673             }
3674         },
3675         { &hf_fp_rx_timing_deviation,
3676             { "Rx Timing Deviation",
3677               "fp.common.control.rx-timing-deviation", FT_UINT8, BASE_DEC, 0, 0x0,
3678               "Common Rx Timing Deviation", HFILL
3679             }
3680         },
3681         { &hf_fp_dch_e_rucch_flag,
3682             { "E-RUCCH Flag",
3683               "fp.common.control.e-rucch-flag", FT_UINT8, BASE_DEC, VALS(e_rucch_flag_vals), 0x0,
3684               NULL, HFILL
3685             }
3686         },
3687         { &hf_fp_edch_header_crc,
3688             { "E-DCH Header CRC",
3689               "fp.edch.header-crc", FT_UINT16, BASE_HEX, 0, 0xfef0,
3690               NULL, HFILL
3691             }
3692         },
3693         { &hf_fp_edch_fsn,
3694             { "FSN",
3695               "fp.edch.fsn", FT_UINT8, BASE_DEC, 0, 0x0f,
3696               "E-DCH Frame Sequence Number", HFILL
3697             }
3698         },
3699         { &hf_fp_edch_number_of_subframes,
3700             { "No of subframes",
3701               "fp.edch.no-of-subframes", FT_UINT8, BASE_DEC, 0, 0x0f,
3702               "E-DCH Number of subframes", HFILL
3703             }
3704         },
3705         { &hf_fp_edch_harq_retransmissions,
3706             { "No of HARQ Retransmissions",
3707               "fp.edch.no-of-harq-retransmissions", FT_UINT8, BASE_DEC, 0, 0x78,
3708               "E-DCH Number of HARQ retransmissions", HFILL
3709             }
3710         },
3711         { &hf_fp_edch_subframe_number,
3712             { "Subframe number",
3713               "fp.edch.subframe-number", FT_UINT8, BASE_DEC, 0, 0x0,
3714               "E-DCH Subframe number", HFILL
3715             }
3716         },
3717         { &hf_fp_edch_number_of_mac_es_pdus,
3718             { "Number of Mac-es PDUs",
3719               "fp.edch.number-of-mac-es-pdus", FT_UINT8, BASE_DEC, 0, 0xf0,
3720               NULL, HFILL
3721             }
3722         },
3723         { &hf_fp_edch_ddi,
3724             { "DDI",
3725               "fp.edch.ddi", FT_UINT8, BASE_DEC, 0, 0x0,
3726               "E-DCH Data Description Indicator", HFILL
3727             }
3728         },
3729         { &hf_fp_edch_subframe,
3730             { "Subframe",
3731               "fp.edch.subframe", FT_STRING, BASE_NONE, NULL, 0x0,
3732               "EDCH Subframe", HFILL
3733             }
3734         },
3735         { &hf_fp_edch_subframe_header,
3736             { "Subframe header",
3737               "fp.edch.subframe-header", FT_STRING, BASE_NONE, NULL, 0x0,
3738               "EDCH Subframe header", HFILL
3739             }
3740         },
3741         { &hf_fp_edch_number_of_mac_d_pdus,
3742             { "Number of Mac-d PDUs",
3743               "fp.edch.number-of-mac-d-pdus", FT_UINT8, BASE_DEC, 0, 0x0,
3744               NULL, HFILL
3745             }
3746         },
3747         { &hf_fp_edch_pdu_padding,
3748             { "Padding",
3749               "fp.edch-data-padding", FT_UINT8, BASE_DEC, 0, 0xc0,
3750               "E-DCH padding before PDU", HFILL
3751             }
3752         },
3753         { &hf_fp_edch_tsn,
3754             { "TSN",
3755               "fp.edch-tsn", FT_UINT8, BASE_DEC, 0, 0x3f,
3756               "E-DCH Transmission Sequence Number", HFILL
3757             }
3758         },
3759         { &hf_fp_edch_mac_es_pdu,
3760             { "MAC-es PDU",
3761               "fp.edch.mac-es-pdu", FT_NONE, BASE_NONE, NULL, 0x0,
3762               NULL, HFILL
3763             }
3764         },
3765
3766         { &hf_fp_edch_user_buffer_size,
3767             { "User Buffer Size",
3768               "fp.edch.user-buffer-size", FT_UINT24, BASE_DEC, NULL, 0x0,
3769               NULL, HFILL
3770             }
3771         },
3772         { &hf_fp_edch_no_macid_sdus,
3773             { "No of MAC-is SDUs",
3774               "fp.edch.no-macis-sdus", FT_UINT16, BASE_DEC, NULL, 0x0,
3775               NULL, HFILL
3776             }
3777         },
3778         { &hf_fp_edch_number_of_mac_is_pdus,
3779             { "Number of Mac-is PDUs",
3780               "fp.edch.number-of-mac-is-pdus", FT_UINT8, BASE_DEC, 0, 0x0,
3781               NULL, HFILL
3782             }
3783         },
3784         { &hf_fp_edch_e_rnti,
3785             { "E-RNTI",
3786               "fp.edch.e-rnti", FT_UINT16, BASE_DEC, 0, 0x0,
3787               NULL, HFILL
3788             }
3789         },
3790
3791         { &hf_fp_edch_macis_descriptors,
3792             { "MAC-is Descriptors",
3793               "fp.edch.mac-is.descriptors", FT_STRING, BASE_NONE, NULL, 0x0,
3794               NULL, HFILL
3795             }
3796         },
3797         { &hf_fp_edch_macis_lchid,
3798             { "LCH-ID",
3799               "fp.edch.mac-is.lchid", FT_UINT8, BASE_HEX, VALS(lchid_vals), 0xf0,
3800               NULL, HFILL
3801             }
3802         },
3803         { &hf_fp_edch_macis_length,
3804             { "Length",
3805               "fp.edch.mac-is.length", FT_UINT16, BASE_DEC, 0, 0x0ffe,
3806               NULL, HFILL
3807             }
3808         },
3809         { &hf_fp_edch_macis_flag,
3810             { "Flag",
3811               "fp.edch.mac-is.lchid", FT_UINT8, BASE_HEX, 0, 0x01,
3812               "Indicates if another entry follows", HFILL
3813             }
3814         },
3815         { &hf_fp_edch_macis_ss,
3816             { "SS",
3817               /* TODO: VALS */
3818               "fp.edch.mac-is.tsn", FT_UINT8, BASE_HEX, 0, 0xc0,
3819               "Segmentation Status", HFILL
3820             }
3821         },
3822         { &hf_fp_edch_macis_tsn,
3823             { "TSN",
3824               "fp.edch.mac-is.tsn", FT_UINT8, BASE_HEX, 0, 0x3f,
3825               "Transmission Sequence Number", HFILL
3826             }
3827         },
3828         { &hf_fp_edch_macis_sdu,
3829             { "MAC-is SDU",
3830               "fp.edch.mac-is.sdu", FT_NONE, BASE_NONE, NULL, 0x0,
3831               NULL, HFILL
3832             }
3833         },
3834
3835
3836         { &hf_fp_frame_seq_nr,
3837             { "Frame Seq Nr",
3838               "fp.frame-seq-nr", FT_UINT8, BASE_DEC, 0, 0xf0,
3839               "Frame Sequence Number", HFILL
3840             }
3841         },
3842         { &hf_fp_hsdsch_pdu_block_header,
3843             { "PDU block header",
3844               "fp.hsdsch.pdu-block-header", FT_STRING, BASE_NONE, NULL, 0x0,
3845               "HS-DSCH type 2 PDU block header", HFILL
3846             }
3847         },
3848         { &hf_fp_hsdsch_pdu_block,
3849             { "PDU block",
3850               "fp.hsdsch.pdu-block", FT_STRING, BASE_NONE, NULL, 0x0,
3851               "HS-DSCH type 2 PDU block data", HFILL
3852             }
3853         },
3854         { &hf_fp_flush,
3855             { "Flush",
3856               "fp.flush", FT_UINT8, BASE_DEC, 0, 0x04,
3857               "Whether all PDUs for this priority queue should be removed", HFILL
3858             }
3859         },
3860         { &hf_fp_fsn_drt_reset,
3861             { "FSN-DRT reset",
3862               "fp.fsn-drt-reset", FT_UINT8, BASE_DEC, 0, 0x02,
3863               "FSN/DRT Reset Flag", HFILL
3864             }
3865         },
3866         { &hf_fp_drt_indicator,
3867             { "DRT Indicator",
3868               "fp.drt-indicator", FT_UINT8, BASE_DEC, 0, 0x01,
3869               NULL, HFILL
3870             }
3871         },
3872         { &hf_fp_fach_indicator,
3873             { "FACH Indicator",
3874               "fp.fach-indicator", FT_UINT8, BASE_DEC, 0, 0x80,
3875               NULL, HFILL
3876             }
3877         },
3878         { &hf_fp_total_pdu_blocks,
3879             { "PDU Blocks",
3880               "fp.pdu_blocks", FT_UINT8, BASE_DEC, 0, 0xf8,
3881               "Total number of PDU blocks", HFILL
3882             }
3883         },
3884         { &hf_fp_drt,
3885             { "DRT",
3886               "fp.drt", FT_UINT16, BASE_DEC, 0, 0x0,
3887               NULL, HFILL
3888             }
3889         },
3890         { &hf_fp_hrnti,
3891             { "HRNTI",
3892               "fp.hrnti", FT_UINT16, BASE_DEC, 0, 0x0,
3893               NULL, HFILL
3894             }
3895         },
3896         { &hf_fp_rach_measurement_result,
3897             { "RACH Measurement Result",
3898               "fp.rach-measurement-result", FT_UINT16, BASE_DEC, 0, 0x0,
3899               NULL, HFILL
3900             }
3901         },
3902         { &hf_fp_lchid,
3903             { "Logical Channel ID",
3904               "fp.lchid", FT_UINT8, BASE_DEC, NULL, 0x0,
3905               NULL, HFILL
3906             }
3907         },
3908         { &hf_fp_pdu_length_in_block,
3909             { "PDU length in block",
3910               "fp.pdu-length-in-block", FT_UINT8, BASE_DEC, 0, 0x0,
3911               "Length of each PDU in this block in bytes", HFILL
3912             }
3913         },
3914         { &hf_fp_pdus_in_block,
3915             { "PDUs in block",
3916               "fp.no-pdus-in-block", FT_UINT8, BASE_DEC, 0, 0x0,
3917               "Number of PDUs in block", HFILL
3918             }
3919         },
3920         { &hf_fp_cmch_pi,
3921             { "CmCH-PI",
3922               "fp.cmch-pi", FT_UINT8, BASE_DEC, 0, 0x0f,
3923               "Common Transport Channel Priority Indicator", HFILL
3924             }
3925         },
3926         { &hf_fp_user_buffer_size,
3927             { "User buffer size",
3928               "fp.user-buffer-size", FT_UINT16, BASE_DEC, 0, 0x0,
3929               "User buffer size in octets", HFILL
3930             }
3931         },
3932         { &hf_fp_hsdsch_credits,
3933             { "HS-DSCH Credits",
3934               "fp.hsdsch-credits", FT_UINT16, BASE_DEC, 0, 0x0,
3935               NULL, HFILL
3936             }
3937         },
3938         { &hf_fp_hsdsch_max_macd_pdu_len,
3939             { "Max MAC-d PDU Length",
3940               "fp.hsdsch.max-macd-pdu-len", FT_UINT16, BASE_DEC, 0, 0xfff8,
3941               "Maximum MAC-d PDU Length in bits", HFILL
3942             }
3943         },
3944         { &hf_fp_hsdsch_max_macdc_pdu_len,
3945             { "Max MAC-d/c PDU Length",
3946               "fp.hsdsch.max-macdc-pdu-len", FT_UINT16, BASE_DEC, 0, 0x07ff,
3947               "Maximum MAC-d/c PDU Length in bits", HFILL
3948             }
3949         },
3950         { &hf_fp_hsdsch_interval,
3951             { "HS-DSCH Interval in milliseconds",
3952               "fp.hsdsch-interval", FT_UINT8, BASE_DEC, 0, 0x0,
3953               NULL, HFILL
3954             }
3955         },
3956         { &hf_fp_hsdsch_calculated_rate,
3957             { "Calculated rate allocation (bps)",
3958               "fp.hsdsch-calculated-rate", FT_UINT32, BASE_DEC, 0, 0x0,
3959               "Calculated rate RNC is allowed to send in bps", HFILL
3960             }
3961         },
3962         { &hf_fp_hsdsch_unlimited_rate,
3963             { "Unlimited rate",
3964               "fp.hsdsch-unlimited-rate", FT_NONE, BASE_NONE, 0, 0x0,
3965               "No restriction on rate at which date may be sent", HFILL
3966             }
3967         },
3968         { &hf_fp_hsdsch_repetition_period,
3969             { "HS-DSCH Repetition Period",
3970               "fp.hsdsch-repetition-period", FT_UINT8, BASE_DEC, 0, 0x0,
3971               "HS-DSCH Repetition Period in milliseconds", HFILL
3972             }
3973         },
3974         { &hf_fp_hsdsch_data_padding,
3975             { "Padding",
3976               "fp.hsdsch-data-padding", FT_UINT8, BASE_DEC, 0, 0xf0,
3977               "HS-DSCH Repetition Period in milliseconds", HFILL
3978             }
3979         },
3980         { &hf_fp_hsdsch_new_ie_flags,
3981             { "New IEs flags",
3982               "fp.hsdsch.new-ie-flags", FT_STRING, BASE_NONE, 0, 0x0,
3983               NULL, HFILL
3984             }
3985         },
3986         { &hf_fp_hsdsch_new_ie_flag[0],
3987             { "DRT IE present",
3988               "fp.hsdsch.new-ie-flag", FT_UINT8, BASE_DEC, 0, 0x80,
3989               NULL, HFILL
3990             }
3991         },
3992         { &hf_fp_hsdsch_new_ie_flag[1],
3993             { "New IE present",
3994               "fp.hsdsch.new-ie-flag", FT_UINT8, BASE_DEC, 0, 0x40,
3995               NULL, HFILL
3996             }
3997         },
3998         { &hf_fp_hsdsch_new_ie_flag[2],
3999             { "New IE present",
4000               "fp.hsdsch.new-ie-flag", FT_UINT8, BASE_DEC, 0, 0x20,
4001               NULL, HFILL
4002             }
4003         },
4004         { &hf_fp_hsdsch_new_ie_flag[3],
4005             { "New IE present",
4006               "fp.hsdsch.new-ie-flag", FT_UINT8, BASE_DEC, 0, 0x10,
4007               NULL, HFILL
4008             }
4009         },
4010         { &hf_fp_hsdsch_new_ie_flag[4],
4011             { "New IE present",
4012               "fp.hsdsch.new-ie-flag", FT_UINT8, BASE_DEC, 0, 0x08,
4013               NULL, HFILL
4014             }
4015         },
4016         { &hf_fp_hsdsch_new_ie_flag[5],
4017             { "New IE present",
4018               "fp.hsdsch.new-ie-flag", FT_UINT8, BASE_DEC, 0, 0x04,
4019               NULL, HFILL
4020             }
4021         },
4022         { &hf_fp_hsdsch_new_ie_flag[6],
4023             { "New IE present",
4024               "fp.hsdsch.new-ie-flag", FT_UINT8, BASE_DEC, 0, 0x02,
4025               NULL, HFILL
4026             }
4027         },
4028         { &hf_fp_hsdsch_new_ie_flag[7],
4029             { "Another new IE flags byte",
4030               "fp.hsdsch.new-ie-flags-byte", FT_UINT8, BASE_DEC, 0, 0x01,
4031               "Another new IE flagsbyte", HFILL
4032             }
4033         },
4034         { &hf_fp_hsdsch_drt,
4035             { "DRT",
4036               "fp.hsdsch.drt", FT_UINT8, BASE_DEC, 0, 0xf0,
4037               "Delay Reference Time", HFILL
4038             }
4039         },
4040         { &hf_fp_hsdsch_entity,
4041             { "HS-DSCH Entity",
4042               "fp.hsdsch.entity", FT_UINT8, BASE_DEC, VALS(hsdshc_mac_entity_vals), 0x0,
4043               "Type of MAC entity for this HS-DSCH channel", HFILL
4044             }
4045         },
4046         { &hf_fp_timing_advance,
4047             { "Timing advance",
4048               "fp.timing-advance", FT_UINT8, BASE_DEC, 0, 0x3f,
4049               "Timing advance in chips", HFILL
4050             }
4051         },
4052         { &hf_fp_num_of_pdu,
4053             { "Number of PDUs",
4054               "fp.hsdsch.num-of-pdu", FT_UINT8, BASE_DEC, 0, 0x0,
4055               "Number of PDUs in the payload", HFILL
4056             }
4057         },
4058         { &hf_fp_mac_d_pdu_len,
4059             { "MAC-d PDU Length",
4060               "fp.hsdsch.mac-d-pdu-len", FT_UINT16, BASE_DEC, 0, 0xfff8,
4061               "MAC-d PDU Length in bits", HFILL
4062             }
4063         },
4064         { &hf_fp_mac_d_pdu,
4065             { "MAC-d PDU",
4066               "fp.mac-d-pdu", FT_BYTES, BASE_NONE, NULL, 0x0,
4067               NULL, HFILL
4068             }
4069         },
4070         { &hf_fp_data,
4071             { "Data",
4072               "fp.data", FT_BYTES, BASE_NONE, NULL, 0x0,
4073               NULL, HFILL
4074             }
4075         },
4076         { &hf_fp_crcis,
4077             { "CRCIs",
4078               "fp.crcis", FT_BYTES, BASE_NONE, NULL, 0x0,
4079               "CRC Indicators for uplink TBs", HFILL
4080             }
4081         },
4082         { &hf_fp_t1,
4083             { "T1",
4084               "fp.t1", FT_UINT24, BASE_DEC, NULL, 0x0,
4085               "RNC frame number indicating time it sends frame", HFILL
4086             }
4087         },
4088         { &hf_fp_t2,
4089             { "T2",
4090               "fp.t2", FT_UINT24, BASE_DEC, NULL, 0x0,
4091               "NodeB frame number indicating time it received DL Sync", HFILL
4092             }
4093         },
4094         { &hf_fp_t3,
4095             { "T3",
4096               "fp.t3", FT_UINT24, BASE_DEC, NULL, 0x0,
4097               "NodeB frame number indicating time it sends frame", HFILL
4098             }
4099         },
4100         { &hf_fp_ul_sir_target,
4101             { "UL_SIR_TARGET",
4102               "fp.ul-sir-target", FT_FLOAT, BASE_NONE, 0, 0x0,
4103               "Value (in dB) of the SIR target to be used by the UL inner loop power control", HFILL
4104             }
4105         },
4106         { &hf_fp_pusch_set_id,
4107             { "PUSCH Set Id",
4108               "fp.pusch-set-id", FT_UINT8, BASE_DEC, NULL, 0x0,
4109               "Identifies PUSCH Set from those configured in NodeB", HFILL
4110             }
4111         },
4112         { &hf_fp_activation_cfn,
4113             { "Activation CFN",
4114               "fp.activation-cfn", FT_UINT8, BASE_DEC, NULL, 0x0,
4115               "Activation Connection Frame Number", HFILL
4116             }
4117         },
4118         { &hf_fp_duration,
4119             { "Duration (ms)",
4120               "fp.pusch-set-id", FT_UINT8, BASE_DEC, NULL, 0x0,
4121               "Duration of the activation period of the PUSCH Set", HFILL
4122             }
4123         },
4124         { &hf_fp_power_offset,
4125             { "Power offset",
4126               "fp.power-offset", FT_FLOAT, BASE_NONE, NULL, 0x0,
4127               "Power offset (in dB)", HFILL
4128             }
4129         },
4130         { &hf_fp_code_number,
4131             { "Code number",
4132               "fp.code-number", FT_UINT8, BASE_DEC, NULL, 0x0,
4133               NULL, HFILL
4134             }
4135         },
4136         { &hf_fp_spreading_factor,
4137             { "Spreading factor",
4138               "fp.spreading-factor", FT_UINT8, BASE_DEC, VALS(spreading_factor_vals), 0xf0,
4139               NULL, HFILL
4140             }
4141         },
4142         { &hf_fp_mc_info,
4143             { "MC info",
4144               "fp.mc-info", FT_UINT8, BASE_DEC, NULL, 0x0e,
4145               NULL, HFILL
4146             }
4147         },
4148         { &hf_fp_rach_new_ie_flags,
4149             { "New IEs flags",
4150               "fp.rach.new-ie-flags", FT_STRING, BASE_NONE, 0, 0x0,
4151               NULL, HFILL
4152             }
4153         },
4154         { &hf_fp_rach_new_ie_flag_unused[0],
4155             { "New IE present",
4156               "fp.rach.new-ie-flag", FT_UINT8, BASE_DEC, 0, 0x80,
4157               NULL, HFILL
4158             }
4159         },
4160         { &hf_fp_rach_new_ie_flag_unused[1],
4161             { "New IE present",
4162               "fp.rach.new-ie-flag", FT_UINT8, BASE_DEC, 0, 0x40,
4163               NULL, HFILL
4164             }
4165         },
4166         { &hf_fp_rach_new_ie_flag_unused[2],
4167             { "New IE present",
4168               "fp.rach.new-ie-flag", FT_UINT8, BASE_DEC, 0, 0x20,
4169               "New IE present (unused)", HFILL
4170             }
4171         },
4172         { &hf_fp_rach_new_ie_flag_unused[3],
4173             { "New IE present",
4174               "fp.rach.new-ie-flag", FT_UINT8, BASE_DEC, 0, 0x10,
4175               "New IE present (unused)", HFILL
4176             }
4177         },
4178         { &hf_fp_rach_new_ie_flag_unused[4],
4179             { "New IE present",
4180               "fp.rach.new-ie-flag", FT_UINT8, BASE_DEC, 0, 0x08,
4181               "New IE present (unused)", HFILL
4182             }
4183         },
4184         { &hf_fp_rach_new_ie_flag_unused[5],
4185             { "New IE present",
4186               "fp.rach.new-ie-flag", FT_UINT8, BASE_DEC, 0, 0x04,
4187               "New IE present (unused)", HFILL
4188             }
4189         },
4190         { &hf_fp_rach_new_ie_flag_unused[6],
4191             { "New IE present",
4192               "fp.rach.new-ie-flag", FT_UINT8, BASE_DEC, 0, 0x02,
4193               "New IE present (unused)", HFILL
4194             }
4195         },
4196         { &hf_fp_rach_cell_portion_id_present,
4197             { "Cell portion ID present",
4198               "fp.rach.cell-portion-id-present", FT_UINT8, BASE_DEC, 0, 0x01,
4199               NULL, HFILL
4200             }
4201         },
4202         { &hf_fp_rach_angle_of_arrival_present,
4203             { "Angle of arrival present",
4204               "fp.rach.angle-of-arrival-present", FT_UINT8, BASE_DEC, 0, 0x01,
4205               NULL, HFILL
4206             }
4207         },
4208         { &hf_fp_rach_ext_propagation_delay_present,
4209             { "Ext Propagation Delay Present",
4210               "fp.rach.ext-propagation-delay-present", FT_UINT8, BASE_DEC, 0, 0x02,
4211               NULL, HFILL
4212             }
4213         },
4214         { &hf_fp_rach_ext_rx_sync_ul_timing_deviation_present,
4215             { "Ext Received Sync UL Timing Deviation present",
4216               "fp.rach.ext-rx-sync-ul-timing-deviation-present", FT_UINT8, BASE_DEC, 0, 0x02,
4217               NULL, HFILL
4218             }
4219         },
4220         { &hf_fp_rach_ext_rx_timing_deviation_present,
4221             { "Ext Rx Timing Deviation present",
4222               "fp.rach.ext-rx-timing-deviation-present", FT_UINT8, BASE_DEC, 0, 0x01,
4223               NULL, HFILL
4224             }
4225         },
4226         { &hf_fp_cell_portion_id,
4227             { "Cell Portion ID",
4228               "fp.cell-portion-id", FT_UINT8, BASE_DEC, NULL, 0x3f,
4229               NULL, HFILL
4230             }
4231         },
4232         { &hf_fp_ext_propagation_delay,
4233             { "Ext Propagation Delay",
4234               "fp.ext-propagation-delay", FT_UINT16, BASE_DEC, NULL, 0x03ff,
4235               NULL, HFILL
4236             }
4237         },
4238         { &hf_fp_angle_of_arrival,
4239             { "Angle of Arrival",
4240               "fp.angle-of-arrival", FT_UINT16, BASE_DEC, NULL, 0x03ff,
4241               NULL, HFILL
4242             }
4243         },
4244         { &hf_fp_ext_received_sync_ul_timing_deviation,
4245             { "Ext Received SYNC UL Timing Deviation",
4246               "fp.ext-received-sync-ul-timing-deviation", FT_UINT16, BASE_DEC, NULL, 0x1fff,
4247               NULL, HFILL
4248             }
4249         },
4250
4251
4252         { &hf_fp_radio_interface_parameter_update_flag[0],
4253             { "CFN valid",
4254               "fp.radio-interface-param.cfn-valid", FT_UINT16, BASE_DEC, 0, 0x0001,
4255               NULL, HFILL
4256             }
4257         },
4258         { &hf_fp_radio_interface_parameter_update_flag[1],
4259             { "TPC PO valid",
4260               "fp.radio-interface-param.tpc-po-valid", FT_UINT16, BASE_DEC, 0, 0x0002,
4261               NULL, HFILL
4262             }
4263         },
4264         { &hf_fp_radio_interface_parameter_update_flag[2],
4265             { "DPC mode valid",
4266               "fp.radio-interface-param.dpc-mode-valid", FT_UINT16, BASE_DEC, 0, 0x0004,
4267               NULL, HFILL
4268             }
4269         },
4270         { &hf_fp_radio_interface_parameter_update_flag[3],
4271             { "RL sets indicator valid",
4272               "fp.radio-interface_param.rl-sets-indicator-valid", FT_UINT16, BASE_DEC, 0, 0x0020,
4273               NULL, HFILL
4274             }
4275         },
4276         { &hf_fp_radio_interface_parameter_update_flag[4],
4277             { "MAX_UE_TX_POW valid",
4278               "fp.radio-interface-param.max-ue-tx-pow-valid", FT_UINT16, BASE_DEC, 0, 0x0040,
4279               "MAX UE TX POW valid", HFILL
4280             }
4281         },
4282         { &hf_fp_dpc_mode,
4283             { "DPC Mode",
4284               "fp.dpc-mode", FT_UINT8, BASE_DEC, NULL, 0x20,
4285               "DPC Mode to be applied in the uplink", HFILL
4286             }
4287         },
4288         { &hf_fp_tpc_po,
4289             { "TPC PO",
4290               "fp.tpc-po", FT_UINT8, BASE_DEC, NULL, 0x1f,
4291               NULL, HFILL
4292             }
4293         },
4294         { &hf_fp_multiple_rl_set_indicator,
4295             { "Multiple RL sets indicator",
4296               "fp.multiple-rl-sets-indicator", FT_UINT8, BASE_DEC, NULL, 0x80,
4297               NULL, HFILL
4298             }
4299         },
4300         { &hf_fp_max_ue_tx_pow,
4301             { "MAX_UE_TX_POW",
4302               "fp.max-ue-tx-pow", FT_INT8, BASE_DEC, NULL, 0x0,
4303               "Max UE TX POW (dBm)", HFILL
4304             }
4305         },
4306         { &hf_fp_congestion_status,
4307             { "Congestion Status",
4308               "fp.congestion-status", FT_UINT8, BASE_DEC, VALS(congestion_status_vals), 0x0,
4309               NULL, HFILL
4310             }
4311         },
4312         { &hf_fp_e_rucch_present,
4313             { "E-RUCCH Present",
4314               "fp.erucch-present", FT_UINT8, BASE_DEC, NULL, 0x0,
4315               NULL, HFILL
4316             }
4317         },
4318         { &hf_fp_extended_bits_present,
4319             { "Extended Bits Present",
4320               "fp.extended-bits-present", FT_UINT8, BASE_DEC, NULL, 0x0,
4321               NULL, HFILL
4322             }
4323         },
4324         { &hf_fp_extended_bits,
4325             { "Extended Bits",
4326               "fp.extended-bits", FT_UINT8, BASE_HEX, NULL, 0x0,
4327               NULL, HFILL
4328             }
4329         },
4330         { &hf_fp_spare_extension,
4331             { "Spare Extension",
4332               "fp.spare-extension", FT_NONE, BASE_NONE, NULL, 0x0,
4333               NULL, HFILL
4334             }
4335         },
4336
4337     };
4338
4339
4340     static gint *ett[] =
4341     {
4342         &ett_fp,
4343         &ett_fp_data,
4344         &ett_fp_crcis,
4345         &ett_fp_ddi_config,
4346         &ett_fp_edch_subframe_header,
4347         &ett_fp_edch_subframe,
4348         &ett_fp_edch_maces,
4349         &ett_fp_edch_macis_descriptors,
4350         &ett_fp_edch_macis_pdu,
4351         &ett_fp_hsdsch_new_ie_flags,
4352         &ett_fp_rach_new_ie_flags,
4353         &ett_fp_hsdsch_pdu_block_header,
4354         &ett_fp_release
4355     };
4356
4357     module_t *fp_module;
4358
4359     /* Register protocol. */
4360     proto_fp = proto_register_protocol("FP", "FP", "fp");
4361     proto_register_field_array(proto_fp, hf, array_length(hf));
4362     proto_register_subtree_array(ett, array_length(ett));
4363
4364     /* Allow other dissectors to find this one by name. */
4365     register_dissector("fp", dissect_fp, proto_fp);
4366
4367     /* Preferences */
4368     fp_module = prefs_register_protocol(proto_fp, NULL);
4369
4370     /* Determines whether release information should be displayed */
4371     prefs_register_bool_preference(fp_module, "show_release_info",
4372                                    "Show reported release info",
4373                                    "Show reported release info",
4374                                    &preferences_show_release_info);
4375
4376     /* Determines whether MAC dissector should be called for payloads */
4377     prefs_register_bool_preference(fp_module, "call_mac",
4378                                    "Call MAC dissector for payloads",
4379                                    "Call MAC dissector for payloads",
4380                                    &preferences_call_mac_dissectors);
4381
4382 }
4383
4384
4385 void proto_reg_handoff_fp(void)
4386 {
4387     mac_fdd_rach_handle = find_dissector("mac.fdd.rach");
4388     mac_fdd_fach_handle = find_dissector("mac.fdd.fach");
4389     mac_fdd_pch_handle = find_dissector("mac.fdd.pch");
4390     mac_fdd_dch_handle = find_dissector("mac.fdd.dch");
4391     mac_fdd_edch_handle = find_dissector("mac.fdd.edch");
4392     mac_fdd_hsdsch_handle = find_dissector("mac.fdd.hsdsch");
4393
4394     heur_dissector_add("udp", heur_dissect_fp, proto_fp);
4395 }
4396