epan/dissectors/pidl/samr/samr.cnf cnf_dissect_lsa_BinaryString => lsarpc_dissect_str...
[wireshark-sm.git] / epan / dissectors / packet-umts_fp.c
blob96f6a99f390e1fb74ac6e59c5dfc80d78135d36f
1 /* packet-umts_fp.c
2 * Routines for UMTS FP disassembly
4 * Martin Mathieson
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * SPDX-License-Identifier: GPL-2.0-or-later
13 #include "config.h"
15 #include <epan/packet.h>
16 #include <epan/expert.h>
17 #include <epan/prefs.h>
18 #include <epan/conversation.h>
19 #include <epan/proto_data.h>
20 #include <epan/tfs.h>
22 #include <wsutil/array.h>
23 #include <wsutil/crc7.h> /* For FP data header and control frame CRC. */
24 #include <wsutil/crc16-plain.h> /* For FP Payload CRC. */
25 #include <wsutil/crc11.h> /* For FP EDCH header CRC. */
26 #include <wsutil/pint.h>
28 #include "packet-umts_fp.h"
29 #include "packet-nbap.h"
30 #include "packet-rrc.h"
32 /* The Frame Protocol (FP) is described in:
33 * 3GPP TS 25.427 (for dedicated channels)
34 * 3GPP TS 25.435 (for common/shared channels)
36 * TODO:
37 * - IUR interface-specific formats
38 * - do CRC verification before further parsing
39 * - Set the logical channel properly for non multiplexed, channels
40 * for channels that doesn't have the C/T field! This should be based
41 * on the RRC message RadioBearerSetup.
42 * - E-DCH T2 heuristic dissector
44 void proto_register_fp(void);
45 void proto_reg_handoff_fp(void);
47 /* Initialize the protocol and registered fields. */
49 int proto_fp;
50 extern int proto_umts_mac;
51 extern int proto_umts_rlc;
53 static int hf_fp_release;
54 static int hf_fp_release_version;
55 static int hf_fp_release_year;
56 static int hf_fp_release_month;
57 static int hf_fp_channel_type;
58 static int hf_fp_division;
59 static int hf_fp_direction;
60 static int hf_fp_ddi_config;
61 static int hf_fp_ddi_config_ddi;
62 static int hf_fp_ddi_config_macd_pdu_size;
64 static int hf_fp_header_crc;
65 static int hf_fp_ft;
66 static int hf_fp_cfn;
67 static int hf_fp_pch_cfn;
68 static int hf_fp_pch_toa;
69 static int hf_fp_cfn_control;
70 static int hf_fp_toa;
71 static int hf_fp_tfi;
72 static int hf_fp_usch_tfi;
73 static int hf_fp_cpch_tfi;
74 static int hf_fp_propagation_delay;
75 static int hf_fp_tb;
76 static int hf_fp_chan_zero_tbs;
77 static int hf_fp_received_sync_ul_timing_deviation;
78 static int hf_fp_pch_pi;
79 static int hf_fp_pch_tfi;
80 static int hf_fp_fach_tfi;
81 static int hf_fp_transmit_power_level;
82 static int hf_fp_paging_indication_bitmap;
83 static int hf_fp_relevant_paging_indication_bitmap;
84 static int hf_fp_pdsch_set_id;
85 static int hf_fp_rx_timing_deviation;
86 static int hf_fp_dch_e_rucch_flag;
87 static int hf_fp_dch_control_frame_type;
88 static int hf_fp_dch_rx_timing_deviation;
89 static int hf_fp_quality_estimate;
90 static int hf_fp_payload_crc;
91 static int hf_fp_payload_crc_status;
92 static int hf_fp_edch_header_crc;
93 static int hf_fp_edch_fsn;
94 static int hf_fp_edch_subframe;
95 static int hf_fp_edch_number_of_subframes;
96 static int hf_fp_edch_harq_retransmissions;
97 static int hf_fp_edch_subframe_number;
98 static int hf_fp_edch_number_of_mac_es_pdus;
99 static int hf_fp_edch_ddi;
100 static int hf_fp_edch_subframe_header;
101 static int hf_fp_edch_number_of_mac_d_pdus;
102 static int hf_fp_edch_pdu_padding;
103 static int hf_fp_edch_tsn;
104 static int hf_fp_edch_mac_es_pdu;
106 static int hf_fp_edch_user_buffer_size;
107 static int hf_fp_edch_no_macid_sdus;
108 static int hf_fp_edch_number_of_mac_is_pdus;
109 static int hf_fp_edch_mac_is_pdu;
111 static int hf_fp_edch_e_rnti;
112 static int hf_fp_edch_macis_descriptors;
113 static int hf_fp_edch_macis_lchid;
114 static int hf_fp_edch_macis_length;
115 static int hf_fp_edch_macis_flag;
116 static int hf_fp_edch_entity;
118 static int hf_fp_frame_seq_nr;
119 static int hf_fp_hsdsch_pdu_block_header;
120 /* static int hf_fp_hsdsch_pdu_block; */
121 static int hf_fp_flush;
122 static int hf_fp_fsn_drt_reset;
123 static int hf_fp_drt_indicator;
124 static int hf_fp_fach_indicator;
125 static int hf_fp_total_pdu_blocks;
126 static int hf_fp_drt;
127 static int hf_fp_hrnti;
128 static int hf_fp_rach_measurement_result;
129 static int hf_fp_lchid;
130 static int hf_fp_pdu_length_in_block;
131 static int hf_fp_pdus_in_block;
132 static int hf_fp_cmch_pi;
133 static int hf_fp_user_buffer_size;
134 static int hf_fp_hsdsch_credits;
135 static int hf_fp_hsdsch_max_macd_pdu_len;
136 static int hf_fp_hsdsch_max_macdc_pdu_len;
137 static int hf_fp_hsdsch_interval;
138 static int hf_fp_hsdsch_calculated_rate;
139 static int hf_fp_hsdsch_unlimited_rate;
140 static int hf_fp_hsdsch_repetition_period;
141 static int hf_fp_hsdsch_data_padding;
142 static int hf_fp_hsdsch_new_ie_flags;
143 static int hf_fp_hsdsch_new_ie_flag[8];
144 static int hf_fp_hsdsch_drt;
145 static int hf_fp_hsdsch_entity;
146 static int hf_fp_hsdsch_physical_layer_category;
147 static int hf_fp_timing_advance;
148 static int hf_fp_num_of_pdu;
149 static int hf_fp_mac_d_pdu_len;
150 static int hf_fp_mac_d_pdu;
151 static int hf_fp_data;
152 static int hf_fp_crcis;
153 static int hf_fp_crci[8];
154 static int hf_fp_common_control_frame_type;
155 static int hf_fp_t1;
156 static int hf_fp_t2;
157 static int hf_fp_t3;
158 static int hf_fp_ul_sir_target;
159 static int hf_fp_pusch_set_id;
160 static int hf_fp_activation_cfn;
161 static int hf_fp_duration;
162 static int hf_fp_power_offset;
163 static int hf_fp_code_number;
164 static int hf_fp_spreading_factor;
165 static int hf_fp_mc_info;
167 static int hf_fp_rach_new_ie_flags;
168 static int hf_fp_rach_new_ie_flag_unused[7];
169 static int hf_fp_rach_ext_propagation_delay_present;
170 static int hf_fp_rach_cell_portion_id_present;
171 static int hf_fp_rach_angle_of_arrival_present;
172 static int hf_fp_rach_ext_rx_sync_ul_timing_deviation_present;
173 static int hf_fp_rach_ext_rx_timing_deviation_present;
175 static int hf_fp_cell_portion_id;
176 static int hf_fp_ext_propagation_delay;
177 static int hf_fp_angle_of_arrival;
178 static int hf_fp_ext_received_sync_ul_timing_deviation;
180 static int hf_fp_radio_interface_parameter_update_flag[5];
181 static int hf_fp_dpc_mode;
182 static int hf_fp_tpc_po;
183 static int hf_fp_multiple_rl_set_indicator;
184 static int hf_fp_max_ue_tx_pow;
185 static int hf_fp_congestion_status;
186 static int hf_fp_e_rucch_present;
187 static int hf_fp_extended_bits_present;
188 static int hf_fp_extended_bits;
189 static int hf_fp_spare_extension;
190 static int hf_fp_ul_setup_frame;
191 static int hf_fp_dl_setup_frame;
192 static int hf_fp_relevant_pi_frame;
194 /* Subtrees. */
195 static int ett_fp;
196 static int ett_fp_release;
197 static int ett_fp_data;
198 static int ett_fp_crcis;
199 static int ett_fp_ddi_config;
200 static int ett_fp_edch_subframe_header;
201 static int ett_fp_edch_subframe;
202 static int ett_fp_edch_maces;
203 static int ett_fp_edch_macis_descriptors;
204 static int ett_fp_hsdsch_new_ie_flags;
205 static int ett_fp_rach_new_ie_flags;
206 static int ett_fp_hsdsch_pdu_block_header;
207 static int ett_fp_pch_relevant_pi;
209 static expert_field ei_fp_hsdsch_common_experimental_support;
210 static expert_field ei_fp_hsdsch_common_t3_not_implemented;
211 static expert_field ei_fp_channel_type_unknown;
212 static expert_field ei_fp_ddi_not_defined;
213 static expert_field ei_fp_stop_hsdpa_transmission;
214 static expert_field ei_fp_hsdsch_entity_not_specified;
215 static expert_field ei_fp_expecting_tdd;
216 static expert_field ei_fp_bad_payload_checksum;
217 static expert_field ei_fp_e_rnti_t2_edch_frames;
218 static expert_field ei_fp_crci_no_subdissector;
219 static expert_field ei_fp_timing_adjustment_reported;
220 static expert_field ei_fp_mac_is_sdus_miscount;
221 static expert_field ei_fp_maybe_srb;
222 static expert_field ei_fp_transport_channel_type_unknown;
223 static expert_field ei_fp_pch_lost_relevant_pi_frame;
224 static expert_field ei_fp_unable_to_locate_ddi_entry;
225 static expert_field ei_fp_e_rnti_first_entry;
226 static expert_field ei_fp_bad_header_checksum;
227 static expert_field ei_fp_crci_error_bit_set_for_tb;
228 static expert_field ei_fp_spare_extension;
229 static expert_field ei_fp_no_per_frame_info;
230 static expert_field ei_fp_no_per_conv_channel_info;
231 static expert_field ei_fp_invalid_frame_count;
233 static dissector_handle_t rlc_bcch_handle;
234 static dissector_handle_t mac_fdd_dch_handle;
235 static dissector_handle_t mac_fdd_rach_handle;
236 static dissector_handle_t mac_fdd_fach_handle;
237 static dissector_handle_t mac_fdd_pch_handle;
238 static dissector_handle_t mac_fdd_edch_handle;
239 static dissector_handle_t mac_fdd_edch_type2_handle;
240 static dissector_handle_t mac_fdd_hsdsch_handle;
241 static dissector_handle_t fp_handle;
242 static dissector_handle_t fp_aal2_handle;
245 static proto_tree *top_level_tree;
247 /* Variables used for preferences */
248 static bool preferences_call_mac_dissectors = true;
249 static bool preferences_show_release_info = true;
250 static bool preferences_payload_checksum = true;
251 static bool preferences_header_checksum = true;
252 static bool preferences_track_paging_indications = true;
254 /* E-DCH (T1) channel header information */
255 struct edch_t1_subframe_info
257 uint8_t subframe_number;
258 uint8_t number_of_mac_es_pdus;
259 uint8_t ddi[64];
260 uint16_t number_of_mac_d_pdus[64];
263 /* E-DCH (T2) channel header information */
264 struct edch_t2_subframe_info
266 uint8_t subframe_number;
267 uint8_t number_of_mac_is_pdus;
268 uint8_t number_of_mac_is_sdus[16];
269 uint8_t mac_is_lchid[16][16];
270 uint16_t mac_is_length[16][16];
274 static const value_string channel_type_vals[] =
276 { CHANNEL_RACH_FDD, "RACH_FDD" },
277 { CHANNEL_RACH_TDD, "RACH_TDD" },
278 { CHANNEL_FACH_FDD, "FACH_FDD" },
279 { CHANNEL_FACH_TDD, "FACH_TDD" },
280 { CHANNEL_DSCH_FDD, "DSCH_FDD" },
281 { CHANNEL_DSCH_TDD, "DSCH_TDD" },
282 { CHANNEL_USCH_TDD_384, "USCH_TDD_384" },
283 { CHANNEL_USCH_TDD_128, "USCH_TDD_128" },
284 { CHANNEL_PCH, "PCH" },
285 { CHANNEL_CPCH, "CPCH" },
286 { CHANNEL_BCH, "BCH" },
287 { CHANNEL_DCH, "DCH" },
288 { CHANNEL_HSDSCH, "HSDSCH" },
289 { CHANNEL_IUR_CPCHF, "IUR CPCHF" },
290 { CHANNEL_IUR_FACH, "IUR FACH" },
291 { CHANNEL_IUR_DSCH, "IUR DSCH" },
292 { CHANNEL_EDCH, "EDCH" },
293 { CHANNEL_RACH_TDD_128, "RACH_TDD_128" },
294 { CHANNEL_HSDSCH_COMMON, "HSDSCH-COMMON" },
295 { CHANNEL_HSDSCH_COMMON_T3, "HSDSCH-COMMON-T3" },
296 { CHANNEL_EDCH_COMMON, "EDCH-COMMON"},
297 { 0, NULL }
300 static const value_string division_vals[] =
302 { Division_FDD, "FDD"},
303 { Division_TDD_384, "TDD-384"},
304 { Division_TDD_128, "TDD-128"},
305 { Division_TDD_768, "TDD-768"},
306 { 0, NULL }
309 /* Frame Type (ft) values */
310 #define FT_DATA 0
311 #define FT_CONTROL 1
313 static const value_string frame_type_vals[] = {
314 { FT_DATA, "Data" },
315 { FT_CONTROL, "Control" },
316 { 0, NULL }
319 static const value_string crci_vals[] = {
320 { 0, "Correct" },
321 { 1, "Not correct" },
322 { 0, NULL }
325 static const value_string paging_indication_vals[] = {
326 { 0, "no PI-bitmap in payload" },
327 { 1, "PI-bitmap in payload" },
328 { 0, NULL }
331 static const value_string spreading_factor_vals[] = {
332 { 0, "4"},
333 { 1, "8"},
334 { 2, "16"},
335 { 3, "32"},
336 { 4, "64"},
337 { 5, "128"},
338 { 6, "256"},
339 { 0, NULL }
342 static const value_string congestion_status_vals[] = {
343 { 0, "No TNL congestion"},
344 { 1, "Reserved for future use"},
345 { 2, "TNL congestion - detected by delay build-up"},
346 { 3, "TNL congestion - detected by frame loss"},
347 { 0, NULL }
350 static const value_string e_rucch_flag_vals[] = {
351 { 0, "Conventional E-RUCCH reception" },
352 { 1, "TA Request reception" },
353 { 0, NULL }
356 static const value_string hsdshc_mac_entity_vals[] = {
357 { entity_not_specified, "Unspecified (assume MAC-hs)" },
358 { hs, "MAC-hs" },
359 { ehs, "MAC-ehs" },
360 { 0, NULL }
363 static const value_string edch_mac_entity_vals[] = {
364 { 0, "MAC-e/es" },
365 { 1, "MAC-i/is" },
366 { 0, NULL }
369 static const value_string lchid_vals[] = {
370 { 0, "Logical Channel 1" },
371 { 1, "Logical Channel 2" },
372 { 2, "Logical Channel 3" },
373 { 3, "Logical Channel 4" },
374 { 4, "Logical Channel 5" },
375 { 5, "Logical Channel 6" },
376 { 6, "Logical Channel 7" },
377 { 7, "Logical Channel 8" },
378 { 8, "Logical Channel 9" },
379 { 9, "Logical Channel 10" },
380 { 10, "Logical Channel 11" },
381 { 11, "Logical Channel 12" },
382 { 12, "Logical Channel 13" },
383 { 13, "Logical Channel 14" },
384 { 14, "CCCH (SRB0)" },
385 { 15, "E-RNTI being included (FDD only)" },
386 { 0, NULL }
389 /* Dedicated control types */
390 #define DCH_OUTER_LOOP_POWER_CONTROL 1
391 #define DCH_TIMING_ADJUSTMENT 2
392 #define DCH_DL_SYNCHRONISATION 3
393 #define DCH_UL_SYNCHRONISATION 4
395 #define DCH_DL_NODE_SYNCHRONISATION 6
396 #define DCH_UL_NODE_SYNCHRONISATION 7
397 #define DCH_RX_TIMING_DEVIATION 8
398 #define DCH_RADIO_INTERFACE_PARAMETER_UPDATE 9
399 #define DCH_TIMING_ADVANCE 10
400 #define DCH_TNL_CONGESTION_INDICATION 11
402 static const value_string dch_control_frame_type_vals[] = {
403 { DCH_OUTER_LOOP_POWER_CONTROL, "OUTER LOOP POWER CONTROL" },
404 { DCH_TIMING_ADJUSTMENT, "TIMING ADJUSTMENT" },
405 { DCH_DL_SYNCHRONISATION, "DL SYNCHRONISATION" },
406 { DCH_UL_SYNCHRONISATION, "UL SYNCHRONISATION" },
407 { 5, "Reserved Value" },
408 { DCH_DL_NODE_SYNCHRONISATION, "DL NODE SYNCHRONISATION" },
409 { DCH_UL_NODE_SYNCHRONISATION, "UL NODE SYNCHRONISATION" },
410 { DCH_RX_TIMING_DEVIATION, "RX TIMING DEVIATION" },
411 { DCH_RADIO_INTERFACE_PARAMETER_UPDATE, "RADIO INTERFACE PARAMETER UPDATE" },
412 { DCH_TIMING_ADVANCE, "TIMING ADVANCE" },
413 { DCH_TNL_CONGESTION_INDICATION, "TNL CONGESTION INDICATION" },
414 { 0, NULL }
418 /* Common channel control types */
419 #define COMMON_OUTER_LOOP_POWER_CONTROL 1
420 #define COMMON_TIMING_ADJUSTMENT 2
421 #define COMMON_DL_SYNCHRONISATION 3
422 #define COMMON_UL_SYNCHRONISATION 4
424 #define COMMON_DL_NODE_SYNCHRONISATION 6
425 #define COMMON_UL_NODE_SYNCHRONISATION 7
426 #define COMMON_DYNAMIC_PUSCH_ASSIGNMENT 8
427 #define COMMON_TIMING_ADVANCE 9
428 #define COMMON_HS_DSCH_Capacity_Request 10
429 #define COMMON_HS_DSCH_Capacity_Allocation 11
430 #define COMMON_HS_DSCH_Capacity_Allocation_Type_2 12
432 static const value_string common_control_frame_type_vals[] = {
433 { COMMON_OUTER_LOOP_POWER_CONTROL, "OUTER LOOP POWER CONTROL" },
434 { COMMON_TIMING_ADJUSTMENT, "TIMING ADJUSTMENT" },
435 { COMMON_DL_SYNCHRONISATION, "DL SYNCHRONISATION" },
436 { COMMON_UL_SYNCHRONISATION, "UL SYNCHRONISATION" },
437 { 5, "Reserved Value" },
438 { COMMON_DL_NODE_SYNCHRONISATION, "DL NODE SYNCHRONISATION" },
439 { COMMON_UL_NODE_SYNCHRONISATION, "UL NODE SYNCHRONISATION" },
440 { COMMON_DYNAMIC_PUSCH_ASSIGNMENT, "DYNAMIC PUSCH ASSIGNMENT" },
441 { COMMON_TIMING_ADVANCE, "TIMING ADVANCE" },
442 { COMMON_HS_DSCH_Capacity_Request, "HS-DSCH Capacity Request" },
443 { COMMON_HS_DSCH_Capacity_Allocation, "HS-DSCH Capacity Allocation" },
444 { COMMON_HS_DSCH_Capacity_Allocation_Type_2, "HS-DSCH Capacity Allocation Type 2" },
445 { 0, NULL }
448 /* 0 to 7*/
449 static const uint8_t hsdsch_macdflow_id_rlc_map[] = {
450 RLC_UM, /*0 SRB */
451 RLC_AM, /*1 Interactive PS*/
452 RLC_AM, /*2 Interactive PS*/
453 RLC_UNKNOWN_MODE, /*3 ???*/
454 RLC_AM, /*4 Streaming PS*/
455 RLC_UNKNOWN_MODE,
456 RLC_UNKNOWN_MODE,
457 RLC_UNKNOWN_MODE
460 /* Mapping hsdsch MACd-FlowId to MAC_CONTENT, basically flowid = 1 (0) => SRB*/
461 /* 1 to 8*/
462 static const uint8_t hsdsch_macdflow_id_mac_content_map[] = {
463 MAC_CONTENT_DCCH, /*1 SRB */
464 MAC_CONTENT_PS_DTCH, /*2 Interactive PS*/
465 MAC_CONTENT_PS_DTCH, /*3 Interactive PS*/
466 RLC_UNKNOWN_MODE, /*4 ???*/
467 MAC_CONTENT_PS_DTCH, /*5 Streaming PS*/
468 RLC_UNKNOWN_MODE,
469 RLC_UNKNOWN_MODE,
470 RLC_UNKNOWN_MODE
473 /* Make fake logical channel id's based on MACdFlow-ID's,
474 * XXXX Bug 12121 expanded the number of entries to 8(+2),
475 * not at all sure what the proper value should be 0xfF?
477 static const uint8_t fake_lchid_macd_flow[] = {1,9,14,11,0,12,0,0};
479 /* Dissect message parts */
480 static int dissect_tb_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
481 int offset, struct fp_info *p_fp_info,
482 dissector_handle_t *data_handle,
483 void *data);
485 static int dissect_macd_pdu_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
486 int offset, uint16_t length, uint16_t number_of_pdus, struct fp_info *p_fp_info,
487 void *data);
488 static int dissect_macd_pdu_data_type_2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
489 int offset, uint16_t length, uint16_t number_of_pdus, struct fp_info * fpi,
490 void *data);
492 static int dissect_crci_bits(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
493 fp_info *p_fp_info, int offset);
494 static void dissect_spare_extension_and_crc(tvbuff_t *tvb, packet_info *pinfo,
495 proto_tree *tree, uint8_t dch_crc_present,
496 int offset, unsigned header_length);
497 /* Dissect common control messages */
498 static int dissect_common_outer_loop_power_control(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb,
499 int offset, struct fp_info *p_fp_info);
500 static int dissect_common_timing_adjustment(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb,
501 int offset, struct fp_info *p_fp_info);
502 static int dissect_common_dl_node_synchronisation(packet_info *pinfo, proto_tree *tree,
503 tvbuff_t *tvb, int offset);
504 static int dissect_common_ul_node_synchronisation(packet_info *pinfo, proto_tree *tree,
505 tvbuff_t *tvb, int offset);
506 static int dissect_common_dl_synchronisation(packet_info *pinfo, proto_tree *tree,
507 tvbuff_t *tvb, int offset,
508 struct fp_info *p_fp_info);
509 static int dissect_common_ul_synchronisation(packet_info *pinfo, proto_tree *tree,
510 tvbuff_t *tvb, int offset,
511 struct fp_info *p_fp_info);
512 static int dissect_common_timing_advance(packet_info *pinfo, proto_tree *tree,
513 tvbuff_t *tvb, int offset);
514 static int dissect_hsdpa_capacity_request(packet_info *pinfo, proto_tree *tree,
515 tvbuff_t *tvb, int offset);
516 static int dissect_hsdpa_capacity_allocation(packet_info *pinfo, proto_tree *tree,
517 tvbuff_t *tvb, int offset,
518 struct fp_info *p_fp_info);
519 static int dissect_hsdpa_capacity_allocation_type_2(packet_info *pinfo, proto_tree *tree,
520 tvbuff_t *tvb, int offset);
521 static void dissect_common_control(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
522 int offset, struct fp_info *p_fp_info);
523 static int dissect_common_dynamic_pusch_assignment(packet_info *pinfo, proto_tree *tree,
524 tvbuff_t *tvb, int offset);
526 /* Dissect common channel types */
527 static void dissect_rach_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
528 int offset, struct fp_info *p_fp_info,
529 void *data);
530 static void dissect_fach_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
531 int offset, struct fp_info *p_fp_info,
532 void *data);
533 static void dissect_dsch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
534 int offset, struct fp_info *p_fp_info);
535 static void dissect_usch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
536 int offset, struct fp_info *p_fp_info);
537 static void dissect_pch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
538 int offset, struct fp_info *p_fp_info,
539 void *data);
540 static void dissect_cpch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
541 int offset, struct fp_info *p_fp_info);
542 static void dissect_bch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
543 int offset, struct fp_info *p_fp_info);
544 static void dissect_iur_dsch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
545 int offset, struct fp_info *p_fp_info);
546 static void dissect_hsdsch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
547 int offset, struct fp_info *p_fp_info,
548 void *data);
549 static void dissect_hsdsch_type_2_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
550 int offset, struct fp_info *p_fp_info,
551 void *data);
552 static void dissect_hsdsch_common_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
553 int offset,
554 struct fp_info *p_fp_info,
555 void *data);
557 /* Dissect DCH control messages */
558 static int dissect_dch_timing_adjustment(proto_tree *tree, packet_info *pinfo,
559 tvbuff_t *tvb, int offset);
560 static int dissect_dch_rx_timing_deviation(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset,
561 struct fp_info *p_fp_info);
562 static int dissect_dch_dl_synchronisation(proto_tree *tree, packet_info *pinfo,
563 tvbuff_t *tvb, int offset);
564 static int dissect_dch_ul_synchronisation(proto_tree *tree, packet_info *pinfo,
565 tvbuff_t *tvb, int offset);
566 static int dissect_dch_outer_loop_power_control(proto_tree *tree, packet_info *pinfo,
567 tvbuff_t *tvb, int offset);
568 static int dissect_dch_dl_node_synchronisation(proto_tree *tree, packet_info *pinfo,
569 tvbuff_t *tvb, int offset);
570 static int dissect_dch_ul_node_synchronisation(proto_tree *tree, packet_info *pinfo,
571 tvbuff_t *tvb, int offset);
572 static int dissect_dch_radio_interface_parameter_update(proto_tree *tree, packet_info *pinfo,
573 tvbuff_t *tvb, int offset);
574 static int dissect_dch_timing_advance(proto_tree *tree, packet_info *pinfo,
575 tvbuff_t *tvb, int offset, struct fp_info *p_fp_info);
576 static int dissect_dch_tnl_congestion_indication(proto_tree *tree, packet_info *pinfo,
577 tvbuff_t *tvb, int offset);
580 static void dissect_dch_control_frame(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb,
581 int offset, struct fp_info *p_fp_info);
584 /* Dissect a DCH channel */
585 static void dissect_dch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
586 int offset, struct fp_info *p_fp_info,
587 void *data);
589 /* Dissect dedicated channels */
590 static void dissect_e_dch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
591 int offset, struct fp_info *p_fp_info,
592 bool is_common,
593 void *data);
595 static void dissect_e_dch_t2_or_common_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
596 int offset, struct fp_info *p_fp_info,
597 int number_of_subframes,
598 bool is_common,
599 uint16_t header_crc,
600 proto_item * header_crc_pi,
601 void *data);
603 /* Main dissection function */
604 static int dissect_fp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data);
607 * CRNC sends data downlink on uplink parameters.
609 void
610 set_umts_fp_conv_data(conversation_t *conversation, umts_fp_conversation_info_t *umts_fp_conversation_info)
613 if (conversation == NULL) {
614 return;
617 conversation_add_proto_data(conversation, proto_fp, umts_fp_conversation_info);
621 static int
622 get_tb_count(struct fp_info *p_fp_info)
624 int chan, tb_count = 0;
625 for (chan = 0; chan < p_fp_info->num_chans; chan++) {
626 tb_count += p_fp_info->chan_num_tbs[chan];
628 return tb_count;
631 static bool verify_control_frame_crc(tvbuff_t * tvb, packet_info * pinfo, proto_item * pi, uint16_t frame_crc)
633 uint8_t crc = 0;
634 uint8_t * data = NULL;
635 /* Get data. */
636 data = (uint8_t *)tvb_memdup(wmem_packet_scope(), tvb, 0, tvb_reported_length(tvb));
637 /* Include only FT flag bit in CRC calculation. */
638 data[0] = data[0] & 1;
639 /* Calculate crc7 sum. */
640 crc = crc7update(0, data, tvb_reported_length(tvb));
641 crc = crc7finalize(crc); /* finalize crc */
642 if (frame_crc == crc) {
643 proto_item_append_text(pi, " [correct]");
644 return true;
645 } else {
646 proto_item_append_text(pi, " [incorrect, should be 0x%x]", crc);
647 expert_add_info(pinfo, pi, &ei_fp_bad_header_checksum);
648 return false;
651 static bool verify_header_crc(tvbuff_t * tvb, packet_info * pinfo, proto_item * pi, uint16_t header_crc, unsigned header_length)
653 uint8_t crc = 0;
654 uint8_t * data = NULL;
655 /* Get data of header with first byte removed. */
656 data = (uint8_t *)tvb_memdup(wmem_packet_scope(), tvb, 1, header_length-1);
657 /* Calculate crc7 sum. */
658 crc = crc7update(0, data, header_length-1);
659 crc = crc7finalize(crc); /* finalize crc */
660 if (header_crc == crc) {
661 proto_item_append_text(pi, " [correct]");
662 return true;
663 } else {
664 proto_item_append_text(pi, " [incorrect, should be 0x%x]", crc);
665 expert_add_info(pinfo, pi, &ei_fp_bad_header_checksum);
666 return false;
669 static bool verify_header_crc_edch(tvbuff_t * tvb, packet_info * pinfo, proto_item * pi, uint16_t header_crc, unsigned header_length)
671 uint16_t crc = 0;
672 uint8_t * data = NULL;
673 /* First create new subset of header with first byte removed. */
674 tvbuff_t * headtvb = tvb_new_subset_length(tvb, 1, header_length-1);
675 /* Get data of header with first byte removed. */
676 data = (uint8_t *)tvb_memdup(wmem_packet_scope(), headtvb, 0, header_length-1);
677 /* Remove first 4 bits of the remaining data which are Header CRC cont. */
678 data[0] = data[0] & 0x0f;
679 crc = crc11_307_noreflect_noxor(data, header_length-1);
680 if (header_crc == crc) {
681 proto_item_append_text(pi, " [correct]");
682 return true;
683 } else {
684 proto_item_append_text(pi, " [incorrect, should be 0x%x]", crc);
685 expert_add_info(pinfo, pi, &ei_fp_bad_header_checksum);
686 return false;
690 /* Dissect the TBs of a UL data frame*/
691 static int
692 dissect_tb_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
693 int offset, struct fp_info *p_fp_info,
694 dissector_handle_t *data_handle, void *data)
696 int chan, num_tbs = 0;
697 int bit_offset = 0;
698 int crci_bit_offset = (offset+1)<<3; /* Current offset + Quality estimate of 1 byte at the end*/
699 unsigned data_bits = 0;
700 uint8_t crci_bit = 0;
701 proto_item *tree_ti = NULL;
702 proto_tree *data_tree = NULL;
703 bool dissected = false;
705 /* Add data subtree */
706 tree_ti = proto_tree_add_item(tree, hf_fp_data, tvb, offset, -1, ENC_NA);
707 proto_item_set_text(tree_ti, "TB data for %u chans", p_fp_info->num_chans);
708 data_tree = proto_item_add_subtree(tree_ti, ett_fp_data);
710 if (p_fp_info->num_chans >= MAX_MAC_FRAMES) {
711 expert_add_info_format(pinfo, data_tree, &ei_fp_invalid_frame_count, "Invalid Number of channels (max is %u)", MAX_MAC_FRAMES);
712 return offset;
715 /* Calculate offset to CRCI bits */
717 if (p_fp_info->is_uplink) {
718 for (chan=0; chan < p_fp_info->num_chans; chan++) {
719 int n;
720 for (n=0; n < p_fp_info->chan_num_tbs[chan]; n++) {
721 /* Advance bit offset */
722 crci_bit_offset += p_fp_info->chan_tf_size[chan];
723 /* Pad out to next byte */
724 if (crci_bit_offset % 8) {
725 crci_bit_offset += (8 - (crci_bit_offset % 8));
730 /* Now for the TB data */
731 for (chan=0; chan < p_fp_info->num_chans; chan++) {
732 int n;
733 p_fp_info->cur_chan = chan; /*Set current channel?*/
734 /* Clearly show channels with no TBs */
735 if (p_fp_info->chan_num_tbs[chan] == 0) {
736 proto_item *no_tb_ti = proto_tree_add_uint(data_tree, hf_fp_chan_zero_tbs, tvb,
737 offset+(bit_offset/8),
738 0, chan+1);
739 proto_item_append_text(no_tb_ti, " (of size %d)",
740 p_fp_info->chan_tf_size[chan]);
741 proto_item_set_generated(no_tb_ti);
744 /* Show TBs from non-empty channels */
745 for (n=0; n < p_fp_info->chan_num_tbs[chan]; n++) {
747 proto_item *ti;
748 p_fp_info->cur_tb = chan; /*Set current transport block?*/
749 if (data_tree) {
750 ti = proto_tree_add_item(data_tree, hf_fp_tb, tvb,
751 offset + (bit_offset/8),
752 ((bit_offset % 8) + p_fp_info->chan_tf_size[chan] + 7) / 8,
753 ENC_NA);
754 proto_item_set_text(ti, "TB (chan %u, tb %u, %u bits)",
755 chan+1, n+1, p_fp_info->chan_tf_size[chan]);
758 if (preferences_call_mac_dissectors && data_handle &&
759 (p_fp_info->chan_tf_size[chan] > 0)) {
760 tvbuff_t *next_tvb;
761 proto_item *item;
762 /* If this is DL we should not care about crci bits (since they don't exists)*/
763 if (p_fp_info->is_uplink) {
766 if ( p_fp_info->channel == CHANNEL_RACH_FDD) { /*In RACH we don't have any QE field, hence go back 8 bits.*/
767 crci_bit = tvb_get_bits8(tvb, crci_bit_offset+n-8, 1);
768 item = proto_tree_add_item(data_tree, hf_fp_crci[n%8], tvb, (crci_bit_offset+n-8)/8, 1, ENC_BIG_ENDIAN);
769 proto_item_set_generated(item);
770 } else {
771 crci_bit = tvb_get_bits8(tvb, crci_bit_offset+n, 1);
772 item = proto_tree_add_item(data_tree, hf_fp_crci[n%8], tvb, (crci_bit_offset+n)/8, 1, ENC_BIG_ENDIAN);
773 proto_item_set_generated(item);
777 if (crci_bit == 0 || !p_fp_info->is_uplink) {
778 next_tvb = tvb_new_subset_length(tvb, offset + bit_offset/8,
779 ((bit_offset % 8) + p_fp_info->chan_tf_size[chan] + 7) / 8);
782 /****************/
783 /* TODO: maybe this decision can be based only on info available in fp_info */
784 call_dissector_with_data(*data_handle, next_tvb, pinfo, top_level_tree, data);
785 dissected = true;
786 } else {
787 proto_tree_add_expert(tree, pinfo, &ei_fp_crci_no_subdissector, tvb, offset + bit_offset/8,
788 ((bit_offset % 8) + p_fp_info->chan_tf_size[chan] + 7) / 8);
792 num_tbs++;
794 /* Advance bit offset */
795 bit_offset += p_fp_info->chan_tf_size[chan];
796 data_bits += p_fp_info->chan_tf_size[chan];
798 /* Pad out to next byte */
799 if (bit_offset % 8) {
800 bit_offset += (8 - (bit_offset % 8));
805 if (dissected == false) {
806 col_append_fstr(pinfo->cinfo, COL_INFO, "(%u bits in %u tbs)",
807 data_bits, num_tbs);
810 /* Data tree should cover entire length */
811 if (data_tree) {
812 proto_item_set_len(tree_ti, bit_offset/8);
813 proto_item_append_text(tree_ti, " (%u bits in %u tbs)", data_bits, num_tbs);
816 /* Move offset past TBs (we know it's already padded out to next byte) */
817 offset += (bit_offset / 8);
819 return offset;
823 /* Dissect the MAC-d PDUs of an HS-DSCH (type 1) frame.
824 Length is in bits, and payload is offset by 4 bits of padding */
825 static int
826 dissect_macd_pdu_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
827 int offset, uint16_t length, uint16_t number_of_pdus,
828 struct fp_info *p_fp_info, void *data)
830 int pdu;
831 int bit_offset = 0;
832 proto_item *pdus_ti = NULL;
833 proto_tree *data_tree = NULL;
834 bool dissected = false;
836 /* Add data subtree */
837 pdus_ti = proto_tree_add_item(tree, hf_fp_data, tvb, offset, -1, ENC_NA);
838 proto_item_set_text(pdus_ti, "%u MAC-d PDUs of %u bits", number_of_pdus, length);
839 data_tree = proto_item_add_subtree(pdus_ti, ett_fp_data);
840 if (number_of_pdus >= MAX_MAC_FRAMES) {
841 expert_add_info_format(pinfo, data_tree, &ei_fp_invalid_frame_count, "Invalid number_of_pdus (max is %u)", MAX_MAC_FRAMES);
842 return offset;
845 /* Now for the PDUs */
846 for (pdu=0; pdu < number_of_pdus; pdu++) {
847 proto_item *pdu_ti;
849 if (data_tree) {
850 /* Show 4 bits padding at start of PDU */
851 proto_tree_add_item(data_tree, hf_fp_hsdsch_data_padding, tvb, offset+(bit_offset/8), 1, ENC_BIG_ENDIAN);
854 bit_offset += 4;
856 /* Data bytes! */
857 if (data_tree) {
858 pdu_ti = proto_tree_add_item(data_tree, hf_fp_mac_d_pdu, tvb,
859 offset + (bit_offset/8),
860 ((bit_offset % 8) + length + 7) / 8,
861 ENC_NA);
862 proto_item_set_text(pdu_ti, "MAC-d PDU (PDU %u)", pdu+1);
865 p_fp_info->cur_tb = pdu; /*Set TB (PDU) index correctly*/
866 if (preferences_call_mac_dissectors) {
867 tvbuff_t *next_tvb;
868 next_tvb = tvb_new_subset_length_caplen(tvb, offset + bit_offset/8,
869 ((bit_offset % 8) + length + 7)/8, -1);
870 call_dissector_with_data(mac_fdd_hsdsch_handle, next_tvb, pinfo, top_level_tree, data);
871 dissected = true;
874 /* Advance bit offset */
875 bit_offset += length;
877 /* Pad out to next byte */
878 if (bit_offset % 8) {
879 bit_offset += (8 - (bit_offset % 8));
883 /* Data tree should cover entire length */
884 proto_item_set_len(pdus_ti, bit_offset/8);
886 /* Move offset past PDUs (we know it's already padded out to next byte) */
887 offset += (bit_offset / 8);
889 /* Show summary in info column */
890 if (dissected == false) {
891 col_append_fstr(pinfo->cinfo, COL_INFO, " %u PDUs of %u bits",
892 number_of_pdus, length);
895 return offset;
899 /* Dissect the MAC-d PDUs of an HS-DSCH (type 2) frame.
900 Length is in bytes, and payload is byte-aligned (no padding) */
901 static int
902 dissect_macd_pdu_data_type_2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
903 int offset, uint16_t length, uint16_t number_of_pdus,
904 struct fp_info *fpi, void *data)
906 int pdu;
907 proto_item *pdus_ti = NULL;
908 proto_tree *data_tree = NULL;
909 int first_offset = offset;
910 bool dissected = false;
912 /* Add data subtree */
913 pdus_ti = proto_tree_add_item(tree, hf_fp_data, tvb, offset, -1, ENC_NA);
914 proto_item_set_text(pdus_ti, "%u MAC-d PDUs of %u bytes", number_of_pdus, length);
915 data_tree = proto_item_add_subtree(pdus_ti, ett_fp_data);
917 if (number_of_pdus >= MAX_MAC_FRAMES) {
918 expert_add_info_format(pinfo, data_tree, &ei_fp_invalid_frame_count, "Invalid number_of_pdus (max is %u)", MAX_MAC_FRAMES);
919 return offset;
922 /* Now for the PDUs */
923 for (pdu=0; pdu < number_of_pdus; pdu++) {
924 proto_item *pdu_ti;
926 /* Data bytes! */
927 if (data_tree) {
928 pdu_ti = proto_tree_add_item(data_tree, hf_fp_mac_d_pdu, tvb,
929 offset, length, ENC_NA);
930 proto_item_set_text(pdu_ti, "MAC-d PDU (PDU %u)", pdu+1);
934 if (preferences_call_mac_dissectors) {
936 tvbuff_t *next_tvb = tvb_new_subset_length(tvb, offset, length);
938 fpi->cur_tb = pdu; /*Set proper pdu index for MAC and higher layers*/
939 call_dissector_with_data(mac_fdd_hsdsch_handle, next_tvb, pinfo, top_level_tree, data);
940 dissected = true;
943 /* Advance offset */
944 offset += length;
947 /* Data tree should cover entire length */
948 proto_item_set_len(pdus_ti, offset-first_offset);
950 /* Show summary in info column */
951 if (!dissected) {
952 col_append_fstr(pinfo->cinfo, COL_INFO, " %u PDUs of %u bits",
953 number_of_pdus, length*8);
956 return offset;
959 /* Dissect CRCI bits (uplink) */
960 static int
961 dissect_crci_bits(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
962 fp_info *p_fp_info, int offset)
964 int n, num_tbs;
965 proto_item *ti = NULL;
966 proto_tree *crcis_tree = NULL;
967 unsigned errors = 0;
969 num_tbs = get_tb_count(p_fp_info);
972 /* Add CRCIs subtree */
973 if (tree) {
974 ti = proto_tree_add_item(tree, hf_fp_crcis, tvb, offset, (num_tbs+7)/8, ENC_NA);
975 proto_item_set_text(ti, "CRCI bits for %u tbs", num_tbs);
976 crcis_tree = proto_item_add_subtree(ti, ett_fp_crcis);
979 /* CRCIs */
980 for (n=0; n < num_tbs; n++) {
981 int bit = (tvb_get_uint8(tvb, offset+(n/8)) >> (7-(n%8))) & 0x01;
982 proto_tree_add_item(crcis_tree, hf_fp_crci[n%8], tvb, offset+(n/8),
983 1, ENC_BIG_ENDIAN);
985 if (bit == 1) {
986 errors++;
987 expert_add_info(pinfo, ti, &ei_fp_crci_error_bit_set_for_tb);
991 if (tree) {
992 /* Highlight range of bytes covered by indicator bits */
993 proto_item_set_len(ti, (num_tbs+7) / 8);
995 /* Show error count in root text */
996 proto_item_append_text(ti, " (%u errors)", errors);
999 offset += ((num_tbs+7) / 8);
1000 return offset;
1004 static void
1005 dissect_spare_extension_and_crc(tvbuff_t *tvb, packet_info *pinfo,
1006 proto_tree *tree, uint8_t dch_crc_present,
1007 int offset, unsigned header_length)
1009 int crc_size = 0;
1010 int remain = tvb_reported_length_remaining(tvb, offset);
1012 /* Payload CRC (optional) */
1013 if ((dch_crc_present == 1) || ((dch_crc_present == 2) && (remain >= 2))) {
1014 crc_size = 2;
1017 if (remain > crc_size) {
1018 proto_item *ti;
1019 ti = proto_tree_add_item(tree, hf_fp_spare_extension, tvb,
1020 offset, remain-crc_size, ENC_NA);
1021 proto_item_append_text(ti, " (%u octets)", remain-crc_size);
1022 expert_add_info_format(pinfo, ti, &ei_fp_spare_extension, "Spare Extension present (%u bytes)", remain-crc_size);
1023 offset += remain-crc_size;
1026 if (crc_size) {
1027 unsigned flags = PROTO_CHECKSUM_NO_FLAGS;
1028 uint16_t calc_crc = 0;
1029 if (preferences_payload_checksum) {
1030 flags = PROTO_CHECKSUM_VERIFY;
1031 if ((unsigned)offset > header_length) {
1032 uint8_t * data = (uint8_t *)tvb_memdup(wmem_packet_scope(), tvb, header_length, offset-header_length);
1033 calc_crc = crc16_8005_noreflect_noxor(data, offset-header_length);
1036 if ((unsigned)offset == header_length && remain == 0) {
1037 /* 3GPP TS 25.427 and TS 25.435: "The Payload CRC IE may
1038 * only be present if the frame contains payload" (even
1039 * if defined as present at the setup of the transport bearer.)
1040 * If there's room for the CRC and no payload, assume zero,
1041 * otherwise, assume it's absent.
1043 flags = PROTO_CHECKSUM_NOT_PRESENT;
1045 proto_tree_add_checksum(tree, tvb, offset,
1046 hf_fp_payload_crc, hf_fp_payload_crc_status,
1047 &ei_fp_bad_payload_checksum, pinfo, calc_crc,
1048 ENC_BIG_ENDIAN, flags);
1052 /***********************************************************/
1053 /* Common control message types */
1055 static int
1056 dissect_common_outer_loop_power_control(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb,
1057 int offset, struct fp_info *p_fp_info _U_)
1059 return dissect_dch_outer_loop_power_control(tree, pinfo, tvb, offset);
1063 static int
1064 dissect_common_timing_adjustment(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb,
1065 int offset, struct fp_info *p_fp_info)
1067 int32_t toa;
1068 proto_item *toa_ti;
1070 if (p_fp_info->channel != CHANNEL_PCH) {
1071 uint32_t cfn;
1073 /* CFN control */
1074 proto_tree_add_item_ret_uint(tree, hf_fp_cfn_control, tvb, offset, 1, ENC_BIG_ENDIAN, &cfn);
1075 offset++;
1077 /* ToA */
1078 toa = tvb_get_ntohis(tvb, offset);
1079 toa_ti = proto_tree_add_item(tree, hf_fp_toa, tvb, offset, 2, ENC_BIG_ENDIAN);
1080 offset += 2;
1082 col_append_fstr(pinfo->cinfo, COL_INFO, " CFN=%u, ToA=%d", cfn, toa);
1084 else {
1085 uint32_t cfn;
1087 /* PCH CFN is 12 bits */
1088 proto_tree_add_item_ret_uint(tree, hf_fp_pch_cfn, tvb, offset, 2, ENC_BIG_ENDIAN, &cfn);
1089 offset += 2;
1091 /* 4 bits of padding follow... */
1093 /* 20 bits of ToA (followed by 4 padding bits) */
1094 toa = ((int)(tvb_get_ntoh24(tvb, offset) << 8)) / 4096;
1095 toa_ti = proto_tree_add_int(tree, hf_fp_pch_toa, tvb, offset, 3, toa);
1096 offset += 3;
1098 col_append_fstr(pinfo->cinfo, COL_INFO, " CFN=%u, ToA=%d", cfn, toa);
1101 expert_add_info_format(pinfo, toa_ti, &ei_fp_timing_adjustment_reported, "Timing adjustment reported (%.3f ms)", ((float)(toa) / 8));
1103 return offset;
1106 static int
1107 dissect_common_dl_node_synchronisation(packet_info *pinfo, proto_tree *tree,
1108 tvbuff_t *tvb, int offset)
1110 /* T1 (3 bytes) */
1111 uint32_t encoded = tvb_get_ntoh24(tvb, offset);
1112 float t1 = encoded * (float)0.125;
1113 proto_tree_add_float_format_value(tree, hf_fp_t1, tvb, offset, 3, t1, "%.3f ms (%u)", t1, encoded);
1114 offset += 3;
1116 col_append_fstr(pinfo->cinfo, COL_INFO, " T1=%.3f", t1);
1118 return offset;
1121 static int
1122 dissect_common_ul_node_synchronisation(packet_info *pinfo, proto_tree *tree,
1123 tvbuff_t *tvb, int offset)
1125 uint32_t encoded;
1126 float t1, t2, t3;
1128 /* T1 (3 bytes) */
1129 encoded = tvb_get_ntoh24(tvb, offset);
1130 t1 = encoded * (float)0.125;
1131 proto_tree_add_float_format_value(tree, hf_fp_t1, tvb, offset, 3, t1, "%.3f ms (%u)", t1, encoded);
1132 offset += 3;
1134 /* T2 (3 bytes) */
1135 encoded = tvb_get_ntoh24(tvb, offset);
1136 t2 = encoded * (float)0.125;
1137 proto_tree_add_float_format_value(tree, hf_fp_t2, tvb, offset, 3, t2, "%.3f ms (%u)", t2, encoded);
1138 offset += 3;
1140 /* T3 (3 bytes) */
1141 encoded = tvb_get_ntoh24(tvb, offset);
1142 t3 = encoded * (float)0.125;
1143 proto_tree_add_float_format_value(tree, hf_fp_t3, tvb, offset, 3, t3, "%.3f ms (%u)", t3, encoded);
1144 offset += 3;
1146 col_append_fstr(pinfo->cinfo, COL_INFO, " T1=%.3f T2=%.3f, T3=%.3f",
1147 t1, t2, t3);
1149 return offset;
1152 static int
1153 dissect_common_dl_synchronisation(packet_info *pinfo, proto_tree *tree,
1154 tvbuff_t *tvb, int offset, struct fp_info *p_fp_info)
1156 uint32_t cfn;
1158 if (p_fp_info->channel != CHANNEL_PCH) {
1159 /* CFN control */
1160 proto_tree_add_item_ret_uint(tree, hf_fp_cfn_control, tvb, offset, 1, ENC_BIG_ENDIAN, &cfn);
1161 offset++;
1163 else {
1164 /* PCH CFN is 12 bits */
1165 proto_tree_add_item_ret_uint(tree, hf_fp_pch_cfn, tvb, offset, 2, ENC_BIG_ENDIAN, &cfn);
1167 /* 4 bits of padding follow... */
1168 offset += 2;
1171 col_append_fstr(pinfo->cinfo, COL_INFO, " CFN=%u", cfn);
1173 return offset;
1176 static int
1177 dissect_common_ul_synchronisation(packet_info *pinfo, proto_tree *tree,
1178 tvbuff_t *tvb, int offset, struct fp_info *p_fp_info)
1180 return dissect_common_timing_adjustment(pinfo, tree, tvb, offset, p_fp_info);
1183 static int
1184 dissect_common_timing_advance(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
1186 uint32_t cfn;
1187 uint16_t timing_advance;
1189 /* CFN control */
1190 proto_tree_add_item_ret_uint(tree, hf_fp_cfn_control, tvb, offset, 1, ENC_BIG_ENDIAN, &cfn);
1191 offset++;
1193 /* Timing Advance */
1194 timing_advance = (tvb_get_uint8(tvb, offset) & 0x3f) * 4;
1195 proto_tree_add_uint(tree, hf_fp_timing_advance, tvb, offset, 1, timing_advance);
1196 offset++;
1198 col_append_fstr(pinfo->cinfo, COL_INFO, " CFN = %u, TA = %u",
1199 cfn, timing_advance);
1201 return offset;
1204 static int
1205 dissect_hsdpa_capacity_request(packet_info *pinfo, proto_tree *tree,
1206 tvbuff_t *tvb, int offset)
1208 uint8_t priority;
1209 uint16_t user_buffer_size;
1211 /* CmCH-PI */
1212 priority = (tvb_get_uint8(tvb, offset) & 0x0f);
1213 proto_tree_add_item(tree, hf_fp_cmch_pi, tvb, offset, 1, ENC_BIG_ENDIAN);
1214 offset++;
1216 /* User buffer size */
1217 user_buffer_size = tvb_get_ntohs(tvb, offset);
1218 proto_tree_add_item(tree, hf_fp_user_buffer_size, tvb, offset, 2, ENC_BIG_ENDIAN);
1219 offset += 2;
1221 col_append_fstr(pinfo->cinfo, COL_INFO, " CmCH-PI=%u User-Buffer-Size=%u",
1222 priority, user_buffer_size);
1224 return offset;
1227 static int
1228 dissect_hsdpa_capacity_allocation(packet_info *pinfo, proto_tree *tree,
1229 tvbuff_t *tvb, int offset,
1230 struct fp_info *p_fp_info)
1232 proto_item *ti;
1233 proto_item *rate_ti;
1234 uint16_t max_pdu_length;
1235 uint8_t repetition_period;
1236 uint8_t interval;
1237 uint64_t credits;
1239 /* Congestion status (introduced sometime during R6...) */
1240 if ((p_fp_info->release == 6) || (p_fp_info->release == 7)) {
1241 proto_tree_add_bits_item(tree, hf_fp_congestion_status, tvb,
1242 offset*8 + 2, 2, ENC_BIG_ENDIAN);
1245 /* CmCH-PI */
1246 proto_tree_add_item(tree, hf_fp_cmch_pi, tvb, offset, 1, ENC_BIG_ENDIAN);
1247 offset++;
1249 /* Max MAC-d PDU length (13 bits) */
1250 max_pdu_length = tvb_get_ntohs(tvb, offset) >> 3;
1251 proto_tree_add_item(tree, hf_fp_hsdsch_max_macd_pdu_len, tvb, offset, 2, ENC_BIG_ENDIAN);
1252 offset++;
1254 /* HS-DSCH credits (11 bits) */
1255 ti = proto_tree_add_bits_ret_val(tree, hf_fp_hsdsch_credits, tvb,
1256 offset*8 + 5, 11, &credits, ENC_BIG_ENDIAN);
1257 offset += 2;
1259 /* Interesting values */
1260 if (credits == 0) {
1261 proto_item_append_text(ti, " (stop transmission)");
1262 expert_add_info(pinfo, ti, &ei_fp_stop_hsdpa_transmission);
1264 if (credits == 2047) {
1265 proto_item_append_text(ti, " (unlimited)");
1268 /* HS-DSCH Interval */
1269 interval = tvb_get_uint8(tvb, offset);
1270 ti = proto_tree_add_uint(tree, hf_fp_hsdsch_interval, tvb, offset, 1, interval*10);
1271 offset++;
1272 if (interval == 0) {
1273 proto_item_append_text(ti, " (none of the credits shall be used)");
1276 /* HS-DSCH Repetition period */
1277 repetition_period = tvb_get_uint8(tvb, offset);
1278 ti = proto_tree_add_item(tree, hf_fp_hsdsch_repetition_period, tvb, offset, 1, ENC_BIG_ENDIAN);
1279 offset++;
1280 if (repetition_period == 0) {
1281 proto_item_append_text(ti, " (unlimited repetition period)");
1284 /* Calculated and show effective rate enabled */
1285 if (credits == 2047) {
1286 rate_ti = proto_tree_add_item(tree, hf_fp_hsdsch_unlimited_rate, tvb, 0, 0, ENC_NA);
1287 proto_item_set_generated(rate_ti);
1289 else {
1290 if (interval != 0) {
1291 /* Cast on credits is safe, since we know it won't exceed 10^11 */
1292 rate_ti = proto_tree_add_uint(tree, hf_fp_hsdsch_calculated_rate, tvb, 0, 0,
1293 (uint16_t)credits * max_pdu_length * (1000 / (interval*10)));
1294 proto_item_set_generated(rate_ti);
1298 col_append_fstr(pinfo->cinfo, COL_INFO,
1299 " Max-PDU-len=%u Credits=%u Interval=%u Rep-Period=%u",
1300 max_pdu_length, (uint16_t)credits, interval, repetition_period);
1302 return offset;
1305 static int
1306 dissect_hsdpa_capacity_allocation_type_2(packet_info *pinfo, proto_tree *tree,
1307 tvbuff_t *tvb, int offset)
1309 proto_item *ti;
1310 proto_item *rate_ti;
1311 uint16_t max_pdu_length;
1312 uint8_t repetition_period;
1313 uint8_t interval;
1314 uint16_t credits;
1316 /* Congestion status */
1317 proto_tree_add_bits_item(tree, hf_fp_congestion_status, tvb,
1318 offset*8 + 2, 2, ENC_BIG_ENDIAN);
1320 /* CmCH-PI */
1321 proto_tree_add_item(tree, hf_fp_cmch_pi, tvb, offset, 1, ENC_BIG_ENDIAN);
1322 offset++;
1324 /* 5 spare bits follow here */
1326 /* Max MAC-d/c PDU length (11 bits) */
1327 max_pdu_length = tvb_get_ntohs(tvb, offset) & 0x7ff;
1328 proto_tree_add_item(tree, hf_fp_hsdsch_max_macdc_pdu_len, tvb, offset, 2, ENC_BIG_ENDIAN);
1329 offset += 2;
1331 /* HS-DSCH credits (16 bits) */
1332 credits = (tvb_get_ntohs(tvb, offset));
1333 ti = proto_tree_add_uint(tree, hf_fp_hsdsch_credits, tvb,
1334 offset, 2, credits);
1335 offset += 2;
1337 /* Interesting values */
1338 if (credits == 0) {
1339 proto_item_append_text(ti, " (stop transmission)");
1340 expert_add_info(pinfo, ti, &ei_fp_stop_hsdpa_transmission);
1342 if (credits == 65535) {
1343 proto_item_append_text(ti, " (unlimited)");
1346 /* HS-DSCH Interval */
1347 interval = tvb_get_uint8(tvb, offset);
1348 ti = proto_tree_add_uint(tree, hf_fp_hsdsch_interval, tvb, offset, 1, interval*10);
1349 offset++;
1350 if (interval == 0) {
1351 proto_item_append_text(ti, " (none of the credits shall be used)");
1354 /* HS-DSCH Repetition period */
1355 repetition_period = tvb_get_uint8(tvb, offset);
1356 ti = proto_tree_add_item(tree, hf_fp_hsdsch_repetition_period, tvb, offset, 1, ENC_BIG_ENDIAN);
1357 offset++;
1358 if (repetition_period == 0) {
1359 proto_item_append_text(ti, " (unlimited repetition period)");
1362 /* Calculated and show effective rate enabled */
1363 if (credits == 65535) {
1364 rate_ti = proto_tree_add_item(tree, hf_fp_hsdsch_unlimited_rate, tvb, 0, 0, ENC_NA);
1365 proto_item_set_generated(rate_ti);
1367 else {
1368 if (interval != 0) {
1369 rate_ti = proto_tree_add_uint(tree, hf_fp_hsdsch_calculated_rate, tvb, 0, 0,
1370 credits * max_pdu_length * (1000 / (interval*10)));
1371 proto_item_set_generated(rate_ti);
1375 col_append_fstr(pinfo->cinfo, COL_INFO,
1376 " Max-PDU-len=%u Credits=%u Interval=%u Rep-Period=%u",
1377 max_pdu_length, credits, interval, repetition_period);
1379 return offset;
1384 static int
1385 dissect_common_dynamic_pusch_assignment(packet_info *pinfo, proto_tree *tree,
1386 tvbuff_t *tvb, int offset)
1388 uint8_t pusch_set_id;
1389 uint8_t activation_cfn;
1390 uint8_t duration;
1392 /* PUSCH Set Id */
1393 pusch_set_id = tvb_get_uint8(tvb, offset);
1394 proto_tree_add_item(tree, hf_fp_pusch_set_id, tvb, offset, 1, ENC_BIG_ENDIAN);
1395 offset++;
1397 /* Activation CFN */
1398 activation_cfn = tvb_get_uint8(tvb, offset);
1399 proto_tree_add_item(tree, hf_fp_activation_cfn, tvb, offset, 1, ENC_BIG_ENDIAN);
1400 offset++;
1402 /* Duration */
1403 duration = tvb_get_uint8(tvb, offset) * 10;
1404 proto_tree_add_uint(tree, hf_fp_duration, tvb, offset, 1, duration);
1405 offset++;
1407 col_append_fstr(pinfo->cinfo, COL_INFO,
1408 " PUSCH Set Id=%u Activation CFN=%u Duration=%u",
1409 pusch_set_id, activation_cfn, duration);
1411 return offset;
1418 /* Dissect the control part of a common channel message */
1419 static void
1420 dissect_common_control(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1421 int offset, struct fp_info *p_fp_info)
1423 /* Common control frame type */
1424 uint8_t control_frame_type = tvb_get_uint8(tvb, offset);
1425 proto_tree_add_item(tree, hf_fp_common_control_frame_type, tvb, offset, 1, ENC_BIG_ENDIAN);
1426 offset++;
1428 col_append_str(pinfo->cinfo, COL_INFO,
1429 val_to_str_const(control_frame_type, common_control_frame_type_vals, "Unknown"));
1431 /* Frame-type specific dissection */
1432 switch (control_frame_type) {
1433 case COMMON_OUTER_LOOP_POWER_CONTROL:
1434 /*offset =*/ dissect_common_outer_loop_power_control(pinfo, tree, tvb, offset, p_fp_info);
1435 break;
1436 case COMMON_TIMING_ADJUSTMENT:
1437 /*offset =*/ dissect_common_timing_adjustment(pinfo, tree, tvb, offset, p_fp_info);
1438 break;
1439 case COMMON_DL_SYNCHRONISATION:
1440 /*offset =*/ dissect_common_dl_synchronisation(pinfo, tree, tvb, offset, p_fp_info);
1441 break;
1442 case COMMON_UL_SYNCHRONISATION:
1443 /*offset =*/ dissect_common_ul_synchronisation(pinfo, tree, tvb, offset, p_fp_info);
1444 break;
1445 case COMMON_DL_NODE_SYNCHRONISATION:
1446 /*offset =*/ dissect_common_dl_node_synchronisation(pinfo, tree, tvb, offset);
1447 break;
1448 case COMMON_UL_NODE_SYNCHRONISATION:
1449 /*offset =*/ dissect_common_ul_node_synchronisation(pinfo, tree, tvb, offset);
1450 break;
1451 case COMMON_DYNAMIC_PUSCH_ASSIGNMENT:
1452 /*offset =*/ dissect_common_dynamic_pusch_assignment(pinfo, tree, tvb, offset);
1453 break;
1454 case COMMON_TIMING_ADVANCE:
1455 /*offset =*/ dissect_common_timing_advance(pinfo, tree, tvb, offset);
1456 break;
1457 case COMMON_HS_DSCH_Capacity_Request:
1458 /*offset =*/ dissect_hsdpa_capacity_request(pinfo, tree, tvb, offset);
1459 break;
1460 case COMMON_HS_DSCH_Capacity_Allocation:
1461 /*offset =*/ dissect_hsdpa_capacity_allocation(pinfo, tree, tvb, offset, p_fp_info);
1462 break;
1463 case COMMON_HS_DSCH_Capacity_Allocation_Type_2:
1464 /*offset =*/ dissect_hsdpa_capacity_allocation_type_2(pinfo, tree, tvb, offset);
1465 break;
1467 default:
1468 break;
1471 /* There is no Spare Extension nor payload crc in common control!? */
1472 /* dissect_spare_extension_and_crc(tvb, pinfo, tree, 0, offset);
1478 /**************************/
1479 /* Dissect a RACH channel */
1480 static void
1481 dissect_rach_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1482 int offset, struct fp_info *p_fp_info, void *data)
1484 uint32_t ft;
1485 uint32_t header_crc = 0;
1486 proto_item * header_crc_pi = NULL;
1487 unsigned header_length;
1489 /* Header CRC */
1490 header_crc_pi = proto_tree_add_item_ret_uint(tree, hf_fp_header_crc, tvb, offset, 1, ENC_BIG_ENDIAN, &header_crc);
1492 /* Frame Type */
1493 proto_tree_add_item_ret_uint(tree, hf_fp_ft, tvb, offset, 1, ENC_BIG_ENDIAN, &ft);
1494 offset++;
1496 col_append_fstr(pinfo->cinfo, COL_INFO, " [%s] ", val_to_str_const(ft, frame_type_vals, "Unknown"));
1498 if (ft == FT_CONTROL) {
1499 dissect_common_control(tvb, pinfo, tree, offset, p_fp_info);
1500 /* For control frame the header CRC is actually frame CRC covering all
1501 * bytes except the first */
1502 if (preferences_header_checksum) {
1503 verify_control_frame_crc(tvb, pinfo, header_crc_pi, (uint16_t)header_crc);
1506 else {
1507 uint8_t cfn;
1508 uint32_t encoded;
1509 uint32_t propagation_delay = 0;
1510 proto_item *propagation_delay_ti = NULL;
1511 uint32_t received_sync_ul_timing_deviation = 0;
1512 proto_item *received_sync_ul_timing_deviation_ti = NULL;
1513 proto_item *rx_timing_deviation_ti = NULL;
1514 uint16_t rx_timing_deviation = 0;
1516 /* DATA */
1518 /* CFN */
1519 cfn = tvb_get_uint8(tvb, offset);
1520 proto_tree_add_item(tree, hf_fp_cfn, tvb, offset, 1, ENC_BIG_ENDIAN);
1521 offset++;
1523 col_append_fstr(pinfo->cinfo, COL_INFO, "CFN=%03u ", cfn);
1525 /* TFI */
1526 proto_tree_add_item(tree, hf_fp_tfi, tvb, offset, 1, ENC_BIG_ENDIAN);
1527 offset++;
1529 if (p_fp_info->channel == CHANNEL_RACH_FDD) {
1530 /* Propagation delay */
1531 encoded = tvb_get_uint8(tvb, offset);
1532 propagation_delay = encoded * 3;
1533 propagation_delay_ti = proto_tree_add_uint_format(tree, hf_fp_propagation_delay, tvb, offset, 1,
1534 propagation_delay, "Propagation Delay: %u chips (%u)",
1535 propagation_delay, encoded);
1536 offset++;
1539 /* Should be TDD 3.84 or 7.68 */
1540 if (p_fp_info->channel == CHANNEL_RACH_TDD) {
1541 /* Rx Timing Deviation */
1542 rx_timing_deviation = tvb_get_uint8(tvb, offset);
1543 rx_timing_deviation_ti = proto_tree_add_item(tree, hf_fp_rx_timing_deviation, tvb, offset, 1, ENC_BIG_ENDIAN);
1544 offset++;
1547 if (p_fp_info->channel == CHANNEL_RACH_TDD_128) {
1548 /* Received SYNC UL Timing Deviation */
1549 received_sync_ul_timing_deviation = tvb_get_uint8(tvb, offset);
1550 received_sync_ul_timing_deviation_ti =
1551 proto_tree_add_item(tree, hf_fp_received_sync_ul_timing_deviation, tvb, offset, 1, ENC_BIG_ENDIAN);
1552 offset++;
1555 header_length = offset;
1557 /* TB data */
1558 offset = dissect_tb_data(tvb, pinfo, tree, offset, p_fp_info, &mac_fdd_rach_handle, data);
1560 /* CRCIs */
1561 offset = dissect_crci_bits(tvb, pinfo, tree, p_fp_info, offset);
1563 /* Info introduced in R6 */
1564 /* only check if it looks as if they are present */
1565 if (((p_fp_info->release == 6) || (p_fp_info->release == 7)) &&
1566 (tvb_reported_length_remaining(tvb, offset) > 2))
1568 int n;
1569 uint8_t flags;
1570 /* uint8_t flag_bytes = 0; */
1572 bool cell_portion_id_present = false;
1573 bool ext_propagation_delay_present = false;
1574 bool angle_of_arrival_present = false;
1575 bool ext_rx_sync_ul_timing_deviation_present = false;
1576 bool ext_rx_timing_deviation_present = false;
1578 /* New IE flags (assume mandatory for now) */
1579 do {
1580 proto_item *new_ie_flags_ti;
1581 proto_tree *new_ie_flags_tree;
1582 unsigned ies_found = 0;
1584 /* Add new IE flags subtree */
1585 new_ie_flags_ti = proto_tree_add_string_format(tree, hf_fp_rach_new_ie_flags, tvb, offset, 1,
1586 "", "New IE flags");
1587 new_ie_flags_tree = proto_item_add_subtree(new_ie_flags_ti, ett_fp_rach_new_ie_flags);
1589 /* Read next byte */
1590 flags = tvb_get_uint8(tvb, offset);
1591 /* flag_bytes++ */
1593 /* Dissect individual bits */
1594 for (n=0; n < 8; n++) {
1595 switch (n) {
1596 case 6:
1597 switch (p_fp_info->division) {
1598 case Division_FDD:
1599 /* Ext propagation delay */
1600 ext_propagation_delay_present = true;
1601 proto_tree_add_item(new_ie_flags_tree, hf_fp_rach_ext_propagation_delay_present,
1602 tvb, offset, 1, ENC_BIG_ENDIAN);
1603 break;
1604 case Division_TDD_128:
1605 /* Ext Rx Sync UL Timing */
1606 ext_rx_sync_ul_timing_deviation_present = true;
1607 proto_tree_add_item(new_ie_flags_tree, hf_fp_rach_ext_rx_sync_ul_timing_deviation_present,
1608 tvb, offset, 1, ENC_BIG_ENDIAN);
1610 break;
1611 default:
1612 /* Not defined */
1613 proto_tree_add_item(new_ie_flags_tree, hf_fp_rach_new_ie_flag_unused[6],
1614 tvb, offset, 1, ENC_BIG_ENDIAN);
1615 break;
1617 break;
1618 case 7:
1619 switch (p_fp_info->division) {
1620 case Division_FDD:
1621 /* Cell Portion ID */
1622 cell_portion_id_present = true;
1623 proto_tree_add_item(new_ie_flags_tree, hf_fp_rach_cell_portion_id_present,
1624 tvb, offset, 1, ENC_BIG_ENDIAN);
1625 break;
1626 case Division_TDD_128:
1627 /* AOA */
1628 angle_of_arrival_present = true;
1629 proto_tree_add_item(new_ie_flags_tree, hf_fp_rach_angle_of_arrival_present,
1630 tvb, offset, 1, ENC_BIG_ENDIAN);
1631 break;
1632 case Division_TDD_384:
1633 case Division_TDD_768:
1634 /* Extended Rx Timing Deviation */
1635 ext_rx_timing_deviation_present = true;
1636 proto_tree_add_item(new_ie_flags_tree, hf_fp_rach_ext_rx_timing_deviation_present,
1637 tvb, offset, 1, ENC_BIG_ENDIAN);
1638 break;
1640 break;
1642 default:
1643 /* No defined meanings */
1644 /* Visual Studio Code Analyzer wrongly thinks n can be 7 here. It can't */
1645 proto_tree_add_item(new_ie_flags_tree, hf_fp_rach_new_ie_flag_unused[n],
1646 tvb, offset, 1, ENC_BIG_ENDIAN);
1647 break;
1649 if ((flags >> (7-n)) & 0x01) {
1650 ies_found++;
1653 offset++;
1655 proto_item_append_text(new_ie_flags_ti, " (%u IEs found)", ies_found);
1657 /* Last bit set will indicate another flags byte follows... */
1658 } while (0); /*((flags & 0x01) && (flag_bytes < 31));*/
1660 /* Cell Portion ID */
1661 if (cell_portion_id_present) {
1662 proto_tree_add_item(tree, hf_fp_cell_portion_id, tvb, offset, 1, ENC_BIG_ENDIAN);
1663 offset++;
1666 /* Ext Rx Timing Deviation */
1667 if (ext_rx_timing_deviation_present) {
1668 uint8_t extra_bits;
1669 unsigned bits_to_extend;
1670 switch (p_fp_info->division) {
1671 case Division_TDD_384:
1672 bits_to_extend = 1;
1673 break;
1674 case Division_TDD_768:
1675 bits_to_extend = 2;
1676 break;
1678 default:
1679 /* TODO: report unexpected division type */
1680 bits_to_extend = 1;
1681 break;
1683 extra_bits = tvb_get_uint8(tvb, offset) &
1684 ((bits_to_extend == 1) ? 0x01 : 0x03);
1685 rx_timing_deviation = (extra_bits << 8) | (rx_timing_deviation);
1686 proto_item_append_text(rx_timing_deviation_ti,
1687 " (extended to 0x%x)",
1688 rx_timing_deviation);
1689 proto_tree_add_bits_item(tree, hf_fp_extended_bits, tvb,
1690 offset*8 + (8-bits_to_extend), bits_to_extend, ENC_BIG_ENDIAN);
1691 offset++;
1694 /* Ext propagation delay. */
1695 if (ext_propagation_delay_present) {
1696 uint16_t extra_bits = tvb_get_ntohs(tvb, offset) & 0x03ff;
1697 proto_tree_add_item(tree, hf_fp_ext_propagation_delay, tvb, offset, 2, ENC_BIG_ENDIAN);
1699 /* Adding 10 bits to original 8 */
1700 proto_item_append_text(propagation_delay_ti, " (extended to %u)",
1701 ((extra_bits << 8) | propagation_delay) * 3);
1702 offset += 2;
1705 /* Angle of Arrival (AOA) */
1706 if (angle_of_arrival_present) {
1707 proto_tree_add_item(tree, hf_fp_angle_of_arrival, tvb, offset, 2, ENC_BIG_ENDIAN);
1708 offset += 2;
1711 /* Ext. Rx Sync UL Timing Deviation */
1712 if (ext_rx_sync_ul_timing_deviation_present) {
1713 uint16_t extra_bits;
1715 /* Ext received Sync UL Timing Deviation */
1716 extra_bits = tvb_get_ntohs(tvb, offset) & 0x1fff;
1717 proto_tree_add_item(tree, hf_fp_ext_received_sync_ul_timing_deviation, tvb, offset, 2, ENC_BIG_ENDIAN);
1719 /* Adding 13 bits to original 8 */
1720 proto_item_append_text(received_sync_ul_timing_deviation_ti, " (extended to %u)",
1721 (extra_bits << 8) | received_sync_ul_timing_deviation);
1722 offset += 2;
1725 if (preferences_header_checksum) {
1726 verify_header_crc(tvb, pinfo, header_crc_pi, header_crc, header_length);
1728 /* Spare Extension and Payload CRC */
1729 dissect_spare_extension_and_crc(tvb, pinfo, tree, 1, offset, header_length);
1734 /**************************/
1735 /* Dissect a FACH channel */
1736 static void
1737 dissect_fach_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1738 int offset, struct fp_info *p_fp_info, void *data)
1740 uint32_t ft;
1741 uint32_t header_crc = 0;
1742 proto_item * header_crc_pi = NULL;
1743 unsigned header_length;
1745 /* Header CRC */
1746 header_crc_pi = proto_tree_add_item_ret_uint(tree, hf_fp_header_crc, tvb, offset, 1, ENC_BIG_ENDIAN, &header_crc);
1748 /* Frame Type */
1749 proto_tree_add_item_ret_uint(tree, hf_fp_ft, tvb, offset, 1, ENC_BIG_ENDIAN, &ft);
1750 offset++;
1752 col_append_fstr(pinfo->cinfo, COL_INFO, " [%s] ", val_to_str_const(ft, frame_type_vals, "Unknown"));
1754 if (ft == FT_CONTROL) {
1755 dissect_common_control(tvb, pinfo, tree, offset, p_fp_info);
1756 /* For control frame the header CRC is actually frame CRC covering all
1757 * bytes except the first */
1758 if (preferences_header_checksum) {
1759 verify_control_frame_crc(tvb, pinfo, header_crc_pi, (uint16_t)header_crc);
1762 else {
1763 uint8_t cfn;
1764 /* DATA */
1766 /* CFN */
1767 cfn = tvb_get_uint8(tvb, offset);
1768 proto_tree_add_item(tree, hf_fp_cfn, tvb, offset, 1, ENC_BIG_ENDIAN);
1769 offset++;
1771 col_append_fstr(pinfo->cinfo, COL_INFO, "CFN=%03u ", cfn);
1773 /* TFI */
1774 proto_tree_add_item(tree, hf_fp_fach_tfi, tvb, offset, 1, ENC_BIG_ENDIAN);
1775 offset++;
1777 /* Transmit power level */
1778 proto_tree_add_float(tree, hf_fp_transmit_power_level, tvb, offset, 1,
1779 (float)(int)(tvb_get_uint8(tvb, offset)) / 10);
1780 offset++;
1781 header_length = offset;
1783 /* TB data */
1784 offset = dissect_tb_data(tvb, pinfo, tree, offset, p_fp_info, &mac_fdd_fach_handle, data);
1786 /* New IE flags (if it looks as though they are present) */
1787 if ((p_fp_info->release == 7) &&
1788 (tvb_reported_length_remaining(tvb, offset) > 2)) {
1790 uint8_t flags = tvb_get_uint8(tvb, offset);
1791 uint8_t aoa_present = flags & 0x01;
1792 offset++;
1794 if (aoa_present) {
1795 proto_tree_add_item(tree, hf_fp_angle_of_arrival, tvb, offset, 2, ENC_BIG_ENDIAN);
1796 offset += 2;
1799 if (preferences_header_checksum) {
1800 verify_header_crc(tvb, pinfo, header_crc_pi, header_crc, header_length);
1802 /* Spare Extension and Payload CRC */
1803 dissect_spare_extension_and_crc(tvb, pinfo, tree, 1, offset, header_length);
1808 /**************************/
1809 /* Dissect a DSCH channel */
1810 static void
1811 dissect_dsch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1812 int offset, struct fp_info *p_fp_info)
1814 uint32_t ft;
1816 /* Header CRC */
1817 proto_tree_add_item(tree, hf_fp_header_crc, tvb, offset, 1, ENC_BIG_ENDIAN);
1819 /* Frame Type */
1820 proto_tree_add_item_ret_uint(tree, hf_fp_ft, tvb, offset, 1, ENC_BIG_ENDIAN, &ft);
1821 offset++;
1823 col_append_fstr(pinfo->cinfo, COL_INFO, " [%s] ", val_to_str_const(ft, frame_type_vals, "Unknown"));
1825 if (ft == FT_CONTROL) {
1826 dissect_common_control(tvb, pinfo, tree, offset, p_fp_info);
1828 else {
1829 uint32_t cfn;
1830 unsigned header_length = 0;
1832 /* DATA */
1834 /* CFN */
1835 proto_tree_add_item_ret_uint(tree, hf_fp_cfn, tvb, offset, 1, ENC_BIG_ENDIAN, &cfn);
1836 offset++;
1838 col_append_fstr(pinfo->cinfo, COL_INFO, "CFN=%03u ", cfn);
1840 /* TFI */
1841 proto_tree_add_item(tree, hf_fp_tfi, tvb, offset, 1, ENC_BIG_ENDIAN);
1842 offset++;
1845 /* Other fields depend upon release & FDD/TDD settings */
1846 if (((p_fp_info->release == 99) || (p_fp_info->release == 4)) &&
1847 (p_fp_info->channel == CHANNEL_DSCH_FDD)) {
1849 /* Power offset */
1850 proto_tree_add_float(tree, hf_fp_power_offset, tvb, offset, 1,
1851 (float)(-32.0) +
1852 ((float)(int)(tvb_get_uint8(tvb, offset)) * (float)(0.25)));
1853 offset++;
1855 /* Code number */
1856 proto_tree_add_item(tree, hf_fp_code_number, tvb, offset, 1, ENC_BIG_ENDIAN);
1857 offset++;
1859 /* Spreading Factor (3 bits) */
1860 proto_tree_add_item(tree, hf_fp_spreading_factor, tvb, offset, 1, ENC_BIG_ENDIAN);
1862 /* MC info (4 bits)*/
1863 proto_tree_add_item(tree, hf_fp_mc_info, tvb, offset, 1, ENC_BIG_ENDIAN);
1865 /* Last bit of this byte is spare */
1866 offset++;
1868 else {
1869 /* Normal case */
1871 /* PDSCH Set Id */
1872 proto_tree_add_item(tree, hf_fp_pdsch_set_id, tvb, offset, 1, ENC_BIG_ENDIAN);
1873 offset++;
1875 /* Transmit power level */
1876 proto_tree_add_float(tree, hf_fp_transmit_power_level, tvb, offset, 1,
1877 (float)(int)(tvb_get_uint8(tvb, offset)) / 10);
1878 offset++;
1880 header_length = offset;
1881 /* TB data */
1882 offset = dissect_tb_data(tvb, pinfo, tree, offset, p_fp_info, NULL, NULL);
1884 /* Spare Extension and Payload CRC */
1885 dissect_spare_extension_and_crc(tvb, pinfo, tree, 1, offset, header_length);
1890 /**************************/
1891 /* Dissect a USCH channel */
1892 static void
1893 dissect_usch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1894 int offset, struct fp_info *p_fp_info)
1896 uint32_t ft;
1898 /* Header CRC */
1899 proto_tree_add_item(tree, hf_fp_header_crc, tvb, offset, 1, ENC_BIG_ENDIAN);
1901 /* Frame Type */
1902 proto_tree_add_item_ret_uint(tree, hf_fp_ft, tvb, offset, 1, ENC_BIG_ENDIAN, &ft);
1903 offset++;
1905 col_append_fstr(pinfo->cinfo, COL_INFO, " [%s] ", val_to_str_const(ft, frame_type_vals, "Unknown"));
1907 if (ft == FT_CONTROL) {
1908 dissect_common_control(tvb, pinfo, tree, offset, p_fp_info);
1910 else {
1911 unsigned cfn;
1912 uint16_t rx_timing_deviation;
1913 proto_item *rx_timing_deviation_ti;
1914 unsigned header_length = 0;
1916 /* DATA */
1918 /* CFN */
1919 proto_tree_add_item_ret_uint(tree, hf_fp_cfn, tvb, offset, 1, ENC_BIG_ENDIAN, &cfn);
1920 offset++;
1922 col_append_fstr(pinfo->cinfo, COL_INFO, "CFN=%03u ", cfn);
1924 /* TFI */
1925 proto_tree_add_item(tree, hf_fp_usch_tfi, tvb, offset, 1, ENC_BIG_ENDIAN);
1926 offset++;
1928 /* Rx Timing Deviation */
1929 rx_timing_deviation = tvb_get_uint8(tvb, offset);
1930 rx_timing_deviation_ti = proto_tree_add_item(tree, hf_fp_rx_timing_deviation,
1931 tvb, offset, 1, ENC_BIG_ENDIAN);
1932 offset++;
1933 header_length = offset;
1934 /* TB data */
1935 offset = dissect_tb_data(tvb, pinfo, tree, offset, p_fp_info, NULL, NULL);
1937 /* QE */
1938 proto_tree_add_item(tree, hf_fp_quality_estimate, tvb, offset, 1, ENC_BIG_ENDIAN);
1939 offset++;
1941 /* CRCIs */
1942 offset = dissect_crci_bits(tvb, pinfo, tree, p_fp_info, offset);
1944 /* New IEs */
1945 if ((p_fp_info->release == 7) &&
1946 (tvb_reported_length_remaining(tvb, offset) > 2)) {
1948 uint8_t flags = tvb_get_uint8(tvb, offset);
1949 uint8_t bits_extended = flags & 0x01;
1950 offset++;
1952 if (bits_extended) {
1953 uint8_t extra_bits = tvb_get_uint8(tvb, offset) & 0x03;
1954 proto_item_append_text(rx_timing_deviation_ti,
1955 " (extended to %u)",
1956 (rx_timing_deviation << 2) | extra_bits);
1958 offset++;
1961 /* Spare Extension and Payload CRC */
1962 dissect_spare_extension_and_crc(tvb, pinfo, tree, 1, offset, header_length);
1968 /**************************/
1969 /* Dissect a PCH channel */
1970 static void
1971 dissect_pch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1972 int offset, struct fp_info *p_fp_info, void *data)
1974 uint32_t ft;
1975 uint16_t pch_cfn;
1976 uint32_t tfi;
1977 bool paging_indication;
1978 uint32_t header_crc = 0;
1979 proto_item * header_crc_pi = NULL;
1981 /* Header CRC */
1982 header_crc_pi = proto_tree_add_item_ret_uint(tree, hf_fp_header_crc, tvb, offset, 1, ENC_BIG_ENDIAN, &header_crc);
1984 /* Frame Type */
1985 proto_tree_add_item_ret_uint(tree, hf_fp_ft, tvb, offset, 1, ENC_BIG_ENDIAN, &ft);
1986 offset++;
1988 col_append_fstr(pinfo->cinfo, COL_INFO, " [%s] ", val_to_str_const(ft, frame_type_vals, "Unknown"));
1990 if (ft == FT_CONTROL) {
1991 dissect_common_control(tvb, pinfo, tree, offset, p_fp_info);
1992 /* For control frame the header CRC is actually frame CRC covering all
1993 * bytes except the first */
1994 if (preferences_header_checksum) {
1995 verify_control_frame_crc(tvb, pinfo, header_crc_pi, (uint16_t)header_crc);
1998 else {
1999 unsigned header_length = 0;
2000 /* DATA */
2002 /* 12-bit CFN value */
2003 proto_tree_add_item(tree, hf_fp_pch_cfn, tvb, offset, 2, ENC_BIG_ENDIAN);
2004 pch_cfn = (tvb_get_ntohs(tvb, offset) & 0xfff0) >> 4;
2005 offset++;
2007 col_append_fstr(pinfo->cinfo, COL_INFO, "CFN=%04u ", pch_cfn);
2009 /* Paging indication */
2010 proto_tree_add_item(tree, hf_fp_pch_pi, tvb, offset, 1, ENC_BIG_ENDIAN);
2011 paging_indication = tvb_get_uint8(tvb, offset) & 0x01;
2012 offset++;
2014 /* 5-bit TFI */
2015 proto_tree_add_item_ret_uint(tree, hf_fp_pch_tfi, tvb, offset, 1, ENC_BIG_ENDIAN, &tfi);
2016 offset++;
2017 header_length = offset;
2018 /* Optional paging indications */
2019 if (paging_indication) {
2020 proto_item *ti;
2021 ti = proto_tree_add_item(tree, hf_fp_paging_indication_bitmap, tvb,
2022 offset,
2023 (p_fp_info->paging_indications+7) / 8,
2024 ENC_NA);
2025 proto_item_append_text(ti, " (%u bits)", p_fp_info->paging_indications);
2027 if(preferences_track_paging_indications && !PINFO_FD_VISITED(pinfo)){
2028 paging_indications_info_t* current_pi_info;
2029 current_pi_info = wmem_new0(wmem_file_scope(), paging_indications_info_t);
2030 current_pi_info->frame_number = pinfo->num;
2031 current_pi_info->paging_indications_bitmap = (uint8_t*)tvb_memdup(wmem_file_scope(), tvb, offset, (p_fp_info->paging_indications+7) / 8);
2032 p_fp_info->current_paging_indications = current_pi_info;
2035 offset += ((p_fp_info->paging_indications+7) / 8);
2037 if(preferences_track_paging_indications) {
2038 if(p_fp_info->relevant_paging_indications) {
2039 /*If tracking PI is enabled and PI info (from the last packet) is attached, show on tree*/
2040 proto_item *ti;
2041 proto_tree *relevant_pi_tree;
2043 tvbuff_t *pi_tvb;
2044 pi_tvb = tvb_new_child_real_data(tvb,
2045 p_fp_info->relevant_paging_indications->paging_indications_bitmap,
2046 (p_fp_info->paging_indications+7) / 8,
2047 (p_fp_info->paging_indications+7) / 8);
2048 add_new_data_source(pinfo, pi_tvb, "Relevant Paging Indication");
2049 ti = proto_tree_add_item(tree, hf_fp_relevant_paging_indication_bitmap, pi_tvb,
2051 (p_fp_info->paging_indications+7) / 8,
2052 ENC_NA);
2053 proto_item_append_text(ti, " (%u bits)", p_fp_info->paging_indications);
2054 proto_item_set_generated(ti);
2055 relevant_pi_tree = proto_item_add_subtree(ti, ett_fp_pch_relevant_pi);
2056 ti = proto_tree_add_uint(relevant_pi_tree, hf_fp_relevant_pi_frame,
2057 tvb, 0, 0, p_fp_info->relevant_paging_indications->frame_number);
2058 proto_item_set_generated(ti);
2060 else {
2061 /* PI info not attached. Check if this frame has any Transport Blocks (i.e. RRC payloads) */
2062 if(tfi > 0)
2064 /* This frame has RRC payload(s) but the PI info is missing, report to the user*/
2065 proto_tree_add_expert(tree, pinfo, &ei_fp_pch_lost_relevant_pi_frame, tvb, offset, -1);
2070 /* TB data */
2071 offset = dissect_tb_data(tvb, pinfo, tree, offset, p_fp_info, &mac_fdd_pch_handle, data);
2073 if (preferences_header_checksum) {
2074 verify_header_crc(tvb, pinfo, header_crc_pi, header_crc, header_length);
2076 /* Spare Extension and Payload CRC */
2077 dissect_spare_extension_and_crc(tvb, pinfo, tree, 1, offset, header_length);
2082 /**************************/
2083 /* Dissect a CPCH channel */
2084 static void
2085 dissect_cpch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2086 int offset, struct fp_info *p_fp_info)
2088 uint32_t ft;
2090 /* Header CRC */
2091 proto_tree_add_item(tree, hf_fp_header_crc, tvb, offset, 1, ENC_BIG_ENDIAN);
2093 /* Frame Type */
2094 proto_tree_add_item_ret_uint(tree, hf_fp_ft, tvb, offset, 1, ENC_BIG_ENDIAN, &ft);
2095 offset++;
2097 col_append_fstr(pinfo->cinfo, COL_INFO, " [%s] ", val_to_str_const(ft, frame_type_vals, "Unknown"));
2099 if (ft == FT_CONTROL) {
2100 dissect_common_control(tvb, pinfo, tree, offset, p_fp_info);
2102 else {
2103 unsigned cfn;
2104 uint32_t encoded;
2105 unsigned header_length = 0;
2106 uint32_t propagation_delay = 0;
2108 /* DATA */
2110 /* CFN */
2111 proto_tree_add_item_ret_uint(tree, hf_fp_cfn, tvb, offset, 1, ENC_BIG_ENDIAN, &cfn);
2112 offset++;
2114 col_append_fstr(pinfo->cinfo, COL_INFO, "CFN=%03u ", cfn);
2116 /* TFI */
2117 proto_tree_add_item(tree, hf_fp_cpch_tfi, tvb, offset, 1, ENC_BIG_ENDIAN);
2118 offset++;
2120 /* Propagation delay */
2121 encoded = tvb_get_uint8(tvb, offset);
2122 propagation_delay = encoded * 3;
2123 proto_tree_add_uint_format_value(tree, hf_fp_propagation_delay, tvb, offset, 1,
2124 propagation_delay, "Propagation Delay: %u chips (%u)",
2125 propagation_delay, encoded);
2126 offset++;
2127 header_length = offset; /* XXX this might be wrong */
2128 /* TB data */
2129 offset = dissect_tb_data(tvb, pinfo, tree, offset, p_fp_info, NULL, NULL);
2131 /* CRCIs */
2132 offset = dissect_crci_bits(tvb, pinfo, tree, p_fp_info, offset);
2134 /* Spare Extension and Payload CRC */
2135 dissect_spare_extension_and_crc(tvb, pinfo, tree, 1, offset, header_length);
2140 /**************************/
2141 /* Dissect a BCH channel */
2142 static void
2143 dissect_bch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2144 int offset, struct fp_info *p_fp_info)
2146 uint32_t ft;
2148 /* Header CRC */
2149 proto_tree_add_item(tree, hf_fp_header_crc, tvb, offset, 1, ENC_BIG_ENDIAN);
2151 /* Frame Type */
2152 proto_tree_add_item_ret_uint(tree, hf_fp_ft, tvb, offset, 1, ENC_BIG_ENDIAN, &ft);
2153 offset++;
2155 col_append_fstr(pinfo->cinfo, COL_INFO, " [%s] ", val_to_str_const(ft, frame_type_vals, "Unknown"));
2157 if (ft == FT_CONTROL) {
2158 dissect_common_control(tvb, pinfo, tree, offset, p_fp_info);
2163 /********************************/
2164 /* Dissect an IUR DSCH channel */
2165 static void
2166 dissect_iur_dsch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2167 int offset, struct fp_info *p_fp_info)
2169 uint32_t ft;
2171 /* Header CRC */
2172 proto_tree_add_item(tree, hf_fp_header_crc, tvb, offset, 1, ENC_BIG_ENDIAN);
2174 /* Frame Type */
2175 proto_tree_add_item_ret_uint(tree, hf_fp_ft, tvb, offset, 1, ENC_BIG_ENDIAN, &ft);
2176 offset++;
2178 col_append_fstr(pinfo->cinfo, COL_INFO, " [%s] ", val_to_str_const(ft, frame_type_vals, "Unknown"));
2180 if (ft == FT_CONTROL) {
2181 dissect_common_control(tvb, pinfo, tree, offset, p_fp_info);
2183 else {
2184 /* TODO: DATA */
2191 /************************/
2192 /* DCH control messages */
2194 static int
2195 dissect_dch_timing_adjustment(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, int offset)
2197 uint32_t cfn;
2198 int16_t toa;
2199 proto_item *toa_ti;
2201 /* CFN control */
2202 proto_tree_add_item_ret_uint(tree, hf_fp_cfn_control, tvb, offset, 1, ENC_BIG_ENDIAN, &cfn);
2203 offset++;
2205 /* ToA */
2206 toa = tvb_get_ntohs(tvb, offset);
2207 toa_ti = proto_tree_add_item(tree, hf_fp_toa, tvb, offset, 2, ENC_BIG_ENDIAN);
2208 offset += 2;
2210 expert_add_info_format(pinfo, toa_ti, &ei_fp_timing_adjustment_reported, "Timing adjustment reported (%.3f ms)", ((float)(toa) / 8));
2212 col_append_fstr(pinfo->cinfo, COL_INFO,
2213 " CFN = %u, ToA = %d", cfn, toa);
2215 return offset;
2218 static int
2219 dissect_dch_rx_timing_deviation(packet_info *pinfo, proto_tree *tree,
2220 tvbuff_t *tvb, int offset,
2221 struct fp_info *p_fp_info)
2223 uint16_t timing_deviation;
2224 int timing_deviation_chips;
2225 proto_item *timing_deviation_ti;
2227 /* CFN control */
2228 proto_tree_add_item(tree, hf_fp_cfn_control, tvb, offset, 1, ENC_BIG_ENDIAN);
2229 offset++;
2231 /* Rx Timing Deviation */
2232 timing_deviation = tvb_get_uint8(tvb, offset);
2233 timing_deviation_ti = proto_tree_add_item(tree, hf_fp_dch_rx_timing_deviation, tvb, offset, 1, ENC_BIG_ENDIAN);
2234 offset++;
2236 /* May be extended in R7, but in this case there are at least 2 bytes remaining */
2237 if ((p_fp_info->release == 7) &&
2238 (tvb_reported_length_remaining(tvb, offset) >= 2)) {
2240 /* New IE flags */
2241 uint64_t extended_bits_present;
2242 uint64_t e_rucch_present;
2244 /* Read flags */
2245 proto_tree_add_bits_ret_val(tree, hf_fp_e_rucch_present, tvb,
2246 offset*8 + 6, 1, &e_rucch_present, ENC_BIG_ENDIAN);
2247 proto_tree_add_bits_ret_val(tree, hf_fp_extended_bits_present, tvb,
2248 offset*8 + 7, 1, &extended_bits_present, ENC_BIG_ENDIAN);
2249 offset++;
2251 /* Optional E-RUCCH */
2252 if (e_rucch_present) {
2254 /* Value of bit_offset depends upon division type */
2255 int bit_offset;
2257 switch (p_fp_info->division) {
2258 case Division_TDD_384:
2259 bit_offset = 6;
2260 break;
2261 case Division_TDD_768:
2262 bit_offset = 5;
2263 break;
2264 default:
2266 proto_tree_add_expert(tree, pinfo, &ei_fp_expecting_tdd, tvb, 0, 0);
2267 bit_offset = 6;
2271 proto_tree_add_item(tree, hf_fp_dch_e_rucch_flag, tvb, offset, 1, ENC_BIG_ENDIAN);
2272 proto_tree_add_bits_item(tree, hf_fp_dch_e_rucch_flag, tvb,
2273 offset*8 + bit_offset, 1, ENC_BIG_ENDIAN);
2276 /* Timing deviation may be extended by another:
2277 - 1 bits (3.84 TDD) OR
2278 - 2 bits (7.68 TDD)
2280 if (extended_bits_present) {
2281 uint8_t extra_bits;
2282 unsigned bits_to_extend;
2283 switch (p_fp_info->division) {
2284 case Division_TDD_384:
2285 bits_to_extend = 1;
2286 break;
2287 case Division_TDD_768:
2288 bits_to_extend = 2;
2289 break;
2291 default:
2292 /* TODO: report unexpected division type */
2293 bits_to_extend = 1;
2294 break;
2296 extra_bits = tvb_get_uint8(tvb, offset) &
2297 ((bits_to_extend == 1) ? 0x01 : 0x03);
2298 timing_deviation = (extra_bits << 8) | (timing_deviation);
2299 proto_item_append_text(timing_deviation_ti,
2300 " (extended to 0x%x)",
2301 timing_deviation);
2302 proto_tree_add_bits_item(tree, hf_fp_extended_bits, tvb,
2303 offset*8 + (8-bits_to_extend), bits_to_extend, ENC_BIG_ENDIAN);
2304 offset++;
2308 timing_deviation_chips = (timing_deviation*4) - 1024;
2309 proto_item_append_text(timing_deviation_ti, " (%d chips)",
2310 timing_deviation_chips);
2312 col_append_fstr(pinfo->cinfo, COL_INFO, " deviation = %u (%d chips)",
2313 timing_deviation, timing_deviation_chips);
2315 return offset;
2318 static int
2319 dissect_dch_dl_synchronisation(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, int offset)
2321 uint32_t cfn;
2323 /* CFN control */
2324 proto_tree_add_item_ret_uint(tree, hf_fp_cfn_control, tvb, offset, 1, ENC_BIG_ENDIAN, &cfn);
2325 offset++;
2327 col_append_fstr(pinfo->cinfo, COL_INFO, " CFN = %u", cfn);
2329 return offset;
2332 static int
2333 dissect_dch_ul_synchronisation(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, int offset)
2335 uint32_t cfn;
2336 int16_t toa;
2338 /* CFN control */
2339 proto_tree_add_item_ret_uint(tree, hf_fp_cfn_control, tvb, offset, 1, ENC_BIG_ENDIAN, &cfn);
2340 offset++;
2342 /* ToA */
2343 toa = tvb_get_ntohs(tvb, offset);
2344 proto_tree_add_item(tree, hf_fp_toa, tvb, offset, 2, ENC_BIG_ENDIAN);
2345 offset += 2;
2347 col_append_fstr(pinfo->cinfo, COL_INFO, " CFN = %u, ToA = %d",
2348 cfn, toa);
2350 return offset;
2353 static int
2354 dissect_dch_outer_loop_power_control(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, int offset)
2356 /* UL SIR target */
2357 uint8_t encoded = tvb_get_uint8(tvb, offset);
2358 float target = (float)-8.2 + ((float)0.1 * (float)(int)(encoded));
2359 proto_tree_add_float_format_value(tree, hf_fp_ul_sir_target, tvb, offset, 1, target, "%.1f dB (%u)", target, encoded);
2360 offset++;
2362 col_append_fstr(pinfo->cinfo, COL_INFO, " UL SIR Target = %.1f", target);
2364 return offset;
2367 static int
2368 dissect_dch_dl_node_synchronisation(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, int offset)
2370 return dissect_common_dl_node_synchronisation(pinfo, tree, tvb, offset);
2373 static int
2374 dissect_dch_ul_node_synchronisation(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, int offset)
2376 return dissect_common_ul_node_synchronisation(pinfo, tree, tvb, offset);
2379 static int
2380 dissect_dch_radio_interface_parameter_update(proto_tree *tree, packet_info *pinfo _U_, tvbuff_t *tvb, int offset)
2382 float tpc_po;
2383 int8_t max_tx_pwr;
2384 int n;
2385 uint8_t encoded;
2387 /* Show defined flags in these 2 bytes */
2388 for (n=4; n >= 0; n--) {
2389 proto_tree_add_item(tree, hf_fp_radio_interface_parameter_update_flag[n], tvb, offset, 2, ENC_BIG_ENDIAN);
2391 offset += 2;
2393 /* CFN */
2394 proto_tree_add_item(tree, hf_fp_cfn, tvb, offset, 1, ENC_BIG_ENDIAN);
2395 offset++;
2397 /* DPC mode */
2398 proto_tree_add_item(tree, hf_fp_dpc_mode, tvb, offset, 1, ENC_BIG_ENDIAN);
2400 /* TPC PO */
2401 encoded = tvb_get_uint8(tvb, offset) & 0x1f;
2402 tpc_po = (float)encoded * 0.25f;
2403 proto_tree_add_float_format_value(tree, hf_fp_tpc_po, tvb, offset, 1, tpc_po,
2404 "%.2f dB (%u)", tpc_po, encoded);
2405 offset++;
2407 /* Multiple RL sets indicator */
2408 proto_tree_add_item(tree, hf_fp_multiple_rl_set_indicator, tvb, offset, 1, ENC_BIG_ENDIAN);
2409 offset += 2;
2411 /* Maximum UE TX Power */
2412 encoded = tvb_get_uint8(tvb, offset) & 0x7f;
2413 max_tx_pwr = -55 + encoded;
2414 proto_tree_add_int_format(tree, hf_fp_max_ue_tx_pow, tvb, offset, 1, max_tx_pwr,
2415 "%d dBm (%u)", max_tx_pwr, encoded);
2416 offset++;
2418 return offset;
2421 static int
2422 dissect_dch_timing_advance(proto_tree *tree, packet_info *pinfo,
2423 tvbuff_t *tvb, int offset, struct fp_info *p_fp_info)
2425 uint32_t cfn;
2426 uint16_t timing_advance;
2427 proto_item *timing_advance_ti;
2429 /* CFN control */
2430 proto_tree_add_item_ret_uint(tree, hf_fp_cfn_control, tvb, offset, 1, ENC_BIG_ENDIAN, &cfn);
2431 offset++;
2433 /* Timing Advance */
2434 timing_advance = (tvb_get_uint8(tvb, offset) & 0x3f) * 4;
2435 timing_advance_ti = proto_tree_add_uint(tree, hf_fp_timing_advance, tvb, offset, 1, timing_advance);
2436 offset++;
2438 if ((p_fp_info->release == 7) &&
2439 (tvb_reported_length_remaining(tvb, offset) > 0)) {
2441 /* New IE flags */
2442 uint8_t flags = tvb_get_uint8(tvb, offset);
2443 uint8_t extended_bits = flags & 0x01;
2444 offset++;
2446 if (extended_bits) {
2447 uint8_t extra_bit = tvb_get_uint8(tvb, offset) & 0x01;
2448 proto_item_append_text(timing_advance_ti, " (extended to %u)",
2449 (timing_advance << 1) | extra_bit);
2451 offset++;
2454 col_append_fstr(pinfo->cinfo, COL_INFO, " CFN = %u, TA = %u",
2455 cfn, timing_advance);
2457 return offset;
2460 static int
2461 dissect_dch_tnl_congestion_indication(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, int offset)
2463 uint64_t status;
2465 /* Congestion status */
2466 proto_tree_add_bits_ret_val(tree, hf_fp_congestion_status, tvb,
2467 offset*8 + 6, 2, &status, ENC_BIG_ENDIAN);
2468 offset++;
2470 col_append_fstr(pinfo->cinfo, COL_INFO, " status = %s",
2471 val_to_str_const((uint16_t)status, congestion_status_vals, "unknown"));
2473 return offset;
2479 /* DCH control frame */
2480 static void
2481 dissect_dch_control_frame(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb,
2482 int offset, struct fp_info *p_fp_info)
2484 /* Control frame type */
2485 uint8_t control_frame_type = tvb_get_uint8(tvb, offset);
2486 proto_tree_add_item(tree, hf_fp_dch_control_frame_type, tvb, offset, 1, ENC_BIG_ENDIAN);
2487 offset++;
2489 col_append_str(pinfo->cinfo, COL_INFO,
2490 val_to_str_const(control_frame_type,
2491 dch_control_frame_type_vals, "Unknown"));
2493 switch (control_frame_type) {
2494 case DCH_TIMING_ADJUSTMENT:
2495 /*offset =*/ dissect_dch_timing_adjustment(tree, pinfo, tvb, offset);
2496 break;
2497 case DCH_RX_TIMING_DEVIATION:
2498 /*offset =*/ dissect_dch_rx_timing_deviation(pinfo, tree, tvb, offset, p_fp_info);
2499 break;
2500 case DCH_DL_SYNCHRONISATION:
2501 /*offset =*/ dissect_dch_dl_synchronisation(tree, pinfo, tvb, offset);
2502 break;
2503 case DCH_UL_SYNCHRONISATION:
2504 /*offset =*/ dissect_dch_ul_synchronisation(tree, pinfo, tvb, offset);
2505 break;
2506 case DCH_OUTER_LOOP_POWER_CONTROL:
2507 /*offset =*/ dissect_dch_outer_loop_power_control(tree, pinfo, tvb, offset);
2508 break;
2509 case DCH_DL_NODE_SYNCHRONISATION:
2510 /*offset =*/ dissect_dch_dl_node_synchronisation(tree, pinfo, tvb, offset);
2511 break;
2512 case DCH_UL_NODE_SYNCHRONISATION:
2513 /*offset =*/ dissect_dch_ul_node_synchronisation(tree, pinfo, tvb, offset);
2514 break;
2515 case DCH_RADIO_INTERFACE_PARAMETER_UPDATE:
2516 /*offset =*/ dissect_dch_radio_interface_parameter_update(tree, pinfo, tvb, offset);
2517 break;
2518 case DCH_TIMING_ADVANCE:
2519 /*offset =*/ dissect_dch_timing_advance(tree, pinfo, tvb, offset, p_fp_info);
2520 break;
2521 case DCH_TNL_CONGESTION_INDICATION:
2522 /*offset =*/ dissect_dch_tnl_congestion_indication(tree, pinfo, tvb, offset);
2523 break;
2526 /* Spare Extension */
2527 /* dissect_spare_extension_and_crc(tvb, pinfo, tree, 0, offset);
2531 /*******************************/
2532 /* Dissect a DCH channel */
2533 static void
2534 dissect_dch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2535 int offset, struct fp_info *p_fp_info, void *data)
2537 uint32_t ft;
2538 uint32_t cfn;
2539 unsigned header_length;
2540 uint32_t header_crc = 0;
2541 proto_item * header_crc_pi = NULL;
2543 /* Header CRC */
2544 header_crc_pi = proto_tree_add_item_ret_uint(tree, hf_fp_header_crc, tvb, offset, 1, ENC_BIG_ENDIAN, &header_crc);
2546 /* Frame Type */
2547 proto_tree_add_item_ret_uint(tree, hf_fp_ft, tvb, offset, 1, ENC_BIG_ENDIAN, &ft);
2548 offset++;
2550 col_append_str(pinfo->cinfo, COL_INFO,
2551 (ft == FT_CONTROL )? " [Control] " :
2552 ((p_fp_info->is_uplink) ? " [ULData] " :
2553 " [DLData] " ));
2555 if (ft == FT_CONTROL) {
2556 /* DCH control frame */
2557 dissect_dch_control_frame(tree, pinfo, tvb, offset, p_fp_info);
2558 /* For control frame the header CRC is actually frame CRC covering all
2559 * bytes except the first */
2560 if (preferences_header_checksum) {
2561 verify_control_frame_crc(tvb, pinfo, header_crc_pi, (uint16_t)header_crc);
2563 } else {
2564 /************************/
2565 /* DCH data here */
2566 int chan;
2567 /* CFN */
2568 proto_tree_add_item_ret_uint(tree, hf_fp_cfn, tvb, offset, 1, ENC_BIG_ENDIAN, &cfn);
2569 offset++;
2571 col_append_fstr(pinfo->cinfo, COL_INFO, "CFN=%03u ", cfn);
2573 /* One TFI for each channel */
2574 for (chan=0; chan < p_fp_info->num_chans; chan++) {
2575 proto_tree_add_item(tree, hf_fp_tfi, tvb, offset, 1, ENC_BIG_ENDIAN);
2576 offset++;
2578 header_length = offset;
2579 /* Dissect TB data */
2580 offset = dissect_tb_data(tvb, pinfo, tree, offset, p_fp_info, &mac_fdd_dch_handle, data);
2582 /* QE and CRCI bits (uplink only) */
2583 if (p_fp_info->is_uplink) {
2584 proto_tree_add_item(tree, hf_fp_quality_estimate, tvb, offset, 1, ENC_BIG_ENDIAN);
2585 offset++;
2586 offset = dissect_crci_bits(tvb, pinfo, tree, p_fp_info, offset);
2589 if (preferences_header_checksum) {
2590 verify_header_crc(tvb, pinfo, header_crc_pi, header_crc, header_length);
2592 /* Spare extension and payload CRC (optional) */
2593 dissect_spare_extension_and_crc(tvb, pinfo, tree,
2594 p_fp_info->dch_crc_present, offset, header_length);
2598 /**********************************/
2599 /* Dissect an E-DCH channel */
2600 static void
2601 dissect_e_dch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2602 int offset, struct fp_info *p_fp_info,
2603 bool is_common,
2604 void *data)
2606 uint32_t ft;
2607 uint8_t number_of_subframes;
2608 uint32_t cfn;
2609 int n;
2610 struct edch_t1_subframe_info subframes[16];
2611 uint32_t header_crc = 0;
2612 proto_item * header_crc_pi = NULL;
2613 proto_item * item;
2614 unsigned header_length;
2615 rlc_info * rlcinf;
2617 if (p_fp_info->edch_type == 1) {
2618 col_append_str(pinfo->cinfo, COL_INFO, " (T2)");
2621 /* Header CRC */
2622 /* the bitmask doesn't properly handle this delicate case, do manually */
2623 header_crc = (tvb_get_bits8(tvb, offset*8, 7) << 4) + tvb_get_bits8(tvb, offset*8+8, 4);
2625 /* Frame Type */
2626 ft = tvb_get_uint8(tvb, offset) & 0x01;
2628 col_append_fstr(pinfo->cinfo, COL_INFO, " [%s] ", val_to_str_const(ft, frame_type_vals, "Unknown"));
2630 if (ft == FT_CONTROL) {
2631 /* DCH control frame */
2633 /* For control frame the header CRC is actually frame CRC covering all
2634 * bytes except the first */
2635 header_crc_pi = proto_tree_add_item_ret_uint(tree, hf_fp_header_crc, tvb, offset, 1, ENC_BIG_ENDIAN, &header_crc);
2636 proto_tree_add_item(tree, hf_fp_ft, tvb, 0, 1, ENC_BIG_ENDIAN);
2637 offset++;
2638 if (preferences_header_checksum) {
2639 verify_control_frame_crc(tvb, pinfo, header_crc_pi, (uint16_t)header_crc);
2641 dissect_dch_control_frame(tree, pinfo, tvb, offset, p_fp_info);
2643 else {
2644 /********************************/
2645 /* E-DCH data here */
2646 unsigned bit_offset;
2647 unsigned total_pdus = 0;
2648 unsigned total_bits = 0;
2649 bool dissected = false;
2651 rlcinf = (rlc_info *)p_get_proto_data(wmem_file_scope(), pinfo, proto_umts_rlc, 0);
2652 if (!rlcinf) {
2653 rlcinf = wmem_new0(wmem_packet_scope(), rlc_info);
2656 header_crc_pi = proto_tree_add_uint_format(tree, hf_fp_edch_header_crc, tvb,
2657 offset, 2, header_crc,
2658 "%u%u%u%u %u%u%u. %u%u%u%u .... = E-DCH Header CRC: 0x%x",
2659 (header_crc >> 10) & 1,
2660 (header_crc >> 9) & 1,
2661 (header_crc >> 8) & 1,
2662 (header_crc >> 7) & 1,
2663 (header_crc >> 6) & 1,
2664 (header_crc >> 5) & 1,
2665 (header_crc >> 4) & 1,
2666 (header_crc >> 3) & 1,
2667 (header_crc >> 2) & 1,
2668 (header_crc >> 1) & 1,
2669 (header_crc >> 0) & 1, header_crc);
2670 proto_tree_add_item(tree, hf_fp_ft, tvb, offset, 1, ENC_BIG_ENDIAN);
2671 offset++;
2672 /* FSN */
2673 proto_tree_add_item(tree, hf_fp_edch_fsn, tvb, offset, 1, ENC_BIG_ENDIAN);
2674 offset++;
2676 /* Number of subframes.
2677 This was 3 bits in early releases, is 4 bits offset by 1 in later releases */
2678 if ((p_fp_info->release >= 6) &&
2679 ((p_fp_info->release_year > 2005) ||
2680 ((p_fp_info->release_year == 2005) && (p_fp_info->release_month >= 9)))) {
2682 /* Use 4 bits plus offset of 1 */
2683 number_of_subframes = (tvb_get_uint8(tvb, offset) & 0x0f) + 1;
2685 else {
2686 /* Use 3 bits only */
2687 number_of_subframes = (tvb_get_uint8(tvb, offset) & 0x07);
2689 proto_tree_add_uint(tree, hf_fp_edch_number_of_subframes, tvb, offset, 1,
2690 number_of_subframes);
2692 offset++;
2694 /* CFN */
2695 proto_tree_add_item_ret_uint(tree, hf_fp_cfn, tvb, offset, 1, ENC_BIG_ENDIAN, &cfn);
2696 offset++;
2698 /* Remainder of T2 or common data frames differ here... */
2699 if (p_fp_info->edch_type == 1) {
2700 dissect_e_dch_t2_or_common_channel_info(tvb, pinfo, tree, offset, p_fp_info,
2701 number_of_subframes,
2702 is_common, header_crc,
2703 header_crc_pi, data);
2704 return;
2707 /* EDCH subframe header list */
2708 for (n=0; n < number_of_subframes; n++) {
2709 int i;
2710 int start_offset = offset;
2711 proto_item *subframe_header_ti;
2712 proto_tree *subframe_header_tree;
2714 /* Add subframe header subtree */
2715 subframe_header_ti = proto_tree_add_string_format(tree, hf_fp_edch_subframe_header, tvb, offset, 0,
2716 "", "Subframe");
2717 subframe_header_tree = proto_item_add_subtree(subframe_header_ti, ett_fp_edch_subframe_header);
2719 /* Number of HARQ Retransmissions */
2720 proto_tree_add_item(subframe_header_tree, hf_fp_edch_harq_retransmissions, tvb,
2721 offset, 1, ENC_BIG_ENDIAN);
2723 /* Subframe number */
2724 subframes[n].subframe_number = (tvb_get_uint8(tvb, offset) & 0x07);
2725 proto_tree_add_bits_item(subframe_header_tree, hf_fp_edch_subframe_number, tvb,
2726 offset*8+5, 3, ENC_BIG_ENDIAN);
2727 offset++;
2729 /* Number of MAC-es PDUs */
2730 subframes[n].number_of_mac_es_pdus = (tvb_get_uint8(tvb, offset) & 0xf0) >> 4;
2731 proto_tree_add_item(subframe_header_tree, hf_fp_edch_number_of_mac_es_pdus,
2732 tvb, offset, 1, ENC_BIG_ENDIAN);
2733 bit_offset = 4;
2735 proto_item_append_text(subframe_header_ti, " %u header (%u MAC-es PDUs)",
2736 subframes[n].subframe_number,
2737 subframes[n].number_of_mac_es_pdus);
2739 /* Details of each MAC-es PDU */
2740 for (i=0; i < subframes[n].number_of_mac_es_pdus; i++) {
2741 uint64_t ddi;
2742 uint64_t n_pdus; /*Size of the PDU*/
2744 proto_item *ddi_ti;
2745 int ddi_size = -1;
2746 int p;
2748 /* DDI (6 bits) */
2749 ddi_ti = proto_tree_add_bits_ret_val(subframe_header_tree, hf_fp_edch_ddi, tvb,
2750 offset*8 + bit_offset, 6, &ddi, ENC_BIG_ENDIAN);
2752 rlcinf->rbid[i] = (uint8_t)ddi;
2753 /********************************/
2754 /* Look up data in higher layers*/
2755 /* Look up the size from this DDI value */
2756 for (p=0; p < p_fp_info->no_ddi_entries; p++) {
2757 if (ddi == p_fp_info->edch_ddi[p]) {
2758 ddi_size = p_fp_info->edch_macd_pdu_size[p];
2760 break;
2764 if (ddi_size == -1) {
2765 expert_add_info_format(pinfo, ddi_ti, &ei_fp_ddi_not_defined, "DDI %u not defined for this UE!", (unsigned)ddi);
2766 return;
2768 else {
2769 proto_item_append_text(ddi_ti, " (%d bits)", ddi_size);
2772 subframes[n].ddi[i] = (uint8_t)ddi;
2773 bit_offset += 6;
2775 /* Number of MAC-d PDUs (6 bits) */
2776 item = proto_tree_add_bits_ret_val(subframe_header_tree, hf_fp_edch_number_of_mac_d_pdus, tvb,
2777 offset*8 + bit_offset, 6, &n_pdus, ENC_BIG_ENDIAN);
2778 if (n_pdus > MAX_MAC_FRAMES) {
2779 expert_add_info_format(pinfo, item, &ei_fp_invalid_frame_count, "Invalid number of PDUs (max is %u)", MAX_MAC_FRAMES);
2780 return;
2783 subframes[n].number_of_mac_d_pdus[i] = (uint8_t)n_pdus;
2784 bit_offset += 6;
2787 offset += ((bit_offset+7)/8);
2789 /* Tree should cover entire subframe header */
2790 proto_item_set_len(subframe_header_ti, offset - start_offset);
2792 header_length = offset;
2793 /* EDCH subframes */
2794 for (n=0; n < number_of_subframes; n++) {
2795 int i;
2796 proto_item *subframe_ti;
2797 proto_tree *subframe_tree;
2798 unsigned bits_in_subframe = 0;
2799 unsigned mac_d_pdus_in_subframe = 0;
2800 unsigned lchid=0; /*Logical channel id*/
2801 uint32_t user_identity;
2802 umts_mac_info *macinf;
2803 bit_offset = 0;
2805 macinf = (umts_mac_info *)p_get_proto_data(wmem_file_scope(), pinfo, proto_umts_mac, 0);
2806 if (!macinf) {
2807 macinf = wmem_new0(wmem_packet_scope(), umts_mac_info);
2809 /* Add subframe subtree */
2810 subframe_ti = proto_tree_add_string_format(tree, hf_fp_edch_subframe, tvb, offset, 0,
2811 "", "Subframe %u data", subframes[n].subframe_number);
2812 subframe_tree = proto_item_add_subtree(subframe_ti, ett_fp_edch_subframe);
2814 for (i=0; i < subframes[n].number_of_mac_es_pdus; i++) {
2815 int m;
2816 uint16_t size = 0;
2817 /* uint8_t tsn; */
2818 unsigned send_size;
2819 proto_item *ti;
2820 int macd_idx;
2821 proto_tree *maces_tree = NULL;
2823 /** TODO: Merge these two loops? **/
2824 /* Look up mac-d pdu size for this ddi */
2825 for (m=0; m < p_fp_info->no_ddi_entries; m++) {
2826 if (subframes[n].ddi[i] == p_fp_info->edch_ddi[m]) {
2827 size = p_fp_info->edch_macd_pdu_size[m];
2828 break;
2831 /* Look up logicalchannel id for this DDI value */
2832 for (m=0; m < p_fp_info->no_ddi_entries; m++) {
2833 if (subframes[n].ddi[i] == p_fp_info->edch_ddi[m]) {
2834 lchid = p_fp_info->edch_lchId[m];
2835 break;
2839 if (m == p_fp_info->no_ddi_entries) {
2840 /* Not found. Oops */
2841 expert_add_info(pinfo, NULL, &ei_fp_unable_to_locate_ddi_entry);
2842 return;
2845 /* Send MAC-dd PDUs together as one MAC-es PDU */
2846 send_size = size * subframes[n].number_of_mac_d_pdus[i];
2848 /* 2 bits spare */
2849 proto_tree_add_item(subframe_tree, hf_fp_edch_pdu_padding, tvb,
2850 offset + (bit_offset/8),
2851 1, ENC_BIG_ENDIAN);
2852 bit_offset += 2;
2854 /* TSN */
2855 /* tsn = (tvb_get_uint8(tvb, offset + (bit_offset/8)) & 0x3f); */
2856 proto_tree_add_item(subframe_tree, hf_fp_edch_tsn, tvb,
2857 offset + (bit_offset/8),
2858 1, ENC_BIG_ENDIAN);
2859 bit_offset += 6;
2861 /* PDU */
2862 if (subframe_tree) {
2863 ti = proto_tree_add_item(subframe_tree, hf_fp_edch_mac_es_pdu, tvb,
2864 offset + (bit_offset/8),
2865 ((bit_offset % 8) + send_size + 7) / 8,
2866 ENC_NA);
2867 proto_item_append_text(ti, " (%u * %u = %u bits, PDU %d)",
2868 size, subframes[n].number_of_mac_d_pdus[i],
2869 send_size, n);
2870 maces_tree = proto_item_add_subtree(ti, ett_fp_edch_maces);
2872 /* Determine the UE ID to use in RLC */
2873 user_identity = p_fp_info->com_context_id;
2874 if(p_fp_info->urnti) {
2875 user_identity = p_fp_info->urnti;
2877 for (macd_idx = 0; macd_idx < subframes[n].number_of_mac_d_pdus[i]; macd_idx++) {
2879 if (preferences_call_mac_dissectors) {
2880 /* Should no longer happen ??*/
2881 if (macd_idx >= MAX_MAC_FRAMES) {
2882 expert_add_info_format(pinfo, subframe_tree, &ei_fp_invalid_frame_count, "Invalid frame count (max is %u)", MAX_MAC_FRAMES);
2883 return;
2886 tvbuff_t *next_tvb;
2887 /* create new TVB and pass further on */
2888 next_tvb = tvb_new_subset_length(tvb, offset + bit_offset/8,
2889 ((bit_offset % 8) + size + 7) / 8);
2891 /*Set up information needed for MAC and lower layers*/
2892 macinf->content[macd_idx] = lchId_type_table[lchid]; /*Set the proper Content type for the mac layer.*/
2893 macinf->lchid[macd_idx] = lchid;
2894 rlcinf->mode[macd_idx] = lchId_rlc_map[lchid]; /* Set RLC mode by lchid to RLC_MODE map in nbap.h */
2896 /* Set UE ID to U-RNTI or NBAP Communication Context*/
2897 rlcinf->ueid[macd_idx] = user_identity;
2898 rlcinf->rbid[macd_idx] = lchid;
2899 rlcinf->li_size[macd_idx] = RLC_LI_7BITS;
2901 rlcinf->ciphered[macd_idx] = false;
2902 rlcinf->deciphered[macd_idx] = false;
2903 p_fp_info->cur_tb = macd_idx; /*Set the transport block index */
2905 call_dissector_with_data(mac_fdd_edch_handle, next_tvb, pinfo, top_level_tree, data);
2906 dissected = true;
2908 else {
2909 /* Just add as a MAC-d PDU */
2910 proto_tree_add_item(maces_tree, hf_fp_mac_d_pdu, tvb,
2911 offset + (bit_offset/8),
2912 ((bit_offset % 8) + size + 7) / 8,
2913 ENC_NA);
2915 bit_offset += size;
2918 bits_in_subframe += send_size;
2919 mac_d_pdus_in_subframe += subframes[n].number_of_mac_d_pdus[i];
2921 /* Pad out to next byte */
2922 if (bit_offset % 8) {
2923 bit_offset += (8 - (bit_offset % 8));
2927 if (tree) {
2928 /* Tree should cover entire subframe */
2929 proto_item_set_len(subframe_ti, bit_offset/8);
2930 /* Append summary info to subframe label */
2931 proto_item_append_text(subframe_ti, " (%u bits in %u MAC-d PDUs)",
2932 bits_in_subframe, mac_d_pdus_in_subframe);
2934 total_pdus += mac_d_pdus_in_subframe;
2935 total_bits += bits_in_subframe;
2937 offset += (bit_offset/8);
2940 /* Report number of subframes in info column
2941 * do this only if no other dissector was called */
2942 if (dissected == false) {
2943 col_append_fstr(pinfo->cinfo, COL_INFO,
2944 " CFN = %03u (%u bits in %u pdus in %u subframes)",
2945 cfn, total_bits, total_pdus, number_of_subframes);
2947 /* Add data summary to info column */
2948 /*col_append_fstr(pinfo->cinfo, COL_INFO, " (%u bytes in %u SDUs in %u MAC-is PDUs in %u subframes)",
2949 total_bytes, macis_sdus_found, macis_pdus, number_of_subframes);*/
2950 if (preferences_header_checksum) {
2951 verify_header_crc_edch(tvb, pinfo, header_crc_pi, header_crc, header_length);
2953 /* Spare extension and payload CRC (optional) */
2954 dissect_spare_extension_and_crc(tvb, pinfo, tree,
2955 p_fp_info->dch_crc_present, offset, header_length);
2959 /* Dissect the remainder of the T2 or common frame that differs from T1 */
2960 static void
2961 dissect_e_dch_t2_or_common_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2962 int offset, struct fp_info *p_fp_info,
2963 int number_of_subframes,
2964 bool is_common,
2965 uint16_t header_crc,
2966 proto_item * header_crc_pi,
2967 void *data)
2969 int n;
2970 int pdu_no;
2971 uint64_t total_macis_sdus;
2972 uint16_t macis_sdus_found = 0;
2973 /* uint16_t macis_pdus = 0; */
2974 bool F = true; /* We want to continue loop if get E-RNTI indication... */
2975 int bit_offset;
2976 proto_item *subframe_macis_descriptors_ti = NULL;
2977 static struct edch_t2_subframe_info subframes[16];
2978 unsigned header_length = 0;
2979 /* User Buffer size */
2980 proto_tree_add_bits_item(tree, hf_fp_edch_user_buffer_size, tvb, offset*8,
2981 18, ENC_BIG_ENDIAN);
2982 offset += 2;
2984 /* Spare is in-between... */
2986 /* Total number of MAC-is SDUs */
2987 proto_tree_add_bits_ret_val(tree, hf_fp_edch_no_macid_sdus, tvb, offset*8+4,
2988 12, &total_macis_sdus, ENC_BIG_ENDIAN);
2989 offset += 2;
2991 if (is_common) {
2992 /* E-RNTI */
2993 proto_tree_add_item(tree, hf_fp_edch_e_rnti, tvb, offset, 2, ENC_BIG_ENDIAN);
2994 offset += 2;
2997 bit_offset = offset*8;
2998 /* EDCH subframe header list */
2999 for (n=0; n < number_of_subframes; n++) {
3000 uint64_t subframe_number;
3001 uint64_t no_of_macis_pdus;
3002 proto_item *subframe_header_ti;
3003 proto_tree *subframe_header_tree;
3005 /* Add subframe header subtree */
3006 subframe_header_ti = proto_tree_add_string_format(tree, hf_fp_edch_subframe_header, tvb, offset, 0,
3007 "", "Subframe");
3008 subframe_header_tree = proto_item_add_subtree(subframe_header_ti, ett_fp_edch_subframe_header);
3010 /* Spare bit */
3011 bit_offset++;
3013 if (!is_common) {
3014 /* Number of HARQ Retransmissions */
3015 proto_tree_add_item(subframe_header_tree, hf_fp_edch_harq_retransmissions, tvb,
3016 bit_offset/8, 1, ENC_BIG_ENDIAN);
3017 bit_offset += 4;
3020 /* Subframe number */
3021 proto_tree_add_bits_ret_val(subframe_header_tree, hf_fp_edch_subframe_number, tvb,
3022 bit_offset, 3, &subframe_number, ENC_BIG_ENDIAN);
3023 subframes[n].subframe_number = (uint8_t)subframe_number;
3024 bit_offset += 3;
3026 /* Number of MAC-is PDUs */
3027 proto_tree_add_bits_ret_val(subframe_header_tree, hf_fp_edch_number_of_mac_is_pdus, tvb,
3028 bit_offset, 4, &no_of_macis_pdus, ENC_BIG_ENDIAN);
3029 bit_offset += 4;
3030 subframes[n].number_of_mac_is_pdus = (uint8_t)no_of_macis_pdus;
3031 /* macis_pdus += subframes[n].number_of_mac_is_pdus; */
3033 /* Next 4 bits are spare for T2*/
3034 if (!is_common) {
3035 bit_offset += 4;
3038 /* Show summary in root */
3039 proto_item_append_text(subframe_header_ti, " (SFN %u, %u MAC-is PDUs)",
3040 subframes[n].subframe_number, subframes[n].number_of_mac_is_pdus);
3041 proto_item_set_len(subframe_header_ti, is_common ? 1 : 2);
3043 offset = bit_offset / 8;
3046 /* MAC-is PDU descriptors for each subframe follow */
3047 for (n=0; n < number_of_subframes; n++) {
3048 proto_tree *subframe_macis_descriptors_tree;
3050 /* Add subframe header subtree */
3051 subframe_macis_descriptors_ti = proto_tree_add_string_format(tree, hf_fp_edch_macis_descriptors, tvb, offset, 0,
3052 "", "MAC-is descriptors (SFN %u)", subframes[n].subframe_number);
3053 proto_item_set_len(subframe_macis_descriptors_ti, subframes[n].number_of_mac_is_pdus*2);
3054 subframe_macis_descriptors_tree = proto_item_add_subtree(subframe_macis_descriptors_ti,
3055 ett_fp_edch_macis_descriptors);
3057 /* Find a sequence of descriptors for each MAC-is PDU in this subframe */
3058 for (pdu_no=0; pdu_no < subframes[n].number_of_mac_is_pdus; pdu_no++) {
3059 proto_item *f_ti = NULL;
3061 subframes[n].number_of_mac_is_sdus[pdu_no] = 0;
3063 do {
3064 /* Check we haven't gone past the limit */
3065 if (macis_sdus_found++ > total_macis_sdus) {
3066 expert_add_info_format(pinfo, f_ti, &ei_fp_mac_is_sdus_miscount, "Found too many (%u) MAC-is SDUs - header said there were %u", macis_sdus_found, (uint16_t)total_macis_sdus);
3069 /* LCH-ID */
3070 subframes[n].mac_is_lchid[pdu_no][subframes[n].number_of_mac_is_sdus[pdu_no]] = (tvb_get_uint8(tvb, offset) & 0xf0) >> 4;
3071 proto_tree_add_item(subframe_macis_descriptors_tree, hf_fp_edch_macis_lchid, tvb, offset, 1, ENC_BIG_ENDIAN);
3072 if (subframes[n].mac_is_lchid[pdu_no][subframes[n].number_of_mac_is_sdus[pdu_no]] == 15) {
3073 proto_item *ti;
3075 /* 4 bits of spare */
3076 offset++;
3078 /* E-RNTI */
3079 ti = proto_tree_add_item(tree, hf_fp_edch_e_rnti, tvb, offset, 2, ENC_BIG_ENDIAN);
3080 offset += 2;
3082 /* This is only allowed if:
3083 - it's the common case AND
3084 - it's the first descriptor */
3085 if (!is_common) {
3086 expert_add_info(pinfo, ti, &ei_fp_e_rnti_t2_edch_frames);
3088 if (subframes[n].number_of_mac_is_sdus[pdu_no] > 0) {
3089 expert_add_info(pinfo, ti, &ei_fp_e_rnti_first_entry);
3091 continue;
3094 /* Length */
3095 subframes[n].mac_is_length[pdu_no][subframes[n].number_of_mac_is_sdus[pdu_no]] = (tvb_get_ntohs(tvb, offset) & 0x0ffe) >> 1;
3096 proto_tree_add_item(subframe_macis_descriptors_tree, hf_fp_edch_macis_length, tvb, offset, 2, ENC_BIG_ENDIAN);
3097 offset++;
3099 /* Flag */
3100 F = tvb_get_uint8(tvb, offset) & 0x01;
3101 f_ti = proto_tree_add_item(subframe_macis_descriptors_tree, hf_fp_edch_macis_flag, tvb, offset, 1, ENC_BIG_ENDIAN);
3103 subframes[n].number_of_mac_is_sdus[pdu_no]++;
3105 offset++;
3106 } while (F == 0);
3110 /* Check overall count of MAC-is SDUs */
3111 if (macis_sdus_found != total_macis_sdus) {
3112 expert_add_info_format(pinfo, subframe_macis_descriptors_ti, &ei_fp_mac_is_sdus_miscount, "Frame contains %u MAC-is SDUs - header said there would be %u!", macis_sdus_found, (uint16_t)total_macis_sdus);
3114 header_length = offset;
3115 /* Now PDUs */
3116 for (n=0; n < number_of_subframes; n++) {
3118 /* MAC-is PDU */
3119 for (pdu_no=0; pdu_no < subframes[n].number_of_mac_is_pdus; pdu_no++) {
3120 int i;
3121 unsigned length = 0;
3122 umts_mac_is_info * mac_is_info = wmem_new(wmem_file_scope(), umts_mac_is_info);
3124 mac_is_info->number_of_mac_is_sdus = subframes[n].number_of_mac_is_sdus[pdu_no];
3125 DISSECTOR_ASSERT(subframes[n].number_of_mac_is_sdus[pdu_no] <= MAX_MAC_FRAMES);
3126 for (i = 0; i < subframes[n].number_of_mac_is_sdus[pdu_no]; i++) {
3127 mac_is_info->sdulength[i] = subframes[n].mac_is_length[pdu_no][i];
3128 mac_is_info->lchid[i] = subframes[n].mac_is_lchid[pdu_no][i];
3129 length += subframes[n].mac_is_length[pdu_no][i];
3132 /* Call MAC for this PDU if configured to */
3133 if (preferences_call_mac_dissectors) {
3134 p_add_proto_data(wmem_file_scope(), pinfo, proto_umts_mac, 0, mac_is_info);
3135 call_dissector_with_data(mac_fdd_edch_type2_handle, tvb_new_subset_remaining(tvb, offset), pinfo, top_level_tree, data);
3137 else {
3138 /* Still show data if not decoding as MAC PDU */
3139 proto_tree_add_item(tree, hf_fp_edch_mac_is_pdu, tvb, offset, length, ENC_NA);
3142 /* get_mac_tsn_size in packet-umts_mac.h, gets the global_mac_tsn_size preference in umts_mac.c */
3143 if (get_mac_tsn_size() == MAC_TSN_14BITS) {
3144 offset += length + 2; /* Plus 2 bytes for TSN 14 bits and SS 2 bit. */
3145 } else {
3146 offset += length + 1; /* Plus 1 byte for TSN 6 bits and SS 2 bit. */
3150 if (preferences_header_checksum) {
3151 verify_header_crc_edch(tvb, pinfo, header_crc_pi, header_crc, header_length);
3153 /* Spare extension and payload CRC (optional) */
3154 dissect_spare_extension_and_crc(tvb, pinfo, tree,
3155 p_fp_info->dch_crc_present, offset, header_length);
3160 /**********************************************************/
3161 /* Dissect an HSDSCH channel */
3162 /* The data format corresponds to the format */
3163 /* described in R5 and R6, and frame type 1 in Release 7. */
3164 static void
3165 dissect_hsdsch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
3166 int offset, struct fp_info *p_fp_info, void *data)
3168 uint32_t ft;
3169 unsigned header_length;
3170 uint32_t header_crc = 0;
3171 proto_item * header_crc_pi = NULL;
3173 /* Header CRC */
3174 header_crc_pi = proto_tree_add_item_ret_uint(tree, hf_fp_header_crc, tvb, offset, 1, ENC_BIG_ENDIAN, &header_crc);
3176 /* Frame Type */
3177 proto_tree_add_item_ret_uint(tree, hf_fp_ft, tvb, offset, 1, ENC_BIG_ENDIAN, &ft);
3178 offset++;
3180 col_append_fstr(pinfo->cinfo, COL_INFO, " [%s] ", val_to_str_const(ft, frame_type_vals, "Unknown"));
3182 if (ft == FT_CONTROL) {
3183 dissect_common_control(tvb, pinfo, tree, offset, p_fp_info);
3184 /* For control frame the header CRC is actually frame CRC covering all
3185 * bytes except the first */
3186 if (preferences_header_checksum) {
3187 verify_control_frame_crc(tvb, pinfo, header_crc_pi, (uint16_t)header_crc);
3190 else {
3191 uint8_t number_of_pdus;
3192 uint16_t pdu_length;
3193 uint16_t user_buffer_size;
3194 int i;
3195 umts_mac_info *macinf;
3196 rlc_info *rlcinf;
3197 uint32_t user_identity;
3198 proto_item *item;
3200 rlcinf = (rlc_info *)p_get_proto_data(wmem_file_scope(), pinfo, proto_umts_rlc, 0);
3201 if (!rlcinf) {
3202 rlcinf = wmem_new0(wmem_packet_scope(), rlc_info);
3204 macinf = (umts_mac_info *)p_get_proto_data(wmem_file_scope(), pinfo, proto_umts_mac, 0);
3205 if (!macinf) {
3206 macinf = wmem_new0(wmem_packet_scope(), umts_mac_info);
3209 /**************************************/
3210 /* HS-DCH data here (type 1 in R7) */
3212 /* Frame Seq Nr */
3213 if ((p_fp_info->release == 6) ||
3214 (p_fp_info->release == 7)) {
3216 uint8_t frame_seq_no = (tvb_get_uint8(tvb, offset) & 0xf0) >> 4;
3217 proto_tree_add_item(tree, hf_fp_frame_seq_nr, tvb, offset, 1, ENC_BIG_ENDIAN);
3219 col_append_fstr(pinfo->cinfo, COL_INFO, " seqno=%u", frame_seq_no);
3222 /* CmCH-PI */
3223 proto_tree_add_item(tree, hf_fp_cmch_pi, tvb, offset, 1, ENC_BIG_ENDIAN);
3224 offset++;
3226 /* MAC-d PDU Length (13 bits) */
3227 pdu_length = (tvb_get_ntohs(tvb, offset) >> 3);
3228 proto_tree_add_item(tree, hf_fp_mac_d_pdu_len, tvb, offset, 2, ENC_BIG_ENDIAN);
3229 offset += 2;
3230 macinf->pdu_len = pdu_length;
3232 if ((p_fp_info->release == 6) ||
3233 (p_fp_info->release == 7)) {
3235 /* Flush bit */
3236 proto_tree_add_item(tree, hf_fp_flush, tvb, offset-1, 1, ENC_BIG_ENDIAN);
3238 /* FSN/DRT reset bit */
3239 proto_tree_add_item(tree, hf_fp_fsn_drt_reset, tvb, offset-1, 1, ENC_BIG_ENDIAN);
3242 /* Num of PDUs */
3243 number_of_pdus = tvb_get_uint8(tvb, offset);
3244 item = proto_tree_add_item(tree, hf_fp_num_of_pdu, tvb, offset, 1, ENC_BIG_ENDIAN);
3245 offset++;
3246 if (number_of_pdus > MAX_MAC_FRAMES) {
3247 expert_add_info_format(pinfo, item, &ei_fp_invalid_frame_count, "Invalid number of PDUs (max is %u)", MAX_MAC_FRAMES);
3248 return;
3251 /* User buffer size */
3252 user_buffer_size = tvb_get_ntohs(tvb, offset);
3253 proto_tree_add_item(tree, hf_fp_user_buffer_size, tvb, offset, 2, ENC_BIG_ENDIAN);
3254 offset += 2;
3256 header_length = offset;
3259 /* Determine the UE ID to use in RLC */
3260 user_identity = p_fp_info->com_context_id;
3261 if(p_fp_info->urnti) {
3262 user_identity = p_fp_info->urnti;
3264 /************************/
3265 /*Configure the pdus*/
3266 for (i=0;i<number_of_pdus && i<MIN(MAX_MAC_FRAMES, MAX_RLC_CHANS); i++) {
3267 macinf->content[i] = hsdsch_macdflow_id_mac_content_map[p_fp_info->hsdsch_macflowd_id]; /*MAC_CONTENT_PS_DTCH;*/
3268 macinf->lchid[i] = fake_lchid_macd_flow[p_fp_info->hsdsch_macflowd_id];/*Faked logical channel id 255 used as a mark if it doesn't exist...*/
3269 macinf->fake_chid[i] = true; /**/
3270 macinf->macdflow_id[i] = p_fp_info->hsdsch_macflowd_id; /*Save the flow ID (+1 to make it human readable (it's zero indexed!))*/
3272 /*Check if this is multiplexed (signaled by RRC)*/
3273 if (p_fp_info->hsdhsch_macfdlow_is_mux[p_fp_info->hsdsch_macflowd_id] ) {
3274 macinf->ctmux[i] = true;
3275 } else if (p_fp_info->hsdsch_macflowd_id == 0) { /*MACd-flow = 0 is often SRB */
3276 expert_add_info(pinfo, NULL, &ei_fp_maybe_srb);
3277 } else {
3278 macinf->ctmux[i] = false; /*Either it's multiplexed and not signalled or it's not MUX*/
3281 /* Figure out RLC mode */
3282 if(p_fp_info->hsdsch_rlc_mode != FP_RLC_MODE_UNKNOWN) {
3283 /* We know the RLC mode, possibly reported from NBAP */
3284 rlcinf->mode[i] = (enum rlc_mode)(p_fp_info->hsdsch_rlc_mode - 1);
3286 else {
3287 /* Guess the mode by the MACd-flow-ID, basically MACd-flow-ID = 0 then it's SRB0 == UM else AM */
3288 /* This logic might be incorrect sometimes */
3289 rlcinf->mode[i] = hsdsch_macdflow_id_rlc_map[p_fp_info->hsdsch_macflowd_id];
3292 rlcinf->ueid[i] = user_identity;
3293 rlcinf->li_size[i] = RLC_LI_7BITS;
3294 rlcinf->deciphered[i] = false;
3295 rlcinf->ciphered[i] = false;
3296 rlcinf->rbid[i] = macinf->lchid[i];
3298 #if 0
3299 /*When a flow has been reconfigured rlc needs to be reset.
3300 * This needs more work though since we must figure out when the re-configuration becomes
3301 * active based on the CFN value
3302 * */
3303 /*Indicate we need to reset stream*/
3304 if (p_fp_info->reset_frag) {
3305 rlc_reset_channel(rlcinf->mode[i], macinf->lchid[i], p_fp_info->is_uplink, rlcinf->ueid[i] );
3306 p_fp_info->reset_frag = false;
3309 #endif
3312 col_append_fstr(pinfo->cinfo, COL_INFO, " %ux%u-bit PDUs User-Buffer-Size=%u",
3313 number_of_pdus, pdu_length, user_buffer_size);
3315 /* MAC-d PDUs */
3316 offset = dissect_macd_pdu_data(tvb, pinfo, tree, offset, pdu_length,
3317 number_of_pdus, p_fp_info, data);
3319 /* Extra IEs (if there is room for them) */
3320 if (((p_fp_info->release == 6) ||
3321 (p_fp_info->release == 7)) &&
3322 (tvb_reported_length_remaining(tvb, offset) > 2)) {
3324 int n;
3325 uint8_t flags;
3326 /* uint8_t flag_bytes = 0; */
3328 /* New IE flags */
3329 do {
3330 proto_item *new_ie_flags_ti;
3331 proto_tree *new_ie_flags_tree;
3332 unsigned ies_found = 0;
3334 /* Add new IE flags subtree */
3335 new_ie_flags_ti = proto_tree_add_string_format(tree, hf_fp_hsdsch_new_ie_flags, tvb, offset, 1,
3336 "", "New IE flags");
3337 new_ie_flags_tree = proto_item_add_subtree(new_ie_flags_ti, ett_fp_hsdsch_new_ie_flags);
3339 /* Read next byte */
3340 flags = tvb_get_uint8(tvb, offset);
3341 /* flag_bytes++; */
3343 /* Dissect individual bits */
3344 for (n=0; n < 8; n++) {
3345 proto_tree_add_item(new_ie_flags_tree, hf_fp_hsdsch_new_ie_flag[n], tvb, offset, 1, ENC_BIG_ENDIAN);
3346 if ((flags >> (7-n)) & 0x01) {
3347 ies_found++;
3350 offset++;
3352 proto_item_append_text(new_ie_flags_ti, " (%u IEs found)", ies_found);
3354 /* Last bit set will indicate another flags byte follows... */
3355 } while (0); /*((flags & 0x01) && (flag_bytes < 31));*/
3357 if (1) /*(flags & 0x8) */ {
3358 /* DRT is shown as mandatory in the diagram (3GPP TS 25.435 V6.3.0),
3359 but the description below it states that
3360 it should depend upon the first bit. The detailed description of
3361 New IE flags doesn't agree, so treat as mandatory for now... */
3362 proto_tree_add_item(tree, hf_fp_hsdsch_drt, tvb, offset, 2, ENC_BIG_ENDIAN);
3363 offset += 2;
3366 if (preferences_header_checksum) {
3367 verify_header_crc(tvb, pinfo, header_crc_pi, header_crc, header_length);
3369 /* Spare Extension and Payload CRC */
3370 dissect_spare_extension_and_crc(tvb, pinfo, tree, 1, offset, header_length);
3375 /******************************************/
3376 /* Dissect an HSDSCH type 2 channel */
3377 /* (introduced in Release 7) */
3378 /* N.B. there is currently no support for */
3379 /* frame type 3 (IuR only?) */
3380 static void
3381 dissect_hsdsch_type_2_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
3382 int offset, struct fp_info *p_fp_info,
3383 void *data)
3385 uint32_t ft;
3386 uint32_t header_crc = 0;
3387 proto_item * header_crc_pi = NULL;
3388 uint16_t header_length;
3390 /* Header CRC */
3391 header_crc_pi = proto_tree_add_item_ret_uint(tree, hf_fp_header_crc, tvb, offset, 1, ENC_BIG_ENDIAN, &header_crc);
3393 /* Frame Type */
3394 proto_tree_add_item_ret_uint(tree, hf_fp_ft, tvb, offset, 1, ENC_BIG_ENDIAN, &ft);
3395 offset++;
3397 col_append_fstr(pinfo->cinfo, COL_INFO, " [%s] ", val_to_str_const(ft, frame_type_vals, "Unknown"));
3399 if (ft == FT_CONTROL) {
3400 dissect_common_control(tvb, pinfo, tree, offset, p_fp_info);
3401 /* For control frame the header CRC is actually frame CRC covering all
3402 * bytes except the first */
3403 if (preferences_header_checksum) {
3404 verify_control_frame_crc(tvb, pinfo, header_crc_pi, (uint16_t)header_crc);
3407 else {
3408 uint8_t number_of_pdu_blocks;
3409 bool drt_present = false;
3410 bool fach_present = false;
3411 uint16_t user_buffer_size;
3412 int n;
3413 unsigned j;
3414 uint64_t lchid_val;
3416 #define MAX_PDU_BLOCKS 31
3417 uint64_t lchid_field[MAX_PDU_BLOCKS];
3418 uint64_t pdu_length[MAX_PDU_BLOCKS];
3419 uint64_t no_of_pdus[MAX_PDU_BLOCKS];
3421 umts_mac_info *macinf;
3422 rlc_info *rlcinf;
3423 uint32_t user_identity;
3425 rlcinf = (rlc_info *)p_get_proto_data(wmem_file_scope(), pinfo, proto_umts_rlc, 0);
3426 if (!rlcinf) {
3427 rlcinf = wmem_new0(wmem_packet_scope(), rlc_info);
3429 macinf = (umts_mac_info *)p_get_proto_data(wmem_file_scope(), pinfo, proto_umts_mac, 0);
3430 if (!macinf) {
3431 macinf = wmem_new0(wmem_packet_scope(), umts_mac_info);
3434 /********************************/
3435 /* HS-DCH type 2 data here */
3437 col_append_str(pinfo->cinfo, COL_INFO, "(ehs)");
3439 /* Frame Seq Nr (4 bits) */
3440 if ((p_fp_info->release == 6) ||
3441 (p_fp_info->release == 7)) {
3443 uint8_t frame_seq_no = (tvb_get_uint8(tvb, offset) & 0xf0) >> 4;
3444 proto_tree_add_item(tree, hf_fp_frame_seq_nr, tvb, offset, 1, ENC_BIG_ENDIAN);
3446 col_append_fstr(pinfo->cinfo, COL_INFO, " seqno=%u", frame_seq_no);
3449 /* CmCH-PI (4 bits) */
3450 proto_tree_add_item(tree, hf_fp_cmch_pi, tvb, offset, 1, ENC_BIG_ENDIAN);
3451 offset++;
3453 /* Total number of PDU blocks (5 bits) */
3454 number_of_pdu_blocks = (tvb_get_uint8(tvb, offset) >> 3);
3455 proto_tree_add_item(tree, hf_fp_total_pdu_blocks, tvb, offset, 1, ENC_BIG_ENDIAN);
3457 if (p_fp_info->release == 7) {
3458 /* Flush bit */
3459 proto_tree_add_item(tree, hf_fp_flush, tvb, offset, 1, ENC_BIG_ENDIAN);
3461 /* FSN/DRT reset bit */
3462 proto_tree_add_item(tree, hf_fp_fsn_drt_reset, tvb, offset, 1, ENC_BIG_ENDIAN);
3464 /* DRT Indicator */
3465 drt_present = tvb_get_uint8(tvb, offset) & 0x01;
3466 proto_tree_add_item(tree, hf_fp_drt_indicator, tvb, offset, 1, ENC_BIG_ENDIAN);
3468 offset++;
3470 /* FACH Indicator flag */
3471 fach_present = (tvb_get_uint8(tvb, offset) & 0x80) >> 7;
3472 proto_tree_add_item(tree, hf_fp_fach_indicator, tvb, offset, 1, ENC_BIG_ENDIAN);
3473 offset++;
3475 /* User buffer size */
3476 user_buffer_size = tvb_get_ntohs(tvb, offset);
3477 proto_tree_add_item(tree, hf_fp_user_buffer_size, tvb, offset, 2, ENC_BIG_ENDIAN);
3478 offset += 2;
3480 col_append_fstr(pinfo->cinfo, COL_INFO, " User-Buffer-Size=%u", user_buffer_size);
3484 /********************************************************************/
3485 /* Now read number_of_pdu_blocks header entries */
3486 for (n=0; n < number_of_pdu_blocks; n++) {
3487 proto_item *pdu_block_header_ti;
3488 proto_tree *pdu_block_header_tree;
3489 int block_header_start_offset = offset;
3491 /* Add PDU block header subtree */
3492 pdu_block_header_ti = proto_tree_add_string_format(tree, hf_fp_hsdsch_pdu_block_header,
3493 tvb, offset, 0,
3495 "PDU Block Header");
3496 pdu_block_header_tree = proto_item_add_subtree(pdu_block_header_ti,
3497 ett_fp_hsdsch_pdu_block_header);
3499 /* MAC-d/c PDU length in this block (11 bits) */
3500 proto_tree_add_bits_ret_val(pdu_block_header_tree, hf_fp_pdu_length_in_block, tvb,
3501 (offset*8) + ((n % 2) ? 4 : 0), 11,
3502 &pdu_length[n], ENC_BIG_ENDIAN);
3503 if ((n % 2) == 0)
3504 offset++;
3505 else
3506 offset += 2;
3509 /* # PDUs in this block (4 bits) */
3510 proto_tree_add_bits_ret_val(pdu_block_header_tree, hf_fp_pdus_in_block, tvb,
3511 (offset*8) + ((n % 2) ? 0 : 4), 4,
3512 &no_of_pdus[n], ENC_BIG_ENDIAN);
3513 if ((n % 2) == 0) {
3514 offset++;
3517 /* Logical channel ID in block (4 bits) */
3518 proto_tree_add_bits_ret_val(pdu_block_header_tree, hf_fp_lchid, tvb,
3519 (offset*8) + ((n % 2) ? 4 : 0), 4,
3520 &lchid_field[n], ENC_BIG_ENDIAN);
3521 if ((n % 2) == 1) {
3522 offset++;
3524 else {
3525 if (n == (number_of_pdu_blocks-1)) {
3526 /* Byte is padded out for last block */
3527 offset++;
3531 /* Append summary to header tree root */
3532 proto_item_append_text(pdu_block_header_ti,
3533 " (lch:%u, %u pdus of %u bytes)",
3534 (uint16_t)lchid_field[n],
3535 (uint16_t)no_of_pdus[n],
3536 (uint16_t)pdu_length[n]);
3538 /* Set length of header tree item */
3539 if (((n % 2) == 0) && (n < (number_of_pdu_blocks-1))) {
3540 proto_item_set_len(pdu_block_header_ti,
3541 offset - block_header_start_offset+1);
3543 else {
3544 proto_item_set_len(pdu_block_header_ti,
3545 offset - block_header_start_offset);
3549 header_length = offset;
3551 /**********************************************/
3552 /* Optional fields indicated by earlier flags */
3553 if (drt_present) {
3554 /* DRT */
3555 proto_tree_add_item(tree, hf_fp_drt, tvb, offset, 2, ENC_BIG_ENDIAN);
3556 offset += 2;
3559 if (fach_present) {
3560 /* H-RNTI: */
3561 proto_tree_add_item(tree, hf_fp_hrnti, tvb, offset, 2, ENC_BIG_ENDIAN);
3562 offset += 2;
3564 /* RACH Measurement Result */
3565 proto_tree_add_item(tree, hf_fp_rach_measurement_result, tvb, offset, 2, ENC_BIG_ENDIAN);
3566 offset++;
3570 /* Determine the UE ID to use in RLC */
3571 user_identity = p_fp_info->com_context_id;
3572 if(p_fp_info->urnti) {
3573 user_identity = p_fp_info->urnti;
3575 /********************************************************************/
3576 /* Now read the MAC-d/c PDUs for each block using info from headers */
3577 for (n=0; n < number_of_pdu_blocks; n++) {
3578 for (j=0;j<no_of_pdus[n];j++) {
3580 /*Configure (signal to lower layers) the PDU!*/
3581 if (lchid_field[n] != 0x0f) {
3582 lchid_val = lchid_field[n] + 1; /* Add 1 since 'LCHID' field is zero indexed. ie field value = 0 => Actual L-CHID = 1*/
3583 macinf->content[j] = lchId_type_table[lchid_val];
3584 macinf->lchid[j] = (uint8_t)lchid_val;
3585 macinf->macdflow_id[j] = p_fp_info->hsdsch_macflowd_id;
3586 /*Figure out RLC_MODE based on MACd-flow-ID, basically MACd-flow-ID = 0 then it's SRB0 == UM else AM*/
3587 rlcinf->mode[j] = lchId_rlc_map[lchid_val];
3589 macinf->ctmux[n] = false;
3591 rlcinf->li_size[j] = RLC_LI_7BITS;
3592 rlcinf->ciphered[j] = false;
3593 rlcinf->deciphered[j] = false;
3594 rlcinf->rbid[j] = (uint8_t)lchid_val;
3596 rlcinf->ueid[j] = user_identity;
3598 else {
3599 /* LCHID field is 15. This value indicates BCCH or PCCH mapped on HS-DSCH*/
3600 /* The dissector does not handle this case yet, so we are filling zeroes and default values below*/
3601 macinf->content[j] = MAC_CONTENT_UNKNOWN;
3602 macinf->lchid[j] = 0; /* LCHID field doesn't reflect a real ID in this case*/
3603 macinf->macdflow_id[j] = 0;
3604 macinf->ctmux[j] = false;
3606 rlcinf->mode[j] = RLC_TM; /* PCCH and BCCH should be using RLC TM? */
3607 rlcinf->li_size[j] = RLC_LI_7BITS;
3608 rlcinf->ciphered[j] = false;
3609 rlcinf->deciphered[j] = false;
3610 rlcinf->rbid[j] = 0;
3611 rlcinf->ueid[j] = 0;
3615 /* Add PDU block header subtree */
3616 offset = dissect_macd_pdu_data_type_2(tvb, pinfo, tree, offset,
3617 (uint16_t)pdu_length[n],
3618 (uint16_t)no_of_pdus[n],
3619 p_fp_info, data);
3621 if (preferences_header_checksum) {
3622 verify_header_crc(tvb, pinfo, header_crc_pi, header_crc, header_length);
3624 /* Spare Extension and Payload CRC */
3625 dissect_spare_extension_and_crc(tvb, pinfo, tree, 1, offset, header_length);
3629 * Dissect and CONFIGURE hsdsch_common channel.
3631 * This will dissect hsdsch common channels of type 2, so this is
3632 * very similar to regular type two (ehs) the difference being how
3633 * the configuration is done. NOTE: VERY EXPERIMENTAL.
3635 * @param tvb the tv buffer of the current data
3636 * @param pinfo the packet info of the current data
3637 * @param tree the tree to append this item to
3638 * @param offset the offset in the tvb
3639 * @param p_fp_info FP-packet information
3641 static
3642 void dissect_hsdsch_common_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
3643 int offset, struct fp_info *p_fp_info,
3644 void *data)
3646 uint32_t ft;
3647 uint32_t header_crc = 0;
3648 proto_item * header_crc_pi = NULL;
3649 unsigned header_length;
3651 /* Header CRC */
3652 header_crc_pi = proto_tree_add_item_ret_uint(tree, hf_fp_header_crc, tvb, offset, 1, ENC_BIG_ENDIAN, &header_crc);
3654 /* Frame Type */
3655 proto_tree_add_item_ret_uint(tree, hf_fp_ft, tvb, offset, 1, ENC_BIG_ENDIAN, &ft);
3656 offset++;
3658 col_append_fstr(pinfo->cinfo, COL_INFO, " [%s] ", val_to_str_const(ft, frame_type_vals, "Unknown"));
3660 if (ft == FT_CONTROL) {
3661 dissect_common_control(tvb, pinfo, tree, offset, p_fp_info);
3662 /* For control frame the header CRC is actually frame CRC covering all
3663 * bytes except the first */
3664 if (preferences_header_checksum) {
3665 verify_control_frame_crc(tvb, pinfo, header_crc_pi, (uint16_t)header_crc);
3668 else {
3669 uint8_t number_of_pdu_blocks;
3670 bool drt_present = false;
3671 bool fach_present = false;
3672 uint16_t user_buffer_size;
3673 int n;
3674 unsigned j;
3676 #define MAX_PDU_BLOCKS 31
3677 uint64_t lchid[MAX_PDU_BLOCKS];
3678 uint64_t pdu_length[MAX_PDU_BLOCKS];
3679 uint64_t no_of_pdus[MAX_PDU_BLOCKS];
3680 uint8_t newieflags = 0;
3682 umts_mac_info *macinf;
3683 rlc_info *rlcinf;
3685 rlcinf = (rlc_info *)p_get_proto_data(wmem_file_scope(), pinfo, proto_umts_rlc, 0);
3686 if (!rlcinf) {
3687 rlcinf = wmem_new0(wmem_packet_scope(), rlc_info);
3689 macinf = (umts_mac_info *)p_get_proto_data(wmem_file_scope(), pinfo, proto_umts_mac, 0);
3690 if (!macinf) {
3691 macinf = wmem_new0(wmem_packet_scope(), umts_mac_info);
3693 /********************************/
3694 /* HS-DCH type 2 data here */
3696 col_append_str(pinfo->cinfo, COL_INFO, "(ehs)");
3698 /* Frame Seq Nr (4 bits) */
3699 if ((p_fp_info->release == 6) ||
3700 (p_fp_info->release == 7)) {
3702 uint8_t frame_seq_no = (tvb_get_uint8(tvb, offset) & 0xf0) >> 4;
3703 proto_tree_add_item(tree, hf_fp_frame_seq_nr, tvb, offset, 1, ENC_BIG_ENDIAN);
3705 col_append_fstr(pinfo->cinfo, COL_INFO, " seqno=%u", frame_seq_no);
3708 /* CmCH-PI (4 bits) */
3709 proto_tree_add_item(tree, hf_fp_cmch_pi, tvb, offset, 1, ENC_BIG_ENDIAN);
3710 offset++;
3712 /* Total number of PDU blocks (5 bits) */
3713 number_of_pdu_blocks = (tvb_get_uint8(tvb, offset) >> 3);
3714 proto_tree_add_item(tree, hf_fp_total_pdu_blocks, tvb, offset, 1, ENC_BIG_ENDIAN);
3716 if (p_fp_info->release == 7) {
3717 /* Flush bit */
3718 proto_tree_add_item(tree, hf_fp_flush, tvb, offset, 1, ENC_BIG_ENDIAN);
3720 /* FSN/DRT reset bit */
3721 proto_tree_add_item(tree, hf_fp_fsn_drt_reset, tvb, offset, 1, ENC_BIG_ENDIAN);
3723 /* DRT Indicator */
3724 drt_present = tvb_get_uint8(tvb, offset) & 0x01;
3725 proto_tree_add_item(tree, hf_fp_drt_indicator, tvb, offset, 1, ENC_BIG_ENDIAN);
3727 offset++;
3729 /* FACH Indicator flag */
3730 fach_present = (tvb_get_uint8(tvb, offset) & 0x80) >> 7;
3731 proto_tree_add_item(tree, hf_fp_fach_indicator, tvb, offset, 1, ENC_BIG_ENDIAN);
3732 offset++;
3734 /* User buffer size */
3735 user_buffer_size = tvb_get_ntohs(tvb, offset);
3736 proto_tree_add_item(tree, hf_fp_user_buffer_size, tvb, offset, 2, ENC_BIG_ENDIAN);
3737 offset += 2;
3739 col_append_fstr(pinfo->cinfo, COL_INFO, " User-Buffer-Size=%u", user_buffer_size);
3742 /********************************************************************/
3743 /* Now read number_of_pdu_blocks header entries */
3744 for (n=0; n < number_of_pdu_blocks; n++) {
3745 proto_item *pdu_block_header_ti;
3746 proto_item *item;
3747 proto_tree *pdu_block_header_tree;
3748 int block_header_start_offset = offset;
3750 /* Add PDU block header subtree */
3751 pdu_block_header_ti = proto_tree_add_string_format(tree, hf_fp_hsdsch_pdu_block_header,
3752 tvb, offset, 0,
3754 "PDU Block Header");
3755 pdu_block_header_tree = proto_item_add_subtree(pdu_block_header_ti,
3756 ett_fp_hsdsch_pdu_block_header);
3758 /* MAC-d/c PDU length in this block (11 bits) */
3759 proto_tree_add_bits_ret_val(pdu_block_header_tree, hf_fp_pdu_length_in_block, tvb,
3760 (offset*8) + ((n % 2) ? 4 : 0), 11,
3761 &pdu_length[n], ENC_BIG_ENDIAN);
3762 if ((n % 2) == 0)
3763 offset++;
3764 else
3765 offset += 2;
3768 /* # PDUs in this block (4 bits) */
3769 item = proto_tree_add_bits_ret_val(pdu_block_header_tree, hf_fp_pdus_in_block, tvb,
3770 (offset*8) + ((n % 2) ? 0 : 4), 4,
3771 &no_of_pdus[n], ENC_BIG_ENDIAN);
3772 if ((n % 2) == 0) {
3773 offset++;
3775 if (no_of_pdus[n] > MAX_MAC_FRAMES) {
3776 expert_add_info_format(pinfo, item, &ei_fp_invalid_frame_count, "Invalid number of PDUs (max is %u)", MAX_MAC_FRAMES);
3777 return;
3780 /* Logical channel ID in block (4 bits) */
3781 proto_tree_add_bits_ret_val(pdu_block_header_tree, hf_fp_lchid, tvb,
3782 (offset*8) + ((n % 2) ? 4 : 0), 4,
3783 &lchid[n], ENC_BIG_ENDIAN);
3784 if ((n % 2) == 1) {
3785 offset++;
3787 else {
3788 if (n == (number_of_pdu_blocks-1)) {
3789 /* Byte is padded out for last block */
3790 offset++;
3794 /* Append summary to header tree root */
3795 proto_item_append_text(pdu_block_header_ti,
3796 " (lch:%u, %u pdus of %u bytes)",
3797 (uint16_t)lchid[n],
3798 (uint16_t)no_of_pdus[n],
3799 (uint16_t)pdu_length[n]);
3801 /* Set length of header tree item */
3802 if (((n % 2) == 0) && (n < (number_of_pdu_blocks-1))) {
3803 proto_item_set_len(pdu_block_header_ti,
3804 offset - block_header_start_offset+1);
3806 else {
3807 proto_item_set_len(pdu_block_header_ti,
3808 offset - block_header_start_offset);
3812 header_length = offset;
3814 /**********************************************/
3815 /* Optional fields indicated by earlier flags */
3816 if (drt_present) {
3817 /* DRT */
3818 proto_tree_add_item(tree, hf_fp_drt, tvb, offset, 2, ENC_BIG_ENDIAN);
3819 offset += 2;
3822 if (fach_present) {
3823 /* H-RNTI: */
3824 proto_tree_add_item(tree, hf_fp_hrnti, tvb, offset, 2, ENC_BIG_ENDIAN);
3825 offset += 2;
3827 /* RACH Measurement Result */
3828 proto_tree_add_item(tree, hf_fp_rach_measurement_result, tvb, offset, 1, ENC_BIG_ENDIAN);
3829 offset++;
3832 /********************************************************************/
3833 /* Now read the MAC-d/c PDUs for each block using info from headers */
3834 for (n=0; n < number_of_pdu_blocks; n++) {
3835 tvbuff_t *next_tvb;
3836 for (j=0; j<no_of_pdus[n]; j++) {
3837 /* If all bits are set, then this is BCCH or PCCH according to: 25.435 paragraph: 6.2.7.31 */
3838 if (lchid[n] == 0xF) {
3839 /* In the very few test cases I've seen, this seems to be
3840 * BCCH with transparent MAC layer. Therefore skip right to
3841 * rlc_bcch and hope for the best. */
3842 next_tvb = tvb_new_subset_length(tvb, offset, (int)pdu_length[n]);
3843 call_dissector_with_data(rlc_bcch_handle, next_tvb, pinfo, top_level_tree, data);
3844 offset += (int)pdu_length[n];
3845 } else { /* Else go for CCCH UM, this seems to work. */
3846 p_fp_info->hsdsch_entity = ehs; /* HSDSCH type 2 */
3847 if (j >= MAX_MAC_FRAMES) {
3848 /* Should not happen as we check no_of_pdus[n]*/
3849 expert_add_info_format(pinfo, tree, &ei_fp_invalid_frame_count, "Invalid frame count (max is %u)", MAX_MAC_FRAMES);
3850 return;
3852 p_fp_info->cur_tb = j; /* set cur_tb for MAC and RRC */
3853 macinf->content[j] = MAC_CONTENT_CCCH;
3854 macinf->lchid[j] = (uint8_t)lchid[n]+1; /*Add 1 since it is zero indexed? */
3855 macinf->macdflow_id[j] = p_fp_info->hsdsch_macflowd_id;
3856 macinf->ctmux[j] = false;
3858 rlcinf->li_size[j] = RLC_LI_7BITS;
3859 rlcinf->ciphered[j] = false;
3860 rlcinf->deciphered[j] = false;
3861 rlcinf->rbid[j] = (uint8_t)lchid[n]+1;
3862 rlcinf->ueid[j] = p_fp_info->channel; /*We need to fake "UE ID"*/
3864 next_tvb = tvb_new_subset_length(tvb, offset, (int)pdu_length[n]);
3865 call_dissector_with_data(mac_fdd_hsdsch_handle, next_tvb, pinfo, top_level_tree, data);
3867 offset += (int)pdu_length[n];
3872 /* New IE Flags */
3873 newieflags = tvb_get_uint8(tvb, offset);
3874 /* If newieflags == 0000 0010 then this indicates that there is a
3875 * HS-DSCH physical layer category and no other New IE flags. */
3876 if (newieflags == 2) {
3877 /* HS-DSCH physical layer category presence bit. */
3878 proto_tree_add_uint(tree, hf_fp_hsdsch_new_ie_flag[6], tvb, offset, 1, newieflags);
3879 offset++;
3880 /* HS-DSCH physical layer category. */
3881 proto_tree_add_bits_item(tree, hf_fp_hsdsch_physical_layer_category, tvb, offset*8, 6, ENC_BIG_ENDIAN);
3882 offset++;
3884 if (preferences_header_checksum) {
3885 verify_header_crc(tvb, pinfo, header_crc_pi, header_crc, header_length);
3887 /* Spare Extension and Payload CRC */
3888 dissect_spare_extension_and_crc(tvb, pinfo, tree, 1, offset, header_length);
3891 /* Validates the header CRC in a Control FP frame */
3892 /* Should only be used in heuristic dissectors! */
3893 static bool
3894 check_control_frame_crc_for_heur(tvbuff_t * tvb)
3896 uint8_t crc = 0;
3897 uint8_t calc_crc = 0;
3898 uint8_t * data = NULL;
3899 unsigned reported_length = tvb_reported_length(tvb);
3901 if (reported_length == 0 || reported_length > tvb_captured_length(tvb))
3902 return false;
3904 crc = tvb_get_uint8(tvb, 0) >> 1;
3905 /* Get data. */
3906 data = (uint8_t *)tvb_memdup(wmem_packet_scope(), tvb, 0, tvb_reported_length(tvb));
3907 /* Include only FT flag bit in CRC calculation. */
3908 data[0] = data[0] & 1;
3909 calc_crc = crc7update(0, data, tvb_reported_length(tvb));
3910 calc_crc = crc7finalize(calc_crc);
3912 return calc_crc == crc;
3914 /* Validates the header CRC in a Data FP frame */
3915 /* Should only be used in heuristic dissectors! */
3916 static bool
3917 check_header_crc_for_heur(tvbuff_t *tvb, uint16_t header_length)
3919 uint8_t crc = 0;
3920 uint8_t calc_crc = 0;
3921 const uint8_t * data = NULL;
3923 if (header_length > tvb_captured_length(tvb))
3924 return false;
3926 crc = tvb_get_uint8(tvb, 0) >> 1;
3927 /* Get data of header excluding the first byte */
3928 data = tvb_get_ptr(tvb, 1, header_length - 1);
3930 calc_crc = crc7update(0, data, header_length - 1);
3931 calc_crc = crc7finalize(calc_crc);
3933 return calc_crc == crc;
3935 /* Validates the payload CRC in a Data FP frame */
3936 /* Should only be used in heuristic dissectors! */
3937 static bool
3938 check_payload_crc_for_heur(tvbuff_t *tvb, uint16_t header_length)
3940 uint16_t reported_length;
3941 uint16_t crc_index;
3942 uint16_t crc = 0;
3943 uint16_t calc_crc = 0;
3944 uint16_t payload_index;
3945 uint16_t payload_length;
3946 const uint8_t *data = NULL;
3948 reported_length = tvb_reported_length(tvb);
3949 if (reported_length < 2 || reported_length > tvb_captured_length(tvb)) {
3950 return false;
3952 /* Payload CRC is in the last 2 bytes of the packet */
3953 crc_index = reported_length - 2;
3954 crc = tvb_get_bits16(tvb, crc_index * 8, 16, ENC_BIG_ENDIAN);
3956 payload_index = header_length; /* payload first index is the same as the header length */
3957 payload_length = (reported_length - payload_index) - 2;
3958 data = tvb_get_ptr(tvb, payload_index, payload_length);
3959 calc_crc = crc16_8005_noreflect_noxor(data, payload_length);
3961 return calc_crc == crc;
3963 /* Validates the header CRC in a E-DCH Data FP frame */
3964 /* Should only be used in heuristic dissectors! */
3965 static bool
3966 check_edch_header_crc_for_heur(tvbuff_t *tvb, uint16_t header_length)
3968 uint16_t crc = 0;
3969 uint16_t calc_crc = 0;
3970 uint8_t * data = NULL;
3972 if (header_length > tvb_captured_length(tvb))
3973 return false;
3975 crc = (tvb_get_bits8(tvb, 0, 7) << 4) + tvb_get_bits8(tvb, 8, 4);
3976 /* Get data of header excluding the first byte */
3977 data = (uint8_t *)tvb_memdup(wmem_packet_scope(), tvb, 1, header_length-1);
3978 /*Zero the part in the second byte which contains part of the CRC*/
3979 data[0] = data[0] & 0x0f;
3981 calc_crc = crc11_307_noreflect_noxor(data, header_length-1);
3983 return calc_crc == crc;
3985 /* Generates a unique 32bit identifier based on the frame's metadata */
3986 /* This ID is used in the RLC dissector for reassembly */
3987 /* Should only be used in heuristic dissectors! */
3988 static uint32_t
3989 generate_ue_id_for_heur(packet_info *pinfo)
3991 if (pinfo->ptype == PT_UDP && pinfo->src.type == AT_IPv4 && pinfo->dst.type == AT_IPv4) {
3992 /* This logic assumes FP is delivered over IP/UDP*/
3993 /* Will return the same ID even if the address and ports are reversed */
3995 /* srcXor: [ ------- Source Address ------- ] (4 bytes)*/
3996 /* XOR */
3997 /* [ Source Port ][ Source Port ] (4 bytes)*/
3998 int srcXor = pntoh32(pinfo->src.data) ^ ((pinfo->srcport << 16) | (pinfo->srcport));
4000 /* dstXor: [ ---- Destination Address ---- ] (4 bytes)*/
4001 /* XOR */
4002 /* [ - Dest Port - ][ - Dest Port - ] (4 bytes)*/
4003 int dstXor = pntoh32(pinfo->dst.data) ^ ((pinfo->destport << 16) | (pinfo->destport));
4004 return srcXor ^ dstXor;
4006 else {
4007 /* Fallback - When IP and/or UDP are missing for whatever reason */
4008 /* Using the frame number of the first heuristicly dissected frame as the UE ID should be unique enough */
4009 /* The bitwise NOT operator is used to prevent low UE ID values which are likely to collide */
4010 /* with legitimate UE IDs derived from C-RNTIs in FACH/RACH */
4011 return ~(pinfo->num);
4014 /* Fills common PCH information in a 'fp conversation info' object */
4015 /* Should only be used in heuristic dissectors! */
4016 static void
4017 fill_pch_conversation_info_for_heur(umts_fp_conversation_info_t* umts_fp_conversation_info ,packet_info *pinfo)
4019 umts_fp_conversation_info->iface_type = IuB_Interface;
4020 umts_fp_conversation_info->division = Division_FDD;
4021 umts_fp_conversation_info->dl_frame_number = pinfo->num;
4022 umts_fp_conversation_info->ul_frame_number = pinfo->num;
4023 umts_fp_conversation_info->dch_crc_present = 1;
4024 umts_fp_conversation_info->com_context_id = generate_ue_id_for_heur(pinfo);
4025 umts_fp_conversation_info->rlc_mode = FP_RLC_AM;
4026 copy_address_wmem(wmem_file_scope(), &(umts_fp_conversation_info->crnc_address), &pinfo->src);
4027 umts_fp_conversation_info->crnc_port = pinfo->srcport;
4028 umts_fp_conversation_info->channel = CHANNEL_PCH;
4029 umts_fp_conversation_info->num_dch_in_flow = 1;
4030 umts_fp_conversation_info->fp_dch_channel_info[0].num_dl_chans = 1;
4031 umts_fp_conversation_info->fp_dch_channel_info[0].dl_chan_num_tbs[1] = 1;
4032 umts_fp_conversation_info->channel_specific_info = (void*)wmem_new0(wmem_file_scope(), fp_pch_channel_info_t);
4034 /* Attaches conversation info to both the downlink and uplink 'conversations' (streams) */
4035 /* (Required since only one of them is checked in every dissected FP packet) */
4036 /* Should only be used in heuristic dissectors! */
4037 static void
4038 set_both_sides_umts_fp_conv_data(packet_info *pinfo, umts_fp_conversation_info_t *umts_fp_conversation_info)
4040 conversation_t *packet_direction_conv;
4041 conversation_t *other_direction_conv;
4043 if (pinfo == NULL) {
4044 return;
4047 /* Finding or creating conversation for the way the packet is heading */
4048 packet_direction_conv = (conversation_t *)find_conversation(pinfo->num, &pinfo->net_dst, &pinfo->net_src,
4049 conversation_pt_to_conversation_type(pinfo->ptype),
4050 pinfo->destport, pinfo->srcport, NO_ADDR_B);
4052 if (packet_direction_conv == NULL) {
4053 /* Conversation does not exist yet, creating one now. */
4054 packet_direction_conv = conversation_new(pinfo->num, &pinfo->net_dst, &pinfo->net_src,
4055 conversation_pt_to_conversation_type(pinfo->ptype),
4056 pinfo->destport, pinfo->srcport, NO_ADDR2);
4058 conversation_add_proto_data(packet_direction_conv, proto_fp, umts_fp_conversation_info);
4060 /* Finding or creating conversation for the other side */
4061 other_direction_conv = (conversation_t *)find_conversation(pinfo->num, &pinfo->net_src, &pinfo->net_dst,
4062 conversation_pt_to_conversation_type(pinfo->ptype),
4063 pinfo->srcport, pinfo->destport, NO_ADDR_B);
4065 if (other_direction_conv == NULL) {
4066 /* Conversation does not exist yet, creating one now. */
4067 other_direction_conv = conversation_new(pinfo->num, &pinfo->net_src, &pinfo->net_dst,
4068 conversation_pt_to_conversation_type(pinfo->ptype),
4069 pinfo->srcport, pinfo->destport, NO_ADDR2);
4071 conversation_add_proto_data(other_direction_conv, proto_fp, umts_fp_conversation_info);
4074 static bool
4075 heur_dissect_fp_dcch_over_dch(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
4077 conversation_t *p_conv;
4078 umts_fp_conversation_info_t* umts_fp_conversation_info = NULL;
4079 struct fp_info *p_fp_info;
4080 uint32_t captured_length;
4081 uint32_t reported_length;
4082 uint8_t frame_type;
4083 uint8_t tfi;
4084 uint8_t pch_collisions_byte;
4086 /* Trying to find existing conversation */
4087 p_conv = (conversation_t *)find_conversation(pinfo->num, &pinfo->net_dst, &pinfo->net_src,
4088 conversation_pt_to_conversation_type(pinfo->ptype),
4089 pinfo->destport, pinfo->srcport, NO_ADDR_B);
4091 if (p_conv != NULL) {
4092 /* Checking if the conversation was already framed */
4093 umts_fp_conversation_info = (umts_fp_conversation_info_t *)conversation_get_proto_data(p_conv, proto_fp);
4094 if (umts_fp_conversation_info) {
4095 if (umts_fp_conversation_info->channel == CHANNEL_DCH) {
4096 conversation_set_dissector(p_conv, fp_handle);
4097 dissect_fp(tvb, pinfo, tree, data);
4098 return true;
4100 else if (umts_fp_conversation_info->channel != CHANNEL_UNKNOWN){
4101 /* This conversation was successfully framed as ANOTHER type */
4102 return false;
4107 /* Making sure FP info isn't already attached */
4108 p_fp_info = (fp_info *)p_get_proto_data(wmem_file_scope(), pinfo, proto_fp, 0);
4109 if (p_fp_info) {
4110 return false;
4113 frame_type = tvb_get_uint8(tvb, 0) & 0x01;
4114 if (frame_type == 1) { /* is 'control' frame type*/
4115 return false;
4118 /* Making sure we have at least enough bytes for header (3) + footer (2) */
4119 captured_length = tvb_captured_length(tvb);
4120 if (captured_length < 5) {
4121 return false;
4123 reported_length = tvb_reported_length(tvb);
4125 tfi = tvb_get_uint8(tvb, 2) & 0x1f;
4127 /* Checking if this is a DCH frame with 0 TBs*/
4128 if (tfi == 0x00)
4130 if (reported_length != 5 /* DL */ && reported_length != 7 /* UL */) {
4131 return false;
4133 if (!check_header_crc_for_heur(tvb, 3)) {
4134 return false;
4136 if (!check_payload_crc_for_heur(tvb, 3)) {
4137 return false;
4139 /* All checks passed - This is an unknown DCH FP frame. */
4140 /* To allow dissection of this frame after umts_fp_conversation_info will be added in a later frame */
4141 /* the conversation must be created here if it doesn't exist yet*/
4142 if (p_conv == NULL) {
4143 conversation_new(pinfo->num, &pinfo->net_dst, &pinfo->net_src,
4144 conversation_pt_to_conversation_type(pinfo->ptype),
4145 pinfo->destport, pinfo->srcport, NO_ADDR2);
4147 return false;
4150 /* Checking this is a DCH frame with 1 TB */
4151 if (tfi != 0x01) {
4152 return false;
4155 /* Expecting specific lengths: 24 for downlink frames, 26 for uplink frames */
4156 /* This is the common Transport Format of DCCH over DCH ( See 3GPP TR 25.944 / 4.1.1.3.1.1 ) */
4157 if (reported_length != 24 /* DL */ && reported_length != 26 /* UL */) {
4158 return false;
4161 if (!check_header_crc_for_heur(tvb, 3)) {
4162 return false;
4164 if (!check_payload_crc_for_heur(tvb, 3)) {
4165 return false;
4168 /* Checking if the 4th byte in the frame is zeroed. In this case the CRC checks aren't */
4169 /* deterministic enough to guarantee this is a DCH since this packet could also be a PCH frame */
4170 /* with PI Bitmap of 18 bytes + 0 TBs (Both CRCs will match for both formats) */
4171 pch_collisions_byte = tvb_get_uint8(tvb, 3);
4172 if (pch_collisions_byte == 0) {
4173 return false;
4176 if(!umts_fp_conversation_info) {
4177 umts_fp_conversation_info = wmem_new0(wmem_file_scope(), umts_fp_conversation_info_t);
4178 set_both_sides_umts_fp_conv_data(pinfo, umts_fp_conversation_info);
4180 umts_fp_conversation_info->iface_type = IuB_Interface;
4181 umts_fp_conversation_info->division = Division_FDD;
4182 umts_fp_conversation_info->dl_frame_number = pinfo->num;
4183 umts_fp_conversation_info->ul_frame_number = pinfo->num;
4184 umts_fp_conversation_info->dch_crc_present = 1;
4185 umts_fp_conversation_info->com_context_id = generate_ue_id_for_heur(pinfo);
4186 umts_fp_conversation_info->rlc_mode = FP_RLC_AM;
4187 if (reported_length == 24) { /* Downlink */
4188 copy_address_wmem(wmem_file_scope(), &(umts_fp_conversation_info->crnc_address), &pinfo->src);
4189 umts_fp_conversation_info->crnc_port = pinfo->srcport;
4191 else { /* Uplink*/
4192 copy_address_wmem(wmem_file_scope(), &(umts_fp_conversation_info->crnc_address), &pinfo->dst);
4193 umts_fp_conversation_info->crnc_port = pinfo->destport;
4195 umts_fp_conversation_info->channel = CHANNEL_DCH;
4196 umts_fp_conversation_info->num_dch_in_flow = 1;
4197 umts_fp_conversation_info->dch_ids_in_flow_list[0] = 31;
4198 umts_fp_conversation_info->fp_dch_channel_info[0].num_dl_chans = 1;
4199 umts_fp_conversation_info->fp_dch_channel_info[0].dl_chan_num_tbs[1] = 1;
4200 umts_fp_conversation_info->fp_dch_channel_info[0].dl_chan_tf_size[1] = 148;
4201 umts_fp_conversation_info->fp_dch_channel_info[0].num_ul_chans = 1;
4202 umts_fp_conversation_info->fp_dch_channel_info[0].ul_chan_num_tbs[1] = 1;
4203 umts_fp_conversation_info->fp_dch_channel_info[0].ul_chan_tf_size[1] = 148;
4204 conversation_set_dissector(find_or_create_conversation(pinfo), fp_handle);
4205 dissect_fp(tvb, pinfo, tree, data);
4206 return true;
4208 static bool
4209 heur_dissect_fp_fach1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
4211 conversation_t *p_conv;
4212 fp_fach_channel_info_t* fp_fach_channel_info;
4213 umts_fp_conversation_info_t* umts_fp_conversation_info = NULL;
4214 struct fp_info *p_fp_info;
4215 uint32_t captured_length;
4216 uint32_t reported_length;
4217 uint8_t frame_type;
4218 uint8_t tfi;
4219 uint8_t tctf;
4221 /* Finding or creating conversation */
4222 p_conv = (conversation_t *)find_conversation(pinfo->num, &pinfo->net_dst, &pinfo->net_src,
4223 conversation_pt_to_conversation_type(pinfo->ptype),
4224 pinfo->destport, pinfo->srcport, NO_ADDR_B);
4226 if (p_conv != NULL) {
4227 /* Checking if the conversation was already framed */
4228 umts_fp_conversation_info = (umts_fp_conversation_info_t *)conversation_get_proto_data(p_conv, proto_fp);
4229 if (umts_fp_conversation_info) {
4230 if (umts_fp_conversation_info->channel == CHANNEL_FACH_FDD) {
4231 conversation_set_dissector(p_conv, fp_handle);
4232 dissect_fp(tvb, pinfo, tree, data);
4233 return true;
4235 else if (umts_fp_conversation_info->channel != CHANNEL_UNKNOWN){
4236 /* This conversation was successfully framed as ANOTHER type */
4237 return false;
4241 /* Making sure we have at least enough bytes for header (4) + footer (2) */
4242 captured_length = tvb_captured_length(tvb);
4243 if(captured_length < 6) {
4244 return false;
4247 /* Expecting specific lengths: 51 for frames with 1 TB */
4248 /* This is a common Transport Format of FACH ( See 3GPP TR 25.944 / 4.1.1.2 'FACH1' ) */
4249 reported_length = tvb_reported_length(tvb);
4250 if (reported_length != 51) {
4251 return false;
4254 p_fp_info = (fp_info *)p_get_proto_data(wmem_file_scope(), pinfo, proto_fp, 0);
4256 /* Making sure FP info isn't already attached */
4257 if (p_fp_info) {
4258 return false;
4261 frame_type = tvb_get_uint8(tvb, 0) & 0x01;
4262 if (frame_type == 1) { /* is 'control' frame type*/
4263 /* We can't tell the FP type and content of control frames */
4264 return false;
4267 tfi = tvb_get_uint8(tvb, 2) & 0x1f;
4268 if (tfi != 0x01) {
4269 return false;
4272 tctf = tvb_get_uint8(tvb, 4);
4273 /* Asserting the TCTF field contains a valid (non reserved) value according to TS 25.321 Table 9.2.1-2 */
4274 if (tctf != 0x40 && /* CCCH */
4275 tctf != 0x50 && /* MCCH */
4276 tctf != 0x5F && /* MSCH */
4277 tctf != 0x80 && /* CTCH */
4278 (tctf >> 4) != 0x06 && /* MTCH */
4279 (tctf >> 6) != 0x00 && /* BCCH */
4280 (tctf >> 6) != 0x03) { /* DCCH or DTCH over FACH */
4281 return false;
4284 if (!check_header_crc_for_heur(tvb, 4)) {
4285 return false;
4287 if (!check_payload_crc_for_heur(tvb, 4)) {
4288 return false;
4291 if(!umts_fp_conversation_info) {
4292 umts_fp_conversation_info = wmem_new0(wmem_file_scope(), umts_fp_conversation_info_t);
4293 set_both_sides_umts_fp_conv_data(pinfo, umts_fp_conversation_info);
4295 umts_fp_conversation_info->iface_type = IuB_Interface;
4296 umts_fp_conversation_info->division = Division_FDD;
4297 umts_fp_conversation_info->dl_frame_number = pinfo->num;
4298 umts_fp_conversation_info->ul_frame_number = pinfo->num;
4299 umts_fp_conversation_info->dch_crc_present = 1;
4300 umts_fp_conversation_info->com_context_id = generate_ue_id_for_heur(pinfo);
4301 umts_fp_conversation_info->rlc_mode = FP_RLC_AM;
4302 copy_address_wmem(wmem_file_scope(), &(umts_fp_conversation_info->crnc_address), &pinfo->src);
4303 umts_fp_conversation_info->crnc_port = pinfo->srcport;
4304 umts_fp_conversation_info->channel = CHANNEL_FACH_FDD;
4305 umts_fp_conversation_info->num_dch_in_flow = 1;
4306 umts_fp_conversation_info->fp_dch_channel_info[0].num_dl_chans = 1;
4307 umts_fp_conversation_info->fp_dch_channel_info[0].dl_chan_num_tbs[1] = 1;
4308 umts_fp_conversation_info->fp_dch_channel_info[0].dl_chan_tf_size[1] = 360;
4309 /* Adding the 'channel specific info' for FACH */
4310 fp_fach_channel_info = wmem_new0(wmem_file_scope(), fp_fach_channel_info_t);
4311 fp_fach_channel_info->crnti_to_urnti_map = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
4312 umts_fp_conversation_info->channel_specific_info = (void*)fp_fach_channel_info;
4314 conversation_set_dissector(find_or_create_conversation(pinfo), fp_handle);
4315 dissect_fp(tvb, pinfo, tree, data);
4316 return true;
4318 static bool
4319 heur_dissect_fp_fach2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
4321 conversation_t *p_conv;
4322 fp_fach_channel_info_t* fp_fach_channel_info;
4323 umts_fp_conversation_info_t* umts_fp_conversation_info = NULL;
4324 struct fp_info *p_fp_info;
4325 uint32_t captured_length;
4326 uint32_t reported_length;
4327 uint8_t frame_type;
4328 uint8_t tfi;
4329 uint8_t tctf;
4331 /* Finding or creating conversation */
4332 p_conv = (conversation_t *)find_conversation(pinfo->num, &pinfo->net_dst, &pinfo->net_src,
4333 conversation_pt_to_conversation_type(pinfo->ptype),
4334 pinfo->destport, pinfo->srcport, NO_ADDR_B);
4336 if (p_conv != NULL) {
4337 /* Checking if the conversation was already framed */
4338 umts_fp_conversation_info = (umts_fp_conversation_info_t *)conversation_get_proto_data(p_conv, proto_fp);
4339 if (umts_fp_conversation_info) {
4340 if (umts_fp_conversation_info->channel == CHANNEL_FACH_FDD) {
4341 conversation_set_dissector(p_conv, fp_handle);
4342 dissect_fp(tvb, pinfo, tree, data);
4343 return true;
4345 else if (umts_fp_conversation_info->channel != CHANNEL_UNKNOWN){
4346 /* This conversation was successfully framed as ANOTHER type */
4347 return false;
4351 /* Making sure we have at least enough bytes for header (4) + footer (2) */
4352 captured_length = tvb_captured_length(tvb);
4353 if(captured_length < 6) {
4354 return false;
4357 /* Expecting specific lengths: 27 for frames with 1 TB, 48 for frames with 2 TBs */
4358 /* This is a common Transport Format of FACH ( See 3GPP TR 25.944 / 4.1.1.2 'FACH2' ) */
4359 reported_length = tvb_reported_length(tvb);
4360 if (reported_length != 27 && reported_length != 48) {
4361 return false;
4364 p_fp_info = (fp_info *)p_get_proto_data(wmem_file_scope(), pinfo, proto_fp, 0);
4366 /* Making sure FP info isn't already attached */
4367 if (p_fp_info) {
4368 return false;
4371 frame_type = tvb_get_uint8(tvb, 0) & 0x01;
4372 if (frame_type == 1) { /* is 'control' frame type*/
4373 /* We can't tell the FP type and content of control frames */
4374 return false;
4377 tfi = tvb_get_uint8(tvb, 2) & 0x1f;
4378 if (reported_length == 27 && tfi != 0x01) {
4379 return false;
4381 if (reported_length == 48 && tfi != 0x02) {
4382 return false;
4385 tctf = tvb_get_uint8(tvb, 4);
4386 /* Asserting the TCTF field contains a valid (non reserved) value according to TS 25.321 Table 9.2.1-2 */
4387 if (tctf != 0x40 && /* CCCH */
4388 tctf != 0x50 && /* MCCH */
4389 tctf != 0x5F && /* MSCH */
4390 tctf != 0x80 && /* CTCH */
4391 (tctf >> 4) != 0x06 && /* MTCH */
4392 (tctf >> 6) != 0x00 && /* BCCH */
4393 (tctf >> 6) != 0x03) { /* DCCH or DTCH over FACH */
4394 return false;
4397 if (!check_header_crc_for_heur(tvb, 4)) {
4398 return false;
4400 if (!check_payload_crc_for_heur(tvb, 4)) {
4401 return false;
4404 if(!umts_fp_conversation_info) {
4405 umts_fp_conversation_info = wmem_new0(wmem_file_scope(), umts_fp_conversation_info_t);
4406 set_both_sides_umts_fp_conv_data(pinfo, umts_fp_conversation_info);
4408 umts_fp_conversation_info->iface_type = IuB_Interface;
4409 umts_fp_conversation_info->division = Division_FDD;
4410 umts_fp_conversation_info->dl_frame_number = pinfo->num;
4411 umts_fp_conversation_info->ul_frame_number = pinfo->num;
4412 umts_fp_conversation_info->dch_crc_present = 1;
4413 umts_fp_conversation_info->com_context_id = generate_ue_id_for_heur(pinfo);
4414 umts_fp_conversation_info->rlc_mode = FP_RLC_AM;
4415 copy_address_wmem(wmem_file_scope(), &(umts_fp_conversation_info->crnc_address), &pinfo->src);
4416 umts_fp_conversation_info->crnc_port = pinfo->srcport;
4417 umts_fp_conversation_info->channel = CHANNEL_FACH_FDD;
4418 umts_fp_conversation_info->num_dch_in_flow = 1;
4419 umts_fp_conversation_info->fp_dch_channel_info[0].num_dl_chans = 1;
4420 umts_fp_conversation_info->fp_dch_channel_info[0].dl_chan_num_tbs[1] = 1;
4421 umts_fp_conversation_info->fp_dch_channel_info[0].dl_chan_tf_size[1] = 168;
4422 umts_fp_conversation_info->fp_dch_channel_info[0].dl_chan_num_tbs[2] = 2;
4423 umts_fp_conversation_info->fp_dch_channel_info[0].dl_chan_tf_size[2] = 168;
4424 /* Adding the 'channel specific info' for FACH */
4425 fp_fach_channel_info = wmem_new0(wmem_file_scope(), fp_fach_channel_info_t);
4426 fp_fach_channel_info->crnti_to_urnti_map = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
4427 umts_fp_conversation_info->channel_specific_info = (void*)fp_fach_channel_info;
4429 conversation_set_dissector(find_or_create_conversation(pinfo), fp_handle);
4430 dissect_fp(tvb, pinfo, tree, data);
4431 return true;
4433 static bool
4434 heur_dissect_fp_rach(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
4436 conversation_t *p_conv;
4437 fp_rach_channel_info_t* fp_rach_channel_info;
4438 umts_fp_conversation_info_t* umts_fp_conversation_info = NULL;
4439 struct fp_info *p_fp_info;
4440 uint32_t captured_length;
4441 uint32_t reported_length;
4442 uint8_t frame_type;
4443 uint8_t tfi;
4444 uint8_t tctf;
4446 /* Finding or creating conversation */
4447 p_conv = (conversation_t *)find_conversation(pinfo->num, &pinfo->net_dst, &pinfo->net_src,
4448 conversation_pt_to_conversation_type(pinfo->ptype),
4449 pinfo->destport, pinfo->srcport, NO_ADDR_B);
4451 if (p_conv != NULL) {
4452 /* Checking if the conversation was already framed */
4453 umts_fp_conversation_info = (umts_fp_conversation_info_t *)conversation_get_proto_data(p_conv, proto_fp);
4454 if (umts_fp_conversation_info) {
4455 if (umts_fp_conversation_info->channel == CHANNEL_RACH_FDD) {
4456 conversation_set_dissector(p_conv, fp_handle);
4457 dissect_fp(tvb, pinfo, tree, data);
4458 return true;
4460 else if (umts_fp_conversation_info->channel != CHANNEL_UNKNOWN){
4461 /* This conversation was successfully framed as ANOTHER type */
4462 return false;
4467 /* Making sure we have at least enough bytes for header (4) + footer (2) */
4468 captured_length = tvb_captured_length(tvb);
4469 if(captured_length < 6) {
4470 return false;
4473 /* Expecting specific lengths: rach frames are either 28 or 52 bytes long */
4474 /* This is the common Transport Formats of RACH ( See 3GPP TR 25.944 / 4.1.2.1 ) */
4475 reported_length = tvb_reported_length(tvb);
4476 if (reported_length != 28 && reported_length != 52) {
4477 return false;
4480 p_fp_info = (fp_info *)p_get_proto_data(wmem_file_scope(), pinfo, proto_fp, 0);
4482 /* Making sure FP info isn't already attached */
4483 if (p_fp_info) {
4484 return false;
4487 frame_type = tvb_get_uint8(tvb, 0) & 0x01;
4488 if (frame_type == 1) { /* is 'control' frame type*/
4489 /* We can't tell the FP type and content of control frames */
4490 return false;
4493 tfi = tvb_get_uint8(tvb, 2) & 0x1f;
4494 if (reported_length == 28 && tfi != 0x00) {
4495 return false;
4497 if (reported_length == 52 && tfi != 0x01) {
4498 return false;
4501 tctf = tvb_get_uint8(tvb, 4) >> 6;
4502 /* Asserting the TCTF field contains a valid (non reserved) value according to TS 25.321 Table 9.2.1-4 */
4503 if (tctf != 0x00 && /* CCCH */
4504 tctf != 0x01) /* DCCH over RACH */
4506 return false;
4509 if (!check_header_crc_for_heur(tvb, 4)) {
4510 return false;
4512 if (!check_payload_crc_for_heur(tvb, 4)) {
4513 return false;
4516 if(!umts_fp_conversation_info) {
4517 umts_fp_conversation_info = wmem_new0(wmem_file_scope(), umts_fp_conversation_info_t);
4518 set_both_sides_umts_fp_conv_data(pinfo, umts_fp_conversation_info);
4520 umts_fp_conversation_info->iface_type = IuB_Interface;
4521 umts_fp_conversation_info->division = Division_FDD;
4522 umts_fp_conversation_info->dl_frame_number = pinfo->num;
4523 umts_fp_conversation_info->ul_frame_number = pinfo->num;
4524 umts_fp_conversation_info->dch_crc_present = 1;
4525 umts_fp_conversation_info->com_context_id = generate_ue_id_for_heur(pinfo);
4526 umts_fp_conversation_info->rlc_mode = FP_RLC_AM;
4527 copy_address_wmem(wmem_file_scope(), &(umts_fp_conversation_info->crnc_address), &pinfo->dst);
4528 umts_fp_conversation_info->crnc_port = pinfo->destport;
4529 umts_fp_conversation_info->channel = CHANNEL_RACH_FDD;
4530 umts_fp_conversation_info->num_dch_in_flow = 1;
4531 umts_fp_conversation_info->fp_dch_channel_info[0].num_ul_chans = 0;
4532 umts_fp_conversation_info->fp_dch_channel_info[0].ul_chan_num_tbs[0] = 1;
4533 umts_fp_conversation_info->fp_dch_channel_info[0].ul_chan_num_tbs[1] = 1;
4534 umts_fp_conversation_info->fp_dch_channel_info[0].ul_chan_tf_size[0] = 168;
4535 umts_fp_conversation_info->fp_dch_channel_info[0].ul_chan_tf_size[1] = 360;
4537 /* Adding the 'channel specific info' for RACH */
4538 fp_rach_channel_info = wmem_new0(wmem_file_scope(), fp_rach_channel_info_t);
4539 fp_rach_channel_info->crnti_to_urnti_map = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
4540 umts_fp_conversation_info->channel_specific_info = (void*)fp_rach_channel_info;
4542 conversation_set_dissector(find_or_create_conversation(pinfo), fp_handle);
4543 dissect_fp(tvb, pinfo, tree, data);
4544 return true;
4546 static bool
4547 heur_dissect_fp_pch(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
4549 conversation_t *p_conv;
4550 umts_fp_conversation_info_t* umts_fp_conversation_info = NULL;
4551 fp_pch_channel_info_t* fp_pch_channel_info = NULL;
4552 struct fp_info *p_fp_info;
4553 bool conversation_initialized = false;
4554 uint32_t captured_length;
4555 uint32_t reported_length;
4556 uint8_t frame_type;
4557 uint8_t reserved_bits;
4558 uint8_t tfi;
4559 uint8_t pi_byte_length;
4560 uint16_t tb_byte_length;
4561 bool pi_present;
4562 bool tb_size_found;
4563 bool pi_length_found;
4564 uint8_t cfn_lowest_bits;
4565 uint8_t dch_collisions_byte;
4567 /* To correctly dissect a PCH stream 2 parameters are required: PI Bitmap length & TB length */
4568 /* Both are optional in each packet and having them both in a packet without knowing any of them */
4569 /* is not helpful.*/
4570 /* Hence gathering the info from 2 different frames is required. */
4572 /* Finding or creating conversation */
4573 p_conv = (conversation_t *)find_conversation(pinfo->num, &pinfo->net_dst, &pinfo->net_src,
4574 conversation_pt_to_conversation_type(pinfo->ptype),
4575 pinfo->destport, pinfo->srcport, NO_ADDR_B);
4577 if (p_conv != NULL) {
4578 /* Checking if the conversation was already framed */
4579 umts_fp_conversation_info = (umts_fp_conversation_info_t *)conversation_get_proto_data(p_conv, proto_fp);
4580 if (umts_fp_conversation_info) {
4581 fp_pch_channel_info = (fp_pch_channel_info_t*)umts_fp_conversation_info->channel_specific_info;
4582 /* Making sure this conversation type is "PCH" and the PCH channel info is present */
4583 if (umts_fp_conversation_info->channel == CHANNEL_PCH && fp_pch_channel_info != NULL) {
4584 conversation_initialized = true;
4585 pi_length_found = fp_pch_channel_info->paging_indications != 0;
4586 tb_size_found = umts_fp_conversation_info->fp_dch_channel_info[0].dl_chan_tf_size[1] != 0;
4587 if (pi_length_found && tb_size_found) {
4588 /* Stream already framed - contains both PI length and TB size */
4589 dissect_fp(tvb, pinfo, tree, data);
4590 return true;
4593 else if (umts_fp_conversation_info->channel != CHANNEL_UNKNOWN){
4594 /* This conversation was successfully framed as ANOTHER type */
4595 return false;
4597 else {
4598 /* FP conversation info attached and the channel type is UNKNOWN - might be PCH */
4599 tb_size_found = false;
4600 pi_length_found = false;
4603 else {
4604 /* FP conversation info not attached - no PCH info is known */
4605 tb_size_found = false;
4606 pi_length_found = false;
4609 else {
4610 /* A conversation does not exist yet - no PCH info is known */
4611 tb_size_found = false;
4612 pi_length_found = false;
4615 /* Making sure we have at least enough bytes for header (4) + footer (2) */
4616 captured_length = tvb_captured_length(tvb);
4617 if(captured_length < 6) {
4618 return false;
4621 p_fp_info = (fp_info *)p_get_proto_data(wmem_file_scope(), pinfo, proto_fp, 0);
4622 /* Making sure FP info isn't already attached */
4623 if (p_fp_info) {
4624 return false;
4627 frame_type = tvb_get_uint8(tvb, 0) & 0x01;
4628 if (frame_type == 1) { /* is 'control' frame type*/
4629 /* We can't tell the FP type and content of control frames */
4630 return false;
4633 /* Checking bits after CFN and before PI indicator are zeroed */
4634 reserved_bits = tvb_get_uint8(tvb, 2) & 0x0E;
4635 if (reserved_bits != 0x00) {
4636 return false;
4639 tfi = tvb_get_uint8(tvb, 3) & 0x1f;
4640 if (tfi != 0x00 && tfi != 0x01) {
4641 return false;
4644 if (!check_header_crc_for_heur(tvb, 4)) {
4645 return false;
4647 if (!check_payload_crc_for_heur(tvb, 4)) {
4648 return false;
4651 reported_length = tvb_reported_length(tvb);
4652 pi_present = tvb_get_uint8(tvb, 2) & 0x01; /* Rightmost bit in the 3rd byte */
4653 if (pi_present) {
4654 if (tfi == 0x00 && !pi_length_found) {
4655 /* PI Bitmap present and No TB. Can calculate PI bitmap length */
4656 uint8_t pi_bit_length;
4657 pi_byte_length = reported_length - 6; /* Removing header length (4) and footer length (2)*/
4658 switch (pi_byte_length)
4660 case 3: /* 18 bits bitmap + padding */
4661 pi_bit_length = 18;
4662 break;
4663 case 5: /* 36 bits bitmap + padding */
4664 pi_bit_length = 36;
4665 break;
4666 case 9: /* 72 bits bitmap */
4667 pi_bit_length = 72;
4668 break;
4669 case 18: /* 144 bits bitmap */
4670 pi_bit_length = 144;
4671 break;
4672 default:
4673 return false;
4676 if (pi_bit_length == 144 && !tb_size_found) {
4677 /* Nothing has confirmed yet that this channel is a PCH since */
4678 /* both 'tb_size_found' and 'pi_length_found' are false. */
4679 /* Checking if the 4 LSB bits of the CFN (the 4 leftmost bits in the 3rd byte) aren't zeroed. */
4680 /* if they aren't this is probably PCH because those are reserved in DCH */
4681 cfn_lowest_bits = tvb_get_uint8(tvb, 2) & 0xF0;
4682 if(cfn_lowest_bits == 0) {
4683 /* Checking if the 4th byte in the frame is zeroed. In this case the CRC checks aren't */
4684 /* deterministic enough to guarantee this is a PCH since this packet could also be a DCH frame */
4685 /* with MAC's C/T is 0 and 4 leftmost bits of RLC are 0 */
4686 dch_collisions_byte = tvb_get_uint8(tvb, 3);
4687 if (dch_collisions_byte == 0) {
4688 return false;
4693 if (!umts_fp_conversation_info) {
4694 umts_fp_conversation_info = wmem_new0(wmem_file_scope(), umts_fp_conversation_info_t);
4695 set_both_sides_umts_fp_conv_data(pinfo, umts_fp_conversation_info);
4697 if(!conversation_initialized) {
4698 fill_pch_conversation_info_for_heur(umts_fp_conversation_info, pinfo);
4699 fp_pch_channel_info = (fp_pch_channel_info_t*)umts_fp_conversation_info->channel_specific_info;
4701 fp_pch_channel_info->paging_indications = pi_bit_length;
4702 pi_length_found = true;
4704 else if (tfi == 0x01 && !tb_size_found && pi_length_found) {
4705 /* TB present and PI bitmap length is known. Can calculate TB length.*/
4706 pi_byte_length = (fp_pch_channel_info->paging_indications + 7) / 8;
4707 if (!umts_fp_conversation_info) {
4708 umts_fp_conversation_info = wmem_new0(wmem_file_scope(), umts_fp_conversation_info_t);
4709 set_both_sides_umts_fp_conv_data(pinfo, umts_fp_conversation_info);
4711 if(!conversation_initialized) {
4712 fill_pch_conversation_info_for_heur(umts_fp_conversation_info, pinfo);
4714 tb_byte_length = (reported_length - (pi_byte_length + 6)); /* Removing header length (4), footer length (2) and PI bitmap length*/
4715 /* Possible TB lengths for PCH is 10 or 30 bytes ( See 3GPP TR 25.944 / 4.1.1.2 ) */
4716 if (tb_byte_length == 10 || tb_byte_length == 30) {
4717 umts_fp_conversation_info->fp_dch_channel_info[0].dl_chan_tf_size[1] = tb_byte_length * 8;
4718 tb_size_found = true;
4721 /* TODO: It should be possible to figure both PI & TB sizes if both are present in a frame and neither is known */
4722 /* Since the total size of the frame should be unique */
4723 /* e.g. 19 bytes = header (4) + PI 18bits (3) + TB (10) + footer (2)*/
4724 /* 21 bytes = header (4) + PI 36bits (5) + TB (10) + footer (2)*/
4725 /* etc... */
4726 /* This could mostly help dissect 'busy' PCHs where most of the frames have both PI & TB*/
4728 else {
4729 if (tfi == 0x01 && !tb_size_found) {
4730 /* TB present and PI bitmap is missing. Can calculate TB length.*/
4731 if (!umts_fp_conversation_info) {
4732 umts_fp_conversation_info = wmem_new0(wmem_file_scope(), umts_fp_conversation_info_t);
4733 set_both_sides_umts_fp_conv_data(pinfo, umts_fp_conversation_info);
4735 if(!conversation_initialized) {
4736 fill_pch_conversation_info_for_heur(umts_fp_conversation_info, pinfo);
4738 tb_byte_length = (reported_length - 6); /* Removing header length (4), footer length (2) */
4739 /* Possible TB lengths for PCH is 10 or 30 bytes ( See 3GPP TR 25.944 / 4.1.1.2 ) */
4740 if (tb_byte_length == 10 || tb_byte_length == 30) {
4741 umts_fp_conversation_info->fp_dch_channel_info[0].dl_chan_tf_size[1] = tb_byte_length * 8;
4742 set_both_sides_umts_fp_conv_data(pinfo, umts_fp_conversation_info);
4743 tb_size_found = true;
4748 if (pi_length_found && tb_size_found) {
4749 /* Stream completely framed! */
4750 conversation_set_dissector(find_or_create_conversation(pinfo), fp_handle);
4751 dissect_fp(tvb, pinfo, tree, data);
4752 return true;
4754 else {
4755 /* Some data still missing */
4756 return false;
4759 static bool
4760 heur_dissect_fp_hsdsch_type_1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
4762 conversation_t *p_conv;
4763 umts_fp_conversation_info_t* umts_fp_conversation_info = NULL;
4764 fp_hsdsch_channel_info_t* fp_hsdsch_channel_info;
4765 struct fp_info *p_fp_info;
4766 uint32_t captured_length;
4767 uint32_t reported_length;
4768 uint8_t frame_type;
4769 uint16_t mac_d_pdu_length;
4770 uint16_t num_of_pdus;
4771 uint32_t expected_total_size;
4772 uint32_t next_pdu_index;
4773 uint16_t index_step;
4774 uint8_t pre_pdu_padding;
4776 /* Trying to find existing conversation */
4777 p_conv = (conversation_t *)find_conversation(pinfo->num, &pinfo->net_dst, &pinfo->net_src,
4778 conversation_pt_to_conversation_type(pinfo->ptype),
4779 pinfo->destport, pinfo->srcport, NO_ADDR_B);
4781 if (p_conv != NULL) {
4782 /* Checking if the conversation was already framed */
4783 umts_fp_conversation_info = (umts_fp_conversation_info_t *)conversation_get_proto_data(p_conv, proto_fp);
4784 if (umts_fp_conversation_info) {
4785 fp_hsdsch_channel_info = (fp_hsdsch_channel_info_t*)umts_fp_conversation_info->channel_specific_info;
4786 if (umts_fp_conversation_info->channel == CHANNEL_HSDSCH && fp_hsdsch_channel_info->hsdsch_entity == hs) {
4787 conversation_set_dissector(p_conv, fp_handle);
4788 dissect_fp(tvb, pinfo, tree, data);
4789 return true;
4791 else if (umts_fp_conversation_info->channel != CHANNEL_UNKNOWN){
4792 /* This conversation was successfully framed as ANOTHER type */
4793 return false;
4798 /* Making sure FP info isn't already attached */
4799 p_fp_info = (fp_info *)p_get_proto_data(wmem_file_scope(), pinfo, proto_fp, 0);
4800 if (p_fp_info) {
4801 return false;
4804 captured_length = tvb_reported_length(tvb);
4805 /* Lengths limit: header size (7) + at least 1 PDU Block (2) + CRC Payload size (2)*/
4806 if (captured_length < 11) {
4807 return false;
4810 frame_type = tvb_get_uint8(tvb, 0) & 0x01;
4811 if (frame_type == 1) { /* is 'control' frame type*/
4812 return false;
4815 /* Lengths limit: Smallest HS-DSCH type 1 data frame is 55 bytes (1 PDU of 336 bits) */
4816 reported_length = tvb_reported_length(tvb);
4817 if (reported_length < 55) {
4818 return false;
4821 mac_d_pdu_length = tvb_get_uint16(tvb, 2, ENC_NA) >> 3;
4822 /* Only valid PDU lengths are 336 or 656 */
4823 if (mac_d_pdu_length != 336 && mac_d_pdu_length != 656) {
4824 return false;
4827 num_of_pdus = tvb_get_uint8(tvb, 4);
4828 /* PDUs count shouldn't be 0*/
4829 if (num_of_pdus == 0) {
4830 return false;
4832 /* Maximum PDUs count constraint: 32 PDUs * 336 bits or 17 PDUs * 656 bits */
4833 if ((mac_d_pdu_length == 336 && num_of_pdus > 32) || (mac_d_pdu_length == 656 && num_of_pdus > 17)) {
4834 return false;
4837 /* Making sure the expected packet size is smaller/equals to the entire packet's size */
4838 expected_total_size = (num_of_pdus * mac_d_pdu_length / 8) + 7 /*Header length*/ + 2 /*Footer length*/;
4839 if (expected_total_size > captured_length || expected_total_size > reported_length) {
4840 return false;
4843 /* Iterating through the PDUs making sure the padding nibble is present in all of them */
4844 next_pdu_index = 7;
4845 index_step = mac_d_pdu_length / 8;
4846 for (int i = 0; i < num_of_pdus; i++)
4848 pre_pdu_padding = tvb_get_uint8(tvb, next_pdu_index) >> 4;
4849 if (pre_pdu_padding != 0x00)
4851 /* One of the padding nibbles is not zeroed */
4852 return false;
4854 next_pdu_index += index_step;
4857 if (!check_header_crc_for_heur(tvb, 7)) {
4858 return false;
4860 if (!check_payload_crc_for_heur(tvb, 7)) {
4861 return false;
4864 if(!umts_fp_conversation_info) {
4865 umts_fp_conversation_info = wmem_new0(wmem_file_scope(), umts_fp_conversation_info_t);
4866 set_both_sides_umts_fp_conv_data(pinfo, umts_fp_conversation_info);
4868 umts_fp_conversation_info->iface_type = IuB_Interface;
4869 umts_fp_conversation_info->division = Division_FDD;
4870 umts_fp_conversation_info->dl_frame_number = pinfo->num;
4871 umts_fp_conversation_info->ul_frame_number = pinfo->num;
4872 umts_fp_conversation_info->dch_crc_present = 1;
4873 umts_fp_conversation_info->com_context_id = generate_ue_id_for_heur(pinfo);
4874 umts_fp_conversation_info->rlc_mode = FP_RLC_AM;
4875 copy_address_wmem(wmem_file_scope(), &(umts_fp_conversation_info->crnc_address), &pinfo->src);
4876 umts_fp_conversation_info->crnc_port = pinfo->srcport;
4877 umts_fp_conversation_info->channel = CHANNEL_HSDSCH;
4878 fp_hsdsch_channel_info = wmem_new0(wmem_file_scope(), fp_hsdsch_channel_info_t);
4879 fp_hsdsch_channel_info->hsdsch_entity = hs;
4880 fp_hsdsch_channel_info->hsdsch_macdflow_id = 0;
4881 umts_fp_conversation_info->channel_specific_info = (void*)fp_hsdsch_channel_info;
4883 conversation_set_dissector(find_or_create_conversation(pinfo), fp_handle);
4884 dissect_fp(tvb, pinfo, tree, data);
4885 return true;
4887 static bool
4888 heur_dissect_fp_hsdsch_type_2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
4890 conversation_t *p_conv;
4891 umts_fp_conversation_info_t* umts_fp_conversation_info = NULL;
4892 fp_hsdsch_channel_info_t* fp_hsdsch_channel_info;
4893 struct fp_info *p_fp_info;
4894 uint32_t captured_length;
4895 uint32_t reported_length;
4896 uint8_t frame_type;
4897 uint8_t reserved_fach_ind_bits;
4898 uint8_t pdu_block_header_reserved_bit;
4899 uint8_t pdu_block_headers_count;
4900 uint16_t next_pdu_block_header_index;
4901 uint16_t pdu_block_header_pdu_length;
4902 uint8_t pdu_block_header_pdus_count;
4903 uint8_t pdu_block_header_lchid;
4904 uint32_t total_header_length;
4905 uint32_t expected_payload_length;
4907 /* Trying to find existing conversation */
4908 p_conv = (conversation_t *)find_conversation(pinfo->num, &pinfo->net_dst, &pinfo->net_src,
4909 conversation_pt_to_conversation_type(pinfo->ptype),
4910 pinfo->destport, pinfo->srcport, NO_ADDR_B);
4912 if (p_conv != NULL) {
4913 /* Checking if the conversation was already framed */
4914 umts_fp_conversation_info = (umts_fp_conversation_info_t *)conversation_get_proto_data(p_conv, proto_fp);
4915 if (umts_fp_conversation_info) {
4916 fp_hsdsch_channel_info = (fp_hsdsch_channel_info_t*)umts_fp_conversation_info->channel_specific_info;
4917 if (umts_fp_conversation_info->channel == CHANNEL_HSDSCH && fp_hsdsch_channel_info->hsdsch_entity == ehs) {
4918 conversation_set_dissector(p_conv, fp_handle);
4919 dissect_fp(tvb, pinfo, tree, data);
4920 return true;
4922 else if (umts_fp_conversation_info->channel != CHANNEL_UNKNOWN){
4923 /* This conversation was successfully framed as ANOTHER type */
4924 return false;
4929 /* Making sure FP info isn't already attached */
4930 p_fp_info = (fp_info *)p_get_proto_data(wmem_file_scope(), pinfo, proto_fp, 0);
4931 if (p_fp_info) {
4932 return false;
4935 captured_length = tvb_captured_length(tvb);
4936 reported_length = tvb_reported_length(tvb);
4937 /* Lengths limit: header size + at least 1 PDU Block Header + CRC Payload size */
4938 if (captured_length < 11) {
4939 return false;
4942 frame_type = tvb_get_uint8(tvb, 0) & 0x01;
4943 if (frame_type == 1) { /* is 'control' frame type*/
4944 return false;
4947 pdu_block_header_reserved_bit = (tvb_get_uint8(tvb, 7) & 0x10) >> 4;
4948 if (pdu_block_header_reserved_bit == 0x1) {
4949 return false;
4952 /* Expecting at least 1 PDU Block Header */
4953 pdu_block_headers_count = tvb_get_uint8(tvb, 2) >> 3;
4954 if (pdu_block_headers_count == 0) {
4955 return false;
4958 /* Getting 3 rightmost bits in the FACH Indicator's byte, which are reserved and should be 0 */
4959 reserved_fach_ind_bits = tvb_get_uint8(tvb, 3) & 0x03;
4960 if (reserved_fach_ind_bits != 0x00) {
4961 return false;
4964 /* Iterating through the block headers looking for invalid fields and */
4965 /* calculating the expected total packet length */
4966 total_header_length = 6;
4967 expected_payload_length = 0;
4968 for (int i = 0; i < pdu_block_headers_count; i++)
4970 /* Making sure the next index is not out of range */
4971 if (((uint32_t)(8 + (i * 3))) >= captured_length) {
4972 return false;
4975 /* Getting blocks length and count from the i-th header */
4976 if (i % 2 == 0) {
4977 next_pdu_block_header_index = (i * 25) / 10;
4979 else {
4980 next_pdu_block_header_index = (((i-1) * 25) / 10) + 2;
4982 pdu_block_header_pdu_length = tvb_get_uint16(tvb, 6 + next_pdu_block_header_index, ENC_NA) >> 5;
4983 pdu_block_header_pdus_count = tvb_get_uint8(tvb, 7 + next_pdu_block_header_index) & 0x0F;
4984 pdu_block_header_lchid = tvb_get_uint8(tvb, 8 + next_pdu_block_header_index) >> 4;
4987 /* Making sure PDUs' Length isn't zeroed*/
4988 if (pdu_block_header_pdu_length == 0) {
4989 return false;
4991 /* Making sure PDUs Count isn't zeroed */
4992 if (pdu_block_header_pdus_count == 0) {
4993 return false;
4996 /* Adding this header's length to expected length*/
4997 if (i % 2 == 0) {
4998 total_header_length += 3;
5000 else {
5001 total_header_length += 2;
5003 /* Adding this header's payload's size to expected length*/
5004 expected_payload_length += (pdu_block_header_pdu_length * pdu_block_header_pdus_count);
5006 /* Checking padding after lchid */
5007 if ((tvb_get_uint8(tvb, 8 + (i * 3)) & 0x0F) != 0x00) {
5008 return false;
5010 /* Checking lchid for reserved value 0x0F*/
5012 if (pdu_block_header_lchid == 0x0F) {
5013 return false;
5016 /* Adding Payload CRC'slength to payload length*/
5017 expected_payload_length += 2;
5018 /* Calculated expected packet size must not exceed captured length or reported length*/
5019 if ((total_header_length + expected_payload_length) > captured_length || (total_header_length + expected_payload_length) > reported_length) {
5020 return false;
5023 if (!check_header_crc_for_heur(tvb, total_header_length)) {
5024 return false;
5026 if (!check_payload_crc_for_heur(tvb, total_header_length)) {
5027 return false;
5030 if(!umts_fp_conversation_info) {
5031 umts_fp_conversation_info = wmem_new0(wmem_file_scope(), umts_fp_conversation_info_t);
5032 set_both_sides_umts_fp_conv_data(pinfo, umts_fp_conversation_info);
5034 umts_fp_conversation_info->iface_type = IuB_Interface;
5035 umts_fp_conversation_info->division = Division_FDD;
5036 umts_fp_conversation_info->dl_frame_number = pinfo->num;
5037 umts_fp_conversation_info->ul_frame_number = pinfo->num;
5038 umts_fp_conversation_info->dch_crc_present = 1;
5039 umts_fp_conversation_info->com_context_id = generate_ue_id_for_heur(pinfo);
5040 umts_fp_conversation_info->rlc_mode = FP_RLC_AM;
5041 copy_address_wmem(wmem_file_scope(), &(umts_fp_conversation_info->crnc_address), &pinfo->src);
5042 umts_fp_conversation_info->crnc_port = pinfo->srcport;
5043 umts_fp_conversation_info->channel = CHANNEL_HSDSCH;
5044 fp_hsdsch_channel_info = wmem_new0(wmem_file_scope(), fp_hsdsch_channel_info_t);
5045 fp_hsdsch_channel_info->hsdsch_entity = ehs;
5046 fp_hsdsch_channel_info->hsdsch_macdflow_id = 1;
5047 umts_fp_conversation_info->channel_specific_info = (void*)fp_hsdsch_channel_info;
5049 conversation_set_dissector(find_or_create_conversation(pinfo), fp_handle);
5050 dissect_fp(tvb, pinfo, tree, data);
5051 return true;
5054 static bool
5055 heur_dissect_fp_edch_type_1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
5057 conversation_t *p_conv;
5058 umts_fp_conversation_info_t* umts_fp_conversation_info = NULL;
5059 fp_edch_channel_info_t* fp_edch_channel_info;
5060 struct fp_info *p_fp_info;
5061 uint32_t captured_length;
5062 uint8_t frame_type;
5063 uint8_t num_sub_frames_byte;
5064 uint8_t number_of_subframes;
5065 uint8_t number_of_mac_es_pdus;
5066 uint32_t subframe_number;
5067 uint32_t total_sub_headers_len;
5068 uint32_t total_header_length;
5069 uint32_t payload_length;
5070 uint32_t total_mac_pdus_count;
5071 uint32_t macd_pdu_bit_size;
5072 uint32_t bit_offset;
5073 uint32_t offset;
5074 uint32_t i = 0;
5075 uint32_t n = 0;
5077 /* Trying to find existing conversation */
5078 p_conv = (conversation_t *)find_conversation(pinfo->num, &pinfo->net_dst, &pinfo->net_src,
5079 conversation_pt_to_conversation_type(pinfo->ptype),
5080 pinfo->destport, pinfo->srcport, NO_ADDR_B);
5082 if (p_conv != NULL) {
5083 /* Checking if the conversation was already framed */
5084 umts_fp_conversation_info = (umts_fp_conversation_info_t *)conversation_get_proto_data(p_conv, proto_fp);
5085 if (umts_fp_conversation_info) {
5086 fp_edch_channel_info = (fp_edch_channel_info_t*)umts_fp_conversation_info->channel_specific_info;
5087 if (umts_fp_conversation_info->channel == CHANNEL_EDCH && fp_edch_channel_info->edch_type == 0) {
5088 conversation_set_dissector(p_conv, fp_handle);
5089 dissect_fp(tvb, pinfo, tree, data);
5090 return true;
5092 else if (umts_fp_conversation_info->channel != CHANNEL_UNKNOWN){
5093 /* This conversation was successfully framed as ANOTHER type */
5094 return false;
5099 /* Making sure FP info isn't already attached */
5100 p_fp_info = (fp_info *)p_get_proto_data(wmem_file_scope(), pinfo, proto_fp, 0);
5101 if (p_fp_info) {
5102 return false;
5105 captured_length = tvb_reported_length(tvb);
5106 /* Lengths limit: header size + at least 1 Subframe Header + CRC Payload size */
5107 if (captured_length < 9) {
5108 return false;
5111 frame_type = tvb_get_uint8(tvb, 0) & 0x01;
5112 if (frame_type == 1) { /* is 'control' frame type*/
5113 return false;
5116 num_sub_frames_byte = tvb_get_uint8(tvb, 2);
5117 /* Checking 4 leftmost bits in the 'Number of Subframes' byte, which are reserved and should be 0 */
5118 if (num_sub_frames_byte & 0xf0) {
5119 return false;
5122 /* Values {11-16} are reserved */
5123 number_of_subframes = (num_sub_frames_byte & 0x0f) + 1;
5124 if (number_of_subframes >= 11) {
5125 return false;
5128 /* Iterating through the block headers looking for invalid fields */
5129 total_header_length = 4;
5130 offset = 4;
5131 total_mac_pdus_count = 0;
5132 /* EDCH subframe header list */
5133 for (n=0; n < number_of_subframes; n++) {
5135 /* Making sure the next index is not out of range */
5136 if (((uint32_t)(offset + 3)) >= captured_length) {
5137 return false;
5140 /* Subframe number */
5141 subframe_number = (tvb_get_uint8(tvb, offset) & 0x07);
5142 if (subframe_number > 4) {
5143 return false;
5145 offset++;
5147 /* Number of MAC-es PDUs */
5148 number_of_mac_es_pdus = (tvb_get_uint8(tvb, offset) & 0xf0) >> 4;
5149 if (number_of_mac_es_pdus == 0) {
5150 return false;
5152 bit_offset = 4;
5154 /* Making sure enough bytes are present for all sub-header */
5155 total_sub_headers_len = ((int)((((1.5 + (number_of_mac_es_pdus * 1.5))*8+7)/8)));
5156 if ((offset + total_sub_headers_len) >= captured_length) {
5157 return false;
5159 /* Details of each MAC-es PDU */
5160 for (i=0; i < number_of_mac_es_pdus; i++) {
5161 uint32_t n_pdus; /*Size of the PDU*/
5163 /* DDI (6 bits) */
5164 bit_offset += 6;
5166 /* Number of MAC-d PDUs (6 bits) */
5167 n_pdus = tvb_get_bits8( tvb, offset*8 + bit_offset, 6);
5168 total_mac_pdus_count += n_pdus;
5169 bit_offset += 6;
5172 total_header_length += total_sub_headers_len;
5173 offset += ((bit_offset+7)/8);
5176 /* Figure MAC bit size */
5177 payload_length = captured_length - total_header_length - 3; /* Removing 3 bytes for Payload CRC and TSN */
5178 if (payload_length == (total_mac_pdus_count * 42)) {
5179 macd_pdu_bit_size = 336;
5181 else if (payload_length == (total_mac_pdus_count * 18)) {
5182 macd_pdu_bit_size = 144;
5184 else {
5185 /* Unexpected payload length or DDIs combination */
5186 return false;
5189 if (!check_edch_header_crc_for_heur(tvb, total_header_length)) {
5190 return false;
5192 if (!check_payload_crc_for_heur(tvb, total_header_length)) {
5193 return false;
5196 if(!umts_fp_conversation_info) {
5197 umts_fp_conversation_info = wmem_new0(wmem_file_scope(), umts_fp_conversation_info_t);
5198 set_both_sides_umts_fp_conv_data(pinfo, umts_fp_conversation_info);
5200 umts_fp_conversation_info->iface_type = IuB_Interface;
5201 umts_fp_conversation_info->division = Division_FDD;
5202 umts_fp_conversation_info->dl_frame_number = pinfo->num;
5203 umts_fp_conversation_info->ul_frame_number = pinfo->num;
5204 umts_fp_conversation_info->dch_crc_present = 1;
5205 umts_fp_conversation_info->com_context_id = generate_ue_id_for_heur(pinfo);
5206 umts_fp_conversation_info->rlc_mode = FP_RLC_AM;
5207 copy_address_wmem(wmem_file_scope(), &(umts_fp_conversation_info->crnc_address), &pinfo->src);
5208 umts_fp_conversation_info->crnc_port = pinfo->srcport;
5209 umts_fp_conversation_info->channel = CHANNEL_EDCH;
5210 fp_edch_channel_info = wmem_new0(wmem_file_scope(), fp_edch_channel_info_t);
5211 fp_edch_channel_info->no_ddi_entries = 0x0f;
5212 for(i = 0;i<0x0f;i++) {
5213 fp_edch_channel_info->edch_ddi[i] = i;
5214 fp_edch_channel_info->edch_macd_pdu_size[i] = macd_pdu_bit_size;
5215 fp_edch_channel_info->edch_lchId[i] = 9;
5217 fp_edch_channel_info->edch_type = 0; /* Type 1 */
5218 umts_fp_conversation_info->channel_specific_info = (void*)fp_edch_channel_info;
5220 conversation_set_dissector(find_or_create_conversation(pinfo), fp_handle);
5221 dissect_fp(tvb, pinfo, tree, data);
5222 return true;
5224 /* This method can frame UDP streams containing FP packets but dissection of those packets will */
5225 /* fail since the FP conversation info is never attached */
5226 /* Useful for DCH streams containing CS data and don't have their own heuristic method */
5227 static bool
5228 heur_dissect_fp_unknown_format(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
5230 conversation_t *p_conv;
5231 umts_fp_conversation_info_t* umts_fp_conversation_info = NULL;
5232 struct fp_info *p_fp_info;
5233 uint32_t length;
5234 uint8_t frame_type;
5235 uint32_t ft;
5237 /* Trying to find existing conversation */
5238 p_conv = (conversation_t *)find_conversation(pinfo->num, &pinfo->net_dst, &pinfo->net_src,
5239 conversation_pt_to_conversation_type(pinfo->ptype),
5240 pinfo->destport, pinfo->srcport, NO_ADDR_B);
5242 /* Check if FP Conversation Info is attached */
5243 if (p_conv != NULL) {
5244 umts_fp_conversation_info = (umts_fp_conversation_info_t *)conversation_get_proto_data(p_conv, proto_fp);
5245 if (umts_fp_conversation_info) {
5246 if (umts_fp_conversation_info->channel == CHANNEL_UNKNOWN) {
5247 /* This stream was framed using a previous control frame, we can call FP dissector without further tests*/
5248 dissect_fp(tvb, pinfo, tree, data);
5249 return true;
5251 else {
5252 return false;
5257 p_fp_info = (fp_info *)p_get_proto_data(wmem_file_scope(), pinfo, proto_fp, 0);
5259 /* Check if per-frame FP Info is attached*/
5260 if(p_fp_info) {
5261 /* if FP info is present, check that it really is an ethernet link */
5262 if (p_fp_info->link_type != FP_Link_Ethernet) {
5263 return false;
5266 /* discriminate 'lower' UDP layer from 'user data' UDP layer
5267 * (i.e. if an FP over UDP packet contains a user UDP packet */
5268 if (p_fp_info->srcport != pinfo->srcport ||
5269 p_fp_info->destport != pinfo->destport)
5270 return false;
5272 /* assume this is FP */
5273 dissect_fp(tvb, pinfo, tree, data);
5274 return true;
5277 /* Both per-frame FP info and conversation FP info are missing */
5278 /* Try to frame control frames using header CRC */
5279 ft = (tvb_get_uint8(tvb, 0) & 0x01);
5280 if(ft != FT_CONTROL) {
5281 /* This is a Data frame, can't tell if it's FP. */
5282 return false;
5285 length = tvb_captured_length(tvb);
5286 /* Length limit: control frames header is 2 bytes */
5287 if (length < 2) {
5288 return false;
5291 /* Check 'Frame Type' */
5292 frame_type = tvb_get_uint8(tvb, 1);
5293 /* 0x00 is unused for both dedicated & common FP */
5294 if( frame_type == 0x00 ) {
5295 return false;
5297 /* Max frame types are: */
5298 /* For common channels: 0x0E */
5299 /* For dedicated channels: 0x0B */
5300 /* The left nibble is zeroed in both cases */
5301 if( (frame_type & 0xF0) != 0x00) {
5302 return false;
5305 /* Checking Header CRC*/
5306 if (!check_control_frame_crc_for_heur(tvb)) {
5307 /* The CRC is incorrect */
5308 return false;
5311 /* The CRC is correct! */
5312 /* Attaching 'FP Conversation Info' to the UDP conversation so other */
5313 /* packets (both Control AND Data) will be marked as FP */
5314 umts_fp_conversation_info = wmem_new0(wmem_file_scope(), umts_fp_conversation_info_t);
5315 umts_fp_conversation_info->channel = CHANNEL_UNKNOWN;
5316 set_both_sides_umts_fp_conv_data(pinfo, umts_fp_conversation_info);
5317 /* Call FP Dissector for the current frame */
5318 dissect_fp(tvb, pinfo, tree, data);
5319 return true;
5322 /* This method wraps the heuristic dissectors of all supported channels */
5323 static bool
5324 heur_dissect_fp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
5326 bool match;
5328 match = heur_dissect_fp_dcch_over_dch(tvb, pinfo, tree, data);
5329 if(match)
5330 return true;
5331 match = heur_dissect_fp_fach1(tvb, pinfo, tree, data);
5332 if(match)
5333 return true;
5334 match = heur_dissect_fp_fach2(tvb, pinfo, tree, data);
5335 if(match)
5336 return true;
5337 match = heur_dissect_fp_rach(tvb, pinfo, tree, data);
5338 if(match)
5339 return true;
5340 match = heur_dissect_fp_pch(tvb, pinfo, tree, data);
5341 if(match)
5342 return true;
5343 match = heur_dissect_fp_hsdsch_type_1(tvb, pinfo, tree, data);
5344 if(match)
5345 return true;
5346 match = heur_dissect_fp_hsdsch_type_2(tvb, pinfo, tree, data);
5347 if(match)
5348 return true;
5349 match = heur_dissect_fp_edch_type_1(tvb, pinfo, tree, data);
5350 if(match)
5351 return true;
5352 /* NOTE: Add new heuristic dissectors BEFORE the 'unknown format' dissector */
5353 /* since it might 'swallow' packets if the UDP stream is framed as 'CHANNEL_UNKNOWN' */
5354 match = heur_dissect_fp_unknown_format(tvb, pinfo, tree, data);
5355 if(match)
5356 return true;
5358 return false;
5361 static uint8_t fakes =5; /*[] ={1,5,8};*/
5362 static uint8_t fake_map[256];
5365 * TODO: This need to be fixed!
5366 * Basically you would want the actual RRC messages, that sooner or later maps
5367 * transport channel id's to logical id's or RAB IDs
5368 * to set the proper logical channel/RAB ID, but for now we make syntethic ones.
5369 * */
5371 static uint8_t
5372 make_fake_lchid(packet_info *pinfo _U_, int trchld)
5374 if ( fake_map[trchld] == 0) {
5375 fake_map[trchld] = fakes;
5376 fakes++;
5378 return fake_map[trchld];
5381 /* Tries to resolve the U-RNTI of a channel user based on info in the fp conv info */
5382 static void fp_conv_resolve_urnti(umts_fp_conversation_info_t *p_conv_data)
5384 /* Trying to resolve the U-RNTI of the user if missing */
5385 /* Resolving based on the 'C-RNC Communication Context' field found in NBAP */
5386 if (!p_conv_data->urnti && p_conv_data->com_context_id != 0) {
5387 uint32_t * mapped_urnti = (uint32_t *)(wmem_tree_lookup32(nbap_crncc_urnti_map,p_conv_data->com_context_id));
5388 if (mapped_urnti != 0) {
5389 p_conv_data->urnti = GPOINTER_TO_UINT(mapped_urnti);
5394 /* Figures the best "UE ID" to use in RLC reassembly logic */
5395 static uint32_t get_ue_id_from_conv(umts_fp_conversation_info_t *p_conv_data)
5397 uint32_t user_identity;
5398 /* Choosing RLC 'UE ID': */
5399 /* 1. Preferring the U-RNTI if attached */
5400 /* 2. Fallback - Using the 'C-RNC Communication Context' used in NBAP for this user */
5401 user_identity = p_conv_data->com_context_id;
5402 if(p_conv_data->urnti) {
5403 user_identity = p_conv_data->urnti;
5405 return user_identity;
5408 static fp_info *
5409 fp_set_per_packet_inf_from_conv(conversation_t *p_conv,
5410 umts_fp_conversation_info_t *p_conv_data,
5411 tvbuff_t *tvb, packet_info *pinfo,
5412 proto_tree *tree _U_)
5414 fp_info *fpi;
5415 uint8_t tfi, c_t, lchid;
5416 int offset = 0, i=0, j=0, num_tbs, chan, tb_size, tb_bit_off;
5417 uint32_t ft;
5418 bool is_known_dcch_tf,is_stndalone_ps_rab_tf,is_muxed_cs_ps_tf;
5419 umts_mac_info *macinf;
5420 rlc_info *rlcinf;
5421 uint8_t fake_lchid=0;
5422 int *cur_val=NULL;
5423 fp_hsdsch_channel_info_t* fp_hsdsch_channel_info = NULL;
5424 fp_edch_channel_info_t* fp_edch_channel_info = NULL;
5425 fp_pch_channel_info_t *fp_pch_channel_info = NULL;
5426 fp_fach_channel_info_t* fp_fach_channel_info = NULL;
5427 fp_rach_channel_info_t* fp_rach_channel_info = NULL;
5428 bool info_missing = false;
5430 fpi = wmem_new0(wmem_file_scope(), fp_info);
5431 p_add_proto_data(wmem_file_scope(), pinfo, proto_fp, 0, fpi);
5433 fpi->iface_type = p_conv_data->iface_type;
5434 fpi->division = p_conv_data->division;
5435 fpi->release = 7; /* Set values greater then the checks performed */
5436 fpi->release_year = 2006;
5437 fpi->release_month = 12;
5438 fpi->channel = p_conv_data->channel;
5439 fpi->dch_crc_present = p_conv_data->dch_crc_present;
5440 fpi->link_type = FP_Link_Ethernet;
5442 #if 0
5443 /*Only do this the first run, signals that we need to reset the RLC fragtable*/
5444 if (!PINFO_FD_VISITED(pinfo) && p_conv_data->reset_frag ) {
5445 fpi->reset_frag = p_conv_data->reset_frag;
5446 p_conv_data->reset_frag = false;
5448 #endif
5449 /* remember 'lower' UDP layer port information so we can later
5450 * differentiate 'lower' UDP layer from 'user data' UDP layer */
5451 fpi->srcport = pinfo->srcport;
5452 fpi->destport = pinfo->destport;
5454 fpi->com_context_id = p_conv_data->com_context_id;
5455 if(!p_conv_data->urnti) {
5456 fp_conv_resolve_urnti(p_conv_data);
5458 fpi->urnti = p_conv_data->urnti;
5460 if (pinfo->link_dir == P2P_DIR_UL) {
5461 fpi->is_uplink = true;
5462 } else {
5463 fpi->is_uplink = false;
5466 ft = tvb_get_uint8(tvb, offset) & 0x01;
5468 switch (fpi->channel) {
5469 case CHANNEL_HSDSCH: /* HS-DSCH - High Speed Downlink Shared Channel */
5470 fp_hsdsch_channel_info = (fp_hsdsch_channel_info_t*)p_conv_data->channel_specific_info;
5471 if(fp_hsdsch_channel_info == NULL) {
5472 proto_tree_add_expert_format(tree, pinfo, &ei_fp_no_per_conv_channel_info, tvb, offset, -1,
5473 "Can't dissect HS-DSCH FP stream because no per-conversation channel info was attached!");
5474 info_missing = true;
5475 break;
5477 fpi->hsdsch_entity = fp_hsdsch_channel_info->hsdsch_entity;
5478 fpi->hsdsch_rlc_mode = p_conv_data->rlc_mode;
5479 macinf = wmem_new0(wmem_file_scope(), umts_mac_info);
5480 fpi->hsdsch_macflowd_id = fp_hsdsch_channel_info->hsdsch_macdflow_id;
5481 macinf->content[0] = hsdsch_macdflow_id_mac_content_map[fp_hsdsch_channel_info->hsdsch_macdflow_id];
5482 macinf->lchid[0] = fp_hsdsch_channel_info->hsdsch_macdflow_id;
5483 p_add_proto_data(wmem_file_scope(), pinfo, proto_umts_mac, 0, macinf);
5485 rlcinf = wmem_new0(wmem_file_scope(), rlc_info);
5487 /*Figure out RLC_MODE based on MACd-flow-ID, basically MACd-flow-ID = 0 then it's SRB0 == UM else AM*/
5488 rlcinf->mode[0] = hsdsch_macdflow_id_rlc_map[fp_hsdsch_channel_info->hsdsch_macdflow_id];
5490 if (fpi->hsdsch_entity == hs) {
5491 for (i=0; i<MAX_NUM_HSDHSCH_MACDFLOW; i++) {
5492 /*Figure out if this channel is multiplexed (signaled from RRC)*/
5493 if ((cur_val=(int *)g_tree_lookup(hsdsch_muxed_flows, GINT_TO_POINTER((int)fp_hsdsch_channel_info->hrnti))) != NULL) {
5494 j = 1 << i;
5495 fpi->hsdhsch_macfdlow_is_mux[i] = j & *cur_val;
5496 } else {
5497 fpi->hsdhsch_macfdlow_is_mux[i] = false;
5502 rlcinf->ueid[0] = get_ue_id_from_conv(p_conv_data);
5503 rlcinf->li_size[0] = RLC_LI_7BITS;
5504 rlcinf->ciphered[0] = false;
5505 rlcinf->deciphered[0] = false;
5506 p_add_proto_data(wmem_file_scope(), pinfo, proto_umts_rlc, 0, rlcinf);
5508 return fpi;
5510 case CHANNEL_EDCH:
5511 fp_edch_channel_info = (fp_edch_channel_info_t*)p_conv_data->channel_specific_info;
5512 if(fp_edch_channel_info == NULL) {
5513 proto_tree_add_expert_format(tree, pinfo, &ei_fp_no_per_conv_channel_info, tvb, offset, -1,
5514 "Can't dissect E-DCH FP stream because no per-conversation channel info was attached!");
5515 info_missing = true;
5516 break;
5518 macinf = wmem_new0(wmem_file_scope(), umts_mac_info);
5519 rlcinf = wmem_new0(wmem_file_scope(), rlc_info);
5520 fpi->no_ddi_entries = fp_edch_channel_info->no_ddi_entries;
5521 for (i=0; i<fpi->no_ddi_entries; i++) {
5522 fpi->edch_ddi[i] = fp_edch_channel_info->edch_ddi[i]; /*Set the DDI value*/
5523 fpi->edch_macd_pdu_size[i] = fp_edch_channel_info->edch_macd_pdu_size[i]; /*Set the PDU size*/
5524 fpi->edch_lchId[i] = fp_edch_channel_info->edch_lchId[i]; /*Set the channel id for this entry*/
5526 fpi->edch_type = fp_edch_channel_info->edch_type;
5528 rlcinf->ueid[0] = get_ue_id_from_conv(p_conv_data);
5529 rlcinf->li_size[0] = RLC_LI_7BITS;
5530 rlcinf->ciphered[0] = false;
5531 rlcinf->deciphered[0] = false;
5533 p_add_proto_data(wmem_file_scope(), pinfo, proto_umts_mac, 0, macinf);
5534 p_add_proto_data(wmem_file_scope(), pinfo, proto_umts_rlc, 0, rlcinf);
5536 return fpi;
5538 case CHANNEL_PCH:
5539 fp_pch_channel_info = (fp_pch_channel_info_t*)p_conv_data->channel_specific_info;
5540 if(fp_pch_channel_info == NULL) {
5541 proto_tree_add_expert_format(tree, pinfo, &ei_fp_no_per_conv_channel_info, tvb, offset, -1,
5542 "Can't dissect PCH FP stream because no per-conversation channel info was attached!");
5543 info_missing = true;
5544 break;
5546 fpi->paging_indications = fp_pch_channel_info->paging_indications;
5547 fpi->num_chans = p_conv_data->num_dch_in_flow;
5549 if (ft == FT_CONTROL) {
5550 /* control frame, we're done */
5551 return fpi;
5553 /* Inserting Paging Indication Info extracted from the previous packet */
5554 fpi->relevant_paging_indications = fp_pch_channel_info->last_paging_indication_info;
5555 fp_pch_channel_info->last_paging_indication_info = NULL;
5557 /* Set offset to TFI */
5558 offset = 3;
5559 break;
5560 case CHANNEL_DCH:
5561 fpi->num_chans = p_conv_data->num_dch_in_flow;
5562 if (ft == FT_CONTROL) {
5563 /* control frame, we're done */
5564 return fpi;
5567 rlcinf = wmem_new0(wmem_file_scope(), rlc_info);
5568 macinf = wmem_new0(wmem_file_scope(), umts_mac_info);
5569 offset = 2; /* Set offset to TFI */
5570 fakes = 5; /* Reset fake counter */
5571 for (chan=0; chan < fpi->num_chans; chan++) { /* Iterate over the DCH channels in the flow (each given a TFI) */
5572 /* TFI is 5 bits according to 3GPP TS 25.427, paragraph 6.2.4.4 */
5573 tfi = tvb_get_bits8(tvb, 3+offset*8, 5);
5575 /* Figure out the number of TBs and size */
5576 num_tbs = (fpi->is_uplink) ?
5577 p_conv_data->fp_dch_channel_info[chan].ul_chan_num_tbs[tfi] :
5578 p_conv_data->fp_dch_channel_info[chan].dl_chan_num_tbs[tfi];
5579 tb_size = (fpi->is_uplink) ?
5580 p_conv_data->fp_dch_channel_info[chan].ul_chan_tf_size[tfi] :
5581 p_conv_data->fp_dch_channel_info[chan].dl_chan_tf_size[tfi];
5583 tb_bit_off = (2 + p_conv_data->num_dch_in_flow) * 8; /*Point to the C/T of first TB*/
5584 /* Iterate over the Transport Blocks */
5585 /* Set configuration for each individual block */
5586 for (j=0; j < num_tbs && j+chan < MAX_MAC_FRAMES; j++) {
5587 /* Set transport channel id (useful for debugging) */
5588 macinf->trchid[j+chan] = p_conv_data->dch_ids_in_flow_list[chan];
5590 /* Checking for the common Transport Format of 3.4 kbps SRBs for DCCH ( See 3GPP TR 25.944 / 4.1.1.3.1.1 ) */
5591 is_known_dcch_tf = (tfi == 1 && num_tbs == 1 && tb_size == 148);
5592 /* Checking for Transport Format of interactive or background PS RAB ( See 3GPP TS 34.108 / 6.10.2.4.1.23 -> 6.10.2.4.1.35 ) */
5593 is_stndalone_ps_rab_tf = tb_size == 336;
5594 /* Checking for Transport Format of muxed CS & PS RABs ( See 3GPP TS 34.108 / 6.10.2.4.1.38 -> 6.10.2.4.1.51 ) */
5595 is_muxed_cs_ps_tf = (p_conv_data->dch_ids_in_flow_list[chan] == 24 && tb_size == 340);
5597 if (is_known_dcch_tf || is_muxed_cs_ps_tf) {
5598 /* Channel is multiplexed (ie. C/T field present) */
5599 macinf->ctmux[j+chan] = true;
5601 /* Peek at C/T, different RLC params for different logical channels */
5602 /* C/T is 4 bits according to 3GPP TS 25.321, paragraph 9.2.1, from MAC header (not FP) */
5603 c_t = tvb_get_bits8(tvb, tb_bit_off, 4);
5604 lchid = (c_t + 1) % 0xf; /* C/T field represents the Logical Channel ID but it is zero-based */
5605 macinf->lchid[j+chan] = lchid;
5606 macinf->content[j+chan] = lchId_type_table[lchid]; /* Base MAC content on logical channel id (Table is in packet-nbap.h) */
5607 rlcinf->mode[j+chan] = lchId_rlc_map[lchid]; /* Base RLC mode on logical channel id */
5609 else if (is_stndalone_ps_rab_tf) {
5610 /* Channel isn't multiplexed (ie. C/T field not present) */
5611 macinf->ctmux[j+chan] = false;
5613 /* Using a fake 'interactive PS' DTCH logical channel id */
5614 /* TODO: Once proper lchid is always set, this has to be changed */
5615 macinf->fake_chid[j+chan] = true;
5616 macinf->lchid[j+chan] = 11;
5617 macinf->content[j+chan] = MAC_CONTENT_PS_DTCH;
5618 rlcinf->mode[j+chan] = RLC_AM;
5620 else {
5621 /* Unfamiliar DCH format, faking LCHID */
5622 /* Asuming the channel isn't multiplexed (ie. C/T field not present) */
5623 macinf->ctmux[j+chan] = false;
5625 /* TODO: This stuff has to be reworked! */
5626 /* Generates a fake logical channel id for non multiplexed channel */
5627 fake_lchid = make_fake_lchid(pinfo, p_conv_data->dch_ids_in_flow_list[chan]);
5628 macinf->content[j+chan] = lchId_type_table[fake_lchid];
5629 rlcinf->mode[j+chan] = lchId_rlc_map[fake_lchid];
5631 /************************/
5632 /* TODO: Once proper lchid is always set, this has to be removed */
5633 macinf->fake_chid[j+chan] = true;
5634 macinf->lchid[j+chan] = fake_lchid;
5635 /************************/
5638 /* Set RLC data */
5639 rlcinf->ueid[j + chan] = get_ue_id_from_conv(p_conv_data);
5640 rlcinf->li_size[j+chan] = RLC_LI_7BITS;
5641 rlcinf->ciphered[j+chan] = false;
5642 rlcinf->deciphered[j+chan] = false;
5643 rlcinf->rbid[j+chan] = macinf->lchid[j+chan];
5645 /*Step over this TB and it's C/T field.*/
5646 tb_bit_off += tb_size+4;
5649 offset++;
5651 p_add_proto_data(wmem_file_scope(), pinfo, proto_umts_mac, 0, macinf);
5652 p_add_proto_data(wmem_file_scope(), pinfo, proto_umts_rlc, 0, rlcinf);
5653 /* Set offset to point to first TFI */
5654 offset = 2;
5655 break;
5656 case CHANNEL_FACH_FDD:
5657 fp_fach_channel_info = (fp_fach_channel_info_t*)p_conv_data->channel_specific_info;
5658 if(fp_fach_channel_info == NULL) {
5659 proto_tree_add_expert_format(tree, pinfo, &ei_fp_no_per_conv_channel_info, tvb, offset, -1,
5660 "Can't dissect FACH FP stream because no per-conversation channel info was attached!");
5661 info_missing = true;
5662 break;
5664 fpi->num_chans = p_conv_data->num_dch_in_flow;
5665 if (ft == FT_CONTROL) {
5666 /* control frame, we're done */
5667 return fpi;
5669 /* Set offset to TFI */
5670 offset = 2;
5671 /* Set MAC data */
5672 macinf = wmem_new0(wmem_file_scope(), umts_mac_info);
5673 macinf->ctmux[0] = 1;
5674 macinf->content[0] = MAC_CONTENT_DCCH;
5675 p_add_proto_data(wmem_file_scope(), pinfo, proto_umts_mac, 0, macinf);
5676 /* Set RLC data */
5677 rlcinf = wmem_new0(wmem_file_scope(), rlc_info);
5678 /* For RLC reassembly to work we need to fake a "UE ID" as an identifier of this stream.*/
5679 /* Using the (UDP) conversation's ID and the prefix of 0xFFF */
5680 rlcinf->ueid[0] = (p_conv->conv_index | 0xFFF00000);
5681 rlcinf->mode[0] = RLC_AM;
5682 rlcinf->li_size[0] = RLC_LI_7BITS;
5683 rlcinf->ciphered[0] = false;
5684 rlcinf->deciphered[0] = false;
5685 p_add_proto_data(wmem_file_scope(), pinfo, proto_umts_rlc, 0, rlcinf);
5686 break;
5688 case CHANNEL_RACH_FDD:
5689 fp_rach_channel_info = (fp_rach_channel_info_t*)p_conv_data->channel_specific_info;
5690 if(fp_rach_channel_info == NULL) {
5691 proto_tree_add_expert_format(tree, pinfo, &ei_fp_no_per_conv_channel_info, tvb, offset, -1,
5692 "Can't dissect RACH FP stream because no per-conversation channel info was attached!");
5693 info_missing = true;
5694 break;
5696 fpi->num_chans = p_conv_data->num_dch_in_flow;
5697 if (ft == FT_CONTROL) {
5698 /* control frame, we're done */
5699 return fpi;
5701 /* Set offset to TFI */
5702 offset = 2;
5703 /* set MAC & RLC data */
5704 macinf = wmem_new0(wmem_file_scope(), umts_mac_info);
5705 rlcinf = wmem_new0(wmem_file_scope(), rlc_info);
5706 for ( chan = 0; chan < fpi->num_chans; chan++ ) {
5707 macinf->ctmux[chan] = 1;
5708 macinf->content[chan] = MAC_CONTENT_DCCH;
5709 /* RLC dissector's reassembly requires a non-zero stream identifier ('UE ID') to work */
5710 /* For DCCH: MAC dissector will override this with C-RNTI/U-RNTI */
5711 /* For CCCH: RLC's mode is TM and the dissector does not reassemble at all - showing 0 in the UI to indicate that */
5712 rlcinf->ueid[chan] = 0;
5714 p_add_proto_data(wmem_file_scope(), pinfo, proto_umts_mac, 0, macinf);
5715 p_add_proto_data(wmem_file_scope(), pinfo, proto_umts_rlc, 0, rlcinf);
5716 break;
5717 case CHANNEL_HSDSCH_COMMON:
5718 rlcinf = wmem_new0(wmem_file_scope(), rlc_info);
5719 macinf = wmem_new0(wmem_file_scope(), umts_mac_info);
5720 p_add_proto_data(wmem_file_scope(), pinfo, proto_umts_mac, 0, macinf);
5721 p_add_proto_data(wmem_file_scope(), pinfo, proto_umts_rlc, 0, rlcinf);
5722 break;
5723 default:
5724 expert_add_info(pinfo, NULL, &ei_fp_transport_channel_type_unknown);
5725 info_missing = true;
5726 break;
5729 if(info_missing) {
5730 /* Some information was missing in the conversation struct and the FP info isn't complete */
5731 p_remove_proto_data(wmem_file_scope(), pinfo, proto_fp, 0);
5732 wmem_free(wmem_file_scope(), fpi);
5733 return NULL;
5736 /* Peek at the packet as the per packet info seems not to take the tfi into account */
5737 for (i=0; i<fpi->num_chans; i++) {
5738 /*TFI is 5 bits according to 3GPP TS 25.427, paragraph 6.2.4.4*/
5739 tfi = tvb_get_uint8(tvb, offset) & 0x1f;
5740 if (pinfo->link_dir == P2P_DIR_UL) {
5741 fpi->chan_tf_size[i] = p_conv_data->fp_dch_channel_info[i].ul_chan_tf_size[tfi];
5742 fpi->chan_num_tbs[i] = p_conv_data->fp_dch_channel_info[i].ul_chan_num_tbs[tfi];
5743 } else {
5744 fpi->chan_tf_size[i] = p_conv_data->fp_dch_channel_info[i].dl_chan_tf_size[tfi];
5745 fpi->chan_num_tbs[i] = p_conv_data->fp_dch_channel_info[i].dl_chan_num_tbs[tfi];
5747 offset++;
5751 return fpi;
5754 /* Updates the conversation info of a PCH stream based on information parsed in the current frame*/
5755 static void
5756 update_pch_coversation_info(umts_fp_conversation_info_t *p_conv_data, packet_info *pinfo, struct fp_info *p_fp_info)
5758 fp_pch_channel_info_t* fp_pch_channel_info;
5759 /* The channel type MUST be set to PCH */
5760 DISSECTOR_ASSERT(p_conv_data);
5761 DISSECTOR_ASSERT(p_conv_data->channel == CHANNEL_PCH);
5763 fp_pch_channel_info = (fp_pch_channel_info_t*)p_conv_data->channel_specific_info;
5764 if(p_fp_info->current_paging_indications && !PINFO_FD_VISITED(pinfo))
5766 /* Saving the PI info for the next packet to find */
5767 fp_pch_channel_info->last_paging_indication_info = p_fp_info->current_paging_indications;
5768 /* Resetting this field so we don't add it again to the conversation next time the packet is parsed */
5769 p_fp_info->current_paging_indications = NULL;
5773 /*****************************/
5774 /* Main dissection function. */
5775 static int
5776 dissect_fp_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
5778 proto_tree *fp_tree;
5779 proto_item *ti;
5780 int offset = 0;
5781 struct fp_info *p_fp_info;
5782 conversation_t *p_conv = NULL;
5783 umts_fp_conversation_info_t *p_conv_data = NULL;
5785 /* Append this protocol name rather than replace. */
5786 col_set_str(pinfo->cinfo, COL_PROTOCOL, "FP");
5788 /* Create fp tree. */
5789 ti = proto_tree_add_item(tree, proto_fp, tvb, offset, -1, ENC_NA);
5790 fp_tree = proto_item_add_subtree(ti, ett_fp);
5792 top_level_tree = tree;
5794 /* Look for packet info! */
5795 p_fp_info = (struct fp_info *)p_get_proto_data(wmem_file_scope(), pinfo, proto_fp, 0);
5797 /* Check if we have conversation info */
5798 /* Trying to find exact match - with both RNC's address & port and Node B's address & port */
5799 p_conv = (conversation_t *)find_conversation(pinfo->num, &pinfo->net_dst, &pinfo->net_src,
5800 conversation_pt_to_conversation_type(pinfo->ptype),
5801 pinfo->destport, pinfo->srcport, 0);
5802 if (p_conv) {
5803 p_conv_data = (umts_fp_conversation_info_t *)conversation_get_proto_data(p_conv, proto_fp);
5805 if (!p_conv || !p_conv_data) {
5806 /* Didn't find exact conversation match */
5807 /* Try to find a partial match with just the source/destination included */
5808 p_conv = (conversation_t *)find_conversation(pinfo->num, &pinfo->net_dst, &pinfo->net_src,
5809 conversation_pt_to_conversation_type(pinfo->ptype),
5810 pinfo->destport, pinfo->srcport, NO_ADDR_B);
5811 if (p_conv) {
5812 p_conv_data = (umts_fp_conversation_info_t *)conversation_get_proto_data(p_conv, proto_fp);
5816 if (p_conv_data) {
5817 /*Figure out the direction of the link*/
5818 if (addresses_equal(&(pinfo->net_dst), (&p_conv_data->crnc_address))) {
5819 /* Node B -> CRNC*/
5820 pinfo->link_dir=P2P_DIR_UL;
5822 proto_item *item= proto_tree_add_uint(fp_tree, hf_fp_ul_setup_frame,
5823 tvb, 0, 0, p_conv_data->ul_frame_number);
5824 proto_item_set_generated(item);
5826 else {
5827 /* CRNC -> Node B */
5828 pinfo->link_dir=P2P_DIR_DL;
5830 /* Maybe the frame number should be stored in the proper location already in nbap?, in ul_frame_number*/
5831 proto_item *item= proto_tree_add_uint(fp_tree, hf_fp_dl_setup_frame,
5832 tvb, 0, 0, p_conv_data->ul_frame_number);
5833 proto_item_set_generated(item);
5835 if (p_fp_info == NULL) {
5836 p_fp_info = fp_set_per_packet_inf_from_conv(p_conv, p_conv_data, tvb, pinfo, fp_tree);
5840 if (pinfo->p2p_dir == P2P_DIR_UNKNOWN) {
5841 if (pinfo->link_dir == P2P_DIR_UL) {
5842 pinfo->p2p_dir = P2P_DIR_RECV;
5843 } else {
5844 pinfo->p2p_dir = P2P_DIR_SENT;
5848 /* Can't dissect anything without it... */
5849 if (p_fp_info == NULL) {
5850 proto_tree_add_expert(fp_tree, pinfo, &ei_fp_no_per_frame_info, tvb, offset, -1);
5851 return 1;
5854 /* Show release information */
5855 if (preferences_show_release_info) {
5856 proto_item *release_ti;
5857 proto_tree *release_tree;
5858 proto_item *temp_ti;
5860 release_ti = proto_tree_add_item(fp_tree, hf_fp_release, tvb, 0, 0, ENC_NA);
5861 proto_item_set_generated(release_ti);
5862 proto_item_append_text(release_ti, " R%u (%d/%d)",
5863 p_fp_info->release, p_fp_info->release_year, p_fp_info->release_month);
5864 release_tree = proto_item_add_subtree(release_ti, ett_fp_release);
5866 temp_ti = proto_tree_add_uint(release_tree, hf_fp_release_version, tvb, 0, 0, p_fp_info->release);
5867 proto_item_set_generated(temp_ti);
5869 temp_ti = proto_tree_add_uint(release_tree, hf_fp_release_year, tvb, 0, 0, p_fp_info->release_year);
5870 proto_item_set_generated(temp_ti);
5872 temp_ti = proto_tree_add_uint(release_tree, hf_fp_release_month, tvb, 0, 0, p_fp_info->release_month);
5873 proto_item_set_generated(temp_ti);
5876 /* Show channel type in info column, tree */
5877 col_set_str(pinfo->cinfo, COL_INFO,
5878 val_to_str_const(p_fp_info->channel,
5879 channel_type_vals,
5880 "Unknown channel type"));
5881 if (p_conv_data) {
5882 int i;
5883 col_append_fstr(pinfo->cinfo, COL_INFO, "(%u", p_conv_data->dch_ids_in_flow_list[0]);
5884 for (i=1; i < p_conv_data->num_dch_in_flow; i++) {
5885 col_append_fstr(pinfo->cinfo, COL_INFO, ",%u", p_conv_data->dch_ids_in_flow_list[i]);
5887 col_append_str(pinfo->cinfo, COL_INFO, ") ");
5889 proto_item_append_text(ti, " (%s)",
5890 val_to_str_const(p_fp_info->channel,
5891 channel_type_vals,
5892 "Unknown channel type"));
5894 /* Add channel type as a generated field */
5895 ti = proto_tree_add_uint(fp_tree, hf_fp_channel_type, tvb, 0, 0, p_fp_info->channel);
5896 proto_item_set_generated(ti);
5898 /* Add division type as a generated field */
5899 if (p_fp_info->release == 7) {
5900 ti = proto_tree_add_uint(fp_tree, hf_fp_division, tvb, 0, 0, p_fp_info->division);
5901 proto_item_set_generated(ti);
5904 /* Add link direction as a generated field */
5905 ti = proto_tree_add_boolean(fp_tree, hf_fp_direction, tvb, 0, 0, p_fp_info->is_uplink);
5906 proto_item_set_generated(ti);
5908 /* Don't currently handle IuR-specific formats, but it's useful to even see
5909 the channel type and direction */
5910 if (p_fp_info->iface_type == IuR_Interface) {
5911 return 1;
5914 /* Show DDI config info */
5915 if (p_fp_info->no_ddi_entries > 0) {
5916 int n;
5917 proto_item *ddi_config_ti;
5918 proto_tree *ddi_config_tree;
5920 ddi_config_ti = proto_tree_add_string_format(fp_tree, hf_fp_ddi_config, tvb, offset, 0,
5921 "", "DDI Config (");
5922 proto_item_set_generated(ddi_config_ti);
5923 ddi_config_tree = proto_item_add_subtree(ddi_config_ti, ett_fp_ddi_config);
5925 /* Add each entry */
5926 for (n=0; n < p_fp_info->no_ddi_entries; n++) {
5927 proto_item_append_text(ddi_config_ti, "%s%u->%ubits",
5928 (n == 0) ? "" : " ",
5929 p_fp_info->edch_ddi[n], p_fp_info->edch_macd_pdu_size[n]);
5930 ti = proto_tree_add_uint(ddi_config_tree, hf_fp_ddi_config_ddi, tvb, 0, 0,
5931 p_fp_info->edch_ddi[n]);
5932 proto_item_set_generated(ti);
5933 ti = proto_tree_add_uint(ddi_config_tree, hf_fp_ddi_config_macd_pdu_size, tvb, 0, 0,
5934 p_fp_info->edch_macd_pdu_size[n]);
5935 proto_item_set_generated(ti);
5938 proto_item_append_text(ddi_config_ti, ")");
5941 /*************************************/
5942 /* Dissect according to channel type */
5943 switch (p_fp_info->channel) {
5944 case CHANNEL_RACH_TDD:
5945 case CHANNEL_RACH_TDD_128:
5946 case CHANNEL_RACH_FDD:
5947 dissect_rach_channel_info(tvb, pinfo, fp_tree, offset, p_fp_info,
5948 data);
5949 break;
5950 case CHANNEL_DCH:
5951 dissect_dch_channel_info(tvb, pinfo, fp_tree, offset, p_fp_info,
5952 data);
5953 break;
5954 case CHANNEL_FACH_FDD:
5955 case CHANNEL_FACH_TDD:
5956 dissect_fach_channel_info(tvb, pinfo, fp_tree, offset, p_fp_info,
5957 data);
5958 break;
5959 case CHANNEL_DSCH_FDD:
5960 case CHANNEL_DSCH_TDD:
5961 dissect_dsch_channel_info(tvb, pinfo, fp_tree, offset, p_fp_info);
5962 break;
5963 case CHANNEL_USCH_TDD_128:
5964 case CHANNEL_USCH_TDD_384:
5965 dissect_usch_channel_info(tvb, pinfo, fp_tree, offset, p_fp_info);
5966 break;
5967 case CHANNEL_PCH:
5968 dissect_pch_channel_info(tvb, pinfo, fp_tree, offset, p_fp_info,
5969 data);
5970 update_pch_coversation_info(p_conv_data, pinfo, p_fp_info);
5971 break;
5972 case CHANNEL_CPCH:
5973 dissect_cpch_channel_info(tvb, pinfo, fp_tree, offset, p_fp_info);
5974 break;
5975 case CHANNEL_BCH:
5976 dissect_bch_channel_info(tvb, pinfo, fp_tree, offset, p_fp_info);
5977 break;
5978 case CHANNEL_HSDSCH:
5979 /* Show configured MAC HS-DSCH entity in use */
5980 if (fp_tree)
5982 proto_item *entity_ti;
5983 entity_ti = proto_tree_add_uint(fp_tree, hf_fp_hsdsch_entity,
5984 tvb, 0, 0,
5985 p_fp_info->hsdsch_entity);
5986 proto_item_set_generated(entity_ti);
5988 switch (p_fp_info->hsdsch_entity) {
5989 case entity_not_specified:
5990 case hs:
5991 /* This is the pre-R7 default */
5992 dissect_hsdsch_channel_info(tvb, pinfo, fp_tree, offset, p_fp_info, data);
5993 break;
5994 case ehs:
5995 dissect_hsdsch_type_2_channel_info(tvb, pinfo, fp_tree, offset, p_fp_info, data);
5996 break;
5997 default:
5998 /* Report Error */
5999 expert_add_info(pinfo, NULL, &ei_fp_hsdsch_entity_not_specified);
6000 break;
6002 break;
6003 case CHANNEL_HSDSCH_COMMON:
6004 expert_add_info(pinfo, NULL, &ei_fp_hsdsch_common_experimental_support);
6005 /*if (false)*/
6006 dissect_hsdsch_common_channel_info(tvb, pinfo, fp_tree, offset, p_fp_info, data);
6008 break;
6009 case CHANNEL_HSDSCH_COMMON_T3:
6010 expert_add_info(pinfo, NULL, &ei_fp_hsdsch_common_t3_not_implemented);
6012 /* TODO: */
6013 break;
6014 case CHANNEL_IUR_CPCHF:
6015 /* TODO: */
6016 break;
6017 case CHANNEL_IUR_FACH:
6018 /* TODO: */
6019 break;
6020 case CHANNEL_IUR_DSCH:
6021 dissect_iur_dsch_channel_info(tvb, pinfo, fp_tree, offset, p_fp_info);
6022 break;
6023 case CHANNEL_EDCH:
6024 case CHANNEL_EDCH_COMMON:
6025 /* Show configured MAC E-DCH entity in use */
6026 if (fp_tree)
6028 proto_item *entity_ti;
6029 entity_ti = proto_tree_add_uint(fp_tree, hf_fp_edch_entity,
6030 tvb, 0, 0,
6031 p_fp_info->edch_type);
6032 proto_item_set_generated(entity_ti);
6034 dissect_e_dch_channel_info(tvb, pinfo, fp_tree, offset, p_fp_info,
6035 p_fp_info->channel == CHANNEL_EDCH_COMMON,
6036 data);
6037 break;
6039 default:
6040 expert_add_info(pinfo, NULL, &ei_fp_channel_type_unknown);
6041 break;
6043 return tvb_captured_length(tvb);
6046 static int
6047 dissect_fp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
6049 return dissect_fp_common(tvb, pinfo, tree, NULL);
6052 static int
6053 dissect_fp_aal2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
6055 return dissect_fp_common(tvb, pinfo, tree, data);
6058 void proto_register_fp(void)
6060 static hf_register_info hf[] =
6062 { &hf_fp_release,
6063 { "Release",
6064 "fp.release", FT_NONE, BASE_NONE, NULL, 0x0,
6065 "Release information", HFILL
6068 { &hf_fp_release_version,
6069 { "Release Version",
6070 "fp.release.version", FT_UINT8, BASE_DEC, NULL, 0x0,
6071 "3GPP Release number", HFILL
6074 { &hf_fp_release_year,
6075 { "Release year",
6076 "fp.release.year", FT_UINT16, BASE_DEC, NULL, 0x0,
6077 NULL, HFILL
6080 { &hf_fp_release_month,
6081 { "Release month",
6082 "fp.release.month", FT_UINT8, BASE_DEC, NULL, 0x0,
6083 NULL, HFILL
6086 { &hf_fp_channel_type,
6087 { "Channel Type",
6088 "fp.channel-type", FT_UINT8, BASE_HEX, VALS(channel_type_vals), 0x0,
6089 NULL, HFILL
6092 { &hf_fp_division,
6093 { "Division",
6094 "fp.division", FT_UINT8, BASE_HEX, VALS(division_vals), 0x0,
6095 "Radio division type", HFILL
6098 { &hf_fp_direction,
6099 { "Direction",
6100 "fp.direction", FT_BOOLEAN, BASE_NONE, TFS(&tfs_uplink_downlink), 0x0,
6101 "Link direction", HFILL
6104 { &hf_fp_ddi_config,
6105 { "DDI Config",
6106 "fp.ddi-config", FT_STRING, BASE_NONE, NULL, 0x0,
6107 "DDI Config (for E-DCH)", HFILL
6110 { &hf_fp_ddi_config_ddi,
6111 { "DDI",
6112 "fp.ddi-config.ddi", FT_UINT8, BASE_DEC, NULL, 0x0,
6113 NULL, HFILL
6116 { &hf_fp_ddi_config_macd_pdu_size,
6117 { "MACd PDU Size",
6118 "fp.ddi-config.macd-pdu-size", FT_UINT16, BASE_DEC, NULL, 0x0,
6119 NULL, HFILL
6124 { &hf_fp_header_crc,
6125 { "Header CRC",
6126 "fp.header-crc", FT_UINT8, BASE_HEX, NULL, 0xfe,
6127 NULL, HFILL
6130 { &hf_fp_ft,
6131 { "Frame Type",
6132 "fp.ft", FT_UINT8, BASE_HEX, VALS(frame_type_vals), 0x01,
6133 NULL, HFILL
6136 { &hf_fp_cfn,
6137 { "CFN",
6138 "fp.cfn", FT_UINT8, BASE_DEC, NULL, 0x0,
6139 "Connection Frame Number", HFILL
6142 { &hf_fp_pch_cfn,
6143 { "CFN (PCH)",
6144 "fp.pch.cfn", FT_UINT16, BASE_DEC, NULL, 0xfff0,
6145 "PCH Connection Frame Number", HFILL
6148 { &hf_fp_pch_toa,
6149 { "ToA (PCH)",
6150 "fp.pch.toa", FT_INT24, BASE_DEC, NULL, 0x0,
6151 "PCH Time of Arrival", HFILL
6154 { &hf_fp_cfn_control,
6155 { "CFN control",
6156 "fp.cfn-control", FT_UINT8, BASE_DEC, NULL, 0x0,
6157 "Connection Frame Number Control", HFILL
6160 { &hf_fp_toa,
6161 { "ToA",
6162 "fp.toa", FT_INT16, BASE_DEC, NULL, 0x0,
6163 "Time of arrival (units are 125 microseconds)", HFILL
6166 { &hf_fp_tb,
6167 { "TB",
6168 "fp.tb", FT_BYTES, BASE_NONE, NULL, 0x0,
6169 "Transport Block", HFILL
6172 { &hf_fp_chan_zero_tbs,
6173 { "No TBs for channel",
6174 "fp.channel-with-zero-tbs", FT_UINT32, BASE_DEC, NULL, 0x0,
6175 "Channel with 0 TBs", HFILL
6178 { &hf_fp_tfi,
6179 { "TFI",
6180 "fp.tfi", FT_UINT8, BASE_DEC, NULL, 0x0,
6181 "Transport Format Indicator", HFILL
6184 { &hf_fp_usch_tfi,
6185 { "TFI",
6186 "fp.usch.tfi", FT_UINT8, BASE_DEC, NULL, 0x1f,
6187 "USCH Transport Format Indicator", HFILL
6190 { &hf_fp_cpch_tfi,
6191 { "TFI",
6192 "fp.cpch.tfi", FT_UINT8, BASE_DEC, NULL, 0x1f,
6193 "CPCH Transport Format Indicator", HFILL
6196 { &hf_fp_propagation_delay,
6197 { "Propagation Delay",
6198 "fp.propagation-delay", FT_UINT8, BASE_DEC, NULL, 0x0,
6199 NULL, HFILL
6202 { &hf_fp_dch_control_frame_type,
6203 { "Control Frame Type",
6204 "fp.dch.control.frame-type", FT_UINT8, BASE_HEX, VALS(dch_control_frame_type_vals), 0x0,
6205 "DCH Control Frame Type", HFILL
6208 { &hf_fp_dch_rx_timing_deviation,
6209 { "Rx Timing Deviation",
6210 "fp.dch.control.rx-timing-deviation", FT_UINT8, BASE_DEC, 0, 0x0,
6211 "DCH Rx Timing Deviation", HFILL
6214 { &hf_fp_quality_estimate,
6215 { "Quality Estimate",
6216 "fp.dch.quality-estimate", FT_UINT8, BASE_DEC, 0, 0x0,
6217 NULL, HFILL
6220 { &hf_fp_payload_crc,
6221 { "Payload CRC",
6222 "fp.payload-crc", FT_UINT16, BASE_HEX, 0, 0x0,
6223 NULL, HFILL
6226 { &hf_fp_payload_crc_status,
6227 { "Payload CRC Status",
6228 "fp.payload-crc.status", FT_UINT8, BASE_NONE, VALS(proto_checksum_vals), 0x0,
6229 NULL, HFILL
6232 { &hf_fp_common_control_frame_type,
6233 { "Control Frame Type",
6234 "fp.common.control.frame-type", FT_UINT8, BASE_HEX, VALS(common_control_frame_type_vals), 0x0,
6235 "Common Control Frame Type", HFILL
6238 { &hf_fp_crci[0],
6239 { "CRCI",
6240 "fp.crci", FT_UINT8, BASE_HEX, VALS(crci_vals), 0x80,
6241 "CRC correctness indicator", HFILL
6244 { &hf_fp_crci[1],
6245 { "CRCI",
6246 "fp.crci", FT_UINT8, BASE_HEX, VALS(crci_vals), 0x40,
6247 "CRC correctness indicator", HFILL
6250 { &hf_fp_crci[2],
6251 { "CRCI",
6252 "fp.crci", FT_UINT8, BASE_HEX, VALS(crci_vals), 0x20,
6253 "CRC correctness indicator", HFILL
6256 { &hf_fp_crci[3],
6257 { "CRCI",
6258 "fp.crci", FT_UINT8, BASE_HEX, VALS(crci_vals), 0x10,
6259 "CRC correctness indicator", HFILL
6262 { &hf_fp_crci[4],
6263 { "CRCI",
6264 "fp.crci", FT_UINT8, BASE_HEX, VALS(crci_vals), 0x08,
6265 "CRC correctness indicator", HFILL
6268 { &hf_fp_crci[5],
6269 { "CRCI",
6270 "fp.crci", FT_UINT8, BASE_HEX, VALS(crci_vals), 0x04,
6271 "CRC correctness indicator", HFILL
6274 { &hf_fp_crci[6],
6275 { "CRCI",
6276 "fp.crci", FT_UINT8, BASE_HEX, VALS(crci_vals), 0x02,
6277 "CRC correctness indicator", HFILL
6280 { &hf_fp_crci[7],
6281 { "CRCI",
6282 "fp.crci", FT_UINT8, BASE_HEX, VALS(crci_vals), 0x01,
6283 "CRC correctness indicator", HFILL
6286 { &hf_fp_received_sync_ul_timing_deviation,
6287 { "Received SYNC UL Timing Deviation",
6288 "fp.rx-sync-ul-timing-deviation", FT_UINT8, BASE_DEC, 0, 0x0,
6289 NULL, HFILL
6292 { &hf_fp_pch_pi,
6293 { "Paging Indication",
6294 "fp.pch.pi", FT_UINT8, BASE_DEC, VALS(paging_indication_vals), 0x01,
6295 "Indicates if the PI Bitmap is present", HFILL
6298 { &hf_fp_pch_tfi,
6299 { "TFI",
6300 "fp.pch.tfi", FT_UINT8, BASE_DEC, 0, 0x1f,
6301 "PCH Transport Format Indicator", HFILL
6304 { &hf_fp_fach_tfi,
6305 { "TFI",
6306 "fp.fach.tfi", FT_UINT8, BASE_DEC, 0, 0x1f,
6307 "FACH Transport Format Indicator", HFILL
6310 { &hf_fp_transmit_power_level,
6311 { "Transmit Power Level",
6312 "fp.transmit-power-level", FT_FLOAT, BASE_NONE, 0, 0x0,
6313 "Transmit Power Level (dB)", HFILL
6316 { &hf_fp_pdsch_set_id,
6317 { "PDSCH Set Id",
6318 "fp.pdsch-set-id", FT_UINT8, BASE_DEC, 0, 0x0,
6319 "A pointer to the PDSCH Set which shall be used to transmit", HFILL
6322 { &hf_fp_paging_indication_bitmap,
6323 { "Paging Indications bitmap",
6324 "fp.pch.pi-bitmap", FT_BYTES , BASE_NONE, NULL, 0x0,
6325 "Paging Indication bitmap", HFILL
6328 { &hf_fp_relevant_paging_indication_bitmap,
6329 { "Relevant Paging Indications bitmap",
6330 "fp.pch.relevant-pi-bitmap", FT_BYTES , BASE_NONE, NULL, 0x0,
6331 "The Paging Indication bitmap used to inform users about the current frame", HFILL
6334 { &hf_fp_rx_timing_deviation,
6335 { "Rx Timing Deviation",
6336 "fp.common.control.rx-timing-deviation", FT_UINT8, BASE_DEC, 0, 0x0,
6337 "Common Rx Timing Deviation", HFILL
6340 { &hf_fp_dch_e_rucch_flag,
6341 { "E-RUCCH Flag",
6342 "fp.common.control.e-rucch-flag", FT_UINT8, BASE_DEC, VALS(e_rucch_flag_vals), 0x0,
6343 NULL, HFILL
6346 { &hf_fp_edch_header_crc,
6347 { "E-DCH Header CRC",
6348 "fp.edch.header-crc", FT_UINT16, BASE_HEX, 0, 0,
6349 NULL, HFILL
6352 { &hf_fp_edch_fsn,
6353 { "FSN",
6354 "fp.edch.fsn", FT_UINT8, BASE_DEC, 0, 0x0f,
6355 "E-DCH Frame Sequence Number", HFILL
6358 { &hf_fp_edch_number_of_subframes,
6359 { "No of subframes",
6360 "fp.edch.no-of-subframes", FT_UINT8, BASE_DEC, 0, 0x0f,
6361 "E-DCH Number of subframes", HFILL
6364 { &hf_fp_edch_harq_retransmissions,
6365 { "No of HARQ Retransmissions",
6366 "fp.edch.no-of-harq-retransmissions", FT_UINT8, BASE_DEC, 0, 0x78,
6367 "E-DCH Number of HARQ retransmissions", HFILL
6370 { &hf_fp_edch_subframe_number,
6371 { "Subframe number",
6372 "fp.edch.subframe-number", FT_UINT8, BASE_DEC, 0, 0x0,
6373 "E-DCH Subframe number", HFILL
6376 { &hf_fp_edch_number_of_mac_es_pdus,
6377 { "Number of Mac-es PDUs",
6378 "fp.edch.number-of-mac-es-pdus", FT_UINT8, BASE_DEC, 0, 0xf0,
6379 NULL, HFILL
6382 { &hf_fp_edch_ddi,
6383 { "DDI",
6384 "fp.edch.ddi", FT_UINT8, BASE_DEC, 0, 0x0,
6385 "E-DCH Data Description Indicator", HFILL
6388 { &hf_fp_edch_subframe,
6389 { "Subframe",
6390 "fp.edch.subframe", FT_STRING, BASE_NONE, NULL, 0x0,
6391 "EDCH Subframe", HFILL
6394 { &hf_fp_edch_subframe_header,
6395 { "Subframe header",
6396 "fp.edch.subframe-header", FT_STRING, BASE_NONE, NULL, 0x0,
6397 "EDCH Subframe header", HFILL
6400 { &hf_fp_edch_number_of_mac_d_pdus,
6401 { "Number of Mac-d PDUs",
6402 "fp.edch.number-of-mac-d-pdus", FT_UINT8, BASE_DEC, 0, 0x0,
6403 NULL, HFILL
6406 { &hf_fp_edch_pdu_padding,
6407 { "Padding",
6408 "fp.edch-data-padding", FT_UINT8, BASE_DEC, 0, 0xc0,
6409 "E-DCH padding before PDU", HFILL
6412 { &hf_fp_edch_tsn,
6413 { "TSN",
6414 "fp.edch-tsn", FT_UINT8, BASE_DEC, 0, 0x3f,
6415 "E-DCH Transmission Sequence Number", HFILL
6418 { &hf_fp_edch_mac_es_pdu,
6419 { "MAC-es PDU",
6420 "fp.edch.mac-es-pdu", FT_NONE, BASE_NONE, NULL, 0x0,
6421 NULL, HFILL
6425 { &hf_fp_edch_user_buffer_size,
6426 { "User Buffer Size",
6427 "fp.edch.user-buffer-size", FT_UINT24, BASE_DEC, NULL, 0x0,
6428 NULL, HFILL
6431 { &hf_fp_edch_no_macid_sdus,
6432 { "No of MAC-is SDUs",
6433 "fp.edch.no-macis-sdus", FT_UINT16, BASE_DEC, NULL, 0x0,
6434 NULL, HFILL
6437 { &hf_fp_edch_number_of_mac_is_pdus,
6438 { "Number of Mac-is PDUs",
6439 "fp.edch.number-of-mac-is-pdus", FT_UINT8, BASE_DEC, 0, 0x0,
6440 NULL, HFILL
6443 { &hf_fp_edch_mac_is_pdu,
6444 { "Mac-is PDU",
6445 "fp.edch.mac-is-pdu", FT_BYTES, BASE_NONE, 0, 0x0,
6446 NULL, HFILL
6449 { &hf_fp_edch_e_rnti,
6450 { "E-RNTI",
6451 "fp.edch.e-rnti", FT_UINT16, BASE_DEC, 0, 0x0,
6452 NULL, HFILL
6456 { &hf_fp_edch_macis_descriptors,
6457 { "MAC-is Descriptors",
6458 "fp.edch.mac-is.descriptors", FT_STRING, BASE_NONE, NULL, 0x0,
6459 NULL, HFILL
6462 { &hf_fp_edch_macis_lchid,
6463 { "LCH-ID",
6464 "fp.edch.mac-is.lchid", FT_UINT8, BASE_HEX, VALS(lchid_vals), 0xf0,
6465 NULL, HFILL
6468 { &hf_fp_edch_macis_length,
6469 { "Length",
6470 "fp.edch.mac-is.length", FT_UINT16, BASE_DEC, 0, 0x0ffe,
6471 NULL, HFILL
6474 { &hf_fp_edch_macis_flag,
6475 { "Flag",
6476 "fp.edch.mac-is.flag", FT_UINT8, BASE_HEX, 0, 0x01,
6477 "Indicates if another entry follows", HFILL
6480 { &hf_fp_edch_entity,
6481 { "E-DCH Entity",
6482 "fp.edch.entity", FT_UINT8, BASE_DEC, VALS(edch_mac_entity_vals), 0x0,
6483 "Type of MAC entity for this E-DCH channel", HFILL
6486 { &hf_fp_frame_seq_nr,
6487 { "Frame Seq Nr",
6488 "fp.frame-seq-nr", FT_UINT8, BASE_DEC, 0, 0xf0,
6489 "Frame Sequence Number", HFILL
6492 { &hf_fp_hsdsch_pdu_block_header,
6493 { "PDU block header",
6494 "fp.hsdsch.pdu-block-header", FT_STRING, BASE_NONE, NULL, 0x0,
6495 "HS-DSCH type 2 PDU block header", HFILL
6498 #if 0
6499 { &hf_fp_hsdsch_pdu_block,
6500 { "PDU block",
6501 "fp.hsdsch.pdu-block", FT_STRING, BASE_NONE, NULL, 0x0,
6502 "HS-DSCH type 2 PDU block data", HFILL
6505 #endif
6506 { &hf_fp_flush,
6507 { "Flush",
6508 "fp.flush", FT_UINT8, BASE_DEC, 0, 0x04,
6509 "Whether all PDUs for this priority queue should be removed", HFILL
6512 { &hf_fp_fsn_drt_reset,
6513 { "FSN-DRT reset",
6514 "fp.fsn-drt-reset", FT_UINT8, BASE_DEC, 0, 0x02,
6515 "FSN/DRT Reset Flag", HFILL
6518 { &hf_fp_drt_indicator,
6519 { "DRT Indicator",
6520 "fp.drt-indicator", FT_UINT8, BASE_DEC, 0, 0x01,
6521 NULL, HFILL
6524 { &hf_fp_fach_indicator,
6525 { "FACH Indicator",
6526 "fp.fach-indicator", FT_UINT8, BASE_DEC, 0, 0x80,
6527 NULL, HFILL
6530 { &hf_fp_total_pdu_blocks,
6531 { "PDU Blocks",
6532 "fp.pdu_blocks", FT_UINT8, BASE_DEC, 0, 0xf8,
6533 "Total number of PDU blocks", HFILL
6536 { &hf_fp_drt,
6537 { "DelayRefTime",
6538 "fp.drt", FT_UINT16, BASE_DEC, 0, 0x0,
6539 NULL, HFILL
6542 { &hf_fp_hrnti,
6543 { "HRNTI",
6544 "fp.hrnti", FT_UINT16, BASE_DEC, 0, 0x0,
6545 NULL, HFILL
6548 { &hf_fp_rach_measurement_result,
6549 { "RACH Measurement Result",
6550 "fp.rach-measurement-result", FT_UINT16, BASE_DEC, 0, 0x0,
6551 NULL, HFILL
6554 { &hf_fp_lchid,
6555 { "Logical Channel ID",
6556 "fp.lchid", FT_UINT8, BASE_DEC, NULL, 0x0,
6557 NULL, HFILL
6560 { &hf_fp_pdu_length_in_block,
6561 { "PDU length in block",
6562 "fp.pdu-length-in-block", FT_UINT8, BASE_DEC, 0, 0x0,
6563 "Length of each PDU in this block in bytes", HFILL
6566 { &hf_fp_pdus_in_block,
6567 { "PDUs in block",
6568 "fp.no-pdus-in-block", FT_UINT8, BASE_DEC, 0, 0x0,
6569 "Number of PDUs in block", HFILL
6572 { &hf_fp_cmch_pi,
6573 { "CmCH-PI",
6574 "fp.cmch-pi", FT_UINT8, BASE_DEC, 0, 0x0f,
6575 "Common Transport Channel Priority Indicator", HFILL
6578 { &hf_fp_user_buffer_size,
6579 { "User buffer size",
6580 "fp.user-buffer-size", FT_UINT16, BASE_DEC, 0, 0x0,
6581 "User buffer size in octets", HFILL
6584 { &hf_fp_hsdsch_credits,
6585 { "HS-DSCH Credits",
6586 "fp.hsdsch-credits", FT_UINT16, BASE_DEC, 0, 0x0,
6587 NULL, HFILL
6590 { &hf_fp_hsdsch_max_macd_pdu_len,
6591 { "Max MAC-d PDU Length",
6592 "fp.hsdsch.max-macd-pdu-len", FT_UINT16, BASE_DEC, 0, 0xfff8,
6593 "Maximum MAC-d PDU Length in bits", HFILL
6596 { &hf_fp_hsdsch_max_macdc_pdu_len,
6597 { "Max MAC-d/c PDU Length",
6598 "fp.hsdsch.max-macdc-pdu-len", FT_UINT16, BASE_DEC, 0, 0x07ff,
6599 "Maximum MAC-d/c PDU Length in bits", HFILL
6602 { &hf_fp_hsdsch_interval,
6603 { "HS-DSCH Interval in milliseconds",
6604 "fp.hsdsch-interval", FT_UINT8, BASE_DEC, 0, 0x0,
6605 NULL, HFILL
6608 { &hf_fp_hsdsch_calculated_rate,
6609 { "Calculated rate allocation (bps)",
6610 "fp.hsdsch-calculated-rate", FT_UINT32, BASE_DEC, 0, 0x0,
6611 "Calculated rate RNC is allowed to send in bps", HFILL
6614 { &hf_fp_hsdsch_unlimited_rate,
6615 { "Unlimited rate",
6616 "fp.hsdsch-unlimited-rate", FT_NONE, BASE_NONE, 0, 0x0,
6617 "No restriction on rate at which date may be sent", HFILL
6620 { &hf_fp_hsdsch_repetition_period,
6621 { "HS-DSCH Repetition Period",
6622 "fp.hsdsch-repetition-period", FT_UINT8, BASE_DEC, 0, 0x0,
6623 "HS-DSCH Repetition Period in milliseconds", HFILL
6626 { &hf_fp_hsdsch_data_padding,
6627 { "Padding",
6628 "fp.hsdsch-data-padding", FT_UINT8, BASE_DEC, 0, 0xf0,
6629 "HS-DSCH Repetition Period in milliseconds", HFILL
6632 { &hf_fp_hsdsch_new_ie_flags,
6633 { "New IEs flags",
6634 "fp.hsdsch.new-ie-flags", FT_STRING, BASE_NONE, 0, 0x0,
6635 NULL, HFILL
6638 { &hf_fp_hsdsch_new_ie_flag[0],
6639 { "DRT IE present",
6640 "fp.hsdsch.new-ie-flag", FT_UINT8, BASE_DEC, 0, 0x80,
6641 NULL, HFILL
6644 { &hf_fp_hsdsch_new_ie_flag[1],
6645 { "New IE present",
6646 "fp.hsdsch.new-ie-flag", FT_UINT8, BASE_DEC, 0, 0x40,
6647 NULL, HFILL
6650 { &hf_fp_hsdsch_new_ie_flag[2],
6651 { "New IE present",
6652 "fp.hsdsch.new-ie-flag", FT_UINT8, BASE_DEC, 0, 0x20,
6653 NULL, HFILL
6656 { &hf_fp_hsdsch_new_ie_flag[3],
6657 { "New IE present",
6658 "fp.hsdsch.new-ie-flag", FT_UINT8, BASE_DEC, 0, 0x10,
6659 NULL, HFILL
6662 { &hf_fp_hsdsch_new_ie_flag[4],
6663 { "New IE present",
6664 "fp.hsdsch.new-ie-flag", FT_UINT8, BASE_DEC, 0, 0x08,
6665 NULL, HFILL
6668 { &hf_fp_hsdsch_new_ie_flag[5],
6669 { "New IE present",
6670 "fp.hsdsch.new-ie-flag", FT_UINT8, BASE_DEC, 0, 0x04,
6671 NULL, HFILL
6674 { &hf_fp_hsdsch_new_ie_flag[6],
6675 { "HS-DSCH physical layer category present",
6676 "fp.hsdsch.new-ie-flag", FT_UINT8, BASE_DEC, 0, 0x02,
6677 NULL, HFILL
6680 { &hf_fp_hsdsch_new_ie_flag[7],
6681 { "Another new IE flags byte",
6682 "fp.hsdsch.new-ie-flags-byte", FT_UINT8, BASE_DEC, 0, 0x01,
6683 "Another new IE flagsbyte", HFILL
6686 { &hf_fp_hsdsch_drt,
6687 { "DRT",
6688 "fp.hsdsch.drt", FT_UINT16, BASE_DEC, 0, 0x0,
6689 "Delay Reference Time", HFILL
6692 { &hf_fp_hsdsch_entity,
6693 { "HS-DSCH Entity",
6694 "fp.hsdsch.entity", FT_UINT8, BASE_DEC, VALS(hsdshc_mac_entity_vals), 0x0,
6695 "Type of MAC entity for this HS-DSCH channel", HFILL
6698 { &hf_fp_timing_advance,
6699 { "Timing advance",
6700 "fp.timing-advance", FT_UINT8, BASE_DEC, 0, 0x3f,
6701 "Timing advance in chips", HFILL
6704 { &hf_fp_num_of_pdu,
6705 { "Number of PDUs",
6706 "fp.hsdsch.num-of-pdu", FT_UINT8, BASE_DEC, 0, 0x0,
6707 "Number of PDUs in the payload", HFILL
6710 { &hf_fp_mac_d_pdu_len,
6711 { "MAC-d PDU Length",
6712 "fp.hsdsch.mac-d-pdu-len", FT_UINT16, BASE_DEC, 0, 0xfff8,
6713 "MAC-d PDU Length in bits", HFILL
6716 { &hf_fp_mac_d_pdu,
6717 { "MAC-d PDU",
6718 "fp.mac-d-pdu", FT_BYTES, BASE_NONE, NULL, 0x0,
6719 NULL, HFILL
6722 { &hf_fp_data,
6723 { "Data",
6724 "fp.data", FT_BYTES, BASE_NONE, NULL, 0x0,
6725 NULL, HFILL
6728 { &hf_fp_crcis,
6729 { "CRCIs",
6730 "fp.crcis", FT_BYTES, BASE_NONE, NULL, 0x0,
6731 "CRC Indicators for uplink TBs", HFILL
6734 { &hf_fp_t1,
6735 { "T1",
6736 "fp.t1", FT_FLOAT, BASE_NONE, NULL, 0x0,
6737 "RNC frame number indicating time it sends frame", HFILL
6740 { &hf_fp_t2,
6741 { "T2",
6742 "fp.t2", FT_FLOAT, BASE_NONE, NULL, 0x0,
6743 "NodeB frame number indicating time it received DL Sync", HFILL
6746 { &hf_fp_t3,
6747 { "T3",
6748 "fp.t3", FT_FLOAT, BASE_NONE, NULL, 0x0,
6749 "NodeB frame number indicating time it sends frame", HFILL
6752 { &hf_fp_ul_sir_target,
6753 { "UL_SIR_TARGET",
6754 "fp.ul-sir-target", FT_FLOAT, BASE_NONE, 0, 0x0,
6755 "Value (in dB) of the SIR target to be used by the UL inner loop power control", HFILL
6758 { &hf_fp_pusch_set_id,
6759 { "PUSCH Set Id",
6760 "fp.pusch-set-id", FT_UINT8, BASE_DEC, NULL, 0x0,
6761 "Identifies PUSCH Set from those configured in NodeB", HFILL
6764 { &hf_fp_activation_cfn,
6765 { "Activation CFN",
6766 "fp.activation-cfn", FT_UINT8, BASE_DEC, NULL, 0x0,
6767 "Activation Connection Frame Number", HFILL
6770 { &hf_fp_duration,
6771 { "Duration (ms)",
6772 "fp.pusch-duration", FT_UINT8, BASE_DEC, NULL, 0x0,
6773 "Duration of the activation period of the PUSCH Set", HFILL
6776 { &hf_fp_power_offset,
6777 { "Power offset",
6778 "fp.power-offset", FT_FLOAT, BASE_NONE, NULL, 0x0,
6779 "Power offset (in dB)", HFILL
6782 { &hf_fp_code_number,
6783 { "Code number",
6784 "fp.code-number", FT_UINT8, BASE_DEC, NULL, 0x0,
6785 NULL, HFILL
6788 { &hf_fp_spreading_factor,
6789 { "Spreading factor",
6790 "fp.spreading-factor", FT_UINT8, BASE_DEC, VALS(spreading_factor_vals), 0xf0,
6791 NULL, HFILL
6794 { &hf_fp_mc_info,
6795 { "MC info",
6796 "fp.mc-info", FT_UINT8, BASE_DEC, NULL, 0x0e,
6797 NULL, HFILL
6800 { &hf_fp_rach_new_ie_flags,
6801 { "New IEs flags",
6802 "fp.rach.new-ie-flags", FT_STRING, BASE_NONE, 0, 0x0,
6803 NULL, HFILL
6806 { &hf_fp_rach_new_ie_flag_unused[0],
6807 { "New IE present",
6808 "fp.rach.new-ie-flag", FT_UINT8, BASE_DEC, 0, 0x80,
6809 NULL, HFILL
6812 { &hf_fp_rach_new_ie_flag_unused[1],
6813 { "New IE present",
6814 "fp.rach.new-ie-flag", FT_UINT8, BASE_DEC, 0, 0x40,
6815 NULL, HFILL
6818 { &hf_fp_rach_new_ie_flag_unused[2],
6819 { "New IE present",
6820 "fp.rach.new-ie-flag", FT_UINT8, BASE_DEC, 0, 0x20,
6821 "New IE present (unused)", HFILL
6824 { &hf_fp_rach_new_ie_flag_unused[3],
6825 { "New IE present",
6826 "fp.rach.new-ie-flag", FT_UINT8, BASE_DEC, 0, 0x10,
6827 "New IE present (unused)", HFILL
6830 { &hf_fp_rach_new_ie_flag_unused[4],
6831 { "New IE present",
6832 "fp.rach.new-ie-flag", FT_UINT8, BASE_DEC, 0, 0x08,
6833 "New IE present (unused)", HFILL
6836 { &hf_fp_rach_new_ie_flag_unused[5],
6837 { "New IE present",
6838 "fp.rach.new-ie-flag", FT_UINT8, BASE_DEC, 0, 0x04,
6839 "New IE present (unused)", HFILL
6842 { &hf_fp_rach_new_ie_flag_unused[6],
6843 { "New IE present",
6844 "fp.rach.new-ie-flag", FT_UINT8, BASE_DEC, 0, 0x02,
6845 "New IE present (unused)", HFILL
6848 { &hf_fp_rach_cell_portion_id_present,
6849 { "Cell portion ID present",
6850 "fp.rach.cell-portion-id-present", FT_UINT8, BASE_DEC, 0, 0x01,
6851 NULL, HFILL
6854 { &hf_fp_rach_angle_of_arrival_present,
6855 { "Angle of arrival present",
6856 "fp.rach.angle-of-arrival-present", FT_UINT8, BASE_DEC, 0, 0x01,
6857 NULL, HFILL
6860 { &hf_fp_rach_ext_propagation_delay_present,
6861 { "Ext Propagation Delay Present",
6862 "fp.rach.ext-propagation-delay-present", FT_UINT8, BASE_DEC, 0, 0x02,
6863 NULL, HFILL
6866 { &hf_fp_rach_ext_rx_sync_ul_timing_deviation_present,
6867 { "Ext Received Sync UL Timing Deviation present",
6868 "fp.rach.ext-rx-sync-ul-timing-deviation-present", FT_UINT8, BASE_DEC, 0, 0x02,
6869 NULL, HFILL
6872 { &hf_fp_rach_ext_rx_timing_deviation_present,
6873 { "Ext Rx Timing Deviation present",
6874 "fp.rach.ext-rx-timing-deviation-present", FT_UINT8, BASE_DEC, 0, 0x01,
6875 NULL, HFILL
6878 { &hf_fp_cell_portion_id,
6879 { "Cell Portion ID",
6880 "fp.cell-portion-id", FT_UINT8, BASE_DEC, NULL, 0x3f,
6881 NULL, HFILL
6884 { &hf_fp_ext_propagation_delay,
6885 { "Ext Propagation Delay",
6886 "fp.ext-propagation-delay", FT_UINT16, BASE_DEC, NULL, 0x03ff,
6887 NULL, HFILL
6890 { &hf_fp_angle_of_arrival,
6891 { "Angle of Arrival",
6892 "fp.angle-of-arrival", FT_UINT16, BASE_DEC, NULL, 0x03ff,
6893 NULL, HFILL
6896 { &hf_fp_ext_received_sync_ul_timing_deviation,
6897 { "Ext Received SYNC UL Timing Deviation",
6898 "fp.ext-received-sync-ul-timing-deviation", FT_UINT16, BASE_DEC, NULL, 0x1fff,
6899 NULL, HFILL
6904 { &hf_fp_radio_interface_parameter_update_flag[0],
6905 { "CFN valid",
6906 "fp.radio-interface-param.cfn-valid", FT_UINT16, BASE_DEC, 0, 0x0001,
6907 NULL, HFILL
6910 { &hf_fp_radio_interface_parameter_update_flag[1],
6911 { "TPC PO valid",
6912 "fp.radio-interface-param.tpc-po-valid", FT_UINT16, BASE_DEC, 0, 0x0002,
6913 NULL, HFILL
6916 { &hf_fp_radio_interface_parameter_update_flag[2],
6917 { "DPC mode valid",
6918 "fp.radio-interface-param.dpc-mode-valid", FT_UINT16, BASE_DEC, 0, 0x0004,
6919 NULL, HFILL
6922 { &hf_fp_radio_interface_parameter_update_flag[3],
6923 { "RL sets indicator valid",
6924 "fp.radio-interface_param.rl-sets-indicator-valid", FT_UINT16, BASE_DEC, 0, 0x0020,
6925 NULL, HFILL
6928 { &hf_fp_radio_interface_parameter_update_flag[4],
6929 { "Maximum UE TX Power valid",
6930 "fp.radio-interface-param.max-ue-tx-pow-valid", FT_UINT16, BASE_DEC, 0, 0x0040,
6931 "MAX UE TX POW valid", HFILL
6934 { &hf_fp_dpc_mode,
6935 { "DPC Mode",
6936 "fp.dpc-mode", FT_UINT8, BASE_DEC, NULL, 0x20,
6937 "DPC Mode to be applied in the uplink", HFILL
6940 { &hf_fp_tpc_po,
6941 { "TPC Power Offset",
6942 "fp.tpc-po", FT_FLOAT, BASE_NONE, NULL, 0x0,
6943 NULL, HFILL
6946 { &hf_fp_multiple_rl_set_indicator,
6947 { "Multiple RL sets indicator",
6948 "fp.multiple-rl-sets-indicator", FT_UINT8, BASE_DEC, NULL, 0x80,
6949 NULL, HFILL
6952 { &hf_fp_max_ue_tx_pow,
6953 { "Maximum UE TX Power",
6954 "fp.max-ue-tx-pow", FT_INT8, BASE_DEC, NULL, 0x0,
6955 "Max UE TX POW (dBm)", HFILL
6958 { &hf_fp_congestion_status,
6959 { "Congestion Status",
6960 "fp.congestion-status", FT_UINT8, BASE_DEC, VALS(congestion_status_vals), 0x0,
6961 NULL, HFILL
6964 { &hf_fp_e_rucch_present,
6965 { "E-RUCCH Present",
6966 "fp.erucch-present", FT_UINT8, BASE_DEC, NULL, 0x0,
6967 NULL, HFILL
6970 { &hf_fp_extended_bits_present,
6971 { "Extended Bits Present",
6972 "fp.extended-bits-present", FT_UINT8, BASE_DEC, NULL, 0x0,
6973 NULL, HFILL
6976 { &hf_fp_extended_bits,
6977 { "Extended Bits",
6978 "fp.extended-bits", FT_UINT8, BASE_HEX, NULL, 0x0,
6979 NULL, HFILL
6982 { &hf_fp_spare_extension,
6983 { "Spare Extension",
6984 "fp.spare-extension", FT_NONE, BASE_NONE, NULL, 0x0,
6985 NULL, HFILL
6988 { &hf_fp_ul_setup_frame,
6989 { "UL setup frame",
6990 "fp.ul.setup_frame", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
6991 NULL, HFILL
6994 { &hf_fp_dl_setup_frame,
6995 { "DL setup frame",
6996 "fp.dl.setup_frame", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
6997 NULL, HFILL
7000 { &hf_fp_relevant_pi_frame,
7001 { "Paging Indications frame number",
7002 "fp.pch.relevant-pi-frame", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
7003 "The frame where this Paging Indication bitmap was found",
7004 HFILL
7007 { &hf_fp_hsdsch_physical_layer_category,
7008 { "HS-DSCH physical layer category",
7009 "fp.hsdsch.physical_layer_category", FT_UINT8, BASE_DEC, NULL, 0x0,
7010 NULL, HFILL
7016 static int *ett[] =
7018 &ett_fp,
7019 &ett_fp_data,
7020 &ett_fp_crcis,
7021 &ett_fp_ddi_config,
7022 &ett_fp_edch_subframe_header,
7023 &ett_fp_edch_subframe,
7024 &ett_fp_edch_maces,
7025 &ett_fp_edch_macis_descriptors,
7026 &ett_fp_hsdsch_new_ie_flags,
7027 &ett_fp_rach_new_ie_flags,
7028 &ett_fp_hsdsch_pdu_block_header,
7029 &ett_fp_pch_relevant_pi,
7030 &ett_fp_release
7033 static ei_register_info ei[] = {
7034 { &ei_fp_bad_header_checksum, { "fp.header.bad_checksum", PI_CHECKSUM, PI_WARN, "Bad header checksum", EXPFILL }},
7035 { &ei_fp_crci_no_subdissector, { "fp.crci.no_subdissector", PI_UNDECODED, PI_NOTE, "Not sent to subdissectors as CRCI is set", EXPFILL }},
7036 { &ei_fp_crci_error_bit_set_for_tb, { "fp.crci.error_bit_set_for_tb", PI_CHECKSUM, PI_WARN, "CRCI error bit set for TB", EXPFILL }},
7037 { &ei_fp_spare_extension, { "fp.spare-extension.expert", PI_UNDECODED, PI_WARN, "Spare Extension present", EXPFILL }},
7038 { &ei_fp_bad_payload_checksum, { "fp.payload-crc.bad", PI_CHECKSUM, PI_WARN, "Bad payload checksum", EXPFILL }},
7039 { &ei_fp_stop_hsdpa_transmission, { "fp.stop_hsdpa_transmission", PI_RESPONSE_CODE, PI_NOTE, "Stop HSDPA transmission", EXPFILL }},
7040 { &ei_fp_timing_adjustment_reported, { "fp.timing_adjustment_reported", PI_SEQUENCE, PI_WARN, "Timing adjustment reported", EXPFILL }},
7041 { &ei_fp_expecting_tdd, { "fp.expecting_tdd", PI_MALFORMED, PI_NOTE, "Error: expecting TDD-384 or TDD-768", EXPFILL }},
7042 { &ei_fp_ddi_not_defined, { "fp.ddi_not_defined", PI_MALFORMED, PI_ERROR, "DDI not defined for this UE!", EXPFILL }},
7043 { &ei_fp_unable_to_locate_ddi_entry, { "fp.unable_to_locate_ddi_entry", PI_UNDECODED, PI_ERROR, "Unable to locate DDI entry.", EXPFILL }},
7044 { &ei_fp_mac_is_sdus_miscount, { "fp.mac_is_sdus.miscount", PI_MALFORMED, PI_ERROR, "Found too many MAC-is SDUs", EXPFILL }},
7045 { &ei_fp_e_rnti_t2_edch_frames, { "fp.e_rnti.t2_edch_frames", PI_MALFORMED, PI_ERROR, "E-RNTI not supposed to appear for T2 EDCH frames", EXPFILL }},
7046 { &ei_fp_e_rnti_first_entry, { "fp.e_rnti.first_entry", PI_MALFORMED, PI_ERROR, "E-RNTI must be first entry among descriptors", EXPFILL }},
7047 { &ei_fp_maybe_srb, { "fp.maybe_srb", PI_PROTOCOL, PI_NOTE, "Found MACd-Flow = 0 and not MUX detected. (This might be SRB)", EXPFILL }},
7048 { &ei_fp_transport_channel_type_unknown, { "fp.transport_channel_type.unknown", PI_UNDECODED, PI_WARN, "Unknown transport channel type", EXPFILL }},
7049 { &ei_fp_pch_lost_relevant_pi_frame, { "fp.pch_lost_relevant_pi_frame", PI_SEQUENCE, PI_WARN, "Previous PCH frame containing PI bitmap not captured (common at capture start)", EXPFILL }},
7050 { &ei_fp_hsdsch_entity_not_specified, { "fp.hsdsch_entity_not_specified", PI_MALFORMED, PI_ERROR, "HSDSCH Entity not specified", EXPFILL }},
7051 { &ei_fp_hsdsch_common_experimental_support, { "fp.hsdsch_common.experimental_support", PI_DEBUG, PI_WARN, "HSDSCH COMMON - Experimental support!", EXPFILL }},
7052 { &ei_fp_hsdsch_common_t3_not_implemented, { "fp.hsdsch_common_t3.not_implemented", PI_DEBUG, PI_ERROR, "HSDSCH COMMON T3 - Not implemented!", EXPFILL }},
7053 { &ei_fp_channel_type_unknown, { "fp.channel_type.unknown", PI_MALFORMED, PI_ERROR, "Unknown channel type", EXPFILL }},
7054 { &ei_fp_no_per_frame_info, { "fp.no_per_frame_info", PI_UNDECODED, PI_ERROR, "Can't dissect FP frame because no per-frame info was attached!", EXPFILL }},
7055 { &ei_fp_no_per_conv_channel_info, { "fp.no_per_conv_channel_info", PI_UNDECODED, PI_ERROR, "Can't dissect this FP stream because no per-conversation channel info was attached!", EXPFILL }},
7056 { &ei_fp_invalid_frame_count, { "fp.invalid_frame_count", PI_MALFORMED, PI_ERROR, "Invalid frame count", EXPFILL }},
7059 module_t *fp_module;
7060 expert_module_t *expert_fp;
7062 /* Register protocol. */
7063 proto_fp = proto_register_protocol("FP", "FP", "fp");
7064 proto_register_field_array(proto_fp, hf, array_length(hf));
7065 proto_register_subtree_array(ett, array_length(ett));
7066 expert_fp = expert_register_protocol(proto_fp);
7067 expert_register_field_array(expert_fp, ei, array_length(ei));
7069 /* Allow other dissectors to find this one by name. */
7070 fp_handle = register_dissector("fp", dissect_fp, proto_fp);
7071 fp_aal2_handle = register_dissector("fp.aal2", dissect_fp_aal2, proto_fp);
7073 /* Preferences */
7074 fp_module = prefs_register_protocol(proto_fp, NULL);
7076 /* Determines whether release information should be displayed */
7077 prefs_register_bool_preference(fp_module, "show_release_info",
7078 "Show reported release info",
7079 "Show reported release info",
7080 &preferences_show_release_info);
7082 /* Determines whether MAC dissector should be called for payloads */
7083 prefs_register_bool_preference(fp_module, "call_mac",
7084 "Call MAC dissector for payloads",
7085 "Call MAC dissector for payloads",
7086 &preferences_call_mac_dissectors);
7087 /* Determines whether or not to validate FP payload checksums */
7088 prefs_register_bool_preference(fp_module, "payload_checksum",
7089 "Validate FP payload checksums",
7090 "Validate FP payload checksums",
7091 &preferences_payload_checksum);
7092 /* Determines whether or not to validate FP header checksums */
7093 prefs_register_bool_preference(fp_module, "header_checksum",
7094 "Validate FP header checksums",
7095 "Validate FP header checksums",
7096 &preferences_header_checksum);
7097 /* Determines whether or not to track Paging Indications between PCH frames*/
7098 prefs_register_bool_preference(fp_module, "track_paging_indications",
7099 "Track Paging Indications in PCH channels",
7100 "For each PCH data frame, Try to show the paging indications bitmap found in the previous frame",
7101 &preferences_track_paging_indications);
7102 prefs_register_obsolete_preference(fp_module, "udp_heur");
7103 prefs_register_obsolete_preference(fp_module, "epandchannelconfigurationtable");
7108 void proto_reg_handoff_fp(void)
7110 rlc_bcch_handle = find_dissector_add_dependency("rlc.bcch", proto_fp);
7111 mac_fdd_rach_handle = find_dissector_add_dependency("mac.fdd.rach", proto_fp);
7112 mac_fdd_fach_handle = find_dissector_add_dependency("mac.fdd.fach", proto_fp);
7113 mac_fdd_pch_handle = find_dissector_add_dependency("mac.fdd.pch", proto_fp);
7114 mac_fdd_dch_handle = find_dissector_add_dependency("mac.fdd.dch", proto_fp);
7115 mac_fdd_edch_handle = find_dissector_add_dependency("mac.fdd.edch", proto_fp);
7116 mac_fdd_edch_type2_handle = find_dissector_add_dependency("mac.fdd.edch.type2", proto_fp);
7117 mac_fdd_hsdsch_handle = find_dissector_add_dependency("mac.fdd.hsdsch", proto_fp);
7119 heur_dissector_add("udp", heur_dissect_fp, "FP over UDP", "fp_udp", proto_fp, HEURISTIC_DISABLE);
7120 heur_dissector_add("fp_mux", heur_dissect_fp, "FP over FP Mux", "fp_fp_mux", proto_fp, HEURISTIC_ENABLE);
7122 dissector_add_uint("atm.aal2.type", TRAF_UMTS_FP, fp_aal2_handle);
7126 * Editor modelines - https://www.wireshark.org/tools/modelines.html
7128 * Local variables:
7129 * c-basic-offset: 4
7130 * tab-width: 8
7131 * indent-tabs-mode: nil
7132 * End:
7134 * vi: set shiftwidth=4 tabstop=8 expandtab:
7135 * :indentSize=4:tabSize=8:noTabs=true: