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