2 * Routines for O-RAN fronthaul UC-plane dissection
3 * Copyright 2020, Jan Schiefer, Keysight Technologies, Inc.
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * SPDX-License-Identifier: GPL-2.0-or-later
13 * Dissector for the O-RAN Fronthaul CUS protocol specification.
14 * See https://specifications.o-ran.org/specifications, WG4, Fronthaul Interfaces Workgroup
15 * The current implementation is based on the ORAN-WG4.CUS.0-v16.01 specification
22 #include <epan/packet.h>
23 #include <epan/expert.h>
24 #include <epan/prefs.h>
28 #include <wsutil/array.h>
30 #include "epan/dissectors/packet-oran.h"
32 /* N.B. dissector preferences are taking the place of (some) M-plane parameters, so unfortunately it can be
33 * fiddly to get the preferences into a good state to decode a given capture..
35 * - for U-Plane, track back to last C-Plane frame for that eAxC
36 * - use upCompHdr values from C-Plane if not overridden by U-Plane?
37 * N.B. this matching is tricky see 7.8.1 Coupling of C-Plane and U-Plane
38 * - Radio transport layer (eCPRI) fragmentation / reassembly
39 * - Detect/indicate signs of application layer fragmentation?
40 * - Not handling M-plane setting for "little endian byte order" as applied to IQ samples and beam weights
41 * - for section extensions, check more constraints (which other extension types appear with them, order)
42 * - when some section extensions are present, some section header fields are effectively ignored - flag any remaining ("ignored, "shall")?
43 * - re-order items (decl and hf definitions) to match spec order?
47 void proto_reg_handoff_oran(void);
48 void proto_register_oran(void);
50 /* Initialize the protocol and registered fields */
51 static int proto_oran
;
53 static int oran_tap
= -1;
55 static int hf_oran_du_port_id
;
56 static int hf_oran_bandsector_id
;
57 static int hf_oran_cc_id
;
58 static int hf_oran_ru_port_id
;
59 static int hf_oran_sequence_id
;
60 static int hf_oran_e_bit
;
61 static int hf_oran_subsequence_id
;
63 static int hf_oran_data_direction
;
64 static int hf_oran_payload_version
;
65 static int hf_oran_filter_index
;
66 static int hf_oran_frame_id
;
67 static int hf_oran_subframe_id
;
68 static int hf_oran_slot_id
;
69 static int hf_oran_slot_within_frame
;
70 static int hf_oran_start_symbol_id
;
71 static int hf_oran_numberOfSections
;
72 static int hf_oran_sectionType
;
74 static int hf_oran_udCompHdr
;
75 static int hf_oran_udCompHdrIqWidth
;
76 static int hf_oran_udCompHdrIqWidth_pref
;
77 static int hf_oran_udCompHdrMeth
;
78 static int hf_oran_udCompHdrMeth_pref
;
79 static int hf_oran_udCompLen
;
80 static int hf_oran_numberOfUEs
;
81 static int hf_oran_timeOffset
;
82 static int hf_oran_frameStructure_fft
;
83 static int hf_oran_frameStructure_subcarrier_spacing
;
84 static int hf_oran_cpLength
;
85 static int hf_oran_timing_header
;
86 static int hf_oran_section_id
;
87 static int hf_oran_rb
;
88 static int hf_oran_symInc
;
89 static int hf_oran_startPrbc
;
90 static int hf_oran_reMask_re1
;
91 static int hf_oran_reMask_re2
;
92 static int hf_oran_reMask_re3
;
93 static int hf_oran_reMask_re4
;
94 static int hf_oran_reMask_re5
;
95 static int hf_oran_reMask_re6
;
96 static int hf_oran_reMask_re7
;
97 static int hf_oran_reMask_re8
;
98 static int hf_oran_reMask_re9
;
99 static int hf_oran_reMask_re10
;
100 static int hf_oran_reMask_re11
;
101 static int hf_oran_reMask_re12
;
102 static int hf_oran_reMask
;
103 static int hf_oran_numPrbc
;
104 static int hf_oran_numSymbol
;
105 static int hf_oran_ef
;
106 static int hf_oran_beamId
;
108 static int hf_oran_ciCompHdr
;
109 static int hf_oran_ciCompHdrIqWidth
;
110 static int hf_oran_ciCompHdrMeth
;
111 static int hf_oran_ciCompOpt
;
113 static int hf_oran_extension
;
114 static int hf_oran_exttype
;
115 static int hf_oran_extlen
;
117 static int hf_oran_bfw_bundle
;
118 static int hf_oran_bfw_bundle_id
;
119 static int hf_oran_bfw
;
120 static int hf_oran_bfw_i
;
121 static int hf_oran_bfw_q
;
123 static int hf_oran_ueId
;
124 static int hf_oran_freqOffset
;
125 static int hf_oran_regularizationFactor
;
126 static int hf_oran_laaMsgType
;
127 static int hf_oran_laaMsgLen
;
128 static int hf_oran_lbtHandle
;
129 static int hf_oran_lbtDeferFactor
;
130 static int hf_oran_lbtBackoffCounter
;
131 static int hf_oran_lbtOffset
;
132 static int hf_oran_MCOT
;
133 static int hf_oran_lbtMode
;
134 static int hf_oran_sfnSfEnd
;
135 static int hf_oran_lbtPdschRes
;
136 static int hf_oran_sfStatus
;
137 static int hf_oran_initialPartialSF
;
138 static int hf_oran_lbtDrsRes
;
139 static int hf_oran_lbtBufErr
;
140 static int hf_oran_lbtTrafficClass
;
141 static int hf_oran_lbtCWConfig_H
;
142 static int hf_oran_lbtCWConfig_T
;
143 static int hf_oran_lbtCWR_Rst
;
145 static int hf_oran_reserved
;
146 static int hf_oran_reserved_1bit
;
147 static int hf_oran_reserved_2bits
;
148 static int hf_oran_reserved_4bits
;
149 static int hf_oran_reserved_last_4bits
;
150 static int hf_oran_reserved_last_5bits
;
151 static int hf_oran_reserved_6bits
;
152 static int hf_oran_reserved_last_6bits
;
153 static int hf_oran_reserved_7bits
;
154 static int hf_oran_reserved_last_7bits
;
155 static int hf_oran_reserved_8bits
;
156 static int hf_oran_reserved_16bits
;
157 static int hf_oran_reserved_15bits
;
158 static int hf_oran_reserved_bit1
;
159 static int hf_oran_reserved_bit2
;
160 static int hf_oran_reserved_bit4
;
161 static int hf_oran_reserved_bit5
;
162 static int hf_oran_reserved_bits123
;
163 static int hf_oran_reserved_bits456
;
165 static int hf_oran_bundle_offset
;
166 static int hf_oran_cont_ind
;
168 static int hf_oran_bfwCompHdr
;
169 static int hf_oran_bfwCompHdr_iqWidth
;
170 static int hf_oran_bfwCompHdr_compMeth
;
171 static int hf_oran_symbolId
;
172 static int hf_oran_startPrbu
;
173 static int hf_oran_numPrbu
;
175 static int hf_oran_udCompParam
;
176 static int hf_oran_sReSMask
;
177 static int hf_oran_sReSMask_re12
;
178 static int hf_oran_sReSMask_re11
;
179 static int hf_oran_sReSMask_re10
;
180 static int hf_oran_sReSMask_re9
;
181 static int hf_oran_sReSMask_re8
;
182 static int hf_oran_sReSMask_re7
;
183 static int hf_oran_sReSMask_re6
;
184 static int hf_oran_sReSMask_re5
;
185 static int hf_oran_sReSMask_re4
;
186 static int hf_oran_sReSMask_re3
;
187 static int hf_oran_sReSMask_re2
;
188 static int hf_oran_sReSMask_re1
;
190 static int hf_oran_sReSMask1
;
191 static int hf_oran_sReSMask2
;
192 static int hf_oran_sReSMask1_2_re12
;
193 static int hf_oran_sReSMask1_2_re11
;
194 static int hf_oran_sReSMask1_2_re10
;
195 static int hf_oran_sReSMask1_2_re9
;
197 static int hf_oran_bfwCompParam
;
199 static int hf_oran_iSample
;
200 static int hf_oran_qSample
;
202 static int hf_oran_ciCompParam
;
204 static int hf_oran_blockScaler
;
205 static int hf_oran_compBitWidth
;
206 static int hf_oran_compShift
;
208 static int hf_oran_repetition
;
209 static int hf_oran_rbgSize
;
210 static int hf_oran_rbgMask
;
211 static int hf_oran_noncontig_priority
;
212 static int hf_oran_symbolMask
;
214 static int hf_oran_exponent
;
215 static int hf_oran_iq_user_data
;
217 static int hf_oran_disable_bfws
;
218 static int hf_oran_rad
;
219 static int hf_oran_num_bund_prbs
;
220 static int hf_oran_beam_id
;
221 static int hf_oran_num_weights_per_bundle
;
223 static int hf_oran_ack_nack_req_id
;
225 static int hf_oran_off_start_prb_num_prb_pair
;
226 static int hf_oran_off_start_prb
;
227 static int hf_oran_num_prb
;
229 static int hf_oran_samples_prb
;
230 static int hf_oran_ciSample
;
231 static int hf_oran_ciIsample
;
232 static int hf_oran_ciQsample
;
234 static int hf_oran_beamGroupType
;
235 static int hf_oran_numPortc
;
237 static int hf_oran_csf
;
238 static int hf_oran_modcompscaler
;
240 static int hf_oran_modcomp_param_set
;
241 static int hf_oran_mc_scale_re_mask
;
242 static int hf_oran_mc_scale_offset
;
244 static int hf_oran_eAxC_mask
;
245 static int hf_oran_technology
;
246 static int hf_oran_nullLayerInd
;
248 static int hf_oran_portReMask
;
249 static int hf_oran_portSymbolMask
;
251 static int hf_oran_ext19_port
;
253 static int hf_oran_prb_allocation
;
254 static int hf_oran_nextSymbolId
;
255 static int hf_oran_nextStartPrbc
;
257 static int hf_oran_puncPattern
;
258 static int hf_oran_numPuncPatterns
;
259 static int hf_oran_symbolMask_ext20
;
260 static int hf_oran_startPuncPrb
;
261 static int hf_oran_numPuncPrb
;
262 static int hf_oran_puncReMask
;
263 static int hf_oran_multiSDScope
;
264 static int hf_oran_RbgIncl
;
266 static int hf_oran_ci_prb_group_size
;
267 static int hf_oran_prg_size_st5
;
268 static int hf_oran_prg_size_st6
;
270 static int hf_oran_num_ueid
;
272 static int hf_oran_antMask
;
274 static int hf_oran_transmissionWindowOffset
;
275 static int hf_oran_transmissionWindowSize
;
276 static int hf_oran_toT
;
278 static int hf_oran_bfaCompHdr
;
279 static int hf_oran_bfAzPtWidth
;
280 static int hf_oran_bfZePtWidth
;
281 static int hf_oran_bfAz3ddWidth
;
282 static int hf_oran_bfZe3ddWidth
;
283 static int hf_oran_bfAzPt
;
284 static int hf_oran_bfZePt
;
285 static int hf_oran_bfAz3dd
;
286 static int hf_oran_bfZe3dd
;
287 static int hf_oran_bfAzSl
;
288 static int hf_oran_bfZeSl
;
290 static int hf_oran_cmd_scope
;
291 static int hf_oran_number_of_st4_cmds
;
293 static int hf_oran_st4_cmd_header
;
294 static int hf_oran_st4_cmd_type
;
295 static int hf_oran_st4_cmd_len
;
296 static int hf_oran_st4_cmd_num_slots
;
297 static int hf_oran_st4_cmd_ack_nack_req_id
;
299 static int hf_oran_st4_cmd
;
301 static int hf_oran_sleepmode_trx
;
302 static int hf_oran_sleepmode_asm
;
303 static int hf_oran_log2maskbits
;
304 static int hf_oran_num_slots_ext
;
305 static int hf_oran_antMask_trx_control
;
307 static int hf_oran_ready
;
308 static int hf_oran_number_of_acks
;
309 static int hf_oran_number_of_nacks
;
310 static int hf_oran_ackid
;
311 static int hf_oran_nackid
;
313 static int hf_oran_acknack_request_frame
;
314 static int hf_oran_acknack_request_time
;
315 static int hf_oran_acknack_request_type
;
316 static int hf_oran_acknack_response_frame
;
317 static int hf_oran_acknack_response_time
;
319 static int hf_oran_disable_tdbfns
;
320 static int hf_oran_td_beam_group
;
321 static int hf_oran_disable_tdbfws
;
322 static int hf_oran_td_beam_num
;
324 static int hf_oran_dir_pattern
;
325 static int hf_oran_guard_pattern
;
327 static int hf_oran_ecpri_pcid
;
328 static int hf_oran_ecpri_rtcid
;
329 static int hf_oran_ecpri_seqid
;
331 static int hf_oran_num_sym_prb_pattern
;
332 static int hf_oran_prb_mode
;
333 static int hf_oran_sym_prb_pattern
;
334 static int hf_oran_sym_mask
;
335 static int hf_oran_num_mc_scale_offset
;
336 static int hf_oran_prb_pattern
;
337 static int hf_oran_prb_block_offset
;
338 static int hf_oran_prb_block_size
;
340 static int hf_oran_codebook_index
;
341 static int hf_oran_layerid
;
342 static int hf_oran_numlayers
;
343 static int hf_oran_txscheme
;
344 static int hf_oran_crs_remask
;
345 static int hf_oran_crs_shift
;
346 static int hf_oran_crs_symnum
;
347 static int hf_oran_beamid_ap1
;
348 static int hf_oran_beamid_ap2
;
349 static int hf_oran_beamid_ap3
;
351 static int hf_oran_port_list_index
;
352 static int hf_oran_alpn_per_sym
;
353 static int hf_oran_ant_dmrs_snr
;
354 static int hf_oran_user_group_size
;
355 static int hf_oran_user_group_id
;
356 static int hf_oran_entry_type
;
357 static int hf_oran_dmrs_port_number
;
358 static int hf_oran_ueid_reset
;
359 static int hf_oran_dmrs_symbol_mask
;
360 static int hf_oran_scrambling
;
361 static int hf_oran_nscid
;
362 static int hf_oran_dtype
;
363 static int hf_oran_cmd_without_data
;
364 static int hf_oran_lambda
;
365 static int hf_oran_first_prb
;
366 static int hf_oran_last_prb
;
367 static int hf_oran_low_papr_type
;
368 static int hf_oran_hopping_mode
;
370 static int hf_oran_tx_win_for_on_air_symbol_l
;
371 static int hf_oran_tx_win_for_on_air_symbol_r
;
373 static int hf_oran_num_fo_fb
;
374 static int hf_oran_freq_offset_fb
;
376 static int hf_oran_num_sinr_per_prb
;
377 static int hf_oran_sinr_value
;
379 static int hf_oran_measurement_report
;
380 static int hf_oran_mf
;
381 static int hf_oran_meas_data_size
;
382 static int hf_oran_meas_type_id
;
383 static int hf_oran_ipn_power
;
384 static int hf_oran_ue_tae
;
385 static int hf_oran_ue_layer_power
;
386 static int hf_oran_num_elements
;
387 static int hf_oran_ant_dmrs_snr_val
;
388 static int hf_oran_ue_freq_offset
;
390 static int hf_oran_beam_type
;
391 static int hf_oran_meas_cmd_size
;
393 static int hf_oran_symbol_reordering_layer
;
394 static int hf_oran_dmrs_entry
;
396 static int hf_oran_c_section_common
;
397 static int hf_oran_c_section
;
398 static int hf_oran_u_section
;
400 /* Computed fields */
401 static int hf_oran_c_eAxC_ID
;
402 static int hf_oran_refa
;
404 /* Hidden fields for filtering */
405 static int hf_oran_cplane
;
406 static int hf_oran_uplane
;
407 static int hf_oran_bf
; /* to match frames that configure beamforming in any way */
410 /* Initialize the subtree pointers */
412 static int ett_oran_ecpri_rtcid
;
413 static int ett_oran_ecpri_pcid
;
414 static int ett_oran_ecpri_seqid
;
415 static int ett_oran_section
;
416 static int ett_oran_section_type
;
417 static int ett_oran_u_timing
;
418 static int ett_oran_u_section
;
419 static int ett_oran_u_prb
;
420 static int ett_oran_iq
;
421 static int ett_oran_bfw_bundle
;
422 static int ett_oran_bfw
;
423 static int ett_oran_offset_start_prb_num_prb
;
424 static int ett_oran_prb_cisamples
;
425 static int ett_oran_cisample
;
426 static int ett_oran_udcomphdr
;
427 static int ett_oran_udcompparam
;
428 static int ett_oran_cicomphdr
;
429 static int ett_oran_cicompparam
;
430 static int ett_oran_bfwcomphdr
;
431 static int ett_oran_bfwcompparam
;
432 static int ett_oran_ext19_port
;
433 static int ett_oran_prb_allocation
;
434 static int ett_oran_punc_pattern
;
435 static int ett_oran_bfacomphdr
;
436 static int ett_oran_modcomp_param_set
;
437 static int ett_oran_st4_cmd_header
;
438 static int ett_oran_st4_cmd
;
439 static int ett_oran_sym_prb_pattern
;
440 static int ett_oran_measurement_report
;
441 static int ett_oran_sresmask
;
442 static int ett_oran_c_section_common
;
443 static int ett_oran_c_section
;
444 static int ett_oran_remask
;
445 static int ett_oran_symbol_reordering_layer
;
446 static int ett_oran_dmrs_entry
;
448 /* Don't want all extensions to open and close together. Use extType-1 entry */
449 static int ett_oran_c_section_extension
[HIGHEST_EXTTYPE
];
452 static expert_field ei_oran_unsupported_bfw_compression_method
;
453 static expert_field ei_oran_invalid_sample_bit_width
;
454 static expert_field ei_oran_reserved_numBundPrb
;
455 static expert_field ei_oran_extlen_wrong
;
456 static expert_field ei_oran_invalid_eaxc_bit_width
;
457 static expert_field ei_oran_extlen_zero
;
458 static expert_field ei_oran_rbg_size_reserved
;
459 static expert_field ei_oran_frame_length
;
460 static expert_field ei_oran_numprbc_ext21_zero
;
461 static expert_field ei_oran_ci_prb_group_size_reserved
;
462 static expert_field ei_oran_st8_nackid
;
463 static expert_field ei_oran_st4_no_cmds
;
464 static expert_field ei_oran_st4_zero_len_cmd
;
465 static expert_field ei_oran_st4_wrong_len_cmd
;
466 static expert_field ei_oran_st4_unknown_cmd
;
467 static expert_field ei_oran_mcot_out_of_range
;
468 static expert_field ei_oran_se10_unknown_beamgrouptype
;
469 static expert_field ei_oran_start_symbol_id_not_zero
;
470 static expert_field ei_oran_trx_control_cmd_scope
;
471 static expert_field ei_oran_unhandled_se
;
472 static expert_field ei_oran_bad_symbolmask
;
473 static expert_field ei_oran_numslots_not_zero
;
474 static expert_field ei_oran_version_unsupported
;
475 static expert_field ei_oran_laa_msg_type_unsupported
;
476 static expert_field ei_oran_se_on_unsupported_st
;
477 static expert_field ei_oran_cplane_unexpected_sequence_number
;
478 static expert_field ei_oran_uplane_unexpected_sequence_number
;
479 static expert_field ei_oran_acknack_no_request
;
480 static expert_field ei_oran_udpcomphdr_should_be_zero
;
481 static expert_field ei_oran_radio_fragmentation_c_plane
;
482 static expert_field ei_oran_radio_fragmentation_u_plane
;
483 static expert_field ei_oran_lastRbdid_out_of_range
;
484 static expert_field ei_oran_rbgMask_beyond_last_rbdid
;
485 static expert_field ei_oran_unexpected_measTypeId
;
486 static expert_field ei_oran_unsupported_compression_method
;
487 static expert_field ei_oran_ud_comp_len_wrong_size
;
488 static expert_field ei_oran_sresmask2_not_zero_with_rb
;
489 static expert_field ei_oran_st6_rb_shall_be_0
;
490 static expert_field ei_oran_st10_numsymbol_not_14
;
491 static expert_field ei_oran_st10_startsymbolid_not_0
;
494 /* These are the message types handled by this dissector */
495 #define ECPRI_MT_IQ_DATA 0
496 #define ECPRI_MT_RT_CTRL_DATA 2
499 /* Preference settings - try to set reasonable defaults */
500 static unsigned pref_du_port_id_bits
= 4;
501 static unsigned pref_bandsector_id_bits
= 4;
502 static unsigned pref_cc_id_bits
= 4;
503 static unsigned pref_ru_port_id_bits
= 4;
505 /* TODO: ideally should be per-flow */
506 static unsigned pref_sample_bit_width_uplink
= 14;
507 static unsigned pref_sample_bit_width_downlink
= 14;
509 /* 8.3.3.15 Compression schemes */
511 #define COMP_BLOCK_FP 1
512 #define COMP_BLOCK_SCALE 2
514 #define COMP_MODULATION 4
515 #define BFP_AND_SELECTIVE_RE 5
516 #define MOD_COMPR_AND_SELECTIVE_RE 6
517 #define BFP_AND_SELECTIVE_RE_WITH_MASKS 7
518 #define MOD_COMPR_AND_SELECTIVE_RE_WITH_MASKS 8
520 /* TODO: these ideally should be per-flow too */
521 static int pref_iqCompressionUplink
= COMP_BLOCK_FP
;
522 static int pref_iqCompressionDownlink
= COMP_BLOCK_FP
;
524 /* Is udCompHeader present (both directions) */
525 static int pref_includeUdCompHeaderUplink
= 2; /* start heuristic */
526 static int pref_includeUdCompHeaderDownlink
= 2; /* start heuristic */
528 static unsigned pref_data_plane_section_total_rbs
= 273;
529 static unsigned pref_num_weights_per_bundle
= 32;
530 static unsigned pref_num_bf_antennas
= 32;
531 static bool pref_showIQSampleValues
= true;
533 /* Based upon m-plane param, so will be system-wide */
534 static int pref_support_udcompLen
= 2; /* start heuristic, can force other settings if necessary */
535 static bool udcomplen_heuristic_result_set
= false;
536 static bool udcomplen_heuristic_result
= false;
539 static const enum_val_t dl_compression_options
[] = {
540 { "COMP_NONE", "No Compression", COMP_NONE
},
541 { "COMP_BLOCK_FP", "Block Floating Point Compression", COMP_BLOCK_FP
},
542 { "COMP_BLOCK_SCALE", "Block Scaling Compression", COMP_BLOCK_SCALE
},
543 { "COMP_U_LAW", "u-Law Compression", COMP_U_LAW
},
544 { "COMP_MODULATION", "Modulation Compression", COMP_MODULATION
},
545 { "BFP_AND_SELECTIVE_RE", "Block Floating Point + selective RE sending", BFP_AND_SELECTIVE_RE
},
546 { "MOD_COMPR_AND_SELECTIVE_RE", "Modulation Compression + selective RE sending", MOD_COMPR_AND_SELECTIVE_RE
},
547 { "BFP_AND_SELECTIVE_RE_WITH_MASKS", "Block Floating Point + selective RE sending with masks in section header", BFP_AND_SELECTIVE_RE_WITH_MASKS
},
548 { "MOD_COMPR_AND_SELECTIVE_RE_WITH_MASKS", "Modulation Compression + selective RE sending with masks in section header", MOD_COMPR_AND_SELECTIVE_RE
},
552 static const enum_val_t ul_compression_options
[] = {
553 { "COMP_NONE", "No Compression", COMP_NONE
},
554 { "COMP_BLOCK_FP", "Block Floating Point Compression", COMP_BLOCK_FP
},
555 { "COMP_BLOCK_SCALE", "Block Scaling Compression", COMP_BLOCK_SCALE
},
556 { "COMP_U_LAW", "u-Law Compression", COMP_U_LAW
},
557 { "BFP_AND_SELECTIVE_RE", "Block Floating Point + selective RE sending", BFP_AND_SELECTIVE_RE
},
558 { "BFP_AND_SELECTIVE_RE_WITH_MASKS", "Block Floating Point + selective RE sending with masks in section header", BFP_AND_SELECTIVE_RE_WITH_MASKS
},
562 static const enum_val_t udcomp_support_options
[] = {
563 { "NOT_SUPPORTED", "Not Supported", 0 },
564 { "SUPPORTED", "Supported", 1 },
565 { "HEURISTIC", "Use Heuristic", 2 },
569 static const enum_val_t udcomphdr_present_options
[] = {
570 { "NOT_PRESENT", "Present", 0 },
571 { "PRESENT", "Not Present", 1 },
572 { "HEURISTIC", "Attempt Heuristic", 2 },
577 static const value_string e_bit
[] = {
578 { 0, "More fragments follow" },
579 { 1, "Last fragment" },
584 #define DIR_DOWNLINK 1
587 static const value_string data_direction_vals
[] = {
588 { DIR_UPLINK
, "Uplink" }, /* gNB Rx */
589 { DIR_DOWNLINK
, "Downlink" }, /* gNB Tx */
593 static const value_string rb_vals
[] = {
594 { 0, "Every RB used" },
595 { 1, "Every other RB used" },
599 static const value_string sym_inc_vals
[] = {
600 { 0, "Use the current symbol number" },
601 { 1, "Increment the current symbol number" },
605 static const value_string lbtMode_vals
[] = {
606 { 0, "Full LBT (regular LBT, sending reservation signal until the beginning of the SF/slot)" },
607 { 1, "Partial LBT (looking back 25 usec prior to transmission" },
608 { 2, "Partial LBT (looking back 34 usec prior to transmission" },
609 { 3, "Full LBT and stop (regular LBT, without sending reservation signal" },
613 static const range_string filter_indices
[] = {
614 {0, 0, "standard channel filter"},
615 {1, 1, "UL filter for PRACH preamble formats 0, 1, 2; min. passband 839 x 1.25kHz = 1048.75 kHz"},
616 {2, 2, "UL filter for PRACH preamble format 3, min. passband 839 x 5 kHz = 4195 kHz"},
617 {3, 3, "UL filter for PRACH preamble formats A1, A2, A3, B1, B2, B3, B4, C0, C2; min. passband 139 x \u0394fRA"},
618 {4, 4, "UL filter for NPRACH 0, 1; min. passband 48 x 3.75KHz = 180 KHz"},
619 {5, 5, "UL filter for PRACH preamble formats"},
620 {8, 8, "UL filter NPUSCH"},
621 {9, 9, "Mixed numerology and other channels except PRACH and NB-IoT"},
626 static const range_string section_types
[] = {
627 { SEC_C_UNUSED_RB
, SEC_C_UNUSED_RB
, "Unused Resource Blocks or symbols in Downlink or Uplink" },
628 { SEC_C_NORMAL
, SEC_C_NORMAL
, "Most DL/UL radio channels" },
629 { SEC_C_RSVD2
, SEC_C_RSVD2
, "Reserved for future use" },
630 { SEC_C_PRACH
, SEC_C_PRACH
, "PRACH and mixed-numerology channels" },
631 { SEC_C_SLOT_CONTROL
, SEC_C_SLOT_CONTROL
, "Slot Configuration Control" },
632 { SEC_C_UE_SCHED
, SEC_C_UE_SCHED
, "UE scheduling information (UE-ID assignment to section)" },
633 { SEC_C_CH_INFO
, SEC_C_CH_INFO
, "Channel information" },
634 { SEC_C_LAA
, SEC_C_LAA
, "LAA (License Assisted Access)" },
635 { SEC_C_ACK_NACK_FEEDBACK
, SEC_C_ACK_NACK_FEEDBACK
, "ACK/NACK Feedback" },
636 { SEC_C_SINR_REPORTING
, SEC_C_SINR_REPORTING
, "SINR Reporting" },
637 { SEC_C_RRM_MEAS_REPORTS
, SEC_C_RRM_MEAS_REPORTS
, "RRM Measurement Reports" },
638 { SEC_C_REQUEST_RRM_MEAS
, SEC_C_REQUEST_RRM_MEAS
, "Request RRM Measurements" },
639 { 12, 255, "Reserved for future use" },
642 static const range_string section_types_short
[] = {
643 { SEC_C_UNUSED_RB
, SEC_C_UNUSED_RB
, "(Unused RBs) " },
644 { SEC_C_NORMAL
, SEC_C_NORMAL
, "(Most channels) " },
645 { SEC_C_RSVD2
, SEC_C_RSVD2
, "(reserved) " },
646 { SEC_C_PRACH
, SEC_C_PRACH
, "(PRACH/mixed-\u03bc)" },
647 { SEC_C_SLOT_CONTROL
, SEC_C_SLOT_CONTROL
, "(Slot info) " },
648 { SEC_C_UE_SCHED
, SEC_C_UE_SCHED
, "(UE scheduling info)" },
649 { SEC_C_CH_INFO
, SEC_C_CH_INFO
, "(Channel info) " },
650 { SEC_C_LAA
, SEC_C_LAA
, "(LAA) " },
651 { SEC_C_ACK_NACK_FEEDBACK
, SEC_C_ACK_NACK_FEEDBACK
, "(ACK/NACK) " },
652 { SEC_C_SINR_REPORTING
, SEC_C_SINR_REPORTING
, "(SINR Reporting) " },
653 { SEC_C_RRM_MEAS_REPORTS
, SEC_C_RRM_MEAS_REPORTS
, "(RRM Meas Reports) " },
654 { SEC_C_REQUEST_RRM_MEAS
, SEC_C_REQUEST_RRM_MEAS
, "(Req RRM Meas) " },
655 { 12, 255, "Reserved for future use" },
659 static const range_string ud_comp_header_width
[] = {
660 {0, 0, "I and Q are each 16 bits wide"},
661 {1, 15, "Bit width of I and Q"},
664 /* Table 8.3.3.13-3 */
665 static const range_string ud_comp_header_meth
[] = {
666 {COMP_NONE
, COMP_NONE
, "No compression" },
667 {COMP_BLOCK_FP
, COMP_BLOCK_FP
, "Block floating point compression" },
668 {COMP_BLOCK_SCALE
, COMP_BLOCK_SCALE
, "Block scaling" },
669 {COMP_U_LAW
, COMP_U_LAW
, "Mu - law" },
670 {COMP_MODULATION
, COMP_MODULATION
, "Modulation compression" },
671 {BFP_AND_SELECTIVE_RE
, BFP_AND_SELECTIVE_RE
, "BFP + selective RE sending" },
672 {MOD_COMPR_AND_SELECTIVE_RE
, MOD_COMPR_AND_SELECTIVE_RE
, "mod-compr + selective RE sending" },
673 {BFP_AND_SELECTIVE_RE_WITH_MASKS
, BFP_AND_SELECTIVE_RE_WITH_MASKS
, "BFP + selective RE sending with masks in section header" },
674 {MOD_COMPR_AND_SELECTIVE_RE_WITH_MASKS
, MOD_COMPR_AND_SELECTIVE_RE_WITH_MASKS
, "mod-compr + selective RE sending with masks in section header"},
679 /* Table 7.5.2.13-2 */
680 static const range_string frame_structure_fft
[] = {
681 {0, 0, "Reserved (no FFT/iFFT processing)"},
683 {4, 4, "FFT size 16"},
684 {5, 5, "FFT size 32"},
685 {6, 6, "FFT size 64"},
686 {7, 7, "FFT size 128"},
687 {8, 8, "FFT size 256"},
688 {9, 9, "FFT size 512"},
689 {10, 10, "FFT size 1024"},
690 {11, 11, "FFT size 2048"},
691 {12, 12, "FFT size 4096"},
692 {13, 13, "FFT size 1536"},
693 {14, 14, "FFT size 3072"},
694 {15, 15, "Reserved"},
698 /* Table 7.5.2.13-3 */
699 static const range_string subcarrier_spacings
[] = {
700 { 0, 0, "SCS 15 kHz, 1 slot/subframe, slot length 1 ms" },
701 { 1, 1, "SCS 30 kHz, 2 slots/subframe, slot length 500 \u03bcs" },
702 { 2, 2, "SCS 60 kHz, 4 slots/subframe, slot length 250 \u03bcs" },
703 { 3, 3, "SCS 120 kHz, 8 slots/subframe, slot length 125 \u03bcs" },
704 { 4, 4, "SCS 240 kHz, 16 slots/subframe, slot length 62.5 \u03bcs" },
705 { 5, 11, "Reserved" }, /* N.B., 5 was 480kHz in early spec versions */
706 { 12, 12, "SCS 1.25 kHz, 1 slot/subframe, slot length 1 ms" },
707 { 13, 13, "SCS 3.75 kHz(LTE - specific), 1 slot/subframe, slot length 1 ms" },
708 { 14, 14, "SCS 5 kHz, 1 slot/subframe, slot length 1 ms" },
709 { 15, 15, "SCS 7.5 kHz(LTE - specific), 1 slot/subframe, slot length 1 ms" },
713 /* Table 7.5.3.14-1 laaMsgType definition */
714 static const range_string laaMsgTypes
[] = {
715 {0, 0, "LBT_PDSCH_REQ - lls - O-DU to O-RU request to obtain a PDSCH channel"},
716 {1, 1, "LBT_DRS_REQ - lls - O-DU to O-RU request to obtain the channel and send DRS"},
717 {2, 2, "LBT_PDSCH_RSP - O-RU to O-DU response, channel acq success or failure"},
718 {3, 3, "LBT_DRS_RSP - O-RU to O-DU response, DRS sending success or failure"},
719 {4, 4, "LBT_Buffer_Error - O-RU to O-DU response, reporting buffer overflow"},
720 {5, 5, "LBT_CWCONFIG_REQ - O-DU to O-RU request, congestion window configuration"},
721 {6, 6, "LBT_CWCONFIG_RST - O-RU to O-DU request, congestion window config, response"},
722 {7, 15, "reserved for future methods"},
726 static const range_string freq_offset_fb_values
[] = {
727 {0, 0, "no frequency offset"},
728 {8000, 8000, "value not provided"},
729 {1, 30000, "positive frequency offset, (0, +0.5] subcarrier"},
730 {0x8ad0, 0xffff, "negative frequency offset, [-0.5, 0) subcarrier"},
731 {0x0, 0xffff, "reserved"},
735 static const value_string num_sinr_per_prb_vals
[] = {
747 static const value_string meas_type_id_vals
[] = {
748 { 1, "UE Timing Advance Error" },
749 { 2, "UE Layer power" },
750 { 3, "UE frequency offset" },
751 { 4, "Interference plus Noise for allocated PRBs" },
752 { 5, "Interference plus Noise for unallocated PRBs" },
753 { 6, "DMRS SNR per antenna" },
757 static const value_string beam_type_vals
[] = {
758 { 0, "List of beamId values" },
759 { 1, "Range of beamId values" },
765 static const value_string exttype_vals
[] = {
767 {1, "Beamforming weights"},
768 {2, "Beamforming attributes"},
769 {3, "DL Precoding configuration parameters and indications"},
770 {4, "Modulation compr. params"},
771 {5, "Modulation compression additional scaling parameters"},
772 {6, "Non-contiguous PRB allocation"},
773 {7, "Multiple-eAxC designation"},
774 {8, "Regularization factor"},
775 {9, "Dynamic Spectrum Sharing parameters"},
776 {10, "Multiple ports grouping"},
777 {11, "Flexible BF weights"},
778 {12, "Non-Contiguous PRB Allocation with Frequency Ranges"},
779 {13, "PRB Allocation with Frequency Hopping"},
780 {14, "Nulling-layer Info. for ueId-based beamforming"},
781 {15, "Mixed-numerology Info. for ueId-based beamforming"},
782 {16, "Section description for antenna mapping in UE channel information based UL beamforming"},
783 {17, "Section description for indication of user port group"},
784 {18, "Section description for Uplink Transmission Management"},
785 {19, "Compact beamforming information for multiple port"},
786 {20, "Puncturing extension"},
787 {21, "Variable PRB group size for channel information"},
788 {22, "ACK/NACK request"},
789 {23, "Multiple symbol modulation compression parameters"},
790 {24, "PUSCH DMRS configuration"},
791 {25, "Symbol reordering for DMRS-BF"},
792 {26, "Frequency offset feedback"},
793 {27, "O-DU controlled dimensionality reduction"},
797 /**************************************************************************************/
798 /* Keep track for each Section Extension, which section types are allowed to carry it */
810 static AllowedCTs_t ext_cts
[HIGHEST_EXTTYPE
] = {
811 /* ST0 ST1 ST3 ST5 ST6 ST10 ST11 */
812 { false, true, true, false, false, false, false}, // SE 1 (1,3)
813 { false, true, true, false, false, false, false}, // SE 2 (1,3)
814 { false, true, true, false, false, false, false}, // SE 3 (1,3)
815 { false, true, true, true, false, false, false}, // SE 4 (1,3,5)
816 { false, true, true, true, false, false, false}, // SE 5 (1,3,5)
817 { false, true, true, true, false, false, false}, // SE 6 (1,3,5)
818 { true, false, false, false, false, false, false}, // SE 7 (0)
819 { false, false, false, true, false, false, false}, // SE 8 (5)
820 { true, true, true, true, true, true, true }, // SE 9 (all)
821 { false, true, true, true, false, false, false}, // SE 10 (1,3,5)
822 { false, true, true, false, false, false, false}, // SE 11 (1,3)
823 { false, true, true, true, false, false, false}, // SE 12 (1,3,5)
824 { false, true, true, true, false, false, false}, // SE 13 (1,3,5)
825 { false, false, false, true, false, false, false}, // SE 14 (5)
826 { false, false, false, true, true, false, false}, // SE 15 (5,6)
827 { false, false, false, true, false, false, false}, // SE 16 (5)
828 { false, false, false, true, false, false, false}, // SE 17 (5)
829 { false, true, true, true, false, false, false}, // SE 18 (1,3,5)
830 { false, true, true, false, false, false, false}, // SE 19 (1,3)
831 { true, true, true, true, true, false, false}, // SE 20 (0,1,3,5)
832 { false, false, false, true, true, false, false}, // SE 21 (5,6)
833 { true, true, true, true, true, true, true }, // SE 22 (all)
834 { false, true, true, true, false, false, false}, // SE 23 (1,3,5)
835 { false, false, false, true, false, false, false }, // SE 24 (5)
836 { false, false, false, true, false, false, false }, // SE 25 (5)
837 { false, false, false, true, false, false, false }, // SE 26 (5)
838 { false, false, false, true, false, false, false }, // SE 27 (5)
843 static bool se_allowed_in_st(unsigned se
, unsigned ct
)
845 if (se
==0 || se
>HIGHEST_EXTTYPE
) {
846 /* Don't know about new SE, so don't complain.. */
852 return ext_cts
[se
-1].ST1
;
854 return ext_cts
[se
-1].ST3
;
856 return ext_cts
[se
-1].ST5
;
858 return ext_cts
[se
-1].ST6
;
860 /* New section type that includes 'ef'.. assume ok */
865 /************************************************************************************/
867 static const value_string bfw_comp_headers_iq_width
[] = {
868 {0, "I and Q are 16 bits wide"},
869 {1, "I and Q are 1 bit wide"},
870 {2, "I and Q are 2 bits wide"},
871 {3, "I and Q are 3 bits wide"},
872 {4, "I and Q are 4 bits wide"},
873 {5, "I and Q are 5 bits wide"},
874 {6, "I and Q are 6 bits wide"},
875 {7, "I and Q are 7 bits wide"},
876 {8, "I and Q are 8 bits wide"},
877 {9, "I and Q are 9 bits wide"},
878 {10, "I and Q are 10 bits wide"},
879 {11, "I and Q are 11 bits wide"},
880 {12, "I and Q are 12 bits wide"},
881 {13, "I and Q are 13 bits wide"},
882 {14, "I and Q are 14 bits wide"},
883 {15, "I and Q are 15 bits wide"},
887 /* Table 7.7.1.2-3 */
888 static const value_string bfw_comp_headers_comp_meth
[] = {
889 {COMP_NONE
, "no compression"},
890 {COMP_BLOCK_FP
, "block floating point"},
891 {COMP_BLOCK_SCALE
, "block scaling"},
892 {COMP_U_LAW
, "u-law"},
893 {4, "beamspace compression type I"},
894 {5, "beamspace compression type II"},
898 /* 7.7.6.2 rbgSize (resource block group size) */
899 static const value_string rbg_size_vals
[] = {
912 static const value_string priority_vals
[] = {
915 {2, "-2 (reserved, should not be used)"},
920 /* 7.7.10.2 beamGroupType */
921 static const value_string beam_group_type_vals
[] = {
922 {0x0, "common beam"},
923 {0x1, "beam matrix indication"},
924 {0x2, "beam vector listing"},
925 {0x3, "beamId/ueId listing with associated port-list index"},
929 /* 7.7.9.2 technology (interface name) */
930 static const value_string interface_name_vals
[] = {
936 /* 7.7.18.4 toT (type of transmission) */
937 static const value_string type_of_transmission_vals
[] = {
938 {0x0, "normal transmission mode, data can be distributed in any way the O-RU is implemented to transmit data"},
939 {0x1, "uniformly distributed over the transmission window"},
945 /* 7.7.2.2 (width of bfa parameters) */
946 static const value_string bfa_bw_vals
[] = {
947 {0, "no bits, the field is not applicable (e.g., O-RU does not support it) or the default value shall be used"},
948 {1, "2-bit bitwidth"},
949 {2, "3-bit bitwidth"},
950 {3, "4-bit bitwidth"},
951 {4, "5-bit bitwidth"},
952 {5, "6-bit bitwidth"},
953 {6, "7-bit bitwidth"},
954 {7, "8-bit bitwidth"},
958 /* 7.7.2.7 & 7.7.2.8 */
959 static const value_string sidelobe_suppression_vals
[] = {
971 static const value_string lbtTrafficClass_vals
[] = {
979 static const value_string lbtPdschRes_vals
[] = {
980 {0, "not sensing – indicates that the O-RU is transmitting data"},
981 {1, "currently sensing – indicates the O-RU has not yet acquired the channel"},
982 {2, "success – indicates that the channel was successfully acquired"},
983 {3, "Failure – indicates expiration of the LBT timer. The LBT process should be reset"},
987 static const value_string ci_comp_opt_vals
[] = {
988 {0, "compression per UE, one ciCompParam exists before the I/Q value of each UE"},
989 {1, "compression per PRB, one ciCompParam exists before the I/Q value of each PRB"},
993 static const range_string cmd_scope_vals
[] = {
994 {0, 0, "ARRAY-COMMAND"},
995 {1, 1, "CARRIER-COMMAND"},
996 {2, 2, "O-RU-COMMAND"},
1001 /* N.B., table in 7.5.3.38 is truncated.. */
1002 static const range_string st4_cmd_type_vals
[] = {
1003 {0, 0, "reserved for future command types"},
1004 {1, 1, "TIME_DOMAIN_BEAM_CONFIG"},
1005 {2, 2, "TDD_CONFIG_PATTERN"},
1006 {3, 3, "TRX_CONTROL"},
1008 {5, 255, "reserved for future command types"},
1012 /* Table 7.5.3.51-1 */
1013 static const value_string log2maskbits_vals
[] = {
1015 {1, "min antMask size is 16 bits.."},
1016 {2, "min antMask size is 16 bits.."},
1017 {3, "min antMask size is 16 bits.."},
1033 /* Table 16.1-1 Sleep modes */
1034 static const value_string sleep_mode_trx_vals
[] = {
1035 { 0, "TRXC-mode0-wake-up-duration (symbol)"},
1036 { 1, "TRXC-mode1-wake-up-duration (L)"},
1037 { 2, "TRXC-mode2-wake-up-duration (M)"},
1038 { 3, "TRXC-mode3-wake-up-duration (N)"},
1042 static const value_string sleep_mode_asm_vals
[] = {
1043 { 0, "ASM-mode0-wake-up-duration (symbol)"},
1044 { 1, "ASM-mode1-wake-up-duration (L)"},
1045 { 2, "ASM-mode2-wake-up-duration (M)"},
1046 { 3, "ASM-mode3-wake-up-duration (N)"},
1051 static const value_string prg_size_st5_vals
[] = {
1053 { 1, "Precoding resource block group size as WIDEBAND"},
1054 { 2, "Precoding resource block group size 2"},
1055 { 3, "Precoding resource block group size 4"},
1059 static const value_string prg_size_st6_vals
[] = {
1060 { 0, "if ciPrbGroupSize is 2 or 4, then ciPrbGroupSize, else WIDEBAND"},
1061 { 1, "Precoding resource block group size as WIDEBAND"},
1062 { 2, "Precoding resource block group size 2"},
1063 { 3, "Precoding resource block group size 4"},
1067 static const value_string alpn_per_sym_vals
[] = {
1068 { 0, "report one allocated IPN value per all allocated symbols with DMRS"},
1069 { 1, "report one allocated IPN value per group of consecutive DMRS symbols"},
1073 static const value_string ant_dmrs_snr_vals
[] = {
1074 { 0, "O-RU shall not report the MEAS_ANT_DMRS_SNR"},
1075 { 1, "O-RU shall report the MEAS_ANT_DMRS_SNR"},
1080 static const value_string dtype_vals
[] = {
1081 { 0, "assume DMRS configuration type 1"},
1082 { 1, "assume DMRS configuration type 2"},
1087 static const value_string papr_type_vals
[] = {
1088 { 0, "sequence generator type 1 for short sequence lengths"},
1089 { 1, "sequence generator type 1 for long sequence lengths"},
1090 { 2, "sequence generator type 2 for short sequence lengths"},
1091 { 3, "sequence generator type 2 for long sequence lengths"},
1096 static const value_string hopping_mode_vals
[] = {
1097 { 0, "neither group, nor sequence hopping is enabled"},
1098 { 1, "group hopping is enabled and sequence hopping is disabled"},
1099 { 2, "sequence hopping is enabled and group hopping is disabled"},
1105 static const true_false_string tfs_sfStatus
=
1107 "subframe was transmitted",
1108 "subframe was dropped"
1111 static const true_false_string tfs_lbtBufErr
=
1113 "buffer overflow – data received at O-RU is larger than the available buffer size",
1117 static const true_false_string tfs_partial_full_sf
= {
1122 static const true_false_string disable_tdbfns_tfs
= {
1123 "beam numbers excluded",
1124 "beam numbers included"
1127 static const true_false_string continuity_indication_tfs
= {
1128 "continuity between current and next bundle",
1129 "discontinuity between current and next bundle"
1132 static const true_false_string prb_mode_tfs
= {
1137 static const true_false_string symbol_direction_tfs
= {
1142 static const true_false_string symbol_guard_tfs
= {
1147 static const true_false_string beam_numbers_included_tfs
= {
1148 "time-domain beam numbers excluded in this command",
1149 "time-domain beam numbers included in this command"
1152 static const true_false_string measurement_flag_tfs
= {
1153 "at least one additional measurement report or command after the current one",
1154 "no additional measurement report or command"
1158 /* Forward declaration */
1159 static int dissect_udcompparam(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, unsigned offset
,
1161 uint32_t *exponent
, uint16_t *sReSMask
, bool for_sinr
);
1164 static const true_false_string ready_tfs
= {
1165 "message is a \"ready\" message",
1166 "message is a ACK message"
1169 static const true_false_string multi_sd_scope_tfs
= {
1170 "Puncturing pattern applies to current and following sections",
1171 "Puncturing pattern applies to current section"
1174 static const true_false_string tfs_ueid_reset
= {
1175 "cannot assume same UE as in preceding slot",
1176 "can assume same UE as in preceding slot"
1180 /* Config for (and later, worked-out allocations) bundles for ext11 (dynamic BFW) */
1184 uint8_t ext6_rbg_size
; /* number of PRBs allocated by bitmask */
1186 uint8_t ext6_num_bits_set
;
1187 uint8_t ext6_bits_set
[28]; /* Which bit position this entry has */
1188 /* TODO: store an f value for each bit position? */
1192 unsigned ext12_num_pairs
;
1193 #define MAX_BFW_EXT12_PAIRS 128
1195 uint8_t off_start_prb
;
1197 } ext12_pairs
[MAX_BFW_EXT12_PAIRS
];
1201 unsigned ext13_num_start_prbs
;
1202 #define MAX_BFW_EXT13_ALLOCATIONS 128
1203 unsigned ext13_start_prbs
[MAX_BFW_EXT13_ALLOCATIONS
];
1204 /* TODO: store nextSymbolId here too? */
1208 uint8_t ext21_ci_prb_group_size
;
1210 /* Results/settings (after calling ext11_work_out_bundles()) */
1211 uint32_t num_bundles
;
1212 #define MAX_BFW_BUNDLES 512
1214 uint32_t start
; /* first prb of bundle */
1215 uint32_t end
; /* last prb of bundle*/
1216 bool is_orphan
; /* true if not complete (i.e., end-start < numBundPrb) */
1217 } bundles
[MAX_BFW_BUNDLES
];
1221 /* Work out bundle allocation for ext 11. Take into account ext6/ext21, ext12 or ext13 in this section before ext 11. */
1222 /* Won't be called with numBundPrb=0 */
1223 static void ext11_work_out_bundles(unsigned startPrbc
,
1225 unsigned numBundPrb
, /* number of PRBs pre (full) bundle */
1226 ext11_settings_t
*settings
)
1228 /* Allocation configured by ext 6 */
1229 if (settings
->ext6_set
) {
1230 unsigned bundles_per_entry
= (settings
->ext6_rbg_size
/ numBundPrb
);
1232 /* Need to cope with these not dividing exactly, or even having more PRbs in a bundle that
1233 rbg size. i.e. each bundle gets the correct number of PRBs until
1234 all rbg entries are consumed... */
1236 /* TODO: need to check 7.9.4.2. Different cases depending upon value of RAD */
1238 if (bundles_per_entry
== 0) {
1239 bundles_per_entry
= 1;
1242 /* Maybe also be affected by ext 21 */
1243 if (settings
->ext21_set
) {
1244 /* N.B., have already checked that numPrbc is not 0 */
1246 /* ciPrbGroupSize overrides number of contiguous PRBs in group */
1247 bundles_per_entry
= (settings
->ext6_rbg_size
/ settings
->ext21_ci_prb_group_size
);
1249 /* numPrbc is the number of PRB groups per antenna - handled in call to dissect_bfw_bundle() */
1252 unsigned bundles_set
= 0;
1254 n
< (settings
->ext6_num_bits_set
* settings
->ext6_rbg_size
) / numBundPrb
;
1257 /* Watch out for array bound */
1262 /* For each bundle... */
1264 /* TODO: Work out where first PRB is */
1265 /* May not be the start of an rbg block... */
1266 uint32_t prb_start
= (settings
->ext6_bits_set
[n
] * settings
->ext6_rbg_size
);
1268 /* For each bundle within identified rbgSize block */
1269 for (unsigned m
=0; m
< bundles_per_entry
; m
++) {
1270 settings
->bundles
[bundles_set
].start
= startPrbc
+prb_start
+(m
*numBundPrb
);
1271 /* Start already beyond end, so doesn't count. */
1272 if (settings
->bundles
[bundles_set
].start
> (startPrbc
+numPrbc
-1)) {
1275 /* Bundle consists of numBundPrb bundles */
1276 /* TODO: may involve PRBs from >1 rbg blocks.. */
1277 settings
->bundles
[bundles_set
].end
= startPrbc
+prb_start
+((m
+1)*numBundPrb
)-1;
1278 if (settings
->bundles
[bundles_set
].end
> (startPrbc
+numPrbc
-1)) {
1279 /* Extends beyond end, so counts but is an orphan bundle */
1280 settings
->bundles
[bundles_set
].end
= numPrbc
;
1281 settings
->bundles
[bundles_set
].is_orphan
= true;
1284 /* Get out if have reached array bound */
1285 if (++bundles_set
== MAX_BFW_BUNDLES
) {
1290 settings
->num_bundles
= bundles_set
;
1293 /* Allocation configured by ext 12 */
1294 else if (settings
->ext12_set
) {
1295 /* First, allocate normally from startPrbc, numPrbc */
1296 settings
->num_bundles
= (numPrbc
+numBundPrb
-1) / numBundPrb
;
1298 /* Don't overflow settings->bundles[] ! */
1299 settings
->num_bundles
= MIN(MAX_BFW_BUNDLES
, settings
->num_bundles
);
1301 for (uint32_t n
=0; n
< settings
->num_bundles
; n
++) {
1302 settings
->bundles
[n
].start
= startPrbc
+ n
*numBundPrb
;
1303 settings
->bundles
[n
].end
= settings
->bundles
[n
].start
+ numBundPrb
-1;
1304 /* Does it go beyond the end? */
1305 if (settings
->bundles
[n
].end
> startPrbc
+numPrbc
) {
1306 settings
->bundles
[n
].end
= numPrbc
+numPrbc
;
1307 settings
->bundles
[n
].is_orphan
= true;
1310 if (settings
->num_bundles
== MAX_BFW_BUNDLES
) {
1314 unsigned prb_offset
= startPrbc
+ numPrbc
;
1316 /* Loop over pairs, adding bundles for each */
1317 for (unsigned p
=0; p
< settings
->ext12_num_pairs
; p
++) {
1318 prb_offset
+= settings
->ext12_pairs
[p
].off_start_prb
;
1319 unsigned pair_bundles
= (settings
->ext12_pairs
[p
].num_prb
+numBundPrb
-1) / numBundPrb
;
1321 for (uint32_t n
=0; n
< pair_bundles
; n
++) {
1322 unsigned idx
= settings
->num_bundles
;
1324 settings
->bundles
[idx
].start
= prb_offset
+ n
*numBundPrb
;
1325 settings
->bundles
[idx
].end
= settings
->bundles
[idx
].start
+ numBundPrb
-1;
1326 /* Does it go beyond the end? */
1327 if (settings
->bundles
[idx
].end
> prb_offset
+ settings
->ext12_pairs
[p
].num_prb
) {
1328 settings
->bundles
[idx
].end
= prb_offset
+ settings
->ext12_pairs
[p
].num_prb
;
1329 settings
->bundles
[idx
].is_orphan
= true;
1331 /* Range check / return */
1332 settings
->num_bundles
++;
1333 if (settings
->num_bundles
== MAX_BFW_BUNDLES
) {
1338 prb_offset
+= settings
->ext12_pairs
[p
].num_prb
;
1342 /* Allocation configured by ext 13 */
1343 else if (settings
->ext13_set
) {
1344 unsigned alloc_size
= (numPrbc
+numBundPrb
-1) / numBundPrb
;
1345 settings
->num_bundles
= alloc_size
* settings
->ext13_num_start_prbs
;
1347 /* Don't overflow settings->bundles[] ! */
1348 settings
->num_bundles
= MIN(MAX_BFW_BUNDLES
, settings
->num_bundles
);
1350 for (unsigned alloc
=0; alloc
< settings
->ext13_num_start_prbs
; alloc
++) {
1351 unsigned alloc_start
= alloc
* alloc_size
;
1352 for (uint32_t n
=0; n
< alloc_size
; n
++) {
1353 if ((alloc_start
+n
) >= MAX_BFW_BUNDLES
) {
1357 settings
->bundles
[alloc_start
+n
].start
= settings
->ext13_start_prbs
[alloc
] + startPrbc
+ n
*numBundPrb
;
1358 settings
->bundles
[alloc_start
+n
].end
= settings
->bundles
[alloc_start
+n
].start
+ numBundPrb
-1;
1359 if (settings
->bundles
[alloc_start
+n
].end
> settings
->ext13_start_prbs
[alloc
] + numPrbc
) {
1360 settings
->bundles
[alloc_start
+n
].end
= settings
->ext13_start_prbs
[alloc
] + numPrbc
;
1361 settings
->bundles
[alloc_start
+n
].is_orphan
= true;
1367 /* Bundles not controlled by other extensions - just divide up range into bundles we have */
1369 settings
->num_bundles
= (numPrbc
+numBundPrb
-1) / numBundPrb
;
1371 /* Don't overflow settings->bundles[] ! */
1372 settings
->num_bundles
= MIN(MAX_BFW_BUNDLES
, settings
->num_bundles
);
1374 for (uint32_t n
=0; n
< settings
->num_bundles
; n
++) {
1375 settings
->bundles
[n
].start
= startPrbc
+ n
*numBundPrb
;
1376 settings
->bundles
[n
].end
= settings
->bundles
[n
].start
+ numBundPrb
-1;
1377 /* Does it go beyond the end? */
1378 if (settings
->bundles
[n
].end
> startPrbc
+numPrbc
) {
1379 settings
->bundles
[n
].end
= numPrbc
+numPrbc
;
1380 settings
->bundles
[n
].is_orphan
= true;
1387 /*******************************************************/
1388 /* Overall state of a flow (eAxC/plane) */
1390 /* State for sequence analysis [each direction] */
1391 bool last_frame_seen
[2];
1392 uint32_t last_frame
[2];
1393 uint8_t next_expected_sequence_number
[2];
1395 /* Table recording ackNack requests (ackNackId -> ack_nack_request_t*)
1396 Note that this assumes that the same ackNackId will not be reused within a state,
1397 which may well not be valid */
1398 wmem_tree_t
*ack_nack_requests
;
1400 /* Store udCompHdr seen in C-Plane for UL - can be looked up and used by U-PLane.
1401 Note that this appears in the common section header parts of ST1, ST3, ST5,
1402 so can still be over-written per sectionId in the U-Plane */
1403 bool ul_ud_comp_hdr_set
;
1404 unsigned ul_ud_comp_hdr_bit_width
;
1405 int ul_ud_comp_hdr_compression
;
1407 bool udcomphdrDownlink_heuristic_result_set
;
1408 bool udcomphdrDownlink_heuristic_result
;
1409 bool udcomphdrUplink_heuristic_result_set
;
1410 bool udcomphdrUplink_heuristic_result
;
1412 /* Modulation compression params */
1413 /* TODO: incomplete (see SE4, SE5, SE23), and needs to be per section! */
1414 //uint16_t mod_comp_re_mask;
1415 //bool mod_compr_csf;
1416 //double mod_compr_mod_comp_scaler;
1420 uint32_t request_frame_number
;
1421 nstime_t request_frame_time
;
1430 uint32_t response_frame_number
;
1431 nstime_t response_frame_time
;
1432 } ack_nack_request_t
;
1434 static const value_string acknack_type_vals
[] = {
1436 { ST4Cmd1
, "ST4 (TIME_DOMAIN_BEAM_CONFIG)" },
1437 { ST4Cmd2
, "ST4 (TDD_CONFIG_PATTERN)" },
1438 { ST4Cmd3
, "ST4 (TRX_CONTROL)" },
1439 { ST4Cmd4
, "ST4 (ASM)" },
1443 #define ORAN_C_PLANE 0
1444 #define ORAN_U_PLANE 1
1446 static uint32_t make_flow_key(uint16_t eaxc_id
, uint8_t plane
)
1448 return eaxc_id
| (plane
<< 16);
1452 /* Table maintained on first pass from flow_key(uint32_t) -> flow_state_t* */
1453 static wmem_tree_t
*flow_states_table
;
1455 /* Table consulted on subsequent passes: frame_num -> flow_result_t* */
1456 static wmem_tree_t
*flow_results_table
;
1459 /* Sequence analysis */
1460 bool unexpected_seq_number
;
1461 uint8_t expected_sequence_number
;
1462 uint32_t previous_frame
;
1465 static void show_link_to_acknack_response(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
*pinfo
,
1466 ack_nack_request_t
*response
);
1471 static void write_pdu_label_and_info(proto_item
*ti1
, proto_item
*ti2
,
1472 packet_info
*pinfo
, const char *format
, ...) G_GNUC_PRINTF(4, 5);
1474 /* Write the given formatted text to:
1475 - the info column (if pinfo != NULL)
1476 - 1 or 2 other labels (optional)
1478 static void write_pdu_label_and_info(proto_item
*ti1
, proto_item
*ti2
,
1479 packet_info
*pinfo
, const char *format
, ...)
1481 #define MAX_INFO_BUFFER 256
1482 char info_buffer
[MAX_INFO_BUFFER
];
1485 if ((ti1
== NULL
) && (ti2
== NULL
) && (pinfo
== NULL
)) {
1489 va_start(ap
, format
);
1490 vsnprintf(info_buffer
, MAX_INFO_BUFFER
, format
, ap
);
1493 /* Add to indicated places */
1494 if (pinfo
!= NULL
) {
1495 col_append_str(pinfo
->cinfo
, COL_INFO
, info_buffer
);
1498 proto_item_append_text(ti1
, "%s", info_buffer
);
1501 proto_item_append_text(ti2
, "%s", info_buffer
);
1505 /* Add section labels (type + PRB range) for C-Plane, U-Plane */
1507 write_section_info(proto_item
*section_heading
, packet_info
*pinfo
, proto_item
*protocol_item
,
1508 uint32_t section_id
, uint32_t start_prbx
, uint32_t num_prbx
, uint32_t rb
)
1513 write_pdu_label_and_info(section_heading
, protocol_item
, pinfo
, ", Id: %4d (all PRBs) ", section_id
);
1517 write_pdu_label_and_info(section_heading
, protocol_item
, pinfo
, ", Id: %4d (PRB: %7u)", section_id
, start_prbx
);
1521 write_pdu_label_and_info(section_heading
, protocol_item
, pinfo
, ", Id: %4d (PRB: %3u-%3u%s)", section_id
, start_prbx
,
1522 start_prbx
+ (num_prbx
-1)*(1+rb
), rb
? " (every-other)" : "");
1527 write_channel_section_info(proto_item
*section_heading
, packet_info
*pinfo
,
1528 uint32_t section_id
, uint32_t ueId
, uint32_t start_prbx
, uint32_t num_prbx
,
1537 write_pdu_label_and_info(section_heading
, NULL
, pinfo
,
1538 ", Id: %4d (UEId=%3u PRB %7u, %2u antennas)",
1539 section_id
, ueId
, start_prbx
, num_trx
);
1543 write_pdu_label_and_info(section_heading
, NULL
, pinfo
,
1544 ", Id: %4d (UEId=%3u PRBs %3u-%3u, %2u antennas)",
1545 section_id
, ueId
, start_prbx
, start_prbx
+num_prbx
-1, num_trx
);
1550 /* 5.1.3.2.7 (real time control data / IQ data transfer message series identifier) */
1552 addPcOrRtcid(tvbuff_t
*tvb
, proto_tree
*tree
, int *offset
, int hf
, uint16_t *eAxC
)
1555 proto_item
*oran_pcid_ti
= proto_tree_add_item(tree
, hf
,
1556 tvb
, *offset
, 2, ENC_NA
);
1557 proto_tree
*oran_pcid_tree
= proto_item_add_subtree(oran_pcid_ti
, ett_oran_ecpri_pcid
);
1559 uint64_t duPortId
, bandSectorId
, ccId
, ruPortId
= 0;
1560 int id_offset
= *offset
;
1562 /* All parts of eAxC should be above 0, and should total 16 bits (breakdown controlled by preferences) */
1563 if (!((pref_du_port_id_bits
> 0) && (pref_bandsector_id_bits
> 0) && (pref_cc_id_bits
> 0) && (pref_ru_port_id_bits
> 0) &&
1564 ((pref_du_port_id_bits
+ pref_bandsector_id_bits
+ pref_cc_id_bits
+ pref_ru_port_id_bits
) == 16))) {
1565 expert_add_info(NULL
, tree
, &ei_oran_invalid_eaxc_bit_width
);
1571 unsigned bit_offset
= *offset
* 8;
1573 /* N.B. For sequence analysis / tapping, just interpret these 2 bytes as eAxC ID... */
1574 *eAxC
= tvb_get_uint16(tvb
, *offset
, ENC_BIG_ENDIAN
);
1577 proto_tree_add_bits_ret_val(oran_pcid_tree
, hf_oran_du_port_id
, tvb
, bit_offset
, pref_du_port_id_bits
, &duPortId
, ENC_BIG_ENDIAN
);
1578 bit_offset
+= pref_du_port_id_bits
;
1580 proto_tree_add_bits_ret_val(oran_pcid_tree
, hf_oran_bandsector_id
, tvb
, bit_offset
, pref_bandsector_id_bits
, &bandSectorId
, ENC_BIG_ENDIAN
);
1581 bit_offset
+= pref_bandsector_id_bits
;
1583 proto_tree_add_bits_ret_val(oran_pcid_tree
, hf_oran_cc_id
, tvb
, bit_offset
, pref_cc_id_bits
, &ccId
, ENC_BIG_ENDIAN
);
1584 bit_offset
+= pref_cc_id_bits
;
1586 proto_tree_add_bits_ret_val(oran_pcid_tree
, hf_oran_ru_port_id
, tvb
, bit_offset
, pref_ru_port_id_bits
, &ruPortId
, ENC_BIG_ENDIAN
);
1589 proto_item_append_text(oran_pcid_ti
, " (DU_Port_ID: %d, BandSector_ID: %d, CC_ID: %d, RU_Port_ID: %d)",
1590 (int)duPortId
, (int)bandSectorId
, (int)ccId
, (int)ruPortId
);
1592 snprintf(id
, 16, "%x:%x:%x:%x", (int)duPortId
, (int)bandSectorId
, (int)ccId
, (int)ruPortId
);
1593 proto_item
*pi
= proto_tree_add_string(oran_pcid_tree
, hf_oran_c_eAxC_ID
, tvb
, id_offset
, 2, id
);
1594 proto_item_set_generated(pi
);
1597 /* 5.1.3.2.8 ecpriSeqid (message identifier) */
1599 addSeqid(tvbuff_t
*tvb
, proto_tree
*oran_tree
, int offset
, int plane
, uint8_t *seq_id
, proto_item
**seq_id_ti
)
1602 proto_item
*seqIdItem
= proto_tree_add_item(oran_tree
, hf_oran_ecpri_seqid
, tvb
, offset
, 2, ENC_NA
);
1603 proto_tree
*oran_seqid_tree
= proto_item_add_subtree(seqIdItem
, ett_oran_ecpri_seqid
);
1604 uint32_t seqId
, subSeqId
, e
= 0;
1605 /* Sequence ID (8 bits) */
1606 *seq_id_ti
= proto_tree_add_item_ret_uint(oran_seqid_tree
, hf_oran_sequence_id
, tvb
, offset
, 1, ENC_NA
, &seqId
);
1610 proto_tree_add_item_ret_uint(oran_seqid_tree
, hf_oran_e_bit
, tvb
, offset
, 1, ENC_NA
, &e
);
1611 /* Subsequence ID (7 bits) */
1612 proto_tree_add_item_ret_uint(oran_seqid_tree
, hf_oran_subsequence_id
, tvb
, offset
, 1, ENC_NA
, &subSeqId
);
1615 /* radio-transport fragmentation not allowed for C-Plane messages */
1616 if (plane
== ORAN_C_PLANE
) {
1617 if (e
!=1 || subSeqId
!= 0) {
1618 expert_add_info(NULL
, seqIdItem
, &ei_oran_radio_fragmentation_c_plane
);
1622 if (e
!=1 || subSeqId
!= 0) {
1623 /* TODO: Re-assembly of any radio-fragmentation on U-Plane */
1624 expert_add_info(NULL
, seqIdItem
, &ei_oran_radio_fragmentation_u_plane
);
1629 proto_item_append_text(seqIdItem
, " (SeqId: %3d, E: %d, SubSeqId: %d)", seqId
, e
, subSeqId
);
1634 /* 7.7.1.2 bfwCompHdr (beamforming weight compression header) */
1635 static int dissect_bfwCompHdr(tvbuff_t
*tvb
, proto_tree
*tree
, int offset
,
1636 uint32_t *iq_width
, uint32_t *comp_meth
, proto_item
**comp_meth_ti
)
1639 proto_item
*bfwcomphdr_ti
= proto_tree_add_string_format(tree
, hf_oran_bfwCompHdr
,
1642 proto_tree
*bfwcomphdr_tree
= proto_item_add_subtree(bfwcomphdr_ti
, ett_oran_bfwcomphdr
);
1644 /* Width and method */
1645 proto_tree_add_item_ret_uint(bfwcomphdr_tree
, hf_oran_bfwCompHdr_iqWidth
,
1646 tvb
, offset
, 1, ENC_BIG_ENDIAN
, iq_width
);
1647 /* Special case: 0 -> 16 */
1648 *iq_width
= (*iq_width
==0) ? 16 : *iq_width
;
1649 *comp_meth_ti
= proto_tree_add_item_ret_uint(bfwcomphdr_tree
, hf_oran_bfwCompHdr_compMeth
,
1650 tvb
, offset
, 1, ENC_BIG_ENDIAN
, comp_meth
);
1654 proto_item_append_text(bfwcomphdr_ti
, " (IqWidth=%u, compMeth=%s)",
1656 val_to_str_const(*comp_meth
, bfw_comp_headers_comp_meth
, "reserved"));
1661 /* 7.7.1.3 bfwCompParam (beamforming weight compression parameter).
1662 * Depends upon passed-in bfwCompMeth (field may be empty) */
1663 static int dissect_bfwCompParam(tvbuff_t
*tvb
, proto_tree
*tree
, packet_info
*pinfo
, int offset
,
1664 proto_item
*meth_ti
, uint32_t bfw_comp_method
,
1665 uint32_t *exponent
, bool *supported
)
1667 if (bfw_comp_method
== COMP_NONE
) {
1674 proto_item
*bfwcompparam_ti
= proto_tree_add_string_format(tree
, hf_oran_bfwCompParam
,
1677 proto_tree
*bfwcompparam_tree
= proto_item_add_subtree(bfwcompparam_ti
, ett_oran_bfwcompparam
);
1679 proto_item_append_text(bfwcompparam_ti
,
1680 " (meth=%s)", val_to_str_const(bfw_comp_method
, bfw_comp_headers_comp_meth
, "reserved"));
1683 switch (bfw_comp_method
) {
1684 case COMP_BLOCK_FP
: /* block floating point */
1685 /* 4 reserved bits + exponent */
1686 proto_tree_add_item_ret_uint(bfwcompparam_tree
, hf_oran_exponent
,
1687 tvb
, offset
, 1, ENC_BIG_ENDIAN
, exponent
);
1688 proto_item_append_text(bfwcompparam_ti
, " exponent=%u", *exponent
);
1692 case COMP_BLOCK_SCALE
: /* block scaling */
1693 /* Separate into integer and fractional bits? */
1694 proto_tree_add_item(bfwcompparam_tree
, hf_oran_blockScaler
,
1695 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1698 case COMP_U_LAW
: /* u-law */
1699 /* compBitWidth, compShift */
1700 proto_tree_add_item(bfwcompparam_tree
, hf_oran_compBitWidth
,
1701 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1702 proto_tree_add_item(bfwcompparam_tree
, hf_oran_compShift
,
1703 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1706 case 4: /* beamspace I */
1707 /* TODO: activeBeamspaceCoefficientMask - ceil(K/8) octets */
1708 /* proto_tree_add_item(extension_tree, hf_oran_blockScaler,
1709 tvb, offset, 1, ENC_BIG_ENDIAN);
1712 case 5: /* beamspace II */
1713 /* TODO: activeBeamspaceCoefficientMask - ceil(K/8) octets */
1714 /* reserved (4 bits) + exponent (4 bits)
1715 proto_tree_add_item(bfwcompparam_tree, hf_oran_reserved_4bits, tvb, offset, 1, ENC_NA);
1716 proto_tree_add_item_ret_uint(bfwcompparam_tree, hf_oran_exponent, tvb, offset, 1, ENC_BIG_ENDIAN, exponent);
1726 /* Can't go on if compression scheme not supported */
1727 if (!(*supported
) && meth_ti
) {
1728 expert_add_info_format(pinfo
, meth_ti
, &ei_oran_unsupported_bfw_compression_method
,
1729 "BFW Compression method %u (%s) not decompressed by dissector",
1731 val_to_str_const(bfw_comp_method
, bfw_comp_headers_comp_meth
, "reserved"));
1737 /* Special case for uncompressed/16-bit value */
1738 static float uncompressed_to_float(uint32_t h
)
1740 int16_t i16
= h
& 0x0000ffff;
1741 return ((float)i16
) / 0x7fff;
1744 /* Decompress I/Q value, taking into account method, width, exponent, other input-specific methods */
1745 /* TODO: pass in info needed for Modulation (reMask, csf, mcScaler values) gleaned from SE 4,5,23 */
1746 static float decompress_value(uint32_t bits
, uint32_t comp_method
, uint8_t iq_width
, uint32_t exponent
)
1748 switch (comp_method
) {
1749 case COMP_NONE
: /* no compression */
1750 return uncompressed_to_float(bits
);
1752 case COMP_BLOCK_FP
: /* block floating point */
1753 case BFP_AND_SELECTIVE_RE
:
1755 /* A.1.2 Block Floating Point Decompression Algorithm */
1756 int32_t cPRB
= bits
;
1757 uint32_t scaler
= 1 << exponent
; /* i.e. 2^exponent */
1759 /* Check last bit, in case we need to flip to -ve */
1760 if (cPRB
>= (1<<(iq_width
-1))) {
1761 cPRB
-= (1<<iq_width
);
1766 uint32_t mantissa_scale_factor
= (1 << (iq_width
-1)) - 1;
1767 uint32_t exp_scale_factor
= 1 << (iq_width
+4);
1769 float ret
= cPRB
/ ((float)(mantissa_scale_factor
*exp_scale_factor
));
1773 case COMP_BLOCK_SCALE
:
1775 /* Not supported! But will be reported as expert info outside of this function! */
1778 case COMP_MODULATION
:
1779 case MOD_COMPR_AND_SELECTIVE_RE
:
1785 /* Not supported! But will be reported as expert info outside of this function! */
1790 /* Out-of-range value used for special case */
1791 #define ORPHAN_BUNDLE_NUMBER 999
1793 /* Bundle of PRBs/TRX I/Q samples (ext 11) */
1794 static uint32_t dissect_bfw_bundle(tvbuff_t
*tvb
, proto_tree
*tree
, packet_info
*pinfo
, unsigned offset
,
1795 proto_item
*comp_meth_ti
, uint32_t bfwcomphdr_comp_meth
,
1796 uint32_t num_weights_per_bundle
,
1798 unsigned bundle_number
,
1799 unsigned first_prb
, unsigned last_prb
, bool is_orphan
)
1801 /* Set bundle name */
1802 char bundle_name
[32];
1804 snprintf(bundle_name
, 32, "Bundle %3u", bundle_number
);
1807 g_strlcpy(bundle_name
, "Orphaned ", 32);
1810 /* Create Bundle root */
1811 proto_item
*bundle_ti
;
1812 if (first_prb
!= last_prb
) {
1813 bundle_ti
= proto_tree_add_string_format(tree
, hf_oran_bfw_bundle
,
1815 "%s: (PRBs %3u-%3u)",
1817 first_prb
, last_prb
);
1820 bundle_ti
= proto_tree_add_string_format(tree
, hf_oran_bfw_bundle
,
1826 proto_tree
*bundle_tree
= proto_item_add_subtree(bundle_ti
, ett_oran_bfw_bundle
);
1828 /* Generated bundle id */
1829 proto_item
*bundleid_ti
= proto_tree_add_uint(bundle_tree
, hf_oran_bfw_bundle_id
, tvb
, 0, 0,
1831 proto_item_set_generated(bundleid_ti
);
1832 proto_item_set_hidden(bundleid_ti
);
1835 bool compression_method_supported
= false;
1836 unsigned exponent
= 0;
1837 offset
= dissect_bfwCompParam(tvb
, bundle_tree
, pinfo
, offset
, comp_meth_ti
,
1838 bfwcomphdr_comp_meth
, &exponent
, &compression_method_supported
);
1840 /* Can't show details of unsupported compression method */
1841 if (!compression_method_supported
) {
1842 /* Don't know how to show, so give up */
1846 /* Create Bundle subtree */
1847 int bit_offset
= offset
*8;
1849 int prb_offset
= offset
;
1852 proto_tree_add_item(bundle_tree
, hf_oran_cont_ind
,
1853 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1856 proto_tree_add_item_ret_uint(bundle_tree
, hf_oran_beam_id
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &beam_id
);
1857 proto_item_append_text(bundle_ti
, " (beamId:%u) ", beam_id
);
1860 /* Number of weights per bundle (from preference) */
1861 proto_item
*wpb_ti
= proto_tree_add_uint(bundle_tree
, hf_oran_num_weights_per_bundle
, tvb
, 0, 0,
1862 num_weights_per_bundle
);
1863 proto_item_set_generated(wpb_ti
);
1865 /* Add the weights for this bundle */
1866 for (unsigned w
=0; w
< num_weights_per_bundle
; w
++) {
1868 /* Create subtree */
1869 bfw_offset
= bit_offset
/ 8;
1870 uint8_t bfw_extent
= ((bit_offset
+ (iq_width
*2)) / 8) - bfw_offset
;
1871 proto_item
*bfw_ti
= proto_tree_add_string_format(bundle_tree
, hf_oran_bfw
,
1872 tvb
, bfw_offset
, bfw_extent
,
1873 "", "TRX %3u: (", w
);
1874 proto_tree
*bfw_tree
= proto_item_add_subtree(bfw_ti
, ett_oran_bfw
);
1877 /* Get bits, and convert to float. */
1878 uint32_t bits
= tvb_get_bits(tvb
, bit_offset
, iq_width
, ENC_BIG_ENDIAN
);
1879 float value
= decompress_value(bits
, bfwcomphdr_comp_meth
, iq_width
, exponent
);
1881 proto_tree_add_float_format_value(bfw_tree
, hf_oran_bfw_i
, tvb
, bit_offset
/8, (iq_width
+7)/8, value
, "#%u=%f", w
, value
);
1882 bit_offset
+= iq_width
;
1883 proto_item_append_text(bfw_ti
, "I%u=%f ", w
, value
);
1886 /* Get bits, and convert to float. */
1887 bits
= tvb_get_bits(tvb
, bit_offset
, iq_width
, ENC_BIG_ENDIAN
);
1888 value
= decompress_value(bits
, bfwcomphdr_comp_meth
, iq_width
, exponent
);
1890 proto_tree_add_float_format_value(bfw_tree
, hf_oran_bfw_q
, tvb
, bit_offset
/8, (iq_width
+7)/8, value
, "#%u=%f", w
, value
);
1891 bit_offset
+= iq_width
;
1892 proto_item_append_text(bfw_ti
, "Q%u=%f)", w
, value
);
1895 /* Set extent of bundle */
1896 proto_item_set_len(bundle_ti
, (bit_offset
+7)/8 - prb_offset
);
1898 return (bit_offset
+7)/8;
1901 /* Return new bit offset. in/out will always be byte-aligned.. */
1902 static int dissect_ciCompParam(tvbuff_t
*tvb
, proto_tree
*tree
, packet_info
*pinfo _U_
, unsigned bit_offset
,
1903 unsigned comp_meth
, uint8_t *exponent
)
1905 if (comp_meth
== COMP_NONE
) {
1906 /* Nothing in frame so don't even create subtree */
1911 proto_item
*cicompparam_ti
= proto_tree_add_string_format(tree
, hf_oran_ciCompParam
,
1912 tvb
, bit_offset
/8, 1, "",
1914 proto_tree
*cicompparam_tree
= proto_item_add_subtree(cicompparam_ti
, ett_oran_cicompparam
);
1915 uint32_t ci_exponent
;
1917 /* Contents differ by compression method */
1918 switch (comp_meth
) {
1920 proto_tree_add_item(cicompparam_tree
, hf_oran_reserved_4bits
, tvb
, bit_offset
/8, 1, ENC_NA
);
1921 proto_tree_add_item_ret_uint(cicompparam_tree
, hf_oran_exponent
,
1922 tvb
, bit_offset
/8, 1, ENC_BIG_ENDIAN
, &ci_exponent
);
1923 *exponent
= ci_exponent
;
1924 proto_item_append_text(cicompparam_ti
, " (Exponent=%u)", ci_exponent
);
1925 bit_offset
+= 8; /* one byte */
1927 case COMP_BLOCK_SCALE
:
1928 /* Separate into integer and fractional bits? */
1929 proto_tree_add_item(cicompparam_tree
, hf_oran_blockScaler
,
1930 tvb
, bit_offset
/8, 1, ENC_BIG_ENDIAN
);
1934 /* compBitWidth, compShift */
1935 proto_tree_add_item(cicompparam_tree
, hf_oran_compBitWidth
,
1936 tvb
, bit_offset
/8, 1, ENC_BIG_ENDIAN
);
1937 proto_tree_add_item(cicompparam_tree
, hf_oran_compShift
,
1938 tvb
, bit_offset
/8, 1, ENC_BIG_ENDIAN
);
1943 /* reserved, ? bytes of zeros.. */
1950 /* frameStructure (7.5.2.13) */
1951 static unsigned dissect_frame_structure(proto_item
*tree
, tvbuff_t
*tvb
, unsigned offset
,
1952 uint32_t subframeId
, uint32_t slotId
)
1955 /* FFT Size (4 bits) */
1956 proto_tree_add_item(tree
, hf_oran_frameStructure_fft
, tvb
, offset
, 1, ENC_NA
);
1957 /* Subcarrier spacing (SCS) */
1958 proto_tree_add_item_ret_uint(tree
, hf_oran_frameStructure_subcarrier_spacing
, tvb
, offset
, 1, ENC_NA
, &scs
);
1960 /* Show slot within frame as a generated field. See table 7.5.13-3 */
1961 uint32_t slots_per_subframe
= 1;
1963 slots_per_subframe
= 1 << scs
;
1965 if (scs
<= 4 || scs
>= 12) {
1966 proto_item
*ti
= proto_tree_add_uint(tree
, hf_oran_slot_within_frame
, tvb
, 0, 0,
1967 (slots_per_subframe
*subframeId
) + slotId
);
1968 proto_item_set_generated(ti
);
1973 static unsigned dissect_csf(proto_item
*tree
, tvbuff_t
*tvb
, unsigned bit_offset
,
1974 unsigned iq_width
, bool *p_csf
)
1978 csf_ti
= proto_tree_add_bits_ret_val(tree
, hf_oran_csf
, tvb
, bit_offset
, 1, &csf
, ENC_BIG_ENDIAN
);
1980 /* Table 7.7.4.2-1 Constellation shift definition (index is udIqWidth) */
1981 const char* shift_value
[] = { "n/a", "1/2", "1/4", "1/8", "1/16", "1/32" };
1982 if (iq_width
>=1 && iq_width
<= 5) {
1983 proto_item_append_text(csf_ti
, " (Shift Value is %s)", shift_value
[iq_width
]);
1987 /* Set out parameter */
1988 if (p_csf
!= NULL
) {
1991 return bit_offset
+1;
1996 * N.B. these are the green parts of the tables showing Section Types, differing by section Type */
1997 static int dissect_oran_c_section(tvbuff_t
*tvb
, proto_tree
*tree
, packet_info
*pinfo
,
1998 flow_state_t
* state
,
1999 uint32_t sectionType
, oran_tap_info
*tap_info
, proto_item
*protocol_item
,
2000 uint32_t subframeId
, uint32_t slotId
,
2001 uint8_t ci_iq_width
, uint8_t ci_comp_meth
, unsigned ci_comp_opt
,
2002 unsigned num_sinr_per_prb
)
2004 unsigned offset
= 0;
2005 proto_tree
*c_section_tree
= NULL
;
2006 proto_item
*sectionHeading
= NULL
;
2008 /* Section subtree */
2009 sectionHeading
= proto_tree_add_string_format(tree
, hf_oran_c_section
,
2010 tvb
, offset
, 0, "", "Section");
2011 c_section_tree
= proto_item_add_subtree(sectionHeading
, ett_oran_c_section
);
2013 uint32_t sectionId
= 0;
2015 uint32_t startPrbc
=0, startPrbu
=0;
2016 uint32_t numPrbc
=0, numPrbu
=0;
2018 proto_item
*ueId_ti
= NULL
;
2019 uint32_t beamId
= 0;
2020 proto_item
*beamId_ti
= NULL
;
2021 bool beamId_ignored
= false;
2023 proto_item
*numprbc_ti
= NULL
;
2025 /* Config affecting ext11 bundles (initially unset) */
2026 ext11_settings_t ext11_settings
;
2027 memset(&ext11_settings
, 0, sizeof(ext11_settings
));
2029 bool extension_flag
= false;
2031 /* These sections (ST0, ST1, ST2, ST3, ST5, ST9) are similar, so handle as common with per-type differences */
2032 if (((sectionType
<= SEC_C_UE_SCHED
) || (sectionType
>= SEC_C_SINR_REPORTING
)) &&
2033 (sectionType
!= SEC_C_SLOT_CONTROL
)) {
2036 proto_item
*ti
= proto_tree_add_item_ret_uint(c_section_tree
, hf_oran_section_id
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, §ionId
);
2037 if (sectionId
== 4095) {
2038 proto_item_append_text(ti
, " (not default coupling C/U planes using sectionId)");
2044 proto_tree_add_item_ret_uint(c_section_tree
, hf_oran_rb
, tvb
, offset
, 1, ENC_NA
, &rb
);
2045 /* symInc (1 bit) */
2046 if (sectionType
!= SEC_C_RRM_MEAS_REPORTS
&& /* Section Type 10 */
2047 sectionType
!= SEC_C_REQUEST_RRM_MEAS
) { /* Section Type 11 */
2048 unsigned int sym_inc
;
2049 proto_item
*sym_inc_ti
= proto_tree_add_item_ret_uint(c_section_tree
, hf_oran_symInc
, tvb
, offset
, 1, ENC_NA
, &sym_inc
);
2050 if (sym_inc
!=0 && (sectionType
== SEC_C_SINR_REPORTING
)) { /* Section Type 9 */
2051 /* "0 shall be used" */
2052 proto_item_append_text(sym_inc_ti
, " (should be 0)");
2056 /* reserved (1 bit) */
2057 proto_tree_add_item(c_section_tree
, hf_oran_reserved_bit5
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2060 /* startPrbx and numPrbx */
2061 if (sectionType
== SEC_C_SINR_REPORTING
) {
2062 /* startPrbu (10 bits) */
2063 proto_tree_add_item_ret_uint(c_section_tree
, hf_oran_startPrbu
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &startPrbu
);
2066 numprbc_ti
= proto_tree_add_item_ret_uint(c_section_tree
, hf_oran_numPrbu
, tvb
, offset
, 1, ENC_NA
, &numPrbu
);
2068 proto_item_append_text(numprbc_ti
, " (all PRBs - configured as %u)", pref_data_plane_section_total_rbs
);
2069 numPrbu
= pref_data_plane_section_total_rbs
;
2074 /* startPrbc (10 bits) */
2075 proto_tree_add_item_ret_uint(c_section_tree
, hf_oran_startPrbc
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &startPrbc
);
2078 numprbc_ti
= proto_tree_add_item_ret_uint(c_section_tree
, hf_oran_numPrbc
, tvb
, offset
, 1, ENC_NA
, &numPrbc
);
2080 proto_item_append_text(numprbc_ti
, " (all PRBs - configured as %u)", pref_data_plane_section_total_rbs
);
2085 if (sectionType
!= SEC_C_SINR_REPORTING
) {
2086 static int * const remask_flags
[] = {
2087 &hf_oran_reMask_re1
,
2088 &hf_oran_reMask_re2
,
2089 &hf_oran_reMask_re3
,
2090 &hf_oran_reMask_re4
,
2091 &hf_oran_reMask_re5
,
2092 &hf_oran_reMask_re6
,
2093 &hf_oran_reMask_re7
,
2094 &hf_oran_reMask_re8
,
2095 &hf_oran_reMask_re9
,
2096 &hf_oran_reMask_re10
,
2097 &hf_oran_reMask_re11
,
2098 &hf_oran_reMask_re12
,
2104 proto_tree_add_bitmask_ret_uint64(c_section_tree
, tvb
, offset
,
2105 hf_oran_reMask
, ett_oran_remask
, remask_flags
, ENC_BIG_ENDIAN
, &remask
);
2109 proto_item
*numsymbol_ti
= proto_tree_add_item_ret_uint(c_section_tree
, hf_oran_numSymbol
, tvb
, offset
, 1, ENC_NA
, &numSymbol
);
2110 if ((sectionType
== SEC_C_RRM_MEAS_REPORTS
) && (numSymbol
!= 14)) {
2111 proto_item_append_text(numsymbol_ti
, " (for ST10, should be 14!)");
2112 expert_add_info_format(pinfo
, numsymbol_ti
, &ei_oran_st10_numsymbol_not_14
,
2113 "numSymbol should be 14 for ST10 - found %u", numSymbol
);
2117 /* [ef] (extension flag) */
2118 switch (sectionType
) {
2119 case SEC_C_UNUSED_RB
: /* Section Type 0 */
2120 case SEC_C_NORMAL
: /* Section Type 1 */
2121 case SEC_C_PRACH
: /* Section Type 3 */
2122 case SEC_C_UE_SCHED
: /* Section Type 5 */
2123 case SEC_C_RRM_MEAS_REPORTS
: /* Section Type 10 */
2124 case SEC_C_REQUEST_RRM_MEAS
: /* Section Type 11 */
2125 proto_tree_add_item_ret_boolean(c_section_tree
, hf_oran_ef
, tvb
, offset
, 1, ENC_BIG_ENDIAN
, &extension_flag
);
2128 /* Other section types don't support extensions */
2132 write_section_info(sectionHeading
, pinfo
, protocol_item
, sectionId
, startPrbc
, numPrbc
, rb
);
2133 proto_item_append_text(sectionHeading
, ", Symbols: %2u", numSymbol
);
2136 /* Special case for all PRBs */
2137 numPrbc
= pref_data_plane_section_total_rbs
;
2138 startPrbc
= 0; /* may already be 0... */
2142 write_section_info(sectionHeading
, pinfo
, protocol_item
, sectionId
, startPrbu
, numPrbu
, rb
);
2143 proto_item_append_text(sectionHeading
, ", numSinrPerPrb: %2u", num_sinr_per_prb
);
2146 /* Section type specific fields (after 'numSymbol') */
2147 switch (sectionType
) {
2148 case SEC_C_UNUSED_RB
: /* Section Type 0 - Table 7.4.2-1 */
2149 /* reserved (15 bits) */
2150 proto_tree_add_item(c_section_tree
, hf_oran_reserved_15bits
, tvb
, offset
, 2, ENC_NA
);
2154 case SEC_C_NORMAL
: /* Section Type 1 - Table 7.4.3-1 */
2156 beamId_ti
= proto_tree_add_item_ret_uint(c_section_tree
, hf_oran_beamId
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &beamId
);
2159 proto_item_append_text(sectionHeading
, ", BeamId: %d", beamId
);
2162 case SEC_C_PRACH
: /* Section Type 3 - Table 7.4.5-1 */
2165 beamId_ti
= proto_tree_add_item_ret_uint(c_section_tree
, hf_oran_beamId
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &beamId
);
2169 int32_t freqOffset
; /* Yes, this is signed, so the implicit cast is intentional. */
2170 proto_item
*freq_offset_item
= proto_tree_add_item_ret_uint(c_section_tree
, hf_oran_freqOffset
, tvb
, offset
, 3, ENC_BIG_ENDIAN
, &freqOffset
);
2171 freqOffset
|= 0xff000000; /* Must sign-extend */
2172 proto_item_set_text(freq_offset_item
, "Frequency offset: %d \u0394f", freqOffset
);
2176 proto_tree_add_item(c_section_tree
, hf_oran_reserved_8bits
, tvb
, offset
, 1, ENC_NA
);
2179 proto_item_append_text(sectionHeading
, ", BeamId: %d, FreqOffset: %d \u0394f", beamId
, freqOffset
);
2183 case SEC_C_UE_SCHED
: /* Section Type 5 - Table 7.4.7-1 */
2184 case SEC_C_RRM_MEAS_REPORTS
: /* Section Type 10 - Table 7.4.12-1 */
2186 ueId_ti
= proto_tree_add_item_ret_uint(c_section_tree
, hf_oran_ueId
, tvb
, offset
, 2, ENC_NA
, &ueId
);
2188 if (ueId
== 0x7fff) {
2189 proto_item_append_text(ueId_ti
, " (PRBs not scheduled for eAxC ID in transport header)");
2192 proto_item_append_text(sectionHeading
, ", UEId: %d", ueId
);
2195 case SEC_C_SINR_REPORTING
: /* Section Type 9 - SINR Reporting */
2197 /* Hidden filter for bf (DMFS-BF) */
2198 proto_item
*bf_ti
= proto_tree_add_item(tree
, hf_oran_bf
, tvb
, 0, 0, ENC_NA
);
2199 PROTO_ITEM_SET_HIDDEN(bf_ti
);
2201 unsigned bit_offset
= offset
*8;
2203 for (unsigned prb
=0; prb
< numPrbu
; prb
++) {
2204 /* TODO: create a subtree for each PRB entry with good summary? */
2206 /* Each prb starts byte-aligned */
2207 bit_offset
= ((bit_offset
+7)/8) * 8;
2209 /* N.B., using width/method from UL U-plane preferences, not certain that this is correct.. */
2212 uint32_t exponent
= 0; /* N.B. init to silence warnings, but will always be set if read in COMP_BLOCK_FP case */
2214 bit_offset
= dissect_udcompparam(tvb
, pinfo
, c_section_tree
, bit_offset
/8,
2215 pref_iqCompressionUplink
, &exponent
, &sReSMask
,
2216 true) * 8; /* last param is for_sinr */
2218 /* sinrValues for this PRB. TODO: subtree for each PRB? */
2219 /* TODO: not sure how numSinrPerPrb interacts with rb==1... */
2220 for (unsigned n
=0; n
< num_sinr_per_prb
; n
++) {
2221 unsigned sinr_bits
= tvb_get_bits(tvb
, bit_offset
, pref_sample_bit_width_uplink
, ENC_BIG_ENDIAN
);
2223 /* TODO: using uplink compression settings from preferences. This isn't right.. */
2224 float value
= decompress_value(sinr_bits
, pref_iqCompressionUplink
, pref_sample_bit_width_uplink
, exponent
);
2225 unsigned sample_len_in_bytes
= ((bit_offset
%8)+pref_sample_bit_width_uplink
+7)/8;
2226 proto_item
*val_ti
= proto_tree_add_float(c_section_tree
, hf_oran_sinr_value
, tvb
,
2227 bit_offset
/8, sample_len_in_bytes
, value
);
2228 /* Show here which subcarriers share which values (they all divide 12..) */
2229 proto_item_append_text(val_ti
, " (PRB=%u, subcarriers %u-%u)",
2230 startPrbu
+(prb
*(rb
+1)),
2231 n
*(12/num_sinr_per_prb
), (n
+1)*(12/num_sinr_per_prb
)-1);
2233 bit_offset
+= pref_sample_bit_width_uplink
;
2236 offset
= (bit_offset
+7)/8;
2239 case SEC_C_REQUEST_RRM_MEAS
: /* Section Type 11 - Request RRM Measurements */
2240 /* Reserved (15 bits) */
2241 proto_tree_add_item(c_section_tree
, hf_oran_reserved_15bits
, tvb
, offset
, 2, ENC_NA
);
2249 else if (sectionType
== SEC_C_CH_INFO
) { /* Section Type 6 */
2251 proto_tree_add_item_ret_boolean(c_section_tree
, hf_oran_ef
, tvb
, offset
, 1, ENC_BIG_ENDIAN
, &extension_flag
);
2253 proto_tree_add_item_ret_uint(c_section_tree
, hf_oran_ueId
, tvb
, offset
, 2, ENC_NA
, &ueId
);
2255 /* regularizationFactor */
2256 proto_tree_add_item(c_section_tree
, hf_oran_regularizationFactor
, tvb
, offset
, 2, ENC_NA
);
2258 /* reserved (4 bits) */
2259 proto_tree_add_item(c_section_tree
, hf_oran_reserved_4bits
, tvb
, offset
, 1, ENC_NA
);
2260 /* rb ("Value=0 shall be set") */
2262 proto_item
*rb_ti
= proto_tree_add_item_ret_uint(c_section_tree
, hf_oran_rb
, tvb
, offset
, 1, ENC_NA
, &rb
);
2264 proto_item_append_text(rb_ti
, " (should be set to 0)");
2265 expert_add_info(pinfo
, rb_ti
, &ei_oran_st6_rb_shall_be_0
);
2268 proto_tree_add_item(c_section_tree
, hf_oran_symInc
, tvb
, offset
, 1, ENC_NA
);
2270 proto_tree_add_item_ret_uint(c_section_tree
, hf_oran_startPrbc
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &startPrbc
);
2273 proto_tree_add_item_ret_uint(c_section_tree
, hf_oran_numPrbc
, tvb
, offset
, 1, ENC_NA
, &numPrbc
);
2276 /* Hidden filter for bf */
2277 proto_item
*bf_ti
= proto_tree_add_item(tree
, hf_oran_bf
, tvb
, 0, 0, ENC_NA
);
2278 PROTO_ITEM_SET_HIDDEN(bf_ti
);
2280 /* ciIsample,ciQsample pairs */
2283 uint32_t bit_offset
= offset
*8;
2285 /* Antenna count from preference */
2286 unsigned num_trx
= pref_num_bf_antennas
;
2288 write_channel_section_info(sectionHeading
, pinfo
,
2289 sectionId
, ueId
, startPrbc
, numPrbc
, num_trx
);
2291 bool first_prb
= true;
2292 uint8_t exponent
= 0;
2293 for (prb
=startPrbc
; prb
< startPrbc
+numPrbc
; prb
++) {
2296 unsigned prb_start_offset
= bit_offset
;
2297 proto_item
*prb_ti
= proto_tree_add_string_format(c_section_tree
, hf_oran_samples_prb
,
2298 tvb
, bit_offset
/8, 0,
2300 proto_tree
*prb_tree
= proto_item_add_subtree(prb_ti
, ett_oran_prb_cisamples
);
2302 /* There may be a ciCompParam here.. */
2303 if (first_prb
|| ci_comp_opt
==1) {
2304 bit_offset
= dissect_ciCompParam(tvb
, prb_tree
, pinfo
, bit_offset
, ci_comp_meth
, &exponent
);
2309 for (m
=0; m
< num_trx
; m
++) {
2311 unsigned sample_offset
= bit_offset
/ 8;
2312 uint8_t sample_extent
= ((bit_offset
+ (ci_iq_width
*2)) / 8) - sample_offset
;
2314 /* Create subtree for antenna */
2315 proto_item
*sample_ti
= proto_tree_add_string_format(prb_tree
, hf_oran_ciSample
,
2316 tvb
, sample_offset
, sample_extent
,
2317 "", "TRX=%2u: ", m
);
2318 proto_tree
*sample_tree
= proto_item_add_subtree(sample_ti
, ett_oran_cisample
);
2321 /* Get bits, and convert to float. */
2322 uint32_t bits
= tvb_get_bits(tvb
, bit_offset
, ci_iq_width
, ENC_BIG_ENDIAN
);
2323 float value
= decompress_value(bits
, ci_comp_meth
, ci_iq_width
, exponent
);
2326 proto_tree_add_float_format_value(sample_tree
, hf_oran_ciIsample
, tvb
, bit_offset
/8, (16+7)/8, value
, "#%u=%f", m
, value
);
2327 bit_offset
+= ci_iq_width
;
2328 proto_item_append_text(sample_ti
, "I%u=%f ", m
, value
);
2331 /* Get bits, and convert to float. */
2332 bits
= tvb_get_bits(tvb
, bit_offset
, ci_iq_width
, ENC_BIG_ENDIAN
);
2333 value
= decompress_value(bits
, ci_comp_meth
, ci_iq_width
, exponent
);
2336 proto_tree_add_float_format_value(sample_tree
, hf_oran_ciQsample
, tvb
, bit_offset
/8, (16+7)/8, value
, "#%u=%f", m
, value
);
2337 bit_offset
+= ci_iq_width
;
2338 proto_item_append_text(sample_ti
, "Q%u=%f ", m
, value
);
2340 proto_item_set_len(prb_ti
, (bit_offset
-prb_start_offset
)/8);
2342 offset
= (bit_offset
/8);
2345 bool seen_se10
= false;
2346 uint32_t numPortc
= 0;
2347 proto_item
*bf_ti
= NULL
;
2349 /* Section extension commands */
2350 while (extension_flag
) {
2352 int extension_start_offset
= offset
;
2354 /* Prefetch extType so can use specific extension type ett */
2355 uint32_t exttype
= tvb_get_uint8(tvb
, offset
) & 0x7f;
2356 uint32_t exttype_ett_index
= exttype
;
2357 if (exttype
== 0 || exttype
> HIGHEST_EXTTYPE
) {
2358 /* Just use first one if out of range */
2359 exttype_ett_index
= 1;
2362 /* Create subtree for each extension (with summary) */
2363 proto_item
*extension_ti
= proto_tree_add_string_format(c_section_tree
, hf_oran_extension
,
2364 tvb
, offset
, 0, "", "Extension");
2365 proto_tree
*extension_tree
= proto_item_add_subtree(extension_ti
, ett_oran_c_section_extension
[exttype_ett_index
-1]);
2367 /* ef (i.e. another extension after this one?) */
2368 proto_tree_add_item_ret_boolean(extension_tree
, hf_oran_ef
, tvb
, offset
, 1, ENC_BIG_ENDIAN
, &extension_flag
);
2371 proto_item
*exttype_ti
;
2372 exttype_ti
= proto_tree_add_item(extension_tree
, hf_oran_exttype
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2374 proto_item_append_text(sectionHeading
, " (ext-%u)", exttype
);
2376 proto_item_append_text(extension_ti
, " (ext-%u: %s)", exttype
, val_to_str_const(exttype
, exttype_vals
, "Reserved"));
2378 /* Don't tap if out of range. */
2379 if (exttype
> 0 && exttype
<= HIGHEST_EXTTYPE
) {
2380 tap_info
->extensions
[exttype
] = true;
2383 /* Is this SE allowed for this section type? */
2384 if (!se_allowed_in_st(exttype
, sectionType
)) {
2385 expert_add_info_format(pinfo
, extension_tree
, &ei_oran_se_on_unsupported_st
,
2386 "SE %u (%s) should not appear in ST %u (%s)!",
2387 exttype
, val_to_str_const(exttype
, exttype_vals
, "Reserved"),
2388 sectionType
, rval_to_str_const(sectionType
, section_types
, "Unknown"));
2392 /* extLen (number of 32-bit words) */
2393 uint32_t extlen_len
= ((exttype
==11)||(exttype
==19)||(exttype
==20)) ? 2 : 1; /* Extensions 11/19/20 are special */
2395 proto_item
*extlen_ti
= proto_tree_add_item_ret_uint(extension_tree
, hf_oran_extlen
, tvb
,
2396 offset
, extlen_len
, ENC_BIG_ENDIAN
, &extlen
);
2397 proto_item_append_text(extlen_ti
, " (%u bytes)", extlen
*4);
2398 offset
+= extlen_len
;
2400 expert_add_info_format(pinfo
, extlen_ti
, &ei_oran_extlen_zero
,
2401 "extlen value of 0 is reserved");
2402 /* Break out to avoid infinitely looping! */
2406 bool ext_unhandled
= false;
2410 case 1: /* SE 1: Beamforming Weights */
2412 uint32_t bfwcomphdr_iq_width
, bfwcomphdr_comp_meth
;
2413 proto_item
*comp_meth_ti
= NULL
;
2415 /* Hidden filter for bf */
2416 bf_ti
= proto_tree_add_item(tree
, hf_oran_bf
, tvb
, 0, 0, ENC_NA
);
2417 PROTO_ITEM_SET_HIDDEN(bf_ti
);
2419 /* bfwCompHdr (2 subheaders - bfwIqWidth and bfwCompMeth)*/
2420 offset
= dissect_bfwCompHdr(tvb
, extension_tree
, offset
,
2421 &bfwcomphdr_iq_width
, &bfwcomphdr_comp_meth
, &comp_meth_ti
);
2424 uint32_t exponent
= 0;
2425 bool compression_method_supported
= false;
2426 offset
= dissect_bfwCompParam(tvb
, extension_tree
, pinfo
, offset
, comp_meth_ti
,
2427 bfwcomphdr_comp_meth
, &exponent
, &compression_method_supported
);
2429 /* Can't show details of unsupported compression method */
2430 if (!compression_method_supported
) {
2436 - numBfWeights (taken from preference)
2437 - remaining bytes in extension
2438 We can therefore derive TRX (number of antennas).
2442 Don't know how many there will be, so just fill available bytes...
2444 unsigned weights_bytes
= (extlen
*4)-3;
2445 unsigned num_weights_pairs
= (weights_bytes
*8) / (bfwcomphdr_iq_width
*2);
2446 unsigned num_trx
= num_weights_pairs
;
2447 int bit_offset
= offset
*8;
2449 for (unsigned n
=0; n
< num_trx
; n
++) {
2450 /* Create antenna subtree */
2451 int bfw_offset
= bit_offset
/ 8;
2452 proto_item
*bfw_ti
= proto_tree_add_string_format(extension_tree
, hf_oran_bfw
,
2453 tvb
, bfw_offset
, 0, "", "TRX %3u: (", n
);
2454 proto_tree
*bfw_tree
= proto_item_add_subtree(bfw_ti
, ett_oran_bfw
);
2457 /* Get bits, and convert to float. */
2458 uint32_t bits
= tvb_get_bits(tvb
, bit_offset
, bfwcomphdr_iq_width
, ENC_BIG_ENDIAN
);
2459 float value
= decompress_value(bits
, bfwcomphdr_comp_meth
, bfwcomphdr_iq_width
, exponent
);
2461 proto_tree_add_float_format_value(bfw_tree
, hf_oran_bfw_i
, tvb
, bit_offset
/8,
2462 (bfwcomphdr_iq_width
+7)/8, value
, "%f", value
);
2463 bit_offset
+= bfwcomphdr_iq_width
;
2464 proto_item_append_text(bfw_ti
, "I=%f ", value
);
2466 /* Leave a gap between I and Q values */
2467 proto_item_append_text(bfw_ti
, " ");
2470 /* Get bits, and convert to float. */
2471 bits
= tvb_get_bits(tvb
, bit_offset
, bfwcomphdr_iq_width
, ENC_BIG_ENDIAN
);
2472 value
= decompress_value(bits
, bfwcomphdr_comp_meth
, bfwcomphdr_iq_width
, exponent
);
2474 proto_tree_add_float_format_value(bfw_tree
, hf_oran_bfw_q
, tvb
, bit_offset
/8,
2475 (bfwcomphdr_iq_width
+7)/8, value
, "%f", value
);
2476 bit_offset
+= bfwcomphdr_iq_width
;
2477 proto_item_append_text(bfw_ti
, "Q=%f", value
);
2479 proto_item_append_text(bfw_ti
, ")");
2480 proto_item_set_len(bfw_ti
, (bit_offset
+7)/8 - bfw_offset
);
2482 /* Need to round to next byte */
2483 offset
= (bit_offset
+7)/8;
2488 case 2: /* SE 2: Beamforming attributes */
2490 /* Hidden filter for bf */
2491 bf_ti
= proto_tree_add_item(tree
, hf_oran_bf
, tvb
, 0, 0, ENC_NA
);
2492 PROTO_ITEM_SET_HIDDEN(bf_ti
);
2494 /* bfaCompHdr (get widths of fields to follow) */
2495 uint32_t bfAzPtWidth
, bfZePtWidth
, bfAz3ddWidth
, bfZe3ddWidth
;
2497 proto_item
*bfa_ti
= proto_tree_add_string_format(extension_tree
, hf_oran_bfaCompHdr
,
2498 tvb
, offset
, 2, "", "bfaCompHdr");
2499 proto_tree
*bfa_tree
= proto_item_add_subtree(bfa_ti
, ett_oran_bfacomphdr
);
2501 /* reserved (2 bits) */
2502 proto_tree_add_item(bfa_tree
, hf_oran_reserved_2bits
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2503 /* bfAzPtWidth (3 bits) */
2504 proto_tree_add_item_ret_uint(bfa_tree
, hf_oran_bfAzPtWidth
, tvb
, offset
, 1, ENC_BIG_ENDIAN
, &bfAzPtWidth
);
2505 /* bfZePtWidth (3 bits) */
2506 proto_tree_add_item_ret_uint(bfa_tree
, hf_oran_bfZePtWidth
, tvb
, offset
, 1, ENC_BIG_ENDIAN
, &bfZePtWidth
);
2509 /* reserved (2 bits) */
2510 proto_tree_add_item(bfa_tree
, hf_oran_reserved_2bits
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2511 /* bfAz3ddWidth (3 bits) */
2512 proto_tree_add_item_ret_uint(bfa_tree
, hf_oran_bfAz3ddWidth
, tvb
, offset
, 1, ENC_BIG_ENDIAN
, &bfAz3ddWidth
);
2513 /* bfZe3ddWidth (3 bits) */
2514 proto_tree_add_item_ret_uint(bfa_tree
, hf_oran_bfZe3ddWidth
, tvb
, offset
, 1, ENC_BIG_ENDIAN
, &bfZe3ddWidth
);
2517 unsigned bit_offset
= offset
*8;
2520 if (bfAzPtWidth
> 0) {
2521 proto_tree_add_bits_item(extension_tree
, hf_oran_bfAzPt
, tvb
, bit_offset
, bfAzPtWidth
+1, ENC_BIG_ENDIAN
);
2522 bit_offset
+= (bfAzPtWidth
+1);
2525 if (bfZePtWidth
> 0) {
2526 proto_tree_add_bits_item(extension_tree
, hf_oran_bfZePt
, tvb
, bit_offset
, bfZePtWidth
+1, ENC_BIG_ENDIAN
);
2527 bit_offset
+= (bfZePtWidth
+1);
2530 if (bfAz3ddWidth
> 0) {
2531 proto_tree_add_bits_item(extension_tree
, hf_oran_bfAz3dd
, tvb
, bit_offset
, bfAz3ddWidth
+1, ENC_BIG_ENDIAN
);
2532 bit_offset
+= (bfAz3ddWidth
+1);
2535 if (bfZe3ddWidth
> 0) {
2536 proto_tree_add_bits_item(extension_tree
, hf_oran_bfZe3dd
, tvb
, bit_offset
, bfZe3ddWidth
+1, ENC_BIG_ENDIAN
);
2537 bit_offset
+= (bfZe3ddWidth
+1);
2540 /* Pad to next byte (unless last 2 fields already fit in this one) */
2541 if ((bit_offset
% 8) > 2) {
2542 offset
= (bit_offset
+7) / 8;
2545 offset
= bit_offset
/ 8;
2548 /* bfAzSl (3 bits) */
2549 proto_tree_add_item(extension_tree
, hf_oran_bfAzSl
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2550 /* bfZeSl (3 bits) */
2551 proto_tree_add_item(extension_tree
, hf_oran_bfZeSl
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2556 case 3: /* SE 3: TODO: DL precoding parameters */
2558 /* codebookindex (8 bits) */
2559 /* "This parameter is not used and shall be set to zero." */
2560 proto_tree_add_item(extension_tree
, hf_oran_codebook_index
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2564 proto_tree_add_item_ret_uint(extension_tree
, hf_oran_layerid
, tvb
, offset
, 1, ENC_BIG_ENDIAN
, &layerid
);
2566 proto_tree_add_item(extension_tree
, hf_oran_numlayers
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2569 /* Stop here for non-first data layer */
2570 if (layerid
!= 0 && layerid
!= 0xf) {
2574 /* First data layer case */
2576 proto_tree_add_item(extension_tree
, hf_oran_txscheme
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2578 proto_tree_add_item(extension_tree
, hf_oran_crs_remask
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2581 /* crsShift (1 bit) */
2582 proto_tree_add_item(extension_tree
, hf_oran_crs_shift
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2583 /* reserved (3 bits) */
2584 proto_tree_add_item(extension_tree
, hf_oran_reserved_bits123
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2585 /* crsSymNum (4 bits) */
2586 proto_tree_add_item(extension_tree
, hf_oran_crs_symnum
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2589 proto_tree_add_item(extension_tree
, hf_oran_reserved_8bits
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2592 /* reserved (1 bit) */
2593 proto_tree_add_item(extension_tree
, hf_oran_reserved_1bit
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2594 /* beamIdAP1 (15 bits) */
2595 proto_tree_add_item(extension_tree
, hf_oran_beamid_ap1
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2597 /* reserved (1 bit) */
2598 proto_tree_add_item(extension_tree
, hf_oran_reserved_1bit
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2599 /* beamIdAP2 (15 bits) */
2600 proto_tree_add_item(extension_tree
, hf_oran_beamid_ap2
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2602 /* reserved (1 bit) */
2603 proto_tree_add_item(extension_tree
, hf_oran_reserved_1bit
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2604 /* beamIdAP3 (15 bits) */
2605 proto_tree_add_item(extension_tree
, hf_oran_beamid_ap3
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2610 case 4: /* SE 4: Modulation compression params (5.4.7.4) */
2613 dissect_csf(extension_tree
, tvb
, offset
*8, ci_iq_width
, NULL
);
2616 uint32_t modCompScaler
;
2617 proto_item
*ti
= proto_tree_add_item_ret_uint(extension_tree
, hf_oran_modcompscaler
,
2618 tvb
, offset
, 2, ENC_BIG_ENDIAN
, &modCompScaler
);
2621 /* Work out and show floating point value too. exponent and mantissa are both unsigned */
2622 uint16_t exponent
= (modCompScaler
>> 11) & 0x000f; /* m.s. 4 bits */
2623 uint16_t mantissa
= modCompScaler
& 0x07ff; /* l.s. 11 bits */
2624 double value
= ((double)mantissa
/(1<<11)) * (1.0 / (1 << exponent
));
2625 proto_item_append_text(ti
, " (%f)", value
);
2627 /* TODO: need to store these in per-section data in state that gets looked up by U-Plane */
2631 case 5: /* SE 5: Modulation Compression Additional Parameters (7.7.5) */
2633 /* Applies only to section types 1,3 and 5 */
2634 /* N.B. there may be multiple instances of this SE in the same frame */
2636 /* There may be one or 2 entries, depending upon extlen */
2637 int sets
= 1, reserved_bits
= 0;
2648 /* sets can be 3 or 4, depending upon whether last 28 bits are 0.. */
2649 if ((tvb_get_ntohl(tvb
, offset
+10) & 0x0fffffff) == 0) {
2660 /* Malformed error!!! */
2661 expert_add_info_format(pinfo
, extlen_ti
, &ei_oran_extlen_wrong
,
2662 "For section 5, extlen must be 2, 3 or 4, but %u was dissected",
2667 unsigned bit_offset
= offset
*8;
2669 for (int n
=0; n
< sets
; n
++) {
2670 /* Subtree for each set */
2671 unsigned set_start_offset
= bit_offset
/8;
2672 proto_item
*set_ti
= proto_tree_add_string(extension_tree
, hf_oran_modcomp_param_set
,
2673 tvb
, set_start_offset
, 0, "");
2674 proto_tree
*set_tree
= proto_item_add_subtree(set_ti
, ett_oran_modcomp_param_set
);
2676 uint64_t mcScaleReMask
, mcScaleOffset
;
2679 /* mcScaleReMask (12 bits) */
2680 proto_tree_add_bits_ret_val(set_tree
, hf_oran_mc_scale_re_mask
, tvb
, bit_offset
, 12, &mcScaleReMask
, ENC_BIG_ENDIAN
);
2683 bit_offset
= dissect_csf(set_tree
, tvb
, bit_offset
, ci_iq_width
, &csf
);
2684 /* mcScaleOffset (15 bits) */
2685 proto_item
*ti
= proto_tree_add_bits_ret_val(set_tree
, hf_oran_mc_scale_offset
, tvb
, bit_offset
, 15, &mcScaleOffset
, ENC_BIG_ENDIAN
);
2686 uint16_t exponent
= (mcScaleOffset
>> 11) & 0x000f; /* m.s. 4 bits */
2687 uint16_t mantissa
= mcScaleOffset
& 0x07ff; /* l.s. 11 bits */
2688 double mcScaleOffset_value
= ((double)mantissa
/(1<<11)) * (1.0 / (1 << exponent
));
2689 proto_item_append_text(ti
, " (%f)", mcScaleOffset_value
);
2693 proto_item_set_len(set_ti
, (bit_offset
+7)/8 - set_start_offset
);
2694 proto_item_append_text(set_ti
, " (mcScaleReMask=0x%03x csf=%5s mcScaleOffset=%f)",
2695 (unsigned)mcScaleReMask
, tfs_get_true_false(csf
), mcScaleOffset_value
);
2698 proto_item_append_text(extension_ti
, " (%u sets)", sets
);
2700 /* Reserved (variable-length) */
2701 if (reserved_bits
) {
2702 proto_tree_add_bits_item(extension_tree
, hf_oran_reserved
, tvb
, bit_offset
, reserved_bits
, ENC_BIG_ENDIAN
);
2703 bit_offset
+= reserved_bits
;
2706 offset
= bit_offset
/8;
2710 case 6: /* SE 6: Non-contiguous PRB allocation in time and frequency domain */
2712 /* Update ext6 recorded info */
2713 ext11_settings
.ext6_set
= true;
2716 proto_tree_add_bits_item(extension_tree
, hf_oran_repetition
, tvb
, offset
*8, 1, ENC_BIG_ENDIAN
);
2717 /* rbgSize (PRBs per bit set in rbgMask) */
2719 proto_item
*rbg_size_ti
;
2720 rbg_size_ti
= proto_tree_add_item_ret_uint(extension_tree
, hf_oran_rbgSize
, tvb
, offset
, 1, ENC_BIG_ENDIAN
, &rbgSize
);
2722 /* N.B. this is only true if "se6-rb-bit-supported" is set... */
2723 expert_add_info_format(pinfo
, rbg_size_ti
, &ei_oran_rbg_size_reserved
,
2724 "rbgSize value of 0 is reserved");
2726 /* rbgMask (28 bits) */
2728 proto_item
*rbgmask_ti
= proto_tree_add_item_ret_uint(extension_tree
, hf_oran_rbgMask
, tvb
, offset
, 4, ENC_BIG_ENDIAN
, &rbgMask
);
2730 proto_item_append_text(rbgmask_ti
, " (value ignored since rbgSize is 0)");
2733 /* TODO: if receiver detects non-zero bits outside the valid range, those shall be ignored. */
2736 proto_tree_add_item(extension_tree
, hf_oran_noncontig_priority
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2738 proto_tree_add_item(extension_tree
, hf_oran_symbolMask
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2741 /* Look up rbg_size enum -> value */
2744 /* N.B. reserved, but covered above with expert info (would remain 0) */
2747 ext11_settings
.ext6_rbg_size
= 1; break;
2749 ext11_settings
.ext6_rbg_size
= 2; break;
2751 ext11_settings
.ext6_rbg_size
= 3; break;
2753 ext11_settings
.ext6_rbg_size
= 4; break;
2755 ext11_settings
.ext6_rbg_size
= 6; break;
2757 ext11_settings
.ext6_rbg_size
= 8; break;
2759 ext11_settings
.ext6_rbg_size
= 16; break;
2760 /* N.B., encoded in 3 bits, so no other values are possible */
2763 /* Set to looked-up value */
2764 rbgSize
= ext11_settings
.ext6_rbg_size
;
2766 uint32_t lastRbgid
= 0;
2768 /* The O-DU shall not use combinations of startPrbc, numPrbc and rbgSize leading to a value of lastRbgid larger than 27 */
2769 /* i.e., leftmost bit used should not need to go off left end of rbgMask! */
2770 lastRbgid
= (uint32_t)ceil((numPrbc
+ (startPrbc
% rbgSize
)) / (float)rbgSize
) - 1;
2771 if (lastRbgid
> 27) {
2772 expert_add_info_format(pinfo
, rbg_size_ti
, &ei_oran_lastRbdid_out_of_range
,
2773 "SE6: rbgSize (%u) not compatible with startPrbc(%u) and numPrbc(%u)",
2774 rbgSize
, startPrbc
, numPrbc
);
2779 /* Record (and count) which bits are set in rbgMask */
2780 bool first_seen
= false;
2781 unsigned first_seen_pos
=0, last_seen_pos
=0;
2782 for (unsigned n
=0; n
< 28 && ext11_settings
.ext6_num_bits_set
< 28; n
++) {
2783 if ((rbgMask
>> n
) & 0x01) {
2784 ext11_settings
.ext6_bits_set
[ext11_settings
.ext6_num_bits_set
++] = n
;
2793 /* Show how many bits were set in rbgMask */
2794 proto_item_append_text(rbgmask_ti
, " (%u bits set)", ext11_settings
.ext6_num_bits_set
);
2795 /* Also, that is the range of bits */
2797 proto_item_append_text(rbgmask_ti
, " (%u bits spread)", last_seen_pos
-first_seen_pos
+1);
2800 /* Complain if last set bit is beyond lastRbgid */
2802 if (last_seen_pos
> lastRbgid
) {
2803 expert_add_info_format(pinfo
, rbgmask_ti
, &ei_oran_rbgMask_beyond_last_rbdid
,
2804 "SE6: rbgMask (0x%07x) has bit %u set, but lastRbgId is %u",
2805 rbgMask
, last_seen_pos
, lastRbgid
);
2811 case 7: /* SE 7: eAxC mask */
2812 /* Allow ST0 to address multiple eAxC_ID values for transmission blanking */
2813 proto_tree_add_item(extension_tree
, hf_oran_eAxC_mask
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2817 case 8: /* SE 8: Regularization factor */
2818 proto_tree_add_item(extension_tree
, hf_oran_regularizationFactor
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2822 case 9: /* SE 9: Dynamic Spectrum Sharing parameters */
2823 proto_tree_add_item(extension_tree
, hf_oran_technology
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2825 proto_tree_add_item(extension_tree
, hf_oran_reserved_8bits
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2829 case 10: /* SE 10: Group configuration of multiple ports */
2834 uint32_t beam_group_type
= 0;
2836 bgt_ti
= proto_tree_add_item_ret_uint(extension_tree
, hf_oran_beamGroupType
,
2837 tvb
, offset
, 1, ENC_BIG_ENDIAN
, &beam_group_type
);
2838 proto_item_append_text(extension_ti
, " (%s)", val_to_str_const(beam_group_type
, beam_group_type_vals
, "Unknown"));
2841 proto_tree_add_item_ret_uint(extension_tree
, hf_oran_numPortc
,
2842 tvb
, offset
, 1, ENC_BIG_ENDIAN
, &numPortc
);
2845 /* Will append all beamId values to extension_ti, regardless of beamGroupType */
2848 switch (beam_group_type
) {
2849 case 0x0: /* common beam */
2850 case 0x1: /* beam matrix indication */
2852 proto_tree_add_item(extension_tree
, hf_oran_reserved_8bits
, tvb
, offset
, 1, ENC_NA
);
2856 case 0x2: /* beam vector listing */
2858 proto_item_append_text(extension_ti
, " [ ");
2860 /* Beam listing vector case */
2861 /* Work out how many port beam entries there is room for */
2862 /* Using numPortC as visible in issue 18116 */
2863 for (n
=0; n
< numPortc
; n
++) {
2864 /* 1 reserved bit */
2865 proto_tree_add_item(extension_tree
, hf_oran_reserved_1bit
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2867 /* port beam ID (or UEID) */
2869 proto_item
*beamid_or_ueid_ti
= proto_tree_add_item_ret_uint(extension_tree
, hf_oran_beamId
,
2870 tvb
, offset
, 2, ENC_BIG_ENDIAN
, &id
);
2871 proto_item_append_text(beamid_or_ueid_ti
, " port #%u beam ID (or UEId) %u", n
, id
);
2874 proto_item_append_text(extension_ti
, "%u ", id
);
2877 proto_item_append_text(extension_ti
, "]");
2880 case 0x3: /* beamId/ueId listing with associated port-list index */
2882 proto_item_append_text(extension_ti
, " [ ");
2885 /* first portListIndex */
2886 uint32_t port_list_index
;
2887 proto_tree_add_item_ret_uint(extension_tree
, hf_oran_port_list_index
, tvb
,
2888 offset
, 1, ENC_BIG_ENDIAN
, &port_list_index
);
2891 for (n
=0; n
< numPortc
-1; n
++) {
2892 /* 1 reserved bit */
2893 proto_tree_add_item(extension_tree
, hf_oran_reserved_1bit
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2895 /* port beam ID (or UEID) */
2897 proto_item
*beamid_or_ueid_ti
= proto_tree_add_item_ret_uint(extension_tree
, hf_oran_beamId
,
2898 tvb
, offset
, 2, ENC_BIG_ENDIAN
, &id
);
2899 proto_item_append_text(beamid_or_ueid_ti
, " port #%u beam ID (or UEId) %u", n
, id
);
2903 proto_tree_add_item_ret_uint(extension_tree
, hf_oran_port_list_index
, tvb
,
2904 offset
, 1, ENC_BIG_ENDIAN
, &port_list_index
);
2907 proto_item_append_text(extension_ti
, "%u:%u ", port_list_index
, id
);
2911 proto_item_append_text(extension_ti
, "]");
2917 /* Warning for unsupported/reserved value */
2918 expert_add_info(NULL
, bgt_ti
, &ei_oran_se10_unknown_beamgrouptype
);
2924 case 11: /* SE 11: Flexible Weights Extension Type */
2926 /* Hidden filter for bf */
2927 bf_ti
= proto_tree_add_item(tree
, hf_oran_bf
, tvb
, 0, 0, ENC_NA
);
2928 PROTO_ITEM_SET_HIDDEN(bf_ti
);
2930 /* beamId in section header should be ignored. Guard against appending multiple times.. */
2931 if (beamId_ti
&& !beamId_ignored
) {
2932 proto_item_append_text(beamId_ti
, " (ignored)");
2933 beamId_ignored
= true;
2937 uint32_t numBundPrb
;
2941 proto_tree_add_item_ret_boolean(extension_tree
, hf_oran_disable_bfws
,
2942 tvb
, offset
, 1, ENC_BIG_ENDIAN
, &disableBFWs
);
2944 proto_item_append_text(extension_ti
, " (disableBFWs)");
2948 proto_tree_add_item_ret_boolean(extension_tree
, hf_oran_rad
,
2949 tvb
, offset
, 1, ENC_BIG_ENDIAN
, &rad
);
2950 /* bundleOffset (6 bits) */
2951 proto_tree_add_item(extension_tree
, hf_oran_bundle_offset
, tvb
,
2952 offset
, 1, ENC_BIG_ENDIAN
);
2955 /* numBundPrb (number of prbs in each bundle) */
2956 proto_item
*num_bund_prb_ti
= proto_tree_add_item_ret_uint(extension_tree
, hf_oran_num_bund_prbs
,
2957 tvb
, offset
, 1, ENC_BIG_ENDIAN
, &numBundPrb
);
2959 /* value zero is reserved.. */
2960 if (numBundPrb
== 0) {
2961 expert_add_info_format(pinfo
, num_bund_prb_ti
, &ei_oran_reserved_numBundPrb
,
2962 "Reserved value 0 for numBundPrb seen - not valid");
2965 uint32_t num_bundles
;
2966 bool orphaned_prbs
= false;
2969 /********************************************/
2970 /* Table 7.7.1.1-1 */
2971 /********************************************/
2973 uint32_t bfwcomphdr_iq_width
, bfwcomphdr_comp_meth
;
2974 proto_item
*comp_meth_ti
= NULL
;
2976 /* bfwCompHdr (2 subheaders - bfwIqWidth and bfwCompMeth)*/
2977 offset
= dissect_bfwCompHdr(tvb
, extension_tree
, offset
,
2978 &bfwcomphdr_iq_width
, &bfwcomphdr_comp_meth
, &comp_meth_ti
);
2980 /* Work out number of bundles, but take care not to divide by zero. */
2981 if (numBundPrb
== 0) {
2985 /* Work out bundles! */
2986 ext11_work_out_bundles(startPrbc
, numPrbc
, numBundPrb
, &ext11_settings
);
2987 num_bundles
= ext11_settings
.num_bundles
;
2989 /* Add (complete) bundles */
2990 for (unsigned b
=0; b
< num_bundles
; b
++) {
2992 offset
= dissect_bfw_bundle(tvb
, extension_tree
, pinfo
, offset
,
2993 comp_meth_ti
, bfwcomphdr_comp_meth
,
2994 (ext11_settings
.ext21_set
) ?
2996 pref_num_weights_per_bundle
,
2997 bfwcomphdr_iq_width
,
2998 b
, /* bundle number */
2999 ext11_settings
.bundles
[b
].start
,
3000 ext11_settings
.bundles
[b
].end
,
3001 ext11_settings
.bundles
[b
].is_orphan
);
3006 if (num_bundles
> 0) {
3007 /* Set flag from last bundle entry */
3008 orphaned_prbs
= ext11_settings
.bundles
[num_bundles
-1].is_orphan
;
3012 /********************************************/
3013 /* Table 7.7.1.1-2 */
3014 /* No weights in this case */
3015 /********************************************/
3017 /* Work out number of bundles, but take care not to divide by zero. */
3018 if (numBundPrb
== 0) {
3022 ext11_work_out_bundles(startPrbc
, numPrbc
, numBundPrb
, &ext11_settings
);
3023 num_bundles
= ext11_settings
.num_bundles
;
3025 for (unsigned n
=0; n
< num_bundles
; n
++) {
3027 proto_tree_add_item(extension_tree
, hf_oran_cont_ind
,
3028 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3030 proto_item
*ti
= proto_tree_add_item(extension_tree
, hf_oran_beam_id
,
3031 tvb
, offset
, 2, ENC_BIG_ENDIAN
);
3032 if (!ext11_settings
.bundles
[n
].is_orphan
) {
3033 proto_item_append_text(ti
, " (Bundle %u)", n
);
3036 orphaned_prbs
= true;
3037 proto_item_append_text(ti
, " (Orphaned PRBs)");
3043 /* Add summary to extension root */
3044 if (orphaned_prbs
) {
3045 proto_item_append_text(extension_ti
, " (%u bundles + orphaned)", num_bundles
);
3048 proto_item_append_text(extension_ti
, " (%u bundles)", num_bundles
);
3054 case 12: /* SE 12: Non-Contiguous PRB Allocation with Frequency Ranges */
3056 ext11_settings
.ext12_set
= true;
3059 proto_tree_add_item(extension_tree
, hf_oran_noncontig_priority
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3062 proto_tree_add_item(extension_tree
, hf_oran_symbolMask
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
3065 /* There are now 'R' pairs of (offStartPrb, numPrb) values. Fill extlen bytes with values. If last one is not set,
3066 should be populated with 0s. */
3067 uint32_t extlen_remaining_bytes
= (extlen
*4) - 4;
3070 for (prb_index
= 1; extlen_remaining_bytes
> 0; prb_index
++)
3072 /* Create a subtree for each pair */
3073 proto_item
*pair_ti
= proto_tree_add_string(extension_tree
, hf_oran_off_start_prb_num_prb_pair
,
3074 tvb
, offset
, 2, "");
3075 proto_tree
*pair_tree
= proto_item_add_subtree(pair_ti
, ett_oran_offset_start_prb_num_prb
);
3078 uint32_t off_start_prb
;
3079 proto_tree_add_item_ret_uint(pair_tree
, hf_oran_off_start_prb
, tvb
, offset
, 1, ENC_BIG_ENDIAN
, &off_start_prb
);
3084 proto_tree_add_item_ret_uint(pair_tree
, hf_oran_num_prb
, tvb
, offset
, 1, ENC_BIG_ENDIAN
, &num_prb
);
3087 extlen_remaining_bytes
-= 2;
3089 /* Last pair may be 0,0 if not used. Check for this */
3090 if ((extlen_remaining_bytes
== 0) && (off_start_prb
== 0) && (num_prb
== 0)) {
3091 proto_item_append_text(pair_ti
, " (not used)");
3093 /* Add summary to pair root item, and configure details in ext11_settings */
3095 proto_item_append_text(pair_ti
, "(%u) offStartPrb=%3u, numPrb=%u",
3096 prb_index
, off_start_prb
, num_prb
);
3097 if (ext11_settings
.ext12_num_pairs
< MAX_BFW_EXT12_PAIRS
) {
3098 ext11_settings
.ext12_pairs
[ext11_settings
.ext12_num_pairs
].off_start_prb
= off_start_prb
;
3099 ext11_settings
.ext12_pairs
[ext11_settings
.ext12_num_pairs
++].num_prb
= num_prb
;
3106 case 13: /* SE 13: PRB Allocation with Frequency Hopping */
3108 /* Will update settings for ext11 */
3109 ext11_settings
.ext13_set
= true;
3111 uint32_t extlen_remaining_bytes
= (extlen
*4) - 2;
3112 uint8_t allocation_index
;
3114 unsigned prev_next_symbol_id
= 0, prev_next_start_prbc
= 0;
3116 for (allocation_index
= 1; extlen_remaining_bytes
> 0; allocation_index
++)
3118 /* Subtree for allocation */
3119 proto_item
*allocation_ti
= proto_tree_add_string(extension_tree
, hf_oran_prb_allocation
,
3120 tvb
, offset
, 2, "");
3121 proto_tree
*allocation_tree
= proto_item_add_subtree(allocation_ti
, ett_oran_prb_allocation
);
3123 /* Reserved (2 bits) */
3124 proto_tree_add_item(allocation_tree
, hf_oran_reserved_2bits
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3126 /* nextSymbolId (4 bits) */
3127 uint32_t next_symbol_id
;
3128 proto_tree_add_item_ret_uint(allocation_tree
, hf_oran_nextSymbolId
, tvb
, offset
, 1, ENC_BIG_ENDIAN
, &next_symbol_id
);
3130 /* nextStartPrbc (10 bits) */
3131 uint32_t next_start_prbc
;
3132 proto_tree_add_item_ret_uint(allocation_tree
, hf_oran_nextStartPrbc
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &next_start_prbc
);
3135 /* Add summary to allocation root item */
3136 proto_item_append_text(allocation_ti
, "(%u) nextSymbolId=%3u, nextStartPrbc=%u",
3137 allocation_index
, next_symbol_id
, next_start_prbc
);
3139 /* Checking for duplicates (expected if e.g. had only 2 entries but extlen bytes still to fill */
3140 if ((allocation_index
> 1) && (next_symbol_id
== prev_next_symbol_id
) && (next_start_prbc
== prev_next_start_prbc
)) {
3141 proto_item_append_text(allocation_ti
, " (repeated - to fill up extlen)");
3144 /* Add entry for configuring ext11. don't store out of range */
3145 if (ext11_settings
.ext13_num_start_prbs
< MAX_BFW_EXT13_ALLOCATIONS
) {
3146 ext11_settings
.ext13_start_prbs
[ext11_settings
.ext13_num_start_prbs
++] = next_start_prbc
;
3149 prev_next_symbol_id
= next_symbol_id
;
3150 prev_next_start_prbc
= next_start_prbc
;
3152 extlen_remaining_bytes
-= 2;
3157 case 14: /* SE 14: Nulling-layer Info. for ueId-based beamforming */
3158 /* Hidden filter for bf (DMRS BF) */
3159 bf_ti
= proto_tree_add_item(tree
, hf_oran_bf
, tvb
, 0, 0, ENC_NA
);
3160 PROTO_ITEM_SET_HIDDEN(bf_ti
);
3163 proto_tree_add_item(extension_tree
, hf_oran_nullLayerInd
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3165 proto_tree_add_item(extension_tree
, hf_oran_reserved_8bits
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3169 /* Loop over numPortc++1 (from SE 10) nullLayerInd fields */
3170 for (unsigned port
=0; port
< numPortc
+1; port
++) {
3171 proto_tree_add_item(extension_tree
, hf_oran_nullLayerInd
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3177 case 15: /* SE 15: Mixed-numerology Info. for ueId-based beamforming */
3179 /* frameStructure */
3180 offset
= dissect_frame_structure(extension_tree
, tvb
, offset
,
3181 subframeId
, slotId
);
3183 proto_tree_add_item(extension_tree
, hf_oran_freqOffset
, tvb
, offset
, 3, ENC_BIG_ENDIAN
);
3186 proto_item
*cplength_ti
= proto_tree_add_item(extension_tree
, hf_oran_cpLength
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
3187 if (sectionType
!= 0 && sectionType
!= 3) {
3188 proto_item_append_text(cplength_ti
, " (ignored - used only with ST0 and ST3)");
3194 case 16: /* SE 16: Antenna mapping in UE channel information based UL beamforming */
3196 /* Just filling available bytes with antMask entries.
3197 N.B., if SE 10 also used, could associate each antMask with (beamId or UEId) RX eAxC */
3198 uint32_t extlen_remaining_bytes
= (extlen
*4) - 2;
3199 unsigned num_ant_masks
= extlen_remaining_bytes
/ 8;
3200 for (unsigned n
=0; n
< num_ant_masks
; n
++) {
3201 proto_item
*ti
= proto_tree_add_item(extension_tree
, hf_oran_antMask
, tvb
, offset
, 8, ENC_BIG_ENDIAN
);
3202 proto_item_append_text(ti
, " (RX eAxC #%u)", n
+1);
3208 case 17: /* SE 17: Indication of user port group */
3210 uint32_t extlen_remaining_bytes
= (extlen
*4) - 2;
3211 uint32_t end_bit
= (offset
+extlen_remaining_bytes
) * 8;
3212 uint32_t ueid_index
= 1;
3213 /* TODO: just filling up all available bytes - some may actually be padding.. */
3214 /* "the preceding Section Type and extension messages implicitly provide the number of scheduled users" */
3215 for (uint32_t bit_offset
=offset
*8; bit_offset
< end_bit
; bit_offset
+=4, ueid_index
++) {
3216 proto_item
*ti
= proto_tree_add_bits_item(extension_tree
, hf_oran_num_ueid
, tvb
, bit_offset
, 4, ENC_BIG_ENDIAN
);
3217 proto_item_append_text(ti
, " (user #%u)", ueid_index
);
3222 case 18: /* SE 18: Uplink transmission management */
3223 /* transmissionWindowOffset */
3224 proto_tree_add_item(extension_tree
, hf_oran_transmissionWindowOffset
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
3226 /* reserved (2 bits) */
3227 proto_tree_add_item(extension_tree
, hf_oran_reserved_2bits
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3228 /* transmissionWindowSize (14 bits) */
3229 proto_tree_add_item(extension_tree
, hf_oran_transmissionWindowSize
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
3232 /* reserved (6 bits) */
3233 proto_tree_add_item(extension_tree
, hf_oran_reserved_6bits
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3235 proto_tree_add_item(extension_tree
, hf_oran_toT
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3239 case 19: /* SE 19: Compact beamforming information for multiple port */
3241 /* beamId in section header should be ignored. Guard against appending multiple times.. */
3242 if (beamId_ti
&& !beamId_ignored
) {
3243 proto_item_append_text(beamId_ti
, " (ignored)");
3244 beamId_ignored
= true;
3249 proto_tree_add_item_ret_boolean(extension_tree
, hf_oran_disable_bfws
,
3250 tvb
, offset
, 1, ENC_BIG_ENDIAN
, &disableBFWs
);
3252 proto_item_append_text(extension_ti
, " (disableBFWs)");
3255 uint64_t repetition
;
3256 proto_tree_add_bits_ret_val(extension_tree
, hf_oran_repetition
, tvb
, (offset
*8)+1, 1, &repetition
, ENC_BIG_ENDIAN
);
3258 proto_tree_add_item_ret_uint(extension_tree
, hf_oran_numPortc
,
3259 tvb
, offset
, 1, ENC_BIG_ENDIAN
, &numPortc
);
3263 proto_tree_add_item(extension_tree
, hf_oran_noncontig_priority
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3265 proto_tree_add_item(extension_tree
, hf_oran_symbolMask
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
3269 uint32_t bfwcomphdr_iq_width
, bfwcomphdr_comp_meth
;
3270 proto_item
*comp_meth_ti
= NULL
;
3271 offset
= dissect_bfwCompHdr(tvb
, extension_tree
, offset
,
3272 &bfwcomphdr_iq_width
, &bfwcomphdr_comp_meth
, &comp_meth_ti
);
3276 /* Add entries for each port */
3277 for (unsigned port
=0; port
< numPortc
; port
++) {
3279 /* Create subtree for port entry*/
3280 int port_start_offset
= offset
;
3281 proto_item
*port_ti
= proto_tree_add_string_format(extension_tree
, hf_oran_ext19_port
,
3283 "", "Port %u: ", port
);
3284 proto_tree
*port_tree
= proto_item_add_subtree(port_ti
, ett_oran_ext19_port
);
3286 /* Reserved (4 bits) */
3287 proto_tree_add_item(port_tree
, hf_oran_reserved_4bits
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3288 /* portReMask (12 bits) */
3289 proto_tree_add_item(port_tree
, hf_oran_portReMask
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
3292 /* Reserved (2 bits) */
3293 proto_tree_add_item(port_tree
, hf_oran_reserved_2bits
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3294 /* portSymbolMask (14 bits) */
3295 proto_tree_add_item(port_tree
, hf_oran_portSymbolMask
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
3298 /* Reserved (1 bit) */
3299 proto_tree_add_item(port_tree
, hf_oran_reserved_1bit
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3300 /* beamID (15 bits) */
3301 proto_tree_add_item_ret_uint(port_tree
, hf_oran_beamId
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &beamId
);
3302 proto_item_append_text(port_ti
, " (beamId=%u)", beamId
);
3305 /* No weights present */
3307 /*******************************************************************/
3308 /* Table 7.7.19.1-1 (there is no part -2 for disableBFWs case...), */
3309 /* but for SE 11, bfwCompParam was only present for !disableBFWs */
3310 /*******************************************************************/
3313 bool compression_method_supported
= false;
3314 uint32_t exponent
= 0;
3315 offset
= dissect_bfwCompParam(tvb
, port_tree
, pinfo
, offset
, comp_meth_ti
,
3316 bfwcomphdr_comp_meth
, &exponent
, &compression_method_supported
);
3318 int bit_offset
= offset
*8;
3321 /* Add weights for each TRX */
3322 for (unsigned b
=0; b
< pref_num_bf_antennas
; b
++) {
3324 /* Create BFW subtree */
3325 bfw_offset
= bit_offset
/ 8;
3326 uint8_t bfw_extent
= ((bit_offset
+ (bfwcomphdr_iq_width
*2)) / 8) - bfw_offset
;
3327 proto_item
*bfw_ti
= proto_tree_add_string_format(port_tree
, hf_oran_bfw
,
3328 tvb
, bfw_offset
, bfw_extent
,
3329 "", "TRX %u: (", b
);
3330 proto_tree
*bfw_tree
= proto_item_add_subtree(bfw_ti
, ett_oran_bfw
);
3333 /* Get bits, and convert to float. */
3334 uint32_t bits
= tvb_get_bits(tvb
, bit_offset
, bfwcomphdr_iq_width
, ENC_BIG_ENDIAN
);
3335 float value
= decompress_value(bits
, bfwcomphdr_comp_meth
, bfwcomphdr_iq_width
, exponent
);
3337 proto_tree_add_float_format_value(bfw_tree
, hf_oran_bfw_i
, tvb
, bit_offset
/8,
3338 (bfwcomphdr_iq_width
+7)/8, value
, "#%u=%f", b
, value
);
3339 bit_offset
+= bfwcomphdr_iq_width
;
3340 proto_item_append_text(bfw_ti
, "I%u=%f ", b
, value
);
3343 /* Get bits, and convert to float. */
3344 bits
= tvb_get_bits(tvb
, bit_offset
, bfwcomphdr_iq_width
, ENC_BIG_ENDIAN
);
3345 value
= decompress_value(bits
, bfwcomphdr_comp_meth
, bfwcomphdr_iq_width
, exponent
);
3347 proto_tree_add_float_format_value(bfw_tree
, hf_oran_bfw_q
, tvb
, bit_offset
/8,
3348 (bfwcomphdr_iq_width
+7)/8, value
, "#%u=%f", b
, value
);
3349 bit_offset
+= bfwcomphdr_iq_width
;
3350 proto_item_append_text(bfw_ti
, "Q%u=%f)", b
, value
);
3353 offset
= (bit_offset
+7)/8;
3358 /* Reserved (1 bit) */
3359 proto_tree_add_item(extension_tree
, hf_oran_reserved_1bit
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3360 /* beamID (15 bits) */
3361 proto_tree_add_item_ret_uint(extension_tree
, hf_oran_beamId
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &beamId
);
3362 proto_item_append_text(port_ti
, " (beamId=%u)", beamId
);
3366 /* Set length of this port entry */
3367 proto_item_set_len(port_ti
, offset
-port_start_offset
);
3373 case 20: /* SE 20: Puncturing extension */
3375 /* numPuncPatterns */
3376 uint32_t numPuncPatterns
;
3377 proto_tree_add_item_ret_uint(extension_tree
, hf_oran_numPuncPatterns
, tvb
, offset
, 1, ENC_BIG_ENDIAN
, &numPuncPatterns
);
3380 /* Add each puncturing pattern */
3381 for (uint32_t n
=0; n
< numPuncPatterns
; n
++) {
3382 unsigned pattern_start_offset
= offset
;
3384 /* Subtree for this puncturing pattern */
3385 proto_item
*pattern_ti
= proto_tree_add_string_format(extension_tree
, hf_oran_puncPattern
,
3387 "", "Puncturing Pattern: %u/%u", n
+1, hf_oran_numPuncPatterns
);
3388 proto_tree
*pattern_tree
= proto_item_add_subtree(pattern_ti
, ett_oran_punc_pattern
);
3390 /* SymbolMask (14 bits) */
3391 proto_tree_add_item(pattern_tree
, hf_oran_symbolMask_ext20
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
3393 /* startPuncPrb (10 bits) */
3394 proto_tree_add_item(pattern_tree
, hf_oran_startPuncPrb
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3396 /* numPuncPrb (8 bits) */
3397 proto_tree_add_item(pattern_tree
, hf_oran_numPuncPrb
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3399 /* puncReMask (12 bits) */
3400 proto_tree_add_item(pattern_tree
, hf_oran_puncReMask
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
3403 proto_item
*rb_ti
= proto_tree_add_item(pattern_tree
, hf_oran_rb
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3404 /* reserved (1 bit) */
3405 proto_tree_add_item(pattern_tree
, hf_oran_reserved_bit5
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3406 /* multiSDScope (1 bit) */
3407 proto_tree_add_item(pattern_tree
, hf_oran_multiSDScope
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3408 /* rbgIncl (1 bit) */
3410 proto_tree_add_item_ret_boolean(pattern_tree
, hf_oran_RbgIncl
, tvb
, offset
, 1, ENC_BIG_ENDIAN
, &rbgIncl
);
3414 /* reserved (1 bit) */
3415 proto_tree_add_item(pattern_tree
, hf_oran_reserved_1bit
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3416 /* rbgSize(3 bits) */
3417 proto_tree_add_item(pattern_tree
, hf_oran_rbgSize
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3418 /* rbgMask (28 bits) */
3419 proto_tree_add_item(pattern_tree
, hf_oran_rbgMask
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
3422 proto_item_append_text(rb_ti
, " (ignored)");
3425 proto_item_set_len(pattern_ti
, offset
-pattern_start_offset
);
3430 case 21: /* SE 21: Variable PRB group size for channel information */
3432 /* ciPrbGroupSize */
3433 uint32_t ci_prb_group_size
;
3434 proto_item
*prb_group_size_ti
= proto_tree_add_item_ret_uint(extension_tree
, hf_oran_ci_prb_group_size
, tvb
, offset
, 1, ENC_BIG_ENDIAN
, &ci_prb_group_size
);
3437 switch (ci_prb_group_size
) {
3441 /* Reserved value */
3442 expert_add_info_format(pinfo
, prb_group_size_ti
, &ei_oran_ci_prb_group_size_reserved
,
3443 "SE 11 ciPrbGroupSize is reserved value %u - must be 2-254",
3448 /* This value affects how SE 11 is interpreted */
3449 ext11_settings
.ext21_set
= true;
3450 ext11_settings
.ext21_ci_prb_group_size
= ci_prb_group_size
;
3453 expert_add_info(pinfo
, numprbc_ti
, &ei_oran_numprbc_ext21_zero
);
3458 /* reserved (6 bits) */
3459 proto_tree_add_item(extension_tree
, hf_oran_reserved_6bits
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3461 /* prgSize (2 bits). Interpretation depends upon section type (5 or 6), but also mplane parameters? */
3462 if (sectionType
== SEC_C_UE_SCHED
) { /* Section Type 5 */
3463 proto_tree_add_item(extension_tree
, hf_oran_prg_size_st5
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3465 else if (sectionType
== SEC_C_CH_INFO
) { /* Section Type 6 */
3466 proto_tree_add_item(extension_tree
, hf_oran_prg_size_st6
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3472 case 22: /* SE 22: ACK/NACK request */
3474 uint32_t ack_nack_req_id
;
3475 proto_tree_add_item_ret_uint(extension_tree
, hf_oran_ack_nack_req_id
, tvb
, offset
, 2,
3476 ENC_BIG_ENDIAN
, &ack_nack_req_id
);
3480 if (!PINFO_FD_VISITED(pinfo
)) {
3481 /* Add this request into conversation state on first pass */
3482 ack_nack_request_t
*request_details
= wmem_new0(wmem_file_scope(), ack_nack_request_t
);
3483 request_details
->request_frame_number
= pinfo
->num
;
3484 request_details
->request_frame_time
= pinfo
->abs_ts
;
3485 request_details
->requestType
= SE22
;
3486 /* Insert into flow's tree */
3487 wmem_tree_insert32(state
->ack_nack_requests
, ack_nack_req_id
, request_details
);
3490 /* Try to link forward to ST8 response */
3491 ack_nack_request_t
*response
= wmem_tree_lookup32(state
->ack_nack_requests
,
3494 show_link_to_acknack_response(extension_tree
, tvb
, pinfo
, response
);
3501 case 23: /* SE 23: Arbitrary symbol pattern modulation compression parameters */
3503 /* Green common header */
3505 /* numSymPrbPattern (4 bits) */
3506 uint32_t num_sym_prb_pattern
;
3507 proto_tree_add_item_ret_uint(extension_tree
, hf_oran_num_sym_prb_pattern
, tvb
, offset
, 1, ENC_BIG_ENDIAN
, &num_sym_prb_pattern
);
3508 /* reserved (3 bits) */
3509 proto_tree_add_item(extension_tree
, hf_oran_reserved_bits456
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3510 /* prbMode (1 bit) */
3512 proto_tree_add_item_ret_boolean(extension_tree
, hf_oran_prb_mode
, tvb
, offset
, 1, ENC_BIG_ENDIAN
, &prb_mode
);
3515 /* reserved (8 bits) */
3516 proto_tree_add_item(extension_tree
, hf_oran_reserved_8bits
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3519 /* Dissect each SymPrbPattern */
3520 for (uint32_t n
=0; n
< num_sym_prb_pattern
; n
++) {
3523 proto_item
*pattern_ti
= proto_tree_add_string_format(extension_tree
, hf_oran_sym_prb_pattern
,
3525 prb_mode
? "PRB-BLOCK" : "PRB-MASK");
3526 proto_tree
*pattern_tree
= proto_item_add_subtree(pattern_ti
, ett_oran_sym_prb_pattern
);
3531 /* Reserved (2 bits) */
3532 proto_tree_add_item(pattern_tree
, hf_oran_reserved_2bits
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3533 /* symMask (14 bits) */
3534 proto_tree_add_item(pattern_tree
, hf_oran_sym_mask
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
3536 /* numMcScaleOffset (4 bits) */
3537 proto_tree_add_item(pattern_tree
, hf_oran_num_mc_scale_offset
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3539 if (!prb_mode
) { /* PRB-MASK */
3540 /* prbPattern (4 bits) */
3541 proto_tree_add_item(pattern_tree
, hf_oran_prb_pattern
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3543 /* reserved (8 bits) */
3544 proto_tree_add_item(pattern_tree
, hf_oran_reserved_8bits
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3547 else { /* PRB-BLOCK */
3548 /* prbBlkOffset (8 bits) */
3549 proto_tree_add_item(pattern_tree
, hf_oran_prb_block_offset
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3551 /* prbBlkSize (4 bits) */
3552 proto_tree_add_item(pattern_tree
, hf_oran_prb_block_size
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3556 /* Yellowish part */
3557 if (prb_mode
) { /* PRB-BLOCK */
3558 /* prbBlkSize (4 bits) */
3559 proto_tree_add_item(pattern_tree
, hf_oran_prb_block_size
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3562 /* reserved (4 bits) */
3563 proto_tree_add_item(pattern_tree
, hf_oran_reserved_4bits
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3566 /* mcScaleReMask (12 bits) */
3567 uint64_t mcScaleReMask
, mcScaleOffset
;
3568 proto_tree_add_bits_ret_val(pattern_tree
, hf_oran_mc_scale_re_mask
, tvb
, offset
*8 + 4, 12, &mcScaleReMask
, ENC_BIG_ENDIAN
);
3571 dissect_csf(pattern_tree
, tvb
, offset
*8, ci_iq_width
, NULL
);
3572 /* mcScaleOffset (15 bits) */
3573 proto_tree_add_bits_ret_val(pattern_tree
, hf_oran_mc_scale_offset
, tvb
, offset
*8 + 1, 15, &mcScaleOffset
, ENC_BIG_ENDIAN
);
3576 proto_item_set_end(pattern_ti
, tvb
, offset
);
3581 case 24: /* SE 24: PUSCH DMRS configuration */
3583 /* Hidden filter for bf (DMRS BF) */
3584 bf_ti
= proto_tree_add_item(tree
, hf_oran_bf
, tvb
, 0, 0, ENC_NA
);
3585 PROTO_ITEM_SET_HIDDEN(bf_ti
);
3587 /* alpnPerSym (1 bit) */
3588 proto_tree_add_item(extension_tree
, hf_oran_alpn_per_sym
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3589 /* antDmrsSnr (1 bit) */
3590 proto_tree_add_item(extension_tree
, hf_oran_ant_dmrs_snr
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3591 /* reserved (1 bit) */
3592 proto_tree_add_item(extension_tree
, hf_oran_reserved_bit2
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3593 /* userGroupSize (5 bits) */
3594 uint32_t user_group_size
;
3595 proto_item
*ugs_ti
= proto_tree_add_item_ret_uint(extension_tree
, hf_oran_user_group_size
, tvb
, offset
, 1, ENC_BIG_ENDIAN
, &user_group_size
);
3596 if (user_group_size
== 0) {
3597 proto_item_append_text(ugs_ti
, " (not used)");
3599 else if (user_group_size
> 12) {
3600 proto_item_append_text(ugs_ti
, " (reserved)");
3603 /* userGroupId (8 bits) */
3604 uint32_t user_group_id
;
3605 proto_tree_add_item_ret_uint(extension_tree
, hf_oran_user_group_id
, tvb
, offset
, 1, ENC_BIG_ENDIAN
, &user_group_id
);
3606 if (user_group_id
== 0) {
3607 /* TODO: Value 0 can happen in several cases, described in 7.7.24.7.. */
3611 /* Dissect each entry (until run out of extlen bytes..). Not sure how this works with padding bytes though... */
3612 /* TODO: how to know when have seen last entry? Zero byte (within last 3 bytes of space) are valid... */
3613 while (offset
< (extension_start_offset
+ extlen
*4)) {
3616 proto_item
*entry_ti
= proto_tree_add_string_format(extension_tree
, hf_oran_dmrs_entry
,
3619 proto_tree
*entry_tree
= proto_item_add_subtree(entry_ti
, ett_oran_dmrs_entry
);
3621 /* entryType (3 bits) */
3622 uint32_t entry_type
;
3623 proto_item
*entry_type_ti
;
3624 entry_type_ti
= proto_tree_add_item_ret_uint(entry_tree
, hf_oran_entry_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
, &entry_type
);
3625 if (entry_type
> 3) {
3626 proto_item_append_text(entry_type_ti
, " (reserved)");
3629 /* dmrsPortNumber (5 bits). Values 0-11 allowed */
3630 unsigned int dmrs_port_number
;
3631 proto_item
*dpn_ti
= proto_tree_add_item_ret_uint(entry_tree
, hf_oran_dmrs_port_number
, tvb
, offset
, 1, ENC_BIG_ENDIAN
, &dmrs_port_number
);
3632 if (dmrs_port_number
> 11) {
3633 proto_item_append_text(dpn_ti
, " (12-31 are reserved)");
3637 /* What follows depends upon entryType */
3638 switch (entry_type
) {
3641 /* No further fields for these */
3646 /* Type 2/3 are very similar.. */
3648 /* ueIdReset (1 bit) */
3649 proto_tree_add_item(entry_tree
, hf_oran_ueid_reset
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3650 /* reserved (1 bit) */
3651 proto_tree_add_item(entry_tree
, hf_oran_reserved_bit1
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3652 /* dmrsSymbolMask (14 bits) */
3653 /* TODO: break down into separate mask fields? */
3654 proto_tree_add_item(entry_tree
, hf_oran_dmrs_symbol_mask
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
3658 proto_tree_add_item(entry_tree
, hf_oran_scrambling
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
3662 proto_tree_add_item(entry_tree
, hf_oran_nscid
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3664 /* These 5 bits differ depending upon entry type */
3665 if (entry_type
== 2) {
3667 proto_tree_add_item(entry_tree
, hf_oran_dtype
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3668 /* cdmWithoutData (2 bits) */
3669 proto_tree_add_item(entry_tree
, hf_oran_cmd_without_data
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3670 /* lambda (2 bits) */
3671 proto_tree_add_item(entry_tree
, hf_oran_lambda
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3674 /* reserved (1 bit) */
3675 proto_tree_add_item(entry_tree
, hf_oran_reserved_bit1
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3676 /* lowPaprType (2 bits) */
3677 proto_tree_add_item(entry_tree
, hf_oran_low_papr_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3678 /* hoppingMode (2 bits) */
3679 proto_tree_add_item(entry_tree
, hf_oran_hopping_mode
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3682 /* firstPrb (9 bits) */
3683 proto_tree_add_item(entry_tree
, hf_oran_first_prb
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
3685 /* lastPrb (9 bits) */
3686 proto_tree_add_item(entry_tree
, hf_oran_last_prb
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
3688 /* Reserved (16 bits) */
3689 proto_tree_add_item(entry_tree
, hf_oran_reserved_16bits
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
3694 /* reserved - expert info */
3698 proto_item_append_text(entry_ti
, " (type=%u)", entry_type
);
3699 proto_item_set_end(entry_ti
, tvb
, offset
);
3704 case 25: /* SE 25: Symbol reordering for DMRS-BF */
3705 /* Just dissect each available block of 7 bytes as the 14 symbols for a layer,
3706 where each layer could be one or apply to all layers. */
3708 /* TODO: should only appear in one section of a message.. */
3710 proto_item
*layer_ti
;
3711 while (offset
+7 <= (extension_start_offset
+ extlen
*4)) {
3713 layer_ti
= proto_tree_add_string_format(extension_tree
, hf_oran_symbol_reordering_layer
,
3716 proto_tree
*layer_tree
= proto_item_add_subtree(layer_ti
, ett_oran_symbol_reordering_layer
);
3718 /* All 14 symbols for a layer (or all layers) */
3719 for (unsigned s
=0; s
< 14; s
++) {
3721 /* txWinForOnAirSymbol */
3722 unsigned int tx_win_for_on_air_symbol
;
3723 sym_ti
= proto_tree_add_item_ret_uint(layer_tree
,
3724 (s
% 2) ? hf_oran_tx_win_for_on_air_symbol_r
: hf_oran_tx_win_for_on_air_symbol_l
,
3725 tvb
, offset
, 1, ENC_BIG_ENDIAN
, &tx_win_for_on_air_symbol
);
3726 if (tx_win_for_on_air_symbol
== 0x0F) {
3727 /* Ordering not affected */
3728 proto_item_append_text(sym_ti
, " (sym %u - no info)", s
);
3731 proto_item_append_text(sym_ti
, " (sym %u)", s
);
3738 proto_item_append_text(layer_ti
, " (layer %u)", ++layer
);
3740 /* Set layer subtree label */
3742 proto_item_append_text(layer_ti
, " (all)");
3747 case 26: /* SE 26: Frequency offset feedback */
3748 /* Reserved (8 bits). N.B., added after draft? */
3749 proto_tree_add_item(extension_tree
, hf_oran_reserved_8bits
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3752 /* Reserved (1 bit) */
3753 proto_tree_add_item(extension_tree
, hf_oran_reserved_1bit
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3754 /* numFoFb (7 bits) */
3756 proto_tree_add_item_ret_uint(extension_tree
, hf_oran_num_fo_fb
, tvb
, offset
, 1, ENC_BIG_ENDIAN
, &num_fo_fb
);
3759 /* Add each freqOffsetFb value */
3760 for (unsigned n
=0; n
< num_fo_fb
; n
++) {
3761 unsigned freq_offset_fb
;
3762 /* freqOffsetFb (16 bits) */
3763 proto_item
*offset_ti
= proto_tree_add_item_ret_uint(extension_tree
, hf_oran_freq_offset_fb
,
3764 tvb
, offset
, 2, ENC_BIG_ENDIAN
, &freq_offset_fb
);
3765 /* Show if maps onto a -ve number */
3766 if ((freq_offset_fb
>= 0x8ad0) && (freq_offset_fb
<= 0xffff)) {
3767 proto_item_append_text(offset_ti
, "(value %d)", -1 - (0xffff-freq_offset_fb
));
3769 proto_item_append_text(offset_ti
, " [#%u]", n
+1);
3774 case 27: /* SE 27: O-DU controlled dimensionality reduction */
3776 /* Hidden filter for bf (DMRS BF) */
3777 bf_ti
= proto_tree_add_item(tree
, hf_oran_bf
, tvb
, 0, 0, ENC_NA
);
3778 PROTO_ITEM_SET_HIDDEN(bf_ti
);
3780 /* beamType (2 bits) */
3782 proto_tree_add_item_ret_uint(extension_tree
, hf_oran_beam_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
, &beam_type
);
3783 /* reserved (6 bits) */
3784 proto_tree_add_item(extension_tree
, hf_oran_reserved_last_6bits
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3788 unsigned num_elements
;
3789 proto_tree_add_item_ret_uint(extension_tree
, hf_oran_num_elements
, tvb
, offset
, 1, ENC_BIG_ENDIAN
, &num_elements
);
3792 /* beamId value(s) */
3793 switch (num_elements
) {
3795 for (unsigned n
=0; n
< num_elements
; n
++) {
3796 /* reserved (1 bit) + beamId */
3797 proto_tree_add_item(extension_tree
, hf_oran_reserved_1bit
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3798 proto_tree_add_item(c_section_tree
, hf_oran_beamId
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
3803 /* reserved (1 bit) + beamId */
3804 proto_tree_add_item(extension_tree
, hf_oran_reserved_1bit
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3805 proto_tree_add_item(c_section_tree
, hf_oran_beamId
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
3809 /* Unknown type... */
3816 /* Other/unexpected extension types */
3817 expert_add_info_format(pinfo
, exttype_ti
, &ei_oran_unhandled_se
,
3818 "SE %u (%s) not supported by dissector",
3819 exttype
, val_to_str_const(exttype
, exttype_vals
, "Reserved"));
3820 ext_unhandled
= true;
3824 /* Check offset compared with extlen. There should be 0-3 bytes of padding */
3825 int num_padding_bytes
= (extension_start_offset
+ (extlen
*4) - offset
);
3826 if (!ext_unhandled
&& ((num_padding_bytes
<0) || (num_padding_bytes
>3))) {
3827 expert_add_info_format(pinfo
, extlen_ti
, &ei_oran_extlen_wrong
,
3828 "extlen signalled %u bytes (+ 0-3 bytes padding), but %u were dissected",
3829 extlen
*4, offset
-extension_start_offset
);
3832 /* Move offset to beyond signalled length of extension */
3833 offset
= extension_start_offset
+ (extlen
*4);
3835 /* Set length of extension header. */
3836 proto_item_set_len(extension_ti
, extlen
*4);
3838 /* End of section extension handling */
3842 /* RRM measurement reports have measurement reports after extensions */
3843 if (sectionType
== SEC_C_RRM_MEAS_REPORTS
) /* Section Type 10 */
3845 /* Hidden filter for bf (DMFS-BF) */
3846 bf_ti
= proto_tree_add_item(c_section_tree
, hf_oran_bf
, tvb
, 0, 0, ENC_NA
);
3847 PROTO_ITEM_SET_HIDDEN(bf_ti
);
3851 /* Measurement report subtree */
3852 proto_item
*mr_ti
= proto_tree_add_item(c_section_tree
, hf_oran_measurement_report
,
3853 tvb
, offset
, 0, ENC_ASCII
);
3854 proto_tree
*mr_tree
= proto_item_add_subtree(mr_ti
, ett_oran_measurement_report
);
3855 unsigned report_start_offset
= offset
;
3858 proto_tree_add_item_ret_boolean(mr_tree
, hf_oran_mf
, tvb
, offset
, 1, ENC_BIG_ENDIAN
, &mf
);
3860 /* measTypeId (7 bits) */
3861 uint32_t meas_type_id
;
3862 proto_item
*meas_type_id_ti
;
3863 meas_type_id_ti
= proto_tree_add_item_ret_uint(mr_tree
, hf_oran_meas_type_id
, tvb
, offset
, 1, ENC_BIG_ENDIAN
, &meas_type_id
);
3866 /* Common to all measurement types */
3867 unsigned num_elements
= 0;
3868 if (meas_type_id
== 6) {
3870 proto_tree_add_item_ret_uint(mr_tree
, hf_oran_num_elements
, tvb
, offset
, 1, ENC_BIG_ENDIAN
, &num_elements
);
3873 /* All other meas ids have a reserved byte */
3874 proto_tree_add_item(mr_tree
, hf_oran_reserved_8bits
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3878 /* measDataSize (16 bits). N.B. begins at mf field, i.e. 2 bytes before this one */
3879 unsigned meas_data_size
;
3880 proto_item
*meas_data_size_ti
;
3881 meas_data_size_ti
= proto_tree_add_item_ret_uint(mr_tree
, hf_oran_meas_data_size
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &meas_data_size
);
3882 meas_data_size
*= 4;
3883 proto_item_append_text(meas_data_size_ti
, " (%u bytes)", meas_data_size
);
3886 /* Summary for measurement report root */
3887 proto_item_append_text(mr_ti
, " (%s)", val_to_str_const(meas_type_id
, meas_type_id_vals
, "unknown"));
3888 /* And section header */
3889 proto_item_append_text(tree
, " (%s)", val_to_str_const(meas_type_id
, meas_type_id_vals
, "unknown"));
3891 switch (meas_type_id
) {
3896 proto_item
*ue_tae_ti
;
3897 ue_tae_ti
= proto_tree_add_item_ret_uint(mr_tree
, hf_oran_ue_tae
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &ue_tae
);
3898 /* Show if maps onto a -ve number */
3899 if ((ue_tae
>= 0x8ad0) && (ue_tae
<= 0xffff)) {
3900 proto_item_append_text(ue_tae_ti
, "(value %d)", -1 - (0xffff-ue_tae
));
3904 /* Reserved (16 bits) */
3905 proto_tree_add_item(mr_tree
, hf_oran_reserved_16bits
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
3910 /* ueLayerPower entries (how many? for now just use up meas_data_size..) */
3911 for (unsigned n
=0; n
< (meas_data_size
-4)/2; n
++) {
3912 unsigned ue_layer_power
;
3913 proto_item
*ue_layer_power_ti
;
3914 ue_layer_power_ti
= proto_tree_add_item_ret_uint(mr_tree
, hf_oran_ue_layer_power
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &ue_layer_power
);
3915 /* Show if maps onto a -ve number */
3916 if ((ue_layer_power
>= 0x8ad0) && (ue_layer_power
<= 0xffff)) {
3917 proto_item_append_text(ue_layer_power_ti
, "(value %d)", -1 - (0xffff-ue_layer_power
));
3921 /* padding out to 4 bytes */
3926 unsigned ue_freq_offset
;
3927 proto_item
*ue_freq_offset_ti
;
3928 ue_freq_offset_ti
= proto_tree_add_item_ret_uint(mr_tree
, hf_oran_ue_freq_offset
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &ue_freq_offset
);
3929 /* Show if maps onto a -ve number */
3930 if ((ue_freq_offset
>= 0x8ad0) && (ue_freq_offset
<= 0xffff)) {
3931 proto_item_append_text(ue_freq_offset_ti
, "(value %d)", -1 - (0xffff-ue_freq_offset
));
3935 /* Reserved (16 bits) */
3936 proto_tree_add_item(mr_tree
, hf_oran_reserved_16bits
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
3942 /* reserved (2 bits) */
3943 proto_tree_add_item(mr_tree
, hf_oran_reserved_2bits
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3944 /* symbolMask (14 bits) */
3945 proto_tree_add_item(mr_tree
, hf_oran_symbolMask
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
3948 /* 2 bytes for each PRB ipnPower */
3949 for (unsigned n
=0; n
< numPrbc
; n
++) {
3951 proto_item
*ipn_power_ti
;
3952 /* ipnPower (2 bytes) */
3953 ipn_power_ti
= proto_tree_add_item_ret_uint(mr_tree
, hf_oran_ipn_power
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &ipn_power
);
3954 proto_item_append_text(ipn_power_ti
, " (PRB %3d)", startPrbc
+n
);
3955 /* Show if maps onto a -ve number */
3956 if ((ipn_power
>= 0x8ad0) && (ipn_power
<= 0xffff)) {
3957 proto_item_append_text(ipn_power_ti
, " (value %d)", -1 - (0xffff-ipn_power
));
3961 /* padding out to 4 bytes */
3964 /* antDmrsSnrVal entries */
3965 for (unsigned n
=0; n
< num_elements
; n
++) {
3967 proto_item
*snr_value_ti
;
3968 /* antDmrsSnrVal (2 bytes) */
3969 snr_value_ti
= proto_tree_add_item_ret_uint(mr_tree
, hf_oran_ant_dmrs_snr_val
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &snr_value
);
3970 proto_item_append_text(snr_value_ti
, " (elem %2u)", n
+1);
3971 /* Show if maps onto a -ve number */
3972 if ((snr_value
>= 0x8ad0) && (snr_value
<= 0xffff)) {
3973 proto_item_append_text(snr_value_ti
, " (value %d)", -1 - (0xffff-snr_value
));
3980 /* Anything else is not expected */
3981 expert_add_info_format(pinfo
, meas_type_id_ti
, &ei_oran_unexpected_measTypeId
,
3982 "measTypeId %u (%s) not supported - only 1-6 are expected",
3984 val_to_str_const(meas_type_id
, meas_type_id_vals
, "reserved"));
3989 /* Pad out to next 4 bytes */
3990 if ((offset
-report_start_offset
) % 4) {
3991 offset
+= (4 - ((offset
-report_start_offset
) % 4));
3994 /* End of measurement report tree */
3995 proto_item_set_end(mr_ti
, tvb
, offset
);
3999 /* Request for RRM Measurements has commands after extensions */
4000 if (sectionType
== SEC_C_REQUEST_RRM_MEAS
) /* Section Type 11 */
4004 /* Measurement report subtree */
4005 proto_item
*mr_ti
= proto_tree_add_item(c_section_tree
, hf_oran_measurement_report
,
4006 tvb
, offset
, 0, ENC_ASCII
);
4007 proto_tree
*mr_tree
= proto_item_add_subtree(mr_ti
, ett_oran_measurement_report
);
4010 proto_tree_add_item_ret_boolean(mr_tree
, hf_oran_mf
, tvb
, offset
, 1, ENC_BIG_ENDIAN
, &mf
);
4012 /* measTypeId (7 bits) */
4013 uint32_t meas_type_id
;
4014 proto_item
*meas_type_id_ti
;
4015 meas_type_id_ti
= proto_tree_add_item_ret_uint(mr_tree
, hf_oran_meas_type_id
, tvb
, offset
, 1, ENC_BIG_ENDIAN
, &meas_type_id
);
4018 proto_item
*meas_command_ti
;
4019 uint32_t meas_command_size
;
4021 switch (meas_type_id
) {
4022 case 5: /* command for IpN for unallocated PRBs */
4023 /* reserved (1 byte) */
4024 proto_tree_add_item(mr_tree
, hf_oran_reserved_8bits
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
4026 /* measCmdSize. Presumably number of words so in future could skip unrecognised command types.. */
4027 meas_command_ti
= proto_tree_add_item_ret_uint(mr_tree
, hf_oran_meas_cmd_size
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &meas_command_size
);
4028 proto_item_append_text(meas_command_ti
, " (%u bytes)", meas_command_size
*4);
4030 /* reserved (2 bits) */
4031 proto_tree_add_item(mr_tree
, hf_oran_reserved_2bits
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
4032 /* symbolMask (14 bits) */
4033 proto_tree_add_item(mr_tree
, hf_oran_symbolMask
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
4035 /* reserved (16 bits) */
4036 proto_tree_add_item(mr_tree
, hf_oran_reserved_16bits
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
4041 /* Anything else is not expected */
4042 expert_add_info_format(pinfo
, meas_type_id_ti
, &ei_oran_unexpected_measTypeId
,
4043 "measTypeId %u (%s) not supported - only 5 is expected",
4045 val_to_str_const(meas_type_id
, meas_type_id_vals
, "reserved"));
4051 /* Set extent of overall section */
4052 proto_item_set_len(sectionHeading
, offset
);
4057 /* Dissect udCompHdr (user data compression header, 7.5.2.10) */
4058 /* bit_width and comp_meth are out params */
4059 static int dissect_udcomphdr(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, unsigned offset
,
4061 unsigned *bit_width
, unsigned *comp_meth
, proto_item
**comp_meth_ti
)
4064 proto_item
*udcomphdr_ti
= proto_tree_add_string_format(tree
, hf_oran_udCompHdr
,
4067 proto_tree
*udcomphdr_tree
= proto_item_add_subtree(udcomphdr_ti
, ett_oran_udcomphdr
);
4070 uint32_t hdr_iq_width
;
4071 proto_item
*iq_width_item
= proto_tree_add_item_ret_uint(udcomphdr_tree
, hf_oran_udCompHdrIqWidth
, tvb
, offset
, 1, ENC_NA
, &hdr_iq_width
);
4072 *bit_width
= (hdr_iq_width
) ? hdr_iq_width
: 16;
4073 proto_item_append_text(iq_width_item
, " (%u bits)", *bit_width
);
4076 uint32_t ud_comp_meth
;
4077 *comp_meth_ti
= proto_tree_add_item_ret_uint(udcomphdr_tree
, hf_oran_udCompHdrMeth
, tvb
, offset
, 1, ENC_NA
, &ud_comp_meth
);
4079 *comp_meth
= ud_comp_meth
;
4084 proto_item_append_text(udcomphdr_ti
, " (IqWidth=%u, udCompMeth=%s)",
4085 *bit_width
, rval_to_str_const(ud_comp_meth
, ud_comp_header_meth
, "Unknown"));
4088 proto_item_append_text(udcomphdr_ti
, " (ignored)");
4089 if (hdr_iq_width
|| ud_comp_meth
) {
4090 expert_add_info_format(pinfo
, udcomphdr_ti
, &ei_oran_udpcomphdr_should_be_zero
,
4091 "udCompHdr in C-Plane for DL should be 0 - found %02x",
4092 tvb_get_uint8(tvb
, offset
));
4099 /* Dissect udCompParam (user data compression parameter, 8.3.3.15) */
4100 /* bit_width and comp_meth are out params */
4101 static int dissect_udcompparam(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, unsigned offset
,
4103 uint32_t *exponent
, uint16_t *sReSMask
,
4106 if (comp_meth
== COMP_NONE
||
4107 comp_meth
== COMP_MODULATION
||
4108 comp_meth
== MOD_COMPR_AND_SELECTIVE_RE_WITH_MASKS
) {
4110 /* Not even creating a subtree for udCompMeth 0, 4, 8 */
4115 unsigned start_offset
= offset
;
4116 proto_item
*udcompparam_ti
= proto_tree_add_string_format(tree
, hf_oran_udCompParam
,
4118 (for_sinr
) ? "sinrCompHdr" : "udCompParam");
4119 proto_tree
*udcompparam_tree
= proto_item_add_subtree(udcompparam_ti
, ett_oran_udcompparam
);
4121 /* Show comp_meth as a generated field */
4122 proto_item
*meth_ti
= proto_tree_add_uint(udcompparam_tree
, hf_oran_udCompHdrMeth_pref
, tvb
, 0, 0, comp_meth
);
4123 proto_item_set_generated(meth_ti
);
4125 uint32_t param_exponent
;
4126 uint64_t param_sresmask
;
4128 static int * const sres_mask_flags
[] = {
4129 &hf_oran_sReSMask_re12
,
4130 &hf_oran_sReSMask_re11
,
4131 &hf_oran_sReSMask_re10
,
4132 &hf_oran_sReSMask_re9
,
4133 &hf_oran_sReSMask_re8
,
4134 &hf_oran_sReSMask_re7
,
4135 &hf_oran_sReSMask_re6
,
4136 &hf_oran_sReSMask_re5
,
4137 &hf_oran_sReSMask_re4
,
4138 &hf_oran_sReSMask_re3
,
4139 &hf_oran_sReSMask_re2
,
4140 &hf_oran_sReSMask_re1
,
4144 switch (comp_meth
) {
4145 case COMP_BLOCK_FP
: /* 1 */
4146 case BFP_AND_SELECTIVE_RE_WITH_MASKS
: /* 7 */
4147 /* reserved (4 bits) */
4148 proto_tree_add_item(udcompparam_tree
, hf_oran_reserved_4bits
, tvb
, offset
, 1, ENC_NA
);
4149 /* exponent (4 bits) */
4150 proto_tree_add_item_ret_uint(udcompparam_tree
, hf_oran_exponent
,
4151 tvb
, offset
, 1, ENC_BIG_ENDIAN
, ¶m_exponent
);
4152 *exponent
= param_exponent
;
4153 proto_item_append_text(udcompparam_ti
, " (Exponent=%u)", param_exponent
);
4157 case COMP_BLOCK_SCALE
: /* 2 */
4158 /* Separate into integer and fractional bits? */
4159 proto_tree_add_item(udcompparam_tree
, hf_oran_blockScaler
,
4160 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
4164 case COMP_U_LAW
: /* 3 */
4165 /* compBitWidth, compShift */
4166 proto_tree_add_item(udcompparam_tree
, hf_oran_compBitWidth
,
4167 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
4168 proto_tree_add_item(udcompparam_tree
, hf_oran_compShift
,
4169 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
4173 case BFP_AND_SELECTIVE_RE
: /* 5 */
4175 /* sReSMask (exponent in middle!) */
4176 proto_item
*sresmask_ti
;
4177 sresmask_ti
= proto_tree_add_bitmask_ret_uint64(udcompparam_tree
, tvb
, offset
,
4184 /* Get rid of exponent-shaped gap */
4185 param_sresmask
= ((param_sresmask
>> 4) & 0x0f00) | (param_sresmask
& 0xff);
4187 for (unsigned n
=0; n
< 12; n
++) {
4188 if ((param_sresmask
>> n
) & 0x1) {
4192 proto_item_append_text(sresmask_ti
, " (%2u REs)", res
);
4195 proto_tree_add_item_ret_uint(udcompparam_tree
, hf_oran_exponent
,
4196 tvb
, offset
, 1, ENC_BIG_ENDIAN
, ¶m_exponent
);
4197 *sReSMask
= (uint16_t)param_sresmask
;
4198 *exponent
= param_exponent
;
4200 proto_item_append_text(udcompparam_ti
, " (exponent=%u, %u REs)", *exponent
, res
);
4205 case MOD_COMPR_AND_SELECTIVE_RE
: /* 6 */
4207 /* sReSMask (exponent in middle!) */
4208 proto_item
*sresmask_ti
;
4210 sresmask_ti
= proto_tree_add_bitmask_ret_uint64(udcompparam_tree
, tvb
, offset
,
4217 /* Get rid of reserved-shaped gap */
4218 param_sresmask
= ((param_sresmask
>> 4) & 0x0f00) | (param_sresmask
& 0xff);
4220 for (unsigned n
=0; n
< 12; n
++) {
4221 if ((param_sresmask
>> n
) & 0x1) {
4225 proto_item_append_text(sresmask_ti
, " (%u REs)", res
);
4227 /* reserved (4 bits) */
4228 proto_tree_add_item(udcompparam_tree
, hf_oran_reserved_last_4bits
,
4229 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
4230 *sReSMask
= (uint16_t)param_sresmask
;
4232 proto_item_append_text(udcompparam_ti
, " (%u REs)", res
);
4238 /* reserved (set to all zeros), but how many bytes?? */
4242 proto_item_set_len(udcompparam_ti
, offset
-start_offset
);
4247 /* Dissect ciCompHdr (channel information compression header, 7.5.2.15) */
4248 /* bit_width and comp_meth are out params */
4249 static int dissect_cicomphdr(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, unsigned offset
,
4250 unsigned *bit_width
, unsigned *comp_meth
, uint8_t *comp_opt
)
4253 proto_item
*cicomphdr_ti
= proto_tree_add_string_format(tree
, hf_oran_ciCompHdr
,
4256 proto_tree
*cicomphdr_tree
= proto_item_add_subtree(cicomphdr_ti
, ett_oran_cicomphdr
);
4259 uint32_t hdr_iq_width
;
4260 proto_item
*iq_width_item
= proto_tree_add_item_ret_uint(cicomphdr_tree
, hf_oran_ciCompHdrIqWidth
, tvb
, offset
, 1, ENC_NA
, &hdr_iq_width
);
4261 hdr_iq_width
= (hdr_iq_width
) ? hdr_iq_width
: 16;
4263 *bit_width
= hdr_iq_width
;
4265 proto_item_append_text(iq_width_item
, " (%u bits)", hdr_iq_width
);
4268 uint32_t ci_comp_meth
;
4269 proto_tree_add_item_ret_uint(cicomphdr_tree
, hf_oran_ciCompHdrMeth
, tvb
, offset
, 1, ENC_NA
, &ci_comp_meth
);
4271 *comp_meth
= ci_comp_meth
;
4276 proto_tree_add_item_ret_uint(cicomphdr_tree
, hf_oran_ciCompOpt
, tvb
, offset
, 1, ENC_NA
, &opt
);
4281 proto_item_append_text(cicomphdr_ti
, " (IqWidth=%u, ciCompMeth=%s, ciCompOpt=%s)",
4283 rval_to_str_const(ci_comp_meth
, ud_comp_header_meth
, "Unknown"),
4284 (*comp_opt
) ? "compression per PRB" : "compression per UE");
4288 static void dissect_payload_version(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
*pinfo
, unsigned offset
)
4291 proto_item
*ti
= proto_tree_add_item_ret_uint(tree
, hf_oran_payload_version
, tvb
, offset
, 1, ENC_NA
, &version
);
4293 expert_add_info_format(pinfo
, ti
, &ei_oran_version_unsupported
,
4294 "PayloadVersion %u not supported by dissector (only 1 is known)",
4296 /* TODO: should throw an exception? */
4300 static void show_link_to_acknack_request(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
*pinfo
,
4301 ack_nack_request_t
*request
)
4304 proto_item
*ti
= proto_tree_add_uint(tree
, hf_oran_acknack_request_frame
,
4305 tvb
, 0, 0, request
->request_frame_number
);
4306 PROTO_ITEM_SET_GENERATED(ti
);
4308 /* Work out gap between frames (in ms) */
4309 int seconds_between_packets
= (int)
4310 (pinfo
->abs_ts
.secs
- request
->request_frame_time
.secs
);
4311 int nseconds_between_packets
=
4312 pinfo
->abs_ts
.nsecs
- request
->request_frame_time
.nsecs
;
4314 int total_gap
= (seconds_between_packets
*1000) +
4315 ((nseconds_between_packets
+500000) / 1000000);
4317 ti
= proto_tree_add_uint(tree
, hf_oran_acknack_request_time
,
4318 tvb
, 0, 0, total_gap
);
4319 PROTO_ITEM_SET_GENERATED(ti
);
4321 /* Type of request */
4322 ti
= proto_tree_add_uint(tree
, hf_oran_acknack_request_type
,
4323 tvb
, 0, 0, request
->requestType
);
4324 PROTO_ITEM_SET_GENERATED(ti
);
4327 static void show_link_to_acknack_response(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
*pinfo
,
4328 ack_nack_request_t
*response
)
4330 if (response
->response_frame_number
== 0) {
4331 /* Requests may not get a response, and can't always tell when to expect one */
4335 /* Response frame */
4336 proto_item
*ti
= proto_tree_add_uint(tree
, hf_oran_acknack_response_frame
,
4337 tvb
, 0, 0, response
->response_frame_number
);
4338 PROTO_ITEM_SET_GENERATED(ti
);
4340 /* Work out gap between frames (in ms) */
4341 int seconds_between_packets
= (int)
4342 (response
->response_frame_time
.secs
- pinfo
->abs_ts
.secs
);
4343 int nseconds_between_packets
=
4344 response
->response_frame_time
.nsecs
- pinfo
->abs_ts
.nsecs
;
4346 int total_gap
= (seconds_between_packets
*1000) +
4347 ((nseconds_between_packets
+500000) / 1000000);
4349 ti
= proto_tree_add_uint(tree
, hf_oran_acknack_response_time
,
4350 tvb
, 0, 0, total_gap
);
4351 PROTO_ITEM_SET_GENERATED(ti
);
4356 /* Control plane dissector (section 7). */
4357 static int dissect_oran_c(tvbuff_t
*tvb
, packet_info
*pinfo
,
4358 proto_tree
*tree
, oran_tap_info
*tap_info
, void *data _U_
)
4360 /* Hidden filter for plane */
4361 proto_item
*plane_ti
= proto_tree_add_item(tree
, hf_oran_cplane
, tvb
, 0, 0, ENC_NA
);
4362 PROTO_ITEM_SET_HIDDEN(plane_ti
);
4364 /* Set up structures needed to add the protocol subtree and manage it */
4365 unsigned offset
= 0;
4367 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "O-RAN-FH-C");
4368 col_set_str(pinfo
->cinfo
, COL_INFO
, "C-Plane");
4370 tap_info
->userplane
= false;
4372 /* Create display subtree for the protocol */
4373 proto_item
*protocol_item
= proto_tree_add_item(tree
, proto_oran
, tvb
, 0, -1, ENC_NA
);
4374 proto_item_append_text(protocol_item
, "-C");
4375 proto_tree
*oran_tree
= proto_item_add_subtree(protocol_item
, ett_oran
);
4378 addPcOrRtcid(tvb
, oran_tree
, &offset
, hf_oran_ecpri_rtcid
, &eAxC
);
4379 tap_info
->eaxc
= eAxC
;
4381 /* Message identifier */
4383 proto_item
*seq_id_ti
;
4384 offset
= addSeqid(tvb
, oran_tree
, offset
, ORAN_C_PLANE
, &seq_id
, &seq_id_ti
);
4386 /* Section common subtree */
4387 int section_tree_offset
= offset
;
4388 proto_item
*sectionHeading
= proto_tree_add_string_format(oran_tree
, hf_oran_c_section_common
,
4389 tvb
, offset
, 0, "", "C-Plane Section Type ");
4390 proto_tree
*section_tree
= proto_item_add_subtree(sectionHeading
, ett_oran_c_section_common
);
4392 /* Peek ahead at the section type */
4393 uint32_t sectionType
= 0;
4394 sectionType
= tvb_get_uint8(tvb
, offset
+5);
4397 proto_item
*scs_ti
= NULL
;
4400 uint32_t direction
= 0;
4401 proto_tree_add_item_ret_uint(section_tree
, hf_oran_data_direction
, tvb
, offset
, 1, ENC_NA
, &direction
);
4402 tap_info
->uplink
= (direction
==0);
4404 /* Look up any existing conversation state for eAxC+plane */
4405 uint32_t key
= make_flow_key(eAxC
, ORAN_C_PLANE
);
4406 flow_state_t
* state
= (flow_state_t
*)wmem_tree_lookup32(flow_states_table
, key
);
4408 /* Update/report status of conversation */
4409 if (!PINFO_FD_VISITED(pinfo
)) {
4411 if (state
== NULL
) {
4412 /* Allocate new state */
4413 state
= wmem_new0(wmem_file_scope(), flow_state_t
);
4414 state
->ack_nack_requests
= wmem_tree_new(wmem_epan_scope());
4415 wmem_tree_insert32(flow_states_table
, key
, state
);
4418 /* Check sequence analysis status */
4419 if (state
->last_frame_seen
[direction
] && (seq_id
!= state
->next_expected_sequence_number
[direction
])) {
4420 /* Store this result */
4421 flow_result_t
*result
= wmem_new0(wmem_file_scope(), flow_result_t
);
4422 result
->unexpected_seq_number
= true;
4423 result
->expected_sequence_number
= state
->next_expected_sequence_number
[direction
];
4424 result
->previous_frame
= state
->last_frame
[direction
];
4425 wmem_tree_insert32(flow_results_table
, pinfo
->num
, result
);
4427 /* Update conversation info */
4428 state
->last_frame
[direction
] = pinfo
->num
;
4429 state
->last_frame_seen
[direction
] = true;
4430 state
->next_expected_sequence_number
[direction
] = (seq_id
+1) % 256;
4433 /* Show any issues associated with this frame number */
4434 flow_result_t
*result
= wmem_tree_lookup32(flow_results_table
, pinfo
->num
);
4435 if (result
!=NULL
&& result
->unexpected_seq_number
) {
4436 expert_add_info_format(pinfo
, seq_id_ti
, &ei_oran_cplane_unexpected_sequence_number
,
4437 "Sequence number %u expected, but got %u",
4438 result
->expected_sequence_number
, seq_id
);
4439 tap_info
->missing_sns
= (seq_id
- result
->expected_sequence_number
) % 256;
4440 /* TODO: could add previous/next frames (in seqId tree?) ? */
4443 /* payloadVersion */
4444 dissect_payload_version(section_tree
, tvb
, pinfo
, offset
);
4447 if (sectionType
== SEC_C_SLOT_CONTROL
|| sectionType
== SEC_C_ACK_NACK_FEEDBACK
) {
4448 /* scs (for ST4 and ST8) */
4449 scs_ti
= proto_tree_add_item_ret_uint(section_tree
, hf_oran_frameStructure_subcarrier_spacing
, tvb
, offset
, 1, ENC_NA
, &scs
);
4451 else if (sectionType
== SEC_C_RRM_MEAS_REPORTS
|| sectionType
== SEC_C_REQUEST_RRM_MEAS
) {
4452 /* reserved (4 bits) */
4453 proto_tree_add_item(section_tree
, hf_oran_reserved_last_4bits
, tvb
, offset
, 1, ENC_NA
);
4455 else if (sectionType
!= SEC_C_LAA
) {
4456 /* filterIndex (most common case) */
4457 proto_tree_add_item(section_tree
, hf_oran_filter_index
, tvb
, offset
, 1, ENC_NA
);
4461 unsigned ref_a_offset
= offset
;
4463 uint32_t frameId
= 0;
4464 proto_tree_add_item_ret_uint(section_tree
, hf_oran_frame_id
, tvb
, offset
, 1, ENC_NA
, &frameId
);
4468 uint32_t subframeId
= 0;
4469 proto_tree_add_item_ret_uint(section_tree
, hf_oran_subframe_id
, tvb
, offset
, 1, ENC_NA
, &subframeId
);
4471 uint32_t slotId
= 0;
4472 proto_tree_add_item_ret_uint(section_tree
, hf_oran_slot_id
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &slotId
);
4473 tap_info
->slot
= slotId
;
4477 uint32_t startSymbolId
= 0;
4478 proto_item
*ssid_ti
= NULL
;
4479 if ((sectionType
== SEC_C_ACK_NACK_FEEDBACK
) || /* Section Type 8 */
4480 (sectionType
== SEC_C_SINR_REPORTING
)) { /* Section Type 9 */
4482 proto_tree_add_item(section_tree
, hf_oran_symbolId
, tvb
, offset
, 1, ENC_NA
);
4484 else if (sectionType
!= SEC_C_LAA
) {
4485 /* startSymbolId is in most section types */
4486 ssid_ti
= proto_tree_add_item_ret_uint(section_tree
, hf_oran_start_symbol_id
, tvb
, offset
, 1, ENC_NA
, &startSymbolId
);
4487 if (startSymbolId
&& (sectionType
== SEC_C_RRM_MEAS_REPORTS
)) {
4488 proto_item_append_text(ssid_ti
, " (should be 0 for ST10!)");
4489 expert_add_info_format(pinfo
, ssid_ti
, &ei_oran_st10_startsymbolid_not_0
,
4490 "startSymbolId should be 0 for ST10 - found %u", startSymbolId
);
4494 /* reserved (6 bits) */
4495 proto_tree_add_item(section_tree
, hf_oran_reserved_last_6bits
, tvb
, offset
, 1, ENC_NA
);
4500 snprintf(id
, 16, "%d-%d-%d", frameId
, subframeId
, slotId
);
4501 proto_item
*pi
= proto_tree_add_string(section_tree
, hf_oran_refa
, tvb
, ref_a_offset
, 3, id
);
4502 proto_item_set_generated(pi
);
4504 uint32_t cmd_scope
= 0;
4505 bool st8_ready
= false;
4507 /* numberOfSections (or whatever section has instead) */
4508 uint32_t nSections
= 0;
4509 if (sectionType
== SEC_C_SLOT_CONTROL
) { /* Section Type 4 */
4510 /* Slot Control has these fields instead */
4511 /* reserved (4 bits) */
4512 proto_tree_add_item(section_tree
, hf_oran_reserved_4bits
, tvb
, offset
, 1, ENC_NA
);
4513 /* cmdScope (4 bits) */
4514 proto_tree_add_item_ret_uint(section_tree
, hf_oran_cmd_scope
, tvb
, offset
, 1, ENC_NA
, &cmd_scope
);
4516 else if (sectionType
== SEC_C_ACK_NACK_FEEDBACK
) { /* Section Type 8 */
4517 /* reserved (7 bits) */
4518 proto_tree_add_item(section_tree
, hf_oran_reserved_7bits
, tvb
, offset
, 1, ENC_NA
);
4520 /* TODO: when set, ready in slotId+1.. */
4521 proto_tree_add_item_ret_boolean(section_tree
, hf_oran_ready
, tvb
, offset
, 1, ENC_NA
, &st8_ready
);
4523 /* SCS value is ignored, and may be set to any value by O-RU */
4524 proto_item_append_text(scs_ti
, " (ignored)");
4527 else if (sectionType
!= SEC_C_LAA
) {
4528 proto_tree_add_item_ret_uint(section_tree
, hf_oran_numberOfSections
, tvb
, offset
, 1, ENC_NA
, &nSections
);
4531 proto_tree_add_item(section_tree
, hf_oran_reserved_8bits
, tvb
, offset
, 1, ENC_NA
);
4536 proto_tree_add_item_ret_uint(section_tree
, hf_oran_sectionType
, tvb
, offset
, 1, ENC_NA
, §ionType
);
4539 /* Note this section type in stats */
4540 if (sectionType
< SEC_C_MAX_INDEX
) {
4541 tap_info
->section_types
[sectionType
] = true;
4544 /* Section-specific fields (white entries in Section Type diagrams) */
4545 unsigned bit_width
= 0;
4547 proto_item
*comp_meth_ti
;
4548 unsigned ci_comp_method
= 0;
4549 uint8_t ci_comp_opt
= 0;
4551 uint32_t num_ues
= 0;
4552 uint32_t number_of_acks
= 0, number_of_nacks
= 0;
4554 uint32_t num_sinr_per_prb
= 0;
4556 switch (sectionType
) {
4557 case SEC_C_UNUSED_RB
: /* Section Type 0 */
4559 proto_tree_add_item(section_tree
, hf_oran_timeOffset
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
4561 /* frameStructure */
4562 offset
= dissect_frame_structure(section_tree
, tvb
, offset
,
4563 subframeId
, slotId
);
4566 proto_tree_add_item(section_tree
, hf_oran_cpLength
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
4569 proto_tree_add_item(section_tree
, hf_oran_reserved_8bits
, tvb
, offset
, 1, ENC_NA
);
4573 case SEC_C_NORMAL
: /* Section Type 1 */
4574 case SEC_C_UE_SCHED
: /* Section Type 5 */
4576 offset
= dissect_udcomphdr(tvb
, pinfo
, section_tree
, offset
,
4577 (direction
==1), /* ignore for DL */
4578 &bit_width
, &comp_meth
, &comp_meth_ti
);
4580 proto_tree_add_item(section_tree
, hf_oran_reserved_8bits
, tvb
, offset
, 1, ENC_NA
);
4584 case SEC_C_SLOT_CONTROL
: /* Section Type 4 */
4587 case SEC_C_PRACH
: /* Section Type 3 */
4589 proto_tree_add_item(section_tree
, hf_oran_timeOffset
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
4591 /* frameStructure */
4592 offset
= dissect_frame_structure(section_tree
, tvb
, offset
,
4593 subframeId
, slotId
);
4595 proto_tree_add_item(section_tree
, hf_oran_cpLength
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
4598 offset
= dissect_udcomphdr(tvb
, pinfo
, section_tree
, offset
,
4599 (direction
==1), /* ignore for DL */
4600 &bit_width
, &comp_meth
, &comp_meth_ti
);
4603 case SEC_C_CH_INFO
: /* Section Type 6 */
4605 proto_tree_add_item_ret_uint(section_tree
, hf_oran_numberOfUEs
, tvb
, offset
, 1, ENC_NA
, &num_ues
);
4607 /* ciCompHdr (was reserved) */
4608 offset
= dissect_cicomphdr(tvb
, pinfo
, section_tree
, offset
, &bit_width
, &ci_comp_method
, &ci_comp_opt
);
4610 /* Number of sections may not be filled in (at all, or correctly), so set to the number of UEs.
4611 The data entries are per-UE... they don't have a sectionID, but they could have section extensions... */
4612 if (nSections
== 0 || num_ues
> nSections
) {
4613 nSections
= num_ues
;
4620 case SEC_C_LAA
: /* Section Type 7 */
4621 proto_tree_add_item(section_tree
, hf_oran_reserved_16bits
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
4625 case SEC_C_ACK_NACK_FEEDBACK
: /* Section Type 8 */
4626 /* numberOfAcks (1 byte) */
4627 proto_tree_add_item_ret_uint(section_tree
, hf_oran_number_of_acks
, tvb
, offset
, 1, ENC_BIG_ENDIAN
, &number_of_acks
);
4629 /* numberOfNacks (1 byte) */
4630 proto_tree_add_item_ret_uint(section_tree
, hf_oran_number_of_nacks
, tvb
, offset
, 1, ENC_BIG_ENDIAN
, &number_of_nacks
);
4633 /* Show ACKs and NACKs. For both, try to link back to request. */
4634 for (unsigned int n
=1; n
<= number_of_acks
; n
++) {
4637 ack_ti
= proto_tree_add_item_ret_uint(section_tree
, hf_oran_ackid
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &ackid
);
4640 /* Look up request table in state (which really should be set by now, but test anyway). */
4642 ack_nack_request_t
*request
= wmem_tree_lookup32(state
->ack_nack_requests
, ackid
);
4643 if (request
!= NULL
) {
4644 /* On first pass, update with this response */
4645 if (!PINFO_FD_VISITED(pinfo
)) {
4646 request
->response_frame_number
= pinfo
->num
;
4647 request
->response_frame_time
= pinfo
->abs_ts
;
4650 /* Show request details */
4651 show_link_to_acknack_request(section_tree
, tvb
, pinfo
, request
);
4654 /* Request not found */
4655 expert_add_info_format(pinfo
, ack_ti
, &ei_oran_acknack_no_request
,
4656 "Response for ackId=%u received, but no request found",
4661 for (unsigned int m
=1; m
<= number_of_nacks
; m
++) {
4663 proto_item
*nack_ti
= proto_tree_add_item_ret_uint(section_tree
, hf_oran_nackid
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &nackid
);
4666 expert_add_info_format(pinfo
, nack_ti
, &ei_oran_st8_nackid
,
4667 "Received Nack for ackNackId=%u",
4670 /* Look up request table in state. */
4672 ack_nack_request_t
*request
= wmem_tree_lookup32(state
->ack_nack_requests
, nackid
);
4674 /* On first pass, update with this response */
4675 if (!PINFO_FD_VISITED(pinfo
)) {
4676 request
->response_frame_number
= pinfo
->num
;
4677 request
->response_frame_time
= pinfo
->abs_ts
;
4680 /* Show request details */
4681 show_link_to_acknack_request(section_tree
, tvb
, pinfo
, request
);
4684 /* Request not found */
4685 expert_add_info_format(pinfo
, nack_ti
, &ei_oran_acknack_no_request
,
4686 "Response for nackId=%u received, but no request found",
4693 case SEC_C_SINR_REPORTING
: /* Section Type 9 */
4695 /* numSinrPerPrb (3 bits) */
4696 proto_item
*nspp_ti
;
4697 nspp_ti
= proto_tree_add_item_ret_uint(section_tree
, hf_oran_num_sinr_per_prb
, tvb
, offset
, 1, ENC_BIG_ENDIAN
, &num_sinr_per_prb
);
4698 switch (num_sinr_per_prb
) {
4700 num_sinr_per_prb
= 1; break;
4702 num_sinr_per_prb
= 2; break;
4704 num_sinr_per_prb
= 3; break;
4706 num_sinr_per_prb
= 4; break;
4708 num_sinr_per_prb
= 6; break;
4710 num_sinr_per_prb
= 12; break;
4713 proto_item_append_text(nspp_ti
, " (invalid)");
4714 num_sinr_per_prb
= 1;
4715 /* TODO: expert info? */
4718 /* reserved (13 bits) */
4719 proto_tree_add_item(section_tree
, hf_oran_reserved_last_5bits
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
4721 proto_tree_add_item(section_tree
, hf_oran_reserved_8bits
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
4726 case SEC_C_RRM_MEAS_REPORTS
:
4727 case SEC_C_REQUEST_RRM_MEAS
:
4728 /* reserved (16 bits) */
4729 proto_tree_add_item(section_tree
, hf_oran_reserved_16bits
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
4734 /* Update udCompHdr details in state for UL U-Plane */
4735 if (!PINFO_FD_VISITED(pinfo
) && state
&& direction
==0) {
4736 switch (sectionType
) {
4737 case SEC_C_NORMAL
: /* Section Type 1 */
4738 case SEC_C_PRACH
: /* Section Type 3 */
4739 case SEC_C_UE_SCHED
: /* Section Type 5 */
4740 state
->ul_ud_comp_hdr_set
= true;
4741 state
->ul_ud_comp_hdr_bit_width
= bit_width
;
4742 state
->ul_ud_comp_hdr_compression
= comp_meth
;
4750 proto_item_append_text(sectionHeading
, "%d, %s, Frame: %d, Subframe: %d, Slot: %d, StartSymbol: %d",
4751 sectionType
, val_to_str_const(direction
, data_direction_vals
, "Unknown"),
4752 frameId
, subframeId
, slotId
, startSymbolId
);
4753 write_pdu_label_and_info(protocol_item
, NULL
, pinfo
, ", Type: %2d %s", sectionType
,
4754 rval_to_str_const(sectionType
, section_types_short
, "Unknown"));
4756 /* Set actual length of C-Plane section header */
4757 proto_item_set_len(section_tree
, offset
- section_tree_offset
);
4759 if (sectionType
== SEC_C_ACK_NACK_FEEDBACK
) {
4760 write_pdu_label_and_info(oran_tree
, section_tree
, pinfo
,
4761 (st8_ready
) ? " (Ready)" : " (ACK)");
4765 /* Section type 4 doesn't have normal sections, so deal with here before normal sections */
4766 if (sectionType
== SEC_C_SLOT_CONTROL
) {
4767 /* numberOfST4Cmds */
4768 uint32_t no_st4_cmds
, st4_cmd_len
, num_slots
, ack_nack_req_id
, st4_cmd_type
;
4769 proto_item
*no_ti
= proto_tree_add_item_ret_uint(section_tree
, hf_oran_number_of_st4_cmds
,
4770 tvb
, offset
, 1, ENC_NA
, &no_st4_cmds
);
4771 if (no_st4_cmds
== 0) {
4772 expert_add_info_format(pinfo
, no_ti
, &ei_oran_st4_no_cmds
,
4773 "Not valid for ST4 to carry no commands");
4777 /* reserved (1 byte) */
4778 proto_tree_add_item(section_tree
, hf_oran_reserved_8bits
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
4781 /* Loop over commands. Each has 8-byte common header, followed by cmd-specific payload */
4783 for (uint32_t n
=0; n
< no_st4_cmds
; n
++) {
4784 /* Table 7.4.6-2: Section Type 4 Command common header format */
4785 proto_item
*hdr_ti
= proto_tree_add_string_format(section_tree
, hf_oran_st4_cmd_header
,
4787 "Type 4 Command common header");
4788 proto_tree
*hdr_tree
= proto_item_add_subtree(hdr_ti
, ett_oran_st4_cmd_header
);
4791 proto_tree_add_item_ret_uint(hdr_tree
, hf_oran_st4_cmd_type
, tvb
, offset
, 1, ENC_NA
, &st4_cmd_type
);
4795 len_ti
= proto_tree_add_item_ret_uint(hdr_tree
, hf_oran_st4_cmd_len
, tvb
, offset
, 2, ENC_NA
, &st4_cmd_len
);
4796 if (st4_cmd_len
== 0) {
4797 /* Meaning of 0 not yet defined (v15.00) */
4798 proto_item_append_text(len_ti
, " (reserved)");
4799 expert_add_info(pinfo
, len_ti
, &ei_oran_st4_zero_len_cmd
);
4802 proto_item_append_text(len_ti
, " (%u bytes)", st4_cmd_len
*4);
4807 proto_item
*slots_ti
= proto_tree_add_item_ret_uint(hdr_tree
, hf_oran_st4_cmd_num_slots
, tvb
, offset
, 1, ENC_NA
, &num_slots
);
4808 if (num_slots
== 0) {
4809 proto_item_append_text(slots_ti
, " (until changed)");
4814 proto_item
*ack_nack_req_id_ti
;
4815 ack_nack_req_id_ti
= proto_tree_add_item_ret_uint(hdr_tree
, hf_oran_st4_cmd_ack_nack_req_id
, tvb
, offset
, 2, ENC_NA
, &ack_nack_req_id
);
4817 if (ack_nack_req_id
== 0) {
4818 proto_item_append_text(ack_nack_req_id_ti
, " (no Section type 8 response expected)");
4821 /* reserved (16 bits) */
4822 proto_tree_add_item(hdr_tree
, hf_oran_reserved_16bits
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
4825 /* Set common header summary */
4826 proto_item_append_text(hdr_ti
, " (cmd=%s, len=%u, slots=%u, ackNackReqId=%u)",
4827 rval_to_str_const(st4_cmd_type
, st4_cmd_type_vals
, "Unknown"),
4828 st4_cmd_len
, num_slots
, ack_nack_req_id
);
4830 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " (%s)",
4831 rval_to_str_const(st4_cmd_type
, st4_cmd_type_vals
, "Unknown"));
4834 /* Subtree for this command body */
4835 proto_item
*command_ti
= proto_tree_add_string_format(section_tree
, hf_oran_st4_cmd
,
4837 "Type 4 Command (%s)", rval_to_str_const(st4_cmd_type
, st4_cmd_type_vals
, "Unknown"));
4838 proto_tree
*command_tree
= proto_item_add_subtree(command_ti
, ett_oran_st4_cmd
);
4840 unsigned command_start_offset
= offset
;
4842 /* Check fields compatible with chosen command. */
4843 if (st4_cmd_type
==1) {
4844 if (num_slots
!= 0) {
4845 /* "the value of numSlots should be set to zero for this command type" */
4846 expert_add_info_format(pinfo
, ssid_ti
, &ei_oran_numslots_not_zero
,
4847 "numSlots should be zero for ST4 command 1 - found %u",
4852 if (st4_cmd_type
==3 || st4_cmd_type
==4) {
4853 if (startSymbolId
!= 0) {
4854 /* "expected reception window for the commands is the symbol zero reception window" */
4855 expert_add_info_format(pinfo
, ssid_ti
, &ei_oran_start_symbol_id_not_zero
,
4856 "startSymbolId should be zero for ST4 commands 3&4 - found %u",
4861 /* Add format for this command */
4862 switch (st4_cmd_type
) {
4863 case 1: /* TIME_DOMAIN_BEAM_CONFIG */
4865 bool disable_tdbfns
;
4866 uint32_t bfwcomphdr_iq_width
, bfwcomphdr_comp_meth
;
4868 /* reserved (2 bits) */
4869 proto_tree_add_item(command_tree
, hf_oran_reserved_2bits
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
4870 /* symbolMask (14 bits) */
4871 uint32_t symbol_mask
;
4872 proto_item
*symbol_mask_ti
= proto_tree_add_item_ret_uint(command_tree
, hf_oran_symbolMask
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &symbol_mask
);
4873 /* Symbol bits before 'startSymbolId' in Section Type 4 common header should be set to 0 by O-DU and shall be ignored by O-RU */
4874 /* lsb is symbol 0 */
4875 for (unsigned s
=0; s
< 14; s
++) {
4876 if ((startSymbolId
& (1 << s
)) && (startSymbolId
> s
)) {
4877 proto_item_append_text(symbol_mask_ti
, " (startSymbolId is %u, so some lower symbol bits ignored!)", startSymbolId
);
4878 /* TODO: expert info too? */
4885 proto_tree_add_item_ret_boolean(command_tree
, hf_oran_disable_tdbfns
, tvb
, offset
, 1, ENC_BIG_ENDIAN
, &disable_tdbfns
);
4888 proto_tree_add_item(command_tree
, hf_oran_td_beam_num
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
4891 /* bfwCompHdr (2 subheaders - bfwIqWidth and bfwCompMeth)*/
4892 offset
= dissect_bfwCompHdr(tvb
, command_tree
, offset
,
4893 &bfwcomphdr_iq_width
, &bfwcomphdr_comp_meth
, &comp_meth_ti
);
4894 /* reserved (3 bytes) */
4895 proto_tree_add_bits_item(command_tree
, hf_oran_reserved
, tvb
, offset
*8, 24, ENC_BIG_ENDIAN
);
4898 if (disable_tdbfns
) {
4899 /* No beamnum information to show so get out. */
4903 /* Read beam entries until reach end of command length */
4904 while ((offset
- command_start_offset
) < (st4_cmd_len
* 4)) {
4907 bool disable_tdbfws
;
4908 proto_tree_add_item_ret_boolean(command_tree
, hf_oran_disable_tdbfws
, tvb
, offset
, 1, ENC_BIG_ENDIAN
, &disable_tdbfws
);
4911 proto_tree_add_item(command_tree
, hf_oran_td_beam_num
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
4915 if (!disable_tdbfws
) {
4918 unsigned exponent
= 0;
4919 bool supported
= false;
4920 offset
= dissect_bfwCompParam(tvb
, command_tree
, pinfo
, offset
,
4921 comp_meth_ti
, bfwcomphdr_comp_meth
, &exponent
, &supported
);
4923 /* Antenna count from preference */
4924 unsigned num_trx
= pref_num_bf_antennas
;
4925 int bit_offset
= offset
*8;
4927 for (unsigned trx
=0; trx
< num_trx
; trx
++) {
4928 /* Create antenna subtree */
4929 int bfw_offset
= bit_offset
/ 8;
4930 proto_item
*bfw_ti
= proto_tree_add_string_format(command_tree
, hf_oran_bfw
,
4931 tvb
, bfw_offset
, 0, "", "TRX %3u: (", trx
);
4932 proto_tree
*bfw_tree
= proto_item_add_subtree(bfw_ti
, ett_oran_bfw
);
4935 /* Get bits, and convert to float. */
4936 uint32_t bits
= tvb_get_bits(tvb
, bit_offset
, bfwcomphdr_iq_width
, ENC_BIG_ENDIAN
);
4937 float value
= decompress_value(bits
, bfwcomphdr_comp_meth
, bfwcomphdr_iq_width
, exponent
);
4939 proto_tree_add_float_format_value(bfw_tree
, hf_oran_bfw_i
, tvb
, bit_offset
/8,
4940 (bfwcomphdr_iq_width
+7)/8, value
, "%f", value
);
4941 bit_offset
+= bfwcomphdr_iq_width
;
4942 proto_item_append_text(bfw_ti
, "I=%f ", value
);
4944 /* Leave a gap between I and Q values */
4945 proto_item_append_text(bfw_ti
, " ");
4948 /* Get bits, and convert to float. */
4949 bits
= tvb_get_bits(tvb
, bit_offset
, bfwcomphdr_iq_width
, ENC_BIG_ENDIAN
);
4950 value
= decompress_value(bits
, bfwcomphdr_comp_meth
, bfwcomphdr_iq_width
, exponent
);
4952 proto_tree_add_float_format_value(bfw_tree
, hf_oran_bfw_q
, tvb
, bit_offset
/8,
4953 (bfwcomphdr_iq_width
+7)/8, value
, "%f", value
);
4954 bit_offset
+= bfwcomphdr_iq_width
;
4955 proto_item_append_text(bfw_ti
, "Q=%f", value
);
4957 proto_item_append_text(bfw_ti
, ")");
4958 proto_item_set_len(bfw_ti
, (bit_offset
+7)/8 - bfw_offset
);
4960 /* Need to round to next byte */
4961 offset
= (bit_offset
+7)/8;
4966 case 2: /* TDD_CONFIG_PATTERN */
4967 /* reserved (2 bits) */
4968 proto_tree_add_item(command_tree
, hf_oran_reserved_2bits
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
4969 /* dirPattern (14 bits) */
4970 proto_tree_add_item(command_tree
, hf_oran_dir_pattern
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
4973 /* reserved (2 bits) */
4974 proto_tree_add_item(command_tree
, hf_oran_reserved_2bits
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
4975 /* guardPattern (14 bits) */
4976 proto_tree_add_item(command_tree
, hf_oran_guard_pattern
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
4980 case 3: /* TRX_CONTROL */
4982 /* Only allowed cmdScope is ARRAY-COMMAND */
4983 if (cmd_scope
!= 0) {
4984 expert_add_info(pinfo
, command_tree
, &ei_oran_trx_control_cmd_scope
);
4987 /* reserved (1 bit) */
4988 proto_tree_add_item(command_tree
, hf_oran_reserved_1bit
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
4989 /* log2MaskBits (4 bits) */
4990 unsigned log2maskbits
;
4991 proto_tree_add_item_ret_uint(command_tree
, hf_oran_log2maskbits
, tvb
, offset
, 1, ENC_BIG_ENDIAN
, &log2maskbits
);
4993 uint32_t sleep_mode
;
4994 proto_tree_add_item_ret_uint(command_tree
, hf_oran_sleepmode_trx
, tvb
, offset
, 1, ENC_BIG_ENDIAN
, &sleep_mode
);
4997 /* reserved (4 bits) */
4998 proto_tree_add_item(command_tree
, hf_oran_reserved_4bits
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
4999 /* numSlotsExt (20 bits) */
5000 uint32_t num_slots_ext
;
5001 proto_item
*num_slots_ext_ti
= proto_tree_add_item_ret_uint(command_tree
, hf_oran_num_slots_ext
, tvb
, offset
, 3, ENC_BIG_ENDIAN
, &num_slots_ext
);
5002 if (num_slots
==0 && num_slots_ext
==0) {
5003 proto_item_append_text(num_slots_ext_ti
, " (undefined sleep period)");
5006 /* Time should be rounded up according to SCS */
5007 float total
= (float)(num_slots
+ num_slots_ext
);
5008 /* From table 7.5.2.13-3 */
5009 float slot_length_by_scs
[16] = { 1000, 500, 250, 125, 62.5, 31.25,
5010 0, 0, 0, 0, 0, 0, /* reserved */
5011 1000, 1000, 1000, 1000 };
5012 float slot_length
= slot_length_by_scs
[scs
];
5013 /* Only using valid SCS. TODO: is this test ok? */
5014 if (slot_length
!= 0) {
5015 /* Round up to next slot */
5016 total
= ((int)(total
/ slot_length
) + 1) * slot_length
;
5017 proto_item_append_text(num_slots_ext_ti
, " (defined sleep period of %f us)", total
);
5022 /* reserved (2 bits) */
5023 proto_tree_add_item(command_tree
, hf_oran_reserved_2bits
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
5025 /* symbolMask (14 bits) */
5026 uint32_t symbol_mask
;
5028 sm_ti
= proto_tree_add_item_ret_uint(command_tree
, hf_oran_symbolMask
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &symbol_mask
);
5029 if (symbol_mask
== 0x0) {
5030 proto_item_append_text(sm_ti
, " (wake)");
5031 col_append_str(pinfo
->cinfo
, COL_INFO
, " (wake)");
5033 else if (symbol_mask
== 0x3fff) {
5034 proto_item_append_text(sm_ti
, " (sleep)");
5035 col_append_str(pinfo
->cinfo
, COL_INFO
, " (sleep)");
5038 expert_add_info_format(pinfo
, sm_ti
, &ei_oran_bad_symbolmask
,
5039 "For non-zero sleepMode (%u), symbolMask should be 0x0 or 0x3fff - found 0x%05x",
5040 sleep_mode
, symbol_mask
);
5044 /* antMask (16-2048 bits). Size is lookup from log2MaskBits enum.. */
5045 unsigned antmask_length
= 2;
5046 if (log2maskbits
>= 4) {
5047 antmask_length
= (1 << log2maskbits
) / 8;
5049 proto_item
*ant_mask_ti
= proto_tree_add_item(command_tree
, hf_oran_antMask_trx_control
, tvb
, offset
, antmask_length
, ENC_NA
);
5051 unsigned antenna_count
= 0;
5052 for (unsigned b
=0; b
< antmask_length
; b
++) {
5053 uint8_t byte
= tvb_get_uint8(tvb
, offset
+b
);
5054 for (unsigned bit
=0; bit
< 8; bit
++) {
5055 if ((1 << bit
) & byte
) {
5060 proto_item_append_text(ant_mask_ti
, " (%u antennas)", antenna_count
);
5061 offset
+= antmask_length
;
5063 /* Pad to next 4-byte boundary */
5065 offset
+= (4-(offset
%4));
5070 case 4: /* ASM (advanced sleep mode) */
5071 /* reserved (2+4=6 bits) */
5072 proto_tree_add_item(command_tree
, hf_oran_reserved_6bits
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
5073 /* sleepMode (2 bits) */
5074 uint32_t sleep_mode
;
5075 proto_tree_add_item_ret_uint(command_tree
, hf_oran_sleepmode_asm
, tvb
, offset
, 1, ENC_BIG_ENDIAN
, &sleep_mode
);
5078 /* reserved (4 bits) */
5079 proto_tree_add_item(command_tree
, hf_oran_reserved_4bits
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
5080 /* numSlotsExt (20 bits) */
5081 proto_tree_add_item(command_tree
, hf_oran_num_slots_ext
, tvb
, offset
, 3, ENC_BIG_ENDIAN
);
5084 /* reserved (2 bits) */
5085 proto_tree_add_item(command_tree
, hf_oran_reserved_2bits
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
5086 /* symbolMask (14 bits) */
5087 uint32_t symbol_mask
;
5089 sm_ti
= proto_tree_add_item_ret_uint(command_tree
, hf_oran_symbolMask
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &symbol_mask
);
5090 if (symbol_mask
== 0x0) {
5091 proto_item_append_text(sm_ti
, " (wake)");
5092 col_append_str(pinfo
->cinfo
, COL_INFO
, " (wake)");
5094 else if (symbol_mask
== 0x3fff) {
5095 proto_item_append_text(sm_ti
, " (sleep)");
5096 col_append_str(pinfo
->cinfo
, COL_INFO
, " (sleep)");
5099 expert_add_info_format(pinfo
, sm_ti
, &ei_oran_bad_symbolmask
,
5100 "For non-zero sleepMode (%u), symbolMask should be 0x0 or 0x3fff - found 0x%05x",
5101 sleep_mode
, symbol_mask
);
5105 /* reserved (2 bytes) */
5106 proto_tree_add_item(command_tree
, hf_oran_reserved_16bits
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
5112 expert_add_info_format(pinfo
, len_ti
, &ei_oran_st4_unknown_cmd
,
5113 "Dissected ST4 command (%u) not recognised",
5118 /* Check apparent size of padding (0-3 bytes ok) */
5119 long padding_remaining
= command_start_offset
+ (st4_cmd_len
* 4) - offset
;
5120 if (padding_remaining
< 0 || padding_remaining
> 3) {
5121 expert_add_info_format(pinfo
, len_ti
, &ei_oran_st4_wrong_len_cmd
,
5122 "Dissected ST4 command does not match signalled st4CmdLen - set to %u (%u bytes) but dissected %u bytes",
5123 st4_cmd_len
, st4_cmd_len
*4, offset
-command_start_offset
);
5126 /* Advance by signalled length (needs to be aligned on 4-byte boundary) */
5127 offset
= command_start_offset
+ (st4_cmd_len
* 4);
5129 /* Set end of command tree */
5130 proto_item_set_end(command_ti
, tvb
, offset
);
5132 if (ack_nack_req_id
!= 0) {
5133 if (!PINFO_FD_VISITED(pinfo
)) {
5134 /* Add this request into conversation state on first pass */
5135 ack_nack_request_t
*request_details
= wmem_new0(wmem_file_scope(), ack_nack_request_t
);
5136 request_details
->request_frame_number
= pinfo
->num
;
5137 request_details
->request_frame_time
= pinfo
->abs_ts
;
5138 request_details
->requestType
= ST4Cmd1
+st4_cmd_type
-1;
5140 wmem_tree_insert32(state
->ack_nack_requests
,
5145 /* On later passes, try to link forward to ST8 response */
5146 ack_nack_request_t
*response
= wmem_tree_lookup32(state
->ack_nack_requests
,
5149 show_link_to_acknack_response(section_tree
, tvb
, pinfo
, response
);
5155 /* LAA doesn't have sections either.. */
5156 else if (sectionType
== SEC_C_LAA
) { /* Section Type 7 */
5157 /* 7.2.5 Table 6.4-6 */
5159 proto_item
*mcot_ti
;
5162 uint32_t laa_msg_type
;
5163 proto_item
*laa_msg_type_ti
;
5164 laa_msg_type_ti
= proto_tree_add_item_ret_uint(section_tree
, hf_oran_laaMsgType
, tvb
, offset
, 1, ENC_NA
, &laa_msg_type
);
5166 uint32_t laa_msg_len
;
5167 proto_item
*len_ti
= proto_tree_add_item_ret_uint(section_tree
, hf_oran_laaMsgLen
, tvb
, offset
, 1, ENC_NA
, &laa_msg_len
);
5168 proto_item_append_text(len_ti
, " (%u bytes)", 4*laa_msg_len
);
5169 if (laa_msg_len
== 0) {
5170 proto_item_append_text(len_ti
, " (reserved)");
5174 int payload_offset
= offset
;
5177 switch (laa_msg_type
) {
5180 /* lbtHandle (16 bits) */
5181 proto_tree_add_item(section_tree
, hf_oran_lbtHandle
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
5183 /* lbtOffset (10 bits) */
5184 proto_tree_add_item(section_tree
, hf_oran_lbtOffset
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
5186 /* lbtMode (2 bits) */
5187 proto_tree_add_bits_item(section_tree
, hf_oran_lbtMode
, tvb
, offset
*8+2, 2, ENC_BIG_ENDIAN
);
5188 /* reserved (1 bit) */
5189 proto_tree_add_item(section_tree
, hf_oran_reserved_bit4
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
5190 /* lbtDeferFactor (3 bits) */
5191 proto_tree_add_item(section_tree
, hf_oran_lbtDeferFactor
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
5193 /* lbtBackoffCounter (10 bits) */
5194 proto_tree_add_item(section_tree
, hf_oran_lbtBackoffCounter
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
5197 mcot_ti
= proto_tree_add_item_ret_uint(section_tree
, hf_oran_MCOT
, tvb
, offset
, 1, ENC_BIG_ENDIAN
, &mcot
);
5198 if (mcot
<1 || mcot
>10) {
5199 proto_item_append_text(mcot_ti
, " (should be in range 1-10!)");
5200 expert_add_info_format(pinfo
, mcot_ti
, &ei_oran_mcot_out_of_range
,
5201 "MCOT seen with value %u (must be 1-10)", mcot
);
5204 /* reserved (10 bits) */
5205 proto_tree_add_bits_item(section_tree
, hf_oran_reserved
, tvb
, (offset
*8)+6, 10, ENC_BIG_ENDIAN
);
5209 /* lbtHandle (16 bits) */
5210 proto_tree_add_item(section_tree
, hf_oran_lbtHandle
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
5212 /* lbtOffset (10 bits) */
5213 proto_tree_add_item(section_tree
, hf_oran_lbtOffset
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
5215 /* lbtMode (2 bits) */
5216 proto_tree_add_bits_item(section_tree
, hf_oran_lbtMode
, tvb
, offset
*8+2, 2, ENC_BIG_ENDIAN
);
5217 /* reserved (28 bits) */
5218 proto_tree_add_bits_item(section_tree
, hf_oran_reserved
, tvb
, (offset
*8)+4, 28, ENC_BIG_ENDIAN
);
5222 /* lbtHandle (16 bits) */
5223 proto_tree_add_item(section_tree
, hf_oran_lbtHandle
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
5225 /* lbtPdschRes (2 bits) */
5226 proto_tree_add_item(section_tree
, hf_oran_lbtPdschRes
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
5227 /* inParSF (1 bit) */
5228 proto_tree_add_item(section_tree
, hf_oran_initialPartialSF
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
5229 /* sfStatus (1 bit) */
5230 proto_tree_add_item(section_tree
, hf_oran_sfStatus
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
5231 /* sfnSf (12 bits) */
5232 proto_tree_add_item(section_tree
, hf_oran_sfnSfEnd
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
5234 /* reserved (24 bits) */
5235 proto_tree_add_bits_item(section_tree
, hf_oran_reserved
, tvb
, (offset
*8), 24, ENC_BIG_ENDIAN
);
5239 /* lbtHandle (16 bits) */
5240 proto_tree_add_item(section_tree
, hf_oran_lbtHandle
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
5242 /* lbtDrsRes (1 bit) */
5243 proto_tree_add_item(section_tree
, hf_oran_lbtDrsRes
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
5244 /* reserved (7 bits) */
5245 proto_tree_add_item(section_tree
, hf_oran_reserved_last_7bits
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
5248 /* LBT_Buffer_Error */
5249 /* lbtHandle (16 bits) */
5250 proto_tree_add_item(section_tree
, hf_oran_lbtHandle
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
5252 /* lbtBufErr (1 bit) */
5253 proto_tree_add_item(section_tree
, hf_oran_lbtBufErr
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
5254 /* reserved (7 bits) */
5255 proto_tree_add_item(section_tree
, hf_oran_reserved_last_7bits
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
5258 /* LBT_CWCONFIG_REQ */
5259 /* lbtHandle (16 bits) */
5260 proto_tree_add_item(section_tree
, hf_oran_lbtHandle
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
5262 /* lbtCWConfig_H (8 bits) */
5263 proto_tree_add_item(section_tree
, hf_oran_lbtCWConfig_H
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
5265 /* lbtCWConfig_T (8 bits) */
5266 proto_tree_add_item(section_tree
, hf_oran_lbtCWConfig_T
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
5268 /* lbtMode (2 bits) */
5269 proto_tree_add_bits_item(section_tree
, hf_oran_lbtMode
, tvb
, offset
*8, 2, ENC_BIG_ENDIAN
);
5270 /* lbtTrafficClass (3 bits) */
5271 proto_tree_add_item(section_tree
, hf_oran_lbtTrafficClass
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
5272 /* reserved (19 bits) */
5273 proto_tree_add_bits_item(section_tree
, hf_oran_reserved
, tvb
, (offset
*8)+5, 19, ENC_BIG_ENDIAN
);
5276 /* LBT_CWCONFIG_RSP */
5277 /* lbtHandle (16 bits) */
5278 proto_tree_add_item(section_tree
, hf_oran_lbtHandle
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
5280 /* lbtCWR_Rst (1 bit) */
5281 proto_tree_add_item(section_tree
, hf_oran_lbtCWR_Rst
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
5282 /* reserved (7 bits) */
5283 proto_tree_add_item(section_tree
, hf_oran_reserved_last_7bits
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
5288 expert_add_info_format(pinfo
, laa_msg_type_ti
, &ei_oran_laa_msg_type_unsupported
,
5289 "laaMsgType %u not supported by dissector",
5294 /* For now just skip indicated length of bytes */
5295 offset
= payload_offset
+ 4*(laa_msg_len
+1);
5299 /* Dissect each C section */
5300 for (uint32_t i
= 0; i
< nSections
; ++i
) {
5301 tvbuff_t
*section_tvb
= tvb_new_subset_length_caplen(tvb
, offset
, -1, -1);
5302 offset
+= dissect_oran_c_section(section_tvb
, oran_tree
, pinfo
, state
, sectionType
, tap_info
,
5305 bit_width
, ci_comp_method
, ci_comp_opt
,
5309 /* Expert error if we are short of tvb by > 3 bytes */
5310 if (tvb_reported_length_remaining(tvb
, offset
) > 3) {
5311 expert_add_info_format(pinfo
, protocol_item
, &ei_oran_frame_length
,
5312 "%u bytes remain at end of frame - should be 0-3",
5313 tvb_reported_length_remaining(tvb
, offset
));
5316 return tvb_captured_length(tvb
);
5319 static int dissect_oran_u_re(tvbuff_t
*tvb
, proto_tree
*tree
,
5320 unsigned sample_number
, int samples_offset
,
5321 unsigned sample_bit_width
,
5326 unsigned i_bits
= tvb_get_bits(tvb
, samples_offset
, sample_bit_width
, ENC_BIG_ENDIAN
);
5327 float i_value
= decompress_value(i_bits
, comp_meth
, sample_bit_width
, exponent
);
5328 unsigned sample_len_in_bytes
= ((samples_offset
%8)+sample_bit_width
+7)/8;
5329 proto_item
*i_ti
= proto_tree_add_float(tree
, hf_oran_iSample
, tvb
, samples_offset
/8, sample_len_in_bytes
, i_value
);
5330 proto_item_set_text(i_ti
, "iSample: % 0.7f 0x%04x (RE-%2u in the PRB)", i_value
, i_bits
, sample_number
);
5331 samples_offset
+= sample_bit_width
;
5333 unsigned q_bits
= tvb_get_bits(tvb
, samples_offset
, sample_bit_width
, ENC_BIG_ENDIAN
);
5334 float q_value
= decompress_value(q_bits
, comp_meth
, sample_bit_width
, exponent
);
5335 sample_len_in_bytes
= ((samples_offset
%8)+sample_bit_width
+7)/8;
5336 proto_item
*q_ti
= proto_tree_add_float(tree
, hf_oran_qSample
, tvb
, samples_offset
/8, sample_len_in_bytes
, q_value
);
5337 proto_item_set_text(q_ti
, "qSample: % 0.7f 0x%04x (RE-%2u in the PRB)", q_value
, q_bits
, sample_number
);
5338 samples_offset
+= sample_bit_width
;
5340 return samples_offset
;
5344 static bool udcomplen_appears_present(bool udcomphdr_present
, tvbuff_t
*tvb
, int offset
)
5346 if (!udcomplen_heuristic_result_set
) {
5347 /* All sections will start the same way */
5348 unsigned int section_bytes_before_field
= (udcomphdr_present
) ? 6 : 4;
5350 /* Move offset back to the start of the section */
5351 offset
-= section_bytes_before_field
;
5354 /* This field appears several bytes into the U-plane section */
5355 uint32_t length_remaining
= tvb_reported_length_remaining(tvb
, offset
);
5356 /* Are there enough bytes to still read the length field? */
5357 if (section_bytes_before_field
+2 > length_remaining
) {
5358 udcomplen_heuristic_result
= false;
5359 udcomplen_heuristic_result_set
= true;
5363 /* Read the length field */
5364 uint16_t udcomplen
= tvb_get_ntohs(tvb
, offset
+section_bytes_before_field
);
5366 /* Is this less than a valid section? Realistic minimal section will be bigger than this..
5367 * Could take into account numPrbU, etc */
5368 if (udcomplen
< section_bytes_before_field
+2) {
5369 udcomplen_heuristic_result
= false;
5370 udcomplen_heuristic_result_set
= true;
5374 /* Does this section fit into the frame? */
5375 if (udcomplen
> length_remaining
) {
5376 udcomplen_heuristic_result
= false;
5377 udcomplen_heuristic_result_set
= true;
5381 /* Move past this section */
5382 offset
+= udcomplen
;
5384 /* Are we at the end of the frame? */
5385 /* TODO: if frame is less than 60 bytes, there may be > 4 bytes, likely zeros.. */
5386 if (tvb_reported_length_remaining(tvb
, offset
) < 4) {
5387 udcomplen_heuristic_result
= true;
5388 udcomplen_heuristic_result_set
= true;
5390 } while (!udcomplen_heuristic_result_set
);
5392 return udcomplen_heuristic_result
;
5395 static bool at_udcomphdr(tvbuff_t
*tvb
, int offset
)
5397 if (tvb_captured_length_remaining(tvb
, offset
) < 2) {
5400 uint8_t first_byte
= tvb_get_uint8(tvb
, offset
);
5401 uint8_t reserved_byte
= tvb_get_uint8(tvb
, offset
+1);
5403 /* - iq width could be anything, though unlikely to be signalled as (say) < 1-3? */
5404 /* - meth should be 0-8 */
5405 /* - reserved byte should be 0 */
5406 return (((first_byte
& 0x0f) <= MOD_COMPR_AND_SELECTIVE_RE_WITH_MASKS
) && (reserved_byte
== 0));
5409 static bool udcomphdr_appears_present(flow_state_t
*flow
, uint32_t direction
, tvbuff_t
*tvb
, int offset
)
5411 /* Should really not happen, but guard against this anyway. */
5413 /* No state to update. */
5417 if (direction
== DIR_UPLINK
) {
5418 if (flow
->udcomphdrUplink_heuristic_result_set
) {
5419 /* Return cached value */
5420 return flow
->udcomphdrUplink_heuristic_result
;
5423 /* Work it out, and save answer for next time */
5424 flow
->udcomphdrUplink_heuristic_result_set
= true;
5425 flow
->udcomphdrUplink_heuristic_result
= at_udcomphdr(tvb
, offset
);
5426 return flow
->udcomphdrUplink_heuristic_result
;
5431 if (flow
->udcomphdrDownlink_heuristic_result_set
) {
5432 /* Return cached value */
5433 return flow
->udcomphdrDownlink_heuristic_result
;
5436 /* Work it out, and save answer for next time */
5437 flow
->udcomphdrDownlink_heuristic_result_set
= true;
5438 flow
->udcomphdrDownlink_heuristic_result
= at_udcomphdr(tvb
, offset
);
5439 return flow
->udcomphdrDownlink_heuristic_result
;
5444 /* User plane dissector (section 8) */
5446 dissect_oran_u(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
,
5447 oran_tap_info
*tap_info
, void *data _U_
)
5449 /* Hidden filter for plane */
5450 proto_item
*plane_ti
= proto_tree_add_item(tree
, hf_oran_uplane
, tvb
, 0, 0, ENC_NA
);
5451 PROTO_ITEM_SET_HIDDEN(plane_ti
);
5453 /* Set up structures needed to add the protocol subtree and manage it */
5456 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "O-RAN-FH-U");
5457 col_set_str(pinfo
->cinfo
, COL_INFO
, "U-Plane");
5459 tap_info
->userplane
= true;
5461 /* Create display subtree for the protocol */
5462 proto_item
*protocol_item
= proto_tree_add_item(tree
, proto_oran
, tvb
, 0, -1, ENC_NA
);
5463 proto_item_append_text(protocol_item
, "-U");
5464 proto_tree
*oran_tree
= proto_item_add_subtree(protocol_item
, ett_oran
);
5466 /* Transport header */
5467 /* Real-time control data / IQ data transfer message series identifier */
5469 addPcOrRtcid(tvb
, oran_tree
, &offset
, hf_oran_ecpri_pcid
, &eAxC
);
5470 tap_info
->eaxc
= eAxC
;
5472 /* Message identifier */
5474 proto_item
*seq_id_ti
;
5475 offset
= addSeqid(tvb
, oran_tree
, offset
, ORAN_U_PLANE
, &seq_id
, &seq_id_ti
);
5477 /* Common header for time reference */
5478 proto_item
*timingHeader
= proto_tree_add_string_format(oran_tree
, hf_oran_timing_header
,
5479 tvb
, offset
, 4, "", "Timing Header (");
5480 proto_tree
*timing_header_tree
= proto_item_add_subtree(timingHeader
, ett_oran_u_timing
);
5484 proto_tree_add_item_ret_uint(timing_header_tree
, hf_oran_data_direction
, tvb
, offset
, 1, ENC_NA
, &direction
);
5485 tap_info
->uplink
= (direction
==0);
5486 /* payloadVersion */
5487 dissect_payload_version(timing_header_tree
, tvb
, pinfo
, offset
);
5489 proto_tree_add_item(timing_header_tree
, hf_oran_filter_index
, tvb
, offset
, 1, ENC_NA
);
5492 int ref_a_offset
= offset
;
5495 uint32_t frameId
= 0;
5496 proto_tree_add_item_ret_uint(timing_header_tree
, hf_oran_frame_id
, tvb
, offset
, 1, ENC_NA
, &frameId
);
5500 uint32_t subframeId
= 0;
5501 proto_tree_add_item_ret_uint(timing_header_tree
, hf_oran_subframe_id
, tvb
, offset
, 1, ENC_NA
, &subframeId
);
5503 uint32_t slotId
= 0;
5504 proto_tree_add_item_ret_uint(timing_header_tree
, hf_oran_slot_id
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &slotId
);
5505 tap_info
->slot
= slotId
;
5508 uint32_t symbolId
= 0;
5509 proto_tree_add_item_ret_uint(timing_header_tree
, hf_oran_symbolId
, tvb
, offset
, 1, ENC_NA
, &symbolId
);
5513 snprintf(id
, 16, "%d-%d-%d", frameId
, subframeId
, slotId
);
5514 proto_item
*pi
= proto_tree_add_string(timing_header_tree
, hf_oran_refa
, tvb
, ref_a_offset
, 3, id
);
5515 proto_item_set_generated(pi
);
5517 proto_item_append_text(timingHeader
, "%s, Frame: %d, Subframe: %d, Slot: %d, Symbol: %d)",
5518 val_to_str_const(direction
, data_direction_vals
, "Unknown"), frameId
, subframeId
, slotId
, symbolId
);
5520 unsigned sample_bit_width
;
5522 int includeUdCompHeader
;
5524 /* Update/report status of conversation */
5525 uint32_t key
= make_flow_key(eAxC
, ORAN_U_PLANE
);
5526 flow_state_t
* state
= (flow_state_t
*)wmem_tree_lookup32(flow_states_table
, key
);
5528 if (!PINFO_FD_VISITED(pinfo
)) {
5529 /* Create conversation if doesn't exist yet */
5531 /* Allocate new state */
5532 state
= wmem_new0(wmem_file_scope(), flow_state_t
);
5533 state
->ack_nack_requests
= wmem_tree_new(wmem_epan_scope());
5534 wmem_tree_insert32(flow_states_table
, key
, state
);
5537 /* Check sequence analysis status */
5538 if (state
->last_frame_seen
[direction
] && (seq_id
!= state
->next_expected_sequence_number
[direction
])) {
5539 /* Store this result */
5540 flow_result_t
*result
= wmem_new0(wmem_file_scope(), flow_result_t
);
5541 result
->unexpected_seq_number
= true;
5542 result
->expected_sequence_number
= state
->next_expected_sequence_number
[direction
];
5543 result
->previous_frame
= state
->last_frame
[direction
];
5544 wmem_tree_insert32(flow_results_table
, pinfo
->num
, result
);
5546 /* Update sequence analysis state */
5547 state
->last_frame
[direction
] = pinfo
->num
;
5548 state
->last_frame_seen
[direction
] = true;
5549 state
->next_expected_sequence_number
[direction
] = (seq_id
+1) % 256;
5552 /* Show any issues associated with this frame number */
5553 flow_result_t
*result
= wmem_tree_lookup32(flow_results_table
, pinfo
->num
);
5555 if (result
->unexpected_seq_number
) {
5556 expert_add_info_format(pinfo
, seq_id_ti
, &ei_oran_uplane_unexpected_sequence_number
,
5557 "Sequence number %u expected, but got %u",
5558 result
->expected_sequence_number
, seq_id
);
5559 tap_info
->missing_sns
= (seq_id
- result
->expected_sequence_number
) % 256;
5560 /* TODO: could add previous/next frame (in seqId tree?) ? */
5564 /* Look up preferences for samples */
5565 if (direction
== DIR_UPLINK
) {
5566 sample_bit_width
= pref_sample_bit_width_uplink
;
5567 compression
= pref_iqCompressionUplink
;
5568 includeUdCompHeader
= pref_includeUdCompHeaderUplink
;
5570 sample_bit_width
= pref_sample_bit_width_downlink
;
5571 compression
= pref_iqCompressionDownlink
;
5572 includeUdCompHeader
= pref_includeUdCompHeaderDownlink
;
5575 /* If uplink, load any udCompHdr settings written by C-Plane */
5576 bool ud_cmp_hdr_cplane
= false;
5577 if (state
&& direction
== 0) {
5578 /* Initialise settings from udpCompHdr from C-Plane */
5579 if (state
->ul_ud_comp_hdr_set
) {
5580 sample_bit_width
= state
->ul_ud_comp_hdr_bit_width
;
5581 compression
= state
->ul_ud_comp_hdr_compression
;
5583 ud_cmp_hdr_cplane
= true;
5587 /* Need a valid value (e.g. 9, 14). 0 definitely won't work, as won't progress around loop! */
5588 /* N.B. may yet be overwritten by udCompHdr settings in sections below! */
5589 if (sample_bit_width
== 0) {
5590 expert_add_info_format(pinfo
, protocol_item
, &ei_oran_invalid_sample_bit_width
,
5591 "%cL Sample bit width from %s (%u) not valid, so can't decode sections",
5592 (direction
== DIR_UPLINK
) ? 'U' : 'D',
5593 !ud_cmp_hdr_cplane
? "preference" : "C-Plane",
5599 unsigned number_of_sections
= 0;
5600 unsigned nBytesPerPrb
=0;
5602 /* Add each section (no count, just keep parsing until payload used) */
5604 /* Section subtree */
5605 unsigned section_start_offset
= offset
;
5606 proto_item
*sectionHeading
= proto_tree_add_string_format(oran_tree
, hf_oran_u_section
,
5607 tvb
, offset
, 0, "", "Section");
5608 proto_tree
*section_tree
= proto_item_add_subtree(sectionHeading
, ett_oran_u_section
);
5610 /* Section Header fields (darker green part) */
5613 uint32_t sectionId
= 0;
5614 proto_item
*ti
= proto_tree_add_item_ret_uint(section_tree
, hf_oran_section_id
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, §ionId
);
5615 if (sectionId
== 4095) {
5616 proto_item_append_text(ti
, " (not default coupling C/U planes using sectionId)");
5621 proto_tree_add_item_ret_uint(section_tree
, hf_oran_rb
, tvb
, offset
, 1, ENC_NA
, &rb
);
5623 proto_tree_add_item(section_tree
, hf_oran_symInc
, tvb
, offset
, 1, ENC_NA
);
5625 uint32_t startPrbu
= 0;
5626 proto_tree_add_item_ret_uint(section_tree
, hf_oran_startPrbu
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &startPrbu
);
5630 uint32_t numPrbu
= 0;
5631 proto_tree_add_item_ret_uint(section_tree
, hf_oran_numPrbu
, tvb
, offset
, 1, ENC_NA
, &numPrbu
);
5634 proto_item
*ud_comp_meth_item
, *ud_comp_len_ti
=NULL
;
5635 uint32_t ud_comp_len
;
5637 /* udCompHdr (if preferences indicate will be present) */
5638 bool included
= (includeUdCompHeader
==1) ||
5639 (includeUdCompHeader
==2 && udcomphdr_appears_present(state
, direction
, tvb
, offset
));
5642 /* Extract these values to inform how wide IQ samples in each PRB will be. */
5643 offset
= dissect_udcomphdr(tvb
, pinfo
, section_tree
, offset
, false, &sample_bit_width
,
5644 &compression
, &ud_comp_meth_item
);
5646 /* Not part of udCompHdr */
5647 proto_tree_add_item(section_tree
, hf_oran_reserved_8bits
, tvb
, offset
, 1, ENC_NA
);
5651 /* No fields to dissect - just showing comp values from prefs */
5653 proto_item
*iq_width_item
= proto_tree_add_uint(section_tree
, hf_oran_udCompHdrIqWidth_pref
, tvb
, 0, 0, sample_bit_width
);
5654 proto_item_append_text(iq_width_item
, (ud_cmp_hdr_cplane
) ? " (from c-plane)" : " (from preferences)");
5655 proto_item_set_generated(iq_width_item
);
5658 ud_comp_meth_item
= proto_tree_add_uint(section_tree
, hf_oran_udCompHdrMeth_pref
, tvb
, 0, 0, compression
);
5659 proto_item_append_text(ud_comp_meth_item
, (ud_cmp_hdr_cplane
) ? " (from c-plane)" : " (from preferences)");
5660 proto_item_set_generated(ud_comp_meth_item
);
5663 /* Not supported! TODO: other places where comp method is looked up (e.g., bfw?) */
5664 switch (compression
) {
5667 case BFP_AND_SELECTIVE_RE
:
5670 expert_add_info_format(pinfo
, ud_comp_meth_item
, &ei_oran_unsupported_compression_method
,
5671 "Compression method %u (%s) not supported by dissector",
5673 rval_to_str_const(compression
, ud_comp_header_meth
, "reserved"));
5676 /* udCompLen (when supported, methods 5,6,7,8) */
5677 if (compression
>= BFP_AND_SELECTIVE_RE
) {
5678 bool supported
= (pref_support_udcompLen
==1) || /* supported */
5679 (pref_support_udcompLen
==2 && udcomplen_appears_present(includeUdCompHeader
, tvb
, offset
));
5682 ud_comp_len_ti
= proto_tree_add_item_ret_uint(section_tree
, hf_oran_udCompLen
, tvb
, offset
, 2, ENC_NA
, &ud_comp_len
);
5683 if (ud_comp_len
<= 1) {
5684 proto_item_append_text(ud_comp_len_ti
, " (reserved)");
5686 /* TODO: report if less than a viable section in frame? */
5687 /* Check that there is this much length left in the frame */
5688 if ((int)ud_comp_len
> tvb_reported_length_remaining(tvb
, section_start_offset
)) {
5689 expert_add_info_format(pinfo
, ud_comp_len_ti
, &ei_oran_ud_comp_len_wrong_size
,
5690 "udCompLen indicates %u bytes in section, but only %u are left in frame",
5691 ud_comp_len
, tvb_reported_length_remaining(tvb
, section_start_offset
));
5693 /* Actual length of section will be checked below, at the end of the section */
5698 /* sReSMask1 + sReSMask2 (depends upon compression method) */
5699 uint64_t sresmask1
=0, sresmask2
=0;
5700 if (compression
== BFP_AND_SELECTIVE_RE_WITH_MASKS
||
5701 compression
== MOD_COMPR_AND_SELECTIVE_RE_WITH_MASKS
)
5703 static int * const sres_mask1_2_flags
[] = {
5704 &hf_oran_sReSMask1_2_re12
,
5705 &hf_oran_sReSMask1_2_re11
,
5706 &hf_oran_sReSMask1_2_re10
,
5707 &hf_oran_sReSMask1_2_re9
,
5708 &hf_oran_sReSMask_re8
,
5709 &hf_oran_sReSMask_re7
,
5710 &hf_oran_sReSMask_re6
,
5711 &hf_oran_sReSMask_re5
,
5712 &hf_oran_sReSMask_re4
,
5713 &hf_oran_sReSMask_re3
,
5714 &hf_oran_sReSMask_re2
,
5715 &hf_oran_sReSMask_re1
,
5719 /* reserved (4 bits) */
5720 proto_tree_add_item(section_tree
, hf_oran_reserved_4bits
, tvb
, offset
, 1, ENC_NA
);
5721 /* sReSMask1 (12 bits) */
5722 proto_item
*sresmask_ti
;
5723 sresmask_ti
= proto_tree_add_bitmask_ret_uint64(section_tree
, tvb
, offset
,
5730 /* Count REs present */
5732 for (unsigned n
=0; n
< 12; n
++) {
5733 if ((sresmask1
>> n
) & 0x1) {
5737 proto_item_append_text(sresmask_ti
, " (%u REs)", res
);
5740 /* reserved (4 bits) */
5741 proto_tree_add_item(section_tree
, hf_oran_reserved_4bits
, tvb
, offset
, 1, ENC_NA
);
5742 /* sReSMask2 (12 bits) */
5743 sresmask_ti
= proto_tree_add_bitmask_ret_uint64(section_tree
, tvb
, offset
,
5752 proto_item_append_text(sresmask_ti
, " (ignored)");
5753 if (sresmask2
!= 0) {
5754 expert_add_info(pinfo
, ud_comp_len_ti
, &ei_oran_sresmask2_not_zero_with_rb
);
5758 /* Count REs present */
5760 for (unsigned n
=0; n
< 12; n
++) {
5761 if ((sresmask2
>> n
) & 0x1) {
5765 proto_item_append_text(sresmask_ti
, " (%u REs)", res
);
5769 write_section_info(sectionHeading
, pinfo
, protocol_item
, sectionId
, startPrbu
, numPrbu
, rb
);
5771 /* TODO: should this use the same pref as c-plane? */
5773 /* Special case for all PRBs (NR: the total number of PRBs may be > 255) */
5774 numPrbu
= pref_data_plane_section_total_rbs
;
5775 startPrbu
= 0; /* may already be 0... */
5779 for (unsigned i
= 0; i
< numPrbu
; i
++) {
5780 /* Create subtree */
5781 proto_item
*prbHeading
= proto_tree_add_string_format(section_tree
, hf_oran_samples_prb
,
5784 proto_tree
*rb_tree
= proto_item_add_subtree(prbHeading
, ett_oran_u_prb
);
5785 uint32_t exponent
= 0;
5786 uint16_t sresmask
= 0;
5788 /* udCompParam (depends upon compression method) */
5789 int before
= offset
;
5790 offset
= dissect_udcompparam(tvb
, pinfo
, rb_tree
, offset
, compression
, &exponent
, &sresmask
, false);
5791 int udcompparam_len
= offset
-before
;
5793 /* Show PRB number in root */
5794 proto_item_append_text(prbHeading
, " %3u", startPrbu
+ i
*(1+rb
));
5796 /* Work out how many REs / PRB */
5797 unsigned res_per_prb
= 12;
5798 uint16_t sresmask_to_use
= 0x0fff;
5800 if (compression
>= BFP_AND_SELECTIVE_RE
) {
5801 /* Work out which mask should be used */
5802 if (compression
==BFP_AND_SELECTIVE_RE
|| compression
==MOD_COMPR_AND_SELECTIVE_RE
) {
5803 /* Selective RE cases, use value from compModParam */
5804 sresmask_to_use
= (uint16_t)sresmask
;
5807 /* With masks (in section). Choose between sresmask1 and sresmask2 */
5808 if (rb
==1 || (i
%1)==0) {
5810 sresmask_to_use
= (uint16_t)sresmask1
;
5814 sresmask_to_use
= (uint16_t)sresmask2
;
5818 /* Count REs present using sresmask */
5820 /* Use sresmask to pick out which REs are present */
5821 for (unsigned n
=0; n
<12; n
++) {
5822 if (sresmask_to_use
& (1<<n
)) {
5828 /* N.B. bytes for samples need to be padded out to next byte
5829 (certainly where there aren't 12 REs in PRB..) */
5830 unsigned nBytesForSamples
= (sample_bit_width
* res_per_prb
* 2 + 7) / 8;
5831 nBytesPerPrb
= nBytesForSamples
+ udcompparam_len
;
5833 proto_tree_add_item(rb_tree
, hf_oran_iq_user_data
, tvb
, offset
, nBytesForSamples
, ENC_NA
);
5835 /* Optionally trying to show I/Q RE values */
5836 if (pref_showIQSampleValues
) {
5837 /* Individual values */
5838 unsigned samples_offset
= offset
*8;
5839 unsigned samples
= 0;
5841 if (compression
>= BFP_AND_SELECTIVE_RE
) {
5842 /* Use sresmask to pick out which REs are present */
5843 for (unsigned n
=1; n
<=12; n
++) {
5844 if (sresmask_to_use
& (1<<(n
-1))) {
5845 samples_offset
= dissect_oran_u_re(tvb
, rb_tree
,
5846 n
, samples_offset
, sample_bit_width
, compression
, exponent
);
5852 /* All 12 REs are present */
5853 for (unsigned n
=1; n
<=12; n
++) {
5854 samples_offset
= dissect_oran_u_re(tvb
, rb_tree
,
5855 n
, samples_offset
, sample_bit_width
, compression
, exponent
);
5859 proto_item_append_text(prbHeading
, " (%u REs)", samples
);
5862 /* Advance past samples */
5863 offset
+= nBytesForSamples
;
5865 /* Set end of prb subtree */
5866 proto_item_set_end(prbHeading
, tvb
, offset
);
5869 /* Set extent of section */
5870 proto_item_set_len(sectionHeading
, offset
-section_start_offset
);
5871 if (ud_comp_len_ti
!= NULL
&& ((offset
-section_start_offset
!= ud_comp_len
))) {
5872 expert_add_info_format(pinfo
, ud_comp_len_ti
, &ei_oran_ud_comp_len_wrong_size
,
5873 "udCompLen indicates %u bytes in section, but dissected %u instead",
5874 ud_comp_len
, offset
-section_start_offset
);
5877 bytesLeft
= tvb_captured_length(tvb
) - offset
;
5878 number_of_sections
++;
5879 } while (bytesLeft
>= (4 + nBytesPerPrb
)); /* FIXME: bad heuristic */
5881 /* Show number of sections found */
5882 proto_item
*ti
= proto_tree_add_uint(oran_tree
, hf_oran_numberOfSections
, tvb
, 0, 0, number_of_sections
);
5883 proto_item_set_generated(ti
);
5885 /* Expert error if we are short of tvb by > 3 bytes */
5886 if (tvb_reported_length_remaining(tvb
, offset
) > 3) {
5887 expert_add_info_format(pinfo
, protocol_item
, &ei_oran_frame_length
,
5888 "%u bytes remain at end of frame - should be 0-3",
5889 tvb_reported_length_remaining(tvb
, offset
));
5892 return tvb_captured_length(tvb
);
5896 /**********************************************************************/
5897 /* Main dissection function. */
5898 /* N.B. ecpri message type passed in as 'data' arg by eCPRI dissector */
5900 dissect_oran(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data
)
5902 uint32_t ecpri_message_type
= *(uint32_t *)data
;
5905 /* Allocate and zero tap struct */
5906 oran_tap_info
*tap_info
= wmem_new0(wmem_file_scope(), oran_tap_info
);
5908 switch (ecpri_message_type
) {
5909 case ECPRI_MT_IQ_DATA
:
5910 offset
= dissect_oran_u(tvb
, pinfo
, tree
, tap_info
, data
);
5912 case ECPRI_MT_RT_CTRL_DATA
:
5913 offset
= dissect_oran_c(tvb
, pinfo
, tree
, tap_info
, data
);
5916 /* Not dissecting other types - assume these are handled by eCPRI dissector */
5920 tap_queue_packet(oran_tap
, pinfo
, tap_info
);
5925 static void oran_init_protocol(void)
5927 udcomplen_heuristic_result_set
= false;
5928 udcomplen_heuristic_result
= false;
5932 /* Register the protocol with Wireshark. */
5934 proto_register_oran(void)
5936 static hf_register_info hf
[] = {
5938 /* Section 5.1.3.2.7 */
5939 { &hf_oran_du_port_id
,
5940 { "DU Port ID", "oran_fh_cus.du_port_id",
5941 FT_UINT16
, BASE_DEC
,
5943 "Width set in dissector preference", HFILL
}
5946 /* Section 5.1.3.2.7 */
5947 { &hf_oran_bandsector_id
,
5948 { "BandSector ID", "oran_fh_cus.bandsector_id",
5949 FT_UINT16
, BASE_DEC
,
5951 "Width set in dissector preference", HFILL
}
5954 /* Section 5.1.3.2.7 */
5956 { "CC ID", "oran_fh_cus.cc_id",
5957 FT_UINT16
, BASE_DEC
,
5959 "Width set in dissector preference", HFILL
}
5962 /* Section 5.1.3.2.7 */
5963 { &hf_oran_ru_port_id
,
5964 { "RU Port ID", "oran_fh_cus.ru_port_id",
5965 FT_UINT16
, BASE_DEC
,
5967 "Width set in dissector preference", HFILL
}
5970 /* Section 5.1.3.2.8 */
5971 { &hf_oran_sequence_id
,
5972 { "Sequence ID", "oran_fh_cus.sequence_id",
5975 "The Sequence ID wraps around individually per eAxC", HFILL
}
5978 /* Section 5.1.3.2.8 */
5980 { "E Bit", "oran_fh_cus.e_bit",
5983 "Indicate the last message of a subsequence (U-Plane only)", HFILL
}
5986 /* Section 5.1.3.2.8 */
5987 { &hf_oran_subsequence_id
,
5988 { "Subsequence ID", "oran_fh_cus.subsequence_id",
5991 "The subsequence ID (for eCPRI layer fragmentation)", HFILL
}
5994 /* Section 7.5.2.1 */
5995 { &hf_oran_data_direction
,
5996 { "Data Direction", "oran_fh_cus.data_direction",
5998 VALS(data_direction_vals
), 0x80,
5999 "gNB data direction", HFILL
}
6002 /* Section 7.5.2.2 */
6003 { &hf_oran_payload_version
,
6004 { "Payload Version", "oran_fh_cus.payloadVersion",
6007 "Payload protocol version the following IEs", HFILL
}
6010 /* Section 7.5.2.3 */
6011 { &hf_oran_filter_index
,
6012 { "Filter Index", "oran_fh_cus.filterIndex",
6013 FT_UINT8
, BASE_DEC
| BASE_RANGE_STRING
,
6014 RVALS(filter_indices
), 0x0f,
6015 "used between IQ data and air interface, both in DL and UL", HFILL
}
6018 /* Section 7.5.2.4 */
6019 { &hf_oran_frame_id
,
6020 { "Frame ID", "oran_fh_cus.frameId",
6023 "A counter for 10 ms frames (wrapping period 2.56 seconds)", HFILL
}
6026 /* Section 7.5.2.5 */
6027 { &hf_oran_subframe_id
,
6028 { "Subframe ID", "oran_fh_cus.subframe_id",
6031 "A counter for 1 ms sub-frames within 10ms frame", HFILL
}
6034 /* Section 7.5.2.6 */
6036 { "Slot ID", "oran_fh_cus.slotId",
6037 FT_UINT16
, BASE_DEC
,
6039 "Slot number within a 1ms sub-frame", HFILL
}
6042 /* Generated for convenience */
6043 { &hf_oran_slot_within_frame
,
6044 { "Slot within frame", "oran_fh_cus.slot-within-frame",
6045 FT_UINT16
, BASE_DEC
,
6047 "Slot within frame, to match DCT logs", HFILL
}
6050 /* Section 7.5.2.7 */
6051 { &hf_oran_start_symbol_id
,
6052 { "Start Symbol ID", "oran_fh_cus.startSymbolId",
6055 "The first symbol number within slot affected", HFILL
}
6058 /* Section 7.5.2.8 */
6059 { &hf_oran_numberOfSections
,
6060 { "Number of Sections", "oran_fh_cus.numberOfSections",
6063 "The number of section IDs included in this C-Plane message", HFILL
}
6066 /* Section 7.5.2.9 */
6067 { &hf_oran_sectionType
,
6068 { "Section Type", "oran_fh_cus.sectionType",
6069 FT_UINT8
, BASE_DEC
| BASE_RANGE_STRING
,
6070 RVALS(section_types
), 0x0,
6071 "Determines the characteristics of U-plane data", HFILL
}
6074 /* Section 7.5.2.10 */
6075 { &hf_oran_udCompHdr
,
6076 { "udCompHdr", "oran_fh_cus.udCompHdr",
6077 FT_STRING
, BASE_NONE
,
6082 /* Section 7.5.2.11 */
6083 { &hf_oran_numberOfUEs
,
6084 { "Number Of UEs", "oran_fh_cus.numberOfUEs",
6087 "Indicates number of UEs for which channel info is provided", HFILL
}
6090 /* Section 7.5.2.12 */
6091 { &hf_oran_timeOffset
,
6092 { "Time Offset", "oran_fh_cus.timeOffset",
6093 FT_UINT16
, BASE_DEC
,
6095 "from start of the slot to start of CP in samples", HFILL
}
6098 /* Section 7.5.2.13 */
6099 { &hf_oran_frameStructure_fft
,
6100 { "FFT Size", "oran_fh_cus.frameStructure.fft",
6101 FT_UINT8
, BASE_HEX
| BASE_RANGE_STRING
,
6102 RVALS(frame_structure_fft
), 0xf0,
6103 "The FFT/iFFT size being used for all IQ data processing related to this message", HFILL
}
6106 /* Section 7.5.2.13 */
6107 { &hf_oran_frameStructure_subcarrier_spacing
,
6108 { "Subcarrier Spacing", "oran_fh_cus.frameStructure.spacing",
6109 FT_UINT8
, BASE_HEX
| BASE_RANGE_STRING
,
6110 RVALS(subcarrier_spacings
), 0x0f,
6111 "The sub carrier spacing as well as the number of slots per 1ms sub-frame",
6115 /* Section 7.5.2.14 */
6116 { &hf_oran_cpLength
,
6117 { "cpLength", "oran_fh_cus.cpLength",
6118 FT_UINT16
, BASE_DEC
,
6120 "cyclic prefix length", HFILL
}
6123 { &hf_oran_timing_header
,
6124 { "Timing Header", "oran_fh_cus.timingHeader",
6125 FT_STRING
, BASE_NONE
,
6130 /* Section 7.5.3.1 */
6131 { &hf_oran_section_id
,
6132 { "sectionId", "oran_fh_cus.sectionId",
6133 FT_UINT16
, BASE_DEC
,
6135 "section identifier of data", HFILL
}
6138 /* Section 7.5.3.2 */
6140 { "rb", "oran_fh_cus.rb",
6142 VALS(rb_vals
), 0x08,
6143 "resource block indicator", HFILL
}
6146 /* Section 7.5.5.3 */
6148 { "symInc", "oran_fh_cus.symInc",
6150 VALS(sym_inc_vals
), 0x04,
6151 "Symbol Number Increment Command", HFILL
}
6154 /* Section 7.5.3.4 */
6155 { &hf_oran_startPrbc
,
6156 { "startPrbc", "oran_fh_cus.startPrbc",
6157 FT_UINT16
, BASE_DEC
,
6159 "Starting PRB of Control Plane Section", HFILL
}
6162 /* Section 7.5.3.5 */
6163 { &hf_oran_reMask_re1
,
6164 { "RE 1", "oran_fh_cus.reMask-RE1",
6166 TFS(&tfs_applicable_not_applicable
), 0x8000,
6169 { &hf_oran_reMask_re2
,
6170 { "RE 2", "oran_fh_cus.reMask-RE2",
6172 TFS(&tfs_applicable_not_applicable
), 0x4000,
6175 { &hf_oran_reMask_re3
,
6176 { "RE 3", "oran_fh_cus.reMask-RE3",
6178 TFS(&tfs_applicable_not_applicable
), 0x2000,
6181 { &hf_oran_reMask_re4
,
6182 { "RE 4", "oran_fh_cus.reMask-RE4",
6184 TFS(&tfs_applicable_not_applicable
), 0x1000,
6187 { &hf_oran_reMask_re5
,
6188 { "RE 5", "oran_fh_cus.reMask-RE5",
6190 TFS(&tfs_applicable_not_applicable
), 0x0800,
6193 { &hf_oran_reMask_re6
,
6194 { "RE 6", "oran_fh_cus.reMask-RE6",
6196 TFS(&tfs_applicable_not_applicable
), 0x0400,
6199 { &hf_oran_reMask_re7
,
6200 { "RE 7", "oran_fh_cus.reMask-RE7",
6202 TFS(&tfs_applicable_not_applicable
), 0x0200,
6205 { &hf_oran_reMask_re8
,
6206 { "RE 8", "oran_fh_cus.reMask-RE8",
6208 TFS(&tfs_applicable_not_applicable
), 0x0100,
6211 { &hf_oran_reMask_re9
,
6212 { "RE 9", "oran_fh_cus.reMask-RE9",
6214 TFS(&tfs_applicable_not_applicable
), 0x0080,
6217 { &hf_oran_reMask_re10
,
6218 { "RE 10", "oran_fh_cus.reMask-RE10",
6220 TFS(&tfs_applicable_not_applicable
), 0x0040,
6223 { &hf_oran_reMask_re11
,
6224 { "RE 11", "oran_fh_cus.reMask-RE11",
6226 TFS(&tfs_applicable_not_applicable
), 0x0020,
6229 { &hf_oran_reMask_re12
,
6230 { "RE 12", "oran_fh_cus.reMask-RE12",
6232 TFS(&tfs_applicable_not_applicable
), 0x0010,
6236 { "RE Mask", "oran_fh_cus.reMask",
6237 FT_UINT16
, BASE_HEX
,
6239 "The Resource Element (RE) mask within a PRB", HFILL
}
6242 /* Section 7.5.3.6 */
6244 { "numPrbc", "oran_fh_cus.numPrbc",
6247 "Number of contiguous PRBs per data section description", HFILL
}
6250 /* Section 7.5.3.7 */
6251 { &hf_oran_numSymbol
,
6252 { "Number of Symbols", "oran_fh_cus.numSymbol",
6255 "Defines number of symbols to which the section control is applicable", HFILL
}
6258 /* Section 7.5.3.8 */
6260 { "Extension Flag", "oran_fh_cus.ef",
6263 "Indicates if more section extensions follow", HFILL
}
6266 /* Section 7.5.3.9 */
6268 { "Beam ID", "oran_fh_cus.beamId",
6269 FT_UINT16
, BASE_DEC
,
6271 "Defines the beam pattern to be applied to the U-Plane data", HFILL
}
6274 { &hf_oran_extension
,
6275 { "Extension", "oran_fh_cus.extension",
6276 FT_STRING
, BASE_NONE
,
6278 "Section extension", HFILL
}
6281 /* Section 7.6.2.1 */
6283 { "extType", "oran_fh_cus.extType",
6285 VALS(exttype_vals
), 0x7f,
6286 "The extension type, which provides additional parameters specific to subject data extension", HFILL
}
6289 /* Section 7.6.2.3 */
6291 { "extLen", "oran_fh_cus.extLen",
6292 FT_UINT16
, BASE_DEC
,
6294 "Extension length in 32-bit words", HFILL
}
6299 { "bfw", "oran_fh_cus.bfw",
6300 FT_STRING
, BASE_NONE
,
6302 "Set of weights for a particular antenna", HFILL
}
6304 { &hf_oran_bfw_bundle
,
6305 { "Bundle", "oran_fh_cus.bfw.bundle",
6306 FT_STRING
, BASE_NONE
,
6308 "Bundle of BFWs", HFILL
}
6310 { &hf_oran_bfw_bundle_id
,
6311 { "Bundle Id", "oran_fh_cus.bfw.bundleId",
6312 FT_UINT32
, BASE_DEC
,
6316 /* Section 7.7.1.4 */
6318 { "bfwI", "oran_fh_cus.bfwI",
6319 FT_FLOAT
, BASE_NONE
,
6323 /* Section 7.7.1.5 */
6325 { "bfwQ", "oran_fh_cus.bfwQ",
6326 FT_FLOAT
, BASE_NONE
,
6328 "Quadrature", HFILL
}
6331 /* Section 7.5.3.10 */
6333 { "UE ID", "oran_fh_cus.ueId",
6334 FT_UINT16
, BASE_DEC
,
6336 "logical identifier for set of channel info", HFILL
}
6339 /* Section 7.5.3.11 */
6340 { &hf_oran_freqOffset
,
6341 { "Frequency Offset", "oran_fh_cus.freqOffset",
6342 FT_UINT24
, BASE_DEC
,
6344 "with respect to the carrier center frequency before additional filtering", HFILL
}
6347 /* Section 7.5.3.12 */
6348 { &hf_oran_regularizationFactor
,
6349 { "Regularization Factor", "oran_fh_cus.regularizationFactor",
6352 "Signed value to support MMSE operation within O-RU", HFILL
}
6355 /* Section 7.5.3.14 */
6356 { &hf_oran_laaMsgType
,
6357 { "LAA Message Type", "oran_fh_cus.laaMsgType",
6358 FT_UINT8
, BASE_DEC
| BASE_RANGE_STRING
,
6359 RVALS(laaMsgTypes
), 0xf0,
6363 /* Section 7.5.3.15 */
6364 { &hf_oran_laaMsgLen
,
6365 { "LAA Message Length", "oran_fh_cus.laaMsgLen",
6368 "number of 32-bit words in the LAA section", HFILL
}
6371 /* Section 7.5.3.16 */
6372 { &hf_oran_lbtHandle
,
6373 { "LBT Handle", "oran_fh_cus.lbtHandle",
6374 FT_UINT16
, BASE_HEX
,
6376 "label to identify transaction", HFILL
}
6379 /* Section 7.5.3.17 */
6380 { &hf_oran_lbtDeferFactor
,
6381 { "Defer Factor", "oran_fh_cus.lbtDeferFactor",
6384 "Defer factor in sensing slots as described in 3GPP TS 36.213 Section 15.1.1", HFILL
}
6387 /* Section 7.5.3.18 */
6388 { &hf_oran_lbtBackoffCounter
,
6389 { "Backoff Counter", "oran_fh_cus.lbtBackoffCounter",
6390 FT_UINT16
, BASE_DEC
,
6392 "LBT backoff counter in sensing slots as described in 3GPP TS 36.213 Section 15.1.1", HFILL
}
6395 /* Section 7.5.3.19 */
6396 { &hf_oran_lbtOffset
,
6397 { "LBT Offset", "oran_fh_cus.lbtOffset",
6398 FT_UINT16
, BASE_DEC
,
6400 "LBT start time in microseconds from the beginning of the subframe scheduled by this message", HFILL
}
6403 /* Section 7.5.3.20 */
6405 { "Maximum Channel Occupancy Time", "oran_fh_cus.MCOT",
6408 "LTE TXOP duration in subframes as described in 3GPP TS 36.213 Section 15.1.1", HFILL
}
6411 /* Section 7.5.3.21 */
6413 { "LBT Mode", "oran_fh_cus.lbtMode",
6415 VALS(lbtMode_vals
), 0x0,
6419 /* Section 7.5.3.22 */
6420 { &hf_oran_lbtPdschRes
,
6421 { "lbtPdschRes", "oran_fh_cus.lbtPdschRes",
6423 VALS(lbtPdschRes_vals
), 0xc0,
6424 "LBT result of SFN/SF", HFILL
}
6427 /* Section 7.5.3.23 */
6428 { &hf_oran_sfStatus
,
6429 { "sfStatus", "oran_fh_cus.sfStatus",
6431 TFS(&tfs_sfStatus
), 0x10,
6432 "Indicates whether the subframe was dropped or transmitted", HFILL
}
6435 /* Section 7.5.3.22 */
6436 { &hf_oran_lbtDrsRes
,
6437 { "lbtDrsRes", "oran_fh_cus.lbtDrsRes",
6439 TFS(&tfs_fail_success
), 0x80,
6440 "Indicates whether the subframe was dropped or transmitted", HFILL
}
6443 /* Section 7.5.3.25 */
6444 { &hf_oran_initialPartialSF
,
6445 { "Initial partial SF", "oran_fh_cus.initialPartialSF",
6447 TFS(&tfs_partial_full_sf
), 0x40,
6448 "Indicates whether the initial SF in the LBT process is full or partial", HFILL
}
6451 /* Section 7.5.3.26. */
6452 { &hf_oran_lbtBufErr
,
6453 { "lbtBufErr", "oran_fh_cus.lbtBufErr",
6455 TFS(&tfs_lbtBufErr
), 0x80,
6456 "LBT buffer error", HFILL
}
6459 /* Section 7.5.3.27 */
6460 { &hf_oran_sfnSfEnd
,
6461 { "SFN/SF End", "oran_fh_cus.sfnSfEnd",
6462 FT_UINT16
, BASE_DEC
,
6464 "SFN/SF by which the DRS window must end", HFILL
}
6467 /* Section 7.5.3.28 */
6468 { &hf_oran_lbtCWConfig_H
,
6469 { "lbtCWConfig_H", "oran_fh_cus.lbtCWConfig_H",
6472 "HARQ parameters for congestion window management", HFILL
}
6475 /* Section 7.5.3.29 */
6476 { &hf_oran_lbtCWConfig_T
,
6477 { "lbtCWConfig_T", "oran_fh_cus.lbtCWConfig_T",
6480 "TB parameters for congestion window management", HFILL
}
6483 /* Section 7.5.3.30 */
6484 { &hf_oran_lbtTrafficClass
,
6485 { "lbtTrafficClass", "oran_fh_cus.lbtTrafficClass",
6487 VALS(lbtTrafficClass_vals
), 0x38,
6488 "Traffic class priority for congestion window management", HFILL
}
6491 /* Section 7.5.3.31 */
6492 { &hf_oran_lbtCWR_Rst
,
6493 { "lbtCWR_Rst", "oran_fh_cus.lbtCWR_Rst",
6495 TFS(&tfs_fail_success
), 0x80,
6496 "notification about packet reception successful or not", HFILL
}
6499 /* Reserved fields */
6500 { &hf_oran_reserved
,
6501 { "reserved", "oran_fh_cus.reserved",
6502 FT_UINT64
, BASE_HEX
,
6507 { &hf_oran_reserved_1bit
,
6508 { "reserved", "oran_fh_cus.reserved",
6513 { &hf_oran_reserved_2bits
,
6514 { "reserved", "oran_fh_cus.reserved",
6519 { &hf_oran_reserved_4bits
,
6520 { "reserved", "oran_fh_cus.reserved",
6525 { &hf_oran_reserved_last_4bits
,
6526 { "reserved", "oran_fh_cus.reserved",
6531 { &hf_oran_reserved_last_5bits
,
6532 { "reserved", "oran_fh_cus.reserved",
6537 { &hf_oran_reserved_6bits
,
6538 { "reserved", "oran_fh_cus.reserved",
6543 { &hf_oran_reserved_last_6bits
,
6544 { "reserved", "oran_fh_cus.reserved",
6549 { &hf_oran_reserved_7bits
,
6550 { "reserved", "oran_fh_cus.reserved",
6555 { &hf_oran_reserved_last_7bits
,
6556 { "reserved", "oran_fh_cus.reserved",
6561 { &hf_oran_reserved_8bits
,
6562 { "reserved", "oran_fh_cus.reserved",
6567 { &hf_oran_reserved_16bits
,
6568 { "reserved", "oran_fh_cus.reserved",
6569 FT_UINT16
, BASE_HEX
,
6573 { &hf_oran_reserved_15bits
,
6574 { "reserved", "oran_fh_cus.reserved",
6575 FT_UINT16
, BASE_HEX
,
6579 { &hf_oran_reserved_bit1
,
6580 { "reserved", "oran_fh_cus.reserved",
6585 { &hf_oran_reserved_bit2
,
6586 { "reserved", "oran_fh_cus.reserved",
6591 { &hf_oran_reserved_bit4
,
6592 { "reserved", "oran_fh_cus.reserved",
6597 { &hf_oran_reserved_bit5
,
6598 { "reserved", "oran_fh_cus.reserved",
6603 { &hf_oran_reserved_bits123
,
6604 { "reserved", "oran_fh_cus.reserved",
6609 { &hf_oran_reserved_bits456
,
6610 { "reserved", "oran_fh_cus.reserved",
6618 { &hf_oran_bundle_offset
,
6619 { "BundleOffset", "oran_fh_cus.bundleOffset",
6622 "offset between start of first PRB bundle and startPrbc", HFILL
}
6625 { &hf_oran_cont_ind
,
6626 { "contInd", "oran_fh_cus.contInd",
6628 TFS(&continuity_indication_tfs
), 0x80,
6629 "PRB region continuity flag", HFILL
}
6632 /* 7.7.1.2 bfwCompHdr (beamforming weight compression header) */
6633 { &hf_oran_bfwCompHdr
,
6634 { "bfwCompHdr", "oran_fh_cus.bfwCompHdr",
6635 FT_STRING
, BASE_NONE
,
6637 "Compression method and IQ bit width for beamforming weights", HFILL
}
6639 { &hf_oran_bfwCompHdr_iqWidth
,
6640 { "IQ Bit Width", "oran_fh_cus.bfwCompHdr_iqWidth",
6642 VALS(bfw_comp_headers_iq_width
), 0xf0,
6643 "IQ bit width for the beamforming weights", HFILL
}
6645 { &hf_oran_bfwCompHdr_compMeth
,
6646 { "Compression Method", "oran_fh_cus.bfwCompHdr_compMeth",
6648 VALS(bfw_comp_headers_comp_meth
), 0x0f,
6649 "compression method for the beamforming weights", HFILL
}
6653 { &hf_oran_ciCompParam
,
6654 { "ciCompParam", "oran_fh_cus.ciCompParam",
6655 FT_STRING
, BASE_NONE
,
6657 "channel information compression parameter", HFILL
}
6660 /* Table 7.5.3.32-1 */
6661 { &hf_oran_blockScaler
,
6662 { "blockScaler", "oran_fh_cus.blockScaler",
6665 "unsigned, 1 integer bit, 7 fractional bits", HFILL
}
6667 { &hf_oran_compBitWidth
,
6668 { "compBitWidth", "oran_fh_cus.compBitWidth",
6671 "Length of I bits and length of Q bits after compression over entire PRB", HFILL
}
6673 { &hf_oran_compShift
,
6674 { "compShift", "oran_fh_cus.compShift",
6677 "The shift applied to the entire PRB", HFILL
}
6680 /* Section 7.7.6.6 */
6681 { &hf_oran_repetition
,
6682 { "repetition", "oran_fh_cus.repetition",
6683 FT_BOOLEAN
, BASE_NONE
,
6685 "Repetition of a highest priority data section for C-Plane", HFILL
}
6689 { "rbgSize", "oran_fh_cus.rbgSize",
6691 VALS(rbg_size_vals
), 0x70,
6692 "Number of PRBs of the resource block groups allocated by the bit mask", HFILL
}
6696 { "rbgMask", "oran_fh_cus.rbgMask",
6697 FT_UINT32
, BASE_HEX
,
6699 "Each bit indicates whether a corresponding resource block group is present", HFILL
}
6702 { &hf_oran_noncontig_priority
,
6703 { "priority", "oran_fh_cus.priority",
6705 VALS(priority_vals
), 0xc0,
6709 { &hf_oran_symbolMask
,
6710 { "symbolMask", "oran_fh_cus.symbolMask",
6711 FT_UINT16
, BASE_HEX
,
6713 "Each bit indicates whether the rbgMask applies to a given symbol in the slot", HFILL
}
6717 { &hf_oran_ack_nack_req_id
,
6718 { "ackNackReqId", "oran_fh_cus.ackNackReqId",
6719 FT_UINT16
, BASE_HEX
,
6721 "Indicates the ACK/NACK request ID of a section description", HFILL
}
6724 /* Subtree for next 2 items */
6725 { &hf_oran_off_start_prb_num_prb_pair
,
6726 { "Pair", "oran_fh_cus.offStartPrb_numPrb",
6727 FT_STRING
, BASE_NONE
,
6729 "Pair of offStartPrb and numPrb", HFILL
}
6733 { &hf_oran_off_start_prb
,
6734 { "offStartPrb", "oran_fh_cus.offStartPrb",
6737 "Offset of PRB range start", HFILL
}
6741 { "numPrb", "oran_fh_cus.numPrb",
6744 "Number of PRBs in PRB range", HFILL
}
6747 /* symbolId 8.3.3.7 */
6748 { &hf_oran_symbolId
,
6749 { "Symbol Identifier", "oran_fh_cus.symbolId",
6752 "Identifies a symbol number within a slot", HFILL
}
6755 /* startPrbu 8.3.3.11 */
6756 { &hf_oran_startPrbu
,
6757 { "startPrbu", "oran_fh_cus.startPrbu",
6758 FT_UINT16
, BASE_DEC
,
6760 "starting PRB of user plane section", HFILL
}
6763 /* numPrbu 8.3.3.12 */
6765 { "numPrbu", "oran_fh_cus.numPrbu",
6768 "number of PRBs per user plane section", HFILL
}
6772 { &hf_oran_bfwCompParam
,
6773 { "bfwCompParam", "oran_fh_cus.bfwCompParam",
6774 FT_STRING
, BASE_NONE
,
6776 "Beamforming weight compression parameter", HFILL
}
6780 { &hf_oran_udCompHdrMeth
,
6781 { "User Data Compression Method", "oran_fh_cus.udCompHdrMeth",
6782 FT_UINT8
, BASE_DEC
| BASE_RANGE_STRING
,
6783 RVALS(ud_comp_header_meth
), 0x0f,
6784 "Defines the compression method for the user data in every section in the C-Plane message", HFILL
}
6786 { &hf_oran_udCompHdrMeth_pref
,
6787 { "User Data Compression Method", "oran_fh_cus.udCompHdrMeth",
6788 FT_UINT8
, BASE_DEC
| BASE_RANGE_STRING
,
6789 RVALS(ud_comp_header_meth
), 0x0,
6790 "Defines the compression method for the user data in every section in the C-Plane message", HFILL
}
6793 { &hf_oran_udCompLen
,
6794 { "udCompLen", "oran_fh_cus.udCompLen",
6795 FT_UINT16
, BASE_DEC
,
6797 "PRB field length in octets", HFILL
}
6801 { &hf_oran_udCompHdrIqWidth
,
6802 { "User Data IQ width", "oran_fh_cus.udCompHdrWidth",
6803 FT_UINT8
, BASE_DEC
| BASE_RANGE_STRING
,
6804 RVALS(ud_comp_header_width
), 0xf0,
6805 "Defines the IQ bit width for the user data in every section in the C-Plane message", HFILL
}
6807 { &hf_oran_udCompHdrIqWidth_pref
,
6808 { "User Data IQ width", "oran_fh_cus.udCompHdrWidth",
6811 "Defines the IQ bit width for the user data in every section in the C-Plane message", HFILL
}
6814 /* Section 8.3.3.15 (not always present - depends upon meth) */
6815 { &hf_oran_udCompParam
,
6816 { "User Data Compression Parameter", "oran_fh_cus.udCompParam",
6817 FT_STRING
, BASE_NONE
,
6819 "Applies to whatever compression method is specified by the associated sectionID's compMeth value", HFILL
}
6822 { &hf_oran_sReSMask
,
6823 { "sReSMask", "oran_fh_cus.sReSMask",
6824 FT_UINT16
, BASE_HEX
,
6826 "selective RE sending mask", HFILL
}
6829 { &hf_oran_sReSMask_re12
,
6830 { "RE-12", "oran_fh_cus.sReSMask-re12",
6832 TFS(&tfs_present_not_present
), 0x8000,
6835 { &hf_oran_sReSMask_re11
,
6836 { "RE-11", "oran_fh_cus.sReSMask-re11",
6838 TFS(&tfs_present_not_present
), 0x4000,
6841 { &hf_oran_sReSMask_re10
,
6842 { "RE-10", "oran_fh_cus.sReSMask-re10",
6844 TFS(&tfs_present_not_present
), 0x2000,
6847 { &hf_oran_sReSMask_re9
,
6848 { "RE-9", "oran_fh_cus.sReSMask-re9",
6850 TFS(&tfs_present_not_present
), 0x1000,
6853 { &hf_oran_sReSMask_re8
,
6854 { "RE-8", "oran_fh_cus.sReSMask-re8",
6856 TFS(&tfs_present_not_present
), 0x0080,
6859 { &hf_oran_sReSMask_re7
,
6860 { "RE-7", "oran_fh_cus.sReSMask-re7",
6862 TFS(&tfs_present_not_present
), 0x0040,
6865 { &hf_oran_sReSMask_re6
,
6866 { "RE-6", "oran_fh_cus.sReSMask-re6",
6868 TFS(&tfs_present_not_present
), 0x0020,
6871 { &hf_oran_sReSMask_re5
,
6872 { "RE-5", "oran_fh_cus.sReSMask-re5",
6874 TFS(&tfs_present_not_present
), 0x0010,
6877 { &hf_oran_sReSMask_re4
,
6878 { "RE-4", "oran_fh_cus.sReSMask-re4",
6880 TFS(&tfs_present_not_present
), 0x0008,
6883 { &hf_oran_sReSMask_re3
,
6884 { "RE-3", "oran_fh_cus.sReSMask-re3",
6886 TFS(&tfs_present_not_present
), 0x0004,
6889 { &hf_oran_sReSMask_re2
,
6890 { "RE-2", "oran_fh_cus.sReSMask-re2",
6892 TFS(&tfs_present_not_present
), 0x0002,
6895 { &hf_oran_sReSMask_re1
,
6896 { "RE-1", "oran_fh_cus.sReSMask-re1",
6898 TFS(&tfs_present_not_present
), 0x0001,
6903 { &hf_oran_sReSMask1
,
6904 { "sReSMask1", "oran_fh_cus.sReSMask1",
6905 FT_UINT16
, BASE_HEX
,
6907 "selective RE sending mask 1", HFILL
}
6910 { &hf_oran_sReSMask2
,
6911 { "sReSMask2", "oran_fh_cus.sReSMask2",
6912 FT_UINT16
, BASE_HEX
,
6914 "selective RE sending mask 2", HFILL
}
6917 { &hf_oran_sReSMask1_2_re12
,
6918 { "RE-12", "oran_fh_cus.sReSMask-re12",
6920 TFS(&tfs_present_not_present
), 0x0800,
6923 { &hf_oran_sReSMask1_2_re11
,
6924 { "RE-11", "oran_fh_cus.sReSMask-re11",
6926 TFS(&tfs_present_not_present
), 0x0400,
6929 { &hf_oran_sReSMask1_2_re10
,
6930 { "RE-10", "oran_fh_cus.sReSMask-re10",
6932 TFS(&tfs_present_not_present
), 0x0200,
6935 { &hf_oran_sReSMask1_2_re9
,
6936 { "RE-9", "oran_fh_cus.sReSMask-re9",
6938 TFS(&tfs_present_not_present
), 0x0100,
6942 /* Section 6.3.3.15 */
6944 { "iSample", "oran_fh_cus.iSample",
6945 FT_FLOAT
, BASE_NONE
,
6947 "In-phase Sample value", HFILL
}
6950 /* Section 6.3.3.16 */
6952 { "qSample", "oran_fh_cus.qSample",
6953 FT_FLOAT
, BASE_NONE
,
6955 "Quadrature Sample value", HFILL
}
6958 { &hf_oran_exponent
,
6959 { "Exponent", "oran_fh_cus.exponent",
6962 "Exponent applicable to the I & Q mantissas", HFILL
}
6965 { &hf_oran_iq_user_data
,
6966 { "IQ User Data", "oran_fh_cus.iq_user_data",
6967 FT_BYTES
, BASE_NONE
,
6969 "Used for the In-phase and Quadrature sample mantissa", HFILL
}
6972 { &hf_oran_c_eAxC_ID
,
6973 { "c_eAxC_ID", "oran_fh_cus.c_eaxc_id",
6974 FT_STRING
, BASE_NONE
,
6976 "This is a calculated field for the c_eAxC ID, which identifies the message stream", HFILL
}
6980 { "RefA", "oran_fh_cus.refa",
6981 FT_STRING
, BASE_NONE
,
6983 "This is a calculated field for the RefA ID, which provides a reference in time", HFILL
}
6987 /* Section 7.5.2.15 */
6988 { &hf_oran_ciCompHdr
,
6989 { "ciCompHdr", "oran_fh_cus.ciCompHdr",
6990 FT_STRING
, BASE_NONE
,
6994 { &hf_oran_ciCompHdrMeth
,
6995 { "User Data Compression Method", "oran_fh_cus.ciCompHdrMeth",
6996 FT_UINT8
, BASE_DEC
| BASE_RANGE_STRING
,
6997 RVALS(ud_comp_header_meth
), 0x0e,
6998 "Defines the compression method for the user data in every section in the C-Plane message", HFILL
}
7000 { &hf_oran_ciCompHdrIqWidth
,
7001 { "User Data IQ width", "oran_fh_cus.udCompHdrWidth",
7002 FT_UINT8
, BASE_DEC
| BASE_RANGE_STRING
,
7003 RVALS(ud_comp_header_width
), 0xf0,
7004 "Defines the IQ bit width for the user data in every section in the C-Plane message", HFILL
}
7006 { &hf_oran_ciCompOpt
,
7007 { "ciCompOpt", "oran_fh_cus.ciCompOpt",
7009 VALS(ci_comp_opt_vals
), 0x01,
7014 { &hf_oran_disable_bfws
,
7015 { "disableBFWs", "oran_fh_cus.disableBFWs",
7018 "Indicate if BFWs under section extension are disabled", HFILL
}
7022 { "RAD", "oran_fh_cus.rad",
7025 "Reset After PRB Discontinuity", HFILL
}
7028 { &hf_oran_num_bund_prbs
,
7029 { "numBundPrb", "oran_fh_cus.numBundPrb",
7032 "Number of bundled PRBs per BFWs", HFILL
}
7035 { "beamId", "oran_fh_cus.beamId",
7036 FT_UINT16
, BASE_DEC
,
7040 { &hf_oran_num_weights_per_bundle
,
7041 { "Num weights per bundle", "oran_fh_cus.num_weights_per_bundle",
7042 FT_UINT16
, BASE_DEC
,
7044 "From dissector preference", HFILL
}
7047 { &hf_oran_samples_prb
,
7048 {"PRB", "oran_fh_cus.prb",
7049 FT_STRING
, BASE_NONE
,
7051 "Grouping of samples for a particular Physical Resource Block", HFILL
}
7055 { &hf_oran_ciSample
,
7056 { "ciSample", "oran_fh_cus.ciSample",
7057 FT_STRING
, BASE_NONE
,
7059 "Sample (I and Q values)", HFILL
}
7061 { &hf_oran_ciIsample
,
7062 { "ciIsample", "oran_fh_cus.ciISample",
7063 FT_FLOAT
, BASE_NONE
,
7065 "Channel information complex value - I part", HFILL
}
7067 { &hf_oran_ciQsample
,
7068 { "ciQsample", "oran_fh_cus.ciQSample",
7069 FT_FLOAT
, BASE_NONE
,
7071 "Channel information complex value - Q part", HFILL
}
7075 { &hf_oran_beamGroupType
,
7076 { "beamGroupType", "oran_fh_cus.beamGroupType",
7078 VALS(beam_group_type_vals
), 0xc0,
7079 "The type of beam grouping", HFILL
}
7082 { &hf_oran_numPortc
,
7083 { "numPortc", "oran_fh_cus.numPortc",
7086 "The number of eAxC ports", HFILL
}
7089 /* 7.7.4.2 (1 bit) */
7091 { "csf", "oran_fh_cus.csf",
7092 FT_BOOLEAN
, BASE_NONE
,
7094 "constellation shift flag", HFILL
}
7097 { &hf_oran_modcompscaler
,
7098 { "modCompScaler", "oran_fh_cus.modcompscaler",
7099 FT_UINT16
, BASE_DEC
,
7101 "modulation compression scaler value", HFILL
}
7105 { &hf_oran_modcomp_param_set
,
7106 { "Set", "oran_fh_cus.modcomp-param-set",
7107 FT_STRING
, BASE_NONE
,
7112 /* mcScaleReMask 7.7.5.2 (12 bits) */
7113 { &hf_oran_mc_scale_re_mask
,
7114 { "mcScaleReMask", "oran_fh_cus.mcscaleremask",
7115 FT_BOOLEAN
, BASE_NONE
,
7117 "modulation compression power scale RE mask", HFILL
}
7119 /* mcScaleOffset 7.7.5.4 (15 bits) */
7120 { &hf_oran_mc_scale_offset
,
7121 { "mcScaleOffset", "oran_fh_cus.mcscaleoffset",
7122 FT_UINT24
, BASE_DEC
,
7124 "scaling value for modulation compression", HFILL
}
7126 /* eAxCmask (7.7.7.2) */
7127 { &hf_oran_eAxC_mask
,
7128 { "eAxC Mask", "oran_fh_cus.eaxcmask",
7129 FT_UINT16
, BASE_HEX
,
7131 "Which eAxC_ID values the C-Plane message applies to", HFILL
}
7133 /* technology (interface name) 7.7.9.2 */
7134 { &hf_oran_technology
,
7135 { "Technology", "oran_fh_cus.technology",
7137 VALS(interface_name_vals
), 0x0,
7138 "Interface name (that C-PLane section applies to)", HFILL
}
7140 /* Exttype 14 (7.7.14.2) */
7141 { &hf_oran_nullLayerInd
,
7142 { "nullLayerInd", "oran_fh_cus.nulllayerind",
7143 FT_BOOLEAN
, BASE_NONE
,
7145 "Whether corresponding layer is nulling-layer or not", HFILL
}
7148 /* Exttype 19 (7.7.19.8) */
7149 { &hf_oran_portReMask
,
7150 { "portReMask", "oran_fh_cus.portReMask",
7152 TFS(&tfs_set_notset
), 0x0fff,
7153 "RE bitmask per port", HFILL
}
7156 { &hf_oran_portSymbolMask
,
7157 { "portSymbolMask", "oran_fh_cus.portSymbolMask",
7159 TFS(&tfs_set_notset
), 0x3fff,
7160 "Symbol bitmask port port", HFILL
}
7163 { &hf_oran_ext19_port
,
7164 {"Port", "oran_fh_cus.ext19.port",
7165 FT_STRING
, BASE_NONE
,
7167 "Entry for a given port in ext19", HFILL
}
7171 { &hf_oran_prb_allocation
,
7172 {"PRB allocation", "oran_fh_cus.prb-allocation",
7173 FT_STRING
, BASE_NONE
,
7178 { &hf_oran_nextSymbolId
,
7179 { "nextSymbolId", "oran_fh_cus.nextSymbolId",
7182 "offset of PRB range start", HFILL
}
7185 { &hf_oran_nextStartPrbc
,
7186 { "nextStartPrbc", "oran_fh_cus.nextStartPrbc",
7187 FT_UINT16
, BASE_DEC
,
7189 "number of PRBs in PRB range", HFILL
}
7192 /* Puncturing patters as appears in SE 20 */
7193 { &hf_oran_puncPattern
,
7194 { "puncPattern", "oran_fh_cus.puncPattern",
7195 FT_STRING
, BASE_NONE
,
7200 /* 7.7.20.2 numPuncPatterns */
7201 { &hf_oran_numPuncPatterns
,
7202 { "numPuncPatterns", "oran_fh_cus.numPuncPatterns",
7205 "number of puncturing patterns", HFILL
}
7207 /* 7.7.20.3 symbolMask */
7208 { &hf_oran_symbolMask_ext20
,
7209 { "symbolMask", "oran_fh_cus.symbolMask",
7210 FT_UINT16
, BASE_HEX
,
7212 "Bitmask where each bit indicates the symbols associated with the puncturing pattern", HFILL
}
7214 /* 7.7.20.4 startPuncPrb */
7215 { &hf_oran_startPuncPrb
,
7216 { "startPuncPrb", "oran_fh_cus.startPuncPrb",
7217 FT_UINT16
, BASE_DEC
,
7219 "starting PRB to which one puncturing pattern applies", HFILL
}
7221 /* 7.7.20.5 numPuncPrb */
7222 { &hf_oran_numPuncPrb
,
7223 { "numPuncPrb", "oran_fh_cus.numPuncPrb",
7224 FT_UINT24
, BASE_DEC
,
7226 "the number of PRBs of the puncturing pattern", HFILL
}
7228 /* 7.7.20.6 puncReMask */
7229 { &hf_oran_puncReMask
,
7230 { "puncReMask", "oran_fh_cus.puncReMask",
7231 FT_UINT16
, BASE_DEC
,
7233 "puncturing pattern RE mask", HFILL
}
7235 /* 7.7.20.12 multiSDScope */
7236 { &hf_oran_multiSDScope
,
7237 { "multiSDScope", "oran_fh_cus.multiSDScope",
7239 TFS(&multi_sd_scope_tfs
), 0x02,
7240 "multiple section description scope flag", HFILL
}
7242 /* 7.7.20.4 rbgIncl */
7244 { "rbgIncl", "oran_fh_cus.rbgIncl",
7247 "rbg included flag", HFILL
}
7250 /* 7.7.21.2 ciPrbGroupSize */
7251 { &hf_oran_ci_prb_group_size
,
7252 { "ciPrbGroupSize", "oran_fh_cus.ciPrbGroupSize",
7255 "channel information PRB group size", HFILL
}
7258 { &hf_oran_prg_size_st5
,
7259 { "prgSize", "oran_fh_cus.prgSize",
7261 VALS(prg_size_st5_vals
), 0x03,
7262 "precoding resource block group size", HFILL
}
7264 { &hf_oran_prg_size_st6
,
7265 { "prgSize", "oran_fh_cus.prgSize",
7267 VALS(prg_size_st6_vals
), 0x03,
7268 "precoding resource block group size", HFILL
}
7271 /* 7.7.17.2 numUeID */
7272 { &hf_oran_num_ueid
,
7273 { "numUeID", "oran_fh_cus.numUeID",
7276 "number of ueIDs per user", HFILL
}
7279 /* 7.7.16.2 antMask */
7281 { "antMask", "oran_fh_cus.antMask",
7282 FT_UINT64
, BASE_HEX
,
7283 NULL
, 0xffffffffffffffff,
7284 "indices of antennas to be pre-combined per RX endpoint", HFILL
}
7287 /* 7.7.18.2 transmissionWindowOffset */
7288 { &hf_oran_transmissionWindowOffset
,
7289 { "transmissionWindowOffset", "oran_fh_cus.transmissionWindowOffset",
7290 FT_UINT16
, BASE_DEC
,
7292 "start of the transmission window as an offset to when the transmission window would have been without this parameter, i.e. (Ta3_max - Ta3_min)", HFILL
}
7294 /* 7.7.18.3 transmissionWindowSize */
7295 { &hf_oran_transmissionWindowSize
,
7296 { "transmissionWindowSize", "oran_fh_cus.transmissionWindowSize",
7297 FT_UINT16
, BASE_DEC
,
7299 "size of the transmission window in resolution µs", HFILL
}
7303 { "toT", "oran_fh_cus.toT",
7305 VALS(type_of_transmission_vals
), 0x03,
7306 "type of transmission", HFILL
}
7309 /* 7.7.2.2 bfaCompHdr */
7310 { &hf_oran_bfaCompHdr
,
7311 { "bfaCompHdr", "oran_fh_cus.bfaCompHdr",
7312 FT_STRING
, BASE_NONE
,
7314 "beamforming attributes compression header", HFILL
}
7316 /* 7.7.2.2-2: bfAzPtWidth */
7317 { &hf_oran_bfAzPtWidth
,
7318 { "bfAzPtWidth", "oran_fh_cus.bfAzPtWidth",
7320 VALS(bfa_bw_vals
), 0x38,
7323 /* 7.7.2.2-3: bfZePtWidth */
7324 { &hf_oran_bfZePtWidth
,
7325 { "bfZePtWidth", "oran_fh_cus.bfZePtWidth",
7327 VALS(bfa_bw_vals
), 0x07,
7330 /* 7.7.2.2-4: bfAz3ddWidth */
7331 { &hf_oran_bfAz3ddWidth
,
7332 { "bfAz3ddWidth", "oran_fh_cus.bfAz3ddWidth",
7334 VALS(bfa_bw_vals
), 0x38,
7337 /* 7.7.2.2-5: bfZe3ddWidth */
7338 { &hf_oran_bfZe3ddWidth
,
7339 { "bfZe3ddWidth", "oran_fh_cus.bfZe3ddWidth",
7341 VALS(bfa_bw_vals
), 0x07,
7345 /* 7.7.2.3 bfAzPt */
7347 { "bfAzPt", "oran_fh_cus.bfAzPt",
7350 "beamforming azimuth pointing parameter", HFILL
}
7352 /* 7.7.2.4 bfZePt */
7354 { "bfZePt", "oran_fh_cus.bfZePt",
7357 "beamforming zenith pointing parameter", HFILL
}
7359 /* 7.7.2.5 bfAz3dd */
7361 { "bfAz3dd", "oran_fh_cus.bfAz3dd",
7364 "beamforming azimuth beamwidth parameter", HFILL
}
7366 /* 7.7.2.6 bfZe3dd */
7368 { "bfZe3dd", "oran_fh_cus.bfZe3dd",
7371 "beamforming zenith beamwidth parameter", HFILL
}
7374 /* 7.7.2.7 bfAzSl */
7376 { "bfAzSl", "oran_fh_cus.bfAzSl",
7378 VALS(sidelobe_suppression_vals
), 0x38,
7379 "beamforming azimuth sidelobe parameter", HFILL
}
7381 /* 7.7.2.8 bfZeSl */
7383 { "bfZeSl", "oran_fh_cus.bfZeSl",
7385 VALS(sidelobe_suppression_vals
), 0x07,
7386 "beamforming zenith sidelobe parameter", HFILL
}
7390 { &hf_oran_cmd_scope
,
7391 { "cmdScope", "oran_fh_cus.cmdScope",
7392 FT_UINT8
, BASE_DEC
| BASE_RANGE_STRING
,
7393 RVALS(cmd_scope_vals
), 0x0f,
7394 "command scope", HFILL
}
7397 { &hf_oran_number_of_st4_cmds
,
7398 { "numberOfST4Cmds", "oran_fh_cus.numberOfST4Cmds",
7401 "Number of Section Type 4 commands", HFILL
}
7404 { &hf_oran_st4_cmd_header
,
7405 { "Command common header", "oran_fh_cus.st4CmdCommonHeader",
7406 FT_STRING
, BASE_NONE
,
7412 { &hf_oran_st4_cmd_type
,
7413 { "st4CmdType", "oran_fh_cus.st4CmdType",
7414 FT_UINT8
, BASE_DEC
| BASE_RANGE_STRING
,
7415 RVALS(st4_cmd_type_vals
), 0x0,
7419 { &hf_oran_st4_cmd_len
,
7420 { "st4CmdLen", "oran_fh_cus.st4CmdLen",
7421 FT_UINT16
, BASE_DEC
,
7423 "Length of command in 32-bit words", HFILL
}
7426 { &hf_oran_st4_cmd_num_slots
,
7427 { "numSlots", "oran_fh_cus.st4NumSlots",
7430 "Contiguous slots for which command is applicable", HFILL
}
7433 { &hf_oran_st4_cmd_ack_nack_req_id
,
7434 { "ackNackReqId", "oran_fh_cus.ackNackReqId",
7435 FT_UINT16
, BASE_DEC
,
7437 "ACK/NACK Request Id", HFILL
}
7441 { "Command", "oran_fh_cus.st4Cmd",
7442 FT_STRING
, BASE_NONE
,
7448 { &hf_oran_sleepmode_trx
,
7449 { "sleepMode", "oran_fh_cus.sleepMode",
7451 VALS(sleep_mode_trx_vals
), 0x03,
7454 { &hf_oran_sleepmode_asm
,
7455 { "sleepMode", "oran_fh_cus.sleepMode",
7457 VALS(sleep_mode_asm_vals
), 0x03,
7462 { &hf_oran_log2maskbits
,
7463 { "log2MaskBits", "oran_fh_cus.log2MaskBits",
7465 VALS(log2maskbits_vals
), 0x3c,
7466 "Number of bits to appear in antMask", HFILL
}
7469 { &hf_oran_num_slots_ext
,
7470 { "numSlotsExt", "oran_fh_cus.numSlotsExt",
7471 FT_UINT24
, BASE_HEX
,
7476 { &hf_oran_antMask_trx_control
,
7477 { "antMask", "oran_fh_cus.trxControl.antMask",
7478 FT_BYTES
, BASE_NONE
,
7480 "which antennas should sleep or wake-up", HFILL
}
7484 { "ready", "oran_fh_cus.ready",
7486 TFS(&ready_tfs
), 0x01,
7487 "wake-up ready indicator", HFILL
}
7490 { &hf_oran_number_of_acks
,
7491 { "numberOfAcks", "oran_fh_cus.numberOfAcks",
7494 "number of ACKs for one eAxC_ID", HFILL
}
7497 { &hf_oran_number_of_nacks
,
7498 { "numberOfNacks", "oran_fh_cus.numberOfNacks",
7501 "number of NACKs for one eAxC_ID", HFILL
}
7505 { "ackId", "oran_fh_cus.ackId",
7506 FT_UINT16
, BASE_DEC
,
7512 { "nackId", "oran_fh_cus.nackId",
7513 FT_UINT16
, BASE_DEC
,
7518 /* Links between acknack requests & responses */
7519 { &hf_oran_acknack_request_frame
,
7520 { "Request Frame", "oran_fh_cus.ackNackId.request-frame",
7521 FT_FRAMENUM
, BASE_NONE
,
7522 FRAMENUM_TYPE(FT_FRAMENUM_REQUEST
), 0x0,
7525 { &hf_oran_acknack_request_time
,
7526 { "Time since request in ms", "oran_fh_cus.ackNackId.time-since-request",
7527 FT_UINT32
, BASE_DEC
,
7529 "Time between request and response", HFILL
}
7531 { &hf_oran_acknack_request_type
,
7532 { "Request Type", "oran_fh_cus.ackNackId.request-type",
7533 FT_UINT32
, BASE_DEC
,
7534 VALS(acknack_type_vals
), 0x0,
7537 { &hf_oran_acknack_response_frame
,
7538 { "Response Frame", "oran_fh_cus.ackNackId.response-frame",
7539 FT_FRAMENUM
, BASE_NONE
,
7540 FRAMENUM_TYPE(FT_FRAMENUM_RESPONSE
), 0x0,
7543 { &hf_oran_acknack_response_time
,
7544 { "Time to response in ms", "oran_fh_cus.ackNackId.time-to-response",
7545 FT_UINT32
, BASE_DEC
,
7547 "Time between request and response", HFILL
}
7551 { &hf_oran_disable_tdbfns
,
7552 { "disableTDBFNs", "oran_fh_cus.disableTDBFNs",
7554 TFS(&disable_tdbfns_tfs
), 0x80,
7559 { &hf_oran_td_beam_group
,
7560 { "tdBeamGrp", "oran_fh_cus.tdBeamGrp",
7561 FT_UINT16
, BASE_HEX
,
7563 "Applies to symbolMask in command header", HFILL
}
7566 { &hf_oran_disable_tdbfws
,
7567 { "disableTDBFWs", "oran_fh_cus.disableTDBFWs",
7569 TFS(&beam_numbers_included_tfs
), 0x80,
7574 { &hf_oran_td_beam_num
,
7575 { "tdBeamNum", "oran_fh_cus.tdBeamNum",
7576 FT_UINT16
, BASE_HEX
,
7578 "time-domain beam number", HFILL
}
7582 { &hf_oran_dir_pattern
,
7583 { "dirPattern", "oran_fh_cus.dirPattern",
7585 TFS(&symbol_direction_tfs
), 0x3fff,
7586 "symbol data direction (gNB Tx/Rx) pattern", HFILL
}
7589 { &hf_oran_guard_pattern
,
7590 { "guardPattern", "oran_fh_cus.guardPattern",
7592 TFS(&symbol_guard_tfs
), 0x3fff,
7593 "guard pattern bitmask", HFILL
}
7596 /* For convenient filtering */
7598 { "C-Plane", "oran_fh_cus.c-plane",
7604 { "U-Plane", "oran_fh_cus.u-plane",
7610 { "BeamForming", "oran_fh_cus.bf",
7618 { &hf_oran_ecpri_pcid
,
7619 { "ecpriPcid", "oran_fh_cus.ecpriPcid",
7622 "IQ data transfer message series identifier", HFILL
}
7624 { &hf_oran_ecpri_rtcid
,
7625 { "ecpriRtcid", "oran_fh_cus.ecpriRtcid",
7628 "Real time control data identifier", HFILL
}
7631 { &hf_oran_ecpri_seqid
,
7632 { "ecpriSeqid", "oran_fh_cus.ecpriSeqid",
7635 "message identifier", HFILL
}
7639 { &hf_oran_num_sym_prb_pattern
,
7640 { "numSymPrbPattern", "oran_fh_cus.numSymPrbPattern",
7643 "number of symbol and resource block patterns", HFILL
}
7646 { &hf_oran_prb_mode
,
7647 { "prbMode", "oran_fh_cus.prbMode",
7649 TFS(&prb_mode_tfs
), 0x01,
7653 { &hf_oran_sym_prb_pattern
,
7654 { "symPrbPattern", "oran_fh_cus.symPrbPattern",
7655 FT_STRING
, BASE_NONE
,
7661 { &hf_oran_sym_mask
,
7662 { "symMask", "oran_fh_cus.symMask",
7663 FT_UINT16
, BASE_HEX
,
7665 "symbol mask part of symPrbPattern", HFILL
}
7668 {&hf_oran_num_mc_scale_offset
,
7669 {"numMcScaleOffset", "oran_fh_cus.numMcScaleOffset",
7672 "number of modulation compression scaling value per symPrbPattern",
7676 { &hf_oran_prb_pattern
,
7677 { "prbPattern", "oran_fh_cus.prbPattern",
7680 "resource block pattern part of symPrbPattern", HFILL
}
7684 { &hf_oran_codebook_index
,
7685 { "codebookIndex", "oran_fh_cus.codebookIndex",
7688 "precoder codebook used for transmission", HFILL
}
7692 { "layerID", "oran_fh_cus.layerID",
7695 "Layer ID for DL transmission", HFILL
}
7698 { &hf_oran_numlayers
,
7699 { "numLayers", "oran_fh_cus.numLayers",
7702 "number of layers for DL transmission", HFILL
}
7705 { &hf_oran_txscheme
,
7706 { "txScheme", "oran_fh_cus.txScheme",
7709 "transmission scheme", HFILL
}
7712 { &hf_oran_crs_remask
,
7713 { "crsReMask", "oran_fh_cus.crsReMask",
7714 FT_UINT16
, BASE_HEX
,
7716 "CRS resource element mask", HFILL
}
7719 { &hf_oran_crs_shift
,
7720 { "crsShift", "oran_fh_cus.crsShift",
7723 "CRS resource element mask", HFILL
}
7726 { &hf_oran_crs_symnum
,
7727 { "crsSymNum", "oran_fh_cus.crsSymNum",
7730 "CRS symbol number indication", HFILL
}
7733 { &hf_oran_beamid_ap1
,
7734 { "beamIdAP1", "oran_fh_cus.beamIdAP1",
7735 FT_UINT16
, BASE_DEC
,
7737 "beam id to be used for antenna port 1", HFILL
}
7740 { &hf_oran_beamid_ap2
,
7741 { "beamIdAP2", "oran_fh_cus.beamIdAP2",
7742 FT_UINT16
, BASE_DEC
,
7744 "beam id to be used for antenna port 2", HFILL
}
7747 { &hf_oran_beamid_ap3
,
7748 { "beamIdAP3", "oran_fh_cus.beamIdAP3",
7749 FT_UINT16
, BASE_DEC
,
7751 "beam id to be used for antenna port 3", HFILL
}
7755 { &hf_oran_port_list_index
,
7756 { "portListIndex", "oran_fh_cus.portListIndex",
7759 "the index of an eAxC_ID in the port-list", HFILL
}
7762 { &hf_oran_alpn_per_sym
,
7763 { "alpnPerSym", "oran_fh_cus.alpnPerSym",
7765 VALS(alpn_per_sym_vals
), 0x80,
7768 { &hf_oran_ant_dmrs_snr
,
7769 { "antDmrsSnr", "oran_fh_cus.antDmrsSnr",
7771 VALS(ant_dmrs_snr_vals
), 0x40,
7776 { &hf_oran_user_group_size
,
7777 { "userGroupSize", "oran_fh_cus.userGroupSize",
7780 "number of UE data layers in the user group identified by userGroupId", HFILL
}
7783 { &hf_oran_user_group_id
,
7784 { "userGroupId", "oran_fh_cus.userGroupId",
7787 "number of UE data layers in the user group identified by userGroupId", HFILL
}
7790 { &hf_oran_entry_type
,
7791 { "entryType", "oran_fh_cus.entryType",
7794 "indicates format of the entry", HFILL
}
7797 { &hf_oran_dmrs_port_number
,
7798 { "dmrsPortNumber", "oran_fh_cus.dmrsPortNumber",
7801 "DMRS antenna port number for the associated ueId", HFILL
}
7804 { &hf_oran_ueid_reset
,
7805 { "ueidReset", "oran_fh_cus.ueidReset",
7807 TFS(&tfs_ueid_reset
), 0x80,
7808 "same UEID as the previous slot", HFILL
}
7811 { &hf_oran_dmrs_symbol_mask
,
7812 { "dmrsSymbolMask", "oran_fh_cus.dmrsSymbolMask",
7813 FT_UINT16
, BASE_HEX
,
7815 "symbols within the slot containing DMRS", HFILL
}
7818 { &hf_oran_scrambling
,
7819 { "scrambling", "oran_fh_cus.scrambling",
7820 FT_UINT16
, BASE_HEX
,
7822 "used to calculate the seed value required to initialize pseudo-random generator", HFILL
}
7826 { "nscid", "oran_fh_cus.nscid",
7829 "used to calculate the seed value for pseudo-random generator", HFILL
}
7833 { "dType", "oran_fh_cus.dType",
7835 VALS(dtype_vals
), 0x40,
7836 "PUSCH DMRS configuration type", HFILL
}
7839 { &hf_oran_cmd_without_data
,
7840 { "cmdWithoutData", "oran_fh_cus.cmdWithoutData",
7843 "number of DMRS CDM groups without data", HFILL
}
7847 { "lambda", "oran_fh_cus.lambda",
7853 { &hf_oran_first_prb
,
7854 { "firstPrb", "oran_fh_cus.firstPrb",
7855 FT_UINT16
, BASE_DEC
,
7860 { &hf_oran_last_prb
,
7861 { "lastPrb", "oran_fh_cus.lastPrb",
7862 FT_UINT16
, BASE_DEC
,
7868 /* TODO: add value_string */
7869 { &hf_oran_low_papr_type
,
7870 { "lowPaprType", "oran_fh_cus.lowPaprType",
7872 VALS(papr_type_vals
), 0x30,
7876 { &hf_oran_hopping_mode
,
7877 { "hoppingMode", "oran_fh_cus.hoppingMode",
7879 VALS(hopping_mode_vals
), 0x0c,
7883 { &hf_oran_tx_win_for_on_air_symbol_l
,
7884 { "txWinForOnAirSymbol", "oran_fh_cus.txWinForOnAirSymbol",
7889 { &hf_oran_tx_win_for_on_air_symbol_r
,
7890 { "txWinForOnAirSymbol", "oran_fh_cus.txWinForOnAirSymbol",
7896 { &hf_oran_num_fo_fb
,
7897 { "numFoFb", "oran_fh_cus.numFoFb",
7900 "number of frequency offset feedback", HFILL
}
7903 { &hf_oran_freq_offset_fb
,
7904 { "freqOffsetFb", "oran_fh_cus.freqOffsetFb",
7905 FT_UINT16
, BASE_HEX_DEC
| BASE_RANGE_STRING
,
7906 RVALS(freq_offset_fb_values
), 0x0,
7907 "UE frequency offset feedback", HFILL
}
7911 { &hf_oran_num_sinr_per_prb
,
7912 { "numSinrPerPrb", "oran_fh_cus.numSinrPerPrb",
7914 VALS(num_sinr_per_prb_vals
), 0xe0,
7915 "number of SINR values per PRB", HFILL
}
7919 { &hf_oran_sinr_value
,
7920 { "sinrValue", "oran_fh_cus.sinrValue",
7921 FT_FLOAT
, BASE_NONE
,
7926 { &hf_oran_measurement_report
,
7927 { "Measurement Report", "oran_fh_cus.measurement-report",
7928 FT_STRING
, BASE_NONE
,
7934 { "mf", "oran_fh_cus.mf",
7936 TFS(&measurement_flag_tfs
), 0x80,
7937 "measurement flag", HFILL
}
7940 { &hf_oran_meas_data_size
,
7941 { "measDataSize", "oran_fh_cus.measDataSize",
7942 FT_UINT16
, BASE_DEC
,
7944 "measurement data size (in words)", HFILL
}
7948 { &hf_oran_meas_type_id
,
7949 { "measTypeId", "oran_fh_cus.measTypeId",
7951 VALS(meas_type_id_vals
), 0x7F,
7952 "measurement report type identifier", HFILL
}
7955 { &hf_oran_num_elements
,
7956 { "numElements", "oran_fh_cus.numElements",
7959 "measurement report type identifier", HFILL
}
7963 { "ueTae", "oran_fh_cus.ueTae",
7964 FT_UINT16
, BASE_DEC
| BASE_RANGE_STRING
,
7965 RVALS(freq_offset_fb_values
), 0x0,
7966 "UE Timing Advance Error", HFILL
}
7969 { &hf_oran_ue_layer_power
,
7970 { "ueLayerPower", "oran_fh_cus.ueLayerPower",
7971 FT_UINT16
, BASE_DEC
| BASE_RANGE_STRING
,
7972 RVALS(freq_offset_fb_values
), 0x0,
7973 "UE Layer Power", HFILL
}
7977 { &hf_oran_ue_freq_offset
,
7978 { "ueFreqOffset", "oran_fh_cus.ueFreqOffset",
7979 FT_UINT16
, BASE_DEC
| BASE_RANGE_STRING
,
7980 RVALS(freq_offset_fb_values
), 0x0,
7981 "UE frequency offset", HFILL
}
7984 { &hf_oran_ipn_power
,
7985 { "ipnPower", "oran_fh_cus.ipnPower",
7986 FT_UINT16
, BASE_DEC
| BASE_RANGE_STRING
,
7987 RVALS(freq_offset_fb_values
), 0x0,
7988 "Interference plus Noise power", HFILL
}
7991 { &hf_oran_ant_dmrs_snr_val
,
7992 { "antDmrsSnrVal", "oran_fh_cus.antDmrsSnrVal",
7993 FT_UINT16
, BASE_DEC
| BASE_RANGE_STRING
,
7994 RVALS(freq_offset_fb_values
), 0x0,
7995 "antenna DMRS-SNR", HFILL
}
7999 {&hf_oran_beam_type
,
8000 {"beamType", "oran_fh_cus.beamType",
8001 FT_UINT16
, BASE_DEC
,
8002 VALS(beam_type_vals
), 0xc0,
8007 {&hf_oran_meas_cmd_size
,
8008 {"measCmdSize", "oran_fh_cus.measCmdSize",
8009 FT_UINT16
, BASE_DEC
,
8011 "measurement command size in words",
8015 { &hf_oran_symbol_reordering_layer
,
8016 { "Layer", "oran_fh_cus.layer",
8017 FT_STRING
, BASE_NONE
,
8021 { &hf_oran_dmrs_entry
,
8022 { "Entry", "oran_fh_cus.dmrs-entry",
8023 FT_STRING
, BASE_NONE
,
8028 { &hf_oran_c_section_common
,
8029 { "Common Section", "oran_fh_cus.c-plane.section.common",
8030 FT_STRING
, BASE_NONE
,
8034 { &hf_oran_c_section
,
8035 { "Section", "oran_fh_cus.c-plane.section",
8036 FT_STRING
, BASE_NONE
,
8040 { &hf_oran_u_section
,
8041 { "Section", "oran_fh_cus.u-plane.section",
8042 FT_STRING
, BASE_NONE
,
8048 /* Setup protocol subtree array */
8049 static int *ett
[] = {
8051 &ett_oran_ecpri_pcid
,
8052 &ett_oran_ecpri_rtcid
,
8053 &ett_oran_ecpri_seqid
,
8054 &ett_oran_section_type
,
8056 &ett_oran_u_section
,
8060 &ett_oran_bfw_bundle
,
8062 &ett_oran_offset_start_prb_num_prb
,
8063 &ett_oran_prb_cisamples
,
8065 &ett_oran_udcomphdr
,
8066 &ett_oran_udcompparam
,
8067 &ett_oran_cicomphdr
,
8068 &ett_oran_cicompparam
,
8069 &ett_oran_bfwcomphdr
,
8070 &ett_oran_bfwcompparam
,
8071 &ett_oran_ext19_port
,
8072 &ett_oran_prb_allocation
,
8073 &ett_oran_punc_pattern
,
8074 &ett_oran_bfacomphdr
,
8075 &ett_oran_modcomp_param_set
,
8076 &ett_oran_st4_cmd_header
,
8078 &ett_oran_sym_prb_pattern
,
8079 &ett_oran_measurement_report
,
8081 &ett_oran_c_section_common
,
8082 &ett_oran_c_section
,
8084 &ett_oran_symbol_reordering_layer
,
8085 &ett_oran_dmrs_entry
8088 static int *ext_ett
[HIGHEST_EXTTYPE
];
8089 for (unsigned extno
=0; extno
<HIGHEST_EXTTYPE
; extno
++) {
8090 ext_ett
[extno
] = &ett_oran_c_section_extension
[extno
];
8093 expert_module_t
* expert_oran
;
8095 static ei_register_info ei
[] = {
8096 { &ei_oran_unsupported_bfw_compression_method
, { "oran_fh_cus.unsupported_bfw_compression_method", PI_UNDECODED
, PI_WARN
, "Unsupported BFW Compression Method", EXPFILL
}},
8097 { &ei_oran_invalid_sample_bit_width
, { "oran_fh_cus.invalid_sample_bit_width", PI_UNDECODED
, PI_ERROR
, "Unsupported sample bit width", EXPFILL
}},
8098 { &ei_oran_reserved_numBundPrb
, { "oran_fh_cus.reserved_numBundPrb", PI_MALFORMED
, PI_ERROR
, "Reserved value of numBundPrb", EXPFILL
}},
8099 { &ei_oran_extlen_wrong
, { "oran_fh_cus.extlen_wrong", PI_MALFORMED
, PI_ERROR
, "extlen doesn't match number of dissected bytes", EXPFILL
}},
8100 { &ei_oran_invalid_eaxc_bit_width
, { "oran_fh_cus.invalid_exac_bit_width", PI_UNDECODED
, PI_ERROR
, "Inconsistent eAxC bit width", EXPFILL
}},
8101 { &ei_oran_extlen_zero
, { "oran_fh_cus.extlen_zero", PI_MALFORMED
, PI_ERROR
, "extlen - zero is reserved value", EXPFILL
}},
8102 { &ei_oran_rbg_size_reserved
, { "oran_fh_cus.rbg_size_reserved", PI_MALFORMED
, PI_ERROR
, "rbgSize - zero is reserved value", EXPFILL
}},
8103 { &ei_oran_frame_length
, { "oran_fh_cus.frame_length", PI_MALFORMED
, PI_ERROR
, "there should be 0-3 bytes remaining after PDU in frame", EXPFILL
}},
8104 { &ei_oran_numprbc_ext21_zero
, { "oran_fh_cus.numprbc_ext21_zero", PI_MALFORMED
, PI_ERROR
, "numPrbc shall not be set to 0 when ciPrbGroupSize is configured", EXPFILL
}},
8105 { &ei_oran_ci_prb_group_size_reserved
, { "oran_fh_cus.ci_prb_group_size_reserved", PI_MALFORMED
, PI_WARN
, "ciPrbGroupSize should be 2-254", EXPFILL
}},
8106 { &ei_oran_st8_nackid
, { "oran_fh_cus.st8_nackid", PI_SEQUENCE
, PI_WARN
, "operation for this ackId failed", EXPFILL
}},
8107 { &ei_oran_st4_no_cmds
, { "oran_fh_cus.st4_nackid", PI_MALFORMED
, PI_ERROR
, "Not valid to have no commands in ST4", EXPFILL
}},
8108 { &ei_oran_st4_zero_len_cmd
, { "oran_fh_cus.st4_zero_len_cmd", PI_MALFORMED
, PI_WARN
, "ST4 cmd with length 0 is reserved", EXPFILL
}},
8109 { &ei_oran_st4_wrong_len_cmd
, { "oran_fh_cus.st4_wrong_len_cmd", PI_MALFORMED
, PI_ERROR
, "ST4 cmd with length not matching contents", EXPFILL
}},
8110 { &ei_oran_st4_unknown_cmd
, { "oran_fh_cus.st4_unknown_cmd", PI_MALFORMED
, PI_ERROR
, "ST4 cmd with unknown command code", EXPFILL
}},
8111 { &ei_oran_mcot_out_of_range
, { "oran_fh_cus.mcot_out_of_range", PI_MALFORMED
, PI_ERROR
, "MCOT should be 1-10", EXPFILL
}},
8112 { &ei_oran_se10_unknown_beamgrouptype
, { "oran_fh_cus.se10_unknown_beamgrouptype", PI_MALFORMED
, PI_WARN
, "SE10 - unknown BeamGroupType value", EXPFILL
}},
8113 { &ei_oran_start_symbol_id_not_zero
, { "oran_fh_cus.startsymbolid_shall_be_zero", PI_MALFORMED
, PI_WARN
, "For ST4 commands 3&4, startSymbolId shall be 0", EXPFILL
}},
8114 { &ei_oran_trx_control_cmd_scope
, { "oran_fh_cus.trx_command.bad_cmdscope", PI_MALFORMED
, PI_WARN
, "TRX command must have cmdScope of ARRAY-COMMAND", EXPFILL
}},
8115 { &ei_oran_unhandled_se
, { "oran_fh_cus.se_not_handled", PI_UNDECODED
, PI_WARN
, "SE not recognised/handled by dissector", EXPFILL
}},
8116 { &ei_oran_bad_symbolmask
, { "oran_fh_cus.bad_symbol_mask", PI_MALFORMED
, PI_WARN
, "For non-zero sleepMode, symbolMask must be 0x0 or 0x3ffff", EXPFILL
}},
8117 { &ei_oran_numslots_not_zero
, { "oran_fh_cus.numslots_not_zero", PI_MALFORMED
, PI_WARN
, "For ST4 TIME_DOMAIN_BEAM_WEIGHTS, numSlots should be 0", EXPFILL
}},
8118 { &ei_oran_version_unsupported
, { "oran_fh_cus.version_unsupported", PI_UNDECODED
, PI_WARN
, "Protocol version unsupported", EXPFILL
}},
8119 { &ei_oran_laa_msg_type_unsupported
, { "oran_fh_cus.laa_msg_type_unsupported", PI_UNDECODED
, PI_WARN
, "laaMsgType unsupported", EXPFILL
}},
8120 { &ei_oran_se_on_unsupported_st
, { "oran_fh_cus.se_on_unsupported_st", PI_MALFORMED
, PI_WARN
, "Section Extension should not appear on this Section Type", EXPFILL
}},
8121 { &ei_oran_cplane_unexpected_sequence_number
, { "oran_fh_cus.unexpected_seq_no_cplane", PI_SEQUENCE
, PI_WARN
, "Unexpected sequence number seen in C-Plane", EXPFILL
}},
8122 { &ei_oran_uplane_unexpected_sequence_number
, { "oran_fh_cus.unexpected_seq_no_uplane", PI_SEQUENCE
, PI_WARN
, "Unexpected sequence number seen in U-Plane", EXPFILL
}},
8123 { &ei_oran_acknack_no_request
, { "oran_fh_cus.acknack_no_request", PI_SEQUENCE
, PI_WARN
, "Have ackNackId response, but no request", EXPFILL
}},
8124 { &ei_oran_udpcomphdr_should_be_zero
, { "oran_fh_cus.udcomphdr_should_be_zero", PI_MALFORMED
, PI_WARN
, "C-Plane udCompHdr in DL should be set to 0", EXPFILL
}},
8125 { &ei_oran_radio_fragmentation_c_plane
, { "oran_fh_cus.radio_fragmentation_c_plane", PI_MALFORMED
, PI_ERROR
, "Radio fragmentation not allowed in C-PLane", EXPFILL
}},
8126 { &ei_oran_radio_fragmentation_u_plane
, { "oran_fh_cus.radio_fragmentation_u_plane", PI_UNDECODED
, PI_WARN
, "Radio fragmentation in C-PLane not yet supported", EXPFILL
}},
8127 { &ei_oran_lastRbdid_out_of_range
, { "oran_fh_cus.lastrbdid_out_of_range", PI_MALFORMED
, PI_WARN
, "SE 6 has bad rbgSize", EXPFILL
}},
8128 { &ei_oran_rbgMask_beyond_last_rbdid
, { "oran_fh_cus.rbgmask_beyond_lastrbdid", PI_MALFORMED
, PI_WARN
, "rbgMask has bits set beyond lastRbgId", EXPFILL
}},
8129 { &ei_oran_unexpected_measTypeId
, { "oran_fh_cus.unexpected_meastypeid", PI_MALFORMED
, PI_WARN
, "unexpected measTypeId", EXPFILL
}},
8130 { &ei_oran_unsupported_compression_method
, { "oran_fh_cus.compression_type_unsupported", PI_UNDECODED
, PI_WARN
, "Unsupported compression type", EXPFILL
}},
8131 { &ei_oran_ud_comp_len_wrong_size
, { "oran_fh_cus.ud_comp_len_wrong_size", PI_MALFORMED
, PI_WARN
, "udCompLen does not match length of U-Plane section", EXPFILL
}},
8132 { &ei_oran_sresmask2_not_zero_with_rb
, { "oran_fh_cus.sresmask2_not_zero", PI_MALFORMED
, PI_WARN
, "sReSMask2 should be zero when rb set", EXPFILL
}},
8133 { &ei_oran_st6_rb_shall_be_0
, { "oran_fh_cus.st6_rb_set", PI_MALFORMED
, PI_WARN
, "rb should not be set for Section Type 6", EXPFILL
}},
8134 { &ei_oran_st10_numsymbol_not_14
, { "oran_fh_cus.st10_numsymbol_not_14", PI_MALFORMED
, PI_WARN
, "numSymbol should be 14 for Section Type 10", EXPFILL
}},
8135 { &ei_oran_st10_startsymbolid_not_0
, { "oran_fh_cus.st10_startsymbolid_not_0", PI_MALFORMED
, PI_WARN
, "startSymbolId should be 0 for Section Type 10", EXPFILL
}}
8138 /* Register the protocol name and description */
8139 proto_oran
= proto_register_protocol("O-RAN Fronthaul CUS", "O-RAN FH CUS", "oran_fh_cus");
8141 /* Allow dissector to find be found by name. */
8142 register_dissector("oran_fh_cus", dissect_oran
, proto_oran
);
8144 /* Register the tap name. */
8145 oran_tap
= register_tap("oran-fh-cus");
8147 /* Required function calls to register the header fields and subtrees */
8148 proto_register_field_array(proto_oran
, hf
, array_length(hf
));
8149 proto_register_subtree_array(ett
, array_length(ett
));
8150 proto_register_subtree_array(ext_ett
, array_length(ext_ett
));
8153 expert_oran
= expert_register_protocol(proto_oran
);
8154 expert_register_field_array(expert_oran
, ei
, array_length(ei
));
8156 module_t
* oran_module
= prefs_register_protocol(proto_oran
, NULL
);
8158 /* Register bit width/compression preferences separately by direction. */
8159 prefs_register_uint_preference(oran_module
, "oran.du_port_id_bits", "DU Port ID bits [a]",
8160 "The bit width of DU Port ID - sum of a,b,c&d (eAxC) must be 16", 10, &pref_du_port_id_bits
);
8161 prefs_register_uint_preference(oran_module
, "oran.bandsector_id_bits", "BandSector ID bits [b]",
8162 "The bit width of BandSector ID - sum of a,b,c&d (eAxC) must be 16", 10, &pref_bandsector_id_bits
);
8163 prefs_register_uint_preference(oran_module
, "oran.cc_id_bits", "CC ID bits [c]",
8164 "The bit width of CC ID - sum of a,b,c&d (eAxC) must be 16", 10, &pref_cc_id_bits
);
8165 prefs_register_uint_preference(oran_module
, "oran.ru_port_id_bits", "RU Port ID bits [d]",
8166 "The bit width of RU Port ID - sum of a,b,c&d (eAxC) must be 16", 10, &pref_ru_port_id_bits
);
8168 prefs_register_uint_preference(oran_module
, "oran.iq_bitwidth_up", "IQ Bitwidth Uplink",
8169 "The bit width of a sample in the Uplink (if no udcompHdr)", 10, &pref_sample_bit_width_uplink
);
8170 prefs_register_enum_preference(oran_module
, "oran.ud_comp_up", "Uplink User Data Compression",
8171 "Uplink User Data Compression", &pref_iqCompressionUplink
, ul_compression_options
, false);
8172 prefs_register_enum_preference(oran_module
, "oran.ud_comp_hdr_up", "udCompHdr field is present for uplink",
8173 "The udCompHdr field in U-Plane messages may or may not be present, depending on the "
8174 "configuration of the O-RU. This preference instructs the dissector to expect "
8175 "this field to be present in uplink messages",
8176 &pref_includeUdCompHeaderUplink
, udcomphdr_present_options
, false);
8178 prefs_register_uint_preference(oran_module
, "oran.iq_bitwidth_down", "IQ Bitwidth Downlink",
8179 "The bit width of a sample in the Downlink (if no udcompHdr)", 10, &pref_sample_bit_width_downlink
);
8180 prefs_register_enum_preference(oran_module
, "oran.ud_comp_down", "Downlink User Data Compression",
8181 "Downlink User Data Compression", &pref_iqCompressionDownlink
, dl_compression_options
, false);
8182 prefs_register_enum_preference(oran_module
, "oran.ud_comp_hdr_down", "udCompHdr field is present for downlink",
8183 "The udCompHdr field in U-Plane messages may or may not be present, depending on the "
8184 "configuration of the O-RU. This preference instructs the dissector to expect "
8185 "this field to be present in downlink messages",
8186 &pref_includeUdCompHeaderDownlink
, udcomphdr_present_options
, false);
8188 prefs_register_uint_preference(oran_module
, "oran.rbs_in_uplane_section", "Total RBs in User-Plane data section",
8189 "This is used if numPrbu is signalled as 0", 10, &pref_data_plane_section_total_rbs
);
8191 prefs_register_uint_preference(oran_module
, "oran.num_weights_per_bundle", "Number of weights per bundle",
8192 "Used in decoding of section extension type 11 (Flexible BF weights)", 10, &pref_num_weights_per_bundle
);
8194 prefs_register_uint_preference(oran_module
, "oran.num_bf_antennas", "Number of BF Antennas",
8195 "Number of BF Antennas (used for C section type 6)", 10, &pref_num_bf_antennas
);
8197 prefs_register_bool_preference(oran_module
, "oran.show_iq_samples", "Show IQ Sample values",
8198 "When enabled, for U-Plane frames show each I and Q value in PRB", &pref_showIQSampleValues
);
8200 prefs_register_obsolete_preference(oran_module
, "oran.num_bf_weights");
8202 prefs_register_enum_preference(oran_module
, "oran.support_udcomplen", "udCompLen supported",
8203 "When enabled, U-Plane messages with relevant compression schemes will include udCompLen",
8204 &pref_support_udcompLen
, udcomp_support_options
, false);
8206 flow_states_table
= wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
8207 flow_results_table
= wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
8209 register_init_routine(&oran_init_protocol
);
8212 /* Simpler form of proto_reg_handoff_oran which can be used if there are
8213 * no prefs-dependent registration function calls. */
8215 proto_reg_handoff_oran(void)
8220 * Editor modelines - http://www.wireshark.org/tools/modelines.html
8225 * indent-tabs-mode: nil
8228 * ex: set shiftwidth=4 tabstop=8 expandtab:
8229 * :indentSize=4:tabSize=8:noTabs=true: