Coverage Report

Created: 2026-09-28 06:52

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