1 /* Routines for UMTS FP disassembly
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
9 * Copyright 1998 Gerald Combs
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.
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.
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.
30 #include <epan/packet.h>
31 #include <epan/expert.h>
33 #include "packet-umts_fp.h"
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)
40 * - IUR interface-specific formats
41 * - verify header & payload CRCs
42 * - do CRC verification before further parsing
45 /* Initialize the protocol and registered fields. */
48 static int hf_fp_channel_type = -1;
49 static int hf_fp_division = -1;
50 static int hf_fp_direction = -1;
51 static int hf_fp_header_crc = -1;
52 static int hf_fp_ft = -1;
53 static int hf_fp_cfn = -1;
54 static int hf_fp_pch_cfn = -1;
55 static int hf_fp_pch_toa = -1;
56 static int hf_fp_cfn_control = -1;
57 static int hf_fp_toa = -1;
58 static int hf_fp_tfi = -1;
59 static int hf_fp_usch_tfi = -1;
60 static int hf_fp_cpch_tfi = -1;
61 static int hf_fp_propagation_delay = -1;
62 static int hf_fp_tb = -1;
63 static int hf_fp_chan_zero_tbs = -1;
64 static int hf_fp_received_sync_ul_timing_deviation = -1;
65 static int hf_fp_pch_pi = -1;
66 static int hf_fp_pch_tfi = -1;
67 static int hf_fp_fach_tfi = -1;
68 static int hf_fp_transmit_power_level = -1;
69 static int hf_fp_paging_indication_bitmap = -1;
70 static int hf_fp_pdsch_set_id = -1;
71 static int hf_fp_rx_timing_deviation = -1;
72 static int hf_fp_dch_e_rucch_flag = -1;
73 static int hf_fp_dch_control_frame_type = -1;
74 static int hf_fp_dch_rx_timing_deviation = -1;
75 static int hf_fp_quality_estimate = -1;
76 static int hf_fp_payload_crc = -1;
77 static int hf_fp_edch_header_crc = -1;
78 static int hf_fp_edch_fsn = -1;
79 static int hf_fp_edch_subframe = -1;
80 static int hf_fp_edch_number_of_subframes = -1;
81 static int hf_fp_edch_harq_retransmissions = -1;
82 static int hf_fp_edch_subframe_number = -1;
83 static int hf_fp_edch_number_of_mac_es_pdus = -1;
84 static int hf_fp_edch_ddi = -1;
85 static int hf_fp_edch_subframe_header = -1;
86 static int hf_fp_edch_number_of_mac_d_pdus = -1;
87 static int hf_fp_edch_pdu_padding = -1;
88 static int hf_fp_edch_tsn = -1;
89 static int hf_fp_edch_mac_es_pdu = -1;
90 static int hf_fp_frame_seq_nr = -1;
91 static int hf_fp_hsdsch_pdu_block_header = -1;
92 static int hf_fp_hsdsch_pdu_block = -1;
93 static int hf_fp_flush = -1;
94 static int hf_fp_fsn_drt_reset = -1;
95 static int hf_fp_drt_indicator = -1;
96 static int hf_fp_fach_indicator = -1;
97 static int hf_fp_total_pdu_blocks = -1;
98 static int hf_fp_drt = -1;
99 static int hf_fp_hrnti = -1;
100 static int hf_fp_rach_measurement_result = -1;
101 static int hf_fp_lchid = -1;
102 static int hf_fp_pdu_length_in_block = -1;
103 static int hf_fp_pdus_in_block = -1;
104 static int hf_fp_cmch_pi = -1;
105 static int hf_fp_user_buffer_size = -1;
106 static int hf_fp_hsdsch_credits = -1;
107 static int hf_fp_hsdsch_max_macd_pdu_len = -1;
108 static int hf_fp_hsdsch_max_macdc_pdu_len = -1;
109 static int hf_fp_hsdsch_interval = -1;
110 static int hf_fp_hsdsch_calculated_rate = -1;
111 static int hf_fp_hsdsch_unlimited_rate = -1;
112 static int hf_fp_hsdsch_repetition_period = -1;
113 static int hf_fp_hsdsch_data_padding = -1;
114 static int hf_fp_hsdsch_new_ie_flags = -1;
115 static int hf_fp_hsdsch_new_ie_flag[8] = {-1, -1, -1, -1, -1, -1, -1, -1};
116 static int hf_fp_hsdsch_drt = -1;
117 static int hf_fp_hsdsch_entity = -1;
118 static int hf_fp_timing_advance = -1;
119 static int hf_fp_num_of_pdu = -1;
120 static int hf_fp_mac_d_pdu_len = -1;
121 static int hf_fp_mac_d_pdu = -1;
122 static int hf_fp_data = -1;
123 static int hf_fp_crcis = -1;
124 static int hf_fp_crci[8] = {-1, -1, -1, -1, -1, -1, -1, -1};
125 static int hf_fp_common_control_frame_type = -1;
126 static int hf_fp_t1 = -1;
127 static int hf_fp_t2 = -1;
128 static int hf_fp_t3 = -1;
129 static int hf_fp_ul_sir_target = -1;
130 static int hf_fp_pusch_set_id = -1;
131 static int hf_fp_activation_cfn = -1;
132 static int hf_fp_duration = -1;
133 static int hf_fp_power_offset = -1;
134 static int hf_fp_code_number = -1;
135 static int hf_fp_spreading_factor = -1;
136 static int hf_fp_mc_info = -1;
138 static int hf_fp_rach_new_ie_flags = -1;
139 static int hf_fp_rach_new_ie_flag_unused[7] = {-1, -1, -1, -1, -1, -1, -1 };
140 static int hf_fp_rach_ext_propagation_delay_present = -1;
141 static int hf_fp_rach_cell_portion_id_present = -1;
142 static int hf_fp_rach_angle_of_arrival_present = -1;
143 static int hf_fp_rach_ext_rx_sync_ul_timing_deviation_present = -1;
144 static int hf_fp_rach_ext_rx_timing_deviation_present = -1;
146 static int hf_fp_cell_portion_id = -1;
147 static int hf_fp_ext_propagation_delay = -1;
148 static int hf_fp_angle_of_arrival = -1;
149 static int hf_fp_ext_received_sync_ul_timing_deviation = -1;
151 static int hf_fp_radio_interface_parameter_update_flag[5] = {-1, -1, -1, -1, -1};
152 static int hf_fp_dpc_mode = -1;
153 static int hf_fp_tpc_po = -1;
154 static int hf_fp_multiple_rl_set_indicator = -1;
155 static int hf_fp_max_ue_tx_pow = -1;
156 static int hf_fp_congestion_status = -1;
157 static int hf_fp_e_rucch_present = -1;
158 static int hf_fp_extended_bits_present = -1;
159 static int hf_fp_extended_bits = -1;
160 static int hf_fp_spare_extension = -1;
163 static int ett_fp = -1;
164 static int ett_fp_data = -1;
165 static int ett_fp_crcis = -1;
166 static int ett_fp_edch_subframe_header = -1;
167 static int ett_fp_edch_subframe = -1;
168 static int ett_fp_hsdsch_new_ie_flags = -1;
169 static int ett_fp_rach_new_ie_flags = -1;
170 static int ett_fp_hsdsch_pdu_block_header = -1;
172 static dissector_handle_t mac_fdd_dch_handle;
173 static dissector_handle_t mac_fdd_rach_handle;
174 static dissector_handle_t mac_fdd_fach_handle;
175 static dissector_handle_t mac_fdd_pch_handle;
176 static dissector_handle_t mac_fdd_edch_handle;
177 static dissector_handle_t mac_fdd_hsdsch_handle;
179 static proto_tree *top_level_tree = NULL;
181 /* E-DCH channel header information */
184 guint8 subframe_number;
185 guint8 number_of_mac_es_pdus;
187 guint16 number_of_mac_d_pdus[64];
190 static const value_string channel_type_vals[] =
192 { CHANNEL_RACH_FDD, "RACH_FDD" },
193 { CHANNEL_RACH_TDD, "RACH_TDD" },
194 { CHANNEL_FACH_FDD, "FACH_FDD" },
195 { CHANNEL_FACH_TDD, "FACH_TDD" },
196 { CHANNEL_DSCH_FDD, "DSCH_FDD" },
197 { CHANNEL_DSCH_TDD, "DSCH_TDD" },
198 { CHANNEL_USCH_TDD_384, "USCH_TDD_384" },
199 { CHANNEL_USCH_TDD_128, "USCH_TDD_128" },
200 { CHANNEL_PCH, "PCH" },
201 { CHANNEL_CPCH, "CPCH" },
202 { CHANNEL_BCH, "BCH" },
203 { CHANNEL_DCH, "DCH" },
204 { CHANNEL_HSDSCH, "HSDSCH" },
205 { CHANNEL_IUR_CPCHF, "IUR CPCHF" },
206 { CHANNEL_IUR_FACH, "IUR FACH" },
207 { CHANNEL_IUR_DSCH, "IUR DSCH" },
208 { CHANNEL_EDCH, "EDCH" },
209 { CHANNEL_RACH_TDD_128, "RACH_TDD_128" },
213 static const value_string division_vals[] =
215 { Division_FDD, "FDD"},
216 { Division_TDD_384, "TDD-384"},
217 { Division_TDD_128, "TDD-128"},
218 { Division_TDD_768, "TDD-768"},
223 static const value_string data_control_vals[] = {
229 static const value_string direction_vals[] = {
235 static const value_string crci_vals[] = {
237 { 1, "Not correct" },
241 static const value_string paging_indication_vals[] = {
242 { 0, "no PI-bitmap in payload" },
243 { 1, "PI-bitmap in payload" },
247 static const value_string spreading_factor_vals[] = {
258 static const value_string congestion_status_vals[] = {
259 {0, "No TNL congestion"},
260 {1, "Reserved for future use"},
261 {2, "TNL congestion - detected by delay build-up"},
262 {3, "TNL congestion - detected by frame loss"},
266 static const value_string e_rucch_flag_vals[] = {
267 { 0, "Conventional E-RUCCH reception" },
268 { 1, "TA Request reception" },
272 static const value_string hsdshc_mac_entity_vals[] = {
273 { entity_not_specified, "Unspecified (assume MAC-hs)" },
280 /* Dedicated control types */
281 #define DCH_OUTER_LOOP_POWER_CONTROL 1
282 #define DCH_TIMING_ADJUSTMENT 2
283 #define DCH_DL_SYNCHRONISATION 3
284 #define DCH_UL_SYNCHRONISATION 4
286 #define DCH_DL_NODE_SYNCHRONISATION 6
287 #define DCH_UL_NODE_SYNCHRONISATION 7
288 #define DCH_RX_TIMING_DEVIATION 8
289 #define DCH_RADIO_INTERFACE_PARAMETER_UPDATE 9
290 #define DCH_TIMING_ADVANCE 10
291 #define DCH_TNL_CONGESTION_INDICATION 11
293 static const value_string dch_control_frame_type_vals[] = {
294 { DCH_OUTER_LOOP_POWER_CONTROL, "OUTER LOOP POWER CONTROL" },
295 { DCH_TIMING_ADJUSTMENT, "TIMING ADJUSTMENT" },
296 { DCH_DL_SYNCHRONISATION, "DL SYNCHRONISATION" },
297 { DCH_UL_SYNCHRONISATION, "UL SYNCHRONISATION" },
298 { 5, "Reserved Value" },
299 { DCH_DL_NODE_SYNCHRONISATION, "DL NODE SYNCHRONISATION" },
300 { DCH_UL_NODE_SYNCHRONISATION, "UL NODE SYNCHRONISATION" },
301 { DCH_RX_TIMING_DEVIATION, "RX TIMING DEVIATION" },
302 { DCH_RADIO_INTERFACE_PARAMETER_UPDATE, "RADIO INTERFACE PARAMETER UPDATE" },
303 { DCH_TIMING_ADVANCE, "TIMING ADVANCE" },
304 { DCH_TNL_CONGESTION_INDICATION, "TNL CONGESTION INDICATION" },
309 /* Common channel control types */
310 #define COMMON_OUTER_LOOP_POWER_CONTROL 1
311 #define COMMON_TIMING_ADJUSTMENT 2
312 #define COMMON_DL_SYNCHRONISATION 3
313 #define COMMON_UL_SYNCHRONISATION 4
315 #define COMMON_DL_NODE_SYNCHRONISATION 6
316 #define COMMON_UL_NODE_SYNCHRONISATION 7
317 #define COMMON_DYNAMIC_PUSCH_ASSIGNMENT 8
318 #define COMMON_TIMING_ADVANCE 9
319 #define COMMON_HS_DSCH_Capacity_Request 10
320 #define COMMON_HS_DSCH_Capacity_Allocation 11
321 #define COMMON_HS_DSCH_Capacity_Allocation_Type_2 12
323 static const value_string common_control_frame_type_vals[] = {
324 { COMMON_OUTER_LOOP_POWER_CONTROL, "OUTER LOOP POWER CONTROL" },
325 { COMMON_TIMING_ADJUSTMENT, "TIMING ADJUSTMENT" },
326 { COMMON_DL_SYNCHRONISATION, "DL SYNCHRONISATION" },
327 { COMMON_UL_SYNCHRONISATION, "UL SYNCHRONISATION" },
328 { 5, "Reserved Value" },
329 { COMMON_DL_NODE_SYNCHRONISATION, "DL NODE SYNCHRONISATION" },
330 { COMMON_UL_NODE_SYNCHRONISATION, "UL NODE SYNCHRONISATION" },
331 { COMMON_DYNAMIC_PUSCH_ASSIGNMENT, "DYNAMIC PUSCH ASSIGNMENT" },
332 { COMMON_TIMING_ADVANCE, "TIMING ADVANCE" },
333 { COMMON_HS_DSCH_Capacity_Request, "HS-DSCH Capacity Request" },
334 { COMMON_HS_DSCH_Capacity_Allocation, "HS-DSCH Capacity Allocation" },
335 { COMMON_HS_DSCH_Capacity_Allocation_Type_2, "HS-DSCH Capacity Allocation Type 2" },
339 /* Dissect message parts */
340 static int dissect_tb_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
341 int offset, struct fp_info *p_fp_info,
342 dissector_handle_t *data_handle);
343 static int dissect_macd_pdu_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
344 int offset, guint16 length, guint16 number_of_pdus);
345 static int dissect_macd_pdu_data_type_2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
346 int offset, guint16 length, guint16 number_of_pdus);
348 static int dissect_crci_bits(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
349 fp_info *p_fp_info, int offset);
350 static void dissect_spare_extension_and_crc(tvbuff_t *tvb, packet_info *pinfo,
351 proto_tree *tree, guint8 dch_crc_present,
354 /* Dissect common control messages */
355 static int dissect_common_outer_loop_power_control(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb,
356 int offset, struct fp_info *p_fp_info);
357 static int dissect_common_timing_adjustment(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb,
358 int offset, struct fp_info *p_fp_info);
359 static int dissect_common_dl_node_synchronisation(packet_info *pinfo, proto_tree *tree,
360 tvbuff_t *tvb, int offset);
361 static int dissect_common_ul_node_synchronisation(packet_info *pinfo, proto_tree *tree,
362 tvbuff_t *tvb, int offset);
363 static int dissect_common_dl_synchronisation(packet_info *pinfo, proto_tree *tree,
364 tvbuff_t *tvb, int offset,
365 struct fp_info *p_fp_info);
366 static int dissect_common_ul_synchronisation(packet_info *pinfo, proto_tree *tree,
367 tvbuff_t *tvb, int offset,
368 struct fp_info *p_fp_info);
369 static int dissect_common_timing_advance(packet_info *pinfo, proto_tree *tree,
370 tvbuff_t *tvb, int offset);
371 static int dissect_hsdpa_capacity_request(packet_info *pinfo, proto_tree *tree,
372 tvbuff_t *tvb, int offset);
373 static int dissect_hsdpa_capacity_allocation(packet_info *pinfo, proto_tree *tree,
374 tvbuff_t *tvb, int offset,
375 struct fp_info *p_fp_info);
376 static int dissect_hsdpa_capacity_allocation_type_2(packet_info *pinfo, proto_tree *tree,
377 tvbuff_t *tvb, int offset);
378 static void dissect_common_control(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
379 int offset, struct fp_info *p_fp_info);
380 static int dissect_common_dynamic_pusch_assignment(packet_info *pinfo, proto_tree *tree,
381 tvbuff_t *tvb, int offset);
383 /* Dissect common channel types */
384 static void dissect_rach_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
385 int offset, struct fp_info *p_fp_info);
386 static void dissect_fach_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
387 int offset, struct fp_info *p_fp_info);
388 static void dissect_dsch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
389 int offset, struct fp_info *p_fp_info);
390 static void dissect_usch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
391 int offset, struct fp_info *p_fp_info);
392 static void dissect_pch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
393 int offset, struct fp_info *p_fp_info);
394 static void dissect_cpch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
395 int offset, struct fp_info *p_fp_info);
396 static void dissect_bch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
397 int offset, struct fp_info *p_fp_info);
398 static void dissect_iur_dsch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
399 int offset, struct fp_info *p_fp_info _U_);
400 static void dissect_hsdsch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
401 int offset, struct fp_info *p_fp_info);
402 static void dissect_hsdsch_type_2_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
403 int offset, struct fp_info *p_fp_info);
406 /* Dissect DCH control messages */
407 static int dissect_dch_timing_adjustment(proto_tree *tree, packet_info *pinfo,
408 tvbuff_t *tvb, int offset);
409 static int dissect_dch_rx_timing_deviation(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset,
410 struct fp_info *p_fp_info);
411 static int dissect_dch_dl_synchronisation(proto_tree *tree, packet_info *pinfo,
412 tvbuff_t *tvb, int offset);
413 static int dissect_dch_ul_synchronisation(proto_tree *tree, packet_info *pinfo,
414 tvbuff_t *tvb, int offset);
415 static int dissect_dch_outer_loop_power_control(proto_tree *tree, packet_info *pinfo,
416 tvbuff_t *tvb, int offset);
417 static int dissect_dch_dl_node_synchronisation(proto_tree *tree, packet_info *pinfo,
418 tvbuff_t *tvb, int offset);
419 static int dissect_dch_ul_node_synchronisation(proto_tree *tree, packet_info *pinfo,
420 tvbuff_t *tvb, int offset);
421 static int dissect_dch_radio_interface_parameter_update(proto_tree *tree, packet_info *pinfo,
422 tvbuff_t *tvb, int offset);
423 static int dissect_dch_timing_advance(proto_tree *tree, packet_info *pinfo,
424 tvbuff_t *tvb, int offset, struct fp_info *p_fp_info);
425 static int dissect_dch_tnl_congestion_indication(proto_tree *tree, packet_info *pinfo,
426 tvbuff_t *tvb, int offset);
429 static void dissect_dch_control_frame(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb,
430 int offset, struct fp_info *p_fp_info);
433 /* Dissect a DCH channel */
434 static void dissect_dch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
435 int offset, struct fp_info *p_fp_info);
437 /* Dissect dedicated channels */
438 static void dissect_e_dch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
439 int offset, struct fp_info *p_fp_info);
441 /* Main dissection function */
442 static void dissect_fp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
444 /* Protocol registration */
445 void proto_register_fp(void);
446 void proto_reg_handoff_fp(void);
449 static int get_tb_count(struct fp_info *p_fp_info)
451 int chan, tb_count = 0;
452 for (chan = 0; chan < p_fp_info->num_chans; chan++) {
453 tb_count += p_fp_info->chan_num_tbs[chan];
458 /* Dissect the TBs of a data frame */
459 int dissect_tb_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
460 int offset, struct fp_info *p_fp_info,
461 dissector_handle_t *data_handle)
463 int chan, num_tbs = 0;
466 proto_item *tree_ti = NULL;
467 proto_tree *data_tree = NULL;
468 gboolean dissected = FALSE;
472 /* Add data subtree */
473 tree_ti = proto_tree_add_item(tree, hf_fp_data, tvb, offset, -1, FALSE);
474 proto_item_set_text(tree_ti, "TB data for %u chans", p_fp_info->num_chans);
475 data_tree = proto_item_add_subtree(tree_ti, ett_fp_data);
478 /* Now for the TB data */
479 for (chan=0; chan < p_fp_info->num_chans; chan++)
483 /* Clearly show channels with no TBs */
484 if (p_fp_info->chan_num_tbs[chan] == 0)
486 proto_item *no_tb_ti = proto_tree_add_uint(data_tree, hf_fp_chan_zero_tbs, tvb,
487 offset+(bit_offset/8),
489 proto_item_append_text(no_tb_ti, " (of size %d)",
490 p_fp_info->chan_tf_size[chan]);
491 PROTO_ITEM_SET_GENERATED(no_tb_ti);
494 /* Show TBs from non-empty channels */
495 pinfo->fd->subnum = chan; /* set subframe number to current TB */
496 for (n=0; n < p_fp_info->chan_num_tbs[chan]; n++)
502 ti = proto_tree_add_item(data_tree, hf_fp_tb, tvb,
503 offset + (bit_offset/8),
504 ((bit_offset % 8) + p_fp_info->chan_tf_size[chan] + 7) / 8,
506 proto_item_set_text(ti, "TB (chan %u, tb %u, %u bits)",
507 chan+1, n+1, p_fp_info->chan_tf_size[chan]);
508 if (data_handle && p_fp_info->chan_tf_size[chan] > 0) {
509 next_tvb = tvb_new_subset(tvb, offset + bit_offset/8,
510 ((bit_offset % 8) + p_fp_info->chan_tf_size[chan] + 7) / 8, -1);
511 /* TODO: maybe this decision can be based only on info available in fp_info */
512 call_dissector(*data_handle, next_tvb, pinfo, top_level_tree);
518 /* Advance bit offset */
519 bit_offset += p_fp_info->chan_tf_size[chan];
520 data_bits += p_fp_info->chan_tf_size[chan];
522 /* Pad out to next byte */
525 bit_offset += (8 - (bit_offset % 8));
530 if (dissected == FALSE && check_col(pinfo->cinfo, COL_INFO))
532 col_append_fstr(pinfo->cinfo, COL_INFO, "(%u bits in %u tbs)",
536 /* Data tree should cover entire length */
539 proto_item_set_len(tree_ti, bit_offset/8);
540 proto_item_append_text(tree_ti, " (%u bits in %u tbs)", data_bits, num_tbs);
543 /* Move offset past TBs (we know its already padded out to next byte) */
544 offset += (bit_offset / 8);
550 /* Dissect the MAC-d PDUs of an HS-DSCH (type 1) frame.
551 Length is in bits, and payload is offset by 4 bits of padding */
552 int dissect_macd_pdu_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
553 int offset, guint16 length, guint16 number_of_pdus)
557 proto_item *pdus_ti = NULL;
558 proto_tree *data_tree = NULL;
559 gboolean dissected = FALSE;
561 /* Add data subtree */
564 pdus_ti = proto_tree_add_item(tree, hf_fp_data, tvb, offset, -1, FALSE);
565 proto_item_set_text(pdus_ti, "%u MAC-d PDUs of %u bits", number_of_pdus, length);
566 data_tree = proto_item_add_subtree(pdus_ti, ett_fp_data);
569 /* Now for the PDUs */
570 for (pdu=0; pdu < number_of_pdus; pdu++)
576 /* Show 4 bits padding at start of PDU */
577 proto_tree_add_item(data_tree, hf_fp_hsdsch_data_padding, tvb, offset+(bit_offset/8), 1, FALSE);
585 pinfo->fd->subnum = pdu; /* set subframe number to current TB */
586 pdu_ti = proto_tree_add_item(data_tree, hf_fp_mac_d_pdu, tvb,
587 offset + (bit_offset/8),
588 ((bit_offset % 8) + length + 7) / 8,
590 proto_item_set_text(pdu_ti, "MAC-d PDU (PDU %u)", pdu+1);
591 next_tvb = tvb_new_subset(tvb, offset + bit_offset/8,
592 ((bit_offset % 8) + length + 7)/8, -1);
593 call_dissector(mac_fdd_hsdsch_handle, next_tvb, pinfo, top_level_tree);
597 /* Advance bit offset */
598 bit_offset += length;
600 /* Pad out to next byte */
603 bit_offset += (8 - (bit_offset % 8));
607 /* Data tree should cover entire length */
608 proto_item_set_len(pdus_ti, bit_offset/8);
610 /* Move offset past PDUs (we know its already padded out to next byte) */
611 offset += (bit_offset / 8);
613 /* Show summary in info column */
614 if (dissected == FALSE && check_col(pinfo->cinfo, COL_INFO))
616 col_append_fstr(pinfo->cinfo, COL_INFO, " %u PDUs of %u bits",
617 number_of_pdus, length);
624 /* Dissect the MAC-d PDUs of an HS-DSCH (type 2) frame.
625 Length is in bytes, and payload is byte-aligned (no padding) */
626 int dissect_macd_pdu_data_type_2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
627 int offset, guint16 length, guint16 number_of_pdus)
630 proto_item *pdus_ti = NULL;
631 proto_tree *data_tree = NULL;
632 int first_offset = offset;
634 /* Add data subtree */
637 pdus_ti = proto_tree_add_item(tree, hf_fp_data, tvb, offset, -1, FALSE);
638 proto_item_set_text(pdus_ti, "%u MAC-d PDUs of %u bytes", number_of_pdus, length);
639 data_tree = proto_item_add_subtree(pdus_ti, ett_fp_data);
642 /* Now for the PDUs */
643 for (pdu=0; pdu < number_of_pdus; pdu++)
650 pdu_ti = proto_tree_add_item(data_tree, hf_fp_mac_d_pdu, tvb,
651 offset, length, FALSE);
652 proto_item_set_text(pdu_ti, "MAC-d PDU (PDU %u)", pdu+1);
659 /* Data tree should cover entire length */
660 proto_item_set_len(pdus_ti, offset-first_offset);
662 /* Show summary in info column */
663 if (check_col(pinfo->cinfo, COL_INFO))
665 col_append_fstr(pinfo->cinfo, COL_INFO, " %u PDUs of %u bits",
666 number_of_pdus, length*8);
672 /* Dissect CRCI bits (uplink) */
673 int dissect_crci_bits(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
674 fp_info *p_fp_info, int offset)
677 proto_item *ti = NULL;
678 proto_tree *crcis_tree = NULL;
681 num_tbs = get_tb_count(p_fp_info);
683 /* Add CRCIs subtree */
686 ti = proto_tree_add_item(tree, hf_fp_crcis, tvb, offset, (num_tbs+7)/8, FALSE);
687 proto_item_set_text(ti, "CRCI bits for %u tbs", num_tbs);
688 crcis_tree = proto_item_add_subtree(ti, ett_fp_crcis);
692 for (n=0; n < num_tbs; n++)
694 int bit = (tvb_get_guint8(tvb, offset+(n/8)) >> (7-(n%8))) & 0x01;
695 proto_tree_add_item(crcis_tree, hf_fp_crci[n%8], tvb, offset+(n/8),
701 expert_add_info_format(pinfo, ti,
702 PI_CHECKSUM, PI_WARN,
703 "CRCI error bit set for TB");
709 /* Highlight range of bytes covered by indicator bits */
710 proto_item_set_len(ti, (num_tbs+7) / 8);
712 /* Show error count in root text */
713 proto_item_append_text(ti, " (%u errors)", errors);
716 offset += ((num_tbs+7) / 8);
721 void dissect_spare_extension_and_crc(tvbuff_t *tvb, packet_info *pinfo,
722 proto_tree *tree, guint8 dch_crc_present,
726 int remain = tvb_length_remaining(tvb, offset);
727 proto_item *ti = NULL;
729 /* Payload CRC (optional) */
730 if (dch_crc_present == 1 || (dch_crc_present == 2 && remain >= 2))
735 if (remain > crc_size)
737 ti = proto_tree_add_item(tree, hf_fp_spare_extension, tvb,
738 offset, remain-crc_size, FALSE);
739 proto_item_append_text(ti, " (%u octets)", remain-crc_size);
740 expert_add_info_format(pinfo, ti,
741 PI_UNDECODED, PI_WARN,
742 "Spare Extension present (%u bytes)", remain-crc_size);
743 offset += remain-crc_size;
748 proto_tree_add_item(tree, hf_fp_payload_crc, tvb, offset, crc_size,
755 /***********************************************************/
756 /* Common control message types */
758 int dissect_common_outer_loop_power_control(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb,
759 int offset, struct fp_info *p_fp_info _U_)
761 return dissect_dch_outer_loop_power_control(tree, pinfo, tvb, offset);
765 int dissect_common_timing_adjustment(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb,
766 int offset, struct fp_info *p_fp_info)
768 if (p_fp_info->channel != CHANNEL_PCH)
774 cfn = tvb_get_guint8(tvb, offset);
775 proto_tree_add_item(tree, hf_fp_cfn_control, tvb, offset, 1, FALSE);
779 toa = tvb_get_ntohs(tvb, offset);
780 proto_tree_add_item(tree, hf_fp_toa, tvb, offset, 2, FALSE);
783 if (check_col(pinfo->cinfo, COL_INFO))
785 col_append_fstr(pinfo->cinfo, COL_INFO, " CFN=%u, ToA=%d", cfn, toa);
793 /* PCH CFN is 12 bits */
794 cfn = (tvb_get_ntohs(tvb, offset) >> 4);
795 proto_tree_add_item(tree, hf_fp_pch_cfn, tvb, offset, 2, FALSE);
798 /* 4 bits of padding follow... */
800 /* 20 bits of ToA (followed by 4 padding bits) */
801 toa = ((int)(tvb_get_ntoh24(tvb, offset) << 8)) / 4096;
802 proto_tree_add_int(tree, hf_fp_pch_toa, tvb, offset, 3, toa);
805 if (check_col(pinfo->cinfo, COL_INFO))
807 col_append_fstr(pinfo->cinfo, COL_INFO, " CFN=%u, ToA=%d", cfn, toa);
813 int dissect_common_dl_node_synchronisation(packet_info *pinfo, proto_tree *tree,
814 tvbuff_t *tvb, int offset)
817 guint32 t1 = tvb_get_ntoh24(tvb, offset);
818 proto_tree_add_item(tree, hf_fp_t1, tvb, offset, 3, FALSE);
821 if (check_col(pinfo->cinfo, COL_INFO))
823 col_append_fstr(pinfo->cinfo, COL_INFO, " T1=%u", t1);
829 int dissect_common_ul_node_synchronisation(packet_info *pinfo, proto_tree *tree,
830 tvbuff_t *tvb, int offset)
835 t1 = tvb_get_ntoh24(tvb, offset);
836 proto_tree_add_item(tree, hf_fp_t1, tvb, offset, 3, FALSE);
840 t2 = tvb_get_ntoh24(tvb, offset);
841 proto_tree_add_item(tree, hf_fp_t2, tvb, offset, 3, FALSE);
845 t3 = tvb_get_ntoh24(tvb, offset);
846 proto_tree_add_item(tree, hf_fp_t3, tvb, offset, 3, FALSE);
849 if (check_col(pinfo->cinfo, COL_INFO))
851 col_append_fstr(pinfo->cinfo, COL_INFO, " T1=%u T2=%u, T3=%u",
858 int dissect_common_dl_synchronisation(packet_info *pinfo, proto_tree *tree,
859 tvbuff_t *tvb, int offset, struct fp_info *p_fp_info)
863 if (p_fp_info->channel != CHANNEL_PCH)
866 cfn = tvb_get_guint8(tvb, offset);
867 proto_tree_add_item(tree, hf_fp_cfn_control, tvb, offset, 1, FALSE);
872 /* PCH CFN is 12 bits */
873 cfn = (tvb_get_ntohs(tvb, offset) >> 4);
874 proto_tree_add_item(tree, hf_fp_pch_cfn, tvb, offset, 2, FALSE);
876 /* 4 bits of padding follow... */
880 if (check_col(pinfo->cinfo, COL_INFO))
882 col_append_fstr(pinfo->cinfo, COL_INFO, " CFN=%u", cfn);
888 int dissect_common_ul_synchronisation(packet_info *pinfo, proto_tree *tree,
889 tvbuff_t *tvb, int offset, struct fp_info *p_fp_info)
891 return dissect_common_timing_adjustment(pinfo, tree, tvb, offset, p_fp_info);
894 int dissect_common_timing_advance(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
897 guint16 timing_advance;
900 cfn = tvb_get_guint8(tvb, offset);
901 proto_tree_add_item(tree, hf_fp_cfn_control, tvb, offset, 1, FALSE);
905 timing_advance = (tvb_get_guint8(tvb, offset) & 0x3f) * 4;
906 proto_tree_add_uint(tree, hf_fp_timing_advance, tvb, offset, 1, timing_advance);
909 if (check_col(pinfo->cinfo, COL_INFO))
911 col_append_fstr(pinfo->cinfo, COL_INFO, " CFN = %u, TA = %u",
912 cfn, timing_advance);
918 int dissect_hsdpa_capacity_request(packet_info *pinfo, proto_tree *tree,
919 tvbuff_t *tvb, int offset)
922 guint16 user_buffer_size;
925 priority = (tvb_get_guint8(tvb, offset) & 0x0f);
926 proto_tree_add_item(tree, hf_fp_cmch_pi, tvb, offset, 1, FALSE);
929 /* User buffer size */
930 user_buffer_size = tvb_get_ntohs(tvb, offset);
931 proto_tree_add_item(tree, hf_fp_user_buffer_size, tvb, offset, 2, FALSE);
934 if (check_col(pinfo->cinfo, COL_INFO))
936 col_append_fstr(pinfo->cinfo, COL_INFO, " CmCH-PI=%u User-Buffer-Size=%u",
937 priority, user_buffer_size);
943 int dissect_hsdpa_capacity_allocation(packet_info *pinfo, proto_tree *tree,
944 tvbuff_t *tvb, int offset,
945 struct fp_info *p_fp_info)
949 guint16 max_pdu_length;
950 guint8 repetition_period;
954 /* Congestion status (introduced sometime during R6...) */
955 if ((p_fp_info->release == 6) || (p_fp_info->release == 7))
957 proto_tree_add_bits_item(tree, hf_fp_congestion_status, tvb,
958 offset*8 + 2, 2, FALSE);
962 proto_tree_add_item(tree, hf_fp_cmch_pi, tvb, offset, 1, FALSE);
965 /* Max MAC-d PDU length (13 bits) */
966 max_pdu_length = tvb_get_ntohs(tvb, offset) >> 3;
967 proto_tree_add_item(tree, hf_fp_hsdsch_max_macd_pdu_len, tvb, offset, 2, FALSE);
970 /* HS-DSCH credits (11 bits) */
971 ti = proto_tree_add_bits_ret_val(tree, hf_fp_hsdsch_credits, tvb,
972 offset*8 + 5, 11, &credits, FALSE);
975 /* Interesting values */
978 proto_item_append_text(ti, " (stop transmission)");
979 expert_add_info_format(pinfo, ti,
980 PI_RESPONSE_CODE, PI_NOTE,
981 "Stop HSDPA transmission");
985 proto_item_append_text(ti, " (unlimited)");
988 /* HS-DSCH Interval */
989 interval = tvb_get_guint8(tvb, offset);
990 ti = proto_tree_add_uint(tree, hf_fp_hsdsch_interval, tvb, offset, 1, interval*10);
994 proto_item_append_text(ti, " (none of the credits shall be used)");
997 /* HS-DSCH Repetition period */
998 repetition_period = tvb_get_guint8(tvb, offset);
999 ti = proto_tree_add_item(tree, hf_fp_hsdsch_repetition_period, tvb, offset, 1, FALSE);
1001 if (repetition_period == 0)
1003 proto_item_append_text(ti, " (unlimited repetition period)");
1006 /* Calculated and show effective rate enabled */
1007 if (credits == 2047)
1009 rate_ti = proto_tree_add_item(tree, hf_fp_hsdsch_unlimited_rate, tvb, 0, 0, FALSE);
1010 PROTO_ITEM_SET_GENERATED(rate_ti);
1016 /* Cast on credits is safe, since we know it won't exceed 10^11 */
1017 rate_ti = proto_tree_add_uint(tree, hf_fp_hsdsch_calculated_rate, tvb, 0, 0,
1018 (guint16)credits * max_pdu_length * (1000 / (interval*10)));
1019 PROTO_ITEM_SET_GENERATED(rate_ti);
1023 if (check_col(pinfo->cinfo, COL_INFO))
1025 col_append_fstr(pinfo->cinfo, COL_INFO,
1026 " Max-PDU-len=%u Credits=%u Interval=%u Rep-Period=%u",
1027 max_pdu_length, (guint16)credits, interval, repetition_period);
1033 int dissect_hsdpa_capacity_allocation_type_2(packet_info *pinfo, proto_tree *tree,
1034 tvbuff_t *tvb, int offset)
1037 proto_item *rate_ti;
1038 guint16 max_pdu_length;
1039 guint8 repetition_period;
1043 /* Congestion status */
1044 proto_tree_add_bits_item(tree, hf_fp_congestion_status, tvb,
1045 offset*8 + 2, 2, FALSE);
1048 proto_tree_add_item(tree, hf_fp_cmch_pi, tvb, offset, 1, FALSE);
1051 /* 5 spare bits follow here */
1053 /* Max MAC-d/c PDU length (11 bits) */
1054 max_pdu_length = tvb_get_ntohs(tvb, offset) & 0x7ff;
1055 proto_tree_add_item(tree, hf_fp_hsdsch_max_macdc_pdu_len, tvb, offset, 2, FALSE);
1058 /* HS-DSCH credits (16 bits) */
1059 credits = (tvb_get_ntohs(tvb, offset));
1060 ti = proto_tree_add_uint(tree, hf_fp_hsdsch_credits, tvb,
1061 offset, 2, credits);
1064 /* Interesting values */
1067 proto_item_append_text(ti, " (stop transmission)");
1068 expert_add_info_format(pinfo, ti,
1069 PI_RESPONSE_CODE, PI_NOTE,
1070 "Stop HSDPA transmission");
1072 if (credits == 65535)
1074 proto_item_append_text(ti, " (unlimited)");
1077 /* HS-DSCH Interval */
1078 interval = tvb_get_guint8(tvb, offset);
1079 ti = proto_tree_add_uint(tree, hf_fp_hsdsch_interval, tvb, offset, 1, interval*10);
1083 proto_item_append_text(ti, " (none of the credits shall be used)");
1086 /* HS-DSCH Repetition period */
1087 repetition_period = tvb_get_guint8(tvb, offset);
1088 ti = proto_tree_add_item(tree, hf_fp_hsdsch_repetition_period, tvb, offset, 1, FALSE);
1090 if (repetition_period == 0)
1092 proto_item_append_text(ti, " (unlimited repetition period)");
1095 /* Calculated and show effective rate enabled */
1096 if (credits == 65535)
1098 rate_ti = proto_tree_add_item(tree, hf_fp_hsdsch_unlimited_rate, tvb, 0, 0, FALSE);
1099 PROTO_ITEM_SET_GENERATED(rate_ti);
1105 rate_ti = proto_tree_add_uint(tree, hf_fp_hsdsch_calculated_rate, tvb, 0, 0,
1106 credits * max_pdu_length * (1000 / (interval*10)));
1107 PROTO_ITEM_SET_GENERATED(rate_ti);
1111 if (check_col(pinfo->cinfo, COL_INFO))
1113 col_append_fstr(pinfo->cinfo, COL_INFO,
1114 " Max-PDU-len=%u Credits=%u Interval=%u Rep-Period=%u",
1115 max_pdu_length, credits, interval, repetition_period);
1123 int dissect_common_dynamic_pusch_assignment(packet_info *pinfo, proto_tree *tree,
1124 tvbuff_t *tvb, int offset)
1126 guint8 pusch_set_id;
1127 guint8 activation_cfn;
1131 pusch_set_id = tvb_get_guint8(tvb, offset);
1132 proto_tree_add_item(tree, hf_fp_pusch_set_id, tvb, offset, 1, FALSE);
1135 /* Activation CFN */
1136 activation_cfn = tvb_get_guint8(tvb, offset);
1137 proto_tree_add_item(tree, hf_fp_activation_cfn, tvb, offset, 1, FALSE);
1141 duration = tvb_get_guint8(tvb, offset) * 10;
1142 proto_tree_add_uint(tree, hf_fp_duration, tvb, offset, 1, duration);
1145 if (check_col(pinfo->cinfo, COL_INFO))
1147 col_append_fstr(pinfo->cinfo, COL_INFO,
1148 " PUSCH Set Id=%u Activation CFN=%u Duration=%u",
1149 pusch_set_id, activation_cfn, duration);
1159 /* Dissect the control part of a common channel message */
1160 void dissect_common_control(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1161 int offset, struct fp_info *p_fp_info)
1163 /* Common control frame type */
1164 guint8 control_frame_type = tvb_get_guint8(tvb, offset);
1165 proto_tree_add_item(tree, hf_fp_common_control_frame_type, tvb, offset, 1, FALSE);
1168 if (check_col(pinfo->cinfo, COL_INFO))
1170 col_append_str(pinfo->cinfo, COL_INFO,
1171 val_to_str(control_frame_type, common_control_frame_type_vals, "Unknown"));
1174 /* Frame-type specific dissection */
1175 switch (control_frame_type)
1177 case COMMON_OUTER_LOOP_POWER_CONTROL:
1178 offset = dissect_common_outer_loop_power_control(pinfo, tree, tvb, offset, p_fp_info);
1180 case COMMON_TIMING_ADJUSTMENT:
1181 offset = dissect_common_timing_adjustment(pinfo, tree, tvb, offset, p_fp_info);
1183 case COMMON_DL_SYNCHRONISATION:
1184 offset = dissect_common_dl_synchronisation(pinfo, tree, tvb, offset, p_fp_info);
1186 case COMMON_UL_SYNCHRONISATION:
1187 offset = dissect_common_ul_synchronisation(pinfo, tree, tvb, offset, p_fp_info);
1189 case COMMON_DL_NODE_SYNCHRONISATION:
1190 offset = dissect_common_dl_node_synchronisation(pinfo, tree, tvb, offset);
1192 case COMMON_UL_NODE_SYNCHRONISATION:
1193 offset = dissect_common_ul_node_synchronisation(pinfo, tree, tvb, offset);
1195 case COMMON_DYNAMIC_PUSCH_ASSIGNMENT:
1196 offset = dissect_common_dynamic_pusch_assignment(pinfo, tree, tvb, offset);
1198 case COMMON_TIMING_ADVANCE:
1199 offset = dissect_common_timing_advance(pinfo, tree, tvb, offset);
1201 case COMMON_HS_DSCH_Capacity_Request:
1202 offset = dissect_hsdpa_capacity_request(pinfo, tree, tvb, offset);
1204 case COMMON_HS_DSCH_Capacity_Allocation:
1205 offset = dissect_hsdpa_capacity_allocation(pinfo, tree, tvb, offset, p_fp_info);
1207 case COMMON_HS_DSCH_Capacity_Allocation_Type_2:
1208 offset = dissect_hsdpa_capacity_allocation_type_2(pinfo, tree, tvb, offset);
1215 /* Spare Extension */
1216 dissect_spare_extension_and_crc(tvb, pinfo, tree, 0, offset);
1221 /**************************/
1222 /* Dissect a RACH channel */
1223 void dissect_rach_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1224 int offset, struct fp_info *p_fp_info)
1226 gboolean is_control_frame;
1229 proto_tree_add_item(tree, hf_fp_header_crc, tvb, offset, 1, FALSE);
1232 is_control_frame = tvb_get_guint8(tvb, offset) & 0x01;
1233 proto_tree_add_item(tree, hf_fp_ft, tvb, offset, 1, FALSE);
1236 if (check_col(pinfo->cinfo, COL_INFO))
1238 col_append_str(pinfo->cinfo, COL_INFO, is_control_frame ? " [Control] " : " [Data] ");
1241 if (is_control_frame)
1243 dissect_common_control(tvb, pinfo, tree, offset, p_fp_info);
1248 guint32 propagation_delay = 0;
1249 proto_item *propagation_delay_ti = NULL;
1250 guint32 received_sync_ul_timing_deviation = 0;
1251 proto_item *received_sync_ul_timing_deviation_ti = NULL;
1252 proto_item *rx_timing_deviation_ti = NULL;
1253 guint16 rx_timing_deviation = 0;
1258 cfn = tvb_get_guint8(tvb, offset);
1259 proto_tree_add_item(tree, hf_fp_cfn, tvb, offset, 1, FALSE);
1262 if (check_col(pinfo->cinfo, COL_INFO))
1264 col_append_fstr(pinfo->cinfo, COL_INFO, "CFN=%03u ", cfn);
1268 proto_tree_add_item(tree, hf_fp_tfi, tvb, offset, 1, FALSE);
1271 if (p_fp_info->channel == CHANNEL_RACH_FDD)
1273 /* Propagation delay */
1274 propagation_delay = tvb_get_guint8(tvb, offset);
1275 propagation_delay_ti = proto_tree_add_uint(tree, hf_fp_propagation_delay, tvb, offset, 1,
1276 propagation_delay*3);
1280 /* Should be TDD 3.84 or 7.68 */
1281 if (p_fp_info->channel == CHANNEL_RACH_TDD)
1283 /* Rx Timing Deviation */
1284 rx_timing_deviation = tvb_get_guint8(tvb, offset);
1285 rx_timing_deviation_ti = proto_tree_add_item(tree, hf_fp_rx_timing_deviation, tvb, offset, 1, FALSE);
1289 if (p_fp_info->channel == CHANNEL_RACH_TDD_128)
1291 /* Received SYNC UL Timing Deviation */
1292 received_sync_ul_timing_deviation = tvb_get_guint8(tvb, offset);
1293 received_sync_ul_timing_deviation_ti =
1294 proto_tree_add_item(tree, hf_fp_received_sync_ul_timing_deviation, tvb, offset, 1, FALSE);
1299 offset = dissect_tb_data(tvb, pinfo, tree, offset, p_fp_info, &mac_fdd_rach_handle);
1302 offset = dissect_crci_bits(tvb, pinfo, tree, p_fp_info, offset);
1304 /* Info introduced in R6 */
1305 /* only check if it looks as if they are present */
1306 if (((p_fp_info->release == 6) ||
1307 (p_fp_info->release == 7)) &&
1308 tvb_length_remaining(tvb, offset) > 2)
1312 guint8 flag_bytes = 0;
1314 gboolean cell_portion_id_present = FALSE;
1315 gboolean ext_propagation_delay_present = FALSE;
1316 gboolean angle_of_arrival_present = FALSE;
1317 gboolean ext_rx_sync_ul_timing_deviation_present = FALSE;
1318 gboolean ext_rx_timing_deviation_present = FALSE;
1320 /* New IE flags (assume mandatory for now) */
1323 proto_item *new_ie_flags_ti;
1324 proto_tree *new_ie_flags_tree;
1325 guint ies_found = 0;
1327 /* Add new IE flags subtree */
1328 new_ie_flags_ti = proto_tree_add_string_format(tree, hf_fp_rach_new_ie_flags, tvb, offset, 1,
1329 "", "New IE flags");
1330 new_ie_flags_tree = proto_item_add_subtree(new_ie_flags_ti, ett_fp_rach_new_ie_flags);
1332 /* Read next byte */
1333 flags = tvb_get_guint8(tvb, offset);
1336 /* Dissect individual bits */
1337 for (n=0; n < 8; n++)
1341 switch (p_fp_info->division)
1344 /* Ext propagation delay */
1345 ext_propagation_delay_present = TRUE;
1346 proto_tree_add_item(new_ie_flags_tree, hf_fp_rach_ext_propagation_delay_present,
1347 tvb, offset, 1, FALSE);
1349 case Division_TDD_128:
1350 /* Ext Rx Sync UL Timing */
1351 ext_rx_sync_ul_timing_deviation_present = TRUE;
1352 proto_tree_add_item(new_ie_flags_tree, hf_fp_rach_ext_rx_sync_ul_timing_deviation_present,
1353 tvb, offset, 1, FALSE);
1358 proto_tree_add_item(new_ie_flags_tree, hf_fp_rach_new_ie_flag_unused[n],
1359 tvb, offset, 1, FALSE);
1364 switch (p_fp_info->division)
1367 /* Cell Portion ID */
1368 cell_portion_id_present = TRUE;
1369 proto_tree_add_item(new_ie_flags_tree, hf_fp_rach_cell_portion_id_present,
1370 tvb, offset, 1, FALSE);
1372 case Division_TDD_128:
1374 angle_of_arrival_present = TRUE;
1375 proto_tree_add_item(new_ie_flags_tree, hf_fp_rach_angle_of_arrival_present,
1376 tvb, offset, 1, FALSE);
1378 case Division_TDD_384:
1379 case Division_TDD_768:
1380 /* Extended Rx Timing Deviation */
1381 ext_rx_timing_deviation_present = TRUE;
1382 proto_tree_add_item(new_ie_flags_tree, hf_fp_rach_ext_rx_timing_deviation_present,
1383 tvb, offset, 1, FALSE);
1389 /* No defined meanings */
1390 proto_tree_add_item(new_ie_flags_tree, hf_fp_rach_new_ie_flag_unused[n],
1391 tvb, offset, 1, FALSE);
1394 if ((flags >> (7-n)) & 0x01)
1401 proto_item_append_text(new_ie_flags_ti, " (%u IEs found)", ies_found);
1403 /* Last bit set will indicate another flags byte follows... */
1404 } while (0); /*((flags & 0x01) && (flag_bytes < 31));*/
1406 /* Cell Portion ID */
1407 if (cell_portion_id_present) {
1408 proto_tree_add_item(tree, hf_fp_cell_portion_id, tvb, offset, 1, FALSE);
1412 /* Ext Rx Timing Deviation */
1413 if (ext_rx_timing_deviation_present)
1416 guint bits_to_extend;
1417 switch (p_fp_info->division)
1419 case Division_TDD_384:
1422 case Division_TDD_768:
1427 /* TODO: report unexpected division type */
1431 extra_bits = tvb_get_guint8(tvb, offset) &
1432 ((bits_to_extend == 1) ? 0x01 : 0x03);
1433 rx_timing_deviation = (extra_bits << 8) | (rx_timing_deviation);
1434 proto_item_append_text(rx_timing_deviation_ti,
1435 " (extended to 0x%x)",
1436 rx_timing_deviation);
1437 proto_tree_add_bits_item(tree, hf_fp_extended_bits, tvb,
1438 offset*8 + (8-bits_to_extend), bits_to_extend, FALSE);
1442 /* Ext propagation delay. */
1443 if (ext_propagation_delay_present)
1445 guint16 extra_bits = tvb_get_ntohs(tvb, offset) & 0x03ff;
1446 proto_tree_add_item(tree, hf_fp_ext_propagation_delay, tvb, offset, 2, FALSE);
1448 /* Adding 10 bits to original 8 */
1449 proto_item_append_text(propagation_delay_ti, " (extended to %u)",
1450 ((extra_bits << 8) | propagation_delay) * 3);
1454 /* Angle of Arrival (AOA) */
1455 if (angle_of_arrival_present)
1457 proto_tree_add_item(tree, hf_fp_angle_of_arrival, tvb, offset, 2, FALSE);
1461 /* Ext. Rx Sync UL Timing Deviation */
1462 if (ext_rx_sync_ul_timing_deviation_present) {
1465 /* Ext received Sync UL Timing Deviation */
1466 extra_bits = tvb_get_ntohs(tvb, offset) & 0x1fff;
1467 proto_tree_add_item(tree, hf_fp_ext_received_sync_ul_timing_deviation, tvb, offset, 2, FALSE);
1469 /* Adding 13 bits to original 8 */
1470 proto_item_append_text(received_sync_ul_timing_deviation_ti, " (extended to %u)",
1471 (extra_bits << 8) | received_sync_ul_timing_deviation);
1476 /* Spare Extension and Payload CRC */
1477 dissect_spare_extension_and_crc(tvb, pinfo, tree, 1, offset);
1482 /**************************/
1483 /* Dissect a FACH channel */
1484 void dissect_fach_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1485 int offset, struct fp_info *p_fp_info)
1487 gboolean is_control_frame;
1490 proto_tree_add_item(tree, hf_fp_header_crc, tvb, offset, 1, FALSE);
1493 is_control_frame = tvb_get_guint8(tvb, offset) & 0x01;
1494 proto_tree_add_item(tree, hf_fp_ft, tvb, offset, 1, FALSE);
1497 if (check_col(pinfo->cinfo, COL_INFO))
1499 col_append_str(pinfo->cinfo, COL_INFO, is_control_frame ? " [Control] " : " [Data] ");
1502 if (is_control_frame)
1504 dissect_common_control(tvb, pinfo, tree, offset, p_fp_info);
1513 cfn = tvb_get_guint8(tvb, offset);
1514 proto_tree_add_item(tree, hf_fp_cfn, tvb, offset, 1, FALSE);
1517 if (check_col(pinfo->cinfo, COL_INFO))
1519 col_append_fstr(pinfo->cinfo, COL_INFO, "CFN=%03u ", cfn);
1523 proto_tree_add_item(tree, hf_fp_fach_tfi, tvb, offset, 1, FALSE);
1526 /* Transmit power level */
1527 proto_tree_add_float(tree, hf_fp_transmit_power_level, tvb, offset, 1,
1528 (float)(int)(tvb_get_guint8(tvb, offset)) / 10);
1532 offset = dissect_tb_data(tvb, pinfo, tree, offset, p_fp_info, &mac_fdd_fach_handle);
1534 /* New IE flags (if it looks as though they are present) */
1535 if ((p_fp_info->release == 7) &&
1536 (tvb_length_remaining(tvb, offset) > 2))
1538 guint8 flags = tvb_get_guint8(tvb, offset);
1539 guint8 aoa_present = flags & 0x01;
1544 proto_tree_add_item(tree, hf_fp_angle_of_arrival, tvb, offset, 2, FALSE);
1549 /* Spare Extension and Payload CRC */
1550 dissect_spare_extension_and_crc(tvb, pinfo, tree, 1, offset);
1555 /**************************/
1556 /* Dissect a DSCH channel */
1557 void dissect_dsch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1558 int offset, struct fp_info *p_fp_info)
1560 gboolean is_control_frame;
1563 proto_tree_add_item(tree, hf_fp_header_crc, tvb, offset, 1, FALSE);
1566 is_control_frame = tvb_get_guint8(tvb, offset) & 0x01;
1567 proto_tree_add_item(tree, hf_fp_ft, tvb, offset, 1, FALSE);
1570 if (check_col(pinfo->cinfo, COL_INFO))
1572 col_append_str(pinfo->cinfo, COL_INFO, is_control_frame ? " [Control] " : " [Data] ");
1575 if (is_control_frame)
1577 dissect_common_control(tvb, pinfo, tree, offset, p_fp_info);
1586 cfn = tvb_get_guint8(tvb, offset);
1587 proto_tree_add_item(tree, hf_fp_cfn, tvb, offset, 1, FALSE);
1590 if (check_col(pinfo->cinfo, COL_INFO))
1592 col_append_fstr(pinfo->cinfo, COL_INFO, "CFN=%03u ", cfn);
1596 proto_tree_add_item(tree, hf_fp_tfi, tvb, offset, 1, FALSE);
1600 /* Other fields depend upon release & FDD/TDD settings */
1601 if (((p_fp_info->release == 99) || (p_fp_info->release == 4)) &&
1602 (p_fp_info->channel == CHANNEL_DSCH_FDD))
1605 proto_tree_add_float(tree, hf_fp_power_offset, tvb, offset, 1,
1607 ((float)(int)(tvb_get_guint8(tvb, offset)) * (float)(0.25)));
1611 proto_tree_add_item(tree, hf_fp_code_number, tvb, offset, 1, FALSE);
1614 /* Spreading Factor (3 bits) */
1615 proto_tree_add_item(tree, hf_fp_spreading_factor, tvb, offset, 1, FALSE);
1617 /* MC info (4 bits)*/
1618 proto_tree_add_item(tree, hf_fp_mc_info, tvb, offset, 1, FALSE);
1620 /* Last bit of this byte is spare */
1628 proto_tree_add_item(tree, hf_fp_pdsch_set_id, tvb, offset, 1, FALSE);
1631 /* Transmit power level */
1632 proto_tree_add_float(tree, hf_fp_transmit_power_level, tvb, offset, 1,
1633 (float)(int)(tvb_get_guint8(tvb, offset)) / 10);
1638 offset = dissect_tb_data(tvb, pinfo, tree, offset, p_fp_info, NULL);
1640 /* Spare Extension and Payload CRC */
1641 dissect_spare_extension_and_crc(tvb, pinfo, tree, 1, offset);
1646 /**************************/
1647 /* Dissect a USCH channel */
1648 void dissect_usch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1649 int offset, struct fp_info *p_fp_info)
1651 gboolean is_control_frame;
1654 proto_tree_add_item(tree, hf_fp_header_crc, tvb, offset, 1, FALSE);
1657 is_control_frame = tvb_get_guint8(tvb, offset) & 0x01;
1658 proto_tree_add_item(tree, hf_fp_ft, tvb, offset, 1, FALSE);
1661 if (check_col(pinfo->cinfo, COL_INFO))
1663 col_append_str(pinfo->cinfo, COL_INFO, is_control_frame ? " [Control] " : " [Data] ");
1666 if (is_control_frame)
1668 dissect_common_control(tvb, pinfo, tree, offset, p_fp_info);
1673 guint16 rx_timing_deviation;
1674 proto_item *rx_timing_deviation_ti;
1679 cfn = tvb_get_guint8(tvb, offset);
1680 proto_tree_add_item(tree, hf_fp_cfn, tvb, offset, 1, FALSE);
1683 if (check_col(pinfo->cinfo, COL_INFO))
1685 col_append_fstr(pinfo->cinfo, COL_INFO, "CFN=%03u ", cfn);
1689 proto_tree_add_item(tree, hf_fp_usch_tfi, tvb, offset, 1, FALSE);
1692 /* Rx Timing Deviation */
1693 rx_timing_deviation = tvb_get_guint8(tvb, offset);
1694 rx_timing_deviation_ti = proto_tree_add_item(tree, hf_fp_rx_timing_deviation,
1695 tvb, offset, 1, FALSE);
1699 offset = dissect_tb_data(tvb, pinfo, tree, offset, p_fp_info, NULL);
1702 proto_tree_add_item(tree, hf_fp_quality_estimate, tvb, offset, 1, FALSE);
1706 offset = dissect_crci_bits(tvb, pinfo, tree, p_fp_info, offset);
1709 if ((p_fp_info->release == 7) &&
1710 (tvb_length_remaining(tvb, offset) > 2))
1712 guint8 flags = tvb_get_guint8(tvb, offset);
1713 guint8 bits_extended = flags & 0x01;
1718 guint8 extra_bits = tvb_get_guint8(tvb, offset) & 0x03;
1719 proto_item_append_text(rx_timing_deviation_ti,
1720 " (extended to %u)",
1721 (rx_timing_deviation << 2) | extra_bits);
1726 /* Spare Extension and Payload CRC */
1727 dissect_spare_extension_and_crc(tvb, pinfo, tree, 1, offset);
1733 /**************************/
1734 /* Dissect a PCH channel */
1735 void dissect_pch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1736 int offset, struct fp_info *p_fp_info)
1738 gboolean is_control_frame;
1740 gboolean paging_indication;
1743 proto_tree_add_item(tree, hf_fp_header_crc, tvb, offset, 1, FALSE);
1746 is_control_frame = tvb_get_guint8(tvb, offset) & 0x01;
1747 proto_tree_add_item(tree, hf_fp_ft, tvb, offset, 1, FALSE);
1750 if (check_col(pinfo->cinfo, COL_INFO))
1752 col_append_str(pinfo->cinfo, COL_INFO, is_control_frame ? " [Control] " : " [Data] ");
1755 if (is_control_frame)
1757 dissect_common_control(tvb, pinfo, tree, offset, p_fp_info);
1763 /* 12-bit CFN value */
1764 proto_tree_add_item(tree, hf_fp_pch_cfn, tvb, offset, 2, FALSE);
1765 pch_cfn = (tvb_get_ntohs(tvb, offset) & 0xfff0) >> 4;
1768 if (check_col(pinfo->cinfo, COL_INFO))
1770 col_append_fstr(pinfo->cinfo, COL_INFO, "CFN=%04u ", pch_cfn);
1773 /* Paging indication */
1774 proto_tree_add_item(tree, hf_fp_pch_pi, tvb, offset, 1, FALSE);
1775 paging_indication = tvb_get_guint8(tvb, offset) & 0x01;
1779 proto_tree_add_item(tree, hf_fp_pch_tfi, tvb, offset, 1, FALSE);
1782 /* Optional paging indications */
1783 if (paging_indication)
1786 ti = proto_tree_add_item(tree, hf_fp_paging_indication_bitmap, tvb,
1788 (p_fp_info->paging_indications+7) / 8,
1790 proto_item_append_text(ti, " (%u bits)", p_fp_info->paging_indications);
1791 offset += ((p_fp_info->paging_indications+7) / 8);
1795 offset = dissect_tb_data(tvb, pinfo, tree, offset, p_fp_info, &mac_fdd_pch_handle);
1797 /* Spare Extension and Payload CRC */
1798 dissect_spare_extension_and_crc(tvb, pinfo, tree, 1, offset);
1803 /**************************/
1804 /* Dissect a CPCH channel */
1805 void dissect_cpch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1806 int offset, struct fp_info *p_fp_info)
1808 gboolean is_control_frame;
1811 proto_tree_add_item(tree, hf_fp_header_crc, tvb, offset, 1, FALSE);
1814 is_control_frame = tvb_get_guint8(tvb, offset) & 0x01;
1815 proto_tree_add_item(tree, hf_fp_ft, tvb, offset, 1, FALSE);
1818 if (check_col(pinfo->cinfo, COL_INFO))
1820 col_append_str(pinfo->cinfo, COL_INFO, is_control_frame ? " [Control] " : " [Data] ");
1823 if (is_control_frame)
1825 dissect_common_control(tvb, pinfo, tree, offset, p_fp_info);
1834 cfn = tvb_get_guint8(tvb, offset);
1835 proto_tree_add_item(tree, hf_fp_cfn, tvb, offset, 1, FALSE);
1838 if (check_col(pinfo->cinfo, COL_INFO))
1840 col_append_fstr(pinfo->cinfo, COL_INFO, "CFN=%03u ", cfn);
1844 proto_tree_add_item(tree, hf_fp_cpch_tfi, tvb, offset, 1, FALSE);
1847 /* Propagation delay */
1848 proto_tree_add_uint(tree, hf_fp_propagation_delay, tvb, offset, 1,
1849 tvb_get_guint8(tvb, offset) * 3);
1853 offset = dissect_tb_data(tvb, pinfo, tree, offset, p_fp_info, NULL);
1856 offset = dissect_crci_bits(tvb, pinfo, tree, p_fp_info, offset);
1858 /* Spare Extension and Payload CRC */
1859 dissect_spare_extension_and_crc(tvb, pinfo, tree, 1, offset);
1864 /**************************/
1865 /* Dissect a BCH channel */
1866 void dissect_bch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1867 int offset, struct fp_info *p_fp_info)
1869 gboolean is_control_frame;
1872 proto_tree_add_item(tree, hf_fp_header_crc, tvb, offset, 1, FALSE);
1875 is_control_frame = tvb_get_guint8(tvb, offset) & 0x01;
1876 proto_tree_add_item(tree, hf_fp_ft, tvb, offset, 1, FALSE);
1879 if (check_col(pinfo->cinfo, COL_INFO))
1881 col_append_str(pinfo->cinfo, COL_INFO, is_control_frame ? " [Control] " : " [Data] ");
1884 if (is_control_frame)
1886 dissect_common_control(tvb, pinfo, tree, offset, p_fp_info);
1891 /********************************/
1892 /* Dissect an IUR DSCH channel */
1893 void dissect_iur_dsch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1894 int offset, struct fp_info *p_fp_info _U_)
1896 gboolean is_control_frame;
1899 proto_tree_add_item(tree, hf_fp_header_crc, tvb, offset, 1, FALSE);
1902 is_control_frame = tvb_get_guint8(tvb, offset) & 0x01;
1903 proto_tree_add_item(tree, hf_fp_ft, tvb, offset, 1, FALSE);
1906 if (check_col(pinfo->cinfo, COL_INFO))
1908 col_append_str(pinfo->cinfo, COL_INFO, is_control_frame ? " [Control] " : " [Data] ");
1911 if (is_control_frame)
1913 dissect_common_control(tvb, pinfo, tree, offset, p_fp_info);
1924 /************************/
1925 /* DCH control messages */
1927 int dissect_dch_timing_adjustment(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, int offset)
1933 control_cfn = tvb_get_guint8(tvb, offset);
1934 proto_tree_add_item(tree, hf_fp_cfn_control, tvb, offset, 1, FALSE);
1938 toa = tvb_get_ntohs(tvb, offset);
1939 proto_tree_add_item(tree, hf_fp_toa, tvb, offset, 2, FALSE);
1942 if (check_col(pinfo->cinfo, COL_INFO))
1944 col_append_fstr(pinfo->cinfo, COL_INFO,
1945 " CFN = %u, ToA = %d", control_cfn, toa);
1951 int dissect_dch_rx_timing_deviation(packet_info *pinfo, proto_tree *tree,
1952 tvbuff_t *tvb, int offset,
1953 struct fp_info *p_fp_info)
1955 guint16 timing_deviation = 0;
1956 gint timing_deviation_chips = 0;
1957 proto_item *timing_deviation_ti = NULL;
1960 proto_tree_add_item(tree, hf_fp_cfn_control, tvb, offset, 1, FALSE);
1963 /* Rx Timing Deviation */
1964 timing_deviation = tvb_get_guint8(tvb, offset);
1965 timing_deviation_ti = proto_tree_add_item(tree, hf_fp_dch_rx_timing_deviation, tvb, offset, 1, FALSE);
1968 /* May be extended in R7, but in this case there are at least 2 bytes remaining */
1969 if ((p_fp_info->release == 7) &&
1970 (tvb_length_remaining(tvb, offset) >= 2))
1973 guint64 extended_bits_present;
1974 guint64 e_rucch_present;
1977 proto_tree_add_bits_ret_val(tree, hf_fp_e_rucch_present, tvb,
1978 offset*8 + 6, 1, &e_rucch_present, FALSE);
1979 proto_tree_add_bits_ret_val(tree, hf_fp_extended_bits_present, tvb,
1980 offset*8 + 7, 1, &extended_bits_present, FALSE);
1983 /* Optional E-RUCCH */
1984 if (e_rucch_present)
1986 /* Value of bit_offset depends upon division type */
1989 switch (p_fp_info->division)
1991 case Division_TDD_384:
1994 case Division_TDD_768:
1999 proto_item *ti = proto_tree_add_text(tree, tvb, 0, 0,
2000 "Error: expecting TDD-384 or TDD-768");
2001 PROTO_ITEM_SET_GENERATED(ti);
2002 expert_add_info_format(pinfo, ti,
2003 PI_MALFORMED, PI_NOTE,
2004 "Error: expecting TDD-384 or TDD-768");
2010 proto_tree_add_item(tree, hf_fp_dch_e_rucch_flag, tvb, offset, 1, FALSE);
2011 proto_tree_add_bits_item(tree, hf_fp_dch_e_rucch_flag, tvb,
2012 offset*8 + bit_offset, 1, FALSE);
2015 /* Timing deviation may be extended by another:
2016 - 1 bits (3.84 TDD) OR
2019 if (extended_bits_present)
2022 guint bits_to_extend;
2023 switch (p_fp_info->division)
2025 case Division_TDD_384:
2028 case Division_TDD_768:
2033 /* TODO: report unexpected division type */
2037 extra_bits = tvb_get_guint8(tvb, offset) &
2038 ((bits_to_extend == 1) ? 0x01 : 0x03);
2039 timing_deviation = (extra_bits << 8) | (timing_deviation);
2040 proto_item_append_text(timing_deviation_ti,
2041 " (extended to 0x%x)",
2043 proto_tree_add_bits_item(tree, hf_fp_extended_bits, tvb,
2044 offset*8 + (8-bits_to_extend), bits_to_extend, FALSE);
2049 timing_deviation_chips = (timing_deviation*4) - 1024;
2050 proto_item_append_text(timing_deviation_ti, " (%d chips)",
2051 timing_deviation_chips);
2053 if (check_col(pinfo->cinfo, COL_INFO))
2055 col_append_fstr(pinfo->cinfo, COL_INFO, " deviation = %u (%d chips)",
2056 timing_deviation, timing_deviation_chips);
2062 int dissect_dch_dl_synchronisation(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, int offset)
2065 guint cfn = tvb_get_guint8(tvb, offset);
2066 proto_tree_add_item(tree, hf_fp_cfn_control, tvb, offset, 1, FALSE);
2069 if (check_col(pinfo->cinfo, COL_INFO))
2071 col_append_fstr(pinfo->cinfo, COL_INFO, " CFN = %u", cfn);
2077 int dissect_dch_ul_synchronisation(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, int offset)
2083 cfn = tvb_get_guint8(tvb, offset);
2084 proto_tree_add_item(tree, hf_fp_cfn_control, tvb, offset, 1, FALSE);
2088 toa = tvb_get_ntohs(tvb, offset);
2089 proto_tree_add_item(tree, hf_fp_toa, tvb, offset, 2, FALSE);
2092 if (check_col(pinfo->cinfo, COL_INFO))
2094 col_append_fstr(pinfo->cinfo, COL_INFO, " CFN = %u, ToA = %d",
2101 int dissect_dch_outer_loop_power_control(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, int offset)
2104 float target = (float)-8.2 + ((float)0.1 * (float)(int)(tvb_get_guint8(tvb, offset)));
2105 proto_tree_add_float(tree, hf_fp_ul_sir_target, tvb, offset, 1, target);
2108 if (check_col(pinfo->cinfo, COL_INFO))
2110 col_append_fstr(pinfo->cinfo, COL_INFO, " UL SIR Target = %f", target);
2116 int dissect_dch_dl_node_synchronisation(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, int offset)
2118 return dissect_common_dl_node_synchronisation(pinfo, tree, tvb, offset);
2121 int dissect_dch_ul_node_synchronisation(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, int offset)
2123 return dissect_common_ul_node_synchronisation(pinfo, tree, tvb, offset);
2126 int dissect_dch_radio_interface_parameter_update(proto_tree *tree, packet_info *pinfo _U_, tvbuff_t *tvb, int offset)
2132 /* Show defined flags in these 2 bytes */
2133 for (n=4; n >= 0; n--)
2135 proto_tree_add_item(tree, hf_fp_radio_interface_parameter_update_flag[n], tvb, offset, 2, FALSE);
2140 cfn = tvb_get_guint8(tvb, offset);
2141 proto_tree_add_item(tree, hf_fp_cfn, tvb, offset, 1, FALSE);
2145 proto_tree_add_item(tree, hf_fp_dpc_mode, tvb, offset, 1, FALSE);
2148 proto_tree_add_item(tree, hf_fp_tpc_po, tvb, offset, 1, FALSE);
2151 /* Multiple RL sets indicator */
2152 proto_tree_add_item(tree, hf_fp_multiple_rl_set_indicator, tvb, offset, 1, FALSE);
2156 value = (tvb_get_guint8(tvb, offset) & 0x7f);
2157 proto_tree_add_int(tree, hf_fp_max_ue_tx_pow, tvb, offset, 1, -55 + value);
2163 int dissect_dch_timing_advance(proto_tree *tree, packet_info *pinfo,
2164 tvbuff_t *tvb, int offset, struct fp_info *p_fp_info)
2167 guint16 timing_advance;
2168 proto_item *timing_advance_ti;
2171 cfn = tvb_get_guint8(tvb, offset);
2172 proto_tree_add_item(tree, hf_fp_cfn_control, tvb, offset, 1, FALSE);
2175 /* Timing Advance */
2176 timing_advance = (tvb_get_guint8(tvb, offset) & 0x3f) * 4;
2177 timing_advance_ti = proto_tree_add_uint(tree, hf_fp_timing_advance, tvb, offset, 1, timing_advance);
2180 if ((p_fp_info->release == 7) &&
2181 (tvb_length_remaining(tvb, offset) > 0))
2184 guint8 flags = tvb_get_guint8(tvb, offset);
2185 guint8 extended_bits = flags & 0x01;
2190 guint8 extra_bit = tvb_get_guint8(tvb, offset) & 0x01;
2191 proto_item_append_text(timing_advance_ti, " (extended to %u)",
2192 (timing_advance << 1) | extra_bit);
2198 if (check_col(pinfo->cinfo, COL_INFO))
2200 col_append_fstr(pinfo->cinfo, COL_INFO, " CFN = %u, TA = %u",
2201 cfn, timing_advance);
2207 int dissect_dch_tnl_congestion_indication(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, int offset)
2211 /* Congestion status */
2212 proto_tree_add_bits_ret_val(tree, hf_fp_congestion_status, tvb,
2213 offset*8 + 6, 2, &status, FALSE);
2216 if (check_col(pinfo->cinfo, COL_INFO))
2218 col_append_fstr(pinfo->cinfo, COL_INFO, " status = %s",
2219 val_to_str((guint16)status, congestion_status_vals, "unknown"));
2228 /* DCH control frame */
2229 void dissect_dch_control_frame(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, int offset,
2230 struct fp_info *p_fp_info)
2232 /* Control frame type */
2233 guint8 control_frame_type = tvb_get_guint8(tvb, offset);
2234 proto_tree_add_item(tree, hf_fp_dch_control_frame_type, tvb, offset, 1, FALSE);
2237 if (check_col(pinfo->cinfo, COL_INFO))
2239 col_append_str(pinfo->cinfo, COL_INFO,
2240 val_to_str(control_frame_type,
2241 dch_control_frame_type_vals, "Unknown"));
2244 switch (control_frame_type)
2246 case DCH_TIMING_ADJUSTMENT:
2247 offset = dissect_dch_timing_adjustment(tree, pinfo, tvb, offset);
2249 case DCH_RX_TIMING_DEVIATION:
2250 offset = dissect_dch_rx_timing_deviation(pinfo, tree, tvb, offset, p_fp_info);
2252 case DCH_DL_SYNCHRONISATION:
2253 offset = dissect_dch_dl_synchronisation(tree, pinfo, tvb, offset);
2255 case DCH_UL_SYNCHRONISATION:
2256 offset = dissect_dch_ul_synchronisation(tree, pinfo, tvb, offset);
2258 case DCH_OUTER_LOOP_POWER_CONTROL:
2259 offset = dissect_dch_outer_loop_power_control(tree, pinfo, tvb, offset);
2261 case DCH_DL_NODE_SYNCHRONISATION:
2262 offset = dissect_dch_dl_node_synchronisation(tree, pinfo, tvb, offset);
2264 case DCH_UL_NODE_SYNCHRONISATION:
2265 offset = dissect_dch_ul_node_synchronisation(tree, pinfo, tvb, offset);
2267 case DCH_RADIO_INTERFACE_PARAMETER_UPDATE:
2268 offset = dissect_dch_radio_interface_parameter_update(tree, pinfo, tvb, offset);
2270 case DCH_TIMING_ADVANCE:
2271 offset = dissect_dch_timing_advance(tree, pinfo, tvb, offset, p_fp_info);
2273 case DCH_TNL_CONGESTION_INDICATION:
2274 offset = dissect_dch_tnl_congestion_indication(tree, pinfo, tvb, offset);
2278 /* Spare Extension */
2279 dissect_spare_extension_and_crc(tvb, pinfo, tree, 0, offset);
2282 /*******************************/
2283 /* Dissect a DCH channel */
2284 void dissect_dch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2285 int offset, struct fp_info *p_fp_info)
2287 gboolean is_control_frame;
2291 proto_tree_add_item(tree, hf_fp_header_crc, tvb, offset, 1, FALSE);
2294 is_control_frame = tvb_get_guint8(tvb, offset) & 0x01;
2295 proto_tree_add_item(tree, hf_fp_ft, tvb, offset, 1, FALSE);
2298 if (check_col(pinfo->cinfo, COL_INFO))
2300 col_append_str(pinfo->cinfo, COL_INFO,
2301 is_control_frame ? " [Control] " :
2302 ((p_fp_info->is_uplink) ? " [ULData] " :
2306 if (is_control_frame)
2308 /* DCH control frame */
2309 dissect_dch_control_frame(tree, pinfo, tvb, offset, p_fp_info);
2313 /************************/
2318 proto_tree_add_item(tree, hf_fp_cfn, tvb, offset, 1, FALSE);
2319 cfn = tvb_get_guint8(tvb, offset);
2322 if (check_col(pinfo->cinfo, COL_INFO))
2324 col_append_fstr(pinfo->cinfo, COL_INFO, "CFN=%03u ", cfn);
2327 /* One TFI for each channel */
2328 for (chan=0; chan < p_fp_info->num_chans; chan++)
2330 proto_tree_add_item(tree, hf_fp_tfi, tvb, offset, 1, FALSE);
2334 /* Dissect TB data */
2335 offset = dissect_tb_data(tvb, pinfo, tree, offset, p_fp_info, &mac_fdd_dch_handle);
2337 /* QE (uplink only) */
2338 if (p_fp_info->is_uplink)
2340 proto_tree_add_item(tree, hf_fp_quality_estimate, tvb, offset, 1, FALSE);
2344 /* CRCI bits (uplink only) */
2345 if (p_fp_info->is_uplink)
2347 offset = dissect_crci_bits(tvb, pinfo, tree, p_fp_info, offset);
2350 /* Spare extension and payload CRC (optional) */
2351 dissect_spare_extension_and_crc(tvb, pinfo, tree,
2352 p_fp_info->dch_crc_present, offset);
2358 /**********************************/
2359 /* Dissect an E-DCH channel */
2360 void dissect_e_dch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2361 int offset, struct fp_info *p_fp_info)
2363 gboolean is_control_frame;
2364 guint8 number_of_subframes;
2367 struct subframe_info subframes[16];
2370 proto_tree_add_item(tree, hf_fp_edch_header_crc, tvb, offset, 2, FALSE);
2373 is_control_frame = tvb_get_guint8(tvb, offset) & 0x01;
2374 proto_tree_add_item(tree, hf_fp_ft, tvb, offset, 1, FALSE);
2377 if (check_col(pinfo->cinfo, COL_INFO))
2379 col_append_str(pinfo->cinfo, COL_INFO, is_control_frame ? " [Control] " : " [Data] ");
2382 if (is_control_frame)
2384 /* DCH control frame */
2385 dissect_dch_control_frame(tree, pinfo, tvb, offset, p_fp_info);
2389 /********************************/
2390 /* E-DCH data here */
2392 guint bit_offset = 0;
2393 guint total_pdus = 0;
2394 guint total_bits = 0;
2395 gboolean dissected = FALSE;
2398 proto_tree_add_item(tree, hf_fp_edch_fsn, tvb, offset, 1, FALSE);
2401 /* Number of subframes.
2402 This was 3 bits in early releases, is 4 bits offset by 1 in later releases */
2403 if ((p_fp_info->release >= 6) &&
2404 ((p_fp_info->release_year > 2005) ||
2405 (p_fp_info->release_year == 2005 && p_fp_info->release_month >= 9)))
2407 /* Use 4 bits plus offset of 1 */
2408 number_of_subframes = (tvb_get_guint8(tvb, offset) & 0x0f) + 1;
2412 /* Use 3 bits only */
2413 number_of_subframes = (tvb_get_guint8(tvb, offset) & 0x07);
2415 proto_tree_add_uint(tree, hf_fp_edch_number_of_subframes, tvb, offset, 1,
2416 number_of_subframes);
2421 cfn = tvb_get_guint8(tvb, offset);
2422 proto_tree_add_item(tree, hf_fp_cfn, tvb, offset, 1, FALSE);
2425 /* EDCH subframe header list */
2426 for (n=0; n < number_of_subframes; n++)
2429 int start_offset = offset;
2430 proto_item *subframe_header_ti;
2431 proto_tree *subframe_header_tree;
2433 /* Add subframe header subtree */
2434 subframe_header_ti = proto_tree_add_string_format(tree, hf_fp_edch_subframe_header, tvb, offset, 0,
2436 subframe_header_tree = proto_item_add_subtree(subframe_header_ti, ett_fp_edch_subframe_header);
2438 /* Number of HARQ Retransmissions */
2439 proto_tree_add_item(subframe_header_tree, hf_fp_edch_harq_retransmissions, tvb,
2442 /* Subframe number */
2443 subframes[n].subframe_number = (tvb_get_guint8(tvb, offset) & 0x07);
2444 proto_tree_add_item(subframe_header_tree, hf_fp_edch_subframe_number, tvb,
2448 /* Number of MAC-es PDUs */
2449 subframes[n].number_of_mac_es_pdus = (tvb_get_guint8(tvb, offset) & 0xf0) >> 4;
2450 proto_tree_add_item(subframe_header_tree, hf_fp_edch_number_of_mac_es_pdus,
2451 tvb, offset, 1, FALSE);
2454 proto_item_append_text(subframe_header_ti, " %u header (%u MAC-es PDUs)",
2455 subframes[n].subframe_number,
2456 subframes[n].number_of_mac_es_pdus);
2458 /* Details of each MAC-es PDU */
2459 for (i=0; i < subframes[n].number_of_mac_es_pdus; i++)
2467 ddi_offset = offset + (bit_offset / 8);
2469 proto_tree_add_bits_ret_val(subframe_header_tree, hf_fp_edch_ddi, tvb,
2470 offset*8 + bit_offset, 6, &ddi, FALSE);
2472 subframes[n].ddi[i] = (guint8)ddi;
2475 /* Number of MAC-d PDUs (6 bits) */
2476 n_pdus_offset = offset + (bit_offset / 8);
2478 proto_tree_add_bits_ret_val(subframe_header_tree, hf_fp_edch_number_of_mac_d_pdus, tvb,
2479 offset*8 + bit_offset, 6, &n_pdus, FALSE);
2481 subframes[n].number_of_mac_d_pdus[i] = (guint8)n_pdus;
2485 offset += ((bit_offset+7)/8);
2487 /* Tree should cover entire subframe header */
2488 proto_item_set_len(subframe_header_ti, offset - start_offset);
2491 /* EDCH subframes */
2493 for (n=0; n < number_of_subframes; n++)
2496 proto_item *subframe_ti;
2497 proto_tree *subframe_tree;
2498 guint bits_in_subframe = 0;
2499 guint mac_d_pdus_in_subframe = 0;
2503 /* Add subframe subtree */
2504 subframe_ti = proto_tree_add_string_format(tree, hf_fp_edch_subframe, tvb, offset, 0,
2505 "", "Subframe %u data", subframes[n].subframe_number);
2506 subframe_tree = proto_item_add_subtree(subframe_ti, ett_fp_edch_subframe);
2508 for (i=0; i < subframes[n].number_of_mac_es_pdus; i++)
2517 /* Look up mac-d pdu size for this ddi */
2518 for (m=0; m < p_fp_info->no_ddi_entries; m++)
2520 if (subframes[n].ddi[i] == p_fp_info->edch_ddi[m])
2522 size = p_fp_info->edch_macd_pdu_size[m];
2527 if (m == p_fp_info->no_ddi_entries)
2529 /* Not found. Oops */
2533 /* Send MAC-dd PDUs together as one MAC-es PDU */
2534 send_size = size * subframes[n].number_of_mac_d_pdus[i];
2537 proto_tree_add_item(subframe_tree, hf_fp_edch_pdu_padding, tvb,
2538 offset + (bit_offset/8),
2543 tsn = (tvb_get_guint8(tvb, offset + (bit_offset/8)) & 0x3f);
2544 proto_tree_add_item(subframe_tree, hf_fp_edch_tsn, tvb,
2545 offset + (bit_offset/8),
2552 ti = proto_tree_add_item(subframe_tree, hf_fp_edch_mac_es_pdu, tvb,
2553 offset + (bit_offset/8),
2554 ((bit_offset % 8) + send_size + 7) / 8,
2556 proto_item_append_text(ti, " (%u * %u = %u bits, subframe %d)",
2557 size, subframes[n].number_of_mac_d_pdus[i],
2560 for (macd_idx = 0; macd_idx < subframes[n].number_of_mac_d_pdus[i]; macd_idx++) {
2562 pinfo->fd->subnum = macd_idx; /* set subframe number to current TB */
2563 /* create new TVB and pass further on */
2564 next_tvb = tvb_new_subset(tvb, offset + bit_offset/8,
2565 ((bit_offset % 8) + size + 7) / 8, -1);
2566 call_dissector(mac_fdd_edch_handle, next_tvb, pinfo, top_level_tree);
2571 bits_in_subframe += send_size;
2572 mac_d_pdus_in_subframe += subframes[n].number_of_mac_d_pdus[i];
2574 /* Pad out to next byte */
2577 bit_offset += (8 - (bit_offset % 8));
2583 /* Tree should cover entire subframe */
2584 proto_item_set_len(subframe_ti, bit_offset/8);
2585 /* Append summary info to subframe label */
2586 proto_item_append_text(subframe_ti, " (%u bits in %u MAC-d PDUs)",
2587 bits_in_subframe, mac_d_pdus_in_subframe);
2589 total_pdus += mac_d_pdus_in_subframe;
2590 total_bits += bits_in_subframe;
2592 offset += (bit_offset/8);
2595 /* Report number of subframes in info column
2596 * do this only if no other dissector was called */
2597 if (dissected == FALSE && check_col(pinfo->cinfo, COL_INFO))
2599 col_append_fstr(pinfo->cinfo, COL_INFO,
2600 " CFN = %03u (%u bits in %u pdus in %u subframes)",
2601 cfn, total_bits, total_pdus, number_of_subframes);
2604 /* Spare extension and payload CRC (optional) */
2605 dissect_spare_extension_and_crc(tvb, pinfo, tree,
2606 p_fp_info->dch_crc_present, offset);
2611 /**********************************************************/
2612 /* Dissect an HSDSCH channel */
2613 /* The data format corresponds to the format */
2614 /* described in R5 and R6, and frame type 1 in Release 7. */
2615 void dissect_hsdsch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2616 int offset, struct fp_info *p_fp_info)
2618 gboolean is_control_frame;
2621 proto_tree_add_item(tree, hf_fp_header_crc, tvb, offset, 1, FALSE);
2624 is_control_frame = tvb_get_guint8(tvb, offset) & 0x01;
2625 proto_tree_add_item(tree, hf_fp_ft, tvb, offset, 1, FALSE);
2628 if (check_col(pinfo->cinfo, COL_INFO))
2630 col_append_str(pinfo->cinfo, COL_INFO, is_control_frame ? " [Control] " : " [Data] ");
2633 if (is_control_frame)
2635 dissect_common_control(tvb, pinfo, tree, offset, p_fp_info);
2639 guint8 number_of_pdus;
2641 guint16 user_buffer_size;
2643 /**************************************/
2644 /* HS-DCH data here (type 1 in R7) */
2647 if ((p_fp_info->release == 6) ||
2648 (p_fp_info->release == 7))
2650 guint8 frame_seq_no = (tvb_get_guint8(tvb, offset) & 0xf0) >> 4;
2651 proto_tree_add_item(tree, hf_fp_frame_seq_nr, tvb, offset, 1, FALSE);
2653 if (check_col(pinfo->cinfo, COL_INFO))
2655 col_append_fstr(pinfo->cinfo, COL_INFO, " seqno=%u", frame_seq_no);
2660 proto_tree_add_item(tree, hf_fp_cmch_pi, tvb, offset, 1, FALSE);
2663 /* MAC-d PDU Length (13 bits) */
2664 pdu_length = (tvb_get_ntohs(tvb, offset) >> 3);
2665 proto_tree_add_item(tree, hf_fp_mac_d_pdu_len, tvb, offset, 2, FALSE);
2668 if ((p_fp_info->release == 6) ||
2669 (p_fp_info->release == 7))
2672 proto_tree_add_item(tree, hf_fp_flush, tvb, offset-1, 1, FALSE);
2674 /* FSN/DRT reset bit */
2675 proto_tree_add_item(tree, hf_fp_fsn_drt_reset, tvb, offset-1, 1, FALSE);
2680 number_of_pdus = tvb_get_guint8(tvb, offset);
2681 proto_tree_add_item(tree, hf_fp_num_of_pdu, tvb, offset, 1, FALSE);
2684 /* User buffer size */
2685 user_buffer_size = tvb_get_ntohs(tvb, offset);
2686 proto_tree_add_item(tree, hf_fp_user_buffer_size, tvb, offset, 2, FALSE);
2690 offset = dissect_macd_pdu_data(tvb, pinfo, tree, offset, pdu_length,
2693 if (check_col(pinfo->cinfo, COL_INFO))
2695 col_append_fstr(pinfo->cinfo, COL_INFO, " User-Buffer-Size=%u", user_buffer_size);
2698 /* Extra IEs (if there is room for them) */
2699 if (((p_fp_info->release == 6) ||
2700 (p_fp_info->release == 7)) &&
2701 (tvb_length_remaining(tvb, offset) > 2))
2705 guint8 flag_bytes = 0;
2710 proto_item *new_ie_flags_ti;
2711 proto_tree *new_ie_flags_tree;
2712 guint ies_found = 0;
2714 /* Add new IE flags subtree */
2715 new_ie_flags_ti = proto_tree_add_string_format(tree, hf_fp_hsdsch_new_ie_flags, tvb, offset, 1,
2716 "", "New IE flags");
2717 new_ie_flags_tree = proto_item_add_subtree(new_ie_flags_ti, ett_fp_hsdsch_new_ie_flags);
2719 /* Read next byte */
2720 flags = tvb_get_guint8(tvb, offset);
2723 /* Dissect individual bits */
2724 for (n=0; n < 8; n++)
2726 proto_tree_add_item(new_ie_flags_tree, hf_fp_hsdsch_new_ie_flag[n], tvb, offset, 1, FALSE);
2727 if ((flags >> (7-n)) & 0x01)
2734 proto_item_append_text(new_ie_flags_ti, " (%u IEs found)", ies_found);
2736 /* Last bit set will indicate another flags byte follows... */
2737 } while (0); /*((flags & 0x01) && (flag_bytes < 31));*/
2739 if (1) /*(flags & 0x8) */
2741 /* DRT is shown as mandatory in the diagram (3GPP TS 25.435 V6.3.0),
2742 but the description below it states that
2743 it should depend upon the first bit. The detailed description of
2744 New IE flags doesn't agree, so treat as mandatory for now... */
2745 proto_tree_add_item(tree, hf_fp_hsdsch_drt, tvb, offset, 2, FALSE);
2750 /* Spare Extension and Payload CRC */
2751 dissect_spare_extension_and_crc(tvb, pinfo, tree, 1, offset);
2756 /******************************************/
2757 /* Dissect an HSDSCH type 2 channel */
2758 /* (introduced in Release 7) */
2759 /* N.B. there is currently no support for */
2760 /* frame type 3 (IuR only?) */
2761 void dissect_hsdsch_type_2_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2762 int offset, struct fp_info *p_fp_info)
2764 gboolean is_control_frame;
2767 proto_tree_add_item(tree, hf_fp_header_crc, tvb, offset, 1, FALSE);
2770 is_control_frame = tvb_get_guint8(tvb, offset) & 0x01;
2771 proto_tree_add_item(tree, hf_fp_ft, tvb, offset, 1, FALSE);
2774 if (check_col(pinfo->cinfo, COL_INFO))
2776 col_append_str(pinfo->cinfo, COL_INFO, is_control_frame ? " [Control] " : " [Data] ");
2779 if (is_control_frame)
2781 dissect_common_control(tvb, pinfo, tree, offset, p_fp_info);
2785 guint8 number_of_pdu_blocks;
2786 gboolean drt_present = FALSE;
2787 gboolean fach_present = FALSE;
2788 guint16 user_buffer_size;
2791 #define MAX_PDU_BLOCKS 31
2792 guint64 lchid[MAX_PDU_BLOCKS];
2793 guint64 pdu_length[MAX_PDU_BLOCKS];
2794 guint64 no_of_pdus[MAX_PDU_BLOCKS];
2796 /********************************/
2797 /* HS-DCH type 2 data here */
2799 col_append_str(pinfo->cinfo, COL_INFO, "(ehs)");
2801 /* Frame Seq Nr (4 bits) */
2802 if ((p_fp_info->release == 6) ||
2803 (p_fp_info->release == 7))
2805 guint8 frame_seq_no = (tvb_get_guint8(tvb, offset) & 0xf0) >> 4;
2806 proto_tree_add_item(tree, hf_fp_frame_seq_nr, tvb, offset, 1, FALSE);
2808 if (check_col(pinfo->cinfo, COL_INFO))
2810 col_append_fstr(pinfo->cinfo, COL_INFO, " seqno=%u", frame_seq_no);
2814 /* CmCH-PI (4 bits) */
2815 proto_tree_add_item(tree, hf_fp_cmch_pi, tvb, offset, 1, FALSE);
2818 /* Total number of PDU blocks (5 bits) */
2819 number_of_pdu_blocks = (tvb_get_guint8(tvb, offset) >> 3);
2820 proto_tree_add_item(tree, hf_fp_total_pdu_blocks, tvb, offset, 1, FALSE);
2822 if (p_fp_info->release == 7)
2825 proto_tree_add_item(tree, hf_fp_flush, tvb, offset, 1, FALSE);
2827 /* FSN/DRT reset bit */
2828 proto_tree_add_item(tree, hf_fp_fsn_drt_reset, tvb, offset, 1, FALSE);
2831 drt_present = tvb_get_guint8(tvb, offset) & 0x01;
2832 proto_tree_add_item(tree, hf_fp_drt_indicator, tvb, offset, 1, FALSE);
2836 /* FACH Indicator flag */
2837 fach_present = (tvb_get_guint8(tvb, offset) & 0x08) >> 7;
2838 proto_tree_add_item(tree, hf_fp_fach_indicator, tvb, offset, 1, FALSE);
2841 /* User buffer size */
2842 user_buffer_size = tvb_get_ntohs(tvb, offset);
2843 proto_tree_add_item(tree, hf_fp_user_buffer_size, tvb, offset, 2, FALSE);
2846 if (check_col(pinfo->cinfo, COL_INFO))
2848 col_append_fstr(pinfo->cinfo, COL_INFO, " User-Buffer-Size=%u", user_buffer_size);
2852 /********************************************************************/
2853 /* Now read number_of_pdu_blocks header entries */
2854 for (n=0; n < number_of_pdu_blocks; n++)
2856 proto_item *pdu_block_header_ti;
2857 proto_tree *pdu_block_header_tree;
2859 /* Add PDU block header subtree */
2860 pdu_block_header_ti = proto_tree_add_string_format(tree, hf_fp_hsdsch_pdu_block_header,
2863 "PDU Block Header");
2864 pdu_block_header_tree = proto_item_add_subtree(pdu_block_header_ti,
2865 ett_fp_hsdsch_pdu_block_header);
2867 /* MAC-d/c PDU length in this block (11 bits) */
2868 proto_tree_add_bits_ret_val(pdu_block_header_tree, hf_fp_pdu_length_in_block, tvb,
2869 (offset*8) + ((n % 2) ? 4 : 0), 11,
2870 &pdu_length[n], FALSE);
2877 /* # PDUs in this block (4 bits) */
2878 proto_tree_add_bits_ret_val(pdu_block_header_tree, hf_fp_pdus_in_block, tvb,
2879 (offset*8) + ((n % 2) ? 0 : 4), 4,
2880 &no_of_pdus[n], FALSE);
2884 /* Logical channel ID in block (4 bits) */
2885 proto_tree_add_bits_ret_val(pdu_block_header_tree, hf_fp_lchid, tvb,
2886 (offset*8) + ((n % 2) ? 4 : 0), 4,
2891 if (n == (number_of_pdu_blocks-1)) {
2892 /* Byte is padded out for last block */
2897 /* Append summary to header tree root */
2898 proto_item_append_text(pdu_block_header_ti,
2899 " (lch:%u, %u pdus of %u bytes)",
2901 (guint16)no_of_pdus[n],
2902 (guint16)pdu_length[n]);
2906 /**********************************************/
2907 /* Optional fields indicated by earlier flags */
2911 proto_tree_add_item(tree, hf_fp_drt, tvb, offset, 2, FALSE);
2918 proto_tree_add_item(tree, hf_fp_hrnti, tvb, offset, 2, FALSE);
2921 /* RACH Measurement Result */
2922 proto_tree_add_item(tree, hf_fp_rach_measurement_result, tvb, offset, 2, FALSE);
2927 /********************************************************************/
2928 /* Now read the MAC-d/c PDUs for each block using info from headers */
2929 for (n=0; n < number_of_pdu_blocks; n++)
2931 /* Add PDU block header subtree */
2932 offset = dissect_macd_pdu_data_type_2(tvb, pinfo, tree, offset,
2933 (guint16)pdu_length[n],
2934 (guint16)no_of_pdus[n]);
2937 /* Spare Extension and Payload CRC */
2938 dissect_spare_extension_and_crc(tvb, pinfo, tree, 1, offset);
2942 static gboolean heur_dissect_fp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2944 struct fp_info *p_fp_info;
2946 p_fp_info = p_get_proto_data(pinfo->fd, proto_fp);
2948 /* if no FP info is present, assume this is not FP over UDP */
2949 if (!p_fp_info) return FALSE;
2951 /* if FP info is present, check that it really is an ethernet link */
2952 if (p_fp_info->link_type != FP_Link_Ethernet) return FALSE;
2954 /* remember 'lower' UDP layer port information */
2955 if (!p_fp_info->srcport || !p_fp_info->destport) {
2956 p_fp_info->srcport = pinfo->srcport;
2957 p_fp_info->destport = pinfo->destport;
2960 /* discriminate 'lower' UDP layer from 'user data' UDP layer
2961 * (i.e. if an FP over UDP packet contains a user UDP packet */
2962 if (p_fp_info->srcport != pinfo->srcport ||
2963 p_fp_info->destport != pinfo->destport)
2966 /* assume this is FP */
2967 dissect_fp(tvb, pinfo, tree);
2972 /*****************************/
2973 /* Main dissection function. */
2974 void dissect_fp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2976 proto_tree *fp_tree;
2979 struct fp_info *p_fp_info;
2981 /* Append this protocol name rather than replace. */
2982 col_set_str(pinfo->cinfo, COL_PROTOCOL, "FP");
2984 /* Create fp tree. */
2985 ti = proto_tree_add_item(tree, proto_fp, tvb, offset, -1, FALSE);
2986 fp_tree = proto_item_add_subtree(ti, ett_fp);
2988 top_level_tree = tree;
2990 /* Look for packet info! */
2991 p_fp_info = p_get_proto_data(pinfo->fd, proto_fp);
2993 /* Can't dissect anything without it... */
2994 if (p_fp_info == NULL)
2997 proto_tree_add_text(fp_tree, tvb, offset, -1,
2998 "Can't dissect FP frame because no per-frame info was attached!");
2999 PROTO_ITEM_SET_GENERATED(ti);
3003 /* Show channel type in info column, tree */
3004 if (check_col(pinfo->cinfo, COL_INFO))
3006 col_add_str(pinfo->cinfo, COL_INFO,
3007 val_to_str(p_fp_info->channel,
3009 "Unknown channel type"));
3011 proto_item_append_text(ti, " (%s)",
3012 val_to_str(p_fp_info->channel,
3014 "Unknown channel type"));
3016 /* Add channel type as a generated field */
3017 ti = proto_tree_add_uint(fp_tree, hf_fp_channel_type, tvb, 0, 0, p_fp_info->channel);
3018 PROTO_ITEM_SET_GENERATED(ti);
3020 /* Add division type as a generated field */
3021 if (p_fp_info->release == 7)
3023 ti = proto_tree_add_uint(fp_tree, hf_fp_division, tvb, 0, 0, p_fp_info->division);
3024 PROTO_ITEM_SET_GENERATED(ti);
3027 /* Add link direction as a generated field */
3028 ti = proto_tree_add_uint(fp_tree, hf_fp_direction, tvb, 0, 0, p_fp_info->is_uplink);
3029 PROTO_ITEM_SET_GENERATED(ti);
3031 /* Don't currently handle IuR-specific formats, but its useful to even see
3032 the channel type and direction */
3033 if (p_fp_info->iface_type == IuR_Interface)
3038 /*************************************/
3039 /* Dissect according to channel type */
3040 switch (p_fp_info->channel)
3042 case CHANNEL_RACH_TDD:
3043 case CHANNEL_RACH_TDD_128:
3044 case CHANNEL_RACH_FDD:
3045 dissect_rach_channel_info(tvb, pinfo, fp_tree, offset, p_fp_info);
3048 dissect_dch_channel_info(tvb, pinfo, fp_tree, offset, p_fp_info);
3050 case CHANNEL_FACH_FDD:
3051 case CHANNEL_FACH_TDD:
3052 dissect_fach_channel_info(tvb, pinfo, fp_tree, offset, p_fp_info);
3054 case CHANNEL_DSCH_FDD:
3055 case CHANNEL_DSCH_TDD:
3056 dissect_dsch_channel_info(tvb, pinfo, fp_tree, offset, p_fp_info);
3058 case CHANNEL_USCH_TDD_128:
3059 case CHANNEL_USCH_TDD_384:
3060 dissect_usch_channel_info(tvb, pinfo, fp_tree, offset, p_fp_info);
3063 dissect_pch_channel_info(tvb, pinfo, fp_tree, offset, p_fp_info);
3066 dissect_cpch_channel_info(tvb, pinfo, fp_tree, offset, p_fp_info);
3069 dissect_bch_channel_info(tvb, pinfo, fp_tree, offset, p_fp_info);
3071 case CHANNEL_HSDSCH:
3072 /* Show configured MAC HS-DSCH entity in use */
3075 proto_item *entity_ti;
3076 entity_ti = proto_tree_add_uint(fp_tree, hf_fp_hsdsch_entity,
3078 p_fp_info->hsdsch_entity);
3079 PROTO_ITEM_SET_GENERATED(entity_ti);
3081 switch (p_fp_info->hsdsch_entity) {
3082 case entity_not_specified:
3084 /* This is the pre-R7 default */
3085 dissect_hsdsch_channel_info(tvb, pinfo, fp_tree, offset, p_fp_info);
3088 dissect_hsdsch_type_2_channel_info(tvb, pinfo, fp_tree, offset, p_fp_info);
3091 /* TODO: dissector error */
3095 case CHANNEL_IUR_CPCHF:
3098 case CHANNEL_IUR_FACH:
3101 case CHANNEL_IUR_DSCH:
3102 dissect_iur_dsch_channel_info(tvb, pinfo, fp_tree, offset, p_fp_info);
3105 dissect_e_dch_channel_info(tvb, pinfo, fp_tree, offset, p_fp_info);
3114 void proto_register_fp(void)
3116 static hf_register_info hf[] =
3118 { &hf_fp_channel_type,
3120 "fp.channel-type", FT_UINT8, BASE_HEX, VALS(channel_type_vals), 0x0,
3126 "fp.division", FT_UINT8, BASE_HEX, VALS(division_vals), 0x0,
3127 "Radio division type", HFILL
3132 "fp.direction", FT_UINT8, BASE_HEX, VALS(direction_vals), 0x0,
3133 "Link direction", HFILL
3136 { &hf_fp_header_crc,
3138 "fp.header-crc", FT_UINT8, BASE_HEX, NULL, 0xfe,
3144 "fp.ft", FT_UINT8, BASE_HEX, VALS(data_control_vals), 0x01,
3150 "fp.cfn", FT_UINT8, BASE_DEC, NULL, 0x0,
3151 "Connection Frame Number", HFILL
3156 "fp.pch.cfn", FT_UINT16, BASE_DEC, NULL, 0xfff0,
3157 "PCH Connection Frame Number", HFILL
3162 "fp.pch.toa", FT_INT24, BASE_DEC, NULL, 0x0,
3163 "PCH Time of Arrival", HFILL
3166 { &hf_fp_cfn_control,
3168 "fp.cfn-control", FT_UINT8, BASE_DEC, NULL, 0x0,
3169 "Connection Frame Number Control", HFILL
3174 "fp.cfn-control", FT_INT16, BASE_DEC, NULL, 0x0,
3175 "Time of arrival (units are 125 microseconds)", HFILL
3180 "fp.tb", FT_BYTES, BASE_NONE, NULL, 0x0,
3181 "Transport Block", HFILL
3184 { &hf_fp_chan_zero_tbs,
3185 { "No TBs for channel",
3186 "fp.channel-with-zero-tbs", FT_UINT32, BASE_DEC, NULL, 0x0,
3187 "Channel with 0 TBs", HFILL
3192 "fp.tfi", FT_UINT8, BASE_DEC, NULL, 0x0,
3193 "Transport Format Indicator", HFILL
3198 "fp.usch.tfi", FT_UINT8, BASE_DEC, NULL, 0x1f,
3199 "USCH Transport Format Indicator", HFILL
3204 "fp.cpch.tfi", FT_UINT8, BASE_DEC, NULL, 0x1f,
3205 "CPCH Transport Format Indicator", HFILL
3208 { &hf_fp_propagation_delay,
3209 { "Propagation Delay",
3210 "fp.propagation-delay", FT_UINT8, BASE_DEC, NULL, 0x0,
3214 { &hf_fp_dch_control_frame_type,
3215 { "Control Frame Type",
3216 "fp.dch.control.frame-type", FT_UINT8, BASE_HEX, VALS(dch_control_frame_type_vals), 0x0,
3217 "DCH Control Frame Type", HFILL
3220 { &hf_fp_dch_rx_timing_deviation,
3221 { "Rx Timing Deviation",
3222 "fp.dch.control.rx-timing-deviation", FT_UINT8, BASE_DEC, 0, 0x0,
3223 "DCH Rx Timing Deviation", HFILL
3226 { &hf_fp_quality_estimate,
3227 { "Quality Estimate",
3228 "fp.dch.quality-estimate", FT_UINT8, BASE_DEC, 0, 0x0,
3232 { &hf_fp_payload_crc,
3234 "fp.payload-crc", FT_UINT16, BASE_HEX, 0, 0x0,
3238 { &hf_fp_common_control_frame_type,
3239 { "Control Frame Type",
3240 "fp.common.control.frame-type", FT_UINT8, BASE_HEX, VALS(common_control_frame_type_vals), 0x0,
3241 "Common Control Frame Type", HFILL
3246 "fp.crci", FT_UINT8, BASE_HEX, VALS(crci_vals), 0x80,
3247 "CRC correctness indicator", HFILL
3252 "fp.crci", FT_UINT8, BASE_HEX, VALS(crci_vals), 0x40,
3253 "CRC correctness indicator", HFILL
3258 "fp.crci", FT_UINT8, BASE_HEX, VALS(crci_vals), 0x20,
3259 "CRC correctness indicator", HFILL
3264 "fp.crci", FT_UINT8, BASE_HEX, VALS(crci_vals), 0x10,
3265 "CRC correctness indicator", HFILL
3270 "fp.crci", FT_UINT8, BASE_HEX, VALS(crci_vals), 0x08,
3271 "CRC correctness indicator", HFILL
3276 "fp.crci", FT_UINT8, BASE_HEX, VALS(crci_vals), 0x04,
3277 "CRC correctness indicator", HFILL
3282 "fp.crci", FT_UINT8, BASE_HEX, VALS(crci_vals), 0x02,
3283 "CRC correctness indicator", HFILL
3288 "fp.crci", FT_UINT8, BASE_HEX, VALS(crci_vals), 0x01,
3289 "CRC correctness indicator", HFILL
3292 { &hf_fp_received_sync_ul_timing_deviation,
3293 { "Received SYNC UL Timing Deviation",
3294 "fp.rx-sync-ul-timing-deviation", FT_UINT8, BASE_DEC, 0, 0x0,
3299 { "Paging Indication",
3300 "fp.pch.pi", FT_UINT8, BASE_DEC, VALS(paging_indication_vals), 0x01,
3301 "Indicates if the PI Bitmap is present", HFILL
3306 "fp.pch.tfi", FT_UINT8, BASE_DEC, 0, 0x1f,
3307 "PCH Transport Format Indicator", HFILL
3312 "fp.fach.tfi", FT_UINT8, BASE_DEC, 0, 0x1f,
3313 "FACH Transport Format Indicator", HFILL
3316 { &hf_fp_transmit_power_level,
3317 { "Transmit Power Level",
3318 "fp.transmit-power-level", FT_FLOAT, BASE_NONE, 0, 0x0,
3319 "Transmit Power Level (dB)", HFILL
3322 { &hf_fp_pdsch_set_id,
3324 "fp.pdsch-set-id", FT_UINT8, BASE_DEC, 0, 0x0,
3325 "A pointer to the PDSCH Set which shall be used to transmit", HFILL
3328 { &hf_fp_paging_indication_bitmap,
3329 { "Paging Indications bitmap",
3330 "fp.pch.pi-bitmap", FT_NONE, BASE_NONE, NULL, 0x0,
3331 "Paging Indication bitmap", HFILL
3334 { &hf_fp_rx_timing_deviation,
3335 { "Rx Timing Deviation",
3336 "fp.common.control.rx-timing-deviation", FT_UINT8, BASE_DEC, 0, 0x0,
3337 "Common Rx Timing Deviation", HFILL
3340 { &hf_fp_dch_e_rucch_flag,
3342 "fp.common.control.e-rucch-flag", FT_UINT8, BASE_DEC, VALS(e_rucch_flag_vals), 0x0,
3346 { &hf_fp_edch_header_crc,
3347 { "E-DCH Header CRC",
3348 "fp.edch.header-crc", FT_UINT16, BASE_HEX, 0, 0xfef,
3354 "fp.edch.fsn", FT_UINT8, BASE_DEC, 0, 0x0f,
3355 "E-DCH Frame Sequence Number", HFILL
3358 { &hf_fp_edch_number_of_subframes,
3359 { "No of subframes",
3360 "fp.edch.no-of-subframes", FT_UINT8, BASE_DEC, 0, 0x0f,
3361 "E-DCH Number of subframes", HFILL
3364 { &hf_fp_edch_harq_retransmissions,
3365 { "No of HARQ Retransmissions",
3366 "fp.edch.no-of-harq-retransmissions", FT_UINT8, BASE_DEC, 0, 0x78,
3367 "E-DCH Number of HARQ retransmissions", HFILL
3370 { &hf_fp_edch_subframe_number,
3371 { "Subframe number",
3372 "fp.edch.subframe-number", FT_UINT8, BASE_DEC, 0, 0x07,
3373 "E-DCH Subframe number", HFILL
3376 { &hf_fp_edch_number_of_mac_es_pdus,
3377 { "Number of Mac-es PDUs",
3378 "fp.edch.number-of-mac-es-pdus", FT_UINT8, BASE_DEC, 0, 0xf0,
3384 "fp.edch.ddi", FT_UINT8, BASE_DEC, 0, 0x0,
3385 "E-DCH Data Description Indicator", HFILL
3388 { &hf_fp_edch_subframe,
3390 "fp.edch.subframe", FT_STRING, BASE_NONE, NULL, 0x0,
3391 "EDCH Subframe", HFILL
3394 { &hf_fp_edch_subframe_header,
3395 { "Subframe header",
3396 "fp.edch.subframe-header", FT_STRING, BASE_NONE, NULL, 0x0,
3397 "EDCH Subframe header", HFILL
3400 { &hf_fp_edch_number_of_mac_d_pdus,
3401 { "Number of Mac-d PDUs",
3402 "fp.edch.number-of-mac-d-pdus", FT_UINT8, BASE_DEC, 0, 0x0,
3406 { &hf_fp_edch_pdu_padding,
3408 "fp.edch-data-padding", FT_UINT8, BASE_DEC, 0, 0xc0,
3409 "E-DCH padding before PDU", HFILL
3414 "fp.edch-tsn", FT_UINT8, BASE_DEC, 0, 0x3f,
3415 "E-DCH Transmission Sequence Number", HFILL
3418 { &hf_fp_edch_mac_es_pdu,
3420 "fp.edch.mac-es-pdu", FT_NONE, BASE_NONE, NULL, 0x0,
3424 { &hf_fp_frame_seq_nr,
3426 "fp.frame-seq-nr", FT_UINT8, BASE_DEC, 0, 0xf0,
3427 "Frame Sequence Number", HFILL
3430 { &hf_fp_hsdsch_pdu_block_header,
3431 { "PDU block header",
3432 "fp.hsdsch.pdu-block-header", FT_STRING, BASE_NONE, NULL, 0x0,
3433 "HS-DSCH type 2 PDU block header", HFILL
3436 { &hf_fp_hsdsch_pdu_block,
3438 "fp.hsdsch.pdu-block", FT_STRING, BASE_NONE, NULL, 0x0,
3439 "HS-DSCH type 2 PDU block data", HFILL
3444 "fp.flush", FT_UINT8, BASE_DEC, 0, 0x04,
3445 "Whether all PDUs for this priority queue should be removed", HFILL
3448 { &hf_fp_fsn_drt_reset,
3450 "fp.fsn-drt-reset", FT_UINT8, BASE_DEC, 0, 0x02,
3451 "FSN/DRT Reset Flag", HFILL
3454 { &hf_fp_drt_indicator,
3456 "fp.drt-indicator", FT_UINT8, BASE_DEC, 0, 0x01,
3460 { &hf_fp_fach_indicator,
3462 "fp.fach-indicator", FT_UINT8, BASE_DEC, 0, 0x80,
3466 { &hf_fp_total_pdu_blocks,
3468 "fp.pdu_blocks", FT_UINT8, BASE_DEC, 0, 0xf8,
3469 "Total number of PDU blocks", HFILL
3474 "fp.drt", FT_UINT16, BASE_DEC, 0, 0x0,
3480 "fp.hrnti", FT_UINT16, BASE_DEC, 0, 0x0,
3484 { &hf_fp_rach_measurement_result,
3485 { "RACH Measurement Result",
3486 "fp.rach-measurement-result", FT_UINT16, BASE_DEC, 0, 0x0,
3491 { "Logical Channel ID",
3492 "fp.lchid", FT_UINT8, BASE_DEC, 0, 0x0,
3496 { &hf_fp_pdu_length_in_block,
3497 { "PDU length in block",
3498 "fp.pdu-length-in-block", FT_UINT8, BASE_DEC, 0, 0x0,
3499 "Length of each PDU in this block in bytes", HFILL
3502 { &hf_fp_pdus_in_block,
3504 "fp.no-pdus-in-block", FT_UINT8, BASE_DEC, 0, 0x0,
3505 "Number of PDUs in block", HFILL
3510 "fp.cmch-pi", FT_UINT8, BASE_DEC, 0, 0x0f,
3511 "Common Transport Channel Priority Indicator", HFILL
3514 { &hf_fp_user_buffer_size,
3515 { "User buffer size",
3516 "fp.user-buffer-size", FT_UINT16, BASE_DEC, 0, 0x0,
3517 "User buffer size in octets", HFILL
3520 { &hf_fp_hsdsch_credits,
3521 { "HS-DSCH Credits",
3522 "fp.hsdsch-credits", FT_UINT16, BASE_DEC, 0, 0x0,
3526 { &hf_fp_hsdsch_max_macd_pdu_len,
3527 { "Max MAC-d PDU Length",
3528 "fp.hsdsch.max-macd-pdu-len", FT_UINT16, BASE_DEC, 0, 0xfff8,
3529 "Maximum MAC-d PDU Length in bits", HFILL
3532 { &hf_fp_hsdsch_max_macdc_pdu_len,
3533 { "Max MAC-d/c PDU Length",
3534 "fp.hsdsch.max-macdc-pdu-len", FT_UINT16, BASE_DEC, 0, 0x07ff,
3535 "Maximum MAC-d/c PDU Length in bits", HFILL
3538 { &hf_fp_hsdsch_interval,
3539 { "HS-DSCH Interval in milliseconds",
3540 "fp.hsdsch-interval", FT_UINT8, BASE_DEC, 0, 0x0,
3544 { &hf_fp_hsdsch_calculated_rate,
3545 { "Calculated rate allocation (bps)",
3546 "fp.hsdsch-calculated-rate", FT_UINT32, BASE_DEC, 0, 0x0,
3547 "Calculated rate RNC is allowed to send in bps", HFILL
3550 { &hf_fp_hsdsch_unlimited_rate,
3552 "fp.hsdsch-unlimited-rate", FT_NONE, BASE_NONE, 0, 0x0,
3553 "No restriction on rate at which date may be sent", HFILL
3556 { &hf_fp_hsdsch_repetition_period,
3557 { "HS-DSCH Repetition Period",
3558 "fp.hsdsch-repetition-period", FT_UINT8, BASE_DEC, 0, 0x0,
3559 "HS-DSCH Repetition Period in milliseconds", HFILL
3562 { &hf_fp_hsdsch_data_padding,
3564 "fp.hsdsch-data-padding", FT_UINT8, BASE_DEC, 0, 0xf0,
3565 "HS-DSCH Repetition Period in milliseconds", HFILL
3568 { &hf_fp_hsdsch_new_ie_flags,
3570 "fp.hsdsch.new-ie-flags", FT_STRING, BASE_NONE, 0, 0x0,
3574 { &hf_fp_hsdsch_new_ie_flag[0],
3576 "fp.hsdsch.new-ie-flag", FT_UINT8, BASE_DEC, 0, 0x80,
3580 { &hf_fp_hsdsch_new_ie_flag[1],
3582 "fp.hsdsch.new-ie-flag", FT_UINT8, BASE_DEC, 0, 0x40,
3586 { &hf_fp_hsdsch_new_ie_flag[2],
3588 "fp.hsdsch.new-ie-flag", FT_UINT8, BASE_DEC, 0, 0x20,
3592 { &hf_fp_hsdsch_new_ie_flag[3],
3594 "fp.hsdsch.new-ie-flag", FT_UINT8, BASE_DEC, 0, 0x10,
3598 { &hf_fp_hsdsch_new_ie_flag[4],
3600 "fp.hsdsch.new-ie-flag", FT_UINT8, BASE_DEC, 0, 0x08,
3604 { &hf_fp_hsdsch_new_ie_flag[5],
3606 "fp.hsdsch.new-ie-flag", FT_UINT8, BASE_DEC, 0, 0x04,
3610 { &hf_fp_hsdsch_new_ie_flag[6],
3612 "fp.hsdsch.new-ie-flag", FT_UINT8, BASE_DEC, 0, 0x02,
3616 { &hf_fp_hsdsch_new_ie_flag[7],
3617 { "Another new IE flags byte",
3618 "fp.hsdsch.new-ie-flags-byte", FT_UINT8, BASE_DEC, 0, 0x01,
3619 "Another new IE flagsbyte", HFILL
3622 { &hf_fp_hsdsch_drt,
3624 "fp.hsdsch.drt", FT_UINT8, BASE_DEC, 0, 0xf0,
3625 "Delay Reference Time", HFILL
3628 { &hf_fp_hsdsch_entity,
3630 "fp.hsdsch.entity", FT_UINT8, BASE_DEC, VALS(hsdshc_mac_entity_vals), 0x0,
3631 "Type of MAC entity for this HS-DSCH channel", HFILL
3634 { &hf_fp_timing_advance,
3636 "fp.timing-advance", FT_UINT8, BASE_DEC, 0, 0x3f,
3637 "Timing advance in chips", HFILL
3640 { &hf_fp_num_of_pdu,
3642 "fp.hsdsch.num-of-pdu", FT_UINT8, BASE_DEC, 0, 0x0,
3643 "Number of PDUs in the payload", HFILL
3646 { &hf_fp_mac_d_pdu_len,
3647 { "MAC-d PDU Length",
3648 "fp.hsdsch.mac-d-pdu-len", FT_UINT16, BASE_DEC, 0, 0xfff8,
3649 "MAC-d PDU Length in bits", HFILL
3654 "fp.mac-d-pdu", FT_BYTES, BASE_NONE, NULL, 0x0,
3660 "fp.data", FT_BYTES, BASE_NONE, NULL, 0x0,
3666 "fp.crcis", FT_BYTES, BASE_NONE, NULL, 0x0,
3667 "CRC Indicators for uplink TBs", HFILL
3672 "fp.t1", FT_UINT24, BASE_DEC, NULL, 0x0,
3673 "RNC frame number indicating time it sends frame", HFILL
3678 "fp.t2", FT_UINT24, BASE_DEC, NULL, 0x0,
3679 "NodeB frame number indicating time it received DL Sync", HFILL
3684 "fp.t3", FT_UINT24, BASE_DEC, NULL, 0x0,
3685 "NodeB frame number indicating time it sends frame", HFILL
3688 { &hf_fp_ul_sir_target,
3690 "fp.ul-sir-target", FT_FLOAT, BASE_NONE, 0, 0x0,
3691 "Value (in dB) of the SIR target to be used by the UL inner loop power control", HFILL
3694 { &hf_fp_pusch_set_id,
3696 "fp.pusch-set-id", FT_UINT8, BASE_DEC, NULL, 0x0,
3697 "Identifies PUSCH Set from those configured in NodeB", HFILL
3700 { &hf_fp_activation_cfn,
3702 "fp.activation-cfn", FT_UINT8, BASE_DEC, NULL, 0x0,
3703 "Activation Connection Frame Number", HFILL
3708 "fp.pusch-set-id", FT_UINT8, BASE_DEC, NULL, 0x0,
3709 "Duration of the activation period of the PUSCH Set", HFILL
3712 { &hf_fp_power_offset,
3714 "fp.power-offset", FT_FLOAT, BASE_NONE, NULL, 0x0,
3715 "Power offset (in dB)", HFILL
3718 { &hf_fp_code_number,
3720 "fp.code-number", FT_UINT8, BASE_DEC, NULL, 0x0,
3724 { &hf_fp_spreading_factor,
3725 { "Spreading factor",
3726 "fp.spreading-factor", FT_UINT8, BASE_DEC, VALS(spreading_factor_vals), 0xf0,
3732 "fp.mc-info", FT_UINT8, BASE_DEC, NULL, 0x0e,
3736 { &hf_fp_rach_new_ie_flags,
3738 "fp.rach.new-ie-flags", FT_STRING, BASE_NONE, 0, 0x0,
3742 { &hf_fp_rach_new_ie_flag_unused[0],
3744 "fp.rach.new-ie-flag", FT_UINT8, BASE_DEC, 0, 0x80,
3748 { &hf_fp_rach_new_ie_flag_unused[1],
3750 "fp.rach.new-ie-flag", FT_UINT8, BASE_DEC, 0, 0x40,
3754 { &hf_fp_rach_new_ie_flag_unused[2],
3756 "fp.rach.new-ie-flag", FT_UINT8, BASE_DEC, 0, 0x20,
3757 "New IE present (unused)", HFILL
3760 { &hf_fp_rach_new_ie_flag_unused[3],
3762 "fp.rach.new-ie-flag", FT_UINT8, BASE_DEC, 0, 0x10,
3763 "New IE present (unused)", HFILL
3766 { &hf_fp_rach_new_ie_flag_unused[4],
3768 "fp.rach.new-ie-flag", FT_UINT8, BASE_DEC, 0, 0x08,
3769 "New IE present (unused)", HFILL
3772 { &hf_fp_rach_new_ie_flag_unused[5],
3774 "fp.rach.new-ie-flag", FT_UINT8, BASE_DEC, 0, 0x04,
3775 "New IE present (unused)", HFILL
3778 { &hf_fp_rach_new_ie_flag_unused[6],
3780 "fp.rach.new-ie-flag", FT_UINT8, BASE_DEC, 0, 0x02,
3781 "New IE present (unused)", HFILL
3784 { &hf_fp_rach_cell_portion_id_present,
3785 { "Cell portion ID present",
3786 "fp.rach.cell-portion-id-present", FT_UINT8, BASE_DEC, 0, 0x01,
3790 { &hf_fp_rach_angle_of_arrival_present,
3791 { "Angle of arrival present",
3792 "fp.rach.angle-of-arrival-present", FT_UINT8, BASE_DEC, 0, 0x01,
3796 { &hf_fp_rach_ext_propagation_delay_present,
3797 { "Ext Propagation Delay Present",
3798 "fp.rach.ext-propagation-delay-present", FT_UINT8, BASE_DEC, 0, 0x02,
3802 { &hf_fp_rach_ext_rx_sync_ul_timing_deviation_present,
3803 { "Ext Received Sync UL Timing Deviation present",
3804 "fp.rach.ext-rx-sync-ul-timing-deviation-present", FT_UINT8, BASE_DEC, 0, 0x02,
3808 { &hf_fp_rach_ext_rx_timing_deviation_present,
3809 { "Ext Rx Timing Deviation present",
3810 "fp.rach.ext-rx-timing-deviation-present", FT_UINT8, BASE_DEC, 0, 0x01,
3814 { &hf_fp_cell_portion_id,
3815 { "Cell Portion ID",
3816 "fp.cell-portion-id", FT_UINT8, BASE_DEC, NULL, 0x3f,
3820 { &hf_fp_ext_propagation_delay,
3821 { "Ext Propagation Delay",
3822 "fp.ext-propagation-delay", FT_UINT16, BASE_DEC, NULL, 0x03ff,
3826 { &hf_fp_angle_of_arrival,
3827 { "Angle of Arrival",
3828 "fp.angle-of-arrival", FT_UINT16, BASE_DEC, NULL, 0x03ff,
3832 { &hf_fp_ext_received_sync_ul_timing_deviation,
3833 { "Ext Received SYNC UL Timing Deviation",
3834 "fp.ext-received-sync-ul-timing-deviation", FT_UINT16, BASE_DEC, NULL, 0x1fff,
3840 { &hf_fp_radio_interface_parameter_update_flag[0],
3842 "fp.radio-interface-param.cfn-valid", FT_UINT16, BASE_DEC, 0, 0x0001,
3846 { &hf_fp_radio_interface_parameter_update_flag[1],
3848 "fp.radio-interface-param.tpc-po-valid", FT_UINT16, BASE_DEC, 0, 0x0002,
3852 { &hf_fp_radio_interface_parameter_update_flag[2],
3854 "fp.radio-interface-param.dpc-mode-valid", FT_UINT16, BASE_DEC, 0, 0x0004,
3858 { &hf_fp_radio_interface_parameter_update_flag[3],
3859 { "RL sets indicator valid",
3860 "fp.radio-interface_param.rl-sets-indicator-valid", FT_UINT16, BASE_DEC, 0, 0x0020,
3864 { &hf_fp_radio_interface_parameter_update_flag[4],
3865 { "MAX_UE_TX_POW valid",
3866 "fp.radio-interface-param.max-ue-tx-pow-valid", FT_UINT16, BASE_DEC, 0, 0x0040,
3867 "MAX UE TX POW valid", HFILL
3872 "fp.dpc-mode", FT_UINT8, BASE_DEC, NULL, 0x20,
3873 "DPC Mode to be applied in the uplink", HFILL
3878 "fp.tpc-po", FT_UINT8, BASE_DEC, NULL, 0x1f,
3882 { &hf_fp_multiple_rl_set_indicator,
3883 { "Multiple RL sets indicator",
3884 "fp.multiple-rl-sets-indicator", FT_UINT8, BASE_DEC, NULL, 0x80,
3888 { &hf_fp_max_ue_tx_pow,
3890 "fp.max-ue-tx-pow", FT_INT8, BASE_DEC, NULL, 0x0,
3891 "Max UE TX POW (dBm)", HFILL
3894 { &hf_fp_congestion_status,
3895 { "Congestion Status",
3896 "fp.congestion-status", FT_UINT8, BASE_DEC, VALS(congestion_status_vals), 0x0,
3900 { &hf_fp_e_rucch_present,
3901 { "E-RUCCH Present",
3902 "fp.erucch-present", FT_UINT8, BASE_DEC, NULL, 0x0,
3906 { &hf_fp_extended_bits_present,
3907 { "Extended Bits Present",
3908 "fp.extended-bits-present", FT_UINT8, BASE_DEC, NULL, 0x0,
3912 { &hf_fp_extended_bits,
3914 "fp.extended-bits", FT_UINT8, BASE_HEX, NULL, 0x0,
3918 { &hf_fp_spare_extension,
3919 { "Spare Extension",
3920 "fp.spare-extension", FT_NONE, BASE_NONE, NULL, 0x0,
3928 static gint *ett[] =
3933 &ett_fp_edch_subframe_header,
3934 &ett_fp_edch_subframe,
3935 &ett_fp_hsdsch_new_ie_flags,
3936 &ett_fp_rach_new_ie_flags,
3937 &ett_fp_hsdsch_pdu_block_header
3940 /* Register protocol. */
3941 proto_fp = proto_register_protocol("FP", "FP", "fp");
3942 proto_register_field_array(proto_fp, hf, array_length(hf));
3943 proto_register_subtree_array(ett, array_length(ett));
3945 /* Allow other dissectors to find this one by name. */
3946 register_dissector("fp", dissect_fp, proto_fp);
3950 void proto_reg_handoff_fp(void)
3952 mac_fdd_rach_handle = find_dissector("mac.fdd.rach");
3953 mac_fdd_fach_handle = find_dissector("mac.fdd.fach");
3954 mac_fdd_pch_handle = find_dissector("mac.fdd.pch");
3955 mac_fdd_dch_handle = find_dissector("mac.fdd.dch");
3956 mac_fdd_edch_handle = find_dissector("mac.fdd.edch");
3957 mac_fdd_hsdsch_handle = find_dissector("mac.fdd.hsdsch");
3959 heur_dissector_add("udp", heur_dissect_fp, proto_fp);