MSWSP: add two more Property Sets
[wireshark-wip.git] / epan / dissectors / packet-umts_fp.c
blob314741db3ad389a927ea4e0f7267da4505229872
1 /* Routines for UMTS FP disassembly
3 * Martin Mathieson
5 * $Id$
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
9 * Copyright 1998 Gerald Combs
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26 #include "config.h"
28 #include <epan/packet.h>
29 #include <epan/expert.h>
30 #include <epan/prefs.h>
31 #include <epan/wmem/wmem.h>
32 #include <epan/conversation.h>
33 #include <glib.h>
34 #include <wsutil/crc7.h> /* For FP data header and control frame CRC. */
35 #include <wsutil/crc16-plain.h> /* For FP Payload CRC. */
36 #include <wsutil/crc11.h> /* For FP EDCH header CRC. */
38 #include "packet-umts_mac.h"
39 #include "packet-rlc.h"
40 #include "packet-umts_fp.h"
41 #include "packet-nbap.h"
42 #include "packet-rrc.h"
44 /* The Frame Protocol (FP) is described in:
45 * 3GPP TS 25.427 (for dedicated channels)
46 * 3GPP TS 25.435 (for common/shared channels)
48 * TODO:
49 * - IUR interface-specific formats
50 * - do CRC verification before further parsing
51 * - Set the logical channel properly for non multiplexed, channels
52 * for channels that doesn't have the C/T flag! This should be based
53 * on the RRC message RadioBearerSetup.
56 /* Initialize the protocol and registered fields. */
58 int proto_fp = -1;
59 extern int proto_umts_mac;
60 extern int proto_rlc;
62 static int hf_fp_release = -1;
63 static int hf_fp_release_version = -1;
64 static int hf_fp_release_year = -1;
65 static int hf_fp_release_month = -1;
66 static int hf_fp_channel_type = -1;
67 static int hf_fp_division = -1;
68 static int hf_fp_direction = -1;
69 static int hf_fp_ddi_config = -1;
70 static int hf_fp_ddi_config_ddi = -1;
71 static int hf_fp_ddi_config_macd_pdu_size = -1;
73 static int hf_fp_header_crc = -1;
74 static int hf_fp_ft = -1;
75 static int hf_fp_cfn = -1;
76 static int hf_fp_pch_cfn = -1;
77 static int hf_fp_pch_toa = -1;
78 static int hf_fp_cfn_control = -1;
79 static int hf_fp_toa = -1;
80 static int hf_fp_tfi = -1;
81 static int hf_fp_usch_tfi = -1;
82 static int hf_fp_cpch_tfi = -1;
83 static int hf_fp_propagation_delay = -1;
84 static int hf_fp_tb = -1;
85 static int hf_fp_chan_zero_tbs = -1;
86 static int hf_fp_received_sync_ul_timing_deviation = -1;
87 static int hf_fp_pch_pi = -1;
88 static int hf_fp_pch_tfi = -1;
89 static int hf_fp_fach_tfi = -1;
90 static int hf_fp_transmit_power_level = -1;
91 static int hf_fp_paging_indication_bitmap = -1;
92 static int hf_fp_pdsch_set_id = -1;
93 static int hf_fp_rx_timing_deviation = -1;
94 static int hf_fp_dch_e_rucch_flag = -1;
95 static int hf_fp_dch_control_frame_type = -1;
96 static int hf_fp_dch_rx_timing_deviation = -1;
97 static int hf_fp_quality_estimate = -1;
98 static int hf_fp_payload_crc = -1;
99 static int hf_fp_edch_header_crc = -1;
100 static int hf_fp_edch_fsn = -1;
101 static int hf_fp_edch_subframe = -1;
102 static int hf_fp_edch_number_of_subframes = -1;
103 static int hf_fp_edch_harq_retransmissions = -1;
104 static int hf_fp_edch_subframe_number = -1;
105 static int hf_fp_edch_number_of_mac_es_pdus = -1;
106 static int hf_fp_edch_ddi = -1;
107 static int hf_fp_edch_subframe_header = -1;
108 static int hf_fp_edch_number_of_mac_d_pdus = -1;
109 static int hf_fp_edch_pdu_padding = -1;
110 static int hf_fp_edch_tsn = -1;
111 static int hf_fp_edch_mac_es_pdu = -1;
113 static int hf_fp_edch_user_buffer_size = -1;
114 static int hf_fp_edch_no_macid_sdus = -1;
115 static int hf_fp_edch_number_of_mac_is_pdus = -1;
116 static int hf_fp_edch_mac_is_pdu = -1;
118 static int hf_fp_edch_e_rnti = -1;
119 static int hf_fp_edch_macis_descriptors = -1;
120 static int hf_fp_edch_macis_lchid = -1;
121 static int hf_fp_edch_macis_length = -1;
122 static int hf_fp_edch_macis_flag = -1;
124 static int hf_fp_frame_seq_nr = -1;
125 static int hf_fp_hsdsch_pdu_block_header = -1;
126 /* static int hf_fp_hsdsch_pdu_block = -1; */
127 static int hf_fp_flush = -1;
128 static int hf_fp_fsn_drt_reset = -1;
129 static int hf_fp_drt_indicator = -1;
130 static int hf_fp_fach_indicator = -1;
131 static int hf_fp_total_pdu_blocks = -1;
132 static int hf_fp_drt = -1;
133 static int hf_fp_hrnti = -1;
134 static int hf_fp_rach_measurement_result = -1;
135 static int hf_fp_lchid = -1;
136 static int hf_fp_pdu_length_in_block = -1;
137 static int hf_fp_pdus_in_block = -1;
138 static int hf_fp_cmch_pi = -1;
139 static int hf_fp_user_buffer_size = -1;
140 static int hf_fp_hsdsch_credits = -1;
141 static int hf_fp_hsdsch_max_macd_pdu_len = -1;
142 static int hf_fp_hsdsch_max_macdc_pdu_len = -1;
143 static int hf_fp_hsdsch_interval = -1;
144 static int hf_fp_hsdsch_calculated_rate = -1;
145 static int hf_fp_hsdsch_unlimited_rate = -1;
146 static int hf_fp_hsdsch_repetition_period = -1;
147 static int hf_fp_hsdsch_data_padding = -1;
148 static int hf_fp_hsdsch_new_ie_flags = -1;
149 static int hf_fp_hsdsch_new_ie_flag[8] = {-1, -1, -1, -1, -1, -1, -1, -1};
150 static int hf_fp_hsdsch_drt = -1;
151 static int hf_fp_hsdsch_entity = -1;
152 static int hf_fp_hsdsch_physical_layer_category = -1;
153 static int hf_fp_timing_advance = -1;
154 static int hf_fp_num_of_pdu = -1;
155 static int hf_fp_mac_d_pdu_len = -1;
156 static int hf_fp_mac_d_pdu = -1;
157 static int hf_fp_data = -1;
158 static int hf_fp_crcis = -1;
159 static int hf_fp_crci[8] = {-1, -1, -1, -1, -1, -1, -1, -1};
160 static int hf_fp_common_control_frame_type = -1;
161 static int hf_fp_t1 = -1;
162 static int hf_fp_t2 = -1;
163 static int hf_fp_t3 = -1;
164 static int hf_fp_ul_sir_target = -1;
165 static int hf_fp_pusch_set_id = -1;
166 static int hf_fp_activation_cfn = -1;
167 static int hf_fp_duration = -1;
168 static int hf_fp_power_offset = -1;
169 static int hf_fp_code_number = -1;
170 static int hf_fp_spreading_factor = -1;
171 static int hf_fp_mc_info = -1;
173 static int hf_fp_rach_new_ie_flags = -1;
174 static int hf_fp_rach_new_ie_flag_unused[7] = {-1, -1, -1, -1, -1, -1, -1 };
175 static int hf_fp_rach_ext_propagation_delay_present = -1;
176 static int hf_fp_rach_cell_portion_id_present = -1;
177 static int hf_fp_rach_angle_of_arrival_present = -1;
178 static int hf_fp_rach_ext_rx_sync_ul_timing_deviation_present = -1;
179 static int hf_fp_rach_ext_rx_timing_deviation_present = -1;
181 static int hf_fp_cell_portion_id = -1;
182 static int hf_fp_ext_propagation_delay = -1;
183 static int hf_fp_angle_of_arrival = -1;
184 static int hf_fp_ext_received_sync_ul_timing_deviation = -1;
186 static int hf_fp_radio_interface_parameter_update_flag[5] = {-1, -1, -1, -1, -1};
187 static int hf_fp_dpc_mode = -1;
188 static int hf_fp_tpc_po = -1;
189 static int hf_fp_multiple_rl_set_indicator = -1;
190 static int hf_fp_max_ue_tx_pow = -1;
191 static int hf_fp_congestion_status = -1;
192 static int hf_fp_e_rucch_present = -1;
193 static int hf_fp_extended_bits_present = -1;
194 static int hf_fp_extended_bits = -1;
195 static int hf_fp_spare_extension = -1;
196 static int hf_fp_ul_setup_frame = -1;
197 static int hf_fp_dl_setup_frame = -1;
199 /* Subtrees. */
200 static int ett_fp = -1;
201 static int ett_fp_release = -1;
202 static int ett_fp_data = -1;
203 static int ett_fp_crcis = -1;
204 static int ett_fp_ddi_config = -1;
205 static int ett_fp_edch_subframe_header = -1;
206 static int ett_fp_edch_subframe = -1;
207 static int ett_fp_edch_maces = -1;
208 static int ett_fp_edch_macis_descriptors = -1;
209 static int ett_fp_hsdsch_new_ie_flags = -1;
210 static int ett_fp_rach_new_ie_flags = -1;
211 static int ett_fp_hsdsch_pdu_block_header = -1;
213 static expert_field ei_fp_hsdsch_common_experimental_support = EI_INIT;
214 static expert_field ei_fp_hsdsch_common_t3_not_implemented = EI_INIT;
215 static expert_field ei_fp_channel_type_unknown = EI_INIT;
216 static expert_field ei_fp_ddi_not_defined = EI_INIT;
217 static expert_field ei_fp_stop_hsdpa_transmission = EI_INIT;
218 static expert_field ei_fp_hsdsch_entity_not_specified = EI_INIT;
219 static expert_field ei_fp_expecting_tdd = EI_INIT;
220 static expert_field ei_fp_bad_payload_checksum = EI_INIT;
221 static expert_field ei_fp_e_rnti_t2_edch_frames = EI_INIT;
222 static expert_field ei_fp_crci_no_subdissector = EI_INIT;
223 static expert_field ei_fp_timing_adjustmentment_reported = EI_INIT;
224 static expert_field ei_fp_mac_is_sdus_miscount = EI_INIT;
225 static expert_field ei_fp_maybe_srb = EI_INIT;
226 static expert_field ei_fp_transport_channel_type_unknown = EI_INIT;
227 static expert_field ei_fp_unable_to_locate_ddi_entry = EI_INIT;
228 static expert_field ei_fp_e_rnti_first_entry = EI_INIT;
229 static expert_field ei_fp_bad_header_checksum = EI_INIT;
230 static expert_field ei_fp_crci_error_bit_set_for_tb = EI_INIT;
231 static expert_field ei_fp_spare_extension = EI_INIT;
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;
243 static proto_tree *top_level_tree = NULL;
245 /* Variables used for preferences */
246 static gboolean preferences_call_mac_dissectors = TRUE;
247 static gboolean preferences_show_release_info = TRUE;
248 static gboolean preferences_payload_checksum = TRUE;
249 static gboolean preferences_header_checksum = TRUE;
250 static gboolean preferences_udp_do_heur = FALSE;
252 /* E-DCH (T1) channel header information */
253 struct edch_t1_subframe_info
255 guint8 subframe_number;
256 guint8 number_of_mac_es_pdus;
257 guint8 ddi[64];
258 guint16 number_of_mac_d_pdus[64];
261 /* E-DCH (T2) channel header information */
262 struct edch_t2_subframe_info
264 guint8 subframe_number;
265 guint8 number_of_mac_is_pdus;
266 guint8 number_of_mac_is_sdus[16];
267 guint8 mac_is_lchid[16][16];
268 guint16 mac_is_length[16][16];
272 static const value_string channel_type_vals[] =
274 { CHANNEL_RACH_FDD, "RACH_FDD" },
275 { CHANNEL_RACH_TDD, "RACH_TDD" },
276 { CHANNEL_FACH_FDD, "FACH_FDD" },
277 { CHANNEL_FACH_TDD, "FACH_TDD" },
278 { CHANNEL_DSCH_FDD, "DSCH_FDD" },
279 { CHANNEL_DSCH_TDD, "DSCH_TDD" },
280 { CHANNEL_USCH_TDD_384, "USCH_TDD_384" },
281 { CHANNEL_USCH_TDD_128, "USCH_TDD_128" },
282 { CHANNEL_PCH, "PCH" },
283 { CHANNEL_CPCH, "CPCH" },
284 { CHANNEL_BCH, "BCH" },
285 { CHANNEL_DCH, "DCH" },
286 { CHANNEL_HSDSCH, "HSDSCH" },
287 { CHANNEL_IUR_CPCHF, "IUR CPCHF" },
288 { CHANNEL_IUR_FACH, "IUR FACH" },
289 { CHANNEL_IUR_DSCH, "IUR DSCH" },
290 { CHANNEL_EDCH, "EDCH" },
291 { CHANNEL_RACH_TDD_128, "RACH_TDD_128" },
292 { CHANNEL_HSDSCH_COMMON, "HSDSCH-COMMON" },
293 { CHANNEL_HSDSCH_COMMON_T3, "HSDSCH-COMMON-T3" },
294 { CHANNEL_EDCH_COMMON, "EDCH-COMMON"},
295 { 0, NULL }
298 static const value_string division_vals[] =
300 { Division_FDD, "FDD"},
301 { Division_TDD_384, "TDD-384"},
302 { Division_TDD_128, "TDD-128"},
303 { Division_TDD_768, "TDD-768"},
304 { 0, NULL }
308 static const value_string data_control_vals[] = {
309 { 0, "Data" },
310 { 1, "Control" },
311 { 0, NULL }
314 static const value_string direction_vals[] = {
315 { 0, "Downlink" },
316 { 1, "Uplink" },
317 { 0, NULL }
320 static const value_string crci_vals[] = {
321 { 0, "Correct" },
322 { 1, "Not correct" },
323 { 0, NULL }
326 static const value_string paging_indication_vals[] = {
327 { 0, "no PI-bitmap in payload" },
328 { 1, "PI-bitmap in payload" },
329 { 0, NULL }
332 static const value_string spreading_factor_vals[] = {
333 { 0, "4"},
334 { 1, "8"},
335 { 2, "16"},
336 { 3, "32"},
337 { 4, "64"},
338 { 5, "128"},
339 { 6, "256"},
340 { 0, NULL }
343 static const value_string congestion_status_vals[] = {
344 { 0, "No TNL congestion"},
345 { 1, "Reserved for future use"},
346 { 2, "TNL congestion - detected by delay build-up"},
347 { 3, "TNL congestion - detected by frame loss"},
348 { 0, NULL }
351 static const value_string e_rucch_flag_vals[] = {
352 { 0, "Conventional E-RUCCH reception" },
353 { 1, "TA Request reception" },
354 { 0, NULL }
357 static const value_string hsdshc_mac_entity_vals[] = {
358 { entity_not_specified, "Unspecified (assume MAC-hs)" },
359 { hs, "MAC-hs" },
360 { ehs, "MAC-ehs" },
361 { 0, NULL }
364 /* TODO: add and use */
365 #if 0
366 static const value_string segmentation_status_vals[] = {
367 { 0, "" },
368 { 1, "" },
369 { 2, "" },
370 { 3, "" },
371 { 0, NULL }
373 #endif
375 static const value_string lchid_vals[] = {
376 { 0, "Logical Channel 1" },
377 { 1, "Logical Channel 2" },
378 { 2, "Logical Channel 3" },
379 { 3, "Logical Channel 4" },
380 { 4, "Logical Channel 5" },
381 { 5, "Logical Channel 6" },
382 { 6, "Logical Channel 7" },
383 { 7, "Logical Channel 8" },
384 { 8, "Logical Channel 9" },
385 { 9, "Logical Channel 10" },
386 { 10, "Logical Channel 11" },
387 { 11, "Logical Channel 12" },
388 { 12, "Logical Channel 13" },
389 { 13, "Logical Channel 14" },
390 { 14, "CCCH (SRB0)" },
391 { 15, "E-RNTI being included (FDD only)" },
392 { 0, NULL }
395 /* Dedicated control types */
396 #define DCH_OUTER_LOOP_POWER_CONTROL 1
397 #define DCH_TIMING_ADJUSTMENT 2
398 #define DCH_DL_SYNCHRONISATION 3
399 #define DCH_UL_SYNCHRONISATION 4
401 #define DCH_DL_NODE_SYNCHRONISATION 6
402 #define DCH_UL_NODE_SYNCHRONISATION 7
403 #define DCH_RX_TIMING_DEVIATION 8
404 #define DCH_RADIO_INTERFACE_PARAMETER_UPDATE 9
405 #define DCH_TIMING_ADVANCE 10
406 #define DCH_TNL_CONGESTION_INDICATION 11
408 static const value_string dch_control_frame_type_vals[] = {
409 { DCH_OUTER_LOOP_POWER_CONTROL, "OUTER LOOP POWER CONTROL" },
410 { DCH_TIMING_ADJUSTMENT, "TIMING ADJUSTMENT" },
411 { DCH_DL_SYNCHRONISATION, "DL SYNCHRONISATION" },
412 { DCH_UL_SYNCHRONISATION, "UL SYNCHRONISATION" },
413 { 5, "Reserved Value" },
414 { DCH_DL_NODE_SYNCHRONISATION, "DL NODE SYNCHRONISATION" },
415 { DCH_UL_NODE_SYNCHRONISATION, "UL NODE SYNCHRONISATION" },
416 { DCH_RX_TIMING_DEVIATION, "RX TIMING DEVIATION" },
417 { DCH_RADIO_INTERFACE_PARAMETER_UPDATE, "RADIO INTERFACE PARAMETER UPDATE" },
418 { DCH_TIMING_ADVANCE, "TIMING ADVANCE" },
419 { DCH_TNL_CONGESTION_INDICATION, "TNL CONGESTION INDICATION" },
420 { 0, NULL }
424 /* Common channel control types */
425 #define COMMON_OUTER_LOOP_POWER_CONTROL 1
426 #define COMMON_TIMING_ADJUSTMENT 2
427 #define COMMON_DL_SYNCHRONISATION 3
428 #define COMMON_UL_SYNCHRONISATION 4
430 #define COMMON_DL_NODE_SYNCHRONISATION 6
431 #define COMMON_UL_NODE_SYNCHRONISATION 7
432 #define COMMON_DYNAMIC_PUSCH_ASSIGNMENT 8
433 #define COMMON_TIMING_ADVANCE 9
434 #define COMMON_HS_DSCH_Capacity_Request 10
435 #define COMMON_HS_DSCH_Capacity_Allocation 11
436 #define COMMON_HS_DSCH_Capacity_Allocation_Type_2 12
438 static const value_string common_control_frame_type_vals[] = {
439 { COMMON_OUTER_LOOP_POWER_CONTROL, "OUTER LOOP POWER CONTROL" },
440 { COMMON_TIMING_ADJUSTMENT, "TIMING ADJUSTMENT" },
441 { COMMON_DL_SYNCHRONISATION, "DL SYNCHRONISATION" },
442 { COMMON_UL_SYNCHRONISATION, "UL SYNCHRONISATION" },
443 { 5, "Reserved Value" },
444 { COMMON_DL_NODE_SYNCHRONISATION, "DL NODE SYNCHRONISATION" },
445 { COMMON_UL_NODE_SYNCHRONISATION, "UL NODE SYNCHRONISATION" },
446 { COMMON_DYNAMIC_PUSCH_ASSIGNMENT, "DYNAMIC PUSCH ASSIGNMENT" },
447 { COMMON_TIMING_ADVANCE, "TIMING ADVANCE" },
448 { COMMON_HS_DSCH_Capacity_Request, "HS-DSCH Capacity Request" },
449 { COMMON_HS_DSCH_Capacity_Allocation, "HS-DSCH Capacity Allocation" },
450 { COMMON_HS_DSCH_Capacity_Allocation_Type_2, "HS-DSCH Capacity Allocation Type 2" },
451 { 0, NULL }
454 /* Dissect message parts */
455 static int dissect_tb_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
456 int offset, struct fp_info *p_fp_info,
457 dissector_handle_t *data_handle);
459 static int dissect_macd_pdu_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
460 int offset, guint16 length, guint16 number_of_pdus,struct fp_info *p_fp_info);
461 static int dissect_macd_pdu_data_type_2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
462 int offset, guint16 length, guint16 number_of_pdus,struct fp_info * fpi);
464 static int dissect_crci_bits(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
465 fp_info *p_fp_info, int offset);
466 static void dissect_spare_extension_and_crc(tvbuff_t *tvb, packet_info *pinfo,
467 proto_tree *tree, guint8 dch_crc_present,
468 int offset, guint header_length);
469 /* Dissect common control messages */
470 static int dissect_common_outer_loop_power_control(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb,
471 int offset, struct fp_info *p_fp_info);
472 static int dissect_common_timing_adjustment(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb,
473 int offset, struct fp_info *p_fp_info);
474 static int dissect_common_dl_node_synchronisation(packet_info *pinfo, proto_tree *tree,
475 tvbuff_t *tvb, int offset);
476 static int dissect_common_ul_node_synchronisation(packet_info *pinfo, proto_tree *tree,
477 tvbuff_t *tvb, int offset);
478 static int dissect_common_dl_synchronisation(packet_info *pinfo, proto_tree *tree,
479 tvbuff_t *tvb, int offset,
480 struct fp_info *p_fp_info);
481 static int dissect_common_ul_synchronisation(packet_info *pinfo, proto_tree *tree,
482 tvbuff_t *tvb, int offset,
483 struct fp_info *p_fp_info);
484 static int dissect_common_timing_advance(packet_info *pinfo, proto_tree *tree,
485 tvbuff_t *tvb, int offset);
486 static int dissect_hsdpa_capacity_request(packet_info *pinfo, proto_tree *tree,
487 tvbuff_t *tvb, int offset);
488 static int dissect_hsdpa_capacity_allocation(packet_info *pinfo, proto_tree *tree,
489 tvbuff_t *tvb, int offset,
490 struct fp_info *p_fp_info);
491 static int dissect_hsdpa_capacity_allocation_type_2(packet_info *pinfo, proto_tree *tree,
492 tvbuff_t *tvb, int offset);
493 static void dissect_common_control(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
494 int offset, struct fp_info *p_fp_info);
495 static int dissect_common_dynamic_pusch_assignment(packet_info *pinfo, proto_tree *tree,
496 tvbuff_t *tvb, int offset);
498 /* Dissect common channel types */
499 static void dissect_rach_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
500 int offset, struct fp_info *p_fp_info);
501 static void dissect_fach_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
502 int offset, struct fp_info *p_fp_info);
503 static void dissect_dsch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
504 int offset, struct fp_info *p_fp_info);
505 static void dissect_usch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
506 int offset, struct fp_info *p_fp_info);
507 static void dissect_pch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
508 int offset, struct fp_info *p_fp_info);
509 static void dissect_cpch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
510 int offset, struct fp_info *p_fp_info);
511 static void dissect_bch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
512 int offset, struct fp_info *p_fp_info);
513 static void dissect_iur_dsch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
514 int offset, struct fp_info *p_fp_info);
515 static void dissect_hsdsch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
516 int offset, struct fp_info *p_fp_info);
517 static void dissect_hsdsch_type_2_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
518 int offset, struct fp_info *p_fp_info);
519 static void dissect_hsdsch_common_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
520 int offset, struct fp_info *p_fp_info);
522 /* Dissect DCH control messages */
523 static int dissect_dch_timing_adjustment(proto_tree *tree, packet_info *pinfo,
524 tvbuff_t *tvb, int offset);
525 static int dissect_dch_rx_timing_deviation(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset,
526 struct fp_info *p_fp_info);
527 static int dissect_dch_dl_synchronisation(proto_tree *tree, packet_info *pinfo,
528 tvbuff_t *tvb, int offset);
529 static int dissect_dch_ul_synchronisation(proto_tree *tree, packet_info *pinfo,
530 tvbuff_t *tvb, int offset);
531 static int dissect_dch_outer_loop_power_control(proto_tree *tree, packet_info *pinfo,
532 tvbuff_t *tvb, int offset);
533 static int dissect_dch_dl_node_synchronisation(proto_tree *tree, packet_info *pinfo,
534 tvbuff_t *tvb, int offset);
535 static int dissect_dch_ul_node_synchronisation(proto_tree *tree, packet_info *pinfo,
536 tvbuff_t *tvb, int offset);
537 static int dissect_dch_radio_interface_parameter_update(proto_tree *tree, packet_info *pinfo,
538 tvbuff_t *tvb, int offset);
539 static int dissect_dch_timing_advance(proto_tree *tree, packet_info *pinfo,
540 tvbuff_t *tvb, int offset, struct fp_info *p_fp_info);
541 static int dissect_dch_tnl_congestion_indication(proto_tree *tree, packet_info *pinfo,
542 tvbuff_t *tvb, int offset);
545 static void dissect_dch_control_frame(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb,
546 int offset, struct fp_info *p_fp_info);
549 /* Dissect a DCH channel */
550 static void dissect_dch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
551 int offset, struct fp_info *p_fp_info);
553 /* Dissect dedicated channels */
554 static void dissect_e_dch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
555 int offset, struct fp_info *p_fp_info,
556 gboolean is_common, rlc_info *rlcinf);
558 static void dissect_e_dch_t2_or_common_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
559 int offset, struct fp_info *p_fp_info,
560 int number_of_subframes,
561 gboolean is_common, guint16 header_crc, proto_item * header_crc_pi);
563 /* Main dissection function */
564 static void dissect_fp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
567 * CRNC sends data downlink on uplink parameters.
569 void
570 set_umts_fp_conv_data(conversation_t *conversation, umts_fp_conversation_info_t *umts_fp_conversation_info)
573 if (conversation == NULL){
574 return;
577 conversation_add_proto_data(conversation, proto_fp, umts_fp_conversation_info);
581 static int
582 get_tb_count(struct fp_info *p_fp_info)
584 int chan, tb_count = 0;
585 for (chan = 0; chan < p_fp_info->num_chans; chan++) {
586 tb_count += p_fp_info->chan_num_tbs[chan];
588 return tb_count;
591 static gboolean verify_control_frame_crc(tvbuff_t * tvb, packet_info * pinfo, proto_item * pi, guint16 frame_crc)
593 guint8 crc = 0;
594 guint8 * data = NULL;
595 /* Get data. */
596 data = tvb_get_string(wmem_packet_scope(), tvb, 0, tvb_length(tvb));
597 /* Include only FT flag bit in CRC calculation. */
598 data[0] = data[0] & 1;
599 /* Calculate crc7 sum. */
600 crc = crc7update(0, data, tvb_length(tvb));
601 crc = crc7finalize(crc); /* finalize crc */
602 if (frame_crc == crc) {
603 proto_item_append_text(pi, " [correct]");
604 return TRUE;
605 } else {
606 proto_item_append_text(pi, " [incorrect, should be 0x%x]", crc);
607 expert_add_info(pinfo, pi, &ei_fp_bad_header_checksum);
608 return FALSE;
611 static gboolean verify_header_crc(tvbuff_t * tvb, packet_info * pinfo, proto_item * pi, guint16 header_crc, guint header_length)
613 guint8 crc = 0;
614 guint8 * data = NULL;
615 /* Get data of header with first byte removed. */
616 data = tvb_get_string(wmem_packet_scope(), tvb, 1, header_length-1);
617 /* Calculate crc7 sum. */
618 crc = crc7update(0, data, header_length-1);
619 crc = crc7finalize(crc); /* finalize crc */
620 if (header_crc == crc) {
621 proto_item_append_text(pi, " [correct]");
622 return TRUE;
623 } else {
624 proto_item_append_text(pi, " [incorrect, should be 0x%x]", crc);
625 expert_add_info(pinfo, pi, &ei_fp_bad_header_checksum);
626 return FALSE;
629 static gboolean verify_header_crc_edch(tvbuff_t * tvb, packet_info * pinfo, proto_item * pi, guint16 header_crc, guint header_length)
631 guint16 crc = 0;
632 guint8 * data = NULL;
633 /* First create new subset of header with first byte removed. */
634 tvbuff_t * headtvb = tvb_new_subset(tvb, 1, header_length-1, header_length-1);
635 /* Get data of header with first byte removed. */
636 data = tvb_get_string(wmem_packet_scope(), headtvb, 0, header_length-1);
637 /* Remove first 4 bits of the remaining data which are Header CRC cont. */
638 data[0] = data[0] & 0x0f;
639 crc = crc11_307_noreflect_noxor(data, header_length-1);
640 if (header_crc == crc) {
641 proto_item_append_text(pi, " [correct]");
642 return TRUE;
643 } else {
644 proto_item_append_text(pi, " [incorrect, should be 0x%x]", crc);
645 expert_add_info(pinfo, pi, &ei_fp_bad_header_checksum);
646 return FALSE;
650 /* Dissect the TBs of a UL data frame*/
651 static int
652 dissect_tb_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
653 int offset, struct fp_info *p_fp_info,
654 dissector_handle_t *data_handle)
656 int chan, num_tbs = 0;
657 int bit_offset = 0;
658 int crci_bit_offset = (offset+1)<<3; /* Current offset + Quality estimate of 1 byte at the end*/
659 guint data_bits = 0;
660 guint8 crci_bit = 0;
661 proto_item *tree_ti = NULL;
662 proto_tree *data_tree = NULL;
663 gboolean dissected = FALSE;
665 if (tree) {
666 /* Add data subtree */
667 tree_ti = proto_tree_add_item(tree, hf_fp_data, tvb, offset, -1, ENC_NA);
668 proto_item_set_text(tree_ti, "TB data for %u chans", p_fp_info->num_chans);
669 data_tree = proto_item_add_subtree(tree_ti, ett_fp_data);
672 /* Calculate offset to CRCI bits */
674 if(p_fp_info->is_uplink){
675 for (chan=0; chan < p_fp_info->num_chans; chan++) {
676 int n;
677 for (n=0; n < p_fp_info->chan_num_tbs[chan]; n++) {
678 /* Advance bit offset */
679 crci_bit_offset += p_fp_info->chan_tf_size[chan];
680 /* Pad out to next byte */
681 if (crci_bit_offset % 8) {
682 crci_bit_offset += (8 - (crci_bit_offset % 8));
687 /* Now for the TB data */
688 for (chan=0; chan < p_fp_info->num_chans; chan++) {
689 int n;
690 p_fp_info->cur_chan = chan; /*Set current channel?*/
691 /* Clearly show channels with no TBs */
692 if (p_fp_info->chan_num_tbs[chan] == 0) {
693 proto_item *no_tb_ti = proto_tree_add_uint(data_tree, hf_fp_chan_zero_tbs, tvb,
694 offset+(bit_offset/8),
695 0, chan+1);
696 proto_item_append_text(no_tb_ti, " (of size %d)",
697 p_fp_info->chan_tf_size[chan]);
698 PROTO_ITEM_SET_GENERATED(no_tb_ti);
701 /* Show TBs from non-empty channels */
702 pinfo->fd->subnum = chan; /* set subframe number to current TB */
703 for (n=0; n < p_fp_info->chan_num_tbs[chan]; n++) {
705 proto_item *ti;
706 p_fp_info->cur_tb = chan; /*Set current transport block?*/
707 if (data_tree) {
708 ti = proto_tree_add_item(data_tree, hf_fp_tb, tvb,
709 offset + (bit_offset/8),
710 ((bit_offset % 8) + p_fp_info->chan_tf_size[chan] + 7) / 8,
711 ENC_NA);
712 proto_item_set_text(ti, "TB (chan %u, tb %u, %u bits)",
713 chan+1, n+1, p_fp_info->chan_tf_size[chan]);
716 if (preferences_call_mac_dissectors /*&& !rlc_is_ciphered(pinfo)*/ && data_handle &&
717 (p_fp_info->chan_tf_size[chan] > 0)) {
718 tvbuff_t *next_tvb;
719 proto_item *item;
720 /* If this is DL we should not care about crci bits (since they dont exists)*/
721 if(p_fp_info->is_uplink){
724 if( p_fp_info->channel == CHANNEL_RACH_FDD){ /*In RACH we don't have any QE field, hence go back 8 bits.*/
725 crci_bit = tvb_get_bits8(tvb,crci_bit_offset+n-8,1);
726 item = proto_tree_add_item(data_tree, hf_fp_crci[n%8], tvb, (crci_bit_offset+n-8)/8, 1, ENC_BIG_ENDIAN);
727 PROTO_ITEM_SET_GENERATED(item);
728 }else{
729 crci_bit = tvb_get_bits8(tvb,crci_bit_offset+n,1);
730 item = proto_tree_add_item(data_tree, hf_fp_crci[n%8], tvb, (crci_bit_offset+n)/8, 1, ENC_BIG_ENDIAN);
731 PROTO_ITEM_SET_GENERATED(item);
735 if(crci_bit == 0 || !p_fp_info->is_uplink) {
736 next_tvb = tvb_new_subset(tvb, offset + bit_offset/8,
737 ((bit_offset % 8) + p_fp_info->chan_tf_size[chan] + 7) / 8, -1);
740 /****************/
741 /* TODO: maybe this decision can be based only on info available in fp_info */
742 call_dissector(*data_handle, next_tvb, pinfo, top_level_tree);
743 dissected = TRUE;
744 } else {
745 proto_tree_add_expert(tree, pinfo, &ei_fp_crci_no_subdissector, tvb, offset + bit_offset/8,
746 ((bit_offset % 8) + p_fp_info->chan_tf_size[chan] + 7) / 8);
750 num_tbs++;
752 /* Advance bit offset */
753 bit_offset += p_fp_info->chan_tf_size[chan];
754 data_bits += p_fp_info->chan_tf_size[chan];
756 /* Pad out to next byte */
757 if (bit_offset % 8) {
758 bit_offset += (8 - (bit_offset % 8));
763 if (dissected == FALSE) {
764 col_append_fstr(pinfo->cinfo, COL_INFO, "(%u bits in %u tbs)",
765 data_bits, num_tbs);
768 /* Data tree should cover entire length */
769 if (data_tree) {
770 proto_item_set_len(tree_ti, bit_offset/8);
771 proto_item_append_text(tree_ti, " (%u bits in %u tbs)", data_bits, num_tbs);
774 /* Move offset past TBs (we know it's already padded out to next byte) */
775 offset += (bit_offset / 8);
777 return offset;
781 /* Dissect the MAC-d PDUs of an HS-DSCH (type 1) frame.
782 Length is in bits, and payload is offset by 4 bits of padding */
783 static int
784 dissect_macd_pdu_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
785 int offset, guint16 length, guint16 number_of_pdus, struct fp_info *p_fp_info)
787 int pdu;
788 int bit_offset = 0;
789 proto_item *pdus_ti = NULL;
790 proto_tree *data_tree = NULL;
791 gboolean dissected = FALSE;
793 /* Add data subtree */
794 if (tree) {
795 pdus_ti = proto_tree_add_item(tree, hf_fp_data, tvb, offset, -1, ENC_NA);
796 proto_item_set_text(pdus_ti, "%u MAC-d PDUs of %u bits", number_of_pdus, length);
797 data_tree = proto_item_add_subtree(pdus_ti, ett_fp_data);
800 /* Now for the PDUs */
801 for (pdu=0; pdu < number_of_pdus; pdu++) {
802 proto_item *pdu_ti;
804 if (data_tree) {
805 /* Show 4 bits padding at start of PDU */
806 proto_tree_add_item(data_tree, hf_fp_hsdsch_data_padding, tvb, offset+(bit_offset/8), 1, ENC_BIG_ENDIAN);
809 bit_offset += 4;
811 /* Data bytes! */
812 if (data_tree) {
813 pinfo->fd->subnum = pdu; /* set subframe number to current TB */
814 p_fp_info->cur_tb = pdu; /*Set TB (PDU) index correctly*/
815 pdu_ti = proto_tree_add_item(data_tree, hf_fp_mac_d_pdu, tvb,
816 offset + (bit_offset/8),
817 ((bit_offset % 8) + length + 7) / 8,
818 ENC_NA);
819 proto_item_set_text(pdu_ti, "MAC-d PDU (PDU %u)", pdu+1);
821 if (preferences_call_mac_dissectors /*&& !rlc_is_ciphered(pinfo)*/) {
822 tvbuff_t *next_tvb;
823 next_tvb = tvb_new_subset(tvb, offset + bit_offset/8,
824 ((bit_offset % 8) + length + 7)/8, -1);
825 call_dissector(mac_fdd_hsdsch_handle, next_tvb, pinfo, top_level_tree);
826 dissected = TRUE;
829 /* Advance bit offset */
830 bit_offset += length;
832 /* Pad out to next byte */
833 if (bit_offset % 8) {
834 bit_offset += (8 - (bit_offset % 8));
838 /* Data tree should cover entire length */
839 proto_item_set_len(pdus_ti, bit_offset/8);
841 /* Move offset past PDUs (we know it's already padded out to next byte) */
842 offset += (bit_offset / 8);
844 /* Show summary in info column */
845 if (dissected == FALSE) {
846 col_append_fstr(pinfo->cinfo, COL_INFO, " %u PDUs of %u bits",
847 number_of_pdus, length);
850 return offset;
854 /* Dissect the MAC-d PDUs of an HS-DSCH (type 2) frame.
855 Length is in bytes, and payload is byte-aligned (no padding) */
856 static int
857 dissect_macd_pdu_data_type_2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
858 int offset, guint16 length, guint16 number_of_pdus,struct fp_info * fpi)
860 int pdu;
861 proto_item *pdus_ti = NULL;
862 proto_tree *data_tree = NULL;
863 int first_offset = offset;
864 gboolean dissected = FALSE;
866 /* Add data subtree */
867 if (tree) {
868 pdus_ti = proto_tree_add_item(tree, hf_fp_data, tvb, offset, -1, ENC_NA);
869 proto_item_set_text(pdus_ti, "%u MAC-d PDUs of %u bytes", number_of_pdus, length);
870 data_tree = proto_item_add_subtree(pdus_ti, ett_fp_data);
873 /* Now for the PDUs */
874 for (pdu=0; pdu < number_of_pdus; pdu++) {
875 proto_item *pdu_ti;
877 /* Data bytes! */
878 if (data_tree) {
879 pdu_ti = proto_tree_add_item(data_tree, hf_fp_mac_d_pdu, tvb,
880 offset, length, ENC_NA);
881 proto_item_set_text(pdu_ti, "MAC-d PDU (PDU %u)", pdu+1);
885 if (preferences_call_mac_dissectors /*&& !rlc_is_ciphered(pinfo)*/) {
887 tvbuff_t *next_tvb = tvb_new_subset(tvb, offset, length, -1);
890 fpi->cur_tb = pdu; /*Set proper pdu index for MAC and higher layers*/
891 call_dissector(mac_fdd_hsdsch_handle, next_tvb, pinfo, top_level_tree);
892 dissected = TRUE;
895 /* Advance offset */
896 offset += length;
899 /* Data tree should cover entire length */
900 proto_item_set_len(pdus_ti, offset-first_offset);
902 /* Show summary in info column */
903 if (!dissected) {
904 col_append_fstr(pinfo->cinfo, COL_INFO, " %u PDUs of %u bits",
905 number_of_pdus, length*8);
908 return offset;
911 /* Dissect CRCI bits (uplink) */
912 static int
913 dissect_crci_bits(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
914 fp_info *p_fp_info, int offset)
916 int n, num_tbs;
917 proto_item *ti = NULL;
918 proto_tree *crcis_tree = NULL;
919 guint errors = 0;
921 num_tbs = get_tb_count(p_fp_info);
924 /* Add CRCIs subtree */
925 if (tree) {
926 ti = proto_tree_add_item(tree, hf_fp_crcis, tvb, offset, (num_tbs+7)/8, ENC_NA);
927 proto_item_set_text(ti, "CRCI bits for %u tbs", num_tbs);
928 crcis_tree = proto_item_add_subtree(ti, ett_fp_crcis);
931 /* CRCIs */
932 for (n=0; n < num_tbs; n++) {
933 int bit = (tvb_get_guint8(tvb, offset+(n/8)) >> (7-(n%8))) & 0x01;
934 proto_tree_add_item(crcis_tree, hf_fp_crci[n%8], tvb, offset+(n/8),
935 1, ENC_BIG_ENDIAN);
937 if (bit == 1) {
938 errors++;
939 expert_add_info(pinfo, ti, &ei_fp_crci_error_bit_set_for_tb);
943 if (tree) {
944 /* Highlight range of bytes covered by indicator bits */
945 proto_item_set_len(ti, (num_tbs+7) / 8);
947 /* Show error count in root text */
948 proto_item_append_text(ti, " (%u errors)", errors);
951 offset += ((num_tbs+7) / 8);
952 return offset;
956 static void
957 dissect_spare_extension_and_crc(tvbuff_t *tvb, packet_info *pinfo,
958 proto_tree *tree, guint8 dch_crc_present,
959 int offset,guint header_length)
961 int crc_size = 0;
962 int remain = tvb_length_remaining(tvb, offset);
964 /* Payload CRC (optional) */
965 if ((dch_crc_present == 1) || ((dch_crc_present == 2) && (remain >= 2))) {
966 crc_size = 2;
969 if (remain > crc_size) {
970 proto_item *ti;
971 ti = proto_tree_add_item(tree, hf_fp_spare_extension, tvb,
972 offset, remain-crc_size, ENC_NA);
973 proto_item_append_text(ti, " (%u octets)", remain-crc_size);
974 expert_add_info_format(pinfo, ti, &ei_fp_spare_extension, "Spare Extension present (%u bytes)", remain-crc_size);
975 offset += remain-crc_size;
978 if (crc_size) {
979 proto_item * pi = proto_tree_add_item(tree, hf_fp_payload_crc, tvb, offset, crc_size,
980 ENC_BIG_ENDIAN);
981 if (preferences_payload_checksum) {
982 guint16 calc_crc, read_crc;
983 guint8 * data = tvb_get_string(wmem_packet_scope(), tvb, header_length, offset-header_length);
984 calc_crc = crc16_8005_noreflect_noxor(data, offset-header_length);
985 read_crc = tvb_get_bits16(tvb, offset*8, 16, FALSE);
987 if (calc_crc == read_crc) {
988 proto_item_append_text(pi, " [correct]");
989 } else {
990 proto_item_append_text(pi, " [incorrect, should be 0x%x]", calc_crc);
991 expert_add_info(pinfo, pi, &ei_fp_bad_payload_checksum);
997 /***********************************************************/
998 /* Common control message types */
1000 static int
1001 dissect_common_outer_loop_power_control(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb,
1002 int offset, struct fp_info *p_fp_info _U_)
1004 return dissect_dch_outer_loop_power_control(tree, pinfo, tvb, offset);
1008 static int
1009 dissect_common_timing_adjustment(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb,
1010 int offset, struct fp_info *p_fp_info)
1012 if (p_fp_info->channel != CHANNEL_PCH) {
1013 guint8 cfn;
1014 gint16 toa;
1016 /* CFN control */
1017 cfn = tvb_get_guint8(tvb, offset);
1018 proto_tree_add_item(tree, hf_fp_cfn_control, tvb, offset, 1, ENC_BIG_ENDIAN);
1019 offset++;
1021 /* ToA */
1022 toa = tvb_get_ntohs(tvb, offset);
1023 proto_tree_add_item(tree, hf_fp_toa, tvb, offset, 2, ENC_BIG_ENDIAN);
1024 offset += 2;
1026 col_append_fstr(pinfo->cinfo, COL_INFO, " CFN=%u, ToA=%d", cfn, toa);
1028 else {
1029 guint16 cfn;
1030 gint32 toa;
1032 /* PCH CFN is 12 bits */
1033 cfn = (tvb_get_ntohs(tvb, offset) >> 4);
1034 proto_tree_add_item(tree, hf_fp_pch_cfn, tvb, offset, 2, ENC_BIG_ENDIAN);
1035 offset += 2;
1037 /* 4 bits of padding follow... */
1039 /* 20 bits of ToA (followed by 4 padding bits) */
1040 toa = ((int)(tvb_get_ntoh24(tvb, offset) << 8)) / 4096;
1041 proto_tree_add_int(tree, hf_fp_pch_toa, tvb, offset, 3, toa);
1042 offset += 3;
1044 col_append_fstr(pinfo->cinfo, COL_INFO, " CFN=%u, ToA=%d", cfn, toa);
1046 return offset;
1049 static int
1050 dissect_common_dl_node_synchronisation(packet_info *pinfo, proto_tree *tree,
1051 tvbuff_t *tvb, int offset)
1053 /* T1 (3 bytes) */
1054 guint32 t1 = tvb_get_ntoh24(tvb, offset);
1055 proto_tree_add_item(tree, hf_fp_t1, tvb, offset, 3, ENC_BIG_ENDIAN);
1056 offset += 3;
1058 col_append_fstr(pinfo->cinfo, COL_INFO, " T1=%u", t1);
1060 return offset;
1063 static int
1064 dissect_common_ul_node_synchronisation(packet_info *pinfo, proto_tree *tree,
1065 tvbuff_t *tvb, int offset)
1067 guint32 t1, t2, t3;
1069 /* T1 (3 bytes) */
1070 t1 = tvb_get_ntoh24(tvb, offset);
1071 proto_tree_add_item(tree, hf_fp_t1, tvb, offset, 3, ENC_BIG_ENDIAN);
1072 offset += 3;
1074 /* T2 (3 bytes) */
1075 t2 = tvb_get_ntoh24(tvb, offset);
1076 proto_tree_add_item(tree, hf_fp_t2, tvb, offset, 3, ENC_BIG_ENDIAN);
1077 offset += 3;
1079 /* T3 (3 bytes) */
1080 t3 = tvb_get_ntoh24(tvb, offset);
1081 proto_tree_add_item(tree, hf_fp_t3, tvb, offset, 3, ENC_BIG_ENDIAN);
1082 offset += 3;
1084 col_append_fstr(pinfo->cinfo, COL_INFO, " T1=%u T2=%u, T3=%u",
1085 t1, t2, t3);
1087 return offset;
1090 static int
1091 dissect_common_dl_synchronisation(packet_info *pinfo, proto_tree *tree,
1092 tvbuff_t *tvb, int offset, struct fp_info *p_fp_info)
1094 guint16 cfn;
1096 if (p_fp_info->channel != CHANNEL_PCH) {
1097 /* CFN control */
1098 cfn = tvb_get_guint8(tvb, offset);
1099 proto_tree_add_item(tree, hf_fp_cfn_control, tvb, offset, 1, ENC_BIG_ENDIAN);
1100 offset++;
1102 else {
1103 /* PCH CFN is 12 bits */
1104 cfn = (tvb_get_ntohs(tvb, offset) >> 4);
1105 proto_tree_add_item(tree, hf_fp_pch_cfn, tvb, offset, 2, ENC_BIG_ENDIAN);
1107 /* 4 bits of padding follow... */
1108 offset += 2;
1111 col_append_fstr(pinfo->cinfo, COL_INFO, " CFN=%u", cfn);
1113 return offset;
1116 static int
1117 dissect_common_ul_synchronisation(packet_info *pinfo, proto_tree *tree,
1118 tvbuff_t *tvb, int offset, struct fp_info *p_fp_info)
1120 return dissect_common_timing_adjustment(pinfo, tree, tvb, offset, p_fp_info);
1123 static int
1124 dissect_common_timing_advance(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
1126 guint8 cfn;
1127 guint16 timing_advance;
1129 /* CFN control */
1130 cfn = tvb_get_guint8(tvb, offset);
1131 proto_tree_add_item(tree, hf_fp_cfn_control, tvb, offset, 1, ENC_BIG_ENDIAN);
1132 offset++;
1134 /* Timing Advance */
1135 timing_advance = (tvb_get_guint8(tvb, offset) & 0x3f) * 4;
1136 proto_tree_add_uint(tree, hf_fp_timing_advance, tvb, offset, 1, timing_advance);
1137 offset++;
1139 col_append_fstr(pinfo->cinfo, COL_INFO, " CFN = %u, TA = %u",
1140 cfn, timing_advance);
1142 return offset;
1145 static int
1146 dissect_hsdpa_capacity_request(packet_info *pinfo, proto_tree *tree,
1147 tvbuff_t *tvb, int offset)
1149 guint8 priority;
1150 guint16 user_buffer_size;
1152 /* CmCH-PI */
1153 priority = (tvb_get_guint8(tvb, offset) & 0x0f);
1154 proto_tree_add_item(tree, hf_fp_cmch_pi, tvb, offset, 1, ENC_BIG_ENDIAN);
1155 offset++;
1157 /* User buffer size */
1158 user_buffer_size = tvb_get_ntohs(tvb, offset);
1159 proto_tree_add_item(tree, hf_fp_user_buffer_size, tvb, offset, 2, ENC_BIG_ENDIAN);
1160 offset += 2;
1162 col_append_fstr(pinfo->cinfo, COL_INFO, " CmCH-PI=%u User-Buffer-Size=%u",
1163 priority, user_buffer_size);
1165 return offset;
1168 static int
1169 dissect_hsdpa_capacity_allocation(packet_info *pinfo, proto_tree *tree,
1170 tvbuff_t *tvb, int offset,
1171 struct fp_info *p_fp_info)
1173 proto_item *ti;
1174 proto_item *rate_ti;
1175 guint16 max_pdu_length;
1176 guint8 repetition_period;
1177 guint8 interval;
1178 guint64 credits;
1180 /* Congestion status (introduced sometime during R6...) */
1181 if ((p_fp_info->release == 6) || (p_fp_info->release == 7)) {
1182 proto_tree_add_bits_item(tree, hf_fp_congestion_status, tvb,
1183 offset*8 + 2, 2, ENC_BIG_ENDIAN);
1186 /* CmCH-PI */
1187 proto_tree_add_item(tree, hf_fp_cmch_pi, tvb, offset, 1, ENC_BIG_ENDIAN);
1188 offset++;
1190 /* Max MAC-d PDU length (13 bits) */
1191 max_pdu_length = tvb_get_ntohs(tvb, offset) >> 3;
1192 proto_tree_add_item(tree, hf_fp_hsdsch_max_macd_pdu_len, tvb, offset, 2, ENC_BIG_ENDIAN);
1193 offset++;
1195 /* HS-DSCH credits (11 bits) */
1196 ti = proto_tree_add_bits_ret_val(tree, hf_fp_hsdsch_credits, tvb,
1197 offset*8 + 5, 11, &credits, ENC_BIG_ENDIAN);
1198 offset += 2;
1200 /* Interesting values */
1201 if (credits == 0) {
1202 proto_item_append_text(ti, " (stop transmission)");
1203 expert_add_info(pinfo, ti, &ei_fp_stop_hsdpa_transmission);
1205 if (credits == 2047) {
1206 proto_item_append_text(ti, " (unlimited)");
1209 /* HS-DSCH Interval */
1210 interval = tvb_get_guint8(tvb, offset);
1211 ti = proto_tree_add_uint(tree, hf_fp_hsdsch_interval, tvb, offset, 1, interval*10);
1212 offset++;
1213 if (interval == 0) {
1214 proto_item_append_text(ti, " (none of the credits shall be used)");
1217 /* HS-DSCH Repetition period */
1218 repetition_period = tvb_get_guint8(tvb, offset);
1219 ti = proto_tree_add_item(tree, hf_fp_hsdsch_repetition_period, tvb, offset, 1, ENC_BIG_ENDIAN);
1220 offset++;
1221 if (repetition_period == 0) {
1222 proto_item_append_text(ti, " (unlimited repetition period)");
1225 /* Calculated and show effective rate enabled */
1226 if (credits == 2047) {
1227 rate_ti = proto_tree_add_item(tree, hf_fp_hsdsch_unlimited_rate, tvb, 0, 0, ENC_NA);
1228 PROTO_ITEM_SET_GENERATED(rate_ti);
1230 else {
1231 if (interval != 0) {
1232 /* Cast on credits is safe, since we know it won't exceed 10^11 */
1233 rate_ti = proto_tree_add_uint(tree, hf_fp_hsdsch_calculated_rate, tvb, 0, 0,
1234 (guint16)credits * max_pdu_length * (1000 / (interval*10)));
1235 PROTO_ITEM_SET_GENERATED(rate_ti);
1239 col_append_fstr(pinfo->cinfo, COL_INFO,
1240 " Max-PDU-len=%u Credits=%u Interval=%u Rep-Period=%u",
1241 max_pdu_length, (guint16)credits, interval, repetition_period);
1243 return offset;
1246 static int
1247 dissect_hsdpa_capacity_allocation_type_2(packet_info *pinfo, proto_tree *tree,
1248 tvbuff_t *tvb, int offset)
1250 proto_item *ti;
1251 proto_item *rate_ti;
1252 guint16 max_pdu_length;
1253 guint8 repetition_period;
1254 guint8 interval;
1255 guint16 credits;
1257 /* Congestion status */
1258 proto_tree_add_bits_item(tree, hf_fp_congestion_status, tvb,
1259 offset*8 + 2, 2, ENC_BIG_ENDIAN);
1261 /* CmCH-PI */
1262 proto_tree_add_item(tree, hf_fp_cmch_pi, tvb, offset, 1, ENC_BIG_ENDIAN);
1263 offset++;
1265 /* 5 spare bits follow here */
1267 /* Max MAC-d/c PDU length (11 bits) */
1268 max_pdu_length = tvb_get_ntohs(tvb, offset) & 0x7ff;
1269 proto_tree_add_item(tree, hf_fp_hsdsch_max_macdc_pdu_len, tvb, offset, 2, ENC_BIG_ENDIAN);
1270 offset += 2;
1272 /* HS-DSCH credits (16 bits) */
1273 credits = (tvb_get_ntohs(tvb, offset));
1274 ti = proto_tree_add_uint(tree, hf_fp_hsdsch_credits, tvb,
1275 offset, 2, credits);
1276 offset += 2;
1278 /* Interesting values */
1279 if (credits == 0) {
1280 proto_item_append_text(ti, " (stop transmission)");
1281 expert_add_info(pinfo, ti, &ei_fp_stop_hsdpa_transmission);
1283 if (credits == 65535) {
1284 proto_item_append_text(ti, " (unlimited)");
1287 /* HS-DSCH Interval */
1288 interval = tvb_get_guint8(tvb, offset);
1289 ti = proto_tree_add_uint(tree, hf_fp_hsdsch_interval, tvb, offset, 1, interval*10);
1290 offset++;
1291 if (interval == 0) {
1292 proto_item_append_text(ti, " (none of the credits shall be used)");
1295 /* HS-DSCH Repetition period */
1296 repetition_period = tvb_get_guint8(tvb, offset);
1297 ti = proto_tree_add_item(tree, hf_fp_hsdsch_repetition_period, tvb, offset, 1, ENC_BIG_ENDIAN);
1298 offset++;
1299 if (repetition_period == 0) {
1300 proto_item_append_text(ti, " (unlimited repetition period)");
1303 /* Calculated and show effective rate enabled */
1304 if (credits == 65535) {
1305 rate_ti = proto_tree_add_item(tree, hf_fp_hsdsch_unlimited_rate, tvb, 0, 0, ENC_NA);
1306 PROTO_ITEM_SET_GENERATED(rate_ti);
1308 else {
1309 if (interval != 0) {
1310 rate_ti = proto_tree_add_uint(tree, hf_fp_hsdsch_calculated_rate, tvb, 0, 0,
1311 credits * max_pdu_length * (1000 / (interval*10)));
1312 PROTO_ITEM_SET_GENERATED(rate_ti);
1316 col_append_fstr(pinfo->cinfo, COL_INFO,
1317 " Max-PDU-len=%u Credits=%u Interval=%u Rep-Period=%u",
1318 max_pdu_length, credits, interval, repetition_period);
1320 return offset;
1325 static int
1326 dissect_common_dynamic_pusch_assignment(packet_info *pinfo, proto_tree *tree,
1327 tvbuff_t *tvb, int offset)
1329 guint8 pusch_set_id;
1330 guint8 activation_cfn;
1331 guint8 duration;
1333 /* PUSCH Set Id */
1334 pusch_set_id = tvb_get_guint8(tvb, offset);
1335 proto_tree_add_item(tree, hf_fp_pusch_set_id, tvb, offset, 1, ENC_BIG_ENDIAN);
1336 offset++;
1338 /* Activation CFN */
1339 activation_cfn = tvb_get_guint8(tvb, offset);
1340 proto_tree_add_item(tree, hf_fp_activation_cfn, tvb, offset, 1, ENC_BIG_ENDIAN);
1341 offset++;
1343 /* Duration */
1344 duration = tvb_get_guint8(tvb, offset) * 10;
1345 proto_tree_add_uint(tree, hf_fp_duration, tvb, offset, 1, duration);
1346 offset++;
1348 col_append_fstr(pinfo->cinfo, COL_INFO,
1349 " PUSCH Set Id=%u Activation CFN=%u Duration=%u",
1350 pusch_set_id, activation_cfn, duration);
1352 return offset;
1359 /* Dissect the control part of a common channel message */
1360 static void
1361 dissect_common_control(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1362 int offset, struct fp_info *p_fp_info)
1364 /* Common control frame type */
1365 guint8 control_frame_type = tvb_get_guint8(tvb, offset);
1366 proto_tree_add_item(tree, hf_fp_common_control_frame_type, tvb, offset, 1, ENC_BIG_ENDIAN);
1367 offset++;
1369 col_append_str(pinfo->cinfo, COL_INFO,
1370 val_to_str_const(control_frame_type, common_control_frame_type_vals, "Unknown"));
1372 /* Frame-type specific dissection */
1373 switch (control_frame_type) {
1374 case COMMON_OUTER_LOOP_POWER_CONTROL:
1375 /*offset =*/ dissect_common_outer_loop_power_control(pinfo, tree, tvb, offset, p_fp_info);
1376 break;
1377 case COMMON_TIMING_ADJUSTMENT:
1378 /*offset =*/ dissect_common_timing_adjustment(pinfo, tree, tvb, offset, p_fp_info);
1379 break;
1380 case COMMON_DL_SYNCHRONISATION:
1381 /*offset =*/ dissect_common_dl_synchronisation(pinfo, tree, tvb, offset, p_fp_info);
1382 break;
1383 case COMMON_UL_SYNCHRONISATION:
1384 /*offset =*/ dissect_common_ul_synchronisation(pinfo, tree, tvb, offset, p_fp_info);
1385 break;
1386 case COMMON_DL_NODE_SYNCHRONISATION:
1387 /*offset =*/ dissect_common_dl_node_synchronisation(pinfo, tree, tvb, offset);
1388 break;
1389 case COMMON_UL_NODE_SYNCHRONISATION:
1390 /*offset =*/ dissect_common_ul_node_synchronisation(pinfo, tree, tvb, offset);
1391 break;
1392 case COMMON_DYNAMIC_PUSCH_ASSIGNMENT:
1393 /*offset =*/ dissect_common_dynamic_pusch_assignment(pinfo, tree, tvb, offset);
1394 break;
1395 case COMMON_TIMING_ADVANCE:
1396 /*offset =*/ dissect_common_timing_advance(pinfo, tree, tvb, offset);
1397 break;
1398 case COMMON_HS_DSCH_Capacity_Request:
1399 /*offset =*/ dissect_hsdpa_capacity_request(pinfo, tree, tvb, offset);
1400 break;
1401 case COMMON_HS_DSCH_Capacity_Allocation:
1402 /*offset =*/ dissect_hsdpa_capacity_allocation(pinfo, tree, tvb, offset, p_fp_info);
1403 break;
1404 case COMMON_HS_DSCH_Capacity_Allocation_Type_2:
1405 /*offset =*/ dissect_hsdpa_capacity_allocation_type_2(pinfo, tree, tvb, offset);
1406 break;
1408 default:
1409 break;
1412 /* There is no Spare Extension nor payload crc in common control!? */
1413 /* dissect_spare_extension_and_crc(tvb, pinfo, tree, 0, offset);
1419 /**************************/
1420 /* Dissect a RACH channel */
1421 static void
1422 dissect_rach_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1423 int offset, struct fp_info *p_fp_info)
1425 gboolean is_control_frame;
1426 guint16 header_crc = 0;
1427 proto_item * header_crc_pi = NULL;
1428 guint header_length = 0;
1430 /* Header CRC */
1431 header_crc = tvb_get_bits8(tvb, 0, 7);
1432 header_crc_pi = proto_tree_add_item(tree, hf_fp_header_crc, tvb, offset, 1, ENC_BIG_ENDIAN);
1434 /* Frame Type */
1435 is_control_frame = tvb_get_guint8(tvb, offset) & 0x01;
1436 proto_tree_add_item(tree, hf_fp_ft, tvb, offset, 1, ENC_BIG_ENDIAN);
1437 offset++;
1439 col_append_str(pinfo->cinfo, COL_INFO, is_control_frame ? " [Control] " : " [Data] ");
1441 if (is_control_frame) {
1442 dissect_common_control(tvb, pinfo, tree, offset, p_fp_info);
1443 /* For control frame the header CRC is actually frame CRC covering all
1444 * bytes except the first */
1445 if (preferences_header_checksum) {
1446 verify_control_frame_crc(tvb, pinfo, header_crc_pi, header_crc);
1449 else {
1450 guint8 cfn;
1451 guint32 propagation_delay = 0;
1452 proto_item *propagation_delay_ti = NULL;
1453 guint32 received_sync_ul_timing_deviation = 0;
1454 proto_item *received_sync_ul_timing_deviation_ti = NULL;
1455 proto_item *rx_timing_deviation_ti = NULL;
1456 guint16 rx_timing_deviation = 0;
1458 /* DATA */
1460 /* CFN */
1461 cfn = tvb_get_guint8(tvb, offset);
1462 proto_tree_add_item(tree, hf_fp_cfn, tvb, offset, 1, ENC_BIG_ENDIAN);
1463 offset++;
1465 col_append_fstr(pinfo->cinfo, COL_INFO, "CFN=%03u ", cfn);
1467 /* TFI */
1468 proto_tree_add_item(tree, hf_fp_tfi, tvb, offset, 1, ENC_BIG_ENDIAN);
1469 offset++;
1471 if (p_fp_info->channel == CHANNEL_RACH_FDD) {
1472 /* Propagation delay */
1473 propagation_delay = tvb_get_guint8(tvb, offset);
1474 propagation_delay_ti = proto_tree_add_uint(tree, hf_fp_propagation_delay, tvb, offset, 1,
1475 propagation_delay*3);
1476 offset++;
1479 /* Should be TDD 3.84 or 7.68 */
1480 if (p_fp_info->channel == CHANNEL_RACH_TDD) {
1481 /* Rx Timing Deviation */
1482 rx_timing_deviation = tvb_get_guint8(tvb, offset);
1483 rx_timing_deviation_ti = proto_tree_add_item(tree, hf_fp_rx_timing_deviation, tvb, offset, 1, ENC_BIG_ENDIAN);
1484 offset++;
1487 if (p_fp_info->channel == CHANNEL_RACH_TDD_128) {
1488 /* Received SYNC UL Timing Deviation */
1489 received_sync_ul_timing_deviation = tvb_get_guint8(tvb, offset);
1490 received_sync_ul_timing_deviation_ti =
1491 proto_tree_add_item(tree, hf_fp_received_sync_ul_timing_deviation, tvb, offset, 1, ENC_BIG_ENDIAN);
1492 offset++;
1495 header_length = offset;
1497 /* TB data */
1498 offset = dissect_tb_data(tvb, pinfo, tree, offset, p_fp_info, &mac_fdd_rach_handle);
1500 /* CRCIs */
1501 offset = dissect_crci_bits(tvb, pinfo, tree, p_fp_info, offset);
1503 /* Info introduced in R6 */
1504 /* only check if it looks as if they are present */
1505 if (((p_fp_info->release == 6) || (p_fp_info->release == 7)) &&
1506 (tvb_length_remaining(tvb, offset) > 2))
1508 int n;
1509 guint8 flags;
1510 /* guint8 flag_bytes = 0; */
1512 gboolean cell_portion_id_present = FALSE;
1513 gboolean ext_propagation_delay_present = FALSE;
1514 gboolean angle_of_arrival_present = FALSE;
1515 gboolean ext_rx_sync_ul_timing_deviation_present = FALSE;
1516 gboolean ext_rx_timing_deviation_present = FALSE;
1518 /* New IE flags (assume mandatory for now) */
1519 do {
1520 proto_item *new_ie_flags_ti;
1521 proto_tree *new_ie_flags_tree;
1522 guint ies_found = 0;
1524 /* Add new IE flags subtree */
1525 new_ie_flags_ti = proto_tree_add_string_format(tree, hf_fp_rach_new_ie_flags, tvb, offset, 1,
1526 "", "New IE flags");
1527 new_ie_flags_tree = proto_item_add_subtree(new_ie_flags_ti, ett_fp_rach_new_ie_flags);
1529 /* Read next byte */
1530 flags = tvb_get_guint8(tvb, offset);
1531 /* flag_bytes++ */
1533 /* Dissect individual bits */
1534 for (n=0; n < 8; n++) {
1535 switch (n) {
1536 case 6:
1537 switch (p_fp_info->division) {
1538 case Division_FDD:
1539 /* Ext propagation delay */
1540 ext_propagation_delay_present = TRUE;
1541 proto_tree_add_item(new_ie_flags_tree, hf_fp_rach_ext_propagation_delay_present,
1542 tvb, offset, 1, ENC_BIG_ENDIAN);
1543 break;
1544 case Division_TDD_128:
1545 /* Ext Rx Sync UL Timing */
1546 ext_rx_sync_ul_timing_deviation_present = TRUE;
1547 proto_tree_add_item(new_ie_flags_tree, hf_fp_rach_ext_rx_sync_ul_timing_deviation_present,
1548 tvb, offset, 1, ENC_BIG_ENDIAN);
1550 break;
1551 default:
1552 /* Not defined */
1553 proto_tree_add_item(new_ie_flags_tree, hf_fp_rach_new_ie_flag_unused[6],
1554 tvb, offset, 1, ENC_BIG_ENDIAN);
1555 break;
1557 break;
1558 case 7:
1559 switch (p_fp_info->division) {
1560 case Division_FDD:
1561 /* Cell Portion ID */
1562 cell_portion_id_present = TRUE;
1563 proto_tree_add_item(new_ie_flags_tree, hf_fp_rach_cell_portion_id_present,
1564 tvb, offset, 1, ENC_BIG_ENDIAN);
1565 break;
1566 case Division_TDD_128:
1567 /* AOA */
1568 angle_of_arrival_present = TRUE;
1569 proto_tree_add_item(new_ie_flags_tree, hf_fp_rach_angle_of_arrival_present,
1570 tvb, offset, 1, ENC_BIG_ENDIAN);
1571 break;
1572 case Division_TDD_384:
1573 case Division_TDD_768:
1574 /* Extended Rx Timing Deviation */
1575 ext_rx_timing_deviation_present = TRUE;
1576 proto_tree_add_item(new_ie_flags_tree, hf_fp_rach_ext_rx_timing_deviation_present,
1577 tvb, offset, 1, ENC_BIG_ENDIAN);
1578 break;
1580 break;
1582 default:
1583 /* No defined meanings */
1584 /* Visual Studio Code Analyzer wrongly thinks n can be 7 here. It can't */
1585 proto_tree_add_item(new_ie_flags_tree, hf_fp_rach_new_ie_flag_unused[n],
1586 tvb, offset, 1, ENC_BIG_ENDIAN);
1587 break;
1589 if ((flags >> (7-n)) & 0x01) {
1590 ies_found++;
1593 offset++;
1595 proto_item_append_text(new_ie_flags_ti, " (%u IEs found)", ies_found);
1597 /* Last bit set will indicate another flags byte follows... */
1598 } while (0); /*((flags & 0x01) && (flag_bytes < 31));*/
1600 /* Cell Portion ID */
1601 if (cell_portion_id_present) {
1602 proto_tree_add_item(tree, hf_fp_cell_portion_id, tvb, offset, 1, ENC_BIG_ENDIAN);
1603 offset++;
1606 /* Ext Rx Timing Deviation */
1607 if (ext_rx_timing_deviation_present) {
1608 guint8 extra_bits;
1609 guint bits_to_extend;
1610 switch (p_fp_info->division) {
1611 case Division_TDD_384:
1612 bits_to_extend = 1;
1613 break;
1614 case Division_TDD_768:
1615 bits_to_extend = 2;
1616 break;
1618 default:
1619 /* TODO: report unexpected division type */
1620 bits_to_extend = 1;
1621 break;
1623 extra_bits = tvb_get_guint8(tvb, offset) &
1624 ((bits_to_extend == 1) ? 0x01 : 0x03);
1625 rx_timing_deviation = (extra_bits << 8) | (rx_timing_deviation);
1626 proto_item_append_text(rx_timing_deviation_ti,
1627 " (extended to 0x%x)",
1628 rx_timing_deviation);
1629 proto_tree_add_bits_item(tree, hf_fp_extended_bits, tvb,
1630 offset*8 + (8-bits_to_extend), bits_to_extend, ENC_BIG_ENDIAN);
1631 offset++;
1634 /* Ext propagation delay. */
1635 if (ext_propagation_delay_present) {
1636 guint16 extra_bits = tvb_get_ntohs(tvb, offset) & 0x03ff;
1637 proto_tree_add_item(tree, hf_fp_ext_propagation_delay, tvb, offset, 2, ENC_BIG_ENDIAN);
1639 /* Adding 10 bits to original 8 */
1640 proto_item_append_text(propagation_delay_ti, " (extended to %u)",
1641 ((extra_bits << 8) | propagation_delay) * 3);
1642 offset += 2;
1645 /* Angle of Arrival (AOA) */
1646 if (angle_of_arrival_present) {
1647 proto_tree_add_item(tree, hf_fp_angle_of_arrival, tvb, offset, 2, ENC_BIG_ENDIAN);
1648 offset += 2;
1651 /* Ext. Rx Sync UL Timing Deviation */
1652 if (ext_rx_sync_ul_timing_deviation_present) {
1653 guint16 extra_bits;
1655 /* Ext received Sync UL Timing Deviation */
1656 extra_bits = tvb_get_ntohs(tvb, offset) & 0x1fff;
1657 proto_tree_add_item(tree, hf_fp_ext_received_sync_ul_timing_deviation, tvb, offset, 2, ENC_BIG_ENDIAN);
1659 /* Adding 13 bits to original 8 */
1660 proto_item_append_text(received_sync_ul_timing_deviation_ti, " (extended to %u)",
1661 (extra_bits << 8) | received_sync_ul_timing_deviation);
1662 offset += 2;
1665 if (preferences_header_checksum) {
1666 verify_header_crc(tvb, pinfo, header_crc_pi, header_crc, header_length);
1668 /* Spare Extension and Payload CRC */
1669 dissect_spare_extension_and_crc(tvb, pinfo, tree, 1, offset,header_length);
1674 /**************************/
1675 /* Dissect a FACH channel */
1676 static void
1677 dissect_fach_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1678 int offset, struct fp_info *p_fp_info)
1680 gboolean is_control_frame;
1681 guint16 header_crc = 0;
1682 proto_item * header_crc_pi = NULL;
1683 guint header_length = 0;
1685 /* Header CRC */
1686 header_crc = tvb_get_bits8(tvb, 0, 7);
1687 header_crc_pi = proto_tree_add_item(tree, hf_fp_header_crc, tvb, offset, 1, ENC_BIG_ENDIAN);
1689 /* Frame Type */
1690 is_control_frame = tvb_get_guint8(tvb, offset) & 0x01;
1691 proto_tree_add_item(tree, hf_fp_ft, tvb, offset, 1, ENC_BIG_ENDIAN);
1692 offset++;
1694 col_append_str(pinfo->cinfo, COL_INFO, is_control_frame ? " [Control] " : " [Data] ");
1696 if (is_control_frame) {
1697 dissect_common_control(tvb, pinfo, tree, offset, p_fp_info);
1698 /* For control frame the header CRC is actually frame CRC covering all
1699 * bytes except the first */
1700 if (preferences_header_checksum) {
1701 verify_control_frame_crc(tvb, pinfo, header_crc_pi, header_crc);
1704 else {
1705 guint8 cfn;
1706 /* DATA */
1708 /* CFN */
1709 cfn = tvb_get_guint8(tvb, offset);
1710 proto_tree_add_item(tree, hf_fp_cfn, tvb, offset, 1, ENC_BIG_ENDIAN);
1711 offset++;
1713 col_append_fstr(pinfo->cinfo, COL_INFO, "CFN=%03u ", cfn);
1715 /* TFI */
1716 proto_tree_add_item(tree, hf_fp_fach_tfi, tvb, offset, 1, ENC_BIG_ENDIAN);
1717 offset++;
1719 /* Transmit power level */
1720 proto_tree_add_float(tree, hf_fp_transmit_power_level, tvb, offset, 1,
1721 (float)(int)(tvb_get_guint8(tvb, offset)) / 10);
1722 offset++;
1723 header_length = offset;
1725 /* TB data */
1726 offset = dissect_tb_data(tvb, pinfo, tree, offset, p_fp_info, &mac_fdd_fach_handle);
1728 /* New IE flags (if it looks as though they are present) */
1729 if ((p_fp_info->release == 7) &&
1730 (tvb_length_remaining(tvb, offset) > 2)) {
1732 guint8 flags = tvb_get_guint8(tvb, offset);
1733 guint8 aoa_present = flags & 0x01;
1734 offset++;
1736 if (aoa_present) {
1737 proto_tree_add_item(tree, hf_fp_angle_of_arrival, tvb, offset, 2, ENC_BIG_ENDIAN);
1738 offset += 2;
1741 if (preferences_header_checksum) {
1742 verify_header_crc(tvb, pinfo, header_crc_pi, header_crc, header_length);
1744 /* Spare Extension and Payload CRC */
1745 dissect_spare_extension_and_crc(tvb, pinfo, tree, 1, offset, header_length);
1750 /**************************/
1751 /* Dissect a DSCH channel */
1752 static void
1753 dissect_dsch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1754 int offset, struct fp_info *p_fp_info)
1756 gboolean is_control_frame;
1758 /* Header CRC */
1759 proto_tree_add_item(tree, hf_fp_header_crc, tvb, offset, 1, ENC_BIG_ENDIAN);
1761 /* Frame Type */
1762 is_control_frame = tvb_get_guint8(tvb, offset) & 0x01;
1763 proto_tree_add_item(tree, hf_fp_ft, tvb, offset, 1, ENC_BIG_ENDIAN);
1764 offset++;
1766 col_append_str(pinfo->cinfo, COL_INFO, is_control_frame ? " [Control] " : " [Data] ");
1768 if (is_control_frame) {
1769 dissect_common_control(tvb, pinfo, tree, offset, p_fp_info);
1771 else {
1772 guint8 cfn;
1773 guint header_length = 0;
1775 /* DATA */
1777 /* CFN */
1778 cfn = tvb_get_guint8(tvb, offset);
1779 proto_tree_add_item(tree, hf_fp_cfn, tvb, offset, 1, ENC_BIG_ENDIAN);
1780 offset++;
1782 col_append_fstr(pinfo->cinfo, COL_INFO, "CFN=%03u ", cfn);
1784 /* TFI */
1785 proto_tree_add_item(tree, hf_fp_tfi, tvb, offset, 1, ENC_BIG_ENDIAN);
1786 offset++;
1789 /* Other fields depend upon release & FDD/TDD settings */
1790 if (((p_fp_info->release == 99) || (p_fp_info->release == 4)) &&
1791 (p_fp_info->channel == CHANNEL_DSCH_FDD)) {
1793 /* Power offset */
1794 proto_tree_add_float(tree, hf_fp_power_offset, tvb, offset, 1,
1795 (float)(-32.0) +
1796 ((float)(int)(tvb_get_guint8(tvb, offset)) * (float)(0.25)));
1797 offset++;
1799 /* Code number */
1800 proto_tree_add_item(tree, hf_fp_code_number, tvb, offset, 1, ENC_BIG_ENDIAN);
1801 offset++;
1803 /* Spreading Factor (3 bits) */
1804 proto_tree_add_item(tree, hf_fp_spreading_factor, tvb, offset, 1, ENC_BIG_ENDIAN);
1806 /* MC info (4 bits)*/
1807 proto_tree_add_item(tree, hf_fp_mc_info, tvb, offset, 1, ENC_BIG_ENDIAN);
1809 /* Last bit of this byte is spare */
1810 offset++;
1812 else {
1813 /* Normal case */
1815 /* PDSCH Set Id */
1816 proto_tree_add_item(tree, hf_fp_pdsch_set_id, tvb, offset, 1, ENC_BIG_ENDIAN);
1817 offset++;
1819 /* Transmit power level */
1820 proto_tree_add_float(tree, hf_fp_transmit_power_level, tvb, offset, 1,
1821 (float)(int)(tvb_get_guint8(tvb, offset)) / 10);
1822 offset++;
1824 header_length = offset;
1825 /* TB data */
1826 offset = dissect_tb_data(tvb, pinfo, tree, offset, p_fp_info, NULL);
1828 /* Spare Extension and Payload CRC */
1829 dissect_spare_extension_and_crc(tvb, pinfo, tree, 1, offset, header_length);
1834 /**************************/
1835 /* Dissect a USCH channel */
1836 static void
1837 dissect_usch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1838 int offset, struct fp_info *p_fp_info)
1840 gboolean is_control_frame;
1842 /* Header CRC */
1843 proto_tree_add_item(tree, hf_fp_header_crc, tvb, offset, 1, ENC_BIG_ENDIAN);
1845 /* Frame Type */
1846 is_control_frame = tvb_get_guint8(tvb, offset) & 0x01;
1847 proto_tree_add_item(tree, hf_fp_ft, tvb, offset, 1, ENC_BIG_ENDIAN);
1848 offset++;
1850 col_append_str(pinfo->cinfo, COL_INFO, is_control_frame ? " [Control] " : " [Data] ");
1852 if (is_control_frame) {
1853 dissect_common_control(tvb, pinfo, tree, offset, p_fp_info);
1855 else {
1856 guint cfn;
1857 guint16 rx_timing_deviation;
1858 proto_item *rx_timing_deviation_ti;
1859 guint header_length = 0;
1861 /* DATA */
1863 /* CFN */
1864 cfn = tvb_get_guint8(tvb, offset);
1865 proto_tree_add_item(tree, hf_fp_cfn, tvb, offset, 1, ENC_BIG_ENDIAN);
1866 offset++;
1868 col_append_fstr(pinfo->cinfo, COL_INFO, "CFN=%03u ", cfn);
1870 /* TFI */
1871 proto_tree_add_item(tree, hf_fp_usch_tfi, tvb, offset, 1, ENC_BIG_ENDIAN);
1872 offset++;
1874 /* Rx Timing Deviation */
1875 rx_timing_deviation = tvb_get_guint8(tvb, offset);
1876 rx_timing_deviation_ti = proto_tree_add_item(tree, hf_fp_rx_timing_deviation,
1877 tvb, offset, 1, ENC_BIG_ENDIAN);
1878 offset++;
1879 header_length = offset;
1880 /* TB data */
1881 offset = dissect_tb_data(tvb, pinfo, tree, offset, p_fp_info, NULL);
1883 /* QE */
1884 proto_tree_add_item(tree, hf_fp_quality_estimate, tvb, offset, 1, ENC_BIG_ENDIAN);
1885 offset++;
1887 /* CRCIs */
1888 offset = dissect_crci_bits(tvb, pinfo, tree, p_fp_info, offset);
1890 /* New IEs */
1891 if ((p_fp_info->release == 7) &&
1892 (tvb_length_remaining(tvb, offset) > 2)) {
1894 guint8 flags = tvb_get_guint8(tvb, offset);
1895 guint8 bits_extended = flags & 0x01;
1896 offset++;
1898 if (bits_extended) {
1899 guint8 extra_bits = tvb_get_guint8(tvb, offset) & 0x03;
1900 proto_item_append_text(rx_timing_deviation_ti,
1901 " (extended to %u)",
1902 (rx_timing_deviation << 2) | extra_bits);
1904 offset++;
1907 /* Spare Extension and Payload CRC */
1908 dissect_spare_extension_and_crc(tvb, pinfo, tree, 1, offset, header_length);
1914 /**************************/
1915 /* Dissect a PCH channel */
1916 static void
1917 dissect_pch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1918 int offset, struct fp_info *p_fp_info)
1920 gboolean is_control_frame;
1921 guint16 pch_cfn;
1922 gboolean paging_indication;
1923 guint16 header_crc = 0;
1924 proto_item * header_crc_pi = NULL;
1926 /* Header CRC */
1927 header_crc = tvb_get_bits8(tvb, 0, 7);
1928 header_crc_pi = proto_tree_add_item(tree, hf_fp_header_crc, tvb, offset, 1, ENC_BIG_ENDIAN);
1930 /* Frame Type */
1931 is_control_frame = tvb_get_guint8(tvb, offset) & 0x01;
1932 proto_tree_add_item(tree, hf_fp_ft, tvb, offset, 1, ENC_BIG_ENDIAN);
1933 offset++;
1935 col_append_str(pinfo->cinfo, COL_INFO, is_control_frame ? " [Control] " : " [Data] ");
1937 if (is_control_frame) {
1938 dissect_common_control(tvb, pinfo, tree, offset, p_fp_info);
1939 /* For control frame the header CRC is actually frame CRC covering all
1940 * bytes except the first */
1941 if (preferences_header_checksum) {
1942 verify_control_frame_crc(tvb, pinfo, header_crc_pi, header_crc);
1945 else {
1946 guint header_length = 0;
1947 /* DATA */
1949 /* 12-bit CFN value */
1950 proto_tree_add_item(tree, hf_fp_pch_cfn, tvb, offset, 2, ENC_BIG_ENDIAN);
1951 pch_cfn = (tvb_get_ntohs(tvb, offset) & 0xfff0) >> 4;
1952 offset++;
1954 col_append_fstr(pinfo->cinfo, COL_INFO, "CFN=%04u ", pch_cfn);
1956 /* Paging indication */
1957 proto_tree_add_item(tree, hf_fp_pch_pi, tvb, offset, 1, ENC_BIG_ENDIAN);
1958 paging_indication = tvb_get_guint8(tvb, offset) & 0x01;
1959 offset++;
1961 /* 5-bit TFI */
1962 proto_tree_add_item(tree, hf_fp_pch_tfi, tvb, offset, 1, ENC_BIG_ENDIAN);
1963 offset++;
1964 header_length = offset;
1965 /* Optional paging indications */
1966 if (paging_indication) {
1967 proto_item *ti;
1968 ti = proto_tree_add_item(tree, hf_fp_paging_indication_bitmap, tvb,
1969 offset,
1970 (p_fp_info->paging_indications+7) / 8,
1971 ENC_NA);
1972 proto_item_append_text(ti, " (%u bits)", p_fp_info->paging_indications);
1973 offset += ((p_fp_info->paging_indications+7) / 8);
1976 /* TB data */
1977 offset = dissect_tb_data(tvb, pinfo, tree, offset, p_fp_info, &mac_fdd_pch_handle);
1979 if (preferences_header_checksum) {
1980 verify_header_crc(tvb, pinfo, header_crc_pi, header_crc, header_length);
1982 /* Spare Extension and Payload CRC */
1983 dissect_spare_extension_and_crc(tvb, pinfo, tree, 1, offset, header_length);
1988 /**************************/
1989 /* Dissect a CPCH channel */
1990 static void
1991 dissect_cpch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1992 int offset, struct fp_info *p_fp_info)
1994 gboolean is_control_frame;
1996 /* Header CRC */
1997 proto_tree_add_item(tree, hf_fp_header_crc, tvb, offset, 1, ENC_BIG_ENDIAN);
1999 /* Frame Type */
2000 is_control_frame = tvb_get_guint8(tvb, offset) & 0x01;
2001 proto_tree_add_item(tree, hf_fp_ft, tvb, offset, 1, ENC_BIG_ENDIAN);
2002 offset++;
2004 col_append_str(pinfo->cinfo, COL_INFO, is_control_frame ? " [Control] " : " [Data] ");
2006 if (is_control_frame) {
2007 dissect_common_control(tvb, pinfo, tree, offset, p_fp_info);
2009 else {
2010 guint cfn;
2011 guint header_length = 0;
2012 /* DATA */
2014 /* CFN */
2015 cfn = tvb_get_guint8(tvb, offset);
2016 proto_tree_add_item(tree, hf_fp_cfn, tvb, offset, 1, ENC_BIG_ENDIAN);
2017 offset++;
2019 col_append_fstr(pinfo->cinfo, COL_INFO, "CFN=%03u ", cfn);
2021 /* TFI */
2022 proto_tree_add_item(tree, hf_fp_cpch_tfi, tvb, offset, 1, ENC_BIG_ENDIAN);
2023 offset++;
2025 /* Propagation delay */
2026 proto_tree_add_uint(tree, hf_fp_propagation_delay, tvb, offset, 1,
2027 tvb_get_guint8(tvb, offset) * 3);
2028 offset++;
2029 header_length = offset; /* XXX this might be wrong */
2030 /* TB data */
2031 offset = dissect_tb_data(tvb, pinfo, tree, offset, p_fp_info, NULL);
2033 /* CRCIs */
2034 offset = dissect_crci_bits(tvb, pinfo, tree, p_fp_info, offset);
2036 /* Spare Extension and Payload CRC */
2037 dissect_spare_extension_and_crc(tvb, pinfo, tree, 1, offset, header_length);
2042 /**************************/
2043 /* Dissect a BCH channel */
2044 static void
2045 dissect_bch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2046 int offset, struct fp_info *p_fp_info)
2048 gboolean is_control_frame;
2050 /* Header CRC */
2051 proto_tree_add_item(tree, hf_fp_header_crc, tvb, offset, 1, ENC_BIG_ENDIAN);
2053 /* Frame Type */
2054 is_control_frame = tvb_get_guint8(tvb, offset) & 0x01;
2055 proto_tree_add_item(tree, hf_fp_ft, tvb, offset, 1, ENC_BIG_ENDIAN);
2056 offset++;
2058 col_append_str(pinfo->cinfo, COL_INFO, is_control_frame ? " [Control] " : " [Data] ");
2060 if (is_control_frame) {
2061 dissect_common_control(tvb, pinfo, tree, offset, p_fp_info);
2066 /********************************/
2067 /* Dissect an IUR DSCH channel */
2068 static void
2069 dissect_iur_dsch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2070 int offset, struct fp_info *p_fp_info)
2072 gboolean is_control_frame;
2074 /* Header CRC */
2075 proto_tree_add_item(tree, hf_fp_header_crc, tvb, offset, 1, ENC_BIG_ENDIAN);
2077 /* Frame Type */
2078 is_control_frame = tvb_get_guint8(tvb, offset) & 0x01;
2079 proto_tree_add_item(tree, hf_fp_ft, tvb, offset, 1, ENC_BIG_ENDIAN);
2080 offset++;
2082 col_append_str(pinfo->cinfo, COL_INFO, is_control_frame ? " [Control] " : " [Data] ");
2084 if (is_control_frame) {
2085 dissect_common_control(tvb, pinfo, tree, offset, p_fp_info);
2087 else {
2088 /* TODO: DATA */
2095 /************************/
2096 /* DCH control messages */
2098 static int
2099 dissect_dch_timing_adjustment(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, int offset)
2101 guint8 control_cfn;
2102 gint16 toa;
2103 proto_item *toa_ti;
2105 /* CFN control */
2106 control_cfn = tvb_get_guint8(tvb, offset);
2107 proto_tree_add_item(tree, hf_fp_cfn_control, tvb, offset, 1, ENC_BIG_ENDIAN);
2108 offset++;
2110 /* ToA */
2111 toa = tvb_get_ntohs(tvb, offset);
2112 toa_ti = proto_tree_add_item(tree, hf_fp_toa, tvb, offset, 2, ENC_BIG_ENDIAN);
2113 offset += 2;
2115 expert_add_info_format(pinfo, toa_ti, &ei_fp_timing_adjustmentment_reported, "Timing adjustmentment reported (%f ms)", (float)(toa / 8));
2117 col_append_fstr(pinfo->cinfo, COL_INFO,
2118 " CFN = %u, ToA = %d", control_cfn, toa);
2120 return offset;
2123 static int
2124 dissect_dch_rx_timing_deviation(packet_info *pinfo, proto_tree *tree,
2125 tvbuff_t *tvb, int offset,
2126 struct fp_info *p_fp_info)
2128 guint16 timing_deviation;
2129 gint timing_deviation_chips;
2130 proto_item *timing_deviation_ti;
2132 /* CFN control */
2133 proto_tree_add_item(tree, hf_fp_cfn_control, tvb, offset, 1, ENC_BIG_ENDIAN);
2134 offset++;
2136 /* Rx Timing Deviation */
2137 timing_deviation = tvb_get_guint8(tvb, offset);
2138 timing_deviation_ti = proto_tree_add_item(tree, hf_fp_dch_rx_timing_deviation, tvb, offset, 1, ENC_BIG_ENDIAN);
2139 offset++;
2141 /* May be extended in R7, but in this case there are at least 2 bytes remaining */
2142 if ((p_fp_info->release == 7) &&
2143 (tvb_length_remaining(tvb, offset) >= 2)) {
2145 /* New IE flags */
2146 guint64 extended_bits_present;
2147 guint64 e_rucch_present;
2149 /* Read flags */
2150 proto_tree_add_bits_ret_val(tree, hf_fp_e_rucch_present, tvb,
2151 offset*8 + 6, 1, &e_rucch_present, ENC_BIG_ENDIAN);
2152 proto_tree_add_bits_ret_val(tree, hf_fp_extended_bits_present, tvb,
2153 offset*8 + 7, 1, &extended_bits_present, ENC_BIG_ENDIAN);
2154 offset++;
2156 /* Optional E-RUCCH */
2157 if (e_rucch_present) {
2159 /* Value of bit_offset depends upon division type */
2160 int bit_offset;
2162 switch (p_fp_info->division) {
2163 case Division_TDD_384:
2164 bit_offset = 6;
2165 break;
2166 case Division_TDD_768:
2167 bit_offset = 5;
2168 break;
2169 default:
2171 proto_tree_add_expert(tree, pinfo, &ei_fp_expecting_tdd, tvb, 0, 0);
2172 bit_offset = 6;
2176 proto_tree_add_item(tree, hf_fp_dch_e_rucch_flag, tvb, offset, 1, ENC_BIG_ENDIAN);
2177 proto_tree_add_bits_item(tree, hf_fp_dch_e_rucch_flag, tvb,
2178 offset*8 + bit_offset, 1, ENC_BIG_ENDIAN);
2181 /* Timing deviation may be extended by another:
2182 - 1 bits (3.84 TDD) OR
2183 - 2 bits (7.68 TDD)
2185 if (extended_bits_present) {
2186 guint8 extra_bits;
2187 guint bits_to_extend;
2188 switch (p_fp_info->division) {
2189 case Division_TDD_384:
2190 bits_to_extend = 1;
2191 break;
2192 case Division_TDD_768:
2193 bits_to_extend = 2;
2194 break;
2196 default:
2197 /* TODO: report unexpected division type */
2198 bits_to_extend = 1;
2199 break;
2201 extra_bits = tvb_get_guint8(tvb, offset) &
2202 ((bits_to_extend == 1) ? 0x01 : 0x03);
2203 timing_deviation = (extra_bits << 8) | (timing_deviation);
2204 proto_item_append_text(timing_deviation_ti,
2205 " (extended to 0x%x)",
2206 timing_deviation);
2207 proto_tree_add_bits_item(tree, hf_fp_extended_bits, tvb,
2208 offset*8 + (8-bits_to_extend), bits_to_extend, ENC_BIG_ENDIAN);
2209 offset++;
2213 timing_deviation_chips = (timing_deviation*4) - 1024;
2214 proto_item_append_text(timing_deviation_ti, " (%d chips)",
2215 timing_deviation_chips);
2217 col_append_fstr(pinfo->cinfo, COL_INFO, " deviation = %u (%d chips)",
2218 timing_deviation, timing_deviation_chips);
2220 return offset;
2223 static int
2224 dissect_dch_dl_synchronisation(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, int offset)
2226 /* CFN control */
2227 guint cfn = tvb_get_guint8(tvb, offset);
2228 proto_tree_add_item(tree, hf_fp_cfn_control, tvb, offset, 1, ENC_BIG_ENDIAN);
2229 offset++;
2231 col_append_fstr(pinfo->cinfo, COL_INFO, " CFN = %u", cfn);
2233 return offset;
2236 static int
2237 dissect_dch_ul_synchronisation(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, int offset)
2239 guint8 cfn;
2240 gint16 toa;
2242 /* CFN control */
2243 cfn = tvb_get_guint8(tvb, offset);
2244 proto_tree_add_item(tree, hf_fp_cfn_control, tvb, offset, 1, ENC_BIG_ENDIAN);
2245 offset++;
2247 /* ToA */
2248 toa = tvb_get_ntohs(tvb, offset);
2249 proto_tree_add_item(tree, hf_fp_toa, tvb, offset, 2, ENC_BIG_ENDIAN);
2250 offset += 2;
2252 col_append_fstr(pinfo->cinfo, COL_INFO, " CFN = %u, ToA = %d",
2253 cfn, toa);
2255 return offset;
2258 static int
2259 dissect_dch_outer_loop_power_control(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, int offset)
2261 /* UL SIR target */
2262 float target = (float)-8.2 + ((float)0.1 * (float)(int)(tvb_get_guint8(tvb, offset)));
2263 proto_tree_add_float(tree, hf_fp_ul_sir_target, tvb, offset, 1, target);
2264 offset++;
2266 col_append_fstr(pinfo->cinfo, COL_INFO, " UL SIR Target = %f", target);
2268 return offset;
2271 static int
2272 dissect_dch_dl_node_synchronisation(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, int offset)
2274 return dissect_common_dl_node_synchronisation(pinfo, tree, tvb, offset);
2277 static int
2278 dissect_dch_ul_node_synchronisation(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, int offset)
2280 return dissect_common_ul_node_synchronisation(pinfo, tree, tvb, offset);
2283 static int
2284 dissect_dch_radio_interface_parameter_update(proto_tree *tree, packet_info *pinfo _U_, tvbuff_t *tvb, int offset)
2286 int n;
2287 guint8 value;
2289 /* Show defined flags in these 2 bytes */
2290 for (n=4; n >= 0; n--) {
2291 proto_tree_add_item(tree, hf_fp_radio_interface_parameter_update_flag[n], tvb, offset, 2, ENC_BIG_ENDIAN);
2293 offset += 2;
2295 /* CFN */
2296 tvb_get_guint8(tvb, offset);
2297 proto_tree_add_item(tree, hf_fp_cfn, tvb, offset, 1, ENC_BIG_ENDIAN);
2298 offset++;
2300 /* DPC mode */
2301 proto_tree_add_item(tree, hf_fp_dpc_mode, tvb, offset, 1, ENC_BIG_ENDIAN);
2303 /* TPC PO */
2304 proto_tree_add_item(tree, hf_fp_tpc_po, tvb, offset, 1, ENC_BIG_ENDIAN);
2305 offset++;
2307 /* Multiple RL sets indicator */
2308 proto_tree_add_item(tree, hf_fp_multiple_rl_set_indicator, tvb, offset, 1, ENC_BIG_ENDIAN);
2309 offset += 2;
2311 /* MAX_UE_TX_POW */
2312 value = (tvb_get_guint8(tvb, offset) & 0x7f);
2313 proto_tree_add_int(tree, hf_fp_max_ue_tx_pow, tvb, offset, 1, -55 + value);
2314 offset++;
2316 return offset;
2319 static int
2320 dissect_dch_timing_advance(proto_tree *tree, packet_info *pinfo,
2321 tvbuff_t *tvb, int offset, struct fp_info *p_fp_info)
2323 guint8 cfn;
2324 guint16 timing_advance;
2325 proto_item *timing_advance_ti;
2327 /* CFN control */
2328 cfn = tvb_get_guint8(tvb, offset);
2329 proto_tree_add_item(tree, hf_fp_cfn_control, tvb, offset, 1, ENC_BIG_ENDIAN);
2330 offset++;
2332 /* Timing Advance */
2333 timing_advance = (tvb_get_guint8(tvb, offset) & 0x3f) * 4;
2334 timing_advance_ti = proto_tree_add_uint(tree, hf_fp_timing_advance, tvb, offset, 1, timing_advance);
2335 offset++;
2337 if ((p_fp_info->release == 7) &&
2338 (tvb_length_remaining(tvb, offset) > 0)) {
2340 /* New IE flags */
2341 guint8 flags = tvb_get_guint8(tvb, offset);
2342 guint8 extended_bits = flags & 0x01;
2343 offset++;
2345 if (extended_bits) {
2346 guint8 extra_bit = tvb_get_guint8(tvb, offset) & 0x01;
2347 proto_item_append_text(timing_advance_ti, " (extended to %u)",
2348 (timing_advance << 1) | extra_bit);
2350 offset++;
2353 col_append_fstr(pinfo->cinfo, COL_INFO, " CFN = %u, TA = %u",
2354 cfn, timing_advance);
2356 return offset;
2359 static int
2360 dissect_dch_tnl_congestion_indication(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, int offset)
2362 guint64 status;
2364 /* Congestion status */
2365 proto_tree_add_bits_ret_val(tree, hf_fp_congestion_status, tvb,
2366 offset*8 + 6, 2, &status, ENC_BIG_ENDIAN);
2367 offset++;
2369 col_append_fstr(pinfo->cinfo, COL_INFO, " status = %s",
2370 val_to_str_const((guint16)status, congestion_status_vals, "unknown"));
2372 return offset;
2378 /* DCH control frame */
2379 static void
2380 dissect_dch_control_frame(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb,
2381 int offset, struct fp_info *p_fp_info)
2383 /* Control frame type */
2384 guint8 control_frame_type = tvb_get_guint8(tvb, offset);
2385 proto_tree_add_item(tree, hf_fp_dch_control_frame_type, tvb, offset, 1, ENC_BIG_ENDIAN);
2386 offset++;
2388 col_append_str(pinfo->cinfo, COL_INFO,
2389 val_to_str_const(control_frame_type,
2390 dch_control_frame_type_vals, "Unknown"));
2392 switch (control_frame_type) {
2393 case DCH_TIMING_ADJUSTMENT:
2394 /*offset =*/ dissect_dch_timing_adjustment(tree, pinfo, tvb, offset);
2395 break;
2396 case DCH_RX_TIMING_DEVIATION:
2397 /*offset =*/ dissect_dch_rx_timing_deviation(pinfo, tree, tvb, offset, p_fp_info);
2398 break;
2399 case DCH_DL_SYNCHRONISATION:
2400 /*offset =*/ dissect_dch_dl_synchronisation(tree, pinfo, tvb, offset);
2401 break;
2402 case DCH_UL_SYNCHRONISATION:
2403 /*offset =*/ dissect_dch_ul_synchronisation(tree, pinfo, tvb, offset);
2404 break;
2405 case DCH_OUTER_LOOP_POWER_CONTROL:
2406 /*offset =*/ dissect_dch_outer_loop_power_control(tree, pinfo, tvb, offset);
2407 break;
2408 case DCH_DL_NODE_SYNCHRONISATION:
2409 /*offset =*/ dissect_dch_dl_node_synchronisation(tree, pinfo, tvb, offset);
2410 break;
2411 case DCH_UL_NODE_SYNCHRONISATION:
2412 /*offset =*/ dissect_dch_ul_node_synchronisation(tree, pinfo, tvb, offset);
2413 break;
2414 case DCH_RADIO_INTERFACE_PARAMETER_UPDATE:
2415 /*offset =*/ dissect_dch_radio_interface_parameter_update(tree, pinfo, tvb, offset);
2416 break;
2417 case DCH_TIMING_ADVANCE:
2418 /*offset =*/ dissect_dch_timing_advance(tree, pinfo, tvb, offset, p_fp_info);
2419 break;
2420 case DCH_TNL_CONGESTION_INDICATION:
2421 /*offset =*/ dissect_dch_tnl_congestion_indication(tree, pinfo, tvb, offset);
2422 break;
2425 /* Spare Extension */
2426 /* dissect_spare_extension_and_crc(tvb, pinfo, tree, 0, offset);
2430 /*******************************/
2431 /* Dissect a DCH channel */
2432 static void
2433 dissect_dch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2434 int offset, struct fp_info *p_fp_info)
2436 gboolean is_control_frame;
2437 guint8 cfn;
2438 guint header_length = 0;
2439 guint16 header_crc = 0;
2440 proto_item * header_crc_pi = NULL;
2442 /* Header CRC */
2443 header_crc = tvb_get_bits8(tvb, 0, 7);
2444 header_crc_pi = proto_tree_add_item(tree, hf_fp_header_crc, tvb, offset, 1, ENC_BIG_ENDIAN);
2446 /* Frame Type */
2447 is_control_frame = tvb_get_guint8(tvb, offset) & 0x01;
2448 proto_tree_add_item(tree, hf_fp_ft, tvb, offset, 1, ENC_BIG_ENDIAN);
2449 offset++;
2451 col_append_str(pinfo->cinfo, COL_INFO,
2452 is_control_frame ? " [Control] " :
2453 ((p_fp_info->is_uplink) ? " [ULData] " :
2454 " [DLData] " ));
2456 if (is_control_frame) {
2457 /* DCH control frame */
2458 dissect_dch_control_frame(tree, pinfo, tvb, offset, p_fp_info);
2459 /* For control frame the header CRC is actually frame CRC covering all
2460 * bytes except the first */
2461 if (preferences_header_checksum) {
2462 verify_control_frame_crc(tvb, pinfo, header_crc_pi, header_crc);
2464 }else{
2465 /************************/
2466 /* DCH data here */
2467 int chan;
2468 /* CFN */
2469 proto_tree_add_item(tree, hf_fp_cfn, tvb, offset, 1, ENC_BIG_ENDIAN);
2470 cfn = tvb_get_guint8(tvb, offset);
2471 offset++;
2473 col_append_fstr(pinfo->cinfo, COL_INFO, "CFN=%03u ", cfn);
2475 /* One TFI for each channel */
2476 for (chan=0; chan < p_fp_info->num_chans; chan++) {
2477 proto_tree_add_item(tree, hf_fp_tfi, tvb, offset, 1, ENC_BIG_ENDIAN);
2478 offset++;
2480 header_length = offset;
2481 /* Dissect TB data */
2482 offset = dissect_tb_data(tvb, pinfo, tree, offset, p_fp_info, &mac_fdd_dch_handle);
2484 /* QE (uplink only) */
2485 if (p_fp_info->is_uplink) {
2486 proto_tree_add_item(tree, hf_fp_quality_estimate, tvb, offset, 1, ENC_BIG_ENDIAN);
2487 offset++;
2490 /* CRCI bits (uplink only) */
2491 if (p_fp_info->is_uplink) {
2492 offset = dissect_crci_bits(tvb, pinfo, tree, p_fp_info, offset);
2494 if (preferences_header_checksum) {
2495 verify_header_crc(tvb, pinfo, header_crc_pi, header_crc, header_length);
2497 /* Spare extension and payload CRC (optional) */
2498 dissect_spare_extension_and_crc(tvb, pinfo, tree,
2499 p_fp_info->dch_crc_present, offset, header_length);
2503 /**********************************/
2504 /* Dissect an E-DCH channel */
2505 static void
2506 dissect_e_dch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2507 int offset, struct fp_info *p_fp_info,
2508 gboolean is_common, rlc_info *rlcinf)
2510 gboolean is_control_frame;
2511 guint8 number_of_subframes;
2512 guint8 cfn;
2513 int n;
2514 struct edch_t1_subframe_info subframes[16];
2515 guint16 header_crc = 0;
2516 proto_item * header_crc_pi = NULL;
2517 guint header_length = 0;
2519 if (p_fp_info->edch_type == 1) {
2520 col_append_str(pinfo->cinfo, COL_INFO, " (T2)");
2523 /* Header CRC */
2524 /* the bitmask doesn't properly handle this delicate case, do manually */
2525 header_crc = (tvb_get_bits8(tvb, offset*8, 7) << 4) + tvb_get_bits8(tvb, offset*8+8, 4);
2527 /* Frame Type */
2528 is_control_frame = tvb_get_guint8(tvb, offset) & 0x01;
2530 col_append_str(pinfo->cinfo, COL_INFO, is_control_frame ? " [Control] " : " [Data] ");
2532 if (is_control_frame) {
2533 /* DCH control frame */
2535 /* For control frame the header CRC is actually frame CRC covering all
2536 * bytes except the first */
2537 header_crc = tvb_get_bits8(tvb, 0, 7);
2538 header_crc_pi = proto_tree_add_item(tree, hf_fp_header_crc, tvb, 0, 1, ENC_BIG_ENDIAN);
2539 proto_tree_add_item(tree, hf_fp_ft, tvb, 0, 1, ENC_BIG_ENDIAN);
2540 offset++;
2541 if (preferences_header_checksum) {
2542 verify_control_frame_crc(tvb, pinfo, header_crc_pi, header_crc);
2544 dissect_dch_control_frame(tree, pinfo, tvb, offset, p_fp_info);
2546 else {
2547 /********************************/
2548 /* E-DCH data here */
2549 guint bit_offset = 0;
2550 guint total_pdus = 0;
2551 guint total_bits = 0;
2552 gboolean dissected = FALSE;
2554 header_crc_pi = proto_tree_add_uint_format(tree, hf_fp_edch_header_crc, tvb,
2555 offset, 2, header_crc,
2556 "%u%u%u%u%u%u%u.%u%u%u%u.... = E-DCH Header CRC: 0x%x",
2557 (header_crc >> 10) & 1,
2558 (header_crc >> 9) & 1,
2559 (header_crc >> 8) & 1,
2560 (header_crc >> 7) & 1,
2561 (header_crc >> 6) & 1,
2562 (header_crc >> 5) & 1,
2563 (header_crc >> 4) & 1,
2564 (header_crc >> 3) & 1,
2565 (header_crc >> 2) & 1,
2566 (header_crc >> 1) & 1,
2567 (header_crc >> 0) & 1, header_crc);
2568 proto_tree_add_item(tree, hf_fp_ft, tvb, offset, 1, ENC_BIG_ENDIAN);
2569 offset++;
2570 /* FSN */
2571 proto_tree_add_item(tree, hf_fp_edch_fsn, tvb, offset, 1, ENC_BIG_ENDIAN);
2572 offset++;
2574 /* Number of subframes.
2575 This was 3 bits in early releases, is 4 bits offset by 1 in later releases */
2576 if ((p_fp_info->release >= 6) &&
2577 ((p_fp_info->release_year > 2005) ||
2578 ((p_fp_info->release_year == 2005) && (p_fp_info->release_month >= 9)))) {
2580 /* Use 4 bits plus offset of 1 */
2581 number_of_subframes = (tvb_get_guint8(tvb, offset) & 0x0f) + 1;
2583 else {
2584 /* Use 3 bits only */
2585 number_of_subframes = (tvb_get_guint8(tvb, offset) & 0x07);
2587 proto_tree_add_uint(tree, hf_fp_edch_number_of_subframes, tvb, offset, 1,
2588 number_of_subframes);
2590 offset++;
2592 /* CFN */
2593 cfn = tvb_get_guint8(tvb, offset);
2594 proto_tree_add_item(tree, hf_fp_cfn, tvb, offset, 1, ENC_BIG_ENDIAN);
2595 offset++;
2597 /* Remainder of T2 or common data frames differ here... */
2598 if (p_fp_info->edch_type == 1) {
2599 dissect_e_dch_t2_or_common_channel_info(tvb, pinfo, tree, offset, p_fp_info,
2600 number_of_subframes, is_common, header_crc, header_crc_pi);
2601 return;
2604 /* EDCH subframe header list */
2605 for (n=0; n < number_of_subframes; n++) {
2606 int i;
2607 int start_offset = offset;
2608 proto_item *subframe_header_ti;
2609 proto_tree *subframe_header_tree;
2611 /* Add subframe header subtree */
2612 subframe_header_ti = proto_tree_add_string_format(tree, hf_fp_edch_subframe_header, tvb, offset, 0,
2613 "", "Subframe");
2614 subframe_header_tree = proto_item_add_subtree(subframe_header_ti, ett_fp_edch_subframe_header);
2616 /* Number of HARQ Retransmissions */
2617 proto_tree_add_item(subframe_header_tree, hf_fp_edch_harq_retransmissions, tvb,
2618 offset, 1, ENC_BIG_ENDIAN);
2620 /* Subframe number */
2621 subframes[n].subframe_number = (tvb_get_guint8(tvb, offset) & 0x07);
2622 proto_tree_add_bits_item(subframe_header_tree, hf_fp_edch_subframe_number, tvb,
2623 offset*8+5, 1, ENC_BIG_ENDIAN);
2624 offset++;
2626 /* Number of MAC-es PDUs */
2627 subframes[n].number_of_mac_es_pdus = (tvb_get_guint8(tvb, offset) & 0xf0) >> 4;
2628 proto_tree_add_item(subframe_header_tree, hf_fp_edch_number_of_mac_es_pdus,
2629 tvb, offset, 1, ENC_BIG_ENDIAN);
2630 bit_offset = 4;
2632 proto_item_append_text(subframe_header_ti, " %u header (%u MAC-es PDUs)",
2633 subframes[n].subframe_number,
2634 subframes[n].number_of_mac_es_pdus);
2636 /* Details of each MAC-es PDU */
2637 for (i=0; i < subframes[n].number_of_mac_es_pdus; i++) {
2638 guint64 ddi;
2639 guint64 n_pdus; /*Size of the PDU*/
2641 proto_item *ddi_ti;
2642 gint ddi_size = -1;
2643 int p;
2645 /* DDI (6 bits) */
2646 ddi_ti = proto_tree_add_bits_ret_val(subframe_header_tree, hf_fp_edch_ddi, tvb,
2647 offset*8 + bit_offset, 6, &ddi, ENC_BIG_ENDIAN);
2649 if(rlcinf){
2650 rlcinf->rbid[i] = (guint8)ddi;
2652 /********************************/
2653 /* Look up data in higher layers*/
2654 /* Look up the size from this DDI value */
2655 for (p=0; p < p_fp_info->no_ddi_entries; p++) {
2656 if (ddi == p_fp_info->edch_ddi[p]) {
2657 ddi_size = p_fp_info->edch_macd_pdu_size[p];
2659 break;
2663 if (ddi_size == -1) {
2664 expert_add_info_format(pinfo, ddi_ti, &ei_fp_ddi_not_defined, "DDI %u not defined for this UE!", (guint)ddi);
2665 return;
2667 else {
2668 proto_item_append_text(ddi_ti, " (%d bits)", ddi_size);
2671 subframes[n].ddi[i] = (guint8)ddi;
2672 bit_offset += 6;
2674 /* Number of MAC-d PDUs (6 bits) */
2675 proto_tree_add_bits_ret_val(subframe_header_tree, hf_fp_edch_number_of_mac_d_pdus, tvb,
2676 offset*8 + bit_offset, 6, &n_pdus, ENC_BIG_ENDIAN);
2678 subframes[n].number_of_mac_d_pdus[i] = (guint8)n_pdus;
2679 bit_offset += 6;
2682 offset += ((bit_offset+7)/8);
2684 /* Tree should cover entire subframe header */
2685 proto_item_set_len(subframe_header_ti, offset - start_offset);
2687 header_length = offset;
2688 /* EDCH subframes */
2689 for (n=0; n < number_of_subframes; n++) {
2690 int i;
2691 proto_item *subframe_ti;
2692 proto_tree *subframe_tree;
2693 guint bits_in_subframe = 0;
2694 guint mac_d_pdus_in_subframe = 0;
2695 guint lchid=0; /*Logcial channel id*/
2696 umts_mac_info *macinf;
2697 bit_offset = 0;
2699 macinf = (umts_mac_info *)p_get_proto_data(pinfo->fd, proto_umts_mac, 0);
2700 /* Add subframe subtree */
2701 subframe_ti = proto_tree_add_string_format(tree, hf_fp_edch_subframe, tvb, offset, 0,
2702 "", "Subframe %u data", subframes[n].subframe_number);
2703 subframe_tree = proto_item_add_subtree(subframe_ti, ett_fp_edch_subframe);
2705 for (i=0; i < subframes[n].number_of_mac_es_pdus; i++) {
2706 int m;
2707 guint16 size = 0;
2708 /* guint8 tsn; */
2709 guint send_size;
2710 proto_item *ti;
2711 int macd_idx;
2712 proto_tree *maces_tree = NULL;
2714 /** TODO: Merge these two loops? **/
2715 /* Look up mac-d pdu size for this ddi */
2716 for (m=0; m < p_fp_info->no_ddi_entries; m++) {
2717 if (subframes[n].ddi[i] == p_fp_info->edch_ddi[m]) {
2718 size = p_fp_info->edch_macd_pdu_size[m];
2719 break;
2722 /* Look up logicalchannel id for this DDI value */
2723 for (m=0; m < p_fp_info->no_ddi_entries; m++) {
2724 if (subframes[n].ddi[i] == p_fp_info->edch_ddi[m]) {
2725 lchid = p_fp_info->edch_lchId[m];
2726 break;
2730 if (m == p_fp_info->no_ddi_entries) {
2731 /* Not found. Oops */
2732 expert_add_info(pinfo, NULL, &ei_fp_unable_to_locate_ddi_entry);
2733 return;
2736 /* Send MAC-dd PDUs together as one MAC-es PDU */
2737 send_size = size * subframes[n].number_of_mac_d_pdus[i];
2739 /* 2 bits spare */
2740 proto_tree_add_item(subframe_tree, hf_fp_edch_pdu_padding, tvb,
2741 offset + (bit_offset/8),
2742 1, ENC_BIG_ENDIAN);
2743 bit_offset += 2;
2745 /* TSN */
2746 /* tsn = (tvb_get_guint8(tvb, offset + (bit_offset/8)) & 0x3f); */
2747 proto_tree_add_item(subframe_tree, hf_fp_edch_tsn, tvb,
2748 offset + (bit_offset/8),
2749 1, ENC_BIG_ENDIAN);
2750 bit_offset += 6;
2752 /* PDU */
2753 if (subframe_tree) {
2754 ti = proto_tree_add_item(subframe_tree, hf_fp_edch_mac_es_pdu, tvb,
2755 offset + (bit_offset/8),
2756 ((bit_offset % 8) + send_size + 7) / 8,
2757 ENC_NA);
2758 proto_item_append_text(ti, " (%u * %u = %u bits, PDU %d)",
2759 size, subframes[n].number_of_mac_d_pdus[i],
2760 send_size, n);
2761 maces_tree = proto_item_add_subtree(ti, ett_fp_edch_maces);
2763 for (macd_idx = 0; macd_idx < subframes[n].number_of_mac_d_pdus[i]; macd_idx++) {
2765 if (preferences_call_mac_dissectors /*&& !rlc_is_ciphered(pinfo)*/) {
2766 tvbuff_t *next_tvb;
2767 pinfo->fd->subnum = macd_idx; /* set subframe number to current TB */
2768 /* create new TVB and pass further on */
2769 next_tvb = tvb_new_subset(tvb, offset + bit_offset/8,
2770 ((bit_offset % 8) + size + 7) / 8, -1);
2773 /*This was all previously stored in [0] rather than [macd_idx] and cur_tb wasnt updated!*/
2774 /*Set up information needed for MAC and lower layers*/
2775 macinf->content[macd_idx] = lchId_type_table[lchid]; /*Set the proper Content type for the mac layer.*/
2776 macinf->lchid[macd_idx] = lchid;
2777 rlcinf->mode[macd_idx] = lchId_rlc_map[lchid]; /* Set RLC mode by lchid to RLC_MODE map in nbap.h */
2779 /* Set U-RNTI to ComuncationContext signaled from nbap*/
2780 rlcinf->urnti[macd_idx] = p_fp_info->com_context_id;
2781 rlcinf->rbid[macd_idx] = lchid; /*subframes[n].ddi[i];*/ /*Save the DDI value for RLC*/
2782 /*g_warning("========Setting RBID:%d for lchid:%d",subframes[n].ddi[i],lchid);*/
2783 /* rlcinf->mode[0] = RLC_AM;*/
2784 rlcinf->li_size[macd_idx] = RLC_LI_7BITS;
2786 /*If this entry exists, SECRUITY_MODE is completed*/
2787 /*if( rrc_ciph_inf && g_tree_lookup(rrc_ciph_inf, GINT_TO_POINTER((gint)p_fp_info->com_context_id)) ){
2788 rlcinf->ciphered[macd_idx] = TRUE;
2789 }else{
2790 rlcinf->ciphered[macd_idx] = FALSE;
2792 rlcinf->ciphered[macd_idx] = FALSE;
2793 rlcinf->deciphered[macd_idx] = FALSE;
2794 p_fp_info->cur_tb = macd_idx; /*Set the transport block index (NOTE: This and not subnum is used in MAC dissector!)*/
2796 /* TODO: use maces_tree? */
2797 call_dissector(mac_fdd_edch_handle, next_tvb, pinfo, top_level_tree);
2798 dissected = TRUE;
2800 else {
2801 /* Just add as a MAC-d PDU */
2802 proto_tree_add_item(maces_tree, hf_fp_mac_d_pdu, tvb,
2803 offset + (bit_offset/8),
2804 ((bit_offset % 8) + size + 7) / 8,
2805 ENC_NA);
2807 bit_offset += size;
2810 bits_in_subframe += send_size;
2811 mac_d_pdus_in_subframe += subframes[n].number_of_mac_d_pdus[i];
2813 /* Pad out to next byte */
2814 if (bit_offset % 8) {
2815 bit_offset += (8 - (bit_offset % 8));
2819 if (tree) {
2820 /* Tree should cover entire subframe */
2821 proto_item_set_len(subframe_ti, bit_offset/8);
2822 /* Append summary info to subframe label */
2823 proto_item_append_text(subframe_ti, " (%u bits in %u MAC-d PDUs)",
2824 bits_in_subframe, mac_d_pdus_in_subframe);
2826 total_pdus += mac_d_pdus_in_subframe;
2827 total_bits += bits_in_subframe;
2829 offset += (bit_offset/8);
2832 /* Report number of subframes in info column
2833 * do this only if no other dissector was called */
2834 if (dissected == FALSE) {
2835 col_append_fstr(pinfo->cinfo, COL_INFO,
2836 " CFN = %03u (%u bits in %u pdus in %u subframes)",
2837 cfn, total_bits, total_pdus, number_of_subframes);
2839 /* Add data summary to info column */
2840 /*col_append_fstr(pinfo->cinfo, COL_INFO, " (%u bytes in %u SDUs in %u MAC-is PDUs in %u subframes)",
2841 total_bytes, macis_sdus_found, macis_pdus, number_of_subframes);*/
2842 if (preferences_header_checksum) {
2843 verify_header_crc_edch(tvb, pinfo, header_crc_pi, header_crc, header_length);
2845 /* Spare extension and payload CRC (optional) */
2846 dissect_spare_extension_and_crc(tvb, pinfo, tree,
2847 p_fp_info->dch_crc_present, offset, header_length);
2851 /* Dissect the remainder of the T2 or common frame that differs from T1 */
2852 static void
2853 dissect_e_dch_t2_or_common_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2854 int offset, struct fp_info *p_fp_info,
2855 int number_of_subframes, gboolean is_common, guint16 header_crc, proto_item * header_crc_pi)
2857 int n;
2858 int pdu_no;
2859 guint64 total_macis_sdus;
2860 guint16 macis_sdus_found = 0;
2861 guint16 macis_pdus = 0;
2862 gboolean F = TRUE; /* We want to continue loop if get E-RNTI indication... */
2863 gint bit_offset;
2864 proto_item *subframe_macis_descriptors_ti = NULL;
2865 static struct edch_t2_subframe_info subframes[16];
2866 guint header_length = 0;
2867 /* User Buffer size */
2868 proto_tree_add_bits_item(tree, hf_fp_edch_user_buffer_size, tvb, offset*8,
2869 18, ENC_BIG_ENDIAN);
2870 offset += 2;
2872 /* Spare is in-between... */
2874 /* Total number of MAC-is SDUs */
2875 proto_tree_add_bits_ret_val(tree, hf_fp_edch_no_macid_sdus, tvb, offset*8+4,
2876 12, &total_macis_sdus, ENC_BIG_ENDIAN);
2877 offset += 2;
2879 if (is_common) {
2880 /* E-RNTI */
2881 proto_tree_add_item(tree, hf_fp_edch_e_rnti, tvb, offset, 2, ENC_BIG_ENDIAN);
2882 offset += 2;
2885 bit_offset = offset*8;
2886 /* EDCH subframe header list */
2887 for (n=0; n < number_of_subframes; n++) {
2888 guint64 subframe_number;
2889 guint64 no_of_macis_pdus;
2890 proto_item *subframe_header_ti;
2891 proto_tree *subframe_header_tree;
2893 /* Add subframe header subtree */
2894 subframe_header_ti = proto_tree_add_string_format(tree, hf_fp_edch_subframe_header, tvb, offset, 0,
2895 "", "Subframe");
2896 subframe_header_tree = proto_item_add_subtree(subframe_header_ti, ett_fp_edch_subframe_header);
2898 /* Spare bit */
2899 bit_offset++;
2901 if (!is_common) {
2902 /* Number of HARQ Retransmissions */
2903 proto_tree_add_item(subframe_header_tree, hf_fp_edch_harq_retransmissions, tvb,
2904 bit_offset/8, 1, ENC_BIG_ENDIAN);
2905 bit_offset += 4;
2908 /* Subframe number */
2909 proto_tree_add_bits_ret_val(subframe_header_tree, hf_fp_edch_subframe_number, tvb,
2910 bit_offset, 3, &subframe_number, ENC_BIG_ENDIAN);
2911 subframes[n].subframe_number = (guint8)subframe_number;
2912 bit_offset += 3;
2914 /* Number of MAC-is PDUs */
2915 proto_tree_add_bits_ret_val(subframe_header_tree, hf_fp_edch_number_of_mac_is_pdus, tvb,
2916 bit_offset, 4, &no_of_macis_pdus, ENC_BIG_ENDIAN);
2917 bit_offset += 4;
2918 subframes[n].number_of_mac_is_pdus = (guint8)no_of_macis_pdus;
2919 macis_pdus += subframes[n].number_of_mac_is_pdus;
2921 /* Next 4 bits are spare for T2*/
2922 if (!is_common) {
2923 bit_offset += 4;
2926 /* Show summary in root */
2927 proto_item_append_text(subframe_header_ti, " (SFN %u, %u MAC-is PDUs)",
2928 subframes[n].subframe_number, subframes[n].number_of_mac_is_pdus);
2929 proto_item_set_len(subframe_header_ti, is_common ? 1 : 2);
2931 offset = bit_offset / 8;
2934 /* MAC-is PDU descriptors for each subframe follow */
2935 for (n=0; n < number_of_subframes; n++) {
2936 proto_tree *subframe_macis_descriptors_tree;
2938 /* Add subframe header subtree */
2939 subframe_macis_descriptors_ti = proto_tree_add_string_format(tree, hf_fp_edch_macis_descriptors, tvb, offset, 0,
2940 "", "MAC-is descriptors (SFN %u)", subframes[n].subframe_number);
2941 proto_item_set_len(subframe_macis_descriptors_ti, subframes[n].number_of_mac_is_pdus*2);
2942 subframe_macis_descriptors_tree = proto_item_add_subtree(subframe_macis_descriptors_ti,
2943 ett_fp_edch_macis_descriptors);
2945 /* Find a sequence of descriptors for each MAC-is PDU in this subframe */
2946 for (pdu_no=0; pdu_no < subframes[n].number_of_mac_is_pdus; pdu_no++) {
2947 proto_item *f_ti = NULL;
2949 subframes[n].number_of_mac_is_sdus[pdu_no] = 0;
2951 do {
2952 /* Check we haven't gone past the limit */
2953 if (macis_sdus_found++ > total_macis_sdus) {
2954 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, (guint16)total_macis_sdus);
2957 /* LCH-ID */
2958 subframes[n].mac_is_lchid[pdu_no][subframes[n].number_of_mac_is_sdus[pdu_no]] = (tvb_get_guint8(tvb, offset) & 0xf0) >> 4;
2959 proto_tree_add_item(subframe_macis_descriptors_tree, hf_fp_edch_macis_lchid, tvb, offset, 1, ENC_BIG_ENDIAN);
2960 if (subframes[n].mac_is_lchid[pdu_no][subframes[n].number_of_mac_is_sdus[pdu_no]] == 15) {
2961 proto_item *ti;
2963 /* 4 bits of spare */
2964 offset++;
2966 /* E-RNTI */
2967 ti = proto_tree_add_item(tree, hf_fp_edch_e_rnti, tvb, offset, 2, ENC_BIG_ENDIAN);
2968 offset += 2;
2970 /* This is only allowed if:
2971 - it's the common case AND
2972 - it's the first descriptor */
2973 if (!is_common) {
2974 expert_add_info(pinfo, ti, &ei_fp_e_rnti_t2_edch_frames);
2976 if (subframes[n].number_of_mac_is_sdus[pdu_no] > 0) {
2977 expert_add_info(pinfo, ti, &ei_fp_e_rnti_first_entry);
2979 continue;
2982 /* Length */
2983 subframes[n].mac_is_length[pdu_no][subframes[n].number_of_mac_is_sdus[pdu_no]] = (tvb_get_ntohs(tvb, offset) & 0x0ffe) >> 1;
2984 proto_tree_add_item(subframe_macis_descriptors_tree, hf_fp_edch_macis_length, tvb, offset, 2, ENC_BIG_ENDIAN);
2985 offset++;
2987 /* Flag */
2988 F = tvb_get_guint8(tvb, offset) & 0x01;
2989 f_ti = proto_tree_add_item(subframe_macis_descriptors_tree, hf_fp_edch_macis_flag, tvb, offset, 1, ENC_BIG_ENDIAN);
2991 subframes[n].number_of_mac_is_sdus[pdu_no]++;
2993 offset++;
2994 } while (F == 0);
2998 /* Check overall count of MAC-is SDUs */
2999 if (macis_sdus_found != total_macis_sdus) {
3000 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, (guint16)total_macis_sdus);
3002 header_length = offset;
3003 /* Now PDUs */
3004 for (n=0; n < number_of_subframes; n++) {
3006 /* MAC-is PDU */
3007 for (pdu_no=0; pdu_no < subframes[n].number_of_mac_is_pdus; pdu_no++) {
3008 int i;
3009 guint length = 0;
3010 umts_mac_is_info * mac_is_info = wmem_new(wmem_file_scope(), umts_mac_is_info);
3012 mac_is_info->number_of_mac_is_sdus = subframes[n].number_of_mac_is_sdus[pdu_no];
3013 DISSECTOR_ASSERT(subframes[n].number_of_mac_is_sdus[pdu_no] <= MAX_MAC_FRAMES);
3014 for (i = 0; i < subframes[n].number_of_mac_is_sdus[pdu_no]; i++) {
3015 mac_is_info->sdulength[i] = subframes[n].mac_is_length[pdu_no][i];
3016 mac_is_info->lchid[i] = subframes[n].mac_is_lchid[pdu_no][i];
3017 length += subframes[n].mac_is_length[pdu_no][i];
3020 /* Call MAC for this PDU if configured to */
3021 if (preferences_call_mac_dissectors) {
3022 p_add_proto_data(pinfo->fd, proto_umts_mac, 0, mac_is_info);
3023 call_dissector(mac_fdd_edch_type2_handle, tvb_new_subset_remaining(tvb, offset), pinfo, top_level_tree);
3025 else {
3026 /* Still show data if not decoding as MAC PDU */
3027 proto_tree_add_item(tree, hf_fp_edch_mac_is_pdu, tvb, offset, length, ENC_NA);
3030 /* get_mac_tsn_size in packet-umts_mac.h, gets the global_mac_tsn_size preference in umts_mac.c */
3031 if (get_mac_tsn_size() == MAC_TSN_14BITS) {
3032 offset += length + 2; /* Plus 2 bytes for TSN 14 bits and SS 2 bit. */
3033 } else {
3034 offset += length + 1; /* Plus 1 byte for TSN 6 bits and SS 2 bit. */
3038 if (preferences_header_checksum) {
3039 verify_header_crc_edch(tvb, pinfo, header_crc_pi, header_crc, header_length);
3041 /* Spare extension and payload CRC (optional) */
3042 dissect_spare_extension_and_crc(tvb, pinfo, tree,
3043 p_fp_info->dch_crc_present, offset, header_length);
3048 /**********************************************************/
3049 /* Dissect an HSDSCH channel */
3050 /* The data format corresponds to the format */
3051 /* described in R5 and R6, and frame type 1 in Release 7. */
3052 static void
3053 dissect_hsdsch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
3054 int offset, struct fp_info *p_fp_info)
3056 gboolean is_control_frame;
3057 guint header_length = 0;
3058 guint16 header_crc = 0;
3059 proto_item * header_crc_pi = NULL;
3061 /* Header CRC */
3062 header_crc = tvb_get_bits8(tvb, 0, 7);
3063 header_crc_pi = proto_tree_add_item(tree, hf_fp_header_crc, tvb, offset, 1, ENC_BIG_ENDIAN);
3065 /* Frame Type */
3066 is_control_frame = tvb_get_guint8(tvb, offset) & 0x01;
3067 proto_tree_add_item(tree, hf_fp_ft, tvb, offset, 1, ENC_BIG_ENDIAN);
3068 offset++;
3070 col_append_str(pinfo->cinfo, COL_INFO, is_control_frame ? " [Control] " : " [Data] ");
3072 if (is_control_frame) {
3073 dissect_common_control(tvb, pinfo, tree, offset, p_fp_info);
3074 /* For control frame the header CRC is actually frame CRC covering all
3075 * bytes except the first */
3076 if (preferences_header_checksum) {
3077 verify_control_frame_crc(tvb, pinfo, header_crc_pi, header_crc);
3080 else {
3081 guint8 number_of_pdus;
3082 guint16 pdu_length;
3083 guint16 user_buffer_size;
3084 int i;
3085 umts_mac_info *macinf;
3086 rlc_info *rlcinf;
3088 rlcinf = (rlc_info *)p_get_proto_data(pinfo->fd, proto_rlc, 0);
3089 macinf = (umts_mac_info *)p_get_proto_data(pinfo->fd, proto_umts_mac, 0);
3091 /**************************************/
3092 /* HS-DCH data here (type 1 in R7) */
3094 /* Frame Seq Nr */
3095 if ((p_fp_info->release == 6) ||
3096 (p_fp_info->release == 7)) {
3098 guint8 frame_seq_no = (tvb_get_guint8(tvb, offset) & 0xf0) >> 4;
3099 proto_tree_add_item(tree, hf_fp_frame_seq_nr, tvb, offset, 1, ENC_BIG_ENDIAN);
3101 col_append_fstr(pinfo->cinfo, COL_INFO, " seqno=%u", frame_seq_no);
3104 /* CmCH-PI */
3105 proto_tree_add_item(tree, hf_fp_cmch_pi, tvb, offset, 1, ENC_BIG_ENDIAN);
3106 offset++;
3108 /* MAC-d PDU Length (13 bits) */
3109 pdu_length = (tvb_get_ntohs(tvb, offset) >> 3);
3110 proto_tree_add_item(tree, hf_fp_mac_d_pdu_len, tvb, offset, 2, ENC_BIG_ENDIAN);
3111 offset += 2;
3112 macinf->pdu_len = pdu_length;
3114 if ((p_fp_info->release == 6) ||
3115 (p_fp_info->release == 7)) {
3117 /* Flush bit */
3118 proto_tree_add_item(tree, hf_fp_flush, tvb, offset-1, 1, ENC_BIG_ENDIAN);
3120 /* FSN/DRT reset bit */
3121 proto_tree_add_item(tree, hf_fp_fsn_drt_reset, tvb, offset-1, 1, ENC_BIG_ENDIAN);
3125 /* Num of PDUs */
3126 number_of_pdus = tvb_get_guint8(tvb, offset);
3127 proto_tree_add_item(tree, hf_fp_num_of_pdu, tvb, offset, 1, ENC_BIG_ENDIAN);
3128 offset++;
3130 /* User buffer size */
3131 user_buffer_size = tvb_get_ntohs(tvb, offset);
3132 proto_tree_add_item(tree, hf_fp_user_buffer_size, tvb, offset, 2, ENC_BIG_ENDIAN);
3133 offset += 2;
3135 header_length = offset;
3138 /************************/
3139 /*Configure the pdus*/
3140 for(i=0;i<number_of_pdus; i++){
3141 macinf->content[i] = hsdsch_macdflow_id_mac_content_map[p_fp_info->hsdsch_macflowd_id]; /*MAC_CONTENT_PS_DTCH;*/
3142 macinf->lchid[i] = fake_lchid_macd_flow[p_fp_info->hsdsch_macflowd_id];/*Faked logical channel id 255 used as a mark it doesnt exists...*/
3143 macinf->fake_chid[i] = TRUE; /**/
3144 macinf->macdflow_id[i] = p_fp_info->hsdsch_macflowd_id; /*Save the flow ID (+1 to make it human readable (it's zero indexed!))*/
3145 /*Figure out RLC_MODE based on MACd-flow-ID, basically MACd-flow-ID = 0 then it's SRB0 == UM else AM*/
3146 rlcinf->mode[i] = hsdsch_macdflow_id_rlc_map[p_fp_info->hsdsch_macflowd_id];
3149 /*Check if this is multiplexed (signaled by RRC)*/
3150 if( /*!rlc_is_ciphered(pinfo) &&*/ p_fp_info->hsdhsch_macfdlow_is_mux[p_fp_info->hsdsch_macflowd_id] ){
3151 macinf->ctmux[i] = TRUE;
3152 }else if(p_fp_info->hsdsch_macflowd_id == 0){ /*MACd-flow = 0 is often SRB */
3153 expert_add_info(pinfo, NULL, &ei_fp_maybe_srb);
3154 }else{
3155 macinf->ctmux[i] = FALSE; /*Either it's multiplexed and not signled or it's not MUX*/
3157 rlcinf->urnti[i] = p_fp_info->com_context_id;
3158 rlcinf->li_size[i] = RLC_LI_7BITS;
3159 rlcinf->deciphered[i] = FALSE;
3160 rlcinf->ciphered[i] = FALSE;
3161 rlcinf->rbid[i] = macinf->lchid[i];
3163 /*When a flow has been reconfigured rlc needs to be reset.
3164 * This needs more work though since we must figure out when the re-configuration becomes
3165 * active based on the CFN value
3166 * */
3167 #if 0
3168 /*Indicate we need to reset stream*/
3169 if(p_fp_info->reset_frag){
3170 rlc_reset_channel(rlcinf->mode[i], macinf->lchid[i], p_fp_info->is_uplink, rlcinf->urnti[i] );
3171 p_fp_info->reset_frag = FALSE;
3174 #endif
3178 /* MAC-d PDUs */
3179 offset = dissect_macd_pdu_data(tvb, pinfo, tree, offset, pdu_length,
3180 number_of_pdus,p_fp_info);
3182 col_append_fstr(pinfo->cinfo, COL_INFO, " %ux%u-bit PDUs User-Buffer-Size=%u",
3183 number_of_pdus, pdu_length, user_buffer_size);
3185 /* Extra IEs (if there is room for them) */
3186 if (((p_fp_info->release == 6) ||
3187 (p_fp_info->release == 7)) &&
3188 (tvb_length_remaining(tvb, offset) > 2)) {
3190 int n;
3191 guint8 flags;
3192 /* guint8 flag_bytes = 0; */
3194 /* New IE flags */
3195 do {
3196 proto_item *new_ie_flags_ti;
3197 proto_tree *new_ie_flags_tree;
3198 guint ies_found = 0;
3200 /* Add new IE flags subtree */
3201 new_ie_flags_ti = proto_tree_add_string_format(tree, hf_fp_hsdsch_new_ie_flags, tvb, offset, 1,
3202 "", "New IE flags");
3203 new_ie_flags_tree = proto_item_add_subtree(new_ie_flags_ti, ett_fp_hsdsch_new_ie_flags);
3205 /* Read next byte */
3206 flags = tvb_get_guint8(tvb, offset);
3207 /* flag_bytes++; */
3209 /* Dissect individual bits */
3210 for (n=0; n < 8; n++) {
3211 proto_tree_add_item(new_ie_flags_tree, hf_fp_hsdsch_new_ie_flag[n], tvb, offset, 1, ENC_BIG_ENDIAN);
3212 if ((flags >> (7-n)) & 0x01) {
3213 ies_found++;
3216 offset++;
3218 proto_item_append_text(new_ie_flags_ti, " (%u IEs found)", ies_found);
3220 /* Last bit set will indicate another flags byte follows... */
3221 } while (0); /*((flags & 0x01) && (flag_bytes < 31));*/
3223 if (1) /*(flags & 0x8) */ {
3224 /* DRT is shown as mandatory in the diagram (3GPP TS 25.435 V6.3.0),
3225 but the description below it states that
3226 it should depend upon the first bit. The detailed description of
3227 New IE flags doesn't agree, so treat as mandatory for now... */
3228 proto_tree_add_item(tree, hf_fp_hsdsch_drt, tvb, offset, 2, ENC_BIG_ENDIAN);
3229 offset += 2;
3232 if (preferences_header_checksum) {
3233 verify_header_crc(tvb, pinfo, header_crc_pi, header_crc, header_length);
3235 /* Spare Extension and Payload CRC */
3236 dissect_spare_extension_and_crc(tvb, pinfo, tree, 1, offset, header_length);
3241 /******************************************/
3242 /* Dissect an HSDSCH type 2 channel */
3243 /* (introduced in Release 7) */
3244 /* N.B. there is currently no support for */
3245 /* frame type 3 (IuR only?) */
3246 static void
3247 dissect_hsdsch_type_2_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
3248 int offset, struct fp_info *p_fp_info)
3250 gboolean is_control_frame;
3251 guint16 header_crc = 0;
3252 proto_item * header_crc_pi = NULL;
3253 guint16 header_length = 0;
3255 /* Header CRC */
3256 header_crc = tvb_get_bits8(tvb, 0, 7);
3257 header_crc_pi = proto_tree_add_item(tree, hf_fp_header_crc, tvb, offset, 1, ENC_BIG_ENDIAN);
3259 /* Frame Type */
3260 is_control_frame = tvb_get_guint8(tvb, offset) & 0x01;
3261 proto_tree_add_item(tree, hf_fp_ft, tvb, offset, 1, ENC_BIG_ENDIAN);
3262 offset++;
3264 col_append_str(pinfo->cinfo, COL_INFO, is_control_frame ? " [Control] " : " [Data] ");
3266 if (is_control_frame) {
3267 dissect_common_control(tvb, pinfo, tree, offset, p_fp_info);
3268 /* For control frame the header CRC is actually frame CRC covering all
3269 * bytes except the first */
3270 if (preferences_header_checksum) {
3271 verify_control_frame_crc(tvb, pinfo, header_crc_pi, header_crc);
3274 else {
3275 guint8 number_of_pdu_blocks;
3276 gboolean drt_present = FALSE;
3277 gboolean fach_present = FALSE;
3278 guint16 user_buffer_size;
3279 int n;
3280 guint j;
3282 #define MAX_PDU_BLOCKS 31
3283 guint64 lchid[MAX_PDU_BLOCKS];
3284 guint64 pdu_length[MAX_PDU_BLOCKS];
3285 guint64 no_of_pdus[MAX_PDU_BLOCKS];
3287 umts_mac_info *macinf;
3288 rlc_info *rlcinf;
3290 rlcinf = (rlc_info *)p_get_proto_data(pinfo->fd, proto_rlc, 0);
3291 macinf = (umts_mac_info *)p_get_proto_data(pinfo->fd, proto_umts_mac, 0);
3292 /********************************/
3293 /* HS-DCH type 2 data here */
3295 col_append_str(pinfo->cinfo, COL_INFO, "(ehs)");
3297 /* Frame Seq Nr (4 bits) */
3298 if ((p_fp_info->release == 6) ||
3299 (p_fp_info->release == 7)) {
3301 guint8 frame_seq_no = (tvb_get_guint8(tvb, offset) & 0xf0) >> 4;
3302 proto_tree_add_item(tree, hf_fp_frame_seq_nr, tvb, offset, 1, ENC_BIG_ENDIAN);
3304 col_append_fstr(pinfo->cinfo, COL_INFO, " seqno=%u", frame_seq_no);
3307 /* CmCH-PI (4 bits) */
3308 proto_tree_add_item(tree, hf_fp_cmch_pi, tvb, offset, 1, ENC_BIG_ENDIAN);
3309 offset++;
3311 /* Total number of PDU blocks (5 bits) */
3312 number_of_pdu_blocks = (tvb_get_guint8(tvb, offset) >> 3);
3313 proto_tree_add_item(tree, hf_fp_total_pdu_blocks, tvb, offset, 1, ENC_BIG_ENDIAN);
3315 if (p_fp_info->release == 7) {
3316 /* Flush bit */
3317 proto_tree_add_item(tree, hf_fp_flush, tvb, offset, 1, ENC_BIG_ENDIAN);
3319 /* FSN/DRT reset bit */
3320 proto_tree_add_item(tree, hf_fp_fsn_drt_reset, tvb, offset, 1, ENC_BIG_ENDIAN);
3322 /* DRT Indicator */
3323 drt_present = tvb_get_guint8(tvb, offset) & 0x01;
3324 proto_tree_add_item(tree, hf_fp_drt_indicator, tvb, offset, 1, ENC_BIG_ENDIAN);
3326 offset++;
3328 /* FACH Indicator flag */
3329 fach_present = (tvb_get_guint8(tvb, offset) & 0x80) >> 7;
3330 proto_tree_add_item(tree, hf_fp_fach_indicator, tvb, offset, 1, ENC_BIG_ENDIAN);
3331 offset++;
3333 /* User buffer size */
3334 user_buffer_size = tvb_get_ntohs(tvb, offset);
3335 proto_tree_add_item(tree, hf_fp_user_buffer_size, tvb, offset, 2, ENC_BIG_ENDIAN);
3336 offset += 2;
3338 col_append_fstr(pinfo->cinfo, COL_INFO, " User-Buffer-Size=%u", user_buffer_size);
3342 /********************************************************************/
3343 /* Now read number_of_pdu_blocks header entries */
3344 for (n=0; n < number_of_pdu_blocks; n++) {
3345 proto_item *pdu_block_header_ti;
3346 proto_tree *pdu_block_header_tree;
3347 int block_header_start_offset = offset;
3349 /* Add PDU block header subtree */
3350 pdu_block_header_ti = proto_tree_add_string_format(tree, hf_fp_hsdsch_pdu_block_header,
3351 tvb, offset, 0,
3353 "PDU Block Header");
3354 pdu_block_header_tree = proto_item_add_subtree(pdu_block_header_ti,
3355 ett_fp_hsdsch_pdu_block_header);
3357 /* MAC-d/c PDU length in this block (11 bits) */
3358 proto_tree_add_bits_ret_val(pdu_block_header_tree, hf_fp_pdu_length_in_block, tvb,
3359 (offset*8) + ((n % 2) ? 4 : 0), 11,
3360 &pdu_length[n], ENC_BIG_ENDIAN);
3361 if ((n % 2) == 0)
3362 offset++;
3363 else
3364 offset += 2;
3367 /* # PDUs in this block (4 bits) */
3368 proto_tree_add_bits_ret_val(pdu_block_header_tree, hf_fp_pdus_in_block, tvb,
3369 (offset*8) + ((n % 2) ? 0 : 4), 4,
3370 &no_of_pdus[n], ENC_BIG_ENDIAN);
3371 if ((n % 2) == 0) {
3372 offset++;
3375 /* Logical channel ID in block (4 bits) */
3376 proto_tree_add_bits_ret_val(pdu_block_header_tree, hf_fp_lchid, tvb,
3377 (offset*8) + ((n % 2) ? 4 : 0), 4,
3378 &lchid[n], ENC_BIG_ENDIAN);
3379 if ((n % 2) == 1) {
3380 offset++;
3382 else {
3383 if (n == (number_of_pdu_blocks-1)) {
3384 /* Byte is padded out for last block */
3385 offset++;
3389 /* Append summary to header tree root */
3390 proto_item_append_text(pdu_block_header_ti,
3391 " (lch:%u, %u pdus of %u bytes)",
3392 (guint16)lchid[n],
3393 (guint16)no_of_pdus[n],
3394 (guint16)pdu_length[n]);
3396 /* Set length of header tree item */
3397 if (((n % 2) == 0) && (n < (number_of_pdu_blocks-1))) {
3398 proto_item_set_len(pdu_block_header_ti,
3399 offset - block_header_start_offset+1);
3401 else {
3402 proto_item_set_len(pdu_block_header_ti,
3403 offset - block_header_start_offset);
3407 if (header_length == 0) {
3408 header_length = offset;
3410 /**********************************************/
3411 /* Optional fields indicated by earlier flags */
3412 if (drt_present) {
3413 /* DRT */
3414 proto_tree_add_item(tree, hf_fp_drt, tvb, offset, 2, ENC_BIG_ENDIAN);
3415 offset += 2;
3418 if (fach_present) {
3419 /* H-RNTI: */
3420 proto_tree_add_item(tree, hf_fp_hrnti, tvb, offset, 2, ENC_BIG_ENDIAN);
3421 offset += 2;
3423 /* RACH Measurement Result */
3424 proto_tree_add_item(tree, hf_fp_rach_measurement_result, tvb, offset, 2, ENC_BIG_ENDIAN);
3425 offset++;
3429 /********************************************************************/
3430 /* Now read the MAC-d/c PDUs for each block using info from headers */
3431 for (n=0; n < number_of_pdu_blocks; n++) {
3432 for(j=0;j<no_of_pdus[n];j++){
3434 /*Configure (signal to lower layers) the PDU!*/
3435 macinf->content[j] = lchId_type_table[lchid[n]+1];/*hsdsch_macdflow_id_mac_content_map[p_fp_info->hsdsch_macflowd_id];*/ /*MAC_CONTENT_PS_DTCH;*/
3436 macinf->lchid[j] = (guint8)lchid[n]+1; /*Add 1 since C/T is zero indexed? ie C/T =0 => L-CHID = 1*/
3437 macinf->macdflow_id[j] = p_fp_info->hsdsch_macflowd_id;
3438 /*Figure out RLC_MODE based on MACd-flow-ID, basically MACd-flow-ID = 0 then it's SRB0 == UM else AM*/
3439 rlcinf->mode[j] = lchId_rlc_map[lchid[n]+1];/*hsdsch_macdflow_id_rlc_map[p_fp_info->hsdsch_macflowd_id];*/
3441 macinf->ctmux[n] = FALSE;
3443 rlcinf->li_size[j] = RLC_LI_7BITS;
3445 /** Configure ciphering **/
3446 /*If this entry exists, SECRUITY_MODE is completed*/
3447 /* if( rrc_ciph_inf && g_tree_lookup(rrc_ciph_inf, GINT_TO_POINTER((gint)p_fp_info->com_context_id)) ){
3448 rlcinf->ciphered[j] = TRUE;
3449 }else{
3450 rlcinf->ciphered[j] = FALSE;
3452 rlcinf->ciphered[j] = FALSE;
3453 rlcinf->deciphered[j] = FALSE;
3454 rlcinf->rbid[j] = (guint8)lchid[n]+1;
3456 rlcinf->urnti[j] = p_fp_info->com_context_id; /*Set URNIT to comuncation context id*/
3459 /* Add PDU block header subtree */
3460 offset = dissect_macd_pdu_data_type_2(tvb, pinfo, tree, offset,
3461 (guint16)pdu_length[n],
3462 (guint16)no_of_pdus[n],p_fp_info);
3464 if (preferences_header_checksum) {
3465 verify_header_crc(tvb, pinfo, header_crc_pi, header_crc, header_length);
3467 /* Spare Extension and Payload CRC */
3468 dissect_spare_extension_and_crc(tvb, pinfo, tree, 1, offset, header_length);
3472 * Dissect and CONFIGURE hsdsch_common channel.
3474 * This will dissect hsdsch common channels of type 2, so this is
3475 * very similar to regular type two (ehs) the difference being how
3476 * the configuration is done. NOTE: VERY EXPERIMENTAL.
3478 * @param tvb the tv buffer of the current data
3479 * @param pinfo the packet info of the current data
3480 * @param tree the tree to append this item to
3481 * @param offset the offset in the tvb
3482 * @param p_fp_info FP-packet information
3484 static
3485 void dissect_hsdsch_common_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
3486 int offset, struct fp_info *p_fp_info){
3487 gboolean is_control_frame;
3488 guint16 header_crc = 0;
3489 proto_item * header_crc_pi = NULL;
3490 guint header_length = 0;
3492 /* Header CRC */
3493 header_crc = tvb_get_bits8(tvb, 0, 7);
3494 header_crc_pi = proto_tree_add_item(tree, hf_fp_header_crc, tvb, offset, 1, ENC_BIG_ENDIAN);
3496 /* Frame Type */
3497 is_control_frame = tvb_get_guint8(tvb, offset) & 0x01;
3498 proto_tree_add_item(tree, hf_fp_ft, tvb, offset, 1, ENC_BIG_ENDIAN);
3499 offset++;
3501 col_append_str(pinfo->cinfo, COL_INFO, is_control_frame ? " [Control] " : " [Data] ");
3503 if (is_control_frame) {
3504 dissect_common_control(tvb, pinfo, tree, offset, p_fp_info);
3505 /* For control frame the header CRC is actually frame CRC covering all
3506 * bytes except the first */
3507 if (preferences_header_checksum) {
3508 verify_control_frame_crc(tvb, pinfo, header_crc_pi, header_crc);
3511 else {
3512 guint8 number_of_pdu_blocks;
3513 gboolean drt_present = FALSE;
3514 gboolean fach_present = FALSE;
3515 guint16 user_buffer_size;
3516 int n;
3517 guint j;
3519 #define MAX_PDU_BLOCKS 31
3520 guint64 lchid[MAX_PDU_BLOCKS];
3521 guint64 pdu_length[MAX_PDU_BLOCKS];
3522 guint64 no_of_pdus[MAX_PDU_BLOCKS];
3523 guint8 newieflags = 0;
3525 umts_mac_info *macinf;
3526 rlc_info *rlcinf;
3528 rlcinf = (rlc_info *)p_get_proto_data(pinfo->fd, proto_rlc, 0);
3529 macinf = (umts_mac_info *)p_get_proto_data(pinfo->fd, proto_umts_mac, 0);
3530 /********************************/
3531 /* HS-DCH type 2 data here */
3533 col_append_str(pinfo->cinfo, COL_INFO, "(ehs)");
3535 /* Frame Seq Nr (4 bits) */
3536 if ((p_fp_info->release == 6) ||
3537 (p_fp_info->release == 7)) {
3539 guint8 frame_seq_no = (tvb_get_guint8(tvb, offset) & 0xf0) >> 4;
3540 proto_tree_add_item(tree, hf_fp_frame_seq_nr, tvb, offset, 1, ENC_BIG_ENDIAN);
3542 col_append_fstr(pinfo->cinfo, COL_INFO, " seqno=%u", frame_seq_no);
3545 /* CmCH-PI (4 bits) */
3546 proto_tree_add_item(tree, hf_fp_cmch_pi, tvb, offset, 1, ENC_BIG_ENDIAN);
3547 offset++;
3549 /* Total number of PDU blocks (5 bits) */
3550 number_of_pdu_blocks = (tvb_get_guint8(tvb, offset) >> 3);
3551 proto_tree_add_item(tree, hf_fp_total_pdu_blocks, tvb, offset, 1, ENC_BIG_ENDIAN);
3553 if (p_fp_info->release == 7) {
3554 /* Flush bit */
3555 proto_tree_add_item(tree, hf_fp_flush, tvb, offset, 1, ENC_BIG_ENDIAN);
3557 /* FSN/DRT reset bit */
3558 proto_tree_add_item(tree, hf_fp_fsn_drt_reset, tvb, offset, 1, ENC_BIG_ENDIAN);
3560 /* DRT Indicator */
3561 drt_present = tvb_get_guint8(tvb, offset) & 0x01;
3562 proto_tree_add_item(tree, hf_fp_drt_indicator, tvb, offset, 1, ENC_BIG_ENDIAN);
3564 offset++;
3566 /* FACH Indicator flag */
3567 fach_present = (tvb_get_guint8(tvb, offset) & 0x80) >> 7;
3568 proto_tree_add_item(tree, hf_fp_fach_indicator, tvb, offset, 1, ENC_BIG_ENDIAN);
3569 offset++;
3571 /* User buffer size */
3572 user_buffer_size = tvb_get_ntohs(tvb, offset);
3573 proto_tree_add_item(tree, hf_fp_user_buffer_size, tvb, offset, 2, ENC_BIG_ENDIAN);
3574 offset += 2;
3576 col_append_fstr(pinfo->cinfo, COL_INFO, " User-Buffer-Size=%u", user_buffer_size);
3579 /********************************************************************/
3580 /* Now read number_of_pdu_blocks header entries */
3581 for (n=0; n < number_of_pdu_blocks; n++) {
3582 proto_item *pdu_block_header_ti;
3583 proto_tree *pdu_block_header_tree;
3584 int block_header_start_offset = offset;
3586 /* Add PDU block header subtree */
3587 pdu_block_header_ti = proto_tree_add_string_format(tree, hf_fp_hsdsch_pdu_block_header,
3588 tvb, offset, 0,
3590 "PDU Block Header");
3591 pdu_block_header_tree = proto_item_add_subtree(pdu_block_header_ti,
3592 ett_fp_hsdsch_pdu_block_header);
3594 /* MAC-d/c PDU length in this block (11 bits) */
3595 proto_tree_add_bits_ret_val(pdu_block_header_tree, hf_fp_pdu_length_in_block, tvb,
3596 (offset*8) + ((n % 2) ? 4 : 0), 11,
3597 &pdu_length[n], ENC_BIG_ENDIAN);
3598 if ((n % 2) == 0)
3599 offset++;
3600 else
3601 offset += 2;
3604 /* # PDUs in this block (4 bits) */
3605 proto_tree_add_bits_ret_val(pdu_block_header_tree, hf_fp_pdus_in_block, tvb,
3606 (offset*8) + ((n % 2) ? 0 : 4), 4,
3607 &no_of_pdus[n], ENC_BIG_ENDIAN);
3608 if ((n % 2) == 0) {
3609 offset++;
3612 /* Logical channel ID in block (4 bits) */
3613 proto_tree_add_bits_ret_val(pdu_block_header_tree, hf_fp_lchid, tvb,
3614 (offset*8) + ((n % 2) ? 4 : 0), 4,
3615 &lchid[n], ENC_BIG_ENDIAN);
3616 if ((n % 2) == 1) {
3617 offset++;
3619 else {
3620 if (n == (number_of_pdu_blocks-1)) {
3621 /* Byte is padded out for last block */
3622 offset++;
3626 /* Append summary to header tree root */
3627 proto_item_append_text(pdu_block_header_ti,
3628 " (lch:%u, %u pdus of %u bytes)",
3629 (guint16)lchid[n],
3630 (guint16)no_of_pdus[n],
3631 (guint16)pdu_length[n]);
3633 /* Set length of header tree item */
3634 if (((n % 2) == 0) && (n < (number_of_pdu_blocks-1))) {
3635 proto_item_set_len(pdu_block_header_ti,
3636 offset - block_header_start_offset+1);
3638 else {
3639 proto_item_set_len(pdu_block_header_ti,
3640 offset - block_header_start_offset);
3643 if (header_length == 0) {
3644 header_length = offset;
3647 /**********************************************/
3648 /* Optional fields indicated by earlier flags */
3649 if (drt_present) {
3650 /* DRT */
3651 proto_tree_add_item(tree, hf_fp_drt, tvb, offset, 2, ENC_BIG_ENDIAN);
3652 offset += 2;
3655 if (fach_present) {
3656 /* H-RNTI: */
3657 proto_tree_add_item(tree, hf_fp_hrnti, tvb, offset, 2, ENC_BIG_ENDIAN);
3658 offset += 2;
3660 /* RACH Measurement Result */
3661 proto_tree_add_item(tree, hf_fp_rach_measurement_result, tvb, offset, 1, ENC_BIG_ENDIAN);
3662 offset++;
3665 /********************************************************************/
3666 /* Now read the MAC-d/c PDUs for each block using info from headers */
3667 for (n=0; n < number_of_pdu_blocks; n++) {
3668 tvbuff_t * next_tvb;
3669 for(j=0;j<no_of_pdus[n];j++){
3670 /* If all bits are set, then this is BCCH or PCCH according to: 25.435 paragraph: 6.2.7.31 */
3671 if(lchid[n] == 0xF) {
3672 /* In the very few test cases I've seen, this seems to be
3673 * BCCH with transparent MAC layer. Therefore skip right to
3674 * rlc_bcch and hope for the best. */
3675 next_tvb = tvb_new_subset(tvb, offset, (gint)pdu_length[n], (gint)pdu_length[n]);
3676 call_dissector(rlc_bcch_handle, next_tvb, pinfo, top_level_tree);
3677 offset += (gint)pdu_length[n];
3678 } else { /* Else go for CCCH UM, this seems to work. */
3679 p_fp_info->hsdsch_entity = ehs; /* HSDSCH type 2 */
3680 /* TODO: use cur_tb or subnum everywhere. */
3681 p_fp_info->cur_tb = j; /* set cur_tb for MAC */
3682 pinfo->fd->subnum = j; /* set subframe number for RRC */
3683 macinf->content[j] = MAC_CONTENT_CCCH;
3684 macinf->lchid[j] = (guint8)lchid[n]+1; /*Add 1 since it is zero indexed? */
3685 macinf->macdflow_id[j] = p_fp_info->hsdsch_macflowd_id;
3686 macinf->ctmux[j] = FALSE;
3692 rlcinf->li_size[j] = RLC_LI_7BITS;
3693 rlcinf->ciphered[j] = FALSE;
3694 rlcinf->deciphered[j] = FALSE;
3695 rlcinf->rbid[j] = (guint8)lchid[n]+1;
3696 rlcinf->urnti[j] = p_fp_info->channel; /*We need to fake urnti*/
3698 next_tvb = tvb_new_subset(tvb, offset, (gint)pdu_length[n], (gint)pdu_length[n]);
3699 call_dissector(mac_fdd_hsdsch_handle, next_tvb, pinfo, top_level_tree);
3704 offset += (gint)pdu_length[n];
3709 /* New IE Flags */
3710 newieflags = tvb_get_guint8(tvb, offset);
3711 /* If newieflags == 0000 0010 then this indicates that there is a
3712 * HS-DSCH physical layer category and no other New IE flags. */
3713 if (newieflags == 2) {
3714 /* HS-DSCH physical layer category presence bit. */
3715 proto_tree_add_uint(tree, hf_fp_hsdsch_new_ie_flag[6], tvb, offset, 1, newieflags);
3716 offset++;
3717 /* HS-DSCH physical layer category. */
3718 proto_tree_add_bits_item(tree, hf_fp_hsdsch_physical_layer_category, tvb, offset*8, 6, ENC_BIG_ENDIAN);
3719 offset++;
3721 if (preferences_header_checksum) {
3722 verify_header_crc(tvb, pinfo, header_crc_pi, header_crc, header_length);
3724 /* Spare Extension and Payload CRC */
3725 dissect_spare_extension_and_crc(tvb, pinfo, tree, 1, offset, header_length);
3728 static gboolean
3729 heur_dissect_fp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
3731 struct fp_info *p_fp_info;
3733 if (!preferences_udp_do_heur) {
3734 return FALSE;
3737 p_fp_info = (fp_info *)p_get_proto_data(pinfo->fd, proto_fp, 0);
3739 /* if no FP info is present, this might be FP in a pcap(ng) file */
3740 if (!p_fp_info) {
3741 /* We only know the header length of control frames, so check that bit first */
3742 int offset = 0, length;
3743 guint8 oct, calc_crc = 0, crc;
3744 unsigned char *buf;
3746 oct = tvb_get_guint8(tvb, offset);
3747 crc = oct & 0xfe;
3748 if ((oct & 0x01) == 1){
3750 * 6.3.2.1 Frame CRC
3751 * Description: It is the result of the CRC applied to the remaining part of the frame,
3752 * i.e. from bit 0 of the first byte of the header (the FT IE) to bit 0 of the last byte of the payload,
3753 * with the corresponding generator polynomial: G(D) = D7+D6+D2+1. See subclause 7.2.
3755 length = tvb_length(tvb);
3756 buf = (unsigned char *)tvb_memdup(wmem_packet_scope(), tvb, 0, length);
3757 buf[0] = 01;
3759 calc_crc = crc7update(calc_crc, buf, length);
3760 if(calc_crc == crc){
3761 /* assume this is FP, set conversatio dissector to catch the data frames too */
3762 conversation_set_dissector(find_or_create_conversation(pinfo), fp_handle);
3763 dissect_fp(tvb, pinfo, tree);
3764 return TRUE;
3767 return FALSE;
3770 /* if FP info is present, check that it really is an ethernet link */
3771 if (p_fp_info->link_type != FP_Link_Ethernet) {
3772 return FALSE;
3775 /* discriminate 'lower' UDP layer from 'user data' UDP layer
3776 * (i.e. if an FP over UDP packet contains a user UDP packet */
3777 if (p_fp_info->srcport != pinfo->srcport ||
3778 p_fp_info->destport != pinfo->destport)
3779 return FALSE;
3781 /* assume this is FP */
3782 dissect_fp(tvb, pinfo, tree);
3783 return TRUE;
3785 static guint8 fakes =5; /*[] ={1,5,8};*/
3786 static guint8 fake_map[31];
3789 * TODO: This need to be fixed!
3790 * Basically you would want the actual RRC messages, that sooner or later maps
3791 * transport channel id's to logical id's or RAB IDs
3792 * to set the proper logical channel/RAB ID, but for now we make syntethic ones.
3793 * */
3795 static guint8
3796 make_fake_lchid(packet_info *pinfo _U_, gint trchld)
3798 if( fake_map[trchld] == 0){
3799 fake_map[trchld] = fakes;
3800 fakes++;
3802 return fake_map[trchld];
3806 * july 2012:
3807 * Alot of configuration has been move into the actual dissecting functions
3808 * since most of the configuration/signalign has to be set per tb (pdu) rather
3809 * for the channel!
3811 static fp_info *
3812 fp_set_per_packet_inf_from_conv(umts_fp_conversation_info_t *p_conv_data,
3813 tvbuff_t *tvb, packet_info *pinfo,
3814 proto_tree *tree _U_)
3816 fp_info *fpi;
3817 guint8 tfi, c_t;
3818 int offset = 0, i=0,j=0,num_tbs,chan,tb_size, tb_bit_off;
3819 gboolean is_control_frame;
3820 umts_mac_info *macinf;
3821 rlc_info *rlcinf;
3822 guint8 fake_lchid=0;
3823 gint *cur_val=NULL;
3825 fpi = wmem_new0(wmem_file_scope(), fp_info);
3826 p_add_proto_data(pinfo->fd, proto_fp, 0, fpi);
3828 fpi->iface_type = p_conv_data->iface_type;
3829 fpi->division = p_conv_data->division;
3830 fpi->release = 7; /* Set values greater then the checks performed */
3831 fpi->release_year = 2006;
3832 fpi->release_month = 12;
3833 fpi->channel = p_conv_data->channel;
3834 fpi->dch_crc_present = p_conv_data->dch_crc_present;
3835 /*fpi->paging_indications;*/
3836 fpi->link_type = FP_Link_Ethernet;
3838 #if 0
3839 /*Only do this the first run, signals that we need to reset the RLC fragtable*/
3840 if(!pinfo->fd->flags.visited && p_conv_data->reset_frag ){
3841 fpi->reset_frag = p_conv_data->reset_frag;
3842 p_conv_data->reset_frag = FALSE;
3844 #endif
3845 /* remember 'lower' UDP layer port information so we can later
3846 * differentiate 'lower' UDP layer from 'user data' UDP layer */
3847 fpi->srcport = pinfo->srcport;
3848 fpi->destport = pinfo->destport;
3850 fpi->com_context_id = p_conv_data->com_context_id;
3852 if (pinfo->link_dir==P2P_DIR_UL) {
3853 fpi->is_uplink = TRUE;
3854 } else {
3855 fpi->is_uplink = FALSE;
3858 is_control_frame = tvb_get_guint8(tvb, offset) & 0x01;
3860 switch (fpi->channel) {
3861 case CHANNEL_HSDSCH: /* HS-DSCH - High Speed Downlink Shared Channel */
3862 fpi->hsdsch_entity = p_conv_data->hsdsch_entity;
3863 macinf = wmem_new0(wmem_file_scope(), umts_mac_info);
3864 fpi->hsdsch_macflowd_id = p_conv_data->hsdsch_macdflow_id;
3865 macinf->content[0] = hsdsch_macdflow_id_mac_content_map[p_conv_data->hsdsch_macdflow_id]; /*MAC_CONTENT_PS_DTCH;*/
3866 macinf->lchid[0] = p_conv_data->hsdsch_macdflow_id;
3867 /*macinf->content[0] = lchId_type_table[p_conv_data->edch_lchId[0]];*/
3868 p_add_proto_data(pinfo->fd, proto_umts_mac, 0, macinf);
3870 rlcinf = wmem_new0(wmem_file_scope(), rlc_info);
3872 /*Figure out RLC_MODE based on MACd-flow-ID, basically MACd-flow-ID = 0 then it's SRB0 == UM else AM*/
3873 rlcinf->mode[0] = hsdsch_macdflow_id_rlc_map[p_conv_data->hsdsch_macdflow_id];
3875 if(fpi->hsdsch_entity == hs /*&& !rlc_is_ciphered(pinfo)*/){
3876 for(i=0; i<MAX_NUM_HSDHSCH_MACDFLOW; i++){
3877 /*Figure out if this channel is multiplexed (signaled from RRC)*/
3878 if((cur_val=(gint *)g_tree_lookup(hsdsch_muxed_flows, GINT_TO_POINTER((gint)p_conv_data->hrnti))) != NULL){
3879 j = 1 << i;
3880 fpi->hsdhsch_macfdlow_is_mux[i] = j & *cur_val;
3881 }else{
3882 fpi->hsdhsch_macfdlow_is_mux[i] = FALSE;
3887 /* Make configurable ?(available in NBAP?) */
3888 /* urnti[MAX_RLC_CHANS] */
3890 switch (p_conv_data->rlc_mode) {
3891 case FP_RLC_TM:
3892 rlcinf->mode[0] = RLC_TM;
3893 break;
3894 case FP_RLC_UM:
3895 rlcinf->mode[0] = RLC_UM;
3896 break;
3897 case FP_RLC_AM:
3898 rlcinf->mode[0] = RLC_AM;
3899 break;
3900 case FP_RLC_MODE_UNKNOWN:
3901 default:
3902 rlcinf->mode[0] = RLC_UNKNOWN_MODE;
3903 break;
3905 /* rbid[MAX_RLC_CHANS] */
3906 /* For RLC re-assembly to work we urnti signaled from NBAP */
3907 rlcinf->urnti[0] = fpi->com_context_id;
3908 rlcinf->li_size[0] = RLC_LI_7BITS;
3909 rlcinf->ciphered[0] = FALSE;
3910 rlcinf->deciphered[0] = FALSE;
3911 p_add_proto_data(pinfo->fd, proto_rlc, 0, rlcinf);
3914 return fpi;
3916 case CHANNEL_EDCH:
3917 /*Most configuration is now done in the actual dissecting function*/
3918 macinf = wmem_new0(wmem_file_scope(), umts_mac_info);
3919 rlcinf = wmem_new0(wmem_file_scope(), rlc_info);
3920 fpi->no_ddi_entries = p_conv_data->no_ddi_entries;
3921 for (i=0; i<fpi->no_ddi_entries; i++) {
3922 fpi->edch_ddi[i] = p_conv_data->edch_ddi[i]; /*Set the DDI value*/
3923 fpi->edch_macd_pdu_size[i] = p_conv_data->edch_macd_pdu_size[i]; /*Set the size*/
3924 fpi->edch_lchId[i] = p_conv_data->edch_lchId[i]; /*Set the channel id for this entry*/
3925 /*macinf->content[i] = lchId_type_table[p_conv_data->edch_lchId[i]]; */ /*Set the proper Content type for the mac layer.*/
3926 /* rlcinf->mode[i] = lchId_rlc_map[p_conv_data->edch_lchId[i]];*/ /* Set RLC mode by lchid to RLC_MODE map in nbap.h */
3929 fpi->edch_type = p_conv_data->edch_type;
3931 /* macinf = wmem_new0(wmem_file_scope(), umts_mac_info);
3932 macinf->content[0] = MAC_CONTENT_PS_DTCH;*/
3933 p_add_proto_data(pinfo->fd, proto_umts_mac, 0, macinf);
3936 /* For RLC re-assembly to work we need a urnti signaled from NBAP */
3937 rlcinf->urnti[0] = fpi->com_context_id;
3938 /* rlcinf->mode[0] = RLC_AM;*/
3939 rlcinf->li_size[0] = RLC_LI_7BITS;
3940 rlcinf->ciphered[0] = FALSE;
3941 rlcinf->deciphered[0] = FALSE;
3943 p_add_proto_data(pinfo->fd, proto_rlc, 0, rlcinf);
3945 return fpi;
3947 case CHANNEL_PCH:
3948 fpi->paging_indications = p_conv_data->paging_indications;
3949 fpi->num_chans = p_conv_data->num_dch_in_flow;
3950 /* Set offset to point to first TFI
3952 if (is_control_frame) {
3953 /* control frame, we're done */
3954 return fpi;
3956 /* Set offset to TFI */
3957 offset = 3;
3958 break;
3959 case CHANNEL_DCH:
3960 fpi->num_chans = p_conv_data->num_dch_in_flow;
3961 if (is_control_frame) {
3962 /* control frame, we're done */
3963 return fpi;
3966 rlcinf = wmem_new0(wmem_file_scope(), rlc_info);
3967 macinf = wmem_new0(wmem_file_scope(), umts_mac_info);
3968 offset = 2; /*To correctly read the tfi*/
3969 fakes = 5; /* Reset fake counter. */
3970 for (chan=0; chan < fpi->num_chans; chan++) { /*Iterate over the what channels*/
3971 /*Iterate over the transport blocks*/
3972 /*tfi = tvb_get_guint8(tvb,offset);*/
3973 /*TFI is 5 bits according to 3GPP TS 25.321, paragraph 6.2.4.4*/
3974 tfi = tvb_get_bits8(tvb,3+offset*8,5);
3976 /*Figure out the number of tbs and size*/
3977 num_tbs = (fpi->is_uplink) ? p_conv_data->fp_dch_channel_info[chan].ul_chan_num_tbs[tfi] : p_conv_data->fp_dch_channel_info[chan].dl_chan_num_tbs[tfi];
3978 tb_size= (fpi->is_uplink) ? p_conv_data->fp_dch_channel_info[i].ul_chan_tf_size[tfi] : p_conv_data->fp_dch_channel_info[i].dl_chan_tf_size[tfi];
3980 /*TODO: This stuff has to be reworked!*/
3981 /*Generates a fake logical channel id for non multiplexed channel*/
3982 if( p_conv_data->dchs_in_flow_list[chan] != 31 && (p_conv_data->dchs_in_flow_list[chan] == 24 &&
3983 tb_size != 340) ){
3984 fake_lchid = make_fake_lchid(pinfo,p_conv_data->dchs_in_flow_list[chan]);
3986 tb_bit_off = (2+p_conv_data->num_dch_in_flow)*8; /*Point to the C/T of first TB*/
3987 /*Set configuration for individual blocks*/
3988 for(j=0; j < num_tbs; j++){
3989 /*Set transport channel id (useful for debugging)*/
3990 macinf->trchid[j+chan] = p_conv_data->dchs_in_flow_list[chan];
3992 /*Transport Channel m31 and 24 might be multiplexed!*/
3993 if( p_conv_data->dchs_in_flow_list[chan] == 31 || p_conv_data->dchs_in_flow_list[chan] == 24){
3995 /****** MUST FIGURE OUT IF THIS IS REALLY MULTIPLEXED OR NOT*******/
3996 /*If Trchid == 31 and only on TB, we have no multiplexing*/
3997 if(0/*p_conv_data->dchs_in_flow_list[chan] == 31 && num_tbs == 1*/){
3998 macinf->ctmux[j+chan] = FALSE;/*Set TRUE if this channel is multiplexed (ie. C/T flag exists)*/
4000 macinf->lchid[j+chan] = 1;
4002 macinf->content[j+chan] = lchId_type_table[1]; /*Base MAC content on logical channel id (Table is in packet-nbap.h)*/
4003 rlcinf->mode[j+chan] = lchId_rlc_map[1]; /*Based RLC mode on logical channel id*/
4006 /*Indicate we don't have multiplexing.*/
4007 else if (p_conv_data->dchs_in_flow_list[chan] == 24 && tb_size != 340){
4008 macinf->ctmux[j+chan] = FALSE;/*Set TRUE if this channel is multiplexed (ie. C/T flag exists)*/
4010 /*g_warning("settin this for %d", pinfo->fd->num);*/
4011 macinf->lchid[j+chan] = fake_lchid;
4012 macinf->fake_chid[j+chan] = TRUE;
4013 macinf->content[j+chan] = MAC_CONTENT_PS_DTCH; /*lchId_type_table[fake_lchid];*/ /*Base MAC content on logical channel id (Table is in packet-nbap.h)*/
4014 rlcinf->mode[j+chan] = RLC_AM;/*lchId_rlc_map[fake_lchid];*/ /*Based RLC mode on logical channel id*/
4016 /*We have multiplexing*/
4017 else{
4018 macinf->ctmux[j+chan] = TRUE;/*Set TRUE if this channel is multiplexed (ie. C/T flag exists)*/
4020 /* Peek at C/T, different RLC params for different logical channels */
4021 /*C/T is 4 bits according to 3GPP TS 25.321, paragraph 9.2.1, from MAC header (not FP)*/
4022 c_t = tvb_get_bits8(tvb, tb_bit_off/*(2+p_conv_data->num_dch_in_flow)*8*/, 4); /* c_t = tvb_get_guint8(tvb,offset);*/
4023 macinf->lchid[j+chan] = c_t+1;
4025 macinf->content[j+chan] = lchId_type_table[c_t+1]; /*Base MAC content on logical channel id (Table is in packet-nbap.h)*/
4026 rlcinf->mode[j+chan] = lchId_rlc_map[c_t+1]; /*Based RLC mode on logical channel id*/
4028 }else{
4029 fake_lchid = make_fake_lchid(pinfo,p_conv_data->dchs_in_flow_list[chan]);
4030 macinf->ctmux[j+chan] = FALSE;/*Set TRUE if this channel is multiplexed (ie. C/T flag exists)*/
4031 /*macinf->content[j+chan] = MAC_CONTENT_CS_DTCH;*/
4032 macinf->content[j+chan] = lchId_type_table[fake_lchid];
4035 rlcinf->mode[j+chan] = lchId_rlc_map[fake_lchid];
4037 /*Generate virtual logical channel id*/
4038 /************************/
4039 /*TODO: Once proper lchid is always set, this has to be removed*/
4040 macinf->fake_chid[j+chan] = TRUE;
4041 macinf->lchid[j+chan] = fake_lchid; /*make_fake_lchid(pinfo, p_conv_data->dchs_in_flow_list[chan]);*/
4042 /************************/
4045 /*** Set rlc info ***/
4046 rlcinf->urnti[j+chan] = p_conv_data->com_context_id;
4047 rlcinf->li_size[j+chan] = RLC_LI_7BITS;
4049 /*If this entry exists, SECRUITY_MODE is completed (signled by RRC)*/
4050 /*if( rrc_ciph_inf && g_tree_lookup(rrc_ciph_inf, GINT_TO_POINTER((gint)p_conv_data->com_context_id)) != NULL ){
4051 rlcinf->ciphered[j+chan] = TRUE;
4052 }else{
4053 rlcinf->ciphered[j+chan] = FALSE;
4055 rlcinf->ciphered[j+chan] = FALSE;
4056 rlcinf->deciphered[j+chan] = FALSE;
4057 rlcinf->rbid[j+chan] = macinf->lchid[j+chan];
4060 /*Step over this TB and it's C/T flag.*/
4061 tb_bit_off += tb_size+4;
4064 offset++;
4066 p_add_proto_data(pinfo->fd, proto_umts_mac, 0, macinf);
4067 p_add_proto_data(pinfo->fd, proto_rlc, 0, rlcinf);
4068 /* Set offset to point to first TFI
4069 * the Number of TFI's = number of DCH's in the flow
4071 offset = 2;
4072 break;
4073 case CHANNEL_FACH_FDD:
4074 fpi->num_chans = p_conv_data->num_dch_in_flow;
4075 if (is_control_frame) {
4076 /* control frame, we're done */
4077 return fpi;
4079 /* Set offset to point to first TFI
4080 * the Number of TFI's = number of DCH's in the flow
4082 offset = 2;
4083 /* Set MAC data */
4084 macinf = wmem_new0(wmem_file_scope(), umts_mac_info);
4085 macinf->ctmux[0] = 1;
4086 macinf->content[0] = MAC_CONTENT_DCCH;
4087 p_add_proto_data(pinfo->fd, proto_umts_mac, 0, macinf);
4088 /* Set RLC data */
4089 rlcinf = wmem_new0(wmem_file_scope(), rlc_info);
4090 /* Make configurable ?(avaliable in NBAP?) */
4091 /* For RLC re-assembly to work we need to fake urnti */
4092 rlcinf->urnti[0] = fpi->channel;
4093 rlcinf->mode[0] = RLC_AM;
4094 /* rbid[MAX_RLC_CHANS] */
4095 rlcinf->li_size[0] = RLC_LI_7BITS;
4096 rlcinf->ciphered[0] = FALSE;
4097 rlcinf->deciphered[0] = FALSE;
4098 p_add_proto_data(pinfo->fd, proto_rlc, 0, rlcinf);
4099 break;
4101 case CHANNEL_RACH_FDD:
4102 fpi->num_chans = p_conv_data->num_dch_in_flow;
4103 if (is_control_frame) {
4104 /* control frame, we're done */
4105 return fpi;
4107 /* Set offset to point to first TFI
4108 * the Number of TFI's = number of DCH's in the flow
4110 offset = 2;
4111 /* set MAC data */
4112 macinf = wmem_new0(wmem_file_scope(), umts_mac_info);
4113 rlcinf = wmem_new0(wmem_file_scope(), rlc_info);
4114 for( chan = 0; chan < fpi->num_chans; chan++ ){
4115 macinf->ctmux[chan] = 1;
4116 macinf->content[chan] = MAC_CONTENT_DCCH;
4117 rlcinf->urnti[chan] = fpi->com_context_id; /*Note that MAC probably will change this*/
4122 p_add_proto_data(pinfo->fd, proto_umts_mac,0, macinf);
4123 p_add_proto_data(pinfo->fd, proto_rlc, 0, rlcinf);
4124 break;
4125 case CHANNEL_HSDSCH_COMMON:
4126 rlcinf = wmem_new0(wmem_file_scope(), rlc_info);
4127 macinf = wmem_new0(wmem_file_scope(), umts_mac_info);
4128 p_add_proto_data(pinfo->fd, proto_umts_mac, 0, macinf);
4129 p_add_proto_data(pinfo->fd, proto_rlc, 0, rlcinf);
4130 break;
4131 default:
4132 expert_add_info(pinfo, NULL, &ei_fp_transport_channel_type_unknown);
4133 return NULL;
4136 /* Peek at the packet as the per packet info seems not to take the tfi into account */
4137 for (i=0; i<fpi->num_chans; i++) {
4138 tfi = tvb_get_guint8(tvb,offset);
4140 /*TFI is 5 bits according to 3GPP TS 25.321, paragraph 6.2.4.4*/
4141 /*tfi = tvb_get_bits8(tvb,offset*8,5);*/
4142 if (pinfo->link_dir==P2P_DIR_UL) {
4143 fpi->chan_tf_size[i] = p_conv_data->fp_dch_channel_info[i].ul_chan_tf_size[tfi];
4144 fpi->chan_num_tbs[i] = p_conv_data->fp_dch_channel_info[i].ul_chan_num_tbs[tfi];
4145 } else {
4146 fpi->chan_tf_size[i] = p_conv_data->fp_dch_channel_info[i].dl_chan_tf_size[tfi];
4147 fpi->chan_num_tbs[i] = p_conv_data->fp_dch_channel_info[i].dl_chan_num_tbs[tfi];
4149 offset++;
4153 return fpi;
4156 /*****************************/
4157 /* Main dissection function. */
4158 static void
4159 dissect_fp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
4161 proto_tree *fp_tree;
4162 proto_item *ti;
4163 gint offset = 0;
4164 struct fp_info *p_fp_info;
4165 rlc_info *rlcinf;
4166 conversation_t *p_conv;
4167 umts_fp_conversation_info_t *p_conv_data = NULL;
4169 /* Append this protocol name rather than replace. */
4170 col_set_str(pinfo->cinfo, COL_PROTOCOL, "FP");
4172 /* Create fp tree. */
4173 ti = proto_tree_add_item(tree, proto_fp, tvb, offset, -1, ENC_NA);
4174 fp_tree = proto_item_add_subtree(ti, ett_fp);
4176 top_level_tree = tree;
4178 /* Look for packet info! */
4179 p_fp_info = (struct fp_info *)p_get_proto_data(pinfo->fd, proto_fp, 0);
4181 /* Check if we have conversation info */
4182 p_conv = (conversation_t *)find_conversation(pinfo->fd->num, &pinfo->net_dst, &pinfo->net_src,
4183 pinfo->ptype,
4184 pinfo->destport, pinfo->srcport, NO_ADDR_B);
4187 if (p_conv) {
4188 /*Find correct conversation, basically find the on thats closest to this frame*/
4189 /*while(p_conv->next != NULL && p_conv->next->setup_frame < pinfo->fd->num){
4190 p_conv = p_conv->next;
4193 p_conv_data = (umts_fp_conversation_info_t *)conversation_get_proto_data(p_conv, proto_fp);
4195 if (p_conv_data) {
4196 /*Figure out the direction of the link*/
4197 if (ADDRESSES_EQUAL(&(pinfo->net_dst), (&p_conv_data->crnc_address))) {
4199 proto_item* item= proto_tree_add_uint(fp_tree, hf_fp_ul_setup_frame,
4200 tvb, 0, 0, p_conv_data->ul_frame_number);
4202 PROTO_ITEM_SET_GENERATED(item);
4203 /* CRNC -> Node B */
4204 pinfo->link_dir=P2P_DIR_UL;
4205 if (p_fp_info == NULL) {
4206 p_fp_info = fp_set_per_packet_inf_from_conv(p_conv_data, tvb, pinfo, fp_tree);
4209 else {
4210 /* Maybe the frame number should be stored in the proper location already in nbap?, in ul_frame_number*/
4211 proto_item* item= proto_tree_add_uint(fp_tree, hf_fp_dl_setup_frame,
4212 tvb, 0, 0, p_conv_data->ul_frame_number);
4214 PROTO_ITEM_SET_GENERATED(item);
4215 pinfo->link_dir=P2P_DIR_DL;
4216 if (p_fp_info == NULL) {
4217 p_fp_info = fp_set_per_packet_inf_from_conv(p_conv_data, tvb, pinfo, fp_tree);
4224 if(pinfo->p2p_dir == P2P_DIR_UNKNOWN){
4225 if(pinfo->link_dir==P2P_DIR_UL) {
4226 pinfo->p2p_dir = P2P_DIR_RECV;
4227 } else {
4228 pinfo->p2p_dir = P2P_DIR_SENT;
4232 /* Can't dissect anything without it... */
4233 if (p_fp_info == NULL) {
4234 ti = proto_tree_add_text(fp_tree, tvb, offset, -1,
4235 "Can't dissect FP frame because no per-frame info was attached!");
4236 PROTO_ITEM_SET_GENERATED(ti);
4237 return;
4240 rlcinf = (rlc_info *)p_get_proto_data(pinfo->fd, proto_rlc, 0);
4242 /* Show release information */
4243 if (preferences_show_release_info) {
4244 proto_item *release_ti;
4245 proto_tree *release_tree;
4246 proto_item *temp_ti;
4248 release_ti = proto_tree_add_item(fp_tree, hf_fp_release, tvb, 0, 0, ENC_NA);
4249 PROTO_ITEM_SET_GENERATED(release_ti);
4250 proto_item_append_text(release_ti, " R%u (%d/%d)",
4251 p_fp_info->release, p_fp_info->release_year, p_fp_info->release_month);
4252 release_tree = proto_item_add_subtree(release_ti, ett_fp_release);
4254 temp_ti = proto_tree_add_uint(release_tree, hf_fp_release_version, tvb, 0, 0, p_fp_info->release);
4255 PROTO_ITEM_SET_GENERATED(temp_ti);
4257 temp_ti = proto_tree_add_uint(release_tree, hf_fp_release_year, tvb, 0, 0, p_fp_info->release_year);
4258 PROTO_ITEM_SET_GENERATED(temp_ti);
4260 temp_ti = proto_tree_add_uint(release_tree, hf_fp_release_month, tvb, 0, 0, p_fp_info->release_month);
4261 PROTO_ITEM_SET_GENERATED(temp_ti);
4264 /* Show channel type in info column, tree */
4265 col_set_str(pinfo->cinfo, COL_INFO,
4266 val_to_str_const(p_fp_info->channel,
4267 channel_type_vals,
4268 "Unknown channel type"));
4269 if (p_conv_data) {
4270 int i;
4271 col_append_fstr(pinfo->cinfo, COL_INFO, "(%u",p_conv_data->dchs_in_flow_list[0]);
4272 for (i=1; i < p_conv_data->num_dch_in_flow; i++) {
4273 col_append_fstr(pinfo->cinfo, COL_INFO, ",%u",p_conv_data->dchs_in_flow_list[i]);
4275 col_append_fstr(pinfo->cinfo, COL_INFO, ") ");
4277 proto_item_append_text(ti, " (%s)",
4278 val_to_str_const(p_fp_info->channel,
4279 channel_type_vals,
4280 "Unknown channel type"));
4282 /* Add channel type as a generated field */
4283 ti = proto_tree_add_uint(fp_tree, hf_fp_channel_type, tvb, 0, 0, p_fp_info->channel);
4284 PROTO_ITEM_SET_GENERATED(ti);
4286 /* Add division type as a generated field */
4287 if (p_fp_info->release == 7) {
4288 ti = proto_tree_add_uint(fp_tree, hf_fp_division, tvb, 0, 0, p_fp_info->division);
4289 PROTO_ITEM_SET_GENERATED(ti);
4292 /* Add link direction as a generated field */
4293 ti = proto_tree_add_uint(fp_tree, hf_fp_direction, tvb, 0, 0, p_fp_info->is_uplink);
4294 PROTO_ITEM_SET_GENERATED(ti);
4296 /* Don't currently handle IuR-specific formats, but it's useful to even see
4297 the channel type and direction */
4298 if (p_fp_info->iface_type == IuR_Interface) {
4299 return;
4302 /* Show DDI config info */
4303 if (p_fp_info->no_ddi_entries > 0) {
4304 int n;
4305 proto_item *ddi_config_ti;
4306 proto_tree *ddi_config_tree;
4308 ddi_config_ti = proto_tree_add_string_format(fp_tree, hf_fp_ddi_config, tvb, offset, 0,
4309 "", "DDI Config (");
4310 PROTO_ITEM_SET_GENERATED(ddi_config_ti);
4311 ddi_config_tree = proto_item_add_subtree(ddi_config_ti, ett_fp_ddi_config);
4313 /* Add each entry */
4314 for (n=0; n < p_fp_info->no_ddi_entries; n++) {
4315 proto_item_append_text(ddi_config_ti, "%s%u->%ubits",
4316 (n==0) ? "" : " ",
4317 p_fp_info->edch_ddi[n], p_fp_info->edch_macd_pdu_size[n]);
4318 ti = proto_tree_add_uint(ddi_config_tree, hf_fp_ddi_config_ddi, tvb, 0, 0,
4319 p_fp_info->edch_ddi[n]);
4320 PROTO_ITEM_SET_GENERATED(ti);
4321 ti = proto_tree_add_uint(ddi_config_tree, hf_fp_ddi_config_macd_pdu_size, tvb, 0, 0,
4322 p_fp_info->edch_macd_pdu_size[n]);
4323 PROTO_ITEM_SET_GENERATED(ti);
4326 proto_item_append_text(ddi_config_ti, ")");
4329 /*************************************/
4330 /* Dissect according to channel type */
4331 switch (p_fp_info->channel) {
4332 case CHANNEL_RACH_TDD:
4333 case CHANNEL_RACH_TDD_128:
4334 case CHANNEL_RACH_FDD:
4335 dissect_rach_channel_info(tvb, pinfo, fp_tree, offset, p_fp_info);
4336 break;
4337 case CHANNEL_DCH:
4338 dissect_dch_channel_info(tvb, pinfo, fp_tree, offset, p_fp_info);
4339 break;
4340 case CHANNEL_FACH_FDD:
4341 case CHANNEL_FACH_TDD:
4342 dissect_fach_channel_info(tvb, pinfo, fp_tree, offset, p_fp_info);
4343 break;
4344 case CHANNEL_DSCH_FDD:
4345 case CHANNEL_DSCH_TDD:
4346 dissect_dsch_channel_info(tvb, pinfo, fp_tree, offset, p_fp_info);
4347 break;
4348 case CHANNEL_USCH_TDD_128:
4349 case CHANNEL_USCH_TDD_384:
4350 dissect_usch_channel_info(tvb, pinfo, fp_tree, offset, p_fp_info);
4351 break;
4352 case CHANNEL_PCH:
4353 dissect_pch_channel_info(tvb, pinfo, fp_tree, offset, p_fp_info);
4354 break;
4355 case CHANNEL_CPCH:
4356 dissect_cpch_channel_info(tvb, pinfo, fp_tree, offset, p_fp_info);
4357 break;
4358 case CHANNEL_BCH:
4359 dissect_bch_channel_info(tvb, pinfo, fp_tree, offset, p_fp_info);
4360 break;
4361 case CHANNEL_HSDSCH:
4362 /* Show configured MAC HS-DSCH entity in use */
4363 if (fp_tree)
4365 proto_item *entity_ti;
4366 entity_ti = proto_tree_add_uint(fp_tree, hf_fp_hsdsch_entity,
4367 tvb, 0, 0,
4368 p_fp_info->hsdsch_entity);
4369 PROTO_ITEM_SET_GENERATED(entity_ti);
4371 switch (p_fp_info->hsdsch_entity) {
4372 case entity_not_specified:
4373 case hs:
4374 /* This is the pre-R7 default */
4375 dissect_hsdsch_channel_info(tvb, pinfo, fp_tree, offset, p_fp_info);
4376 break;
4377 case ehs:
4378 dissect_hsdsch_type_2_channel_info(tvb, pinfo, fp_tree, offset, p_fp_info);
4379 break;
4380 default:
4381 /* Report Error */
4382 expert_add_info(pinfo, NULL, &ei_fp_hsdsch_entity_not_specified);
4383 break;
4385 break;
4386 case CHANNEL_HSDSCH_COMMON:
4387 expert_add_info(pinfo, NULL, &ei_fp_hsdsch_common_experimental_support);
4388 /*if(FALSE)*/
4389 dissect_hsdsch_common_channel_info(tvb,pinfo, fp_tree, offset, p_fp_info);
4391 break;
4392 case CHANNEL_HSDSCH_COMMON_T3:
4393 expert_add_info(pinfo, NULL, &ei_fp_hsdsch_common_t3_not_implemented);
4395 /* TODO: */
4396 break;
4397 case CHANNEL_IUR_CPCHF:
4398 /* TODO: */
4399 break;
4400 case CHANNEL_IUR_FACH:
4401 /* TODO: */
4402 break;
4403 case CHANNEL_IUR_DSCH:
4404 dissect_iur_dsch_channel_info(tvb, pinfo, fp_tree, offset, p_fp_info);
4405 break;
4406 case CHANNEL_EDCH:
4407 case CHANNEL_EDCH_COMMON:
4408 dissect_e_dch_channel_info(tvb, pinfo, fp_tree, offset, p_fp_info,
4409 p_fp_info->channel == CHANNEL_EDCH_COMMON, rlcinf);
4410 break;
4412 default:
4413 expert_add_info(pinfo, NULL, &ei_fp_channel_type_unknown);
4414 break;
4419 void proto_register_fp(void)
4421 static hf_register_info hf[] =
4423 { &hf_fp_release,
4424 { "Release",
4425 "fp.release", FT_NONE, BASE_NONE, NULL, 0x0,
4426 "Release information", HFILL
4429 { &hf_fp_release_version,
4430 { "Release Version",
4431 "fp.release.version", FT_UINT8, BASE_DEC, NULL, 0x0,
4432 "3GPP Release number", HFILL
4435 { &hf_fp_release_year,
4436 { "Release year",
4437 "fp.release.year", FT_UINT16, BASE_DEC, NULL, 0x0,
4438 NULL, HFILL
4441 { &hf_fp_release_month,
4442 { "Release month",
4443 "fp.release.month", FT_UINT8, BASE_DEC, NULL, 0x0,
4444 NULL, HFILL
4447 { &hf_fp_channel_type,
4448 { "Channel Type",
4449 "fp.channel-type", FT_UINT8, BASE_HEX, VALS(channel_type_vals), 0x0,
4450 NULL, HFILL
4453 { &hf_fp_division,
4454 { "Division",
4455 "fp.division", FT_UINT8, BASE_HEX, VALS(division_vals), 0x0,
4456 "Radio division type", HFILL
4459 { &hf_fp_direction,
4460 { "Direction",
4461 "fp.direction", FT_UINT8, BASE_HEX, VALS(direction_vals), 0x0,
4462 "Link direction", HFILL
4465 { &hf_fp_ddi_config,
4466 { "DDI Config",
4467 "fp.ddi-config", FT_STRING, BASE_NONE, NULL, 0x0,
4468 "DDI Config (for E-DCH)", HFILL
4471 { &hf_fp_ddi_config_ddi,
4472 { "DDI",
4473 "fp.ddi-config.ddi", FT_UINT8, BASE_DEC, NULL, 0x0,
4474 NULL, HFILL
4477 { &hf_fp_ddi_config_macd_pdu_size,
4478 { "MACd PDU Size",
4479 "fp.ddi-config.macd-pdu-size", FT_UINT16, BASE_DEC, NULL, 0x0,
4480 NULL, HFILL
4485 { &hf_fp_header_crc,
4486 { "Header CRC",
4487 "fp.header-crc", FT_UINT8, BASE_HEX, NULL, 0xfe,
4488 NULL, HFILL
4491 { &hf_fp_ft,
4492 { "Frame Type",
4493 "fp.ft", FT_UINT8, BASE_HEX, VALS(data_control_vals), 0x01,
4494 NULL, HFILL
4497 { &hf_fp_cfn,
4498 { "CFN",
4499 "fp.cfn", FT_UINT8, BASE_DEC, NULL, 0x0,
4500 "Connection Frame Number", HFILL
4503 { &hf_fp_pch_cfn,
4504 { "CFN (PCH)",
4505 "fp.pch.cfn", FT_UINT16, BASE_DEC, NULL, 0xfff0,
4506 "PCH Connection Frame Number", HFILL
4509 { &hf_fp_pch_toa,
4510 { "ToA (PCH)",
4511 "fp.pch.toa", FT_INT24, BASE_DEC, NULL, 0x0,
4512 "PCH Time of Arrival", HFILL
4515 { &hf_fp_cfn_control,
4516 { "CFN control",
4517 "fp.cfn-control", FT_UINT8, BASE_DEC, NULL, 0x0,
4518 "Connection Frame Number Control", HFILL
4521 { &hf_fp_toa,
4522 { "ToA",
4523 "fp.toa", FT_INT16, BASE_DEC, NULL, 0x0,
4524 "Time of arrival (units are 125 microseconds)", HFILL
4527 { &hf_fp_tb,
4528 { "TB",
4529 "fp.tb", FT_BYTES, BASE_NONE, NULL, 0x0,
4530 "Transport Block", HFILL
4533 { &hf_fp_chan_zero_tbs,
4534 { "No TBs for channel",
4535 "fp.channel-with-zero-tbs", FT_UINT32, BASE_DEC, NULL, 0x0,
4536 "Channel with 0 TBs", HFILL
4539 { &hf_fp_tfi,
4540 { "TFI",
4541 "fp.tfi", FT_UINT8, BASE_DEC, NULL, 0x0,
4542 "Transport Format Indicator", HFILL
4545 { &hf_fp_usch_tfi,
4546 { "TFI",
4547 "fp.usch.tfi", FT_UINT8, BASE_DEC, NULL, 0x1f,
4548 "USCH Transport Format Indicator", HFILL
4551 { &hf_fp_cpch_tfi,
4552 { "TFI",
4553 "fp.cpch.tfi", FT_UINT8, BASE_DEC, NULL, 0x1f,
4554 "CPCH Transport Format Indicator", HFILL
4557 { &hf_fp_propagation_delay,
4558 { "Propagation Delay",
4559 "fp.propagation-delay", FT_UINT8, BASE_DEC, NULL, 0x0,
4560 NULL, HFILL
4563 { &hf_fp_dch_control_frame_type,
4564 { "Control Frame Type",
4565 "fp.dch.control.frame-type", FT_UINT8, BASE_HEX, VALS(dch_control_frame_type_vals), 0x0,
4566 "DCH Control Frame Type", HFILL
4569 { &hf_fp_dch_rx_timing_deviation,
4570 { "Rx Timing Deviation",
4571 "fp.dch.control.rx-timing-deviation", FT_UINT8, BASE_DEC, 0, 0x0,
4572 "DCH Rx Timing Deviation", HFILL
4575 { &hf_fp_quality_estimate,
4576 { "Quality Estimate",
4577 "fp.dch.quality-estimate", FT_UINT8, BASE_DEC, 0, 0x0,
4578 NULL, HFILL
4581 { &hf_fp_payload_crc,
4582 { "Payload CRC",
4583 "fp.payload-crc", FT_UINT16, BASE_HEX, 0, 0x0,
4584 NULL, HFILL
4587 { &hf_fp_common_control_frame_type,
4588 { "Control Frame Type",
4589 "fp.common.control.frame-type", FT_UINT8, BASE_HEX, VALS(common_control_frame_type_vals), 0x0,
4590 "Common Control Frame Type", HFILL
4593 { &hf_fp_crci[0],
4594 { "CRCI",
4595 "fp.crci", FT_UINT8, BASE_HEX, VALS(crci_vals), 0x80,
4596 "CRC correctness indicator", HFILL
4599 { &hf_fp_crci[1],
4600 { "CRCI",
4601 "fp.crci", FT_UINT8, BASE_HEX, VALS(crci_vals), 0x40,
4602 "CRC correctness indicator", HFILL
4605 { &hf_fp_crci[2],
4606 { "CRCI",
4607 "fp.crci", FT_UINT8, BASE_HEX, VALS(crci_vals), 0x20,
4608 "CRC correctness indicator", HFILL
4611 { &hf_fp_crci[3],
4612 { "CRCI",
4613 "fp.crci", FT_UINT8, BASE_HEX, VALS(crci_vals), 0x10,
4614 "CRC correctness indicator", HFILL
4617 { &hf_fp_crci[4],
4618 { "CRCI",
4619 "fp.crci", FT_UINT8, BASE_HEX, VALS(crci_vals), 0x08,
4620 "CRC correctness indicator", HFILL
4623 { &hf_fp_crci[5],
4624 { "CRCI",
4625 "fp.crci", FT_UINT8, BASE_HEX, VALS(crci_vals), 0x04,
4626 "CRC correctness indicator", HFILL
4629 { &hf_fp_crci[6],
4630 { "CRCI",
4631 "fp.crci", FT_UINT8, BASE_HEX, VALS(crci_vals), 0x02,
4632 "CRC correctness indicator", HFILL
4635 { &hf_fp_crci[7],
4636 { "CRCI",
4637 "fp.crci", FT_UINT8, BASE_HEX, VALS(crci_vals), 0x01,
4638 "CRC correctness indicator", HFILL
4641 { &hf_fp_received_sync_ul_timing_deviation,
4642 { "Received SYNC UL Timing Deviation",
4643 "fp.rx-sync-ul-timing-deviation", FT_UINT8, BASE_DEC, 0, 0x0,
4644 NULL, HFILL
4647 { &hf_fp_pch_pi,
4648 { "Paging Indication",
4649 "fp.pch.pi", FT_UINT8, BASE_DEC, VALS(paging_indication_vals), 0x01,
4650 "Indicates if the PI Bitmap is present", HFILL
4653 { &hf_fp_pch_tfi,
4654 { "TFI",
4655 "fp.pch.tfi", FT_UINT8, BASE_DEC, 0, 0x1f,
4656 "PCH Transport Format Indicator", HFILL
4659 { &hf_fp_fach_tfi,
4660 { "TFI",
4661 "fp.fach.tfi", FT_UINT8, BASE_DEC, 0, 0x1f,
4662 "FACH Transport Format Indicator", HFILL
4665 { &hf_fp_transmit_power_level,
4666 { "Transmit Power Level",
4667 "fp.transmit-power-level", FT_FLOAT, BASE_NONE, 0, 0x0,
4668 "Transmit Power Level (dB)", HFILL
4671 { &hf_fp_pdsch_set_id,
4672 { "PDSCH Set Id",
4673 "fp.pdsch-set-id", FT_UINT8, BASE_DEC, 0, 0x0,
4674 "A pointer to the PDSCH Set which shall be used to transmit", HFILL
4677 { &hf_fp_paging_indication_bitmap,
4678 { "Paging Indications bitmap",
4679 "fp.pch.pi-bitmap", FT_NONE, BASE_NONE, NULL, 0x0,
4680 "Paging Indication bitmap", HFILL
4683 { &hf_fp_rx_timing_deviation,
4684 { "Rx Timing Deviation",
4685 "fp.common.control.rx-timing-deviation", FT_UINT8, BASE_DEC, 0, 0x0,
4686 "Common Rx Timing Deviation", HFILL
4689 { &hf_fp_dch_e_rucch_flag,
4690 { "E-RUCCH Flag",
4691 "fp.common.control.e-rucch-flag", FT_UINT8, BASE_DEC, VALS(e_rucch_flag_vals), 0x0,
4692 NULL, HFILL
4695 { &hf_fp_edch_header_crc,
4696 { "E-DCH Header CRC",
4697 "fp.edch.header-crc", FT_UINT16, BASE_HEX, 0, 0,
4698 NULL, HFILL
4701 { &hf_fp_edch_fsn,
4702 { "FSN",
4703 "fp.edch.fsn", FT_UINT8, BASE_DEC, 0, 0x0f,
4704 "E-DCH Frame Sequence Number", HFILL
4707 { &hf_fp_edch_number_of_subframes,
4708 { "No of subframes",
4709 "fp.edch.no-of-subframes", FT_UINT8, BASE_DEC, 0, 0x0f,
4710 "E-DCH Number of subframes", HFILL
4713 { &hf_fp_edch_harq_retransmissions,
4714 { "No of HARQ Retransmissions",
4715 "fp.edch.no-of-harq-retransmissions", FT_UINT8, BASE_DEC, 0, 0x78,
4716 "E-DCH Number of HARQ retransmissions", HFILL
4719 { &hf_fp_edch_subframe_number,
4720 { "Subframe number",
4721 "fp.edch.subframe-number", FT_UINT8, BASE_DEC, 0, 0x0,
4722 "E-DCH Subframe number", HFILL
4725 { &hf_fp_edch_number_of_mac_es_pdus,
4726 { "Number of Mac-es PDUs",
4727 "fp.edch.number-of-mac-es-pdus", FT_UINT8, BASE_DEC, 0, 0xf0,
4728 NULL, HFILL
4731 { &hf_fp_edch_ddi,
4732 { "DDI",
4733 "fp.edch.ddi", FT_UINT8, BASE_DEC, 0, 0x0,
4734 "E-DCH Data Description Indicator", HFILL
4737 { &hf_fp_edch_subframe,
4738 { "Subframe",
4739 "fp.edch.subframe", FT_STRING, BASE_NONE, NULL, 0x0,
4740 "EDCH Subframe", HFILL
4743 { &hf_fp_edch_subframe_header,
4744 { "Subframe header",
4745 "fp.edch.subframe-header", FT_STRING, BASE_NONE, NULL, 0x0,
4746 "EDCH Subframe header", HFILL
4749 { &hf_fp_edch_number_of_mac_d_pdus,
4750 { "Number of Mac-d PDUs",
4751 "fp.edch.number-of-mac-d-pdus", FT_UINT8, BASE_DEC, 0, 0x0,
4752 NULL, HFILL
4755 { &hf_fp_edch_pdu_padding,
4756 { "Padding",
4757 "fp.edch-data-padding", FT_UINT8, BASE_DEC, 0, 0xc0,
4758 "E-DCH padding before PDU", HFILL
4761 { &hf_fp_edch_tsn,
4762 { "TSN",
4763 "fp.edch-tsn", FT_UINT8, BASE_DEC, 0, 0x3f,
4764 "E-DCH Transmission Sequence Number", HFILL
4767 { &hf_fp_edch_mac_es_pdu,
4768 { "MAC-es PDU",
4769 "fp.edch.mac-es-pdu", FT_NONE, BASE_NONE, NULL, 0x0,
4770 NULL, HFILL
4774 { &hf_fp_edch_user_buffer_size,
4775 { "User Buffer Size",
4776 "fp.edch.user-buffer-size", FT_UINT24, BASE_DEC, NULL, 0x0,
4777 NULL, HFILL
4780 { &hf_fp_edch_no_macid_sdus,
4781 { "No of MAC-is SDUs",
4782 "fp.edch.no-macis-sdus", FT_UINT16, BASE_DEC, NULL, 0x0,
4783 NULL, HFILL
4786 { &hf_fp_edch_number_of_mac_is_pdus,
4787 { "Number of Mac-is PDUs",
4788 "fp.edch.number-of-mac-is-pdus", FT_UINT8, BASE_DEC, 0, 0x0,
4789 NULL, HFILL
4792 { &hf_fp_edch_mac_is_pdu,
4793 { "Mac-is PDU",
4794 "fp.edch.mac-is-pdu", FT_BYTES, BASE_NONE, 0, 0x0,
4795 NULL, HFILL
4798 { &hf_fp_edch_e_rnti,
4799 { "E-RNTI",
4800 "fp.edch.e-rnti", FT_UINT16, BASE_DEC, 0, 0x0,
4801 NULL, HFILL
4805 { &hf_fp_edch_macis_descriptors,
4806 { "MAC-is Descriptors",
4807 "fp.edch.mac-is.descriptors", FT_STRING, BASE_NONE, NULL, 0x0,
4808 NULL, HFILL
4811 { &hf_fp_edch_macis_lchid,
4812 { "LCH-ID",
4813 "fp.edch.mac-is.lchid", FT_UINT8, BASE_HEX, VALS(lchid_vals), 0xf0,
4814 NULL, HFILL
4817 { &hf_fp_edch_macis_length,
4818 { "Length",
4819 "fp.edch.mac-is.length", FT_UINT16, BASE_DEC, 0, 0x0ffe,
4820 NULL, HFILL
4823 { &hf_fp_edch_macis_flag,
4824 { "Flag",
4825 "fp.edch.mac-is.lchid", FT_UINT8, BASE_HEX, 0, 0x01,
4826 "Indicates if another entry follows", HFILL
4829 { &hf_fp_frame_seq_nr,
4830 { "Frame Seq Nr",
4831 "fp.frame-seq-nr", FT_UINT8, BASE_DEC, 0, 0xf0,
4832 "Frame Sequence Number", HFILL
4835 { &hf_fp_hsdsch_pdu_block_header,
4836 { "PDU block header",
4837 "fp.hsdsch.pdu-block-header", FT_STRING, BASE_NONE, NULL, 0x0,
4838 "HS-DSCH type 2 PDU block header", HFILL
4841 #if 0
4842 { &hf_fp_hsdsch_pdu_block,
4843 { "PDU block",
4844 "fp.hsdsch.pdu-block", FT_STRING, BASE_NONE, NULL, 0x0,
4845 "HS-DSCH type 2 PDU block data", HFILL
4848 #endif
4849 { &hf_fp_flush,
4850 { "Flush",
4851 "fp.flush", FT_UINT8, BASE_DEC, 0, 0x04,
4852 "Whether all PDUs for this priority queue should be removed", HFILL
4855 { &hf_fp_fsn_drt_reset,
4856 { "FSN-DRT reset",
4857 "fp.fsn-drt-reset", FT_UINT8, BASE_DEC, 0, 0x02,
4858 "FSN/DRT Reset Flag", HFILL
4861 { &hf_fp_drt_indicator,
4862 { "DRT Indicator",
4863 "fp.drt-indicator", FT_UINT8, BASE_DEC, 0, 0x01,
4864 NULL, HFILL
4867 { &hf_fp_fach_indicator,
4868 { "FACH Indicator",
4869 "fp.fach-indicator", FT_UINT8, BASE_DEC, 0, 0x80,
4870 NULL, HFILL
4873 { &hf_fp_total_pdu_blocks,
4874 { "PDU Blocks",
4875 "fp.pdu_blocks", FT_UINT8, BASE_DEC, 0, 0xf8,
4876 "Total number of PDU blocks", HFILL
4879 { &hf_fp_drt,
4880 { "DelayRefTime",
4881 "fp.drt", FT_UINT16, BASE_DEC, 0, 0x0,
4882 NULL, HFILL
4885 { &hf_fp_hrnti,
4886 { "HRNTI",
4887 "fp.hrnti", FT_UINT16, BASE_DEC, 0, 0x0,
4888 NULL, HFILL
4891 { &hf_fp_rach_measurement_result,
4892 { "RACH Measurement Result",
4893 "fp.rach-measurement-result", FT_UINT16, BASE_DEC, 0, 0x0,
4894 NULL, HFILL
4897 { &hf_fp_lchid,
4898 { "Logical Channel ID",
4899 "fp.lchid", FT_UINT8, BASE_DEC, NULL, 0x0,
4900 NULL, HFILL
4903 { &hf_fp_pdu_length_in_block,
4904 { "PDU length in block",
4905 "fp.pdu-length-in-block", FT_UINT8, BASE_DEC, 0, 0x0,
4906 "Length of each PDU in this block in bytes", HFILL
4909 { &hf_fp_pdus_in_block,
4910 { "PDUs in block",
4911 "fp.no-pdus-in-block", FT_UINT8, BASE_DEC, 0, 0x0,
4912 "Number of PDUs in block", HFILL
4915 { &hf_fp_cmch_pi,
4916 { "CmCH-PI",
4917 "fp.cmch-pi", FT_UINT8, BASE_DEC, 0, 0x0f,
4918 "Common Transport Channel Priority Indicator", HFILL
4921 { &hf_fp_user_buffer_size,
4922 { "User buffer size",
4923 "fp.user-buffer-size", FT_UINT16, BASE_DEC, 0, 0x0,
4924 "User buffer size in octets", HFILL
4927 { &hf_fp_hsdsch_credits,
4928 { "HS-DSCH Credits",
4929 "fp.hsdsch-credits", FT_UINT16, BASE_DEC, 0, 0x0,
4930 NULL, HFILL
4933 { &hf_fp_hsdsch_max_macd_pdu_len,
4934 { "Max MAC-d PDU Length",
4935 "fp.hsdsch.max-macd-pdu-len", FT_UINT16, BASE_DEC, 0, 0xfff8,
4936 "Maximum MAC-d PDU Length in bits", HFILL
4939 { &hf_fp_hsdsch_max_macdc_pdu_len,
4940 { "Max MAC-d/c PDU Length",
4941 "fp.hsdsch.max-macdc-pdu-len", FT_UINT16, BASE_DEC, 0, 0x07ff,
4942 "Maximum MAC-d/c PDU Length in bits", HFILL
4945 { &hf_fp_hsdsch_interval,
4946 { "HS-DSCH Interval in milliseconds",
4947 "fp.hsdsch-interval", FT_UINT8, BASE_DEC, 0, 0x0,
4948 NULL, HFILL
4951 { &hf_fp_hsdsch_calculated_rate,
4952 { "Calculated rate allocation (bps)",
4953 "fp.hsdsch-calculated-rate", FT_UINT32, BASE_DEC, 0, 0x0,
4954 "Calculated rate RNC is allowed to send in bps", HFILL
4957 { &hf_fp_hsdsch_unlimited_rate,
4958 { "Unlimited rate",
4959 "fp.hsdsch-unlimited-rate", FT_NONE, BASE_NONE, 0, 0x0,
4960 "No restriction on rate at which date may be sent", HFILL
4963 { &hf_fp_hsdsch_repetition_period,
4964 { "HS-DSCH Repetition Period",
4965 "fp.hsdsch-repetition-period", FT_UINT8, BASE_DEC, 0, 0x0,
4966 "HS-DSCH Repetition Period in milliseconds", HFILL
4969 { &hf_fp_hsdsch_data_padding,
4970 { "Padding",
4971 "fp.hsdsch-data-padding", FT_UINT8, BASE_DEC, 0, 0xf0,
4972 "HS-DSCH Repetition Period in milliseconds", HFILL
4975 { &hf_fp_hsdsch_new_ie_flags,
4976 { "New IEs flags",
4977 "fp.hsdsch.new-ie-flags", FT_STRING, BASE_NONE, 0, 0x0,
4978 NULL, HFILL
4981 { &hf_fp_hsdsch_new_ie_flag[0],
4982 { "DRT IE present",
4983 "fp.hsdsch.new-ie-flag", FT_UINT8, BASE_DEC, 0, 0x80,
4984 NULL, HFILL
4987 { &hf_fp_hsdsch_new_ie_flag[1],
4988 { "New IE present",
4989 "fp.hsdsch.new-ie-flag", FT_UINT8, BASE_DEC, 0, 0x40,
4990 NULL, HFILL
4993 { &hf_fp_hsdsch_new_ie_flag[2],
4994 { "New IE present",
4995 "fp.hsdsch.new-ie-flag", FT_UINT8, BASE_DEC, 0, 0x20,
4996 NULL, HFILL
4999 { &hf_fp_hsdsch_new_ie_flag[3],
5000 { "New IE present",
5001 "fp.hsdsch.new-ie-flag", FT_UINT8, BASE_DEC, 0, 0x10,
5002 NULL, HFILL
5005 { &hf_fp_hsdsch_new_ie_flag[4],
5006 { "New IE present",
5007 "fp.hsdsch.new-ie-flag", FT_UINT8, BASE_DEC, 0, 0x08,
5008 NULL, HFILL
5011 { &hf_fp_hsdsch_new_ie_flag[5],
5012 { "New IE present",
5013 "fp.hsdsch.new-ie-flag", FT_UINT8, BASE_DEC, 0, 0x04,
5014 NULL, HFILL
5017 { &hf_fp_hsdsch_new_ie_flag[6],
5018 { "HS-DSCH physical layer category present",
5019 "fp.hsdsch.new-ie-flag", FT_UINT8, BASE_DEC, 0, 0x02,
5020 NULL, HFILL
5023 { &hf_fp_hsdsch_new_ie_flag[7],
5024 { "Another new IE flags byte",
5025 "fp.hsdsch.new-ie-flags-byte", FT_UINT8, BASE_DEC, 0, 0x01,
5026 "Another new IE flagsbyte", HFILL
5029 { &hf_fp_hsdsch_drt,
5030 { "DRT",
5031 "fp.hsdsch.drt", FT_UINT8, BASE_DEC, 0, 0xf0,
5032 "Delay Reference Time", HFILL
5035 { &hf_fp_hsdsch_entity,
5036 { "HS-DSCH Entity",
5037 "fp.hsdsch.entity", FT_UINT8, BASE_DEC, VALS(hsdshc_mac_entity_vals), 0x0,
5038 "Type of MAC entity for this HS-DSCH channel", HFILL
5041 { &hf_fp_timing_advance,
5042 { "Timing advance",
5043 "fp.timing-advance", FT_UINT8, BASE_DEC, 0, 0x3f,
5044 "Timing advance in chips", HFILL
5047 { &hf_fp_num_of_pdu,
5048 { "Number of PDUs",
5049 "fp.hsdsch.num-of-pdu", FT_UINT8, BASE_DEC, 0, 0x0,
5050 "Number of PDUs in the payload", HFILL
5053 { &hf_fp_mac_d_pdu_len,
5054 { "MAC-d PDU Length",
5055 "fp.hsdsch.mac-d-pdu-len", FT_UINT16, BASE_DEC, 0, 0xfff8,
5056 "MAC-d PDU Length in bits", HFILL
5059 { &hf_fp_mac_d_pdu,
5060 { "MAC-d PDU",
5061 "fp.mac-d-pdu", FT_BYTES, BASE_NONE, NULL, 0x0,
5062 NULL, HFILL
5065 { &hf_fp_data,
5066 { "Data",
5067 "fp.data", FT_BYTES, BASE_NONE, NULL, 0x0,
5068 NULL, HFILL
5071 { &hf_fp_crcis,
5072 { "CRCIs",
5073 "fp.crcis", FT_BYTES, BASE_NONE, NULL, 0x0,
5074 "CRC Indicators for uplink TBs", HFILL
5077 { &hf_fp_t1,
5078 { "T1",
5079 "fp.t1", FT_UINT24, BASE_DEC, NULL, 0x0,
5080 "RNC frame number indicating time it sends frame", HFILL
5083 { &hf_fp_t2,
5084 { "T2",
5085 "fp.t2", FT_UINT24, BASE_DEC, NULL, 0x0,
5086 "NodeB frame number indicating time it received DL Sync", HFILL
5089 { &hf_fp_t3,
5090 { "T3",
5091 "fp.t3", FT_UINT24, BASE_DEC, NULL, 0x0,
5092 "NodeB frame number indicating time it sends frame", HFILL
5095 { &hf_fp_ul_sir_target,
5096 { "UL_SIR_TARGET",
5097 "fp.ul-sir-target", FT_FLOAT, BASE_NONE, 0, 0x0,
5098 "Value (in dB) of the SIR target to be used by the UL inner loop power control", HFILL
5101 { &hf_fp_pusch_set_id,
5102 { "PUSCH Set Id",
5103 "fp.pusch-set-id", FT_UINT8, BASE_DEC, NULL, 0x0,
5104 "Identifies PUSCH Set from those configured in NodeB", HFILL
5107 { &hf_fp_activation_cfn,
5108 { "Activation CFN",
5109 "fp.activation-cfn", FT_UINT8, BASE_DEC, NULL, 0x0,
5110 "Activation Connection Frame Number", HFILL
5113 { &hf_fp_duration,
5114 { "Duration (ms)",
5115 "fp.pusch-set-id", FT_UINT8, BASE_DEC, NULL, 0x0,
5116 "Duration of the activation period of the PUSCH Set", HFILL
5119 { &hf_fp_power_offset,
5120 { "Power offset",
5121 "fp.power-offset", FT_FLOAT, BASE_NONE, NULL, 0x0,
5122 "Power offset (in dB)", HFILL
5125 { &hf_fp_code_number,
5126 { "Code number",
5127 "fp.code-number", FT_UINT8, BASE_DEC, NULL, 0x0,
5128 NULL, HFILL
5131 { &hf_fp_spreading_factor,
5132 { "Spreading factor",
5133 "fp.spreading-factor", FT_UINT8, BASE_DEC, VALS(spreading_factor_vals), 0xf0,
5134 NULL, HFILL
5137 { &hf_fp_mc_info,
5138 { "MC info",
5139 "fp.mc-info", FT_UINT8, BASE_DEC, NULL, 0x0e,
5140 NULL, HFILL
5143 { &hf_fp_rach_new_ie_flags,
5144 { "New IEs flags",
5145 "fp.rach.new-ie-flags", FT_STRING, BASE_NONE, 0, 0x0,
5146 NULL, HFILL
5149 { &hf_fp_rach_new_ie_flag_unused[0],
5150 { "New IE present",
5151 "fp.rach.new-ie-flag", FT_UINT8, BASE_DEC, 0, 0x80,
5152 NULL, HFILL
5155 { &hf_fp_rach_new_ie_flag_unused[1],
5156 { "New IE present",
5157 "fp.rach.new-ie-flag", FT_UINT8, BASE_DEC, 0, 0x40,
5158 NULL, HFILL
5161 { &hf_fp_rach_new_ie_flag_unused[2],
5162 { "New IE present",
5163 "fp.rach.new-ie-flag", FT_UINT8, BASE_DEC, 0, 0x20,
5164 "New IE present (unused)", HFILL
5167 { &hf_fp_rach_new_ie_flag_unused[3],
5168 { "New IE present",
5169 "fp.rach.new-ie-flag", FT_UINT8, BASE_DEC, 0, 0x10,
5170 "New IE present (unused)", HFILL
5173 { &hf_fp_rach_new_ie_flag_unused[4],
5174 { "New IE present",
5175 "fp.rach.new-ie-flag", FT_UINT8, BASE_DEC, 0, 0x08,
5176 "New IE present (unused)", HFILL
5179 { &hf_fp_rach_new_ie_flag_unused[5],
5180 { "New IE present",
5181 "fp.rach.new-ie-flag", FT_UINT8, BASE_DEC, 0, 0x04,
5182 "New IE present (unused)", HFILL
5185 { &hf_fp_rach_new_ie_flag_unused[6],
5186 { "New IE present",
5187 "fp.rach.new-ie-flag", FT_UINT8, BASE_DEC, 0, 0x02,
5188 "New IE present (unused)", HFILL
5191 { &hf_fp_rach_cell_portion_id_present,
5192 { "Cell portion ID present",
5193 "fp.rach.cell-portion-id-present", FT_UINT8, BASE_DEC, 0, 0x01,
5194 NULL, HFILL
5197 { &hf_fp_rach_angle_of_arrival_present,
5198 { "Angle of arrival present",
5199 "fp.rach.angle-of-arrival-present", FT_UINT8, BASE_DEC, 0, 0x01,
5200 NULL, HFILL
5203 { &hf_fp_rach_ext_propagation_delay_present,
5204 { "Ext Propagation Delay Present",
5205 "fp.rach.ext-propagation-delay-present", FT_UINT8, BASE_DEC, 0, 0x02,
5206 NULL, HFILL
5209 { &hf_fp_rach_ext_rx_sync_ul_timing_deviation_present,
5210 { "Ext Received Sync UL Timing Deviation present",
5211 "fp.rach.ext-rx-sync-ul-timing-deviation-present", FT_UINT8, BASE_DEC, 0, 0x02,
5212 NULL, HFILL
5215 { &hf_fp_rach_ext_rx_timing_deviation_present,
5216 { "Ext Rx Timing Deviation present",
5217 "fp.rach.ext-rx-timing-deviation-present", FT_UINT8, BASE_DEC, 0, 0x01,
5218 NULL, HFILL
5221 { &hf_fp_cell_portion_id,
5222 { "Cell Portion ID",
5223 "fp.cell-portion-id", FT_UINT8, BASE_DEC, NULL, 0x3f,
5224 NULL, HFILL
5227 { &hf_fp_ext_propagation_delay,
5228 { "Ext Propagation Delay",
5229 "fp.ext-propagation-delay", FT_UINT16, BASE_DEC, NULL, 0x03ff,
5230 NULL, HFILL
5233 { &hf_fp_angle_of_arrival,
5234 { "Angle of Arrival",
5235 "fp.angle-of-arrival", FT_UINT16, BASE_DEC, NULL, 0x03ff,
5236 NULL, HFILL
5239 { &hf_fp_ext_received_sync_ul_timing_deviation,
5240 { "Ext Received SYNC UL Timing Deviation",
5241 "fp.ext-received-sync-ul-timing-deviation", FT_UINT16, BASE_DEC, NULL, 0x1fff,
5242 NULL, HFILL
5247 { &hf_fp_radio_interface_parameter_update_flag[0],
5248 { "CFN valid",
5249 "fp.radio-interface-param.cfn-valid", FT_UINT16, BASE_DEC, 0, 0x0001,
5250 NULL, HFILL
5253 { &hf_fp_radio_interface_parameter_update_flag[1],
5254 { "TPC PO valid",
5255 "fp.radio-interface-param.tpc-po-valid", FT_UINT16, BASE_DEC, 0, 0x0002,
5256 NULL, HFILL
5259 { &hf_fp_radio_interface_parameter_update_flag[2],
5260 { "DPC mode valid",
5261 "fp.radio-interface-param.dpc-mode-valid", FT_UINT16, BASE_DEC, 0, 0x0004,
5262 NULL, HFILL
5265 { &hf_fp_radio_interface_parameter_update_flag[3],
5266 { "RL sets indicator valid",
5267 "fp.radio-interface_param.rl-sets-indicator-valid", FT_UINT16, BASE_DEC, 0, 0x0020,
5268 NULL, HFILL
5271 { &hf_fp_radio_interface_parameter_update_flag[4],
5272 { "MAX_UE_TX_POW valid",
5273 "fp.radio-interface-param.max-ue-tx-pow-valid", FT_UINT16, BASE_DEC, 0, 0x0040,
5274 "MAX UE TX POW valid", HFILL
5277 { &hf_fp_dpc_mode,
5278 { "DPC Mode",
5279 "fp.dpc-mode", FT_UINT8, BASE_DEC, NULL, 0x20,
5280 "DPC Mode to be applied in the uplink", HFILL
5283 { &hf_fp_tpc_po,
5284 { "TPC PO",
5285 "fp.tpc-po", FT_UINT8, BASE_DEC, NULL, 0x1f,
5286 NULL, HFILL
5289 { &hf_fp_multiple_rl_set_indicator,
5290 { "Multiple RL sets indicator",
5291 "fp.multiple-rl-sets-indicator", FT_UINT8, BASE_DEC, NULL, 0x80,
5292 NULL, HFILL
5295 { &hf_fp_max_ue_tx_pow,
5296 { "MAX_UE_TX_POW",
5297 "fp.max-ue-tx-pow", FT_INT8, BASE_DEC, NULL, 0x0,
5298 "Max UE TX POW (dBm)", HFILL
5301 { &hf_fp_congestion_status,
5302 { "Congestion Status",
5303 "fp.congestion-status", FT_UINT8, BASE_DEC, VALS(congestion_status_vals), 0x0,
5304 NULL, HFILL
5307 { &hf_fp_e_rucch_present,
5308 { "E-RUCCH Present",
5309 "fp.erucch-present", FT_UINT8, BASE_DEC, NULL, 0x0,
5310 NULL, HFILL
5313 { &hf_fp_extended_bits_present,
5314 { "Extended Bits Present",
5315 "fp.extended-bits-present", FT_UINT8, BASE_DEC, NULL, 0x0,
5316 NULL, HFILL
5319 { &hf_fp_extended_bits,
5320 { "Extended Bits",
5321 "fp.extended-bits", FT_UINT8, BASE_HEX, NULL, 0x0,
5322 NULL, HFILL
5325 { &hf_fp_spare_extension,
5326 { "Spare Extension",
5327 "fp.spare-extension", FT_NONE, BASE_NONE, NULL, 0x0,
5328 NULL, HFILL
5331 { &hf_fp_ul_setup_frame,
5332 { "UL setup frame",
5333 "fp.ul.setup_frame", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
5334 NULL, HFILL
5337 { &hf_fp_dl_setup_frame,
5338 { "DL setup frame",
5339 "fp.dl.setup_frame", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
5340 NULL, HFILL
5343 { &hf_fp_hsdsch_physical_layer_category,
5344 { "HS-DSCH physical layer category",
5345 "fp.hsdsch.physical_layer_category", FT_UINT8, BASE_DEC, NULL, 0x0,
5346 NULL, HFILL
5352 static gint *ett[] =
5354 &ett_fp,
5355 &ett_fp_data,
5356 &ett_fp_crcis,
5357 &ett_fp_ddi_config,
5358 &ett_fp_edch_subframe_header,
5359 &ett_fp_edch_subframe,
5360 &ett_fp_edch_maces,
5361 &ett_fp_edch_macis_descriptors,
5362 &ett_fp_hsdsch_new_ie_flags,
5363 &ett_fp_rach_new_ie_flags,
5364 &ett_fp_hsdsch_pdu_block_header,
5365 &ett_fp_release
5368 static ei_register_info ei[] = {
5369 { &ei_fp_bad_header_checksum, { "fp.header.bad_checksum.", PI_CHECKSUM, PI_WARN, "Bad header checksum.", EXPFILL }},
5370 { &ei_fp_crci_no_subdissector, { "fp.crci.no_subdissector", PI_UNDECODED, PI_NOTE, "Not sent to subdissectors as CRCI is set", EXPFILL }},
5371 { &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 }},
5372 { &ei_fp_spare_extension, { "fp.spare-extension.expert", PI_UNDECODED, PI_WARN, "Spare Extension present (%u bytes)", EXPFILL }},
5373 { &ei_fp_bad_payload_checksum, { "fp.payload-crc.bad.", PI_CHECKSUM, PI_WARN, "Bad payload checksum.", EXPFILL }},
5374 { &ei_fp_stop_hsdpa_transmission, { "fp.stop_hsdpa_transmission", PI_RESPONSE_CODE, PI_NOTE, "Stop HSDPA transmission", EXPFILL }},
5375 { &ei_fp_timing_adjustmentment_reported, { "fp.timing_adjustmentment_reported", PI_SEQUENCE, PI_WARN, "Timing adjustmentment reported (%f ms)", EXPFILL }},
5376 { &ei_fp_expecting_tdd, { "fp.expecting_tdd", PI_MALFORMED, PI_NOTE, "Error: expecting TDD-384 or TDD-768", EXPFILL }},
5377 { &ei_fp_ddi_not_defined, { "fp.ddi_not_defined", PI_MALFORMED, PI_ERROR, "DDI %u not defined for this UE!", EXPFILL }},
5378 { &ei_fp_unable_to_locate_ddi_entry, { "fp.unable_to_locate_ddi_entry", PI_UNDECODED, PI_ERROR, "Unable to locate DDI entry.", EXPFILL }},
5379 { &ei_fp_mac_is_sdus_miscount, { "fp.mac_is_sdus.miscount", PI_MALFORMED, PI_ERROR, "Found too many (%u) MAC-is SDUs - header said there were %u", EXPFILL }},
5380 { &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 }},
5381 { &ei_fp_e_rnti_first_entry, { "fp.e_rnti.first_entry", PI_MALFORMED, PI_ERROR, "E-RNTI must be first entry among descriptors", EXPFILL }},
5382 { &ei_fp_maybe_srb, { "fp.maybe_srb", PI_PROTOCOL, PI_NOTE, "Found MACd-Flow = 0 and not MUX detected. (This might be SRB)", EXPFILL }},
5383 { &ei_fp_transport_channel_type_unknown, { "fp.transport_channel_type.unknown", PI_UNDECODED, PI_WARN, "Unknown transport channel type", EXPFILL }},
5384 { &ei_fp_hsdsch_entity_not_specified, { "fp.hsdsch_entity_not_specified", PI_MALFORMED, PI_ERROR, "HSDSCH Entity not specified", EXPFILL }},
5385 { &ei_fp_hsdsch_common_experimental_support, { "fp.hsdsch_common.experimental_support", PI_DEBUG, PI_WARN, "HSDSCH COMMON - Experimental support!", EXPFILL }},
5386 { &ei_fp_hsdsch_common_t3_not_implemented, { "fp.hsdsch_common_t3.not_implemented", PI_DEBUG, PI_ERROR, "HSDSCH COMMON T3 - Not implemeneted!", EXPFILL }},
5387 { &ei_fp_channel_type_unknown, { "fp.channel_type.unknown", PI_MALFORMED, PI_ERROR, "Unknown channel type", EXPFILL }},
5390 module_t *fp_module;
5391 expert_module_t* expert_fp;
5393 /* Register protocol. */
5394 proto_fp = proto_register_protocol("FP", "FP", "fp");
5395 proto_register_field_array(proto_fp, hf, array_length(hf));
5396 proto_register_subtree_array(ett, array_length(ett));
5397 expert_fp = expert_register_protocol(proto_fp);
5398 expert_register_field_array(expert_fp, ei, array_length(ei));
5400 /* Allow other dissectors to find this one by name. */
5401 register_dissector("fp", dissect_fp, proto_fp);
5403 /* Preferences */
5404 fp_module = prefs_register_protocol(proto_fp, NULL);
5406 /* Determines whether release information should be displayed */
5407 prefs_register_bool_preference(fp_module, "show_release_info",
5408 "Show reported release info",
5409 "Show reported release info",
5410 &preferences_show_release_info);
5412 /* Determines whether MAC dissector should be called for payloads */
5413 prefs_register_bool_preference(fp_module, "call_mac",
5414 "Call MAC dissector for payloads",
5415 "Call MAC dissector for payloads",
5416 &preferences_call_mac_dissectors);
5417 /* Determines whether or not to validate FP payload checksums */
5418 prefs_register_bool_preference(fp_module, "payload_checksum",
5419 "Validate FP payload checksums",
5420 "Validate FP payload checksums",
5421 &preferences_payload_checksum);
5422 /* Determines whether or not to validate FP header checksums */
5423 prefs_register_bool_preference(fp_module, "header_checksum",
5424 "Validate FP header checksums",
5425 "Validate FP header checksums",
5426 &preferences_header_checksum);
5427 /* Determines whether or not to validate FP header checksums */
5428 prefs_register_bool_preference(fp_module, "udp_heur",
5429 "Enable UDP heur dissector",
5430 "Enable UDP heur dissector",
5431 &preferences_udp_do_heur);
5435 void proto_reg_handoff_fp(void)
5437 rlc_bcch_handle = find_dissector("rlc.bcch");
5438 mac_fdd_rach_handle = find_dissector("mac.fdd.rach");
5439 mac_fdd_fach_handle = find_dissector("mac.fdd.fach");
5440 mac_fdd_pch_handle = find_dissector("mac.fdd.pch");
5441 mac_fdd_dch_handle = find_dissector("mac.fdd.dch");
5442 mac_fdd_edch_handle = find_dissector("mac.fdd.edch");
5443 mac_fdd_edch_type2_handle = find_dissector("mac.fdd.edch.type2");
5444 mac_fdd_hsdsch_handle = find_dissector("mac.fdd.hsdsch");
5445 fp_handle = find_dissector("fp");
5447 heur_dissector_add("udp", heur_dissect_fp, proto_fp);