Bug Summary

File:builds/wireshark/wireshark/epan/dissectors/packet-oran.c
Warning:line 7231, column 51
Access to field 'expected_dl_sections' results in a dereference of a null pointer (loaded from variable 'result')

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name packet-oran.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -fno-delete-null-pointer-checks -mframe-pointer=all -relaxed-aliasing -fmath-errno -ffp-contract=on -fno-rounding-math -ffloat16-excess-precision=fast -fbfloat16-excess-precision=fast -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/builds/wireshark/wireshark/build -fcoverage-compilation-dir=/builds/wireshark/wireshark/build -resource-dir /usr/lib/llvm-22/lib/clang/22 -isystem /usr/include/glib-2.0 -isystem /usr/lib/x86_64-linux-gnu/glib-2.0/include -isystem /builds/wireshark/wireshark/epan/dissectors -isystem /builds/wireshark/wireshark/build/epan/dissectors -isystem /usr/include/mit-krb5 -isystem /usr/include/libxml2 -isystem /builds/wireshark/wireshark/epan -D CARES_NO_DEPRECATED -D G_DISABLE_DEPRECATED -D G_DISABLE_SINGLE_INCLUDES -D WS_BUILD_DLL -D WS_DEBUG -D WS_DEBUG_UTF_8 -I /builds/wireshark/wireshark/build -I /builds/wireshark/wireshark -I /builds/wireshark/wireshark/include -D _GLIBCXX_ASSERTIONS -internal-isystem /usr/lib/llvm-22/lib/clang/22/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fmacro-prefix-map=/builds/wireshark/wireshark/= -fmacro-prefix-map=/builds/wireshark/wireshark/build/= -fmacro-prefix-map=../= -Wno-format-nonliteral -std=gnu17 -ferror-limit 19 -fvisibility=hidden -fwrapv -fwrapv-pointer -fstrict-flex-arrays=3 -stack-protector 2 -fstack-clash-protection -fcf-protection=full -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fexceptions -fcolor-diagnostics -analyzer-output=html -faddrsig -fdwarf2-cfi-asm -o /builds/wireshark/wireshark/sbout/2026-07-02-100350-3577-1 -x c /builds/wireshark/wireshark/epan/dissectors/packet-oran.c
1/* packet-oran.c
2 * Routines for O-RAN fronthaul UC-plane dissection
3 * Copyright 2020, Jan Schiefer, Keysight Technologies, Inc.
4 * Copyright 2020- Martin Mathieson
5 *
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <[email protected]>
8 * Copyright 1998 Gerald Combs
9 *
10 * SPDX-License-Identifier: GPL-2.0-or-later
11 */
12
13 /*
14 * Dissector for the O-RAN Fronthaul CUS protocol specification.
15 * See https://specifications.o-ran.org/specifications, WG4, Fronthaul Interfaces Workgroup
16 * The current implementation is based on the ORAN-WG4.CUS.0-v20.00 specification.
17 * Note that other eCPRI message types are handled in packet-ecpri.c
18 */
19
20#include <config.h>
21
22#include <math.h>
23
24#include <epan/packet.h>
25#include <epan/expert.h>
26#include <epan/prefs.h>
27#include <epan/tap.h>
28#include <epan/tfs.h>
29#include <epan/reassemble.h>
30
31#include <wsutil/ws_roundup.h>
32#include <wsutil/ws_padding_to.h>
33
34#include "epan/dissectors/packet-oran.h"
35
36/* N.B. dissector preferences are taking the place of (some) M-plane parameters,
37 * so unfortunately it can be fiddly to get the preferences into a good state to
38 * decode a given capture..
39 * TODO:
40 * - for U-Plane, track back to last C-Plane frame for that eAxC
41 * doing, but this matching can be tricky see 7.8.1 Coupling of C-Plane and U-Plane
42 * - Detect/indicate signs of application layer fragmentation?
43 * same eAxC in same symbol (same/different section ID?)
44 * - Not handling M-plane setting for "little endian byte order" as applied to
45 * IQ samples and beam weights does anyone use this?
46 * - for section extensions, check more constraints (which other extension types
47 * appear with them, order, repeated)
48 * - re-order items (decl and hf definitions) to match spec order?
49 * - track energy-saving status, and identify TRX or ASM commands as 'Sleep extension'
50 */
51
52/* Prototypes */
53void proto_register_oran(void);
54
55/* Initialize the protocol and registered fields */
56static int proto_oran;
57
58static int oran_tap = -1;
59
60static int hf_oran_du_port_id;
61static int hf_oran_bandsector_id;
62static int hf_oran_cc_id;
63static int hf_oran_ru_port_id;
64static int hf_oran_sequence_id;
65static int hf_oran_e_bit;
66static int hf_oran_subsequence_id;
67static int hf_oran_previous_frame;
68
69static int hf_oran_data_direction;
70static int hf_oran_payload_version;
71static int hf_oran_filter_index;
72static int hf_oran_frame_id;
73static int hf_oran_subframe_id;
74static int hf_oran_slot_id;
75static int hf_oran_slot_within_frame;
76static int hf_oran_start_symbol_id;
77static int hf_oran_numberOfSections;
78static int hf_oran_sectionType;
79
80static int hf_oran_udCompHdr;
81static int hf_oran_udCompHdrIqWidth;
82static int hf_oran_udCompHdrIqWidth_pref;
83static int hf_oran_udCompHdrMeth;
84static int hf_oran_udCompHdrMeth_pref;
85static int hf_oran_udCompLen;
86static int hf_oran_numberOfUEs;
87static int hf_oran_timeOffset;
88static int hf_oran_frameStructure_fft;
89static int hf_oran_frameStructure_subcarrier_spacing;
90static int hf_oran_cpLength;
91static int hf_oran_timing_header;
92static int hf_oran_section_id;
93static int hf_oran_rb;
94static int hf_oran_symInc;
95static int hf_oran_startPrbc;
96static int hf_oran_reMask_re1;
97static int hf_oran_reMask_re2;
98static int hf_oran_reMask_re3;
99static int hf_oran_reMask_re4;
100static int hf_oran_reMask_re5;
101static int hf_oran_reMask_re6;
102static int hf_oran_reMask_re7;
103static int hf_oran_reMask_re8;
104static int hf_oran_reMask_re9;
105static int hf_oran_reMask_re10;
106static int hf_oran_reMask_re11;
107static int hf_oran_reMask_re12;
108static int hf_oran_reMask;
109static int hf_oran_numPrbc;
110static int hf_oran_numSymbol;
111static int hf_oran_ef;
112static int hf_oran_beamId;
113
114static int hf_oran_sinrCompHdrIqWidth_pref;
115static int hf_oran_sinrCompHdrMeth_pref;
116
117static int hf_oran_ciCompHdr;
118static int hf_oran_ciCompHdrIqWidth;
119static int hf_oran_ciCompHdrMeth;
120static int hf_oran_ciCompOpt;
121
122static int hf_oran_extension;
123static int hf_oran_exttype;
124static int hf_oran_extlen;
125
126static int hf_oran_bfw_bundle;
127static int hf_oran_bfw_bundle_id;
128static int hf_oran_bfw;
129static int hf_oran_bfw_i;
130static int hf_oran_bfw_q;
131
132static int hf_oran_ueId;
133static int hf_oran_freqOffset;
134static int hf_oran_regularizationFactor;
135static int hf_oran_laaMsgType;
136static int hf_oran_laaMsgLen;
137static int hf_oran_lbtHandle;
138static int hf_oran_lbtDeferFactor;
139static int hf_oran_lbtBackoffCounter;
140static int hf_oran_lbtOffset;
141static int hf_oran_MCOT;
142static int hf_oran_lbtMode;
143static int hf_oran_sfnSfEnd;
144static int hf_oran_lbtPdschRes;
145static int hf_oran_sfStatus;
146static int hf_oran_initialPartialSF;
147static int hf_oran_lbtDrsRes;
148static int hf_oran_lbtBufErr;
149static int hf_oran_lbtTrafficClass;
150static int hf_oran_lbtCWConfig_H;
151static int hf_oran_lbtCWConfig_T;
152static int hf_oran_lbtCWR_Rst;
153
154static int hf_oran_reserved;
155static int hf_oran_reserved_1bit;
156static int hf_oran_reserved_2bits;
157static int hf_oran_reserved_3bits;
158static int hf_oran_reserved_4bits;
159static int hf_oran_reserved_last_4bits;
160static int hf_oran_reserved_last_5bits;
161static int hf_oran_reserved_6bits;
162static int hf_oran_reserved_last_6bits;
163static int hf_oran_reserved_7bits;
164static int hf_oran_reserved_last_7bits;
165static int hf_oran_reserved_8bits;
166static int hf_oran_reserved_16bits;
167static int hf_oran_reserved_15bits;
168static int hf_oran_reserved_bit1;
169static int hf_oran_reserved_bit2;
170static int hf_oran_reserved_bit4;
171static int hf_oran_reserved_bit5;
172static int hf_oran_reserved_bits123;
173static int hf_oran_reserved_bits456;
174
175static int hf_oran_bundle_offset;
176static int hf_oran_cont_ind;
177
178static int hf_oran_bfwCompHdr;
179static int hf_oran_bfwCompHdr_iqWidth;
180static int hf_oran_bfwCompHdr_compMeth;
181static int hf_oran_symbolId;
182static int hf_oran_startPrbu;
183static int hf_oran_numPrbu;
184
185static int hf_oran_udCompParam;
186static int hf_oran_sReSMask;
187static int hf_oran_sReSMask_re12;
188static int hf_oran_sReSMask_re11;
189static int hf_oran_sReSMask_re10;
190static int hf_oran_sReSMask_re9;
191static int hf_oran_sReSMask_re8;
192static int hf_oran_sReSMask_re7;
193static int hf_oran_sReSMask_re6;
194static int hf_oran_sReSMask_re5;
195static int hf_oran_sReSMask_re4;
196static int hf_oran_sReSMask_re3;
197static int hf_oran_sReSMask_re2;
198static int hf_oran_sReSMask_re1;
199
200static int hf_oran_sReSMask1;
201static int hf_oran_sReSMask2;
202static int hf_oran_sReSMask1_2_re12;
203static int hf_oran_sReSMask1_2_re11;
204static int hf_oran_sReSMask1_2_re10;
205static int hf_oran_sReSMask1_2_re9;
206
207static int hf_oran_bfwCompParam;
208
209static int hf_oran_iSample;
210static int hf_oran_qSample;
211
212static int hf_oran_ciCompParam;
213
214static int hf_oran_blockScaler;
215static int hf_oran_compBitWidth;
216static int hf_oran_compShift;
217
218static int hf_oran_active_beamspace_coefficient_n1;
219static int hf_oran_active_beamspace_coefficient_n2;
220static int hf_oran_active_beamspace_coefficient_n3;
221static int hf_oran_active_beamspace_coefficient_n4;
222static int hf_oran_active_beamspace_coefficient_n5;
223static int hf_oran_active_beamspace_coefficient_n6;
224static int hf_oran_active_beamspace_coefficient_n7;
225static int hf_oran_active_beamspace_coefficient_n8;
226static int hf_oran_activeBeamspaceCoefficientMask;
227static int hf_oran_activeBeamspaceCoefficientMask_bits_set;
228
229static int hf_oran_se6_repetition;
230
231static int hf_oran_rbgSize;
232static int hf_oran_rbgMask;
233static int hf_oran_noncontig_priority;
234
235static int hf_oran_symbol_mask;
236static int hf_oran_symbol_mask_s13;
237static int hf_oran_symbol_mask_s12;
238static int hf_oran_symbol_mask_s11;
239static int hf_oran_symbol_mask_s10;
240static int hf_oran_symbol_mask_s9;
241static int hf_oran_symbol_mask_s8;
242static int hf_oran_symbol_mask_s7;
243static int hf_oran_symbol_mask_s6;
244static int hf_oran_symbol_mask_s5;
245static int hf_oran_symbol_mask_s4;
246static int hf_oran_symbol_mask_s3;
247static int hf_oran_symbol_mask_s2;
248static int hf_oran_symbol_mask_s1;
249static int hf_oran_symbol_mask_s0;
250
251static int hf_oran_exponent;
252static int hf_oran_iq_user_data;
253
254static int hf_oran_disable_bfws;
255static int hf_oran_rad;
256static int hf_oran_num_bund_prbs;
257static int hf_oran_beam_id;
258static int hf_oran_num_weights_per_bundle;
259
260static int hf_oran_ack_nack_req_id;
261
262static int hf_oran_frequency_range;
263static int hf_oran_off_start_prb;
264static int hf_oran_num_prb;
265
266static int hf_oran_samples_prb;
267static int hf_oran_ciSample;
268static int hf_oran_ciIsample;
269static int hf_oran_ciQsample;
270
271static int hf_oran_beamGroupType;
272static int hf_oran_numPortc;
273
274static int hf_oran_csf;
275static int hf_oran_modcompscaler;
276
277static int hf_oran_modcomp_param_set;
278static int hf_oran_mc_scale_re_mask_re1;
279static int hf_oran_mc_scale_re_mask_re2;
280static int hf_oran_mc_scale_re_mask_re3;
281static int hf_oran_mc_scale_re_mask_re4;
282static int hf_oran_mc_scale_re_mask_re5;
283static int hf_oran_mc_scale_re_mask_re6;
284static int hf_oran_mc_scale_re_mask_re7;
285static int hf_oran_mc_scale_re_mask_re8;
286static int hf_oran_mc_scale_re_mask_re9;
287static int hf_oran_mc_scale_re_mask_re10;
288static int hf_oran_mc_scale_re_mask_re11;
289static int hf_oran_mc_scale_re_mask_re12;
290static int hf_oran_mc_scale_re_mask_re1_even;
291static int hf_oran_mc_scale_re_mask_re2_even;
292static int hf_oran_mc_scale_re_mask_re3_even;
293static int hf_oran_mc_scale_re_mask_re4_even;
294static int hf_oran_mc_scale_re_mask_re5_even;
295static int hf_oran_mc_scale_re_mask_re6_even;
296static int hf_oran_mc_scale_re_mask_re7_even;
297static int hf_oran_mc_scale_re_mask_re8_even;
298static int hf_oran_mc_scale_re_mask_re9_even;
299static int hf_oran_mc_scale_re_mask_re10_even;
300static int hf_oran_mc_scale_re_mask_re11_even;
301static int hf_oran_mc_scale_re_mask_re12_even;
302
303static int hf_oran_mc_scale_re_mask;
304static int hf_oran_mc_scale_re_mask_even;
305
306static int hf_oran_mc_scale_offset;
307
308static int hf_oran_eAxC_mask;
309static int hf_oran_technology;
310static int hf_oran_nullLayerInd;
311
312static int hf_oran_se19_repetition;
313static int hf_oran_portReMask;
314static int hf_oran_portSymbolMask;
315
316static int hf_oran_ext19_port;
317
318static int hf_oran_prb_allocation;
319static int hf_oran_nextSymbolId;
320static int hf_oran_nextStartPrbc;
321
322static int hf_oran_puncPattern;
323static int hf_oran_numPuncPatterns;
324static int hf_oran_symbolMask_ext20;
325static int hf_oran_startPuncPrb;
326static int hf_oran_numPuncPrb;
327static int hf_oran_puncReMask;
328static int hf_oran_multiSDScope;
329static int hf_oran_RbgIncl;
330
331static int hf_oran_ci_prb_group_size;
332static int hf_oran_prg_size_st5;
333static int hf_oran_prg_size_st6;
334
335static int hf_oran_num_ueid;
336
337static int hf_oran_antMask;
338
339static int hf_oran_transmissionWindowOffset;
340static int hf_oran_transmissionWindowSize;
341static int hf_oran_toT;
342
343static int hf_oran_bfaCompHdr;
344static int hf_oran_bfAzPtWidth;
345static int hf_oran_bfZePtWidth;
346static int hf_oran_bfAz3ddWidth;
347static int hf_oran_bfZe3ddWidth;
348static int hf_oran_bfAzPt;
349static int hf_oran_bfZePt;
350static int hf_oran_bfAz3dd;
351static int hf_oran_bfZe3dd;
352static int hf_oran_bfAzSl;
353static int hf_oran_bfZeSl;
354
355static int hf_oran_cmd_scope;
356static int hf_oran_number_of_st4_cmds;
357
358static int hf_oran_st4_cmd_header;
359static int hf_oran_st4_cmd_type;
360static int hf_oran_st4_cmd_len;
361static int hf_oran_st4_cmd_num_slots;
362static int hf_oran_st4_cmd_ack_nack_req_id;
363
364static int hf_oran_st4_cmd;
365
366static int hf_oran_sleepmode_trx;
367static int hf_oran_sleepmode_asm;
368static int hf_oran_log2maskbits;
369static int hf_oran_num_slots_ext;
370static int hf_oran_antMask_trx_control;
371
372static int hf_oran_ready;
373static int hf_oran_number_of_acks;
374static int hf_oran_number_of_nacks;
375static int hf_oran_ackid;
376static int hf_oran_nackid;
377
378static int hf_oran_acknack_request_frame;
379static int hf_oran_acknack_request_time;
380static int hf_oran_acknack_request_type;
381static int hf_oran_acknack_response_frame;
382static int hf_oran_acknack_response_time;
383
384static int hf_oran_disable_tdbfns;
385static int hf_oran_td_beam_group;
386static int hf_oran_disable_tdbfws;
387static int hf_oran_td_beam_num;
388
389static int hf_oran_dir_pattern;
390static int hf_oran_guard_pattern;
391
392static int hf_oran_ecpri_pcid;
393static int hf_oran_ecpri_rtcid;
394static int hf_oran_ecpri_seqid;
395
396static int hf_oran_num_sym_prb_pattern;
397static int hf_oran_prb_mode;
398static int hf_oran_sym_prb_pattern;
399static int hf_oran_sym_mask;
400static int hf_oran_num_mc_scale_offset;
401static int hf_oran_prb_pattern;
402static int hf_oran_prb_block_offset;
403static int hf_oran_prb_block_size;
404
405static int hf_oran_codebook_index;
406static int hf_oran_layerid;
407static int hf_oran_numlayers;
408static int hf_oran_txscheme;
409static int hf_oran_crs_remask;
410static int hf_oran_crs_shift;
411static int hf_oran_crs_symnum;
412static int hf_oran_beamid_ap1;
413static int hf_oran_beamid_ap2;
414static int hf_oran_beamid_ap3;
415
416static int hf_oran_port_list_index;
417static int hf_oran_alpn_per_sym;
418static int hf_oran_ant_dmrs_snr;
419static int hf_oran_user_group_size;
420static int hf_oran_user_group_id;
421static int hf_oran_entry_type;
422static int hf_oran_dmrs_port_number;
423static int hf_oran_ueid_reset;
424
425static int hf_oran_dmrs_symbol_mask;
426static int hf_oran_dmrs_symbol_mask_s13;
427static int hf_oran_dmrs_symbol_mask_s12;
428static int hf_oran_dmrs_symbol_mask_s11;
429static int hf_oran_dmrs_symbol_mask_s10;
430static int hf_oran_dmrs_symbol_mask_s9;
431static int hf_oran_dmrs_symbol_mask_s8;
432static int hf_oran_dmrs_symbol_mask_s7;
433static int hf_oran_dmrs_symbol_mask_s6;
434static int hf_oran_dmrs_symbol_mask_s5;
435static int hf_oran_dmrs_symbol_mask_s4;
436static int hf_oran_dmrs_symbol_mask_s3;
437static int hf_oran_dmrs_symbol_mask_s2;
438static int hf_oran_dmrs_symbol_mask_s1;
439static int hf_oran_dmrs_symbol_mask_s0;
440
441static int hf_oran_scrambling;
442static int hf_oran_nscid;
443static int hf_oran_dtype;
444static int hf_oran_cmd_without_data;
445static int hf_oran_lambda;
446static int hf_oran_first_prb;
447static int hf_oran_last_prb;
448static int hf_oran_low_papr_type;
449static int hf_oran_hopping_mode;
450
451static int hf_oran_tx_win_for_on_air_symbol_l;
452static int hf_oran_tx_win_for_on_air_symbol_r;
453
454static int hf_oran_num_fo_fb;
455static int hf_oran_freq_offset_fb;
456
457static int hf_oran_num_ue_sinr_rpt;
458static int hf_oran_num_sinr_per_prb;
459static int hf_oran_num_sinr_per_prb_right;
460
461static int hf_oran_sinr_value;
462
463static int hf_oran_measurement_report;
464static int hf_oran_mf;
465static int hf_oran_meas_data_size;
466static int hf_oran_meas_type_id;
467static int hf_oran_ipn_power;
468static int hf_oran_ue_tae;
469static int hf_oran_ue_layer_power;
470static int hf_oran_num_elements;
471static int hf_oran_ant_dmrs_snr_val;
472static int hf_oran_ue_freq_offset;
473
474static int hf_oran_measurement_command;
475
476static int hf_oran_beam_type;
477static int hf_oran_meas_cmd_size;
478
479static int hf_oran_symbol_reordering_layer;
480static int hf_oran_dmrs_entry;
481
482static int hf_oran_c_section_common;
483static int hf_oran_c_section;
484static int hf_oran_u_section;
485
486static int hf_oran_u_section_ul_symbol_time;
487static int hf_oran_u_section_ul_symbol_frames;
488static int hf_oran_u_section_ul_symbol_first_frame;
489static int hf_oran_u_section_ul_symbol_last_frame;
490
491static int hf_oran_cd_scg_size;
492static int hf_oran_cd_scg_phase_step;
493
494static int hf_oran_sinr_prb;
495static int hf_oran_oru_control_sinr_slot_mask_id;
496static int hf_oran_pos_meas;
497
498static int hf_oran_ue_radial_speed;
499static int hf_oran_ue_az_aoa;
500static int hf_oran_ue_ze_aoa;
501static int hf_oran_ue_pos_toa_offset;
502
503static int hf_oran_num_rep_ue;
504static int hf_oran_rep_ueid;
505static int hf_oran_is_last_rep;
506static int hf_oran_rep_index;
507static int hf_oran_num_reps;
508
509
510/* Computed fields */
511static int hf_oran_c_eAxC_ID;
512static int hf_oran_refa;
513
514static int hf_oran_bfws_frame_defined;
515static int hf_oran_bfws_symbols_since_defined;
516
517static int hf_oran_corresponding_cplane_frame;
518static int hf_oran_corresponding_cplane_frame_time_delta;
519
520
521/* Convenient fields for filtering, mostly shown as hidden */
522static int hf_oran_cplane;
523static int hf_oran_uplane;
524static int hf_oran_bf; /* to match frames that configure beamforming in any way */
525static int hf_oran_zero_prb;
526static int hf_oran_nonzero_prb;
527static int hf_oran_bundle_weights_all_zero;
528
529static int hf_oran_ul_cplane_ud_comp_hdr_frame;
530
531/* For reassembly */
532static int hf_oran_fragments;
533static int hf_oran_fragment;
534static int hf_oran_fragment_overlap;
535static int hf_oran_fragment_overlap_conflict;
536static int hf_oran_fragment_multiple_tails;
537static int hf_oran_fragment_too_long_fragment;
538static int hf_oran_fragment_error;
539static int hf_oran_fragment_count;
540static int hf_oran_reassembled_in;
541static int hf_oran_reassembled_length;
542static int hf_oran_reassembled_data;
543
544static int hf_oran_payload;
545
546
547/* Subtrees */
548static int ett_oran;
549static int ett_oran_ecpri_rtcid;
550static int ett_oran_ecpri_pcid;
551static int ett_oran_ecpri_seqid;
552static int ett_oran_section;
553static int ett_oran_section_type;
554static int ett_oran_u_timing;
555static int ett_oran_u_section;
556static int ett_oran_u_prb;
557static int ett_oran_iq;
558static int ett_oran_bfw_bundle;
559static int ett_oran_bfw;
560static int ett_oran_frequency_range;
561static int ett_oran_prb_cisamples;
562static int ett_oran_cisample;
563static int ett_oran_udcomphdr;
564static int ett_oran_udcompparam;
565static int ett_oran_cicomphdr;
566static int ett_oran_cicompparam;
567static int ett_oran_bfwcomphdr;
568static int ett_oran_bfwcompparam;
569static int ett_oran_ext19_port;
570static int ett_oran_prb_allocation;
571static int ett_oran_punc_pattern;
572static int ett_oran_bfacomphdr;
573static int ett_oran_modcomp_param_set;
574static int ett_oran_st4_cmd_header;
575static int ett_oran_st4_cmd;
576static int ett_oran_sym_prb_pattern;
577static int ett_oran_measurement_report;
578static int ett_oran_measurement_command;
579static int ett_oran_sresmask;
580static int ett_oran_c_section_common;
581static int ett_oran_c_section;
582static int ett_oran_remask;
583static int ett_oran_mc_scale_remask;
584static int ett_oran_symbol_reordering_layer;
585static int ett_oran_dmrs_entry;
586static int ett_oran_dmrs_symbol_mask;
587static int ett_oran_symbol_mask;
588static int ett_oran_active_beamspace_coefficient_mask;
589static int ett_oran_sinr_prb;
590
591static int ett_oran_fragment;
592static int ett_oran_fragments;
593
594/* Reassembly table. */
595static reassembly_table oran_reassembly_table;
596
597static void *oran_key(const packet_info *pinfo _U___attribute__((unused)), const uint32_t id _U___attribute__((unused)), const void *data)
598{
599 return (void *)data;
600}
601
602static void oran_free_key(void *ptr _U___attribute__((unused)))
603{
604}
605
606static reassembly_table_functions oran_reassembly_table_functions =
607{
608 g_direct_hash,
609 g_direct_equal,
610 oran_key,
611 oran_key,
612 oran_free_key,
613 oran_free_key
614};
615
616static const fragment_items oran_frag_items = {
617 &ett_oran_fragment,
618 &ett_oran_fragments,
619 &hf_oran_fragments,
620 &hf_oran_fragment,
621 &hf_oran_fragment_overlap,
622 &hf_oran_fragment_overlap_conflict,
623 &hf_oran_fragment_multiple_tails,
624 &hf_oran_fragment_too_long_fragment,
625 &hf_oran_fragment_error,
626 &hf_oran_fragment_count,
627 &hf_oran_reassembled_in,
628 &hf_oran_reassembled_length,
629 &hf_oran_reassembled_data,
630 "O-RAN FH CUS fragments"
631};
632
633
634
635/* Don't want all extensions to open and close together. Use [extType-1] entry */
636static int ett_oran_c_section_extension[HIGHEST_EXTTYPE32];
637
638/* Expert info */
639static expert_field ei_oran_unsupported_bfw_compression_method;
640static expert_field ei_oran_invalid_sample_bit_width;
641static expert_field ei_oran_reserved_numBundPrb;
642static expert_field ei_oran_extlen_wrong;
643static expert_field ei_oran_invalid_eaxc_bit_width;
644static expert_field ei_oran_extlen_zero;
645static expert_field ei_oran_rbg_size_reserved;
646static expert_field ei_oran_frame_length;
647static expert_field ei_oran_numprbc_ext21_zero;
648static expert_field ei_oran_ci_prb_group_size_reserved;
649static expert_field ei_oran_st8_nackid;
650static expert_field ei_oran_st4_no_cmds;
651static expert_field ei_oran_st4_zero_len_cmd;
652static expert_field ei_oran_st4_wrong_len_cmd;
653static expert_field ei_oran_st4_unknown_cmd;
654static expert_field ei_oran_mcot_out_of_range;
655static expert_field ei_oran_se10_unknown_beamgrouptype;
656static expert_field ei_oran_se10_not_allowed;
657static expert_field ei_oran_start_symbol_id_not_zero;
658static expert_field ei_oran_trx_control_cmd_scope;
659static expert_field ei_oran_unhandled_se;
660static expert_field ei_oran_bad_symbolmask;
661static expert_field ei_oran_numslots_not_zero;
662static expert_field ei_oran_version_unsupported;
663static expert_field ei_oran_laa_msg_type_unsupported;
664static expert_field ei_oran_se_on_unsupported_st;
665static expert_field ei_oran_cplane_unexpected_sequence_number_ul;
666static expert_field ei_oran_cplane_unexpected_sequence_number_dl;
667static expert_field ei_oran_uplane_unexpected_sequence_number_ul;
668static expert_field ei_oran_uplane_unexpected_sequence_number_dl;
669static expert_field ei_oran_acknack_no_request;
670static expert_field ei_oran_udpcomphdr_should_be_zero;
671static expert_field ei_oran_radio_fragmentation_c_plane;
672static expert_field ei_oran_lastRbdid_out_of_range;
673static expert_field ei_oran_rbgMask_beyond_last_rbdid;
674static expert_field ei_oran_unexpected_measTypeId;
675static expert_field ei_oran_unsupported_compression_method;
676static expert_field ei_oran_ud_comp_len_wrong_size;
677static expert_field ei_oran_sresmask2_not_zero_with_rb;
678static expert_field ei_oran_st6_rb_shall_be_0;
679static expert_field ei_oran_st9_not_ul;
680static expert_field ei_oran_st10_numsymbol_not_14;
681static expert_field ei_oran_st10_startsymbolid_not_0;
682static expert_field ei_oran_st10_not_ul;
683static expert_field ei_oran_se24_nothing_to_inherit;
684static expert_field ei_oran_num_sinr_per_prb_unknown;
685static expert_field ei_oran_start_symbol_id_bits_ignored;
686static expert_field ei_oran_user_group_id_reserved_value;
687static expert_field ei_oran_port_list_index_zero;
688static expert_field ei_oran_ul_uplane_symbol_too_long;
689static expert_field ei_oran_reserved_not_zero;
690static expert_field ei_oran_too_many_symbols;
691static expert_field ei_oran_se30_not_ul;
692static expert_field ei_oran_se30_unknown_ueid;
693static expert_field ei_oran_beamid_bfws_not_found;
694static expert_field ei_oran_syminc_set_for_uplane;
695
696
697
698/* These are the message types handled by this dissector. Others have handling in packet-ecpri.c */
699#define ECPRI_MT_IQ_DATA0 0
700#define ECPRI_MT_RT_CTRL_DATA2 2
701
702
703/* Preference settings - try to set reasonable defaults */
704static unsigned pref_du_port_id_bits = 4;
705static unsigned pref_bandsector_id_bits = 4;
706static unsigned pref_cc_id_bits = 4;
707static unsigned pref_ru_port_id_bits = 4;
708
709/* TODO: ideally should be per-flow */
710static unsigned pref_sample_bit_width_uplink = 14;
711static unsigned pref_sample_bit_width_downlink = 14;
712static unsigned pref_sample_bit_width_sinr = 14;
713
714/* TODO: these ideally should be per-flow too */
715static int pref_iqCompressionUplink = COMP_BLOCK_FP1;
716static int pref_iqCompressionDownlink = COMP_BLOCK_FP1;
717
718static int pref_iqCompressionSINR = COMP_BLOCK_FP1;
719
720
721/* Is udCompHeader present (both directions) */
722static int pref_includeUdCompHeaderUplink = 2; /* start using heuristic */
723static int pref_includeUdCompHeaderDownlink = 2; /* start using heuristic */
724
725/* Are we ignoring UL C-Plane udCompHdr? */
726static bool_Bool pref_override_ul_compression = false0;
727
728static unsigned pref_data_plane_section_total_rbs = 273;
729static unsigned pref_num_bf_antennas = 32;
730static bool_Bool pref_showIQSampleValues = true1;
731
732/* Based upon m-plane param, so will be system-wide */
733static int pref_support_udcompLen = 2; /* start heuristic, can force other settings if necessary */
734static bool_Bool udcomplen_heuristic_result_set = false0;
735static bool_Bool udcomplen_heuristic_result = false0;
736
737/* st6-4byte-alignment-required */
738static bool_Bool st6_4byte_alignment = false0;
739
740/* Requested, allows I/Q to be stored as integers.. */
741static bool_Bool show_unscaled_values = false0;
742
743/* Initialized off. Timing is in microseconds. */
744static unsigned us_allowed_for_ul_in_symbol = 0;
745
746/* Reassemble U-Plane (at Radio Transport layer) */
747static bool_Bool do_radio_transport_layer_reassembly = true1;
748
749/* Link U-plane back to C-plane using sectionIds */
750static bool_Bool link_planes_together = true1;
751
752static const enum_val_t dl_compression_options[] = {
753 { "COMP_NONE", "No Compression", COMP_NONE0 },
754 { "COMP_BLOCK_FP", "Block Floating Point Compression", COMP_BLOCK_FP1 },
755 { "COMP_BLOCK_SCALE", "Block Scaling Compression", COMP_BLOCK_SCALE2 },
756 { "COMP_U_LAW", "u-Law Compression", COMP_U_LAW3 },
757 { "COMP_MODULATION", "Modulation Compression", COMP_MODULATION4 },
758 { "BFP_AND_SELECTIVE_RE", "Block Floating Point + selective RE sending", BFP_AND_SELECTIVE_RE5 },
759 { "MOD_COMPR_AND_SELECTIVE_RE", "Modulation Compression + selective RE sending", MOD_COMPR_AND_SELECTIVE_RE6 },
760 { "BFP_AND_SELECTIVE_RE_WITH_MASKS", "Block Floating Point + selective RE sending with masks in section header", BFP_AND_SELECTIVE_RE_WITH_MASKS7 },
761 { "MOD_COMPR_AND_SELECTIVE_RE_WITH_MASKS", "Modulation Compression + selective RE sending with masks in section header", MOD_COMPR_AND_SELECTIVE_RE6 },
762 { NULL((void*)0), NULL((void*)0), 0 }
763};
764
765/* No Modulation compression in UL.. */
766static const enum_val_t ul_compression_options[] = {
767 { "COMP_NONE", "No Compression", COMP_NONE0 },
768 { "COMP_BLOCK_FP", "Block Floating Point Compression", COMP_BLOCK_FP1 },
769 { "COMP_BLOCK_SCALE", "Block Scaling Compression", COMP_BLOCK_SCALE2 },
770 { "COMP_U_LAW", "u-Law Compression", COMP_U_LAW3 },
771 { "BFP_AND_SELECTIVE_RE", "Block Floating Point + selective RE sending", BFP_AND_SELECTIVE_RE5 },
772 { "BFP_AND_SELECTIVE_RE_WITH_MASKS", "Block Floating Point + selective RE sending with masks in section header", BFP_AND_SELECTIVE_RE_WITH_MASKS7 },
773 { NULL((void*)0), NULL((void*)0), 0 }
774};
775
776static const enum_val_t udcomplen_support_options[] = {
777 { "NOT_SUPPORTED", "Not Supported", 0 },
778 { "SUPPORTED", "Supported", 1 },
779 { "HEURISTIC", "Attempt Heuristic", 2 },
780 { NULL((void*)0), NULL((void*)0), 0 }
781};
782
783static const enum_val_t udcomphdr_present_options[] = {
784 { "NOT_PRESENT", "Not Present", 0 },
785 { "PRESENT", "Present", 1 },
786 { "HEURISTIC", "Attempt Heuristic", 2 },
787 { NULL((void*)0), NULL((void*)0), 0 }
788};
789
790
791
792static const value_string e_bit[] = {
793 { 0, "More fragments follow" },
794 { 1, "Last fragment" },
795 { 0, NULL((void*)0)}
796};
797
798#define DIR_UPLINK0 0
799#define DIR_DOWNLINK1 1
800
801
802static const value_string data_direction_vals[] = {
803 { DIR_UPLINK0, "Uplink" }, /* gNB Rx */
804 { DIR_DOWNLINK1, "Downlink" }, /* gNB Tx */
805 { 0, NULL((void*)0)}
806};
807
808static const value_string rb_vals[] = {
809 { 0, "Every RB used" },
810 { 1, "Every other RB used" },
811 { 0, NULL((void*)0)}
812};
813
814static const value_string sym_inc_vals[] = {
815 { 0, "Use the current symbol number" },
816 { 1, "Increment the current symbol number" },
817 { 0, NULL((void*)0)}
818};
819
820static const value_string lbtMode_vals[] = {
821 { 0, "Full LBT (regular LBT, sending reservation signal until the beginning of the SF/slot)" },
822 { 1, "Partial LBT (looking back 25 usec prior to transmission" },
823 { 2, "Partial LBT (looking back 34 usec prior to transmission" },
824 { 3, "Full LBT and stop (regular LBT, without sending reservation signal" },
825 { 0, NULL((void*)0)}
826};
827
828static const range_string filter_indices[] = {
829 {0, 0, "standard channel filter"},
830 {1, 1, "UL filter for PRACH preamble formats 0, 1, 2; min. passband 839 x 1.25kHz = 1048.75 kHz"},
831 {2, 2, "UL filter for PRACH preamble format 3, min. passband 839 x 5 kHz = 4195 kHz"},
832 {3, 3, "UL filter for PRACH preamble formats A1, A2, A3, B1, B2, B3, B4, C0, C2; min. passband 139 x \u0394fRA"},
833 {4, 4, "UL filter for NPRACH 0, 1; min. passband 48 x 3.75KHz = 180 KHz"},
834 {5, 5, "UL filter for PRACH preamble formats"},
835 {8, 8, "UL filter NPUSCH"},
836 {9, 9, "Mixed numerology and other channels except PRACH and NB-IoT"},
837 {9, 15, "Reserved"},
838 {0, 0, NULL((void*)0)}
839};
840
841/* 7.3.1-1 */
842static const range_string section_types[] = {
843 { SEC_C_UNUSED_RB, SEC_C_UNUSED_RB, "Unused Resource Blocks or symbols in Downlink or Uplink" },
844 { SEC_C_NORMAL, SEC_C_NORMAL, "Most DL/UL radio channels" },
845 { SEC_C_RSVD2, SEC_C_RSVD2, "Reserved for future use" },
846 { SEC_C_PRACH, SEC_C_PRACH, "PRACH and mixed-numerology channels" },
847 { SEC_C_SLOT_CONTROL, SEC_C_SLOT_CONTROL, "Slot Configuration Control" },
848 { SEC_C_UE_SCHED, SEC_C_UE_SCHED, "UE scheduling information (UE-ID assignment to section)" },
849 { SEC_C_CH_INFO, SEC_C_CH_INFO, "Channel information" },
850 { SEC_C_LAA, SEC_C_LAA, "LAA (License Assisted Access)" },
851 { SEC_C_ACK_NACK_FEEDBACK, SEC_C_ACK_NACK_FEEDBACK, "ACK/NACK Feedback" },
852 { SEC_C_SINR_REPORTING, SEC_C_SINR_REPORTING, "SINR Reporting" },
853 { SEC_C_RRM_MEAS_REPORTS, SEC_C_RRM_MEAS_REPORTS, "RRM Measurement Reports" },
854 { SEC_C_REQUEST_RRM_MEAS, SEC_C_REQUEST_RRM_MEAS, "Request RRM Measurements" },
855 { 12, 255, "Reserved for future use" },
856 { 0, 0, NULL((void*)0)} };
857
858static const range_string section_types_short[] = {
859 { SEC_C_UNUSED_RB, SEC_C_UNUSED_RB, "(Unused RBs) " },
860 { SEC_C_NORMAL, SEC_C_NORMAL, "(Most channels) " },
861 { SEC_C_RSVD2, SEC_C_RSVD2, "(reserved) " },
862 { SEC_C_PRACH, SEC_C_PRACH, "(PRACH/mixed-\u03bc)" },
863 { SEC_C_SLOT_CONTROL, SEC_C_SLOT_CONTROL, "(Slot info) " },
864 { SEC_C_UE_SCHED, SEC_C_UE_SCHED, "(UE scheduling info)" },
865 { SEC_C_CH_INFO, SEC_C_CH_INFO, "(Channel info) " },
866 { SEC_C_LAA, SEC_C_LAA, "(LAA) " },
867 { SEC_C_ACK_NACK_FEEDBACK, SEC_C_ACK_NACK_FEEDBACK, "(ACK/NACK) " },
868 { SEC_C_SINR_REPORTING, SEC_C_SINR_REPORTING, "(SINR Reporting) " },
869 { SEC_C_RRM_MEAS_REPORTS, SEC_C_RRM_MEAS_REPORTS, "(RRM Meas Reports) " },
870 { SEC_C_REQUEST_RRM_MEAS, SEC_C_REQUEST_RRM_MEAS, "(Req RRM Meas) " },
871 { 12, 255, "Reserved for future use" },
872 { 0, 0, NULL((void*)0) }
873};
874
875static const range_string ud_comp_header_width[] = {
876 {0, 0, "I and Q are each 16 bits wide"},
877 {1, 15, "Bit width of I and Q"},
878 {0, 0, NULL((void*)0)} };
879
880/* Table 8.3.3.13-3 */
881static const range_string ud_comp_header_meth[] = {
882 {COMP_NONE0, COMP_NONE0, "No compression" },
883 {COMP_BLOCK_FP1, COMP_BLOCK_FP1, "Block floating point compression" },
884 {COMP_BLOCK_SCALE2, COMP_BLOCK_SCALE2, "Block scaling" },
885 {COMP_U_LAW3, COMP_U_LAW3, "Mu - law" },
886 {COMP_MODULATION4, COMP_MODULATION4, "Modulation compression" },
887 {BFP_AND_SELECTIVE_RE5, BFP_AND_SELECTIVE_RE5, "BFP + selective RE sending" },
888 {MOD_COMPR_AND_SELECTIVE_RE6, MOD_COMPR_AND_SELECTIVE_RE6, "mod-compr + selective RE sending" },
889 {BFP_AND_SELECTIVE_RE_WITH_MASKS7, BFP_AND_SELECTIVE_RE_WITH_MASKS7, "BFP + selective RE sending with masks in section header" },
890 {MOD_COMPR_AND_SELECTIVE_RE_WITH_MASKS8, MOD_COMPR_AND_SELECTIVE_RE_WITH_MASKS8, "mod-compr + selective RE sending with masks in section header"},
891 {9, 15, "Reserved"},
892 {0, 0, NULL((void*)0)}
893};
894
895/* Table 7.5.2.13-2 */
896static const range_string frame_structure_fft[] = {
897 {0, 0, "Reserved (no FFT/iFFT processing)"},
898 {1, 3, "Reserved"},
899 {4, 4, "FFT size 16"},
900 {5, 5, "FFT size 32"},
901 {6, 6, "FFT size 64"},
902 {7, 7, "FFT size 128"},
903 {8, 8, "FFT size 256"},
904 {9, 9, "FFT size 512"},
905 {10, 10, "FFT size 1024"},
906 {11, 11, "FFT size 2048"},
907 {12, 12, "FFT size 4096"},
908 {13, 13, "FFT size 1536"},
909 {14, 14, "FFT size 3072"},
910 {15, 15, "Reserved"},
911 {0, 0, NULL((void*)0)}
912};
913
914/* Table 7.5.2.13-3 */
915static const range_string subcarrier_spacings[] = {
916 { 0, 0, "SCS 15 kHz, 1 slot/subframe, slot length 1 ms" },
917 { 1, 1, "SCS 30 kHz, 2 slots/subframe, slot length 500 \u03bcs" },
918 { 2, 2, "SCS 60 kHz, 4 slots/subframe, slot length 250 \u03bcs" },
919 { 3, 3, "SCS 120 kHz, 8 slots/subframe, slot length 125 \u03bcs" },
920 { 4, 4, "SCS 240 kHz, 16 slots/subframe, slot length 62.5 \u03bcs" },
921 { 5, 11, "Reserved" }, /* N.B., 5 was 480kHz in early spec versions */
922 { 12, 12, "SCS 1.25 kHz, 1 slot/subframe, slot length 1 ms" },
923 { 13, 13, "SCS 3.75 kHz(LTE - specific), 1 slot/subframe, slot length 1 ms" },
924 { 14, 14, "SCS 5 kHz, 1 slot/subframe, slot length 1 ms" },
925 { 15, 15, "SCS 7.5 kHz(LTE - specific), 1 slot/subframe, slot length 1 ms" },
926 { 0, 0, NULL((void*)0) }
927};
928
929/* Table 7.5.3.14-1 laaMsgType definition */
930static const range_string laaMsgTypes[] = {
931 {0, 0, "LBT_PDSCH_REQ - lls - O-DU to O-RU request to obtain a PDSCH channel"},
932 {1, 1, "LBT_DRS_REQ - lls - O-DU to O-RU request to obtain the channel and send DRS"},
933 {2, 2, "LBT_PDSCH_RSP - O-RU to O-DU response, channel acq success or failure"},
934 {3, 3, "LBT_DRS_RSP - O-RU to O-DU response, DRS sending success or failure"},
935 {4, 4, "LBT_Buffer_Error - O-RU to O-DU response, reporting buffer overflow"},
936 {5, 5, "LBT_CWCONFIG_REQ - O-DU to O-RU request, congestion window configuration"},
937 {6, 6, "LBT_CWCONFIG_RST - O-RU to O-DU request, congestion window config, response"},
938 {7, 15, "reserved for future methods"},
939 {0, 0, NULL((void*)0)}
940};
941
942/* 7.7.26.3 */
943static const range_string freq_offset_fb_values[] = {
944 {0, 0, "no frequency offset"},
945 {8000, 8000, "value not provided"},
946 {1, 30000, "positive frequency offset, (0, +0.5] subcarrier"},
947 {0x8ad0, 0xffff, "negative frequency offset, [-0.5, 0) subcarrier"},
948 {0x0, 0xffff, "reserved"},
949 {0, 0, NULL((void*)0)}
950};
951
952/* Table 7.5.2.19-1 */
953static const value_string num_sinr_per_prb_vals[] = {
954 { 0, "1" },
955 { 1, "2" },
956 { 2, "3" },
957 { 3, "4" },
958 { 4, "6" },
959 { 5, "12" },
960 { 6, "1 SINR value per section for DFT-s-OFDM" },
961 { 7, "reserved" },
962 { 0, NULL((void*)0)}
963};
964
965static const value_string meas_type_id_vals[] = {
966 { 1, "UE Timing Advance Error" },
967 { 2, "UE Layer power" },
968 { 3, "UE frequency offset" },
969 { 4, "Interference plus Noise for allocated PRBs" },
970 { 5, "Interference plus Noise for unallocated PRBs" },
971 { 6, "DMRS-SNR per antenna" },
972 { 7, "UE positioning measurement report" },
973 { 8, "UE radial speed measurement report" },
974 { 9, "UE post-equalization MU inteference measurement" },
975 { 10, "UE TPMI and rank recommendation measurement" },
976 { 11, "UE layer pre-equalization SINR report" },
977 { 0, NULL((void*)0)}
978};
979
980static const value_string beam_type_vals[] = {
981 { 0, "List of beamId values" },
982 { 1, "Range of beamId values" },
983 { 0, NULL((void*)0)}
984};
985
986/* 7.7.24.3 */
987static const value_string entry_type_vals[] = {
988 { 0, "inherit config from preceding entry (2 or 3) ueIdReset=0" },
989 { 1, "inherit config from preceding entry (2 or 3) ueIdReset=1" },
990 { 2, "related parameters if have transform precoding disabled " },
991 { 3, "related parameters if have transform precoding enabled " },
992 { 0, NULL((void*)0)}
993};
994
995/* Table 7.7.29.3-1 */
996static const range_string cd_scg_size_vals[] = {
997 { 0, 0, "1 subcarrier" },
998 { 1, 1, "1 RB x N subcarriers" },
999 { 2, 2, "2 RB x N subcarriers" },
1000 { 3, 3, "4 RB x N subcarriers" },
1001 { 4, 4, "8 RB x N subcarriers" },
1002 { 5, 5, "16 RB x N subcarriers" },
1003 { 6, 6, "32 RB x N subcarriers" },
1004 { 7, 15, "reserved"},
1005 { 0, 0, NULL((void*)0)}
1006};
1007
1008
1009/* Table 7.6.1-1 */
1010static const value_string exttype_vals[] = {
1011 {0, "Reserved"},
1012 {1, "Beamforming weights"},
1013 {2, "Beamforming attributes"},
1014 {3, "DL Precoding configuration parameters and indications"},
1015 {4, "Modulation compr. params"},
1016 {5, "Modulation compression additional scaling parameters"},
1017 {6, "Non-contiguous PRB allocation"},
1018 {7, "Multiple-eAxC designation"},
1019 {8, "Regularization factor"},
1020 {9, "Dynamic Spectrum Sharing parameters"},
1021 {10, "Multiple ports grouping"},
1022 {11, "Flexible BF weights"},
1023 {12, "Non-Contiguous PRB Allocation with Frequency Ranges"},
1024 {13, "PRB Allocation with Frequency Hopping"},
1025 {14, "Nulling-layer Info. for ueId-based beamforming"},
1026 {15, "Mixed-numerology Info. for ueId-based beamforming"},
1027 {16, "Section description for antenna mapping in UE channel information based UL beamforming"},
1028 {17, "Section description for indication of user port group"},
1029 {18, "Section description for Uplink Transmission Management"},
1030 {19, "Compact beamforming information for multiple port"},
1031 {20, "Puncturing extension"},
1032 {21, "Variable PRB group size for channel information"},
1033 {22, "ACK/NACK request"},
1034 {23, "Multiple symbol modulation compression parameters"},
1035 {24, "PUSCH DMRS configuration"},
1036 {25, "Symbol reordering for DMRS-BF"},
1037 {26, "Frequency offset feedback"},
1038 {27, "O-DU controlled dimensionality reduction"},
1039 {28, "O-DU controlled frequency resolution for SINR reporting"},
1040 {29, "Cyclic delay adjustment"},
1041 {30, "PUSCH repetition indication"},
1042 {31, "MCS Information"},
1043 {32, "Rank and TPMI measurement request"},
1044 {0, NULL((void*)0)}
1045};
1046static value_string_ext exttype_vals_ext = VALUE_STRING_EXT_INIT(exttype_vals){ _try_val_to_str_ext_init, 0, (sizeof (exttype_vals) / sizeof
((exttype_vals)[0]))-1, exttype_vals, "exttype_vals", ((void
*)0) }
;
1047
1048
1049/**************************************************************************************/
1050/* Keep track for each Section Extension, which section types are allowed to carry it */
1051typedef struct {
1052 bool_Bool ST0;
1053 bool_Bool ST1;
1054 bool_Bool ST3;
1055 bool_Bool ST5;
1056 bool_Bool ST6;
1057 bool_Bool ST10;
1058 bool_Bool ST11;
1059} AllowedCTs_t;
1060
1061
1062static const AllowedCTs_t ext_cts[HIGHEST_EXTTYPE32] = {
1063 /* ST0 ST1 ST3 ST5 ST6 ST10 ST11 */
1064 { false0, true1, true1, false0, false0, false0, false0}, // SE 1 (1,3)
1065 { false0, true1, true1, false0, false0, false0, false0}, // SE 2 (1,3)
1066 { false0, true1, true1, false0, false0, false0, false0}, // SE 3 (1,3)
1067 { false0, true1, true1, true1, false0, false0, false0}, // SE 4 (1,3,5)
1068 { false0, true1, true1, true1, false0, false0, false0}, // SE 5 (1,3,5)
1069 { false0, true1, true1, true1, false0, true1, true1 }, // SE 6 (1,3,5,10,11)
1070 { true1, false0, false0, false0, false0, false0, false0}, // SE 7 (0)
1071 { false0, false0, false0, true1, false0, false0, false0}, // SE 8 (5)
1072 { true1, true1, true1, true1, true1, true1, true1 }, // SE 9 (all)
1073 { false0, true1, true1, true1, false0, false0, false0}, // SE 10 (1,3,5)
1074 { false0, true1, true1, false0, false0, false0, false0}, // SE 11 (1,3)
1075 { false0, true1, true1, true1, false0, true1, true1 }, // SE 12 (1,3,5,10,11)
1076 { false0, true1, true1, true1, false0, false0, false0}, // SE 13 (1,3,5)
1077 { false0, false0, false0, true1, false0, false0, false0}, // SE 14 (5)
1078 { false0, false0, false0, true1, true1, false0, false0}, // SE 15 (5,6)
1079 { false0, false0, false0, true1, false0, false0, false0}, // SE 16 (5)
1080 { false0, false0, false0, true1, false0, false0, false0}, // SE 17 (5)
1081 { false0, true1, true1, true1, false0, false0, false0}, // SE 18 (1,3,5)
1082 { false0, true1, true1, false0, false0, false0, false0}, // SE 19 (1,3)
1083 { true1, true1, true1, true1, true1, true1, true1 }, // SE 20 (0,1,3,5,10,11)
1084 { false0, false0, false0, true1, true1, false0, false0}, // SE 21 (5,6)
1085 { true1, true1, true1, true1, true1, true1, true1 }, // SE 22 (all)
1086 { false0, true1, true1, true1, false0, false0, false0}, // SE 23 (1,3,5)
1087 { false0, false0, false0, true1, false0, false0, false0}, // SE 24 (5)
1088 { false0, false0, false0, true1, false0, false0, false0}, // SE 25 (5)
1089 { false0, false0, false0, true1, false0, false0, false0}, // SE 26 (5)
1090 { false0, false0, false0, true1, false0, false0, false0}, // SE 27 (5)
1091 { false0, false0, false0, true1, false0, false0, false0}, // SE 28 (5)
1092 { false0, true1, true1, true1, false0, false0, false0}, // SE 29 (1,3,5)
1093 { false0, false0, false0, true1, false0, false0, false0}, // SE 30 (5)
1094 { false0, true1, true1, true1, false0, false0, false0}, // SE 31 (1,3,5)
1095 { false0, false0, false0, true1, false0, false0, false0}, // SE 32 (5)
1096};
1097
1098static bool_Bool se_allowed_in_st(unsigned se, unsigned st)
1099{
1100 if (se==0 || se>HIGHEST_EXTTYPE32) {
1101 /* Don't know about new SE, so don't complain.. */
1102 return true1;
1103 }
1104
1105 switch (st) {
1106 case 0:
1107 return ext_cts[se-1].ST0;
1108 case 1:
1109 return ext_cts[se-1].ST1;
1110 case 3:
1111 return ext_cts[se-1].ST3;
1112 case 5:
1113 return ext_cts[se-1].ST5;
1114 case 6:
1115 return ext_cts[se-1].ST6;
1116 case 10:
1117 return ext_cts[se-1].ST10;
1118 case 11:
1119 return ext_cts[se-1].ST11;
1120 default:
1121 /* New/unknown section type that includes 'ef'.. assume ok */
1122 return true1;
1123 }
1124}
1125
1126/************************************************************************************/
1127
1128/* Table 7.7.1.2-2 */
1129static const value_string bfw_comp_headers_iq_width[] = {
1130 {0, "I and Q are 16 bits wide"},
1131 {1, "I and Q are 1 bit wide"},
1132 {2, "I and Q are 2 bits wide"},
1133 {3, "I and Q are 3 bits wide"},
1134 {4, "I and Q are 4 bits wide"},
1135 {5, "I and Q are 5 bits wide"},
1136 {6, "I and Q are 6 bits wide"},
1137 {7, "I and Q are 7 bits wide"},
1138 {8, "I and Q are 8 bits wide"},
1139 {9, "I and Q are 9 bits wide"},
1140 {10, "I and Q are 10 bits wide"},
1141 {11, "I and Q are 11 bits wide"},
1142 {12, "I and Q are 12 bits wide"},
1143 {13, "I and Q are 13 bits wide"},
1144 {14, "I and Q are 14 bits wide"},
1145 {15, "I and Q are 15 bits wide"},
1146 {0, NULL((void*)0)}
1147};
1148
1149/* Table 7.7.1.2-3 */
1150static const value_string bfw_comp_headers_comp_meth[] = {
1151 {COMP_NONE0, "no compression"},
1152 {COMP_BLOCK_FP1, "block floating point"},
1153 {COMP_BLOCK_SCALE2, "block scaling"},
1154 {COMP_U_LAW3, "u-law"},
1155 {4, "beamspace compression type I"},
1156 {5, "beamspace compression type II"},
1157 {0, NULL((void*)0)}
1158};
1159
1160/* 7.7.6.2 rbgSize (resource block group size) */
1161static const value_string rbg_size_vals[] = {
1162 {0, "reserved"},
1163 {1, "1"},
1164 {2, "2"},
1165 {3, "3"},
1166 {4, "4"},
1167 {5, "6"},
1168 {6, "8"},
1169 {7, "16"},
1170 {0, NULL((void*)0)}
1171};
1172
1173/* 7.7.6.5 */
1174static const value_string priority_vals[] = {
1175 {0, "0"},
1176 {1, "+1"},
1177 {2, "-2 (reserved, should not be used)"},
1178 {3, "-1"},
1179 {0, NULL((void*)0)}
1180};
1181
1182/* 7.7.10.2 beamGroupType */
1183static const value_string beam_group_type_vals[] = {
1184 {0x0, "common beam"},
1185 {0x1, "beam matrix indication"},
1186 {0x2, "beam vector listing"},
1187 {0x3, "beamId/ueId listing with associated port-list index"},
1188 {0, NULL((void*)0)}
1189};
1190
1191/* 7.7.9.2 technology (interface name) */
1192static const value_string interface_name_vals[] = {
1193 {0x0, "LTE"},
1194 {0x1, "NR"},
1195 {0, NULL((void*)0)}
1196};
1197
1198/* 7.7.18.4 toT (type of transmission) */
1199static const value_string type_of_transmission_vals[] = {
1200 {0x0, "normal transmission mode, data can be distributed in any way the O-RU is implemented to transmit data"},
1201 {0x1, "uniformly distributed over the transmission window"},
1202 {0x2, "Reserved"},
1203 {0x3, "Reserved"},
1204 {0, NULL((void*)0)}
1205};
1206
1207/* 7.7.2.2 (width of bfa parameters) */
1208static const value_string bfa_bw_vals[] = {
1209 {0, "no bits, the field is not applicable (e.g., O-RU does not support it) or the default value shall be used"},
1210 {1, "2-bit bitwidth"},
1211 {2, "3-bit bitwidth"},
1212 {3, "4-bit bitwidth"},
1213 {4, "5-bit bitwidth"},
1214 {5, "6-bit bitwidth"},
1215 {6, "7-bit bitwidth"},
1216 {7, "8-bit bitwidth"},
1217 {0, NULL((void*)0)}
1218};
1219
1220/* 7.7.2.7 & 7.7.2.8 */
1221static const value_string sidelobe_suppression_vals[] = {
1222 {0, "10 dB"},
1223 {1, "15 dB"},
1224 {2, "20 dB"},
1225 {3, "25 dB"},
1226 {4, "30 dB"},
1227 {5, "35 dB"},
1228 {6, "40 dB"},
1229 {7, ">= 45 dB"},
1230 {0, NULL((void*)0)}
1231};
1232
1233static const value_string lbtTrafficClass_vals[] = {
1234 {1, "Priority 1"},
1235 {2, "Priority 2"},
1236 {3, "Priority 3"},
1237 {4, "Priority 4"},
1238 {0, NULL((void*)0)}
1239};
1240
1241/* 7.5.3.22 */
1242static const value_string lbtPdschRes_vals[] = {
1243 {0, "not sensing – indicates that the O-RU is transmitting data"},
1244 {1, "currently sensing – indicates the O-RU has not yet acquired the channel"},
1245 {2, "success – indicates that the channel was successfully acquired"},
1246 {3, "Failure – indicates expiration of the LBT timer. The LBT process should be reset"},
1247 {0, NULL((void*)0)}
1248};
1249
1250/* Table 7.5.2.15-3 */
1251static const value_string ci_comp_opt_vals[] = {
1252 {0, "compression per UE, one ciCompParam exists before the I/Q value of each UE"},
1253 {1, "compression per PRB, one ciCompParam exists before the I/Q value of each PRB"},
1254 {0, NULL((void*)0)}
1255};
1256
1257/* 7.5.2.17 */
1258static const range_string cmd_scope_vals[] = {
1259 {0, 0, "ARRAY-COMMAND"},
1260 {1, 1, "CARRIER-COMMAND"},
1261 {2, 2, "O-RU-COMMAND"},
1262 {3, 15, "reserved"},
1263 {0, 0, NULL((void*)0)}
1264};
1265
1266/* N.B., table in 7.5.3.38 is truncated.. */
1267static const range_string st4_cmd_type_vals[] = {
1268 {0, 0, "reserved for future command types"},
1269 {1, 1, "TIME_DOMAIN_BEAM_CONFIG"},
1270 {2, 2, "TDD_CONFIG_PATTERN"},
1271 {3, 3, "TRX_CONTROL"},
1272 {4, 4, "ASM"},
1273 {5, 5, "TRX_CONTROL_BIDIR"},
1274 {6, 255, "reserved for future command types"},
1275 {0, 0, NULL((void*)0)}
1276};
1277
1278/* Table 7.5.3.51-1 */
1279static const value_string log2maskbits_vals[] = {
1280 {0, "reserved"},
1281 {1, "min antMask size is 16 bits.."},
1282 {2, "min antMask size is 16 bits.."},
1283 {3, "min antMask size is 16 bits.."},
1284 {4, "16 bits"},
1285 {5, "32 bits"},
1286 {6, "64 bits"},
1287 {7, "128 bits"},
1288 {8, "256 bits"},
1289 {9, "512 bits"},
1290 {10, "1024 bits"},
1291 {11, "2048 bits"},
1292 {12, "4096 bits"},
1293 {13, "8192 bits"},
1294 {14, "16384 bits"},
1295 {15, "reserved"},
1296 {0, NULL((void*)0)}
1297};
1298
1299/* Table 16.1-1 Sleep modes */
1300static const value_string sleep_mode_trx_vals[] = {
1301 { 0, "TRXC-mode0-wake-up-duration (symbol)"},
1302 { 1, "TRXC-mode1-wake-up-duration (L)"},
1303 { 2, "TRXC-mode2-wake-up-duration (M)"},
1304 { 3, "TRXC-mode3-wake-up-duration (N)"},
1305 { 0, NULL((void*)0)}
1306};
1307
1308static const value_string sleep_mode_asm_vals[] = {
1309 { 0, "ASM-mode0-wake-up-duration (symbol)"},
1310 { 1, "ASM-mode1-wake-up-duration (L)"},
1311 { 2, "ASM-mode2-wake-up-duration (M)"},
1312 { 3, "ASM-mode3-wake-up-duration (N)"},
1313 { 0, NULL((void*)0)}
1314};
1315
1316/* 7.7.21.3.1 */
1317static const value_string prg_size_st5_vals[] = {
1318 { 0, "reserved"},
1319 { 1, "Precoding resource block group size as WIDEBAND"},
1320 { 2, "Precoding resource block group size 2"},
1321 { 3, "Precoding resource block group size 4"},
1322 { 0, NULL((void*)0)}
1323};
1324
1325/* 7.7.21.3.2 */
1326static const value_string prg_size_st6_vals[] = {
1327 { 0, "if ciPrbGroupSize is 2 or 4, then ciPrbGroupSize, else WIDEBAND"},
1328 { 1, "Precoding resource block group size as WIDEBAND"},
1329 { 2, "Precoding resource block group size 2"},
1330 { 3, "Precoding resource block group size 4"},
1331 { 0, NULL((void*)0)}
1332};
1333
1334/* 7.7.24.4 */
1335static const value_string alpn_per_sym_vals[] = {
1336 { 0, "report one allocated IPN value per all allocated symbols with DMRS"},
1337 { 1, "report one allocated IPN value per group of consecutive DMRS symbols"},
1338 { 0, NULL((void*)0)}
1339};
1340
1341/* 7.7.24.5 */
1342static const value_string ant_dmrs_snr_vals[] = {
1343 { 0, "O-RU shall not report the MEAS_ANT_DMRS_SNR"},
1344 { 1, "O-RU shall report the MEAS_ANT_DMRS_SNR"},
1345 { 0, NULL((void*)0)}
1346};
1347
1348/* 7.7.24.14 */
1349static const value_string dtype_vals[] = {
1350 { 0, "assume DMRS configuration type 1"},
1351 { 1, "assume DMRS configuration type 2"},
1352 { 0, NULL((void*)0)}
1353};
1354
1355/* 7.7.24.17 */
1356static const value_string papr_type_vals[] = {
1357 { 0, "sequence generator type 1 for short sequence lengths"},
1358 { 1, "sequence generator type 1 for long sequence lengths"},
1359 { 2, "sequence generator type 2 for short sequence lengths"},
1360 { 3, "sequence generator type 2 for long sequence lengths"},
1361 { 0, NULL((void*)0)}
1362};
1363
1364/* 7.7.24.18 */
1365static const value_string hopping_mode_vals[] = {
1366 { 0, "neither group, nor sequence hopping is enabled"},
1367 { 1, "group hopping is enabled and sequence hopping is disabled"},
1368 { 2, "sequence hopping is enabled and group hopping is disabled"},
1369 { 3, "reserved"},
1370 { 0, NULL((void*)0)}
1371};
1372
1373
1374static const true_false_string tfs_sfStatus =
1375{
1376 "subframe was transmitted",
1377 "subframe was dropped"
1378};
1379
1380static const true_false_string tfs_lbtBufErr =
1381{
1382 "buffer overflow – data received at O-RU is larger than the available buffer size",
1383 "reserved"
1384};
1385
1386static const true_false_string tfs_partial_full_sf = {
1387 "partial SF",
1388 "full SF"
1389};
1390
1391static const true_false_string disable_tdbfns_tfs = {
1392 "beam numbers excluded",
1393 "beam numbers included"
1394};
1395
1396static const true_false_string continuity_indication_tfs = {
1397 "continuity between current and next bundle",
1398 "discontinuity between current and next bundle"
1399};
1400
1401static const true_false_string prb_mode_tfs = {
1402 "PRB-BLOCK mode",
1403 "PRB-MASK mode"
1404};
1405
1406static const true_false_string symbol_direction_tfs = {
1407 "DL symbol",
1408 "UL symbol"
1409};
1410
1411static const true_false_string symbol_guard_tfs = {
1412 "guard symbol",
1413 "non-guard symbol"
1414};
1415
1416static const true_false_string beam_numbers_included_tfs = {
1417 "time-domain beam numbers excluded in this command",
1418 "time-domain beam numbers included in this command"
1419};
1420
1421static const true_false_string measurement_flag_tfs = {
1422 "at least one additional measurement report or command after the current one",
1423 "no additional measurement report or command"
1424};
1425
1426static const true_false_string repetition_se6_tfs = {
1427 "repeated highest priority data section in the C-Plane message",
1428 "no repetition"
1429};
1430
1431static const true_false_string repetition_se19_tfs = {
1432 "per port information not present in the extension",
1433 "per port info present in the extension"
1434};
1435
1436static const true_false_string tfs_report_no_report_pos_meas =
1437{
1438 "Report MEAS_UE_POS for UE",
1439 "Do not report UE_POS for UE"
1440};
1441
1442
1443/* Forward declaration */
1444static int dissect_udcompparam(tvbuff_t *tvb, packet_info *pinfo _U___attribute__((unused)), proto_tree *tree, unsigned offset,
1445 unsigned comp_meth,
1446 uint32_t *exponent, uint16_t *sReSMask, bool_Bool for_sinr);
1447
1448
1449static const true_false_string ready_tfs = {
1450 "message is a \"ready\" message",
1451 "message is a ACK message"
1452};
1453
1454static const true_false_string multi_sd_scope_tfs = {
1455 "Puncturing pattern applies to current and following sections",
1456 "Puncturing pattern applies to current section"
1457};
1458
1459static const true_false_string tfs_ueid_reset = {
1460 "cannot assume same UE as in preceding slot",
1461 "can assume same UE as in preceding slot"
1462};
1463
1464
1465/* Config for (and later, worked-out allocations) bundles for ext11 (dynamic BFW) */
1466typedef struct {
1467 /* Ext 6 config */
1468 bool_Bool ext6_set;
1469 uint8_t ext6_rbg_size; /* number of PRBs allocated by bitmask */
1470
1471 uint8_t ext6_num_bits_set;
1472 uint8_t ext6_bits_set[28]; /* Which bit position this entry has */
1473 /* TODO: store an f value for each bit position? */
1474
1475 /* Ext 12 config */
1476 bool_Bool ext12_set;
1477 unsigned ext12_num_pairs;
1478#define MAX_BFW_EXT12_PAIRS128 128
1479 struct {
1480 uint8_t off_start_prb;
1481 uint8_t num_prb;
1482 } ext12_pairs[MAX_BFW_EXT12_PAIRS128];
1483
1484 /* Ext 13 config */
1485 bool_Bool ext13_set;
1486 unsigned ext13_num_start_prbs;
1487#define MAX_BFW_EXT13_ALLOCATIONS128 128
1488 unsigned ext13_start_prbs[MAX_BFW_EXT13_ALLOCATIONS128];
1489 /* TODO: store nextSymbolId here too? */
1490
1491 /* Ext 21 config */
1492 bool_Bool ext21_set;
1493 uint8_t ext21_ci_prb_group_size;
1494
1495 /* Results/settings (after calling ext11_work_out_bundles()) */
1496 uint32_t num_bundles;
1497#define MAX_BFW_BUNDLES512 512
1498 struct {
1499 uint32_t start; /* first prb of bundle */
1500 uint32_t end; /* last prb of bundle*/
1501 bool_Bool is_orphan; /* true if not complete (i.e., end-start < numBundPrb) */
1502 } bundles[MAX_BFW_BUNDLES512];
1503} ext11_settings_t;
1504
1505
1506/* Work out bundle allocation for ext 11. Take into account ext6/ext21, ext12 or ext13 in this section before ext 11. */
1507/* Won't be called with numBundPrb=0 */
1508static void ext11_work_out_bundles(unsigned startPrbc,
1509 unsigned numPrbc,
1510 unsigned numBundPrb, /* number of PRBs per (full) bundle */
1511 ext11_settings_t *settings)
1512{
1513 /* Allocation configured by ext 6 */
1514 if (settings->ext6_set) {
1515 unsigned bundles_per_entry = (settings->ext6_rbg_size / numBundPrb);
1516
1517 /* Need to cope with these not dividing exactly, or even having more PRbs in a bundle that
1518 rbg size. i.e. each bundle gets the correct number of PRBs until
1519 all rbg entries are consumed... */
1520
1521 /* TODO: need to check 7.9.4.2. Different cases depending upon value of RAD */
1522
1523 if (bundles_per_entry == 0) {
1524 bundles_per_entry = 1;
1525 }
1526
1527 /* Ext6 behaviour may also be affected by ext 21 */
1528 if (settings->ext21_set) {
1529 /* N.B., have already checked that numPrbc is not 0 */
1530
1531 /* ciPrbGroupSize overrides number of contiguous PRBs in group */
1532 bundles_per_entry = (settings->ext6_rbg_size / settings->ext21_ci_prb_group_size);
1533
1534 /* numPrbc is the number of PRB groups per antenna - handled in call to dissect_bfw_bundle() */
1535 }
1536
1537 unsigned bundles_set = 0;
1538 bool_Bool reached_orphan = false0;
1539 /* For each bit set in ext6 rbg mask.. */
1540 for (unsigned n=0;
1541 !reached_orphan && n < (settings->ext6_num_bits_set * settings->ext6_rbg_size) / numBundPrb;
1542 n++) {
1543
1544 /* Watch out for array bound */
1545 if (n >= 28) {
1546 break;
1547 }
1548
1549 /* For each bundle... */
1550
1551 /* TODO: Work out where first PRB is */
1552 /* May not be the start of an rbg block... */
1553 uint32_t prb_start = (settings->ext6_bits_set[n] * settings->ext6_rbg_size);
1554
1555 /* For each bundle within identified rbgSize block */
1556 for (unsigned m=0; !reached_orphan && m < bundles_per_entry; m++) {
1557
1558 settings->bundles[bundles_set].start = startPrbc+prb_start+(m*numBundPrb);
1559
1560 /* Start already beyond end, so doesn't count. */
1561 if (settings->bundles[bundles_set].start > (startPrbc+numPrbc-1)) {
1562 settings->num_bundles = bundles_set;
1563 return;
1564 }
1565
1566 /* Bundle consists of numBundPrb bundles */
1567 /* TODO: may involve PRBs from >1 rbg blocks.. */
1568 settings->bundles[bundles_set].end = startPrbc+prb_start+((m+1)*numBundPrb)-1;
1569 if (settings->bundles[bundles_set].end > (startPrbc+numPrbc-1)) {
1570 /* Extends beyond end, so counts but is an orphan bundle */
1571 settings->bundles[bundles_set].end = startPrbc+numPrbc-1;
1572 settings->bundles[bundles_set].is_orphan = true1;
1573 reached_orphan = true1;
1574 }
1575
1576 /* Get out if have reached array bound */
1577 if (++bundles_set == MAX_BFW_BUNDLES512) {
1578 return;
1579 }
1580 }
1581 }
1582 settings->num_bundles = bundles_set;
1583 }
1584
1585 /* Allocation configured by ext 12 */
1586 else if (settings->ext12_set) {
1587 /* First, allocate normally from startPrbc, numPrbc */
1588 settings->num_bundles = (numPrbc+numBundPrb-1) / numBundPrb;
1589
1590 /* Don't overflow settings->bundles[] ! */
1591 settings->num_bundles = MIN(MAX_BFW_BUNDLES, settings->num_bundles)(((512) < (settings->num_bundles)) ? (512) : (settings->
num_bundles))
;
1592
1593 for (uint32_t n=0; n < settings->num_bundles; n++) {
1594 settings->bundles[n].start = startPrbc + n*numBundPrb;
1595 settings->bundles[n].end = settings->bundles[n].start + numBundPrb-1;
1596 /* Does it go beyond the end? */
1597 if (settings->bundles[n].end > startPrbc+numPrbc) {
1598 settings->bundles[n].end = startPrbc+numPrbc;
1599 settings->bundles[n].is_orphan = true1;
1600 }
1601 }
1602 if (settings->num_bundles == MAX_BFW_BUNDLES512) {
1603 return;
1604 }
1605
1606 unsigned prb_offset = startPrbc + numPrbc;
1607
1608 /* Loop over pairs, adding bundles for each */
1609 for (unsigned p=0; p < settings->ext12_num_pairs; p++) {
1610 prb_offset += settings->ext12_pairs[p].off_start_prb;
1611 unsigned pair_bundles = (settings->ext12_pairs[p].num_prb+numBundPrb-1) / numBundPrb;
1612
1613 for (uint32_t n=0; n < pair_bundles; n++) {
1614 unsigned idx = settings->num_bundles;
1615
1616 settings->bundles[idx].start = prb_offset + n*numBundPrb;
1617 settings->bundles[idx].end = settings->bundles[idx].start + numBundPrb-1;
1618 /* Does it go beyond the end? */
1619 if (settings->bundles[idx].end > prb_offset + settings->ext12_pairs[p].num_prb) {
1620 settings->bundles[idx].end = prb_offset + settings->ext12_pairs[p].num_prb;
1621 settings->bundles[idx].is_orphan = true1;
1622 }
1623 /* Range check / return */
1624 settings->num_bundles++;
1625 if (settings->num_bundles == MAX_BFW_BUNDLES512) {
1626 return;
1627 }
1628 }
1629
1630 prb_offset += settings->ext12_pairs[p].num_prb;
1631 }
1632 }
1633
1634 /* Allocation configured by ext 13 */
1635 else if (settings->ext13_set) {
1636 unsigned alloc_size = (numPrbc+numBundPrb-1) / numBundPrb;
1637 settings->num_bundles = alloc_size * settings->ext13_num_start_prbs;
1638
1639 /* Don't overflow settings->bundles[] ! */
1640 settings->num_bundles = MIN(MAX_BFW_BUNDLES, settings->num_bundles)(((512) < (settings->num_bundles)) ? (512) : (settings->
num_bundles))
;
1641
1642 for (unsigned alloc=0; alloc < settings->ext13_num_start_prbs; alloc++) {
1643 unsigned alloc_start = alloc * alloc_size;
1644 for (uint32_t n=0; n < alloc_size; n++) {
1645 if ((alloc_start+n) >= MAX_BFW_BUNDLES512) {
1646 /* ERROR */
1647 return;
1648 }
1649 settings->bundles[alloc_start+n].start = settings->ext13_start_prbs[alloc] + startPrbc + n*numBundPrb;
1650 settings->bundles[alloc_start+n].end = settings->bundles[alloc_start+n].start + numBundPrb-1;
1651 if (settings->bundles[alloc_start+n].end > settings->ext13_start_prbs[alloc] + numPrbc) {
1652 settings->bundles[alloc_start+n].end = settings->ext13_start_prbs[alloc] + numPrbc;
1653 settings->bundles[alloc_start+n].is_orphan = true1;
1654 }
1655 }
1656 }
1657 }
1658
1659 /* Case where bundles are not controlled by other extensions - just divide up range into bundles we have */
1660 else {
1661 settings->num_bundles = (numPrbc+numBundPrb-1) / numBundPrb; /* rounded up */
1662
1663 /* Don't overflow settings->bundles[] */
1664 settings->num_bundles = MIN(MAX_BFW_BUNDLES, settings->num_bundles)(((512) < (settings->num_bundles)) ? (512) : (settings->
num_bundles))
;
1665
1666 /* For each bundle.. */
1667 for (uint32_t n=0; n < settings->num_bundles; n++) {
1668 /* Allocate start and end */
1669 settings->bundles[n].start = startPrbc + n*numBundPrb;
1670 settings->bundles[n].end = settings->bundles[n].start + numBundPrb - 1;
1671 /* If would go beyond end of PRBs, limit and identify as orphan */
1672 if (settings->bundles[n].end > startPrbc+numPrbc) {
1673 settings->bundles[n].end = startPrbc+numPrbc;
1674 settings->bundles[n].is_orphan = true1;
1675 }
1676 }
1677 }
1678}
1679
1680
1681/* Modulation Compression configuration */
1682typedef struct {
1683 /* Application of each entry is filtered by RE.
1684 * TODO: should also be filtered by PRB + symbol... */
1685 uint16_t mod_compr_re_mask;
1686
1687 /* Settings to apply */
1688 bool_Bool mod_compr_csf;
1689 float mod_compr_scaler;
1690} mod_compr_config_t;
1691
1692/* Multiple configs with a section */
1693typedef struct {
1694 uint16_t section_id;
1695 uint32_t num_configs;
1696
1697 #define MAX_MOD_COMPR_CONFIGS12 12
1698 mod_compr_config_t configs[MAX_MOD_COMPR_CONFIGS12];
1699} section_mod_compr_config_t;
1700
1701/* Flow has separate configs for each section */
1702typedef struct {
1703 uint16_t num_sections;
1704
1705 /* Separate config for each section */
1706 section_mod_compr_config_t sections[MAX_SECTION_IDs32];
1707} mod_compr_params_t;
1708
1709
1710typedef struct {
1711 uint32_t frame_number;
1712 nstime_t frame_time;
1713
1714 /* Timing to match */
1715 uint8_t frame;
1716 uint8_t subframe;
1717 uint8_t slot;
1718 uint8_t startSymbol;
1719
1720 bool_Bool in_use;
1721 uint16_t startPrb;
1722 uint16_t numPrb;
1723 uint16_t numSymbols;
1724 uint16_t beamIds[273];
1725} section_details_t;
1726
1727typedef struct {
1728 uint16_t sectionId;
1729 /* For the same sectionId, can have 2 currently active entries.. */
1730 section_details_t details[2];
1731} expected_section_data_t;
1732
1733
1734/*******************************************************/
1735/* Overall state of a flow (eAxC/plane) */
1736typedef struct {
1737 /* State for sequence analysis [each direction] */
1738 bool_Bool last_frame_seen[2];
1739 uint32_t last_frame[2];
1740 uint8_t next_expected_sequence_number[2];
1741
1742 /* DL expected frames. sectionId -> expected_section_data_t* */
1743 wmem_tree_t *expected_dl_sections;
1744
1745 /* Table recording ackNack requests (ackNackId -> ack_nack_request_t*)
1746 Note that this assumes that the same ackNackId will not be reused within a state,
1747 which may well not be valid */
1748 wmem_tree_t *ack_nack_requests;
1749
1750 /* Store udCompHdr seen in C-Plane for UL - can be looked up and used by U-PLane.
1751 Note that this appears in the common section header parts of ST1, ST3, ST5,
1752 so can still be over-written per sectionId in the U-Plane */
1753 unsigned ul_ud_comp_hdr_frame;
1754 bool_Bool ul_ud_comp_hdr_set;
1755 unsigned ul_ud_comp_hdr_bit_width;
1756 int ul_ud_comp_hdr_compression;
1757
1758 bool_Bool udcomphdrDownlink_heuristic_result_set;
1759 bool_Bool udcomphdrDownlink_heuristic_result;
1760 bool_Bool udcomphdrUplink_heuristic_result_set;
1761 bool_Bool udcomphdrUplink_heuristic_result;
1762
1763 /* Modulation compression params */
1764 mod_compr_params_t mod_comp_params;
1765} flow_state_t;
1766
1767static section_mod_compr_config_t* get_mod_compr_section_to_write(flow_state_t *flow,
1768 unsigned sectionId)
1769{
1770 if (flow == NULL((void*)0)) {
1771 return NULL((void*)0);
1772 }
1773
1774 /* Look for this section among existing entries */
1775 for (unsigned s=0; s < flow->mod_comp_params.num_sections; s++) {
1776 if (flow->mod_comp_params.sections[s].section_id == sectionId) {
1777 return &flow->mod_comp_params.sections[s];
1778 }
1779 }
1780
1781 /* Not found, so try to add a new one */
1782 if (flow->mod_comp_params.num_sections >= MAX_SECTION_IDs32) {
1783 /* Can't allocate one! */
1784 return NULL((void*)0);
1785 }
1786 else {
1787 flow->mod_comp_params.sections[flow->mod_comp_params.num_sections].section_id = sectionId;
1788 return &flow->mod_comp_params.sections[flow->mod_comp_params.num_sections++];
1789 }
1790}
1791
1792static section_mod_compr_config_t* get_mod_compr_section_to_read(flow_state_t *flow,
1793 unsigned sectionId)
1794{
1795 if (flow == NULL((void*)0)) {
1796 return NULL((void*)0);
1797 }
1798
1799 /* Look for this section among existing entries */
1800 for (unsigned s=0; s < flow->mod_comp_params.num_sections; s++) {
1801 if (flow->mod_comp_params.sections[s].section_id == sectionId) {
1802 return &flow->mod_comp_params.sections[s];
1803 }
1804 }
1805
1806 /* Not found */
1807 return NULL((void*)0);
1808}
1809
1810
1811
1812typedef struct {
1813 uint32_t request_frame_number;
1814 nstime_t request_frame_time;
1815 enum {
1816 SE22,
1817 ST4Cmd1,
1818 ST4Cmd2,
1819 ST4Cmd3,
1820 ST4Cmd4
1821 } requestType;
1822
1823 uint32_t response_frame_number;
1824 nstime_t response_frame_time;
1825} ack_nack_request_t;
1826
1827static const value_string acknack_type_vals[] = {
1828 { SE22, "SE 22" },
1829 { ST4Cmd1, "ST4 (TIME_DOMAIN_BEAM_CONFIG)" },
1830 { ST4Cmd2, "ST4 (TDD_CONFIG_PATTERN)" },
1831 { ST4Cmd3, "ST4 (TRX_CONTROL)" },
1832 { ST4Cmd4, "ST4 (ASM)" },
1833 { 0, NULL((void*)0)}
1834};
1835
1836#define ORAN_C_PLANE0 0
1837#define ORAN_U_PLANE1 1
1838
1839/* Using parts of src/dst MAC address, so don't confuse UL messages with DL messages configuring UL.. */
1840static uint32_t make_flow_key(packet_info *pinfo, uint16_t eaxc_id, uint8_t plane, bool_Bool opposite_dir)
1841{
1842 uint16_t eth_bits = 0;
1843 if (pinfo->dl_src.len == 6 && pinfo->dl_dst.len == 6) {
1844 /* Only using (most of) 2 bytes from addresses for now, but reluctant to make key longer.. */
1845 const uint8_t *src_eth = (uint8_t*)pinfo->dl_src.data;
1846 const uint8_t *dst_eth = (uint8_t*)pinfo->dl_dst.data;
1847 if (!opposite_dir) {
1848 eth_bits = (src_eth[0]<<8) | dst_eth[5];
1849 }
1850 else {
1851 eth_bits = (dst_eth[0]<<8) | src_eth[5];
1852 }
1853 }
1854 return eaxc_id | (plane << 16) | (eth_bits << 17);
1855}
1856
1857
1858/* Table maintained on first pass from flow_key(uint32_t) -> flow_state_t* */
1859static wmem_tree_t *flow_states_table;
1860
1861/* Table consulted on subsequent passes: frame_num -> flow_result_t* */
1862static wmem_tree_t *flow_results_table;
1863
1864typedef struct {
1865 /* Sequence analysis */
1866 bool_Bool unexpected_seq_number;
1867 uint8_t expected_sequence_number;
1868 uint32_t previous_frame;
1869
1870 /* sectionId -> expected_section_data_t* */
1871 wmem_tree_t *expected_dl_sections;
1872
1873} flow_result_t;
1874
1875
1876/* Uplink timing */
1877/* For a given symbol, track first to last UL frame to find out first-last time */
1878/* frameId (8) + subframeId (4) + slotId (6) + symbolId (6) = 24 bits */
1879/* N.B. if a capture lasts > 2.5s, may see same timing come around again... */
1880static uint32_t get_timing_key(uint8_t frameId, uint8_t subframeId, uint8_t slotId, uint8_t symbolId)
1881{
1882 return symbolId + (slotId<<8) + (subframeId<<14) + (frameId<<18);
1883}
1884
1885typedef struct {
1886 uint32_t first_frame;
1887 nstime_t first_frame_time;
1888 uint32_t frames_seen_in_symbol;
1889 uint32_t last_frame_in_symbol;
1890} ul_timing_for_slot;
1891
1892/* Set during first pass. timing_key -> ul_timing_for_slot* */
1893static wmem_tree_t *ul_symbol_timing;
1894
1895
1896/* Tracking lifetimes of DL beamIds */
1897typedef struct {
1898 uint32_t frame_defined;
1899 uint32_t symbol_when_defined;
1900} bfw_definition;
1901
1902/* Maintained during first pass: beamId (from ext11) -> bfw_definition */
1903static wmem_tree_t *dl_beam_ids_defined;
1904/* Lookup where/when beamIds were defined (frameid:beamid) -> bfw_definition */
1905static wmem_tree_t *dl_beam_ids_results;
1906
1907
1908static void show_link_to_acknack_response(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo,
1909 ack_nack_request_t *response);
1910
1911
1912
1913
1914static void write_pdu_label_and_info(proto_item *ti1, proto_item *ti2,
1915 packet_info *pinfo, const char *format, ...) G_GNUC_PRINTF(4, 5)__attribute__((__format__ (__printf__, 4, 5)));
1916
1917 /* Write the given formatted text to:
1918 - the info column (if pinfo != NULL)
1919 - 1 or 2 other labels (optional)
1920 */
1921static void write_pdu_label_and_info(proto_item *ti1, proto_item *ti2,
1922 packet_info *pinfo, const char *format, ...)
1923{
1924#define MAX_INFO_BUFFER256 256
1925 char info_buffer[MAX_INFO_BUFFER256];
1926 va_list ap;
1927
1928 if ((ti1 == NULL((void*)0)) && (ti2 == NULL((void*)0)) && (pinfo == NULL((void*)0))) {
1929 return;
1930 }
1931
1932 va_start(ap, format)__builtin_va_start(ap, format);
1933 vsnprintf(info_buffer, MAX_INFO_BUFFER256, format, ap);
1934 va_end(ap)__builtin_va_end(ap);
1935
1936 /* Add to indicated places */
1937 if (pinfo != NULL((void*)0)) {
1938 col_append_str(pinfo->cinfo, COL_INFO, info_buffer);
1939 }
1940 if (ti1 != NULL((void*)0)) {
1941 proto_item_append_text(ti1, "%s", info_buffer);
1942 }
1943 if (ti2 != NULL((void*)0)) {
1944 proto_item_append_text(ti2, "%s", info_buffer);
1945 }
1946}
1947
1948/* Add section labels (type + PRB range) for C-Plane, U-Plane */
1949static void
1950write_section_info(proto_item *section_heading, packet_info *pinfo, proto_item *protocol_item,
1951 uint32_t section_id, uint32_t start_prbx, uint32_t num_prbx, uint32_t rb)
1952{
1953 switch (num_prbx) {
1954 case 0:
1955 /* None -> all */
1956 write_pdu_label_and_info(section_heading, protocol_item, pinfo, ", Id: %4d (all PRBs)", section_id);
1957 break;
1958 case 1:
1959 /* Single PRB */
1960 write_pdu_label_and_info(section_heading, protocol_item, pinfo, ", Id: %4d (PRB: %7u)", section_id, start_prbx);
1961 break;
1962 default:
1963 /* Range */
1964 write_pdu_label_and_info(section_heading, protocol_item, pinfo, ", Id: %4d (PRB: %3u-%3u%s)", section_id, start_prbx,
1965 start_prbx + (num_prbx-1)*(1+rb), rb ? " (every-other)" : "");
1966 }
1967}
1968
1969static void
1970write_channel_section_info(proto_item *section_heading, packet_info *pinfo,
1971 uint32_t section_id, uint32_t ueId, uint32_t start_prbx, uint32_t num_prbx,
1972 uint32_t num_trx)
1973{
1974 switch (num_prbx) {
1975 case 0:
1976 /* TODO: ?? */
1977 break;
1978 case 1:
1979 /* Single PRB */
1980 write_pdu_label_and_info(section_heading, NULL((void*)0), pinfo,
1981 ", Id: %4d (UEId=%5u PRB %7u, %2u antennas)",
1982 section_id, ueId, start_prbx, num_trx);
1983 break;
1984 default:
1985 /* Range */
1986 write_pdu_label_and_info(section_heading, NULL((void*)0), pinfo,
1987 ", Id: %4d (UEId=%5u PRBs %3u-%3u, %2u antennas)",
1988 section_id, ueId, start_prbx, start_prbx+num_prbx-1, num_trx);
1989 }
1990}
1991
1992/* Add a reserved field, and warn if value isn't 0 */
1993/* TODO: maybe add a pref not to output expert warning if becomes too annoying? */
1994static void add_reserved_field(proto_tree *tree, int hf, tvbuff_t *tvb, int offset, int len)
1995{
1996 uint32_t reserved;
1997 proto_item *res_ti = proto_tree_add_item_ret_uint(tree, hf, tvb, offset, len, ENC_NA0x00000000, &reserved);
1998 if (reserved != 0) {
1999 expert_add_info_format(NULL((void*)0), res_ti, &ei_oran_reserved_not_zero,
2000 "reserved field saw value of 0x%x", reserved);
2001 }
2002}
2003
2004/* 5.1.3.2.7 (real time control data / IQ data transfer message series identifier) */
2005static void
2006addPcOrRtcid(tvbuff_t *tvb, proto_tree *tree, unsigned *offset, int hf, uint16_t *eAxC, oran_tap_info *tap_info)
2007{
2008 /* Subtree */
2009 proto_item *oran_pcid_ti = proto_tree_add_item(tree, hf,
2010 tvb, *offset, 2, ENC_NA0x00000000);
2011 proto_tree *oran_pcid_tree = proto_item_add_subtree(oran_pcid_ti, ett_oran_ecpri_pcid);
2012
2013 uint64_t duPortId, bandSectorId, ccId, ruPortId = 0;
2014 int id_offset = *offset;
2015
2016 /* All parts of eAxC should be above 0, and should total 16 bits (breakdown controlled by preferences) */
2017 if (!((pref_du_port_id_bits > 0) && (pref_bandsector_id_bits > 0) && (pref_cc_id_bits > 0) && (pref_ru_port_id_bits > 0) &&
2018 ((pref_du_port_id_bits + pref_bandsector_id_bits + pref_cc_id_bits + pref_ru_port_id_bits) == 16))) {
2019 expert_add_info(NULL((void*)0), tree, &ei_oran_invalid_eaxc_bit_width);
2020 *eAxC = 0;
2021 *offset += 2;
2022 return;
2023 }
2024
2025 unsigned bit_offset = *offset * 8;
2026
2027 /* N.B. For sequence analysis / tapping, just interpret these 2 bytes as eAxC ID... */
2028 *eAxC = tvb_get_uint16(tvb, *offset, ENC_BIG_ENDIAN0x00000000);
2029
2030 /* DU Port ID */
2031 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_ENDIAN0x00000000);
2032 bit_offset += pref_du_port_id_bits;
2033 /* BandSector ID */
2034 proto_tree_add_bits_ret_val(oran_pcid_tree, hf_oran_bandsector_id, tvb, bit_offset, pref_bandsector_id_bits, &bandSectorId, ENC_BIG_ENDIAN0x00000000);
2035 bit_offset += pref_bandsector_id_bits;
2036 /* CC ID */
2037 proto_tree_add_bits_ret_val(oran_pcid_tree, hf_oran_cc_id, tvb, bit_offset, pref_cc_id_bits, &ccId, ENC_BIG_ENDIAN0x00000000);
2038 bit_offset += pref_cc_id_bits;
2039 /* RU Port ID */
2040 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_ENDIAN0x00000000);
2041 *offset += 2;
2042
2043 proto_item_append_text(oran_pcid_ti, " (DU_Port_ID: %d, BandSector_ID: %d, CC_ID: %d, RU_Port_ID: %d)",
2044 (int)duPortId, (int)bandSectorId, (int)ccId, (int)ruPortId);
2045 char id[16];
2046 snprintf(id, 16, "%x:%x:%x:%x", (int)duPortId, (int)bandSectorId, (int)ccId, (int)ruPortId);
2047 proto_item *pi = proto_tree_add_string(oran_pcid_tree, hf_oran_c_eAxC_ID, tvb, id_offset, 2, id);
2048 proto_item_set_generated(pi);
2049
2050 tap_info->eaxc = *eAxC;
2051 tap_info->eaxc_du_port_id = (uint16_t)duPortId;
2052 tap_info->eaxc_bandsector_id = (uint16_t)bandSectorId;
2053 tap_info->eaxc_cc_id = (uint16_t)ccId;
2054 tap_info->eaxc_ru_port_id = (uint16_t)ruPortId;
2055}
2056
2057/* Uniquely identify the U-plane stream that may need to be reassembled */
2058static uint32_t make_reassembly_id(uint32_t seqid, uint32_t direction, uint16_t eAxC,
2059 uint8_t frameid, uint8_t subframeid,
2060 uint8_t slotid, uint8_t symbolid)
2061{
2062 /* N.B., no room in 32-bits for all of this info, so cut down some of the fields
2063 and hope for no collisions */
2064 return (seqid << 24) | (direction << 23) | (slotid << 22) | (subframeid << 18) |
2065 (frameid << 9) | (symbolid << 6) | (eAxC & 0x3f);
2066}
2067
2068/* 5.1.3.2.8 ecpriSeqid (message identifier) */
2069/* Return out info that may be used for sequence number analysis and reassembly */
2070static int
2071addSeqid(tvbuff_t *tvb, proto_tree *oran_tree, int offset, int plane, uint32_t *seq_id, proto_item **seq_id_ti, packet_info *pinfo,
2072 uint32_t *subseqid, uint32_t *e)
2073{
2074 /* Subtree */
2075 proto_item *seqIdItem = proto_tree_add_item(oran_tree, hf_oran_ecpri_seqid, tvb, offset, 2, ENC_NA0x00000000);
2076 proto_tree *oran_seqid_tree = proto_item_add_subtree(seqIdItem, ett_oran_ecpri_seqid);
2077
2078 /* Sequence ID (8 bits) */
2079 *seq_id_ti = proto_tree_add_item_ret_uint(oran_seqid_tree, hf_oran_sequence_id, tvb, offset, 1, ENC_NA0x00000000, seq_id);
2080 offset += 1;
2081
2082 /* Show link back to previous sequence ID, if set */
2083 flow_result_t *result = wmem_tree_lookup32(flow_results_table, pinfo->num);
2084 if (result) {
2085 proto_item *prev_ti = proto_tree_add_uint(oran_seqid_tree, hf_oran_previous_frame, tvb, 0, 0, result->previous_frame);
2086 proto_item_set_generated(prev_ti);
2087 }
2088
2089 /* E bit */
2090 proto_tree_add_item_ret_uint(oran_seqid_tree, hf_oran_e_bit, tvb, offset, 1, ENC_NA0x00000000, e);
2091 /* Subsequence ID (7 bits) */
2092 proto_tree_add_item_ret_uint(oran_seqid_tree, hf_oran_subsequence_id, tvb, offset, 1, ENC_NA0x00000000, subseqid);
2093 offset += 1;
2094
2095 /* radio-transport fragmentation not allowed for C-Plane messages */
2096 if (plane == ORAN_C_PLANE0) {
2097 if (*e !=1 || *subseqid != 0) {
2098 expert_add_info(NULL((void*)0), seqIdItem, &ei_oran_radio_fragmentation_c_plane);
2099 }
2100 }
2101
2102 /* Summary */
2103 proto_item_append_text(seqIdItem, " (SeqId: %3d, E: %d, SubSeqId: %d)", *seq_id, *e, *subseqid);
2104 return offset;
2105}
2106
2107static int dissect_symbolmask(tvbuff_t *tvb, proto_tree *tree, int offset, uint32_t *symbol_mask, proto_item **ti)
2108{
2109 uint64_t temp_val;
2110
2111 static int * const symbol_mask_flags[] = {
2112 &hf_oran_symbol_mask_s13,
2113 &hf_oran_symbol_mask_s12,
2114 &hf_oran_symbol_mask_s11,
2115 &hf_oran_symbol_mask_s10,
2116 &hf_oran_symbol_mask_s9,
2117 &hf_oran_symbol_mask_s8,
2118 &hf_oran_symbol_mask_s7,
2119 &hf_oran_symbol_mask_s6,
2120 &hf_oran_symbol_mask_s5,
2121 &hf_oran_symbol_mask_s4,
2122 &hf_oran_symbol_mask_s3,
2123 &hf_oran_symbol_mask_s2,
2124 &hf_oran_symbol_mask_s1,
2125 &hf_oran_symbol_mask_s0,
2126 NULL((void*)0)
2127 };
2128
2129 proto_item *temp_ti = proto_tree_add_bitmask_ret_uint64(tree, tvb, offset,
2130 hf_oran_symbol_mask,
2131 ett_oran_symbol_mask, symbol_mask_flags,
2132 ENC_BIG_ENDIAN0x00000000, &temp_val);
2133 /* Set out parameters */
2134 if (symbol_mask) {
2135 *symbol_mask = (uint32_t)temp_val;
2136 }
2137 if (ti) {
2138 *ti = temp_ti;
2139 }
2140 return offset+2;
2141}
2142
2143/* 7.7.1.2 bfwCompHdr (beamforming weight compression header) */
2144static int dissect_bfwCompHdr(tvbuff_t *tvb, proto_tree *tree, int offset,
2145 uint32_t *iq_width, uint32_t *comp_meth, proto_item **comp_meth_ti)
2146{
2147 /* Subtree */
2148 proto_item *bfwcomphdr_ti = proto_tree_add_string_format(tree, hf_oran_bfwCompHdr,
2149 tvb, offset, 1, "",
2150 "bfwCompHdr");
2151 proto_tree *bfwcomphdr_tree = proto_item_add_subtree(bfwcomphdr_ti, ett_oran_bfwcomphdr);
2152
2153 /* Width and method */
2154 proto_tree_add_item_ret_uint(bfwcomphdr_tree, hf_oran_bfwCompHdr_iqWidth,
2155 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, iq_width);
2156 /* Special case: 0 -> 16 */
2157 *iq_width = (*iq_width==0) ? 16 : *iq_width;
2158 *comp_meth_ti = proto_tree_add_item_ret_uint(bfwcomphdr_tree, hf_oran_bfwCompHdr_compMeth,
2159 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, comp_meth);
2160 offset++;
2161
2162 /* Summary */
2163 proto_item_append_text(bfwcomphdr_ti, " (IqWidth=%u, compMeth=%s)",
2164 *iq_width,
2165 val_to_str_const(*comp_meth, bfw_comp_headers_comp_meth, "reserved"));
2166
2167 return offset;
2168}
2169
2170/* Return offset */
2171/* Returning number of entries set - would be good to also return an array of set TRX# so could show which array element
2172 each BFW is actually for.. */
2173static int dissect_active_beamspace_coefficient_mask(tvbuff_t *tvb, proto_tree *tree, int offset, unsigned *num_trx_entries, uint16_t **trx_entries)
2174{
2175 /* activeBeamspaceCoefficientMask - ceil(K/8) octets */
2176 /* K is the number of elements in uncompressed beamforming weight vector.
2177 * Calculated from parameters describing tx-array or tx-array */
2178 unsigned k_octets = (pref_num_bf_antennas + 7) / 8;
2179
2180 static uint16_t trx_enabled[1024];
2181
2182 /* TODO: could use a bigger bitmask array, but for now just uses this bytes-worth for each byte */
2183 static int * const mask_bits[] = {
2184 &hf_oran_active_beamspace_coefficient_n1,
2185 &hf_oran_active_beamspace_coefficient_n2,
2186 &hf_oran_active_beamspace_coefficient_n3,
2187 &hf_oran_active_beamspace_coefficient_n4,
2188 &hf_oran_active_beamspace_coefficient_n5,
2189 &hf_oran_active_beamspace_coefficient_n6,
2190 &hf_oran_active_beamspace_coefficient_n7,
2191 &hf_oran_active_beamspace_coefficient_n8,
2192 NULL((void*)0)
2193 };
2194
2195 *num_trx_entries = 0;
2196 uint64_t val;
2197 for (unsigned n=0; n < k_octets; n++) {
2198 proto_tree_add_bitmask_ret_uint64(tree, tvb, offset,
2199 hf_oran_activeBeamspaceCoefficientMask,
2200 ett_oran_active_beamspace_coefficient_mask, mask_bits,
2201 ENC_BIG_ENDIAN0x00000000, &val);
2202 offset++;
2203 /* Add up the set bits for this byte (but be careful not to count beyond last real K bit..) */
2204 for (unsigned b=0; b < 8; b++) {
2205 if ((1 << b) & (unsigned)val) {
2206 if (((n*8)+b) < pref_num_bf_antennas) {
2207 if (*num_trx_entries < 1024-1) { /* Don't write beyond array (which should be plenty big) */
2208 trx_enabled[(*num_trx_entries)++] = (n*8) + b + 1;
2209 }
2210 }
2211 }
2212 }
2213 }
2214 /* Set pointer to static array */
2215 *trx_entries = trx_enabled;
2216
2217 /* Show how many bits set */
2218 proto_item *ti = proto_tree_add_uint(tree, hf_oran_activeBeamspaceCoefficientMask_bits_set, tvb,
2219 offset-k_octets, k_octets, *num_trx_entries);
2220 proto_item_set_generated(ti);
2221
2222 return offset;
2223}
2224
2225static void add_beam_id_to_tap(oran_tap_info *tap_info, uint16_t beam_id)
2226{
2227 if (tap_info->num_beams < MAX_BEAMS_IN_FRAME32) {
2228 tap_info->beams[tap_info->num_beams++] = beam_id;
2229 }
2230}
2231
2232
2233/* 7.7.1.3 bfwCompParam (beamforming weight compression parameter).
2234 * Depends upon passed-in bfwCompMeth (field may be empty) */
2235static int dissect_bfwCompParam(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, int offset,
2236 proto_item *meth_ti, uint32_t *bfw_comp_method,
2237 uint32_t *exponent, bool_Bool *supported, unsigned *num_trx_entries, uint16_t **trx_entries)
2238{
2239 if (*bfw_comp_method == COMP_NONE0) {
2240 /* Absent! */
2241 *num_trx_entries = 0;
2242 *supported = true1;
2243 return offset;
2244 }
2245
2246 /* Subtree */
2247 proto_item *bfwcompparam_ti = proto_tree_add_string_format(tree, hf_oran_bfwCompParam,
2248 tvb, offset, 1, "",
2249 "bfwCompParam");
2250 proto_tree *bfwcompparam_tree = proto_item_add_subtree(bfwcompparam_ti, ett_oran_bfwcompparam);
2251
2252 proto_item_append_text(bfwcompparam_ti,
2253 " (meth=%s)", val_to_str_const(*bfw_comp_method, bfw_comp_headers_comp_meth, "reserved"));
2254
2255 *num_trx_entries = 0;
2256 *supported = false0;
2257 switch (*bfw_comp_method) {
2258 case COMP_BLOCK_FP1: /* block floating point */
2259 /* 4 reserved bits + exponent */
2260 add_reserved_field(bfwcompparam_tree, hf_oran_reserved_4bits, tvb, offset, 1);
2261 proto_tree_add_item_ret_uint(bfwcompparam_tree, hf_oran_exponent,
2262 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, exponent);
2263 proto_item_append_text(bfwcompparam_ti, " exponent=%u", *exponent);
2264 *supported = true1;
2265 offset++;
2266 break;
2267 case COMP_BLOCK_SCALE2: /* block scaling */
2268 /* Separate into integer and fractional bits? */
2269 proto_tree_add_item(bfwcompparam_tree, hf_oran_blockScaler,
2270 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
2271 offset++;
2272 break;
2273 case COMP_U_LAW3: /* u-law */
2274 /* compBitWidth, compShift */
2275 proto_tree_add_item(bfwcompparam_tree, hf_oran_compBitWidth,
2276 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
2277 proto_tree_add_item(bfwcompparam_tree, hf_oran_compShift,
2278 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
2279 offset++;
2280 break;
2281 case 4: /* beamspace I (BLOCK SCALING) */
2282 /* activeBeamspaceCoefficientMask */
2283 offset = dissect_active_beamspace_coefficient_mask(tvb, bfwcompparam_tree, offset, num_trx_entries, trx_entries);
2284 *bfw_comp_method = COMP_BLOCK_SCALE2;
2285 *supported = false0; /* TODO: true once BLOCK SCALE is supported */
2286 proto_tree_add_item(bfwcompparam_tree, hf_oran_blockScaler,
2287 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
2288 offset++;
2289 break;
2290 case 5: /* beamspace II (BLOCK FLOATING POINT) */
2291 /* activeBeamspaceCoefficientMask */
2292 offset = dissect_active_beamspace_coefficient_mask(tvb, bfwcompparam_tree, offset, num_trx_entries, trx_entries);
2293 /* reserved (4 bits) + exponent (4 bits) */
2294 add_reserved_field(bfwcompparam_tree, hf_oran_reserved_4bits, tvb, offset, 1);
2295 proto_tree_add_item_ret_uint(bfwcompparam_tree, hf_oran_exponent, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, exponent);
2296 offset += 1;
2297 *bfw_comp_method = COMP_BLOCK_FP1;
2298 *supported = true1;
2299 break;
2300
2301 default:
2302 /* Not handled */
2303 break;
2304 }
2305
2306 proto_item_set_end(bfwcompparam_ti, tvb, offset);
2307
2308 /* Can't go on if compression scheme not supported */
2309 if (!(*supported) && meth_ti) {
2310 expert_add_info_format(pinfo, meth_ti, &ei_oran_unsupported_bfw_compression_method,
2311 "BFW Compression method %u (%s) not decompressed by dissector",
2312 *bfw_comp_method,
2313 val_to_str_const(*bfw_comp_method, bfw_comp_headers_comp_meth, "reserved"));
2314 }
2315 return offset;
2316}
2317
2318
2319/* Special case for uncompressed/16-bit value */
2320static float uncompressed_to_float(uint32_t h)
2321{
2322 int16_t i16 = h & 0x0000ffff;
2323 if (show_unscaled_values) {
2324 return (float)i16;
2325 }
2326 return ((float)i16) / 0x7fff;
2327}
2328
2329/* Decompress I/Q value, taking into account method, width, exponent, other input-specific methods */
2330static float decompress_value(uint32_t bits, uint32_t comp_method, uint8_t iq_width,
2331 uint32_t exponent,
2332 /* Modulation compression settings. N.B. should also pass in PRB + symbol? */
2333 section_mod_compr_config_t *m_c_p, uint8_t re)
2334{
2335 switch (comp_method) {
2336 case COMP_NONE0: /* no compression */
2337 return uncompressed_to_float(bits);
2338
2339 case COMP_BLOCK_FP1: /* block floating point */
2340 case BFP_AND_SELECTIVE_RE5:
2341 {
2342 /* A.1.3 Block Floating Point Decompression Algorithm */
2343 int32_t cPRB = bits;
2344 uint32_t scaler = 1 << exponent; /* i.e. 2^exponent */
2345
2346 /* Check last bit, in case we need to flip to -ve */
2347 if (cPRB >= (1<<(iq_width-1))) {
2348 cPRB -= (1<<iq_width);
2349 }
2350
2351 /* Unscale (8.1.3.1) */
2352 cPRB *= scaler;
2353 if (show_unscaled_values) {
2354 return (float)cPRB;
2355 }
2356
2357 uint32_t mantissa_scale_factor = 1 << (iq_width-1); /* 2^(mantissabits-1) */
2358 uint32_t exp_scale_factor = 1 << 15; /* 2^(2^exponentbits - 1 ) The exponent bit width is fixed to 4, so the maximum exponent is 15 */
2359
2360 float ret = cPRB / ((float)(mantissa_scale_factor*exp_scale_factor));
2361 return ret;
2362 }
2363
2364 case COMP_BLOCK_SCALE2:
2365 case COMP_U_LAW3:
2366 /* Not supported! But will be reported as expert info outside of this function! */
2367 return 0.0;
2368
2369 case COMP_MODULATION4:
2370 case MOD_COMPR_AND_SELECTIVE_RE6:
2371 {
2372 /* Described in A.5 (with pseudo code) */
2373 /* N.B., Applies to downlink data only - is not used for BFW */
2374
2375 /* Defaults if not overridden. TODO: what should these be? */
2376 bool_Bool csf = false0;
2377 float mcScaler = (float)(1 << 11);
2378
2379 /* Find csf + mcScaler to use. Non-default configs gleaned from SE 4,5,23 */
2380 /* TODO: should ideally be filtering by symbol and PRB too (as configured from SE23) */
2381 if (re > 0 && m_c_p && m_c_p->num_configs > 0) {
2382 for (unsigned c=0; c<m_c_p->num_configs; c++) {
2383 if (m_c_p->configs[c].mod_compr_re_mask & (1 << (12-re))) {
2384 /* Return first (should be only) found */
2385 csf = m_c_p->configs[c].mod_compr_csf;
2386 mcScaler = m_c_p->configs[c].mod_compr_scaler;
2387 break;
2388 }
2389 }
2390 }
2391
2392 int32_t cPRB = bits;
2393
2394 /* 2) Map iqSample to iqSampleFx */
2395 /* Check last bit, in case we need to flip to -ve */
2396 if (cPRB >= (1<<(iq_width-1))) {
2397 cPRB -= (1<<iq_width);
2398 }
2399 float iqSampleFx = (float)cPRB / (1 << (iq_width-1));
2400
2401
2402 /* 3) or 4) (b) - add unshifted value if csf set */
2403 float csf_to_add = 0.0;
2404 if (csf) {
2405 /* Unshift the constellation point */
2406 csf_to_add = (float)1.0 / (1 << (iq_width));
2407 }
2408 iqSampleFx += csf_to_add;
2409
2410 /* 3) or 4) (c) - unscaling */
2411 float iqSampleScaled = mcScaler * iqSampleFx * (float)sqrt(2);
2412 return iqSampleScaled;
2413 }
2414
2415 default:
2416 /* Not supported! But will be reported as expert info outside of this function! */
2417 return 0.0;
2418 }
2419}
2420
2421/* Out-of-range value used for special case */
2422#define ORPHAN_BUNDLE_NUMBER999 999
2423
2424/* Bundle of PRBs/TRX I/Q samples (ext 11) */
2425static uint32_t dissect_bfw_bundle(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, unsigned offset,
2426 proto_item *comp_meth_ti, uint32_t bfwcomphdr_comp_meth,
2427 section_mod_compr_config_t *mod_compr_params,
2428 uint32_t num_weights_per_bundle,
2429 uint8_t iq_width,
2430 unsigned bundle_number,
2431 unsigned first_prb, unsigned last_prb, bool_Bool is_orphan,
2432 uint32_t symbol_count,
2433 section_details_t *section_details,
2434 oran_tap_info *tap_info)
2435{
2436 /* Set bundle name */
2437 char bundle_name[32];
2438 if (!is_orphan) {
2439 snprintf(bundle_name, 32, "Bundle %3u", bundle_number);
2440 }
2441 else {
2442 (void) g_strlcpy(bundle_name, "Orphaned ", 32);
2443 }
2444
2445 /* Create Bundle root */
2446 proto_item *bundle_ti;
2447 if (first_prb != last_prb) {
2448 bundle_ti = proto_tree_add_string_format(tree, hf_oran_bfw_bundle,
2449 tvb, offset, 0, "",
2450 "%s: (PRBs %3u-%3u)",
2451 bundle_name,
2452 first_prb, last_prb);
2453 }
2454 else {
2455 bundle_ti = proto_tree_add_string_format(tree, hf_oran_bfw_bundle,
2456 tvb, offset, 0, "",
2457 "%s: (PRB %3u)",
2458 bundle_name,
2459 first_prb);
2460 }
2461 proto_tree *bundle_tree = proto_item_add_subtree(bundle_ti, ett_oran_bfw_bundle);
2462
2463 /* Generated bundle id */
2464 proto_item *bundleid_ti = proto_tree_add_uint(bundle_tree, hf_oran_bfw_bundle_id, tvb, 0, 0,
2465 bundle_number);
2466 proto_item_set_generated(bundleid_ti);
2467 proto_item_set_hidden(bundleid_ti);
2468
2469 /* bfwCompParam */
2470 bool_Bool compression_method_supported = false0;
2471 unsigned exponent = 0;
2472 unsigned num_trx_entries = 0;
2473 uint16_t *trx_entries;
2474 offset = dissect_bfwCompParam(tvb, bundle_tree, pinfo, offset, comp_meth_ti,
2475 &bfwcomphdr_comp_meth, &exponent, &compression_method_supported,
2476 &num_trx_entries, &trx_entries);
2477
2478 /* Create Bundle subtree */
2479 int bit_offset = offset*8;
2480 int bfw_offset;
2481
2482 /* contInd */
2483 proto_tree_add_item(bundle_tree, hf_oran_cont_ind,
2484 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
2485 /* beamId */
2486 uint32_t beam_id;
2487 proto_tree_add_item_ret_uint(bundle_tree, hf_oran_beam_id, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &beam_id);
2488 proto_item_append_text(bundle_ti, " (beamId:%u) ", beam_id);
2489 bit_offset += 16;
2490 add_beam_id_to_tap(tap_info, beam_id);
2491
2492 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
2493 if (section_details) {
2494 for (unsigned prb = first_prb; prb <= last_prb; prb++) {
2495 if (prb < 273) {
2496 section_details->beamIds[prb] = beam_id;
2497 }
2498 }
2499 }
2500 }
2501
2502 /* On first pass, record that beamId was defined here */
2503 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
2504 bfw_definition *definition = wmem_new0(wmem_file_scope(), bfw_definition)((bfw_definition*)wmem_alloc0((wmem_file_scope()), sizeof(bfw_definition
)))
;
2505 definition->frame_defined = pinfo->num;
2506 definition->symbol_when_defined = symbol_count;
2507 wmem_tree_insert32(dl_beam_ids_defined, beam_id, definition);
2508 }
2509
2510
2511 /* Number of weights per bundle (from preference) */
2512 proto_item *wpb_ti = proto_tree_add_uint(bundle_tree, hf_oran_num_weights_per_bundle, tvb, 0, 0,
2513 num_weights_per_bundle);
2514 proto_item_set_generated(wpb_ti);
2515
2516 /* Add the weights for this bundle. Overwrite with what was seen in bfwCompParam if beamspace */
2517 if (num_trx_entries != 0) {
2518 num_weights_per_bundle = num_trx_entries;
2519 }
2520
2521 bool_Bool non_zero_weights_seen = false0;
2522 int bit_offset_before_weights = bit_offset;
2523 for (unsigned w=0; w < num_weights_per_bundle; w++) {
2524
2525 uint16_t trx_index = (num_trx_entries) ? trx_entries[w] : w+1;
2526
2527 /* Create subtree */
2528 bfw_offset = bit_offset / 8;
2529 uint8_t bfw_extent = ((bit_offset + (iq_width*2)) / 8) - bfw_offset;
2530 proto_item *bfw_ti = proto_tree_add_string_format(bundle_tree, hf_oran_bfw,
2531 tvb, bfw_offset, bfw_extent,
2532 "", "TRX %3u: (", trx_index);
2533 proto_tree *bfw_tree = proto_item_add_subtree(bfw_ti, ett_oran_bfw);
2534
2535 /* I */
2536 /* Get bits, and convert to float. */
2537 uint32_t bits = tvb_get_bits32(tvb, bit_offset, iq_width, ENC_BIG_ENDIAN0x00000000);
2538 if (bits) {
2539 non_zero_weights_seen = true1;
2540 }
2541 float value = decompress_value(bits, bfwcomphdr_comp_meth, iq_width,
2542 exponent, mod_compr_params, 0 /* RE */);
2543 /* Add to tree. */
2544 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);
2545 bit_offset += iq_width;
2546 proto_item_append_text(bfw_ti, "I%u=%f ", w, value);
2547
2548 /* Q */
2549 /* Get bits, and convert to float. */
2550 bits = tvb_get_bits32(tvb, bit_offset, iq_width, ENC_BIG_ENDIAN0x00000000);
2551 if (bits) {
2552 non_zero_weights_seen = true1;
2553 }
2554
2555 value = decompress_value(bits, bfwcomphdr_comp_meth, iq_width,
2556 exponent, mod_compr_params, 0 /* RE */);
2557 /* Add to tree. */
2558 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);
2559 bit_offset += iq_width;
2560 proto_item_append_text(bfw_ti, "Q%u=%f)", w, value);
2561 }
2562
2563 if (!non_zero_weights_seen) {
2564 proto_tree_add_item(bundle_tree, hf_oran_bundle_weights_all_zero, tvb,
2565 bit_offset_before_weights, (bit_offset+7)/8 - (bit_offset_before_weights/8), ENC_NA0x00000000);
2566 }
2567
2568 /* Set extent of bundle */
2569 proto_item_set_end(bundle_ti, tvb, (bit_offset+7)/8);
2570
2571 return (bit_offset+7)/8;
2572}
2573
2574/* Return new bit offset. in/out will always be byte-aligned.. */
2575static int dissect_ciCompParam(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U___attribute__((unused)), unsigned bit_offset,
2576 unsigned comp_meth, uint8_t *exponent)
2577{
2578 if (comp_meth == COMP_NONE0) {
2579 /* Nothing in frame so don't even create subtree */
2580 return bit_offset;
2581 }
2582
2583 /* Subtree */
2584 proto_item *cicompparam_ti = proto_tree_add_string_format(tree, hf_oran_ciCompParam,
2585 tvb, bit_offset/8, 1, "",
2586 "ciCompParam");
2587 proto_tree *cicompparam_tree = proto_item_add_subtree(cicompparam_ti, ett_oran_cicompparam);
2588 uint32_t ci_exponent;
2589
2590 /* Contents differ by compression method */
2591 switch (comp_meth) {
2592 case COMP_BLOCK_FP1:
2593 add_reserved_field(cicompparam_tree, hf_oran_reserved_4bits, tvb, bit_offset/8, 1);
2594 proto_tree_add_item_ret_uint(cicompparam_tree, hf_oran_exponent,
2595 tvb, bit_offset/8, 1, ENC_BIG_ENDIAN0x00000000, &ci_exponent);
2596 *exponent = ci_exponent;
2597 proto_item_append_text(cicompparam_ti, " (Exponent=%u)", ci_exponent);
2598 bit_offset += 8; /* one byte */
2599 break;
2600 case COMP_BLOCK_SCALE2:
2601 /* Separate into integer (1) and fractional (7) bits? */
2602 proto_tree_add_item(cicompparam_tree, hf_oran_blockScaler,
2603 tvb, bit_offset/8, 1, ENC_BIG_ENDIAN0x00000000);
2604 bit_offset += 8;
2605 break;
2606 case COMP_U_LAW3:
2607 /* compBitWidth, compShift (4 bits each) */
2608 proto_tree_add_item(cicompparam_tree, hf_oran_compBitWidth,
2609 tvb, bit_offset/8, 1, ENC_BIG_ENDIAN0x00000000);
2610 proto_tree_add_item(cicompparam_tree, hf_oran_compShift,
2611 tvb, bit_offset/8, 1, ENC_BIG_ENDIAN0x00000000);
2612 bit_offset += 8;
2613 break;
2614
2615 default:
2616 /* reserved, ? bytes of zeros.. */
2617 break;
2618 }
2619
2620 return bit_offset;
2621}
2622
2623/* frameStructure (7.5.2.13) */
2624static unsigned dissect_frame_structure(proto_item *tree, tvbuff_t *tvb, unsigned offset,
2625 uint32_t subframeId, uint32_t slotId)
2626{
2627 uint32_t scs;
2628 /* FFT Size (4 bits) */
2629 proto_tree_add_item(tree, hf_oran_frameStructure_fft, tvb, offset, 1, ENC_NA0x00000000);
2630 /* Subcarrier spacing (SCS) */
2631 proto_tree_add_item_ret_uint(tree, hf_oran_frameStructure_subcarrier_spacing, tvb, offset, 1, ENC_NA0x00000000, &scs);
2632
2633 /* Show slot within frame as a generated field. See table 7.5.13-3 */
2634 uint32_t slots_per_subframe = 1;
2635 if (scs <= 4) {
2636 slots_per_subframe = 1 << scs;
2637 }
2638 if (scs <= 4 || scs >= 12) {
2639 proto_item *ti = proto_tree_add_uint(tree, hf_oran_slot_within_frame, tvb, 0, 0,
2640 (slots_per_subframe*subframeId) + slotId);
2641 proto_item_set_generated(ti);
2642 }
2643 return offset + 1;
2644}
2645
2646static unsigned dissect_csf(proto_item *tree, tvbuff_t *tvb, unsigned bit_offset,
2647 unsigned iq_width, bool_Bool *p_csf)
2648{
2649 proto_item *csf_ti;
2650 uint64_t csf;
2651 csf_ti = proto_tree_add_bits_ret_val(tree, hf_oran_csf, tvb, bit_offset, 1, &csf, ENC_BIG_ENDIAN0x00000000);
2652 if (csf) {
2653 /* Table 7.7.4.2-1 Constellation shift definition (index is udIqWidth) */
2654 const char* shift_value[] = { "n/a", "1/2", "1/4", "1/8", "1/16", "1/32" };
2655 if (iq_width >=1 && iq_width <= 5) {
2656 proto_item_append_text(csf_ti, " (Shift Value is %s)", shift_value[iq_width]);
2657 }
2658 }
2659
2660 /* Set out parameter */
2661 if (p_csf != NULL((void*)0)) {
2662 *p_csf = (csf!=0);
2663 }
2664 return bit_offset+1;
2665}
2666
2667
2668/* Section 7.
2669 * N.B. these are the green parts of the tables showing Section Types, differing by section Type */
2670static int dissect_oran_c_section(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo,
2671 flow_state_t* state,
2672 uint32_t sectionType, oran_tap_info *tap_info, proto_item *protocol_item,
2673 uint32_t subframeId, uint32_t frameId, uint32_t slotId, uint32_t startSymbolId,
2674 uint8_t ci_iq_width, uint8_t ci_comp_meth, unsigned ci_comp_opt,
2675 unsigned num_sinr_per_prb)
2676{
2677 unsigned offset = 0;
2678 proto_tree *c_section_tree = NULL((void*)0);
2679 proto_item *sectionHeading = NULL((void*)0);
2680
2681 /* Section subtree */
2682 sectionHeading = proto_tree_add_string_format(tree, hf_oran_c_section,
2683 tvb, offset, 0, "", "Section");
2684 c_section_tree = proto_item_add_subtree(sectionHeading, ett_oran_c_section);
2685
2686 uint32_t sectionId = 0;
2687
2688 uint32_t startPrbc=0, startPrbu=0;
2689 uint32_t numPrbc=0, numPrbu=0;
2690 uint32_t ueId = 0;
2691 proto_item *ueId_ti = NULL((void*)0);
2692 uint32_t section_beamId = 0;
2693 proto_item *section_beamId_ti = NULL((void*)0);
2694 bool_Bool section_beamId_ignored = false0;
2695
2696 proto_item *numsymbol_ti = NULL((void*)0);
2697 bool_Bool numsymbol_ignored = false0;
2698
2699 proto_item *numprbc_ti = NULL((void*)0);
2700
2701 /* Config affecting ext11 bundles (initially unset) */
2702 ext11_settings_t ext11_settings;
2703 memset(&ext11_settings, 0, sizeof(ext11_settings));
2704
2705 /* Section Type 10 needs to keep track of PRB range that should be reported
2706 for msgTypeId=5 (Interference plus Noise for unallocated PRBs) */
2707 /* All PRBs start as false */
2708#define MAX_PRBS273 273
2709 bool_Bool prbs_for_st10_type5[MAX_PRBS273];
2710 memset(&prbs_for_st10_type5, 0, sizeof(prbs_for_st10_type5));
2711
2712 /* These UEIds are set by ST5, ST10 (single value), and extended by SE10 */
2713#define MAX_UEIDS16 16
2714 uint32_t ueids[MAX_UEIDS16];
2715 uint32_t number_of_ueids = 0;
2716
2717
2718 bool_Bool extension_flag = false0;
2719
2720 /* These sections (ST0, ST1, ST2, ST3, ST5, ST9, ST10, ST11) are similar, so handle as common with per-type differences */
2721 if (((sectionType <= SEC_C_UE_SCHED) || (sectionType >= SEC_C_SINR_REPORTING)) &&
2722 (sectionType != SEC_C_SLOT_CONTROL)) {
2723
2724 /* sectionID */
2725 proto_item *ti = proto_tree_add_item_ret_uint(c_section_tree, hf_oran_section_id, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &sectionId);
2726 if (sectionId == 4095) {
2727 proto_item_append_text(ti, " (not default coupling C/U planes using sectionId)");
2728 }
2729 offset++;
2730
2731 if (tap_info->num_section_ids < MAX_SECTION_IDs32) {
2732 tap_info->section_ids[tap_info->num_section_ids++] = sectionId;
2733 }
2734
2735 /* rb */
2736 uint32_t rb;
2737 proto_tree_add_item_ret_uint(c_section_tree, hf_oran_rb, tvb, offset, 1, ENC_NA0x00000000, &rb);
2738 /* symInc (1 bit) */
2739 /* TODO: mark as ignored if SE6, SE12 or SE19 present */
2740 if (sectionType != SEC_C_RRM_MEAS_REPORTS && /* Section Type 10 */
2741 sectionType != SEC_C_REQUEST_RRM_MEAS) { /* Section Type 11 */
2742 unsigned int sym_inc;
2743 proto_item *sym_inc_ti = proto_tree_add_item_ret_uint(c_section_tree, hf_oran_symInc, tvb, offset, 1, ENC_NA0x00000000, &sym_inc);
2744 if (sym_inc !=0 && (sectionType == SEC_C_SINR_REPORTING)) { /* Section Type 9 */
2745 /* "0 shall be used" */
2746 proto_item_append_text(sym_inc_ti, " (should be 0)");
2747 }
2748 }
2749 else {
2750 /* reserved (1 bit) */
2751 add_reserved_field(c_section_tree, hf_oran_reserved_bit5, tvb, offset, 1);
2752 }
2753
2754 /* startPrbx and numPrbx */
2755 if (sectionType == SEC_C_SINR_REPORTING) {
2756 /* startPrbu (10 bits) */
2757 proto_tree_add_item_ret_uint(c_section_tree, hf_oran_startPrbu, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &startPrbu);
2758 offset += 2;
2759
2760 /* numPrbu */
2761 numprbc_ti = proto_tree_add_item_ret_uint(c_section_tree, hf_oran_numPrbu, tvb, offset, 1, ENC_NA0x00000000, &numPrbu);
2762 if (numPrbu == 0) {
2763 proto_item_append_text(numprbc_ti, " (all PRBs - configured as %u)", pref_data_plane_section_total_rbs);
2764 numPrbu = pref_data_plane_section_total_rbs;
2765 }
2766 offset += 1;
2767 }
2768 else {
2769 /* startPrbc (10 bits) */
2770 proto_tree_add_item_ret_uint(c_section_tree, hf_oran_startPrbc, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &startPrbc);
2771 offset += 2;
2772
2773 /* numPrbc */
2774 numprbc_ti = proto_tree_add_item_ret_uint(c_section_tree, hf_oran_numPrbc, tvb, offset, 1, ENC_NA0x00000000, &numPrbc);
2775 if (numPrbc == 0) {
2776 proto_item_append_text(numprbc_ti, " (all PRBs - configured as %u)", pref_data_plane_section_total_rbs);
2777 /* TODO: should probably set to pref_data_plane_section_total_rbs, and define MAX_PRBS to > 273 ? */
2778 numPrbc = MAX_PRBS273;
2779 }
2780 offset += 1;
2781 }
2782
2783 /* Start with range from section. May get changed by SE6, SE12, SE20 */
2784 for (unsigned n=startPrbc; n < startPrbc+numPrbc; n++) {
2785 if (n < MAX_PRBS273) {
2786 prbs_for_st10_type5[n] = true1;
2787 }
2788 }
2789
2790 if (sectionType != SEC_C_SINR_REPORTING) { /* *NOT* Section Type 9 */
2791 static int * const remask_flags[] = {
2792 &hf_oran_reMask_re1,
2793 &hf_oran_reMask_re2,
2794 &hf_oran_reMask_re3,
2795 &hf_oran_reMask_re4,
2796 &hf_oran_reMask_re5,
2797 &hf_oran_reMask_re6,
2798 &hf_oran_reMask_re7,
2799 &hf_oran_reMask_re8,
2800 &hf_oran_reMask_re9,
2801 &hf_oran_reMask_re10,
2802 &hf_oran_reMask_re11,
2803 &hf_oran_reMask_re12,
2804 NULL((void*)0)
2805 };
2806
2807 /* reMask */
2808 uint64_t remask;
2809 proto_tree_add_bitmask_ret_uint64(c_section_tree, tvb, offset,
2810 hf_oran_reMask, ett_oran_remask, remask_flags, ENC_BIG_ENDIAN0x00000000, &remask);
2811 offset++;
2812 /* numSymbol */
2813 uint32_t numSymbol;
2814 numsymbol_ti = proto_tree_add_item_ret_uint(c_section_tree, hf_oran_numSymbol, tvb, offset, 1, ENC_NA0x00000000, &numSymbol);
2815 if ((sectionType == SEC_C_RRM_MEAS_REPORTS) && (numSymbol != 14)) { /* Section type 10 must have 14 symbols */
2816 proto_item_append_text(numsymbol_ti, " (for ST10, should be 14!)");
2817 expert_add_info_format(pinfo, numsymbol_ti, &ei_oran_st10_numsymbol_not_14,
2818 "numSymbol should be 14 for ST10 - found %u", numSymbol);
2819 }
2820 if ((startSymbolId + numSymbol) > 14) {
2821 /* Warn if startSymbol + numSymbol would be > 14 */
2822 expert_add_info_format(pinfo, numsymbol_ti, &ei_oran_too_many_symbols,
2823 "startSymbolId (%u) + numSymbol (%u) exceeds max of 14",
2824 startSymbolId, numSymbol);
2825 }
2826 offset++;
2827
2828 /* [ef] (extension flag) */
2829 switch (sectionType) {
2830 case SEC_C_UNUSED_RB: /* Section Type 0 */
2831 case SEC_C_NORMAL: /* Section Type 1 */
2832 case SEC_C_PRACH: /* Section Type 3 */
2833 case SEC_C_UE_SCHED: /* Section Type 5 */
2834 case SEC_C_RRM_MEAS_REPORTS: /* Section Type 10 */
2835 case SEC_C_REQUEST_RRM_MEAS: /* Section Type 11 */
2836 proto_tree_add_item_ret_boolean(c_section_tree, hf_oran_ef, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &extension_flag);
2837 break;
2838 default:
2839 /* Other section types don't support extensions */
2840 break;
2841 }
2842
2843 write_section_info(sectionHeading, pinfo, protocol_item, sectionId, startPrbc, numPrbc, rb);
2844 proto_item_append_text(sectionHeading, ", Symbols: %2u", numSymbol);
2845
2846 if (numPrbc == 0) {
2847 /* Special case for all PRBs */
2848 numPrbc = pref_data_plane_section_total_rbs;
2849 startPrbc = 0; /* may already be 0... */
2850 }
2851 }
2852 else {
2853 /* Section Type 9 */
2854 write_section_info(sectionHeading, pinfo, protocol_item, sectionId, startPrbu, numPrbu, rb);
2855 proto_item_append_text(sectionHeading, ", numSinrPerPrb: %2u", num_sinr_per_prb);
2856 }
2857
2858 /* Section type specific fields (after 'numSymbol') */
2859 switch (sectionType) {
2860 case SEC_C_UNUSED_RB: /* Section Type 0 - Table 7.4.2-1 */
2861 /* reserved (15 bits) */
2862 add_reserved_field(c_section_tree, hf_oran_reserved_15bits, tvb, offset, 2);
2863 offset += 2;
2864 break;
2865
2866 case SEC_C_NORMAL: /* Section Type 1 - Table 7.4.3-1 */
2867 /* beamId */
2868 section_beamId_ti = proto_tree_add_item_ret_uint(c_section_tree, hf_oran_beamId, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &section_beamId);
2869 offset += 2;
2870
2871 /* beamId might get invalidated by e.g., ext-6, ext-11, so unused value will still be shown here.. */
2872 proto_item_append_text(sectionHeading, ", BeamId: %d", section_beamId);
2873 break;
2874
2875 case SEC_C_PRACH: /* Section Type 3 - Table 7.4.5-1 */
2876 {
2877 /* beamId */
2878 section_beamId_ti = proto_tree_add_item_ret_uint(c_section_tree, hf_oran_beamId, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &section_beamId);
2879 offset += 2;
2880
2881 /* freqOffset */
2882 int32_t freqOffset; /* Yes, this is signed, so the cast is intentional. */
2883 proto_item *freq_offset_item = proto_tree_add_item_ret_uint(c_section_tree, hf_oran_freqOffset, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000, (uint32_t*)&freqOffset);
2884 freqOffset |= 0xff000000; /* Must sign-extend */
2885 proto_item_set_text(freq_offset_item, "Frequency offset: %d \u0394f", freqOffset);
2886 offset += 3;
2887
2888 /* reserved (8 bits) */
2889 add_reserved_field(c_section_tree, hf_oran_reserved_8bits, tvb, offset, 1);
2890 offset += 1;
2891
2892 /* beamId might get invalidated by e.g., ext-6, ext-11, so unused value will still be shown here.. */
2893 proto_item_append_text(sectionHeading, ", BeamId: %d, FreqOffset: %d \u0394f", section_beamId, freqOffset);
2894 break;
2895 }
2896
2897 case SEC_C_UE_SCHED: /* Section Type 5 - Table 7.4.7-1 */
2898 case SEC_C_RRM_MEAS_REPORTS: /* Section Type 10 - Table 7.4.12-1 */
2899 /* ueId */
2900 ueId_ti = proto_tree_add_item_ret_uint(c_section_tree, hf_oran_ueId, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &ueId);
2901 offset += 2;
2902 if (ueId == 0x7fff) {
2903 proto_item_append_text(ueId_ti, " (PRBs not scheduled for eAxC ID in transport header)");
2904 }
2905 else {
2906 ueids[number_of_ueids++] = ueId;
2907 }
2908
2909 proto_item_append_text(sectionHeading, ", UEId: %d", ueId);
2910 break;
2911
2912 case SEC_C_SINR_REPORTING: /* Section Type 9 - SINR Reporting */
2913 {
2914 /* Hidden filter for bf (DMFS-BF) */
2915 proto_item *bf_ti = proto_tree_add_item(tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
2916 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
2917
2918 unsigned bit_offset = offset*8;
2919
2920 /* sinr iqWidth */
2921 proto_item *iq_width_item = proto_tree_add_uint(c_section_tree, hf_oran_sinrCompHdrIqWidth_pref, tvb, 0, 0, pref_sample_bit_width_sinr);
2922 proto_item_append_text(iq_width_item, " (from preferences)");
2923 proto_item_set_generated(iq_width_item);
2924
2925 /* sinr compMethod */
2926 proto_item *sinr_comp_meth_item = proto_tree_add_uint(c_section_tree, hf_oran_sinrCompHdrMeth_pref, tvb, 0, 0, pref_iqCompressionSINR);
2927 proto_item_append_text(sinr_comp_meth_item, " (from preferences)");
2928 proto_item_set_generated(sinr_comp_meth_item);
2929
2930 /* Add SINR entries for each PRB */
2931 for (unsigned prb=startPrbu; prb < startPrbu+numPrbu; prb++) {
2932 /* Create a subtree for each PRB */
2933 proto_item *prb_ti = proto_tree_add_string_format(c_section_tree, hf_oran_sinr_prb,
2934 tvb, offset, 0, "", "PRB %3u (", prb);
2935 proto_tree *prb_tree = proto_item_add_subtree(prb_ti, ett_oran_sinr_prb);
2936
2937 /* Each prb starts byte-aligned */
2938 bit_offset = ((bit_offset+7)/8) * 8;
2939
2940 /* N.B., using width/method from UL U-plane preferences, not certain that this is correct.. */
2941
2942 /* sinrCompParam (udCompParam format, may be empty) */
2943 uint32_t exponent = 0; /* N.B. init to silence warnings, but will always be set if read in COMP_BLOCK_FP case */
2944 uint16_t sReSMask;
2945 bit_offset = dissect_udcompparam(tvb, pinfo, prb_tree, bit_offset/8,
2946 pref_iqCompressionSINR, &exponent, &sReSMask,
2947 true1) * 8; /* last param is for_sinr */
2948
2949 /* sinrValues for this PRB. */
2950 /* TODO: not sure how numSinrPerPrb interacts with rb==1... */
2951 for (unsigned n=0; n < num_sinr_per_prb; n++) {
2952 unsigned sinr_bits = tvb_get_bits32(tvb, bit_offset, pref_sample_bit_width_sinr, ENC_BIG_ENDIAN0x00000000);
2953
2954 /* Using SINR compression settings from preferences */
2955 float value = decompress_value(sinr_bits,
2956 pref_iqCompressionSINR, pref_sample_bit_width_sinr,
2957 exponent,
2958 NULL((void*)0) /* no ModCompr for SINR */, 0 /* RE */);
2959 unsigned sample_len_in_bytes = ((bit_offset%8)+pref_sample_bit_width_sinr+7)/8;
2960 proto_item *val_ti = proto_tree_add_float(prb_tree, hf_oran_sinr_value, tvb,
2961 bit_offset/8, sample_len_in_bytes, value);
2962 proto_item_append_text(prb_ti, " %8f", value);
2963
2964 /* Show here which subcarriers share which values (they all divide 12..) */
2965 if (num_sinr_per_prb == 12) {
2966 proto_item_append_text(val_ti, " (PRB=%u, subcarrier %u)",
2967 startPrbu+((prb-startPrbu)*(rb+1)), n*(12/num_sinr_per_prb));
2968 }
2969 else {
2970 proto_item_append_text(val_ti, " (PRB=%u, subcarriers %u-%u)",
2971 startPrbu+((prb-startPrbu)*(rb+1)),
2972 n*(12/num_sinr_per_prb), (n+1)*(12/num_sinr_per_prb)-1);
2973 }
2974 bit_offset += pref_sample_bit_width_sinr;
2975 }
2976
2977 /* 1-byte alignment per PRB (7.2.11) */
2978 offset = (bit_offset+7)/8;
2979 bit_offset = offset*8;
2980
2981 proto_item_append_text(prb_ti, ")");
2982 proto_item_set_end(prb_ti, tvb, offset);
2983 }
2984 break;
2985 }
2986 case SEC_C_REQUEST_RRM_MEAS: /* Section Type 11 - Request RRM Measurements */
2987 /* Reserved (15 bits) */
2988 add_reserved_field(c_section_tree, hf_oran_reserved_15bits, tvb, offset, 2);
2989 offset += 2;
2990 break;
2991
2992 default:
2993 break;
2994 }
2995 }
2996 else if (sectionType == SEC_C_CH_INFO) { /* Section Type 6 */
2997 /* ef */
2998 proto_tree_add_item_ret_boolean(c_section_tree, hf_oran_ef, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &extension_flag);
2999 /* ueId */
3000 proto_tree_add_item_ret_uint(c_section_tree, hf_oran_ueId, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &ueId);
3001 offset += 2;
3002 /* regularizationFactor */
3003 proto_tree_add_item(c_section_tree, hf_oran_regularizationFactor, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
3004 offset += 2;
3005 /* reserved (4 bits) */
3006 add_reserved_field(c_section_tree, hf_oran_reserved_4bits, tvb, offset, 1);
3007 /* rb ("Value=0 shall be set") */
3008 uint32_t rb;
3009 proto_item *rb_ti = proto_tree_add_item_ret_uint(c_section_tree, hf_oran_rb, tvb, offset, 1, ENC_NA0x00000000, &rb);
3010 if (rb != 0) {
3011 proto_item_append_text(rb_ti, " (should be set to 0)");
3012 expert_add_info(pinfo, rb_ti, &ei_oran_st6_rb_shall_be_0);
3013 }
3014 /* symInc */
3015 proto_tree_add_item(c_section_tree, hf_oran_symInc, tvb, offset, 1, ENC_NA0x00000000);
3016 /* startPrbc */
3017 proto_tree_add_item_ret_uint(c_section_tree, hf_oran_startPrbc, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &startPrbc);
3018 offset += 2;
3019 /* numPrbc */
3020 proto_tree_add_item_ret_uint(c_section_tree, hf_oran_numPrbc, tvb, offset, 1, ENC_NA0x00000000, &numPrbc);
3021 offset += 1;
3022
3023 /* Hidden filter for bf */
3024 proto_item *bf_ti = proto_tree_add_item(tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
3025 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
3026
3027 /* ciIsample,ciQsample pairs */
3028 unsigned m;
3029 unsigned prb;
3030 uint32_t bit_offset = offset*8;
3031
3032 /* Antenna count from preference */
3033 unsigned num_trx = pref_num_bf_antennas;
3034
3035 write_channel_section_info(sectionHeading, pinfo,
3036 sectionId, ueId, startPrbc, numPrbc, num_trx);
3037
3038 bool_Bool first_prb = true1;
3039 uint8_t exponent = 0;
3040 for (prb=startPrbc; prb < startPrbc+numPrbc; prb++) {
3041
3042 /* PRB subtree */
3043 unsigned prb_start_offset = bit_offset;
3044 proto_item *prb_ti = proto_tree_add_string_format(c_section_tree, hf_oran_samples_prb,
3045 tvb, bit_offset/8, 0,
3046 "", "PRB=%u", prb);
3047 proto_tree *prb_tree = proto_item_add_subtree(prb_ti, ett_oran_prb_cisamples);
3048
3049 /* There may be a ciCompParam here.. */
3050 if (first_prb || ci_comp_opt==1) {
3051 bit_offset = dissect_ciCompParam(tvb, prb_tree, pinfo, bit_offset, ci_comp_meth, &exponent);
3052 }
3053 first_prb = false0;
3054
3055 /* Antennas */
3056 for (m=0; m < num_trx; m++) {
3057
3058 unsigned sample_offset = bit_offset / 8;
3059 uint8_t sample_extent = ((bit_offset + (ci_iq_width*2)) / 8) - sample_offset;
3060
3061 /* Create subtree for antenna */
3062 proto_item *sample_ti = proto_tree_add_string_format(prb_tree, hf_oran_ciSample,
3063 tvb, sample_offset, sample_extent,
3064 "", "TRX=%2u: ", m);
3065 proto_tree *sample_tree = proto_item_add_subtree(sample_ti, ett_oran_cisample);
3066
3067 /* I */
3068 /* Get bits, and convert to float. */
3069 uint32_t bits = tvb_get_bits32(tvb, bit_offset, ci_iq_width, ENC_BIG_ENDIAN0x00000000);
3070 float value = decompress_value(bits, ci_comp_meth, ci_iq_width, exponent, NULL((void*)0) /* no ModCompr for ST6 */, 0 /* RE */);
3071
3072 /* Add to tree. */
3073 proto_tree_add_float_format_value(sample_tree, hf_oran_ciIsample, tvb, bit_offset/8, (ci_iq_width+7)/8, value, "#%u=%f", m, value);
3074 bit_offset += ci_iq_width;
3075 proto_item_append_text(sample_ti, "I%u=%f ", m, value);
3076
3077 /* Q */
3078 /* Get bits, and convert to float. */
3079 bits = tvb_get_bits32(tvb, bit_offset, ci_iq_width, ENC_BIG_ENDIAN0x00000000);
3080 value = decompress_value(bits, ci_comp_meth, ci_iq_width, exponent, NULL((void*)0) /* no ModCompr for ST6 */, 0 /* RE */);
3081
3082 /* Add to tree. */
3083 proto_tree_add_float_format_value(sample_tree, hf_oran_ciQsample, tvb, bit_offset/8, (ci_iq_width+7)/8, value, "#%u=%f", m, value);
3084 bit_offset += ci_iq_width;
3085 proto_item_append_text(sample_ti, "Q%u=%f ", m, value);
3086 }
3087 proto_item_set_len(prb_ti, (bit_offset-prb_start_offset+7)/8);
3088 }
3089
3090 /* Pad out by 1 or 4 bytes, according to preference */
3091 if (!st6_4byte_alignment) {
3092 offset = (bit_offset + 7) / 8;
3093 }
3094 else {
3095 int mode = bit_offset % 32;
3096 if (mode != 0) {
3097 offset = (bit_offset + (32-mode))/8;
3098 }
3099 else {
3100 offset = bit_offset/8;
3101 }
3102 }
3103 proto_item_set_end(c_section_tree, tvb, offset);
3104 }
3105
3106
3107 expected_section_data_t *dl_data_section = NULL((void*)0);
3108 unsigned index_to_use = 0;
3109
3110 /* On first pass, allocate a section entry to use */
3111 if (link_planes_together && !PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
3112
3113 if (!tap_info->uplink) {
3114 /* Look for existing entry for sectionId to overwrite first. */
3115 dl_data_section = wmem_tree_lookup32(state->expected_dl_sections,
3116 sectionId);
3117 if (dl_data_section == NULL((void*)0)) {
3118 /* None, so create */
3119 dl_data_section = wmem_new0(wmem_file_scope(), expected_section_data_t)((expected_section_data_t*)wmem_alloc0((wmem_file_scope()), sizeof
(expected_section_data_t)))
;
3120 wmem_tree_insert32(state->expected_dl_sections,
3121 sectionId,
3122 dl_data_section);
3123 }
3124
3125 /* If 2nd entry not in use, use that one */
3126 if (!dl_data_section->details[1].in_use) {
3127 index_to_use = 1;
3128 }
3129 else {
3130 /* Both in use, so replace the older of the 2 entries */
3131 if (dl_data_section->details[1].frame_number < dl_data_section->details[0].frame_number) {
3132 index_to_use = 1;
3133 }
3134 }
3135
3136 if (dl_data_section) {
3137 section_details_t *details = &dl_data_section->details[index_to_use];
3138
3139 details->in_use = true1;
3140 details->frame = frameId;
3141 details->subframe = subframeId;
3142 details->slot = slotId;
3143 details->startSymbol = startSymbolId;
3144
3145 details->frame_number = pinfo->num;
3146 details->frame_time = pinfo->abs_ts;
3147 dl_data_section->sectionId = sectionId;
3148 details->startPrb = startPrbc;
3149 details->numPrb = numPrbc;
3150 for (unsigned prb = startPrbc; prb <= startPrbc+numPrbc; prb++) {
3151 if (prb < 273) {
3152 details->beamIds[prb] = section_beamId;
3153 }
3154 }
3155 }
3156 }
3157 }
3158
3159 bool_Bool seen_se10 = false0;
3160 uint32_t numPortc = 0;
3161 proto_item *bf_ti = NULL((void*)0);
3162
3163 /* Section extension commands */
3164 while (extension_flag) {
3165 int extension_start_offset = offset;
3166
3167 /* Prefetch extType so can use specific extension type ett */
3168 uint32_t exttype = tvb_get_uint8(tvb, offset) & 0x7f;
3169 uint32_t exttype_ett_index = exttype;
3170 if (exttype == 0 || exttype > HIGHEST_EXTTYPE32) {
3171 /* Just use first one if out of range */
3172 exttype_ett_index = 1;
3173 }
3174
3175 /* Create subtree for each extension (with summary) */
3176 proto_item *extension_ti = proto_tree_add_string_format(c_section_tree, hf_oran_extension,
3177 tvb, offset, 0, "", "Extension");
3178 proto_tree *extension_tree = proto_item_add_subtree(extension_ti, ett_oran_c_section_extension[exttype_ett_index-1]);
3179
3180 /* ef (i.e. another extension after this one?) */
3181 proto_tree_add_item_ret_boolean(extension_tree, hf_oran_ef, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &extension_flag);
3182
3183 /* extType */
3184 proto_item *exttype_ti;
3185 exttype_ti = proto_tree_add_item(extension_tree, hf_oran_exttype, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3186 offset++;
3187 proto_item_append_text(sectionHeading, " (ext-%u)", exttype);
3188
3189 proto_item_append_text(extension_ti, " (ext-%u: %s)", exttype, val_to_str_ext_const(exttype, &exttype_vals_ext, "Reserved"));
3190
3191 /* Don't tap if out of range. */
3192 if (exttype > 0 && exttype <= HIGHEST_EXTTYPE32) {
3193 tap_info->extensions[exttype] = true1;
3194 }
3195
3196 /* Is this SE allowed for this section type? */
3197 if (!se_allowed_in_st(exttype, sectionType)) {
3198 expert_add_info_format(pinfo, extension_tree, &ei_oran_se_on_unsupported_st,
3199 "SE %u (%s) should not appear in ST %u (%s)!",
3200 exttype, val_to_str_ext_const(exttype, &exttype_vals_ext, "Reserved"),
3201 sectionType, rval_to_str_const(sectionType, section_types, "Unknown"));
3202 }
3203
3204
3205 /* extLen (number of 32-bit words) */
3206 uint32_t extlen_len = ((exttype==11)||(exttype==19)||(exttype==20)) ? 2 : 1; /* Extensions 11/19/20 are special */
3207 uint32_t extlen;
3208 proto_item *extlen_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_extlen, tvb,
3209 offset, extlen_len, ENC_BIG_ENDIAN0x00000000, &extlen);
3210 proto_item_append_text(extlen_ti, " (%u bytes)", extlen*4);
3211 offset += extlen_len;
3212 if (extlen == 0) {
3213 expert_add_info(pinfo, extlen_ti, &ei_oran_extlen_zero);
3214 /* Break out to avoid infinitely looping! */
3215 break;
3216 }
3217
3218 bool_Bool ext_unhandled = false0;
3219
3220 switch (exttype) {
3221
3222 case 1: /* SE 1: Beamforming Weights */
3223 {
3224 uint32_t bfwcomphdr_iq_width, bfwcomphdr_comp_meth;
3225 proto_item *comp_meth_ti = NULL((void*)0);
3226
3227 /* Hidden filter for bf */
3228 bf_ti = proto_tree_add_item(tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
3229 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
3230
3231 /* bfwCompHdr (2 subheaders - bfwIqWidth and bfwCompMeth)*/
3232 offset = dissect_bfwCompHdr(tvb, extension_tree, offset,
3233 &bfwcomphdr_iq_width, &bfwcomphdr_comp_meth, &comp_meth_ti);
3234
3235 /* bfwCompParam */
3236 uint32_t exponent = 0;
3237 bool_Bool compression_method_supported = false0;
3238 unsigned num_trx = 0;
3239 uint16_t *trx; /* ptr to array */
3240 offset = dissect_bfwCompParam(tvb, extension_tree, pinfo, offset, comp_meth_ti,
3241 &bfwcomphdr_comp_meth, &exponent, &compression_method_supported,
3242 &num_trx, &trx);
3243
3244 /* Can't show details of unsupported compression method */
3245 if (!compression_method_supported) {
3246 break;
3247 }
3248
3249 /* We know:
3250 - iq_width (above)
3251 - numBfWeights (taken from preference)
3252 - remaining bytes in extension
3253 We can therefore derive TRX (number of antennas).
3254 */
3255
3256 bool_Bool using_array = false0;
3257
3258 /* I & Q samples
3259 May know how many entries from activeBeamspaceCoefficientMask. */
3260 if (num_trx == 0) {
3261 /* Don't know how many there will be, so just fill available bytes... */
3262 unsigned weights_bytes = (extlen*4)-3;
3263 unsigned num_weights_pairs = (weights_bytes*8) / (bfwcomphdr_iq_width*2);
3264 num_trx = num_weights_pairs;
3265 }
3266 else {
3267 using_array = true1;
3268 num_trx = pref_num_bf_antennas;
3269 }
3270
3271 int bit_offset = offset*8;
3272
3273 for (unsigned n=0; n < num_trx; n++) {
3274 /* Create antenna subtree */
3275 int bfw_offset = bit_offset / 8;
3276
3277 uint16_t trx_index = (using_array) ? trx[n] : n+1;
3278
3279 proto_item *bfw_ti = proto_tree_add_string_format(extension_tree, hf_oran_bfw,
3280 tvb, bfw_offset, 0, "", "TRX %3u: (", trx_index);
3281 proto_tree *bfw_tree = proto_item_add_subtree(bfw_ti, ett_oran_bfw);
3282
3283 /* I value */
3284 /* Get bits, and convert to float. */
3285 uint32_t bits = tvb_get_bits32(tvb, bit_offset, bfwcomphdr_iq_width, ENC_BIG_ENDIAN0x00000000);
3286 float value = decompress_value(bits, bfwcomphdr_comp_meth, bfwcomphdr_iq_width, exponent,
3287 NULL((void*)0) /* no ModCompr */, 0 /* RE */);
3288 /* Add to tree. */
3289 proto_tree_add_float(bfw_tree, hf_oran_bfw_i, tvb, bit_offset/8,
3290 (bfwcomphdr_iq_width+7)/8, value);
3291 bit_offset += bfwcomphdr_iq_width;
3292 proto_item_append_text(bfw_ti, "I=%f ", value);
3293
3294 /* Leave a gap between I and Q values */
3295 proto_item_append_text(bfw_ti, " ");
3296
3297 /* Q value */
3298 /* Get bits, and convert to float. */
3299 bits = tvb_get_bits32(tvb, bit_offset, bfwcomphdr_iq_width, ENC_BIG_ENDIAN0x00000000);
3300 value = decompress_value(bits, bfwcomphdr_comp_meth, bfwcomphdr_iq_width, exponent,
3301 NULL((void*)0) /* no ModCompr */, 0 /* RE */);
3302 /* Add to tree. */
3303 proto_tree_add_float(bfw_tree, hf_oran_bfw_q, tvb, bit_offset/8,
3304 (bfwcomphdr_iq_width+7)/8, value);
3305 bit_offset += bfwcomphdr_iq_width;
3306 proto_item_append_text(bfw_ti, "Q=%f", value);
3307
3308 proto_item_append_text(bfw_ti, ")");
3309 proto_item_set_len(bfw_ti, (bit_offset+7)/8 - bfw_offset);
3310 }
3311 /* Need to round to next byte */
3312 offset = (bit_offset+7)/8;
3313
3314 break;
3315 }
3316
3317 case 2: /* SE 2: Beamforming attributes */
3318 {
3319 /* Hidden filter for bf */
3320 bf_ti = proto_tree_add_item(tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
3321 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
3322
3323 /* bfaCompHdr (get widths of fields to follow) */
3324 uint32_t bfAzPtWidth, bfZePtWidth, bfAz3ddWidth, bfZe3ddWidth;
3325 /* subtree */
3326 proto_item *bfa_ti = proto_tree_add_string_format(extension_tree, hf_oran_bfaCompHdr,
3327 tvb, offset, 2, "", "bfaCompHdr");
3328 proto_tree *bfa_tree = proto_item_add_subtree(bfa_ti, ett_oran_bfacomphdr);
3329
3330 /* reserved (2 bits) */
3331 add_reserved_field(bfa_tree, hf_oran_reserved_2bits, tvb, offset, 1);
3332 /* bfAzPtWidth (3 bits) */
3333 proto_tree_add_item_ret_uint(bfa_tree, hf_oran_bfAzPtWidth, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &bfAzPtWidth);
3334 /* bfZePtWidth (3 bits) */
3335 proto_tree_add_item_ret_uint(bfa_tree, hf_oran_bfZePtWidth, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &bfZePtWidth);
3336 offset += 1;
3337
3338 /* reserved (2 bits) */
3339 add_reserved_field(bfa_tree, hf_oran_reserved_2bits, tvb, offset, 1);
3340 /* bfAz3ddWidth (3 bits) */
3341 proto_tree_add_item_ret_uint(bfa_tree, hf_oran_bfAz3ddWidth, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &bfAz3ddWidth);
3342 /* bfZe3ddWidth (3 bits) */
3343 proto_tree_add_item_ret_uint(bfa_tree, hf_oran_bfZe3ddWidth, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &bfZe3ddWidth);
3344 offset += 1;
3345
3346 unsigned bit_offset = offset*8;
3347
3348 /* bfAzPt */
3349 if (bfAzPtWidth > 0) {
3350 proto_tree_add_bits_item(extension_tree, hf_oran_bfAzPt, tvb, bit_offset, bfAzPtWidth+1, ENC_BIG_ENDIAN0x00000000);
3351 bit_offset += (bfAzPtWidth+1);
3352 }
3353 /* bfZePt */
3354 if (bfZePtWidth > 0) {
3355 proto_tree_add_bits_item(extension_tree, hf_oran_bfZePt, tvb, bit_offset, bfZePtWidth+1, ENC_BIG_ENDIAN0x00000000);
3356 bit_offset += (bfZePtWidth+1);
3357 }
3358 /* bfAz3dd */
3359 if (bfAz3ddWidth > 0) {
3360 proto_tree_add_bits_item(extension_tree, hf_oran_bfAz3dd, tvb, bit_offset, bfAz3ddWidth+1, ENC_BIG_ENDIAN0x00000000);
3361 bit_offset += (bfAz3ddWidth+1);
3362 }
3363 /* bfZe3dd */
3364 if (bfZe3ddWidth > 0) {
3365 proto_tree_add_bits_item(extension_tree, hf_oran_bfZe3dd, tvb, bit_offset, bfZe3ddWidth+1, ENC_BIG_ENDIAN0x00000000);
3366 bit_offset += (bfZe3ddWidth+1);
3367 }
3368
3369 /* Pad to next byte (unless last 2 fields already fit in this one) */
3370 if ((bit_offset % 8) > 2) {
3371 offset = (bit_offset+7) / 8;
3372 }
3373 else {
3374 offset = bit_offset / 8;
3375 }
3376
3377 /* bfAzSl (3 bits) */
3378 proto_tree_add_item(extension_tree, hf_oran_bfAzSl, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3379 /* bfZeSl (3 bits) */
3380 proto_tree_add_item(extension_tree, hf_oran_bfZeSl, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3381 offset += 1;
3382 break;
3383 }
3384
3385 case 3: /* SE 3: DL precoding parameters */
3386 {
3387 /* codebookindex (8 bits) */
3388 /* "This parameter is not used and shall be set to zero." */
3389 proto_tree_add_item(extension_tree, hf_oran_codebook_index, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3390 offset += 1;
3391 /* layerid */
3392 uint32_t layerid;
3393 proto_tree_add_item_ret_uint(extension_tree, hf_oran_layerid, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &layerid);
3394 /* numLayers */
3395 proto_tree_add_item(extension_tree, hf_oran_numlayers, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3396 offset += 1;
3397
3398 /* Stop here for non-first data layer */
3399 if (layerid != 0 && layerid != 0xf) {
3400 break;
3401 }
3402
3403 /* First data layer case */
3404 /* txScheme */
3405 proto_tree_add_item(extension_tree, hf_oran_txscheme, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3406 /* crsReMask */
3407 proto_tree_add_item(extension_tree, hf_oran_crs_remask, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
3408 offset += 2;
3409
3410 /* crsShift (1 bit) */
3411 proto_tree_add_item(extension_tree, hf_oran_crs_shift, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3412 /* reserved (3 bits) */
3413 add_reserved_field(extension_tree, hf_oran_reserved_bits123, tvb, offset, 1);
3414 /* crsSymNum (4 bits) */
3415 proto_tree_add_item(extension_tree, hf_oran_crs_symnum, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3416 offset += 1;
3417 /* reserved (8 bits) */
3418 add_reserved_field(extension_tree, hf_oran_reserved_8bits, tvb, offset, 1);
3419 offset += 1;
3420
3421 /* reserved (1 bit) */
3422 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
3423 /* beamIdAP1 (15 bits) */
3424 proto_tree_add_item(extension_tree, hf_oran_beamid_ap1, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
3425 offset += 2;
3426 /* reserved (1 bit) */
3427 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
3428 /* beamIdAP2 (15 bits) */
3429 proto_tree_add_item(extension_tree, hf_oran_beamid_ap2, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
3430 offset += 2;
3431 /* reserved (1 bit) */
3432 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
3433 /* beamIdAP3 (15 bits) */
3434 proto_tree_add_item(extension_tree, hf_oran_beamid_ap3, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
3435 offset += 2;
3436 break;
3437 }
3438
3439 case 4: /* SE 4: Modulation compression params (5.4.7.4) (single sets) */
3440 {
3441 /* csf */
3442 bool_Bool csf;
3443 dissect_csf(extension_tree, tvb, offset*8, ci_iq_width, &csf);
3444
3445 /* modCompScaler */
3446 uint32_t modCompScaler;
3447 proto_item *ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_modcompscaler,
3448 tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &modCompScaler);
3449 offset += 2;
3450
3451 /* Work out and show floating point value too. exponent and mantissa are both unsigned */
3452 uint16_t exponent = (modCompScaler >> 11) & 0x000f; /* m.s. 4 bits */
3453 uint16_t mantissa = modCompScaler & 0x07ff; /* l.s. 11 bits */
3454 float value = ((float)mantissa/(1<<11)) * ((float)1.0 / (1 << exponent));
3455 proto_item_append_text(ti, " (%f)", value);
3456
3457 section_mod_compr_config_t* sect_config = get_mod_compr_section_to_write(state, sectionId);
3458
3459 /* Store these params in this flow's state */
3460 if (sect_config && sect_config->num_configs < MAX_MOD_COMPR_CONFIGS12) {
3461 unsigned i = sect_config->num_configs;
3462 sect_config->configs[i].mod_compr_re_mask = 0xfff; /* Covers all REs */
3463 sect_config->configs[i].mod_compr_csf = csf;
3464 sect_config->configs[i].mod_compr_scaler = value;
3465 sect_config->num_configs++;
3466 }
3467 break;
3468 }
3469
3470 case 5: /* SE 5: Modulation Compression Additional Parameters (7.7.5) (multiple sets) */
3471 {
3472 /* Applies only to section types 1,3 and 5 */
3473 /* N.B. there may be multiple instances of this SE in the same frame */
3474
3475 /* There may be one or 2 entries, depending upon extlen */
3476 int sets = 1, reserved_bits = 0;
3477 switch (extlen) {
3478 case 2:
3479 sets = 1;
3480 reserved_bits = 20;
3481 break;
3482 case 3:
3483 sets = 2;
3484 reserved_bits = 24;
3485 break;
3486 case 4:
3487 /* sets can be 3 or 4, depending upon whether last 28 bits are 0.. */
3488 if ((tvb_get_ntohl(tvb, offset+10) & 0x0fffffff) == 0) {
3489 sets = 3;
3490 reserved_bits = 28;
3491 }
3492 else {
3493 sets = 4;
3494 reserved_bits = 0;
3495 }
3496 break;
3497
3498 default:
3499 /* Malformed error!!! */
3500 expert_add_info_format(pinfo, extlen_ti, &ei_oran_extlen_wrong,
3501 "For section 5, extlen must be 2, 3 or 4, but %u was dissected",
3502 extlen);
3503 break;
3504 }
3505
3506 unsigned bit_offset = offset*8;
3507 /* Dissect each set */
3508 for (int n=0; n < sets; n++) {
3509 /* Subtree for each set */
3510 unsigned set_start_offset = bit_offset/8;
3511 proto_item *set_ti = proto_tree_add_string(extension_tree, hf_oran_modcomp_param_set,
3512 tvb, set_start_offset, 0, "");
3513 proto_tree *set_tree = proto_item_add_subtree(set_ti, ett_oran_modcomp_param_set);
3514
3515 uint64_t mcScaleReMask, mcScaleOffset;
3516 bool_Bool csf;
3517
3518 /* mcScaleReMask (12 bits). Defines which REs the following csf and mcScaleOffset apply to */
3519 static int * const remask_flags[] = {
3520 &hf_oran_mc_scale_re_mask_re1,
3521 &hf_oran_mc_scale_re_mask_re2,
3522 &hf_oran_mc_scale_re_mask_re3,
3523 &hf_oran_mc_scale_re_mask_re4,
3524 &hf_oran_mc_scale_re_mask_re5,
3525 &hf_oran_mc_scale_re_mask_re6,
3526 &hf_oran_mc_scale_re_mask_re7,
3527 &hf_oran_mc_scale_re_mask_re8,
3528 &hf_oran_mc_scale_re_mask_re9,
3529 &hf_oran_mc_scale_re_mask_re10,
3530 &hf_oran_mc_scale_re_mask_re11,
3531 &hf_oran_mc_scale_re_mask_re12,
3532 NULL((void*)0)
3533 };
3534 /* Same as above, but offset by 4 bits */
3535 static int * const remask_flags_even[] = {
3536 &hf_oran_mc_scale_re_mask_re1_even,
3537 &hf_oran_mc_scale_re_mask_re2_even,
3538 &hf_oran_mc_scale_re_mask_re3_even,
3539 &hf_oran_mc_scale_re_mask_re4_even,
3540 &hf_oran_mc_scale_re_mask_re5_even,
3541 &hf_oran_mc_scale_re_mask_re6_even,
3542 &hf_oran_mc_scale_re_mask_re7_even,
3543 &hf_oran_mc_scale_re_mask_re8_even,
3544 &hf_oran_mc_scale_re_mask_re9_even,
3545 &hf_oran_mc_scale_re_mask_re10_even,
3546 &hf_oran_mc_scale_re_mask_re11_even,
3547 &hf_oran_mc_scale_re_mask_re12_even,
3548 NULL((void*)0)
3549 };
3550
3551 /* RE Mask (12 bits) */
3552 proto_tree_add_bitmask_ret_uint64(set_tree, tvb, bit_offset / 8,
3553 (n % 2) ? hf_oran_mc_scale_re_mask_even : hf_oran_mc_scale_re_mask,
3554 ett_oran_mc_scale_remask,
3555 (n % 2) ? remask_flags_even : remask_flags, ENC_BIG_ENDIAN0x00000000, &mcScaleReMask);
3556 bit_offset += 12;
3557
3558 /* csf (1 bit) */
3559 bit_offset = dissect_csf(set_tree, tvb, bit_offset, ci_iq_width, &csf);
3560 /* mcScaleOffset (15 bits) */
3561 proto_item *ti = proto_tree_add_bits_ret_val(set_tree, hf_oran_mc_scale_offset, tvb, bit_offset, 15, &mcScaleOffset, ENC_BIG_ENDIAN0x00000000);
3562 uint16_t exponent = (mcScaleOffset >> 11) & 0x000f; /* m.s. 4 bits */
3563 uint16_t mantissa = mcScaleOffset & 0x07ff; /* l.s. 11 bits */
3564 float mcScaleOffset_value = ((float)mantissa/(1<<11)) * ((float)1.0 / (1 << exponent));
3565 proto_item_append_text(ti, " (%f)", mcScaleOffset_value);
3566 bit_offset += 15;
3567
3568 section_mod_compr_config_t* sect_config = get_mod_compr_section_to_write(state, sectionId);
3569
3570 /* Record this config */
3571 if (sect_config && sect_config->num_configs < MAX_MOD_COMPR_CONFIGS12) {
3572 unsigned i = sect_config->num_configs;
3573 sect_config->configs[i].mod_compr_re_mask = (uint16_t)mcScaleReMask;
3574 sect_config->configs[i].mod_compr_csf = csf;
3575 sect_config->configs[i].mod_compr_scaler = mcScaleOffset_value;
3576 sect_config->num_configs++;
3577 }
3578
3579 /* Summary */
3580 proto_item_set_len(set_ti, (bit_offset+7)/8 - set_start_offset);
3581 proto_item_append_text(set_ti, " (mcScaleReMask=0x%03x csf=%5s mcScaleOffset=%f)",
3582 (unsigned)mcScaleReMask, tfs_get_true_false(csf)tfs_get_string(csf, ((void*)0)), mcScaleOffset_value);
3583 }
3584
3585 proto_item_append_text(extension_ti, " (%u sets)", sets);
3586
3587 /* Reserved (variable-length) */
3588 if (reserved_bits) {
3589 proto_tree_add_bits_item(extension_tree, hf_oran_reserved, tvb, bit_offset, reserved_bits, ENC_BIG_ENDIAN0x00000000);
3590 bit_offset += reserved_bits;
3591 }
3592
3593 offset = bit_offset/8;
3594 break;
3595 }
3596
3597 case 6: /* SE 6: Non-contiguous PRB allocation in time and frequency domain */
3598 {
3599 /* numSymbol not used in this case */
3600 if (numsymbol_ti && !numsymbol_ignored) {
3601 proto_item_append_text(numsymbol_ti, " (ignored)");
3602 numsymbol_ignored = true1;
3603 }
3604
3605 /* Will update ext6 recorded info */
3606 ext11_settings.ext6_set = true1;
3607
3608 /* repetition */
3609 proto_tree_add_bits_item(extension_tree, hf_oran_se6_repetition, tvb, offset*8, 1, ENC_BIG_ENDIAN0x00000000);
3610 /* rbgSize (PRBs per bit set in rbgMask) */
3611 uint32_t rbgSize;
3612 proto_item *rbg_size_ti;
3613 rbg_size_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_rbgSize, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &rbgSize);
3614 if (rbgSize == 0) {
3615 /* N.B. this is only true if "se6-rb-bit-supported" is set... */
3616 expert_add_info(pinfo, rbg_size_ti, &ei_oran_rbg_size_reserved);
3617 }
3618 /* rbgMask (28 bits) */
3619 uint32_t rbgMask;
3620 proto_item *rbgmask_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_rbgMask, tvb, offset, 4, ENC_BIG_ENDIAN0x00000000, &rbgMask);
3621 if (rbgSize == 0) {
3622 proto_item_append_text(rbgmask_ti, " (value ignored since rbgSize is 0)");
3623 }
3624
3625 /* TODO: if receiver detects non-zero bits outside the valid range, those shall be ignored. */
3626 offset += 4;
3627 /* priority */
3628 proto_tree_add_item(extension_tree, hf_oran_noncontig_priority, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3629 /* symbolMask */
3630 offset = dissect_symbolmask(tvb, extension_tree, offset, NULL((void*)0), NULL((void*)0));
3631
3632 /* Look up rbg_size enum -> value */
3633 switch (rbgSize) {
3634 case 0:
3635 /* N.B. reserved, but covered above with expert info (would remain 0) */
3636 break;
3637 case 1:
3638 ext11_settings.ext6_rbg_size = 1; break;
3639 case 2:
3640 ext11_settings.ext6_rbg_size = 2; break;
3641 case 3:
3642 ext11_settings.ext6_rbg_size = 3; break;
3643 case 4:
3644 ext11_settings.ext6_rbg_size = 4; break;
3645 case 5:
3646 ext11_settings.ext6_rbg_size = 6; break;
3647 case 6:
3648 ext11_settings.ext6_rbg_size = 8; break;
3649 case 7:
3650 ext11_settings.ext6_rbg_size = 16; break;
3651 /* N.B., encoded in 3 bits, so no other values are possible */
3652 }
3653
3654 /* Set to looked-up value */
3655 rbgSize = ext11_settings.ext6_rbg_size;
3656
3657 uint32_t lastRbgid = 0;
3658 if (rbgSize != 0) {
3659 /* The O-DU shall not use combinations of startPrbc, numPrbc and rbgSize leading to a value of lastRbgid larger than 27 */
3660 /* i.e., leftmost bit used should not need to go off left end of rbgMask! */
3661 lastRbgid = (uint32_t)ceil((numPrbc + (startPrbc % rbgSize)) / (float)rbgSize) - 1;
3662 if (lastRbgid > 27) {
3663 expert_add_info_format(pinfo, rbg_size_ti, &ei_oran_lastRbdid_out_of_range,
3664 "SE6: rbgSize (%u) not compatible with startPrbc(%u) and numPrbc(%u)",
3665 rbgSize, startPrbc, numPrbc);
3666 break;
3667 }
3668 }
3669
3670 /* Record (and count) which bits are set in rbgMask */
3671 bool_Bool first_seen = false0;
3672 unsigned first_seen_pos=0, last_seen_pos=0;
3673 for (unsigned n=0; n < 28 && ext11_settings.ext6_num_bits_set < 28; n++) {
3674 if ((rbgMask >> n) & 0x01) {
3675 ext11_settings.ext6_bits_set[ext11_settings.ext6_num_bits_set++] = n;
3676 if (!first_seen) {
3677 first_seen = true1;
3678 first_seen_pos = n;
3679 }
3680 last_seen_pos = n;
3681 }
3682 }
3683
3684 /* Show how many bits were set in rbgMask */
3685 proto_item_append_text(rbgmask_ti, " (%u bits set)", ext11_settings.ext6_num_bits_set);
3686 /* Also, that is the range of bits */
3687 if (first_seen) {
3688 proto_item_append_text(rbgmask_ti, " (%u bits spread)", last_seen_pos-first_seen_pos+1);
3689
3690 /* Complain if last set bit is beyond lastRbgid */
3691 if (last_seen_pos > lastRbgid) {
3692 expert_add_info_format(pinfo, rbgmask_ti, &ei_oran_rbgMask_beyond_last_rbdid,
3693 "SE6: rbgMask (0x%07x) has bit %u set, but lastRbgId is %u",
3694 rbgMask, last_seen_pos, lastRbgid);
3695 }
3696 }
3697
3698 /* Also update prbs_for_st10_type5[] */
3699 if (sectionType == 10 && rbgSize != 0) {
3700 /* Unset all entries */
3701 memset(&prbs_for_st10_type5, 0, sizeof(prbs_for_st10_type5));
3702
3703 /* Work out which PRB first bit corresponds to */
3704 unsigned firstPrbStart = (startPrbc/rbgSize) * rbgSize;
3705
3706 /* Add PRBs corresponding to each bit set */
3707 for (unsigned n=0; n < 28 ; n++) {
3708 if ((rbgMask >> n) & 0x01) {
3709 /* Lazy way to clip any values that lie outside of range for section */
3710 for (unsigned p=0; p < rbgSize; p++) {
3711 unsigned start = firstPrbStart + (n*rbgSize);
3712 if ((start+p < MAX_PRBS273) && (start+p >= startPrbc) && (start+p <= startPrbc+numPrbc-1)) {
3713 prbs_for_st10_type5[start+p] = true1;
3714 }
3715 }
3716 }
3717 }
3718 }
3719
3720 break;
3721 }
3722
3723 case 7: /* SE 7: eAxC mask */
3724 /* Allow ST0 to address multiple eAxC_ID values for transmission blanking */
3725 proto_tree_add_item(extension_tree, hf_oran_eAxC_mask, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
3726 offset += 2;
3727 break;
3728
3729 case 8: /* SE 8: Regularization factor */
3730 proto_tree_add_item(extension_tree, hf_oran_regularizationFactor, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
3731 offset += 2;
3732 break;
3733
3734 case 9: /* SE 9: Dynamic Spectrum Sharing parameters */
3735 proto_tree_add_item(extension_tree, hf_oran_technology, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3736 offset += 1;
3737 add_reserved_field(extension_tree, hf_oran_reserved_8bits, tvb, offset, 1);
3738 offset += 1;
3739 break;
3740
3741 case 10: /* SE 10: Group configuration of multiple ports */
3742 {
3743 seen_se10 = true1;
3744
3745 /* beamGroupType */
3746 uint32_t beam_group_type = 0;
3747 proto_item *bgt_ti;
3748 bgt_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_beamGroupType,
3749 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &beam_group_type);
3750 proto_item_append_text(extension_ti, " (%s)", val_to_str_const(beam_group_type, beam_group_type_vals, "Unknown"));
3751
3752 /* numPortc */
3753 proto_tree_add_item_ret_uint(extension_tree, hf_oran_numPortc,
3754 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &numPortc);
3755 offset++;
3756
3757 /* Will append all beamId values to extension_ti, regardless of beamGroupType */
3758 unsigned n;
3759
3760 switch (beam_group_type) {
3761 case 0x0: /* common beam */
3762 case 0x1: /* beam matrix indication */
3763 /* Reserved byte */
3764 add_reserved_field(extension_tree, hf_oran_reserved_8bits, tvb, offset, 1);
3765 offset++;
3766
3767 /* Explain how entries are allocated */
3768 if (beam_group_type == 0x0) {
3769 proto_item_append_text(extension_ti, " (all %u ueid/Beam entries are %u)", numPortc, ueId);
3770 }
3771 else {
3772 /* 'numPortc' consecutive BeamIds from section header */
3773 proto_item_append_text(extension_ti, " (ueId/beam entries are %u -> %u)", ueId, ueId+numPortc);
3774 }
3775
3776 if (sectionType == 5) {
3777 /* These types are not allowed */
3778 expert_add_info_format(pinfo, bgt_ti, &ei_oran_se10_not_allowed,
3779 "SE10: beamGroupType %u is not allowed for section type 5", beam_group_type);
3780 }
3781 break;
3782
3783 case 0x2: /* beam vector listing */
3784 {
3785 proto_item_append_text(extension_ti, " [ ");
3786
3787 /* Beam listing vector case */
3788 /* Work out how many port beam entries there is room for */
3789 /* Using numPortC as visible in issue 18116 */
3790 for (n=0; n < numPortc; n++) {
3791 /* 1 reserved bit */
3792 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
3793
3794 /* port beam ID (or UEID) (15 bits) */
3795 uint32_t id;
3796 proto_item *beamid_or_ueid_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_beamId,
3797 tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &id);
3798 proto_item_append_text(beamid_or_ueid_ti, " port #%u beam ID (or UEId) %u", n, id);
3799 offset += 2;
3800
3801 if (id != 0x7fff) {
3802 if (number_of_ueids < MAX_UEIDS16) {
3803 ueids[number_of_ueids++] = id;
3804 }
3805 }
3806
3807 proto_item_append_text(extension_ti, "%u ", id);
3808 }
3809
3810 proto_item_append_text(extension_ti, "]");
3811 break;
3812 }
3813 case 0x3: /* beamId/ueId listing with associated port-list index */
3814 {
3815 proto_item_append_text(extension_ti, " [ ");
3816
3817 if (numPortc > 0) {
3818 /* first portListIndex is outside loop */
3819 uint32_t port_list_index;
3820 proto_item *pli_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_port_list_index, tvb,
3821 offset, 1, ENC_BIG_ENDIAN0x00000000, &port_list_index);
3822 if (port_list_index == 0) {
3823 /* Value 0 is reserved */
3824 expert_add_info(pinfo, pli_ti, &ei_oran_port_list_index_zero);
3825 }
3826 offset += 1;
3827
3828 for (n=0; n < numPortc-1; n++) {
3829 /* 1 reserved bit */
3830 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
3831
3832 /* port beam ID (or UEID) */
3833 uint32_t id;
3834 proto_item *beamid_or_ueid_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_beamId,
3835 tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &id);
3836 proto_item_append_text(beamid_or_ueid_ti, " port #%u beam ID (or UEId) %u", n, id);
3837 offset += 2;
3838
3839 if (id != 0x7fff) {
3840 if (number_of_ueids < MAX_UEIDS16) {
3841 ueids[number_of_ueids++] = id;
3842 }
3843 }
3844
3845 /* subsequent portListIndex */
3846 pli_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_port_list_index, tvb,
3847 offset, 1, ENC_BIG_ENDIAN0x00000000, &port_list_index);
3848 if (port_list_index == 0) {
3849 /* Value 0 is reserved */
3850 expert_add_info(pinfo, pli_ti, &ei_oran_port_list_index_zero);
3851 }
3852 offset += 1;
3853
3854 proto_item_append_text(extension_ti, "%u:%u ", port_list_index, id);
3855 }
3856 }
3857
3858 proto_item_append_text(extension_ti, "]");
3859 break;
3860 }
3861
3862
3863 default:
3864 /* Warning for unsupported/reserved value */
3865 expert_add_info(NULL((void*)0), bgt_ti, &ei_oran_se10_unknown_beamgrouptype);
3866 break;
3867 }
3868 break;
3869 }
3870
3871 case 11: /* SE 11: Flexible Weights Extension Type */
3872 {
3873 /* Hidden filter for bf */
3874 bf_ti = proto_tree_add_item(tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
3875 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
3876
3877 /* beamId in section header should be ignored. Guard against appending multiple times.. */
3878 if (section_beamId_ti && !section_beamId_ignored) {
3879 proto_item_append_text(section_beamId_ti, " (ignored)");
3880 section_beamId_ignored = true1;
3881 }
3882
3883 bool_Bool disableBFWs;
3884 uint32_t numBundPrb;
3885 bool_Bool rad;
3886
3887 /* disableBFWs */
3888 proto_tree_add_item_ret_boolean(extension_tree, hf_oran_disable_bfws,
3889 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &disableBFWs);
3890 if (disableBFWs) {
3891 proto_item_append_text(extension_ti, " (disableBFWs)");
3892 }
3893
3894 /* RAD */
3895 proto_tree_add_item_ret_boolean(extension_tree, hf_oran_rad,
3896 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &rad);
3897 /* bundleOffset (6 bits) */
3898 proto_tree_add_item(extension_tree, hf_oran_bundle_offset, tvb,
3899 offset, 1, ENC_BIG_ENDIAN0x00000000);
3900 offset++;
3901
3902 /* numBundPrb (number of prbs in each bundle) */
3903 proto_item *num_bund_prb_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_num_bund_prbs,
3904 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &numBundPrb);
3905 offset++;
3906 /* value zero is reserved.. */
3907 if (numBundPrb == 0) {
3908 expert_add_info(pinfo, num_bund_prb_ti, &ei_oran_reserved_numBundPrb);
3909 }
3910
3911 uint32_t num_bundles;
3912 bool_Bool orphaned_prbs = false0;
3913
3914 /* N.B. glibly assuming that Mu=1 */
3915 uint32_t symbol_count = (frameId*20 + slotId) * 14 + startSymbolId;
3916
3917 if (!disableBFWs) {
3918 /********************************************/
3919 /* Table 7.7.1.1-1 */
3920 /********************************************/
3921
3922 uint32_t bfwcomphdr_iq_width, bfwcomphdr_comp_meth;
3923 proto_item *comp_meth_ti = NULL((void*)0);
3924
3925 /* bfwCompHdr (2 subheaders - bfwIqWidth and bfwCompMeth)*/
3926 offset = dissect_bfwCompHdr(tvb, extension_tree, offset,
3927 &bfwcomphdr_iq_width, &bfwcomphdr_comp_meth, &comp_meth_ti);
3928
3929 /* Work out number of bundles, but take care not to divide by zero. */
3930 if (numBundPrb == 0) {
3931 break;
3932 }
3933
3934 /* Work out bundles! */
3935 ext11_work_out_bundles(startPrbc, numPrbc, numBundPrb, &ext11_settings);
3936 num_bundles = ext11_settings.num_bundles;
3937
3938 /* Add (complete) bundles */
3939 for (unsigned b=0; b < num_bundles; b++) {
3940 offset = dissect_bfw_bundle(tvb, extension_tree, pinfo, offset,
3941 comp_meth_ti, bfwcomphdr_comp_meth,
3942 NULL((void*)0) /* no ModCompr */,
3943 (ext11_settings.ext21_set) ?
3944 numPrbc :
3945 pref_num_bf_antennas,
3946 bfwcomphdr_iq_width,
3947 b, /* bundle number */
3948 ext11_settings.bundles[b].start,
3949 ext11_settings.bundles[b].end,
3950 ext11_settings.bundles[b].is_orphan,
3951 symbol_count,
3952 (link_planes_together && dl_data_section) ? &dl_data_section->details[index_to_use] : NULL((void*)0),
3953 tap_info);
3954 if (!offset) {
3955 break;
3956 }
3957 }
3958 if (num_bundles > 0) {
3959 /* Set flag from last bundle entry */
3960 orphaned_prbs = ext11_settings.bundles[num_bundles-1].is_orphan;
3961 }
3962 }
3963 else {
3964 /********************************************/
3965 /* Table 7.7.1.1-2 */
3966 /* No weights in this case */
3967 /********************************************/
3968
3969 /* Work out number of bundles, but take care not to divide by zero. */
3970 if (numBundPrb == 0) {
3971 break;
3972 }
3973
3974 ext11_work_out_bundles(startPrbc, numPrbc, numBundPrb, &ext11_settings);
3975 num_bundles = ext11_settings.num_bundles;
3976
3977 for (unsigned n=0; n < num_bundles; n++) {
3978 /* contInd */
3979 proto_tree_add_item(extension_tree, hf_oran_cont_ind,
3980 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3981 /* beamId */
3982 /* N.B., only added to tap_info if not 0 or ignored (after SEs seen) */
3983 uint32_t beam_id;
3984 proto_item *beamid_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_beam_id,
3985 tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &beam_id);
3986 if (!ext11_settings.bundles[n].is_orphan) {
3987 proto_item_append_text(beamid_ti, " (PRBs %3u-%3u) (Bundle %2u)",
3988 ext11_settings.bundles[n].start,
3989 ext11_settings.bundles[n].end,
3990 n);
3991 }
3992 else {
3993 orphaned_prbs = true1;
3994 proto_item_append_text(beamid_ti, " (PRBs %3u-%3u) (Orphaned PRBs)",
3995 ext11_settings.bundles[n].start,
3996 ext11_settings.bundles[n].end);
3997 }
3998 offset += 2;
3999
4000 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
4001 if (dl_data_section) {
4002 /* Set beamId only for range of PRBs */
4003 for (unsigned prb = ext11_settings.bundles[n].start; prb <= ext11_settings.bundles[n].end; prb++) {
4004 if (prb < 273) {
4005 dl_data_section->details[index_to_use].beamIds[prb] = beam_id;
4006 }
4007 }
4008 }
4009 }
4010
4011 /* Look for where BFWs were sent for this beamId */
4012 bfw_definition *definition;
4013
4014 wmem_tree_key_t key[3];
4015 key[0].length = 1;
4016 key[0].key = &pinfo->num;
4017 key[1].length = 1;
4018 key[1].key = &beam_id;
4019 key[2].length = 0;
4020 key[2].key = NULL((void*)0);
4021
4022 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
4023 /* Look up current result */
4024 definition = wmem_tree_lookup32(dl_beam_ids_defined, beam_id);
4025 if (definition != NULL((void*)0)) {
4026 /* Add to results table for this frame */
4027 wmem_tree_insert32_array(dl_beam_ids_results, key, definition);
4028 }
4029 }
4030 else {
4031 /* Look up from result table */
4032 definition = wmem_tree_lookup32_array(dl_beam_ids_results, key);
4033 }
4034
4035 /* Show link back to frame where/when beamId was defined */
4036 if (definition && definition->frame_defined != 0 && definition->frame_defined != pinfo->num) {
4037 proto_item *defined_ti = proto_tree_add_uint(extension_tree, hf_oran_bfws_frame_defined, tvb, offset, 0, definition->frame_defined);
4038 proto_item_set_generated(defined_ti);
4039 proto_item *since_ti = proto_tree_add_uint(extension_tree, hf_oran_bfws_symbols_since_defined, tvb, offset, 0,
4040 symbol_count - definition->symbol_when_defined);
4041 proto_item_set_generated(since_ti);
4042 }
4043 else {
4044 expert_add_info_format(NULL((void*)0), beamid_ti, &ei_oran_beamid_bfws_not_found,
4045 "ext11 for beamId %u and disableBFWs set, but can't find definition", beam_id);
4046 }
4047 }
4048
4049 }
4050
4051 /* Add summary to extension root */
4052 if (orphaned_prbs) {
4053 proto_item_append_text(extension_ti, " (%u full bundles + orphaned)", num_bundles-1);
4054 }
4055 else {
4056 proto_item_append_text(extension_ti, " (%u bundles)", num_bundles);
4057 }
4058 }
4059
4060 break;
4061
4062 case 12: /* SE 12: Non-Contiguous PRB Allocation with Frequency Ranges */
4063 {
4064 /* numSymbol not used in this case */
4065 if (numsymbol_ti && !numsymbol_ignored) {
4066 proto_item_append_text(numsymbol_ti, " (ignored)");
4067 numsymbol_ignored = true1;
4068 }
4069
4070 ext11_settings.ext12_set = true1;
4071
4072 /* priority */
4073 proto_tree_add_item(extension_tree, hf_oran_noncontig_priority, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4074
4075 /* symbolMask */
4076 offset = dissect_symbolmask(tvb, extension_tree, offset, NULL((void*)0), NULL((void*)0));
4077
4078 /* There are now 'R' pairs of (offStartPrb, numPrb) values. Fill extlen bytes with values. If last one is not set,
4079 should be populated with 0s. */
4080 uint32_t extlen_remaining_bytes = (extlen*4) - 4;
4081 uint8_t prb_index;
4082
4083 /* This is for ST10/ST11. First pair starts after frames signalled there */
4084 uint16_t st10_st11_offset = startPrbc + numPrbc;
4085
4086 for (prb_index = 1; extlen_remaining_bytes > 0; prb_index++)
4087 {
4088 /* Create a subtree for each pair */
4089 proto_item *pair_ti = proto_tree_add_string(extension_tree, hf_oran_frequency_range,
4090 tvb, offset, 2, "");
4091 proto_tree *pair_tree = proto_item_add_subtree(pair_ti, ett_oran_frequency_range);
4092
4093 /* offStartPrb */
4094 uint32_t off_start_prb;
4095 proto_tree_add_item_ret_uint(pair_tree, hf_oran_off_start_prb, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &off_start_prb);
4096 offset++;
4097
4098 /* numPrb */
4099 uint32_t num_prb;
4100 proto_tree_add_item_ret_uint(pair_tree, hf_oran_num_prb, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &num_prb);
4101 offset++;
4102
4103 extlen_remaining_bytes -= 2;
4104
4105 /* Last pair may be 0,0 if not used. Check for this */
4106 if ((extlen_remaining_bytes == 0) && (off_start_prb == 0) && (num_prb == 0)) {
4107 proto_item_append_text(pair_ti, " (not used)");
4108 }
4109 /* Add summary to pair root item, and configure details in ext11_settings */
4110 else {
4111 proto_item_append_text(pair_ti, "(%u) [%u : %u]",
4112 prb_index, off_start_prb, num_prb);
4113 proto_item_append_text(extension_ti, "[%u : %u]",
4114 off_start_prb, num_prb);
4115 if (ext11_settings.ext12_num_pairs < MAX_BFW_EXT12_PAIRS128) {
4116 ext11_settings.ext12_pairs[ext11_settings.ext12_num_pairs].off_start_prb = off_start_prb;
4117 ext11_settings.ext12_pairs[ext11_settings.ext12_num_pairs++].num_prb = num_prb;
4118 }
4119
4120 /* Also update PRBs to be covered for ST10 type 5 */
4121 /* Original range from section is added to.. */
4122 /* TODO: I don't think this is quite right.. */
4123 for (unsigned prb=st10_st11_offset+off_start_prb; prb < st10_st11_offset+off_start_prb+num_prb; prb++) {
4124 if (prb < MAX_PRBS273) {
4125 prbs_for_st10_type5[prb] = true1;
4126 }
4127 }
4128
4129 /* Any next pair will begin after this one */
4130 st10_st11_offset += (off_start_prb + num_prb);
4131 }
4132 }
4133 break;
4134 }
4135
4136 case 13: /* SE 13: PRB Allocation with Frequency Hopping */
4137 {
4138 /* Will update settings for ext11 */
4139 ext11_settings.ext13_set = true1;
4140
4141 uint32_t extlen_remaining_bytes = (extlen*4) - 2;
4142 uint8_t allocation_index;
4143
4144 unsigned prev_next_symbol_id = 0, prev_next_start_prbc = 0;
4145
4146 for (allocation_index = 1; extlen_remaining_bytes > 0; allocation_index++)
4147 {
4148 /* Subtree for allocation */
4149 proto_item *allocation_ti = proto_tree_add_string(extension_tree, hf_oran_prb_allocation,
4150 tvb, offset, 2, "");
4151 proto_tree *allocation_tree = proto_item_add_subtree(allocation_ti, ett_oran_prb_allocation);
4152
4153 /* Reserved (2 bits) */
4154 add_reserved_field(allocation_tree, hf_oran_reserved_2bits, tvb, offset, 1);
4155
4156 /* nextSymbolId (4 bits) */
4157 uint32_t next_symbol_id;
4158 proto_tree_add_item_ret_uint(allocation_tree, hf_oran_nextSymbolId, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &next_symbol_id);
4159
4160 /* nextStartPrbc (10 bits) */
4161 uint32_t next_start_prbc;
4162 proto_tree_add_item_ret_uint(allocation_tree, hf_oran_nextStartPrbc, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &next_start_prbc);
4163 offset += 2;
4164
4165 /* Add summary to allocation root item */
4166 proto_item_append_text(allocation_ti, "(%u) nextSymbolId=%3u, nextStartPrbc=%u",
4167 allocation_index, next_symbol_id, next_start_prbc);
4168
4169 /* Checking for duplicates (expected if e.g. had only 2 entries but extlen bytes still to fill */
4170 if ((allocation_index > 1) && (next_symbol_id == prev_next_symbol_id) && (next_start_prbc == prev_next_start_prbc)) {
4171 proto_item_append_text(allocation_ti, " (repeated - to fill up extlen)");
4172 }
4173 else {
4174 /* Add entry for configuring ext11. don't store out of range */
4175 if (ext11_settings.ext13_num_start_prbs < MAX_BFW_EXT13_ALLOCATIONS128) {
4176 ext11_settings.ext13_start_prbs[ext11_settings.ext13_num_start_prbs++] = next_start_prbc;
4177 }
4178 }
4179 prev_next_symbol_id = next_symbol_id;
4180 prev_next_start_prbc = next_start_prbc;
4181
4182 extlen_remaining_bytes -= 2;
4183 }
4184 break;
4185 }
4186
4187 case 14: /* SE 14: Nulling-layer Info. for ueId-based beamforming */
4188 /* Hidden filter for bf (DMRS BF) */
4189 bf_ti = proto_tree_add_item(tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
4190 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
4191
4192 if (!seen_se10) {
4193 proto_tree_add_item(extension_tree, hf_oran_nullLayerInd, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4194 offset += 1;
4195 add_reserved_field(extension_tree, hf_oran_reserved_8bits, tvb, offset, 1);
4196 offset += 1;
4197 }
4198 else {
4199 /* Loop over numPortc++1 (from SE 10) nullLayerInd fields */
4200 for (unsigned port=0; port < numPortc+1; port++) {
4201 proto_tree_add_item(extension_tree, hf_oran_nullLayerInd, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4202 offset += 1;
4203 }
4204 }
4205 break;
4206
4207 case 15: /* SE 15: Mixed-numerology Info. for ueId-based beamforming */
4208 {
4209 /* frameStructure */
4210 offset = dissect_frame_structure(extension_tree, tvb, offset,
4211 subframeId, slotId);
4212 /* freqOffset */
4213 proto_tree_add_item(extension_tree, hf_oran_freqOffset, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
4214 offset += 3;
4215 /* cpLength */
4216 proto_item *cplength_ti = proto_tree_add_item(extension_tree, hf_oran_cpLength, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4217 if (sectionType != 0 && sectionType != 3) {
4218 proto_item_append_text(cplength_ti, " (ignored - used only with ST0 and ST3)");
4219 }
4220 offset += 2;
4221 break;
4222 }
4223
4224 case 16: /* SE 16: Antenna mapping in UE channel information based UL beamforming */
4225 {
4226 /* Just filling available bytes with antMask entries.
4227 N.B., if SE 10 also used, could associate each antMask with (beamId or UEId) RX eAxC */
4228 uint32_t extlen_remaining_bytes = (extlen*4) - 2;
4229 unsigned num_ant_masks = extlen_remaining_bytes / 8;
4230 for (unsigned n=0; n < num_ant_masks; n++) {
4231 proto_item *ti = proto_tree_add_item(extension_tree, hf_oran_antMask, tvb, offset, 8, ENC_BIG_ENDIAN0x00000000);
4232 proto_item_append_text(ti, " (RX eAxC #%u)", n+1);
4233 offset += 8;
4234 }
4235 break;
4236 }
4237
4238 case 17: /* SE 17: Indication of user port group. Applies to ST5 + SE10 with group type 1 (beam matrix indication) */
4239 {
4240 uint32_t extlen_remaining_bytes = (extlen*4) - 2;
4241 uint32_t end_bit = (offset+extlen_remaining_bytes) * 8;
4242 uint32_t ueid_index = 1;
4243
4244 /* "the preceding Section Type and extension messages implicitly provide the number of scheduled users" */
4245 for (uint32_t bit_offset=offset*8; (bit_offset < end_bit) && (ueid_index <= number_of_ueids); bit_offset+=4, ueid_index++) {
4246 /* numUeId (Number of UE Ids per user) */
4247 proto_item *ti = proto_tree_add_bits_item(extension_tree, hf_oran_num_ueid, tvb, bit_offset, 4, ENC_BIG_ENDIAN0x00000000);
4248 /* TODO: show ueids[ueid_index] here too? */
4249 proto_item_append_text(ti, " (user #%u)", ueid_index);
4250 }
4251 break;
4252 }
4253
4254 case 18: /* SE 18: Uplink transmission management */
4255 /* transmissionWindowOffset */
4256 proto_tree_add_item(extension_tree, hf_oran_transmissionWindowOffset, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4257 offset += 2;
4258 /* reserved (2 bits) */
4259 add_reserved_field(extension_tree, hf_oran_reserved_2bits, tvb, offset, 1);
4260 /* transmissionWindowSize (14 bits) */
4261 proto_tree_add_item(extension_tree, hf_oran_transmissionWindowSize, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4262 offset += 2;
4263
4264 /* reserved (6 bits) */
4265 add_reserved_field(extension_tree, hf_oran_reserved_6bits, tvb, offset, 1);
4266 /* toT (2 bits) */
4267 proto_tree_add_item(extension_tree, hf_oran_toT, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4268 offset += 1;
4269 break;
4270
4271 case 19: /* SE 19: Compact beamforming information for multiple port */
4272 {
4273 /* beamId in section header should be ignored. Guard against appending multiple times.. */
4274 if (section_beamId_ti && !section_beamId_ignored) {
4275 proto_item_append_text(section_beamId_ti, " (ignored)");
4276 section_beamId_ignored = true1;
4277 }
4278
4279 /* numSymbol not used in this case */
4280 if (numsymbol_ti && !numsymbol_ignored) {
4281 proto_item_append_text(numsymbol_ti, " (ignored)");
4282 numsymbol_ignored = true1;
4283 }
4284
4285 /* disableBFWs */
4286 bool_Bool disableBFWs;
4287 proto_tree_add_item_ret_boolean(extension_tree, hf_oran_disable_bfws,
4288 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &disableBFWs);
4289 if (disableBFWs) {
4290 proto_item_append_text(extension_ti, " (disableBFWs)");
4291 }
4292 /* repetition (1 bit) */
4293 uint64_t repetition;
4294 proto_tree_add_bits_ret_val(extension_tree, hf_oran_se19_repetition, tvb, (offset*8)+1, 1, &repetition, ENC_BIG_ENDIAN0x00000000);
4295 /* numPortc (6 bits) */
4296 proto_tree_add_item_ret_uint(extension_tree, hf_oran_numPortc,
4297 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &numPortc);
4298 offset++;
4299
4300 /* priority (2 bits) */
4301 proto_tree_add_item(extension_tree, hf_oran_noncontig_priority, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4302 /* symbolMask (14 bits) */
4303 offset = dissect_symbolmask(tvb, extension_tree, offset, NULL((void*)0), NULL((void*)0));
4304
4305 uint32_t bfwcomphdr_iq_width, bfwcomphdr_comp_meth;
4306 proto_item *comp_meth_ti = NULL((void*)0);
4307
4308 if (!repetition) {
4309
4310 if (!disableBFWs) {
4311 /* bfwCompHdr */
4312 offset = dissect_bfwCompHdr(tvb, extension_tree, offset,
4313 &bfwcomphdr_iq_width, &bfwcomphdr_comp_meth, &comp_meth_ti);
4314 }
4315
4316 /* Add entries for each port */
4317 for (unsigned port=0; port < numPortc; port++) {
4318
4319 /* Create subtree for port entry*/
4320 int port_start_offset = offset;
4321 proto_item *port_ti = proto_tree_add_string_format(extension_tree, hf_oran_ext19_port,
4322 tvb, offset, 0,
4323 "", "Port %u: ", port);
4324 proto_tree *port_tree = proto_item_add_subtree(port_ti, ett_oran_ext19_port);
4325
4326 /* Reserved (4 bits) */
4327 add_reserved_field(port_tree, hf_oran_reserved_4bits, tvb, offset, 1);
4328 /* portReMask (12 bits) */
4329 proto_tree_add_item(port_tree, hf_oran_portReMask, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4330 offset += 2;
4331
4332 /* Reserved (2 bits) */
4333 add_reserved_field(port_tree, hf_oran_reserved_2bits, tvb, offset, 1);
4334 /* portSymbolMask (14 bits) */
4335 proto_tree_add_item(port_tree, hf_oran_portSymbolMask, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4336 offset += 2;
4337
4338 /* Reserved (1 bit) */
4339 add_reserved_field(port_tree, hf_oran_reserved_1bit, tvb, offset, 1);
4340 /* beamID (15 bits) */
4341 uint16_t beamId;
4342 proto_tree_add_item_ret_uint16(port_tree, hf_oran_beamId, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &beamId);
4343 proto_item_append_text(port_ti, " (beamId=%u)", beamId);
4344 offset += 2;
4345
4346 /* No weights present */
4347 if (!disableBFWs) {
4348 /*******************************************************************/
4349 /* Table 7.7.19.1-1 (there is no part -2 for disableBFWs case...), */
4350 /* but for SE 11, bfwCompParam was only present for !disableBFWs */
4351 /*******************************************************************/
4352
4353 /* bfwCompParam */
4354 bool_Bool compression_method_supported = false0;
4355 uint32_t exponent = 0;
4356 unsigned num_trx_entries = 0;
4357 uint16_t *trx;
4358 offset = dissect_bfwCompParam(tvb, port_tree, pinfo, offset, comp_meth_ti,
4359 &bfwcomphdr_comp_meth, &exponent, &compression_method_supported,
4360 &num_trx_entries, &trx);
4361
4362 int bit_offset = offset*8;
4363 int bfw_offset;
4364
4365 /* Add weights for each TRX */
4366 unsigned trx_to_add = (num_trx_entries==0) ? pref_num_bf_antennas : num_trx_entries;
4367 for (unsigned b=0; b < trx_to_add; b++) {
4368
4369 uint16_t trx_index = (num_trx_entries) ? trx[b] : b+1;
4370
4371 /* Create BFW subtree */
4372 bfw_offset = bit_offset / 8;
4373 uint8_t bfw_extent = ((bit_offset + (bfwcomphdr_iq_width*2)) / 8) - bfw_offset;
4374 proto_item *bfw_ti = proto_tree_add_string_format(port_tree, hf_oran_bfw,
4375 tvb, bfw_offset, bfw_extent,
4376 "", "TRX %u: (", trx_index);
4377 proto_tree *bfw_tree = proto_item_add_subtree(bfw_ti, ett_oran_bfw);
4378
4379 /* I */
4380 uint32_t bits = tvb_get_bits32(tvb, bit_offset, bfwcomphdr_iq_width, ENC_BIG_ENDIAN0x00000000);
4381 float value = decompress_value(bits, bfwcomphdr_comp_meth, bfwcomphdr_iq_width, exponent, NULL((void*)0) /* no ModCompr */, 0 /* RE */);
4382 /* Add to tree. */
4383 proto_tree_add_float_format_value(bfw_tree, hf_oran_bfw_i, tvb, bit_offset/8,
4384 (bfwcomphdr_iq_width+7)/8, value, "#%u=%f", b, value);
4385 bit_offset += bfwcomphdr_iq_width;
4386 proto_item_append_text(bfw_ti, "I%u=%f ", b, value);
4387
4388 /* Q */
4389 bits = tvb_get_bits32(tvb, bit_offset, bfwcomphdr_iq_width, ENC_BIG_ENDIAN0x00000000);
4390 value = decompress_value(bits, bfwcomphdr_comp_meth, bfwcomphdr_iq_width, exponent, NULL((void*)0) /* no ModCompr */, 0 /* RE */);
4391 /* Add to tree. */
4392 proto_tree_add_float_format_value(bfw_tree, hf_oran_bfw_q, tvb, bit_offset/8,
4393 (bfwcomphdr_iq_width+7)/8, value, "#%u=%f", b, value);
4394 bit_offset += bfwcomphdr_iq_width;
4395 proto_item_append_text(bfw_ti, "Q%u=%f)", b, value);
4396 }
4397
4398 offset = (bit_offset+7)/8;
4399 }
4400 else {
4401 /* No weights... */
4402 }
4403
4404 /* Set length of this port entry */
4405 proto_item_set_len(port_ti, offset-port_start_offset);
4406 }
4407 }
4408 break;
4409 }
4410
4411 case 20: /* SE 20: Puncturing extension */
4412 {
4413 /* numPuncPatterns */
4414 uint32_t numPuncPatterns;
4415 proto_tree_add_item_ret_uint(extension_tree, hf_oran_numPuncPatterns, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &numPuncPatterns);
4416 offset += 1;
4417
4418 /* Add each puncturing pattern */
4419 for (uint32_t n=0; n < numPuncPatterns; n++) {
4420 unsigned pattern_start_offset = offset;
4421
4422 /* Subtree for this puncturing pattern */
4423 proto_item *pattern_ti = proto_tree_add_string_format(extension_tree, hf_oran_puncPattern,
4424 tvb, offset, 0,
4425 "", "Puncturing Pattern: %u/%u", n+1, numPuncPatterns);
4426 proto_tree *pattern_tree = proto_item_add_subtree(pattern_ti, ett_oran_punc_pattern);
4427
4428 /* SymbolMask (14 bits) */
4429 proto_tree_add_item(pattern_tree, hf_oran_symbolMask_ext20, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4430 offset += 1;
4431
4432 uint32_t startPuncPrb, numPuncPrb;
4433
4434 /* startPuncPrb (10 bits) */
4435 proto_tree_add_item_ret_uint(pattern_tree, hf_oran_startPuncPrb, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &startPuncPrb);
4436 offset += 2;
4437 /* numPuncPrb (8 bits) */
4438 proto_tree_add_item_ret_uint(pattern_tree, hf_oran_numPuncPrb, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &numPuncPrb);
4439 offset += 1;
4440
4441 proto_item_append_text(pattern_ti, " [%u->%u]", startPuncPrb, startPuncPrb+numPuncPrb-1);
4442
4443 /* Make a hole in range of PRBs to report */
4444 for (unsigned p=startPuncPrb; p < startPuncPrb+numPuncPrb; p++) {
4445 if (p < MAX_PRBS273) {
4446 prbs_for_st10_type5[p] = false0;
4447 }
4448 }
4449
4450 /* puncReMask (12 bits) */
4451 proto_tree_add_item(pattern_tree, hf_oran_puncReMask, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4452 offset += 1;
4453 /* rb (1 bit) */
4454 proto_item *rb_ti = proto_tree_add_item(pattern_tree, hf_oran_rb, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4455 /* reserved (1 bit) */
4456 add_reserved_field(pattern_tree, hf_oran_reserved_bit5, tvb, offset, 1);
4457 /* multiSDScope (1 bit) */
4458 proto_tree_add_item(pattern_tree, hf_oran_multiSDScope, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4459 /* rbgIncl (1 bit) */
4460 bool_Bool rbgIncl;
4461 proto_tree_add_item_ret_boolean(pattern_tree, hf_oran_RbgIncl, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &rbgIncl);
4462 offset += 1;
4463
4464 if (rbgIncl) {
4465 /* reserved (1 bit) */
4466 add_reserved_field(pattern_tree, hf_oran_reserved_1bit, tvb, offset, 1);
4467 /* rbgSize(3 bits) */
4468 proto_tree_add_item(pattern_tree, hf_oran_rbgSize, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4469 /* rbgMask (28 bits) */
4470 proto_tree_add_item(pattern_tree, hf_oran_rbgMask, tvb, offset, 4, ENC_BIG_ENDIAN0x00000000);
4471 offset += 4;
4472
4473 proto_item_append_text(rb_ti, " (ignored)");
4474 }
4475
4476 proto_item_set_len(pattern_ti, offset-pattern_start_offset);
4477 }
4478
4479 break;
4480 }
4481 case 21: /* SE 21: Variable PRB group size for channel information */
4482 {
4483 /* ciPrbGroupSize */
4484 uint32_t ci_prb_group_size;
4485 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_ENDIAN0x00000000, &ci_prb_group_size);
4486 offset += 1;
4487
4488 switch (ci_prb_group_size) {
4489 case 0:
4490 case 1:
4491 case 255:
4492 /* Reserved value */
4493 expert_add_info_format(pinfo, prb_group_size_ti, &ei_oran_ci_prb_group_size_reserved,
4494 "SE 11 ciPrbGroupSize is reserved value %u - must be 2-254",
4495 ci_prb_group_size);
4496 break;
4497 default:
4498 /* This value affects how SE 11 is interpreted */
4499 ext11_settings.ext21_set = true1;
4500 ext11_settings.ext21_ci_prb_group_size = ci_prb_group_size;
4501
4502 if (numPrbc == 0) {
4503 expert_add_info(pinfo, numprbc_ti, &ei_oran_numprbc_ext21_zero);
4504 }
4505 break;
4506 }
4507
4508 /* reserved (6 bits) */
4509 add_reserved_field(extension_tree, hf_oran_reserved_6bits, tvb, offset, 1);
4510
4511 /* prgSize (2 bits). Interpretation depends upon section type (5 or 6), but also mplane parameters? */
4512 if (sectionType == SEC_C_UE_SCHED) { /* Section Type 5 */
4513 proto_tree_add_item(extension_tree, hf_oran_prg_size_st5, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4514 }
4515 else if (sectionType == SEC_C_CH_INFO) { /* Section Type 6 */
4516 proto_tree_add_item(extension_tree, hf_oran_prg_size_st6, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4517 }
4518 offset += 1;
4519 break;
4520 }
4521
4522 case 22: /* SE 22: ACK/NACK request */
4523 {
4524 uint32_t ack_nack_req_id;
4525 proto_tree_add_item_ret_uint(extension_tree, hf_oran_ack_nack_req_id, tvb, offset, 2,
4526 ENC_BIG_ENDIAN0x00000000, &ack_nack_req_id);
4527 offset += 2;
4528
4529 if (state) {
4530 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
4531 /* Add this request into conversation state on first pass */
4532 ack_nack_request_t *request_details = wmem_new0(wmem_file_scope(), ack_nack_request_t)((ack_nack_request_t*)wmem_alloc0((wmem_file_scope()), sizeof
(ack_nack_request_t)))
;
4533 request_details->request_frame_number = pinfo->num;
4534 request_details->request_frame_time = pinfo->abs_ts;
4535 request_details->requestType = SE22;
4536 /* Insert into flow's tree */
4537 wmem_tree_insert32(state->ack_nack_requests, ack_nack_req_id, request_details);
4538 }
4539 else {
4540 /* Try to link forward to ST8 response */
4541 ack_nack_request_t *response = wmem_tree_lookup32(state->ack_nack_requests,
4542 ack_nack_req_id);
4543 if (response) {
4544 show_link_to_acknack_response(extension_tree, tvb, pinfo, response);
4545 }
4546 }
4547 }
4548 break;
4549 }
4550
4551 case 23: /* SE 23: Arbitrary symbol pattern modulation compression parameters */
4552 {
4553 /* Green common header */
4554
4555 /* numSymPrbPattern (4 bits) */
4556 uint32_t num_sym_prb_pattern;
4557 proto_tree_add_item_ret_uint(extension_tree, hf_oran_num_sym_prb_pattern, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &num_sym_prb_pattern);
4558 /* reserved (3 bits) */
4559 add_reserved_field(extension_tree, hf_oran_reserved_bits456, tvb, offset, 1);
4560 /* prbMode (1 bit) */
4561 bool_Bool prb_mode;
4562 proto_tree_add_item_ret_boolean(extension_tree, hf_oran_prb_mode, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &prb_mode);
4563 offset += 1;
4564
4565 /* reserved (8 bits) */
4566 add_reserved_field(extension_tree, hf_oran_reserved_8bits, tvb, offset, 1);
4567 offset += 1;
4568
4569 /* Dissect each SymPrbPattern */
4570 for (uint32_t n=0; n < num_sym_prb_pattern; n++) {
4571
4572 /* Subtree */
4573 proto_item *pattern_ti = proto_tree_add_string_format(extension_tree, hf_oran_sym_prb_pattern,
4574 tvb, offset, 1, "",
4575 prb_mode ? "PRB-BLOCK" : "PRB-MASK");
4576 proto_tree *pattern_tree = proto_item_add_subtree(pattern_ti, ett_oran_sym_prb_pattern);
4577
4578
4579 /* Orange part */
4580
4581 /* Reserved (2 bits) */
4582 add_reserved_field(pattern_tree, hf_oran_reserved_2bits, tvb, offset, 1);
4583 /* symMask (14 bits) */
4584 proto_tree_add_item(pattern_tree, hf_oran_sym_mask, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4585 offset += 2;
4586 /* numMcScaleOffset (4 bits) */
4587 uint32_t numMcScaleOffset;
4588 proto_tree_add_item_ret_uint(pattern_tree, hf_oran_num_mc_scale_offset, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &numMcScaleOffset);
4589
4590 if (!prb_mode) { /* PRB-MASK */
4591 /* prbPattern (4 bits) */
4592 proto_tree_add_item(pattern_tree, hf_oran_prb_pattern, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4593 offset += 1;
4594 /* reserved (8 bits) */
4595 add_reserved_field(pattern_tree, hf_oran_reserved_8bits, tvb, offset, 1);
4596 offset += 1;
4597 }
4598 else { /* PRB-BLOCK */
4599 /* prbBlkOffset (8 bits) */
4600 proto_tree_add_item(pattern_tree, hf_oran_prb_block_offset, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4601 offset += 1;
4602 /* prbBlkSize (4 bits) */
4603 proto_tree_add_item(pattern_tree, hf_oran_prb_block_size, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4604 offset += 1;
4605 }
4606
4607 /* Yellowish part */
4608 if (prb_mode) { /* PRB-BLOCK */
4609 /* prbBlkSize (4 bits) */
4610 proto_tree_add_item(pattern_tree, hf_oran_prb_block_size, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4611 }
4612 else {
4613 /* reserved (4 bits) */
4614 add_reserved_field(pattern_tree, hf_oran_reserved_4bits, tvb, offset, 1);
4615 }
4616
4617 for (unsigned c=0; c < numMcScaleOffset; c++) {
4618
4619 if (c > 0) {
4620 /* reserved (4 bits) */
4621 add_reserved_field(pattern_tree, hf_oran_reserved_4bits, tvb, offset, 1);
4622 }
4623
4624 static int * const remask_flags_even[] = {
4625 &hf_oran_mc_scale_re_mask_re1_even,
4626 &hf_oran_mc_scale_re_mask_re2_even,
4627 &hf_oran_mc_scale_re_mask_re3_even,
4628 &hf_oran_mc_scale_re_mask_re4_even,
4629 &hf_oran_mc_scale_re_mask_re5_even,
4630 &hf_oran_mc_scale_re_mask_re6_even,
4631 &hf_oran_mc_scale_re_mask_re7_even,
4632 &hf_oran_mc_scale_re_mask_re8_even,
4633 &hf_oran_mc_scale_re_mask_re9_even,
4634 &hf_oran_mc_scale_re_mask_re10_even,
4635 &hf_oran_mc_scale_re_mask_re11_even,
4636 &hf_oran_mc_scale_re_mask_re12_even,
4637 NULL((void*)0)
4638 };
4639
4640 /* mcScaleReMask (12 bits). Defines which REs the following csf and mcScaleOffset apply to */
4641 uint64_t mcScaleReMask, mcScaleOffset;
4642 proto_tree_add_bitmask_ret_uint64(pattern_tree, tvb, offset,
4643 hf_oran_mc_scale_re_mask_even,
4644 ett_oran_mc_scale_remask,
4645 remask_flags_even, ENC_BIG_ENDIAN0x00000000, &mcScaleReMask);
4646
4647 offset += 2;
4648 /* csf (1 bit) */
4649 bool_Bool csf;
4650 dissect_csf(pattern_tree, tvb, offset*8, ci_iq_width, &csf);
4651 /* mcScaleOffset (15 bits) */
4652 proto_item *ti = proto_tree_add_bits_ret_val(pattern_tree, hf_oran_mc_scale_offset, tvb, offset*8 + 1, 15, &mcScaleOffset, ENC_BIG_ENDIAN0x00000000);
4653 uint16_t exponent = (mcScaleOffset >> 11) & 0x000f; /* m.s. 4 bits */
4654 uint16_t mantissa = mcScaleOffset & 0x07ff; /* l.s. 11 bits */
4655 float mcScaleOffset_value = ((float)mantissa/(1<<11)) * ((float)1.0 / (1 << exponent));
4656 proto_item_append_text(ti, " (%f)", mcScaleOffset_value);
4657
4658 offset += 2;
4659
4660 /* Record this config. */
4661 /* TODO: at some point, will also want to store/use PRB + symbol filters */
4662 section_mod_compr_config_t* sect_config = get_mod_compr_section_to_write(state, sectionId);
4663
4664 if (sect_config && sect_config->num_configs < MAX_MOD_COMPR_CONFIGS12) {
4665 unsigned i = sect_config->num_configs;
4666 sect_config->configs[i].mod_compr_re_mask = (uint16_t)mcScaleReMask;
4667 sect_config->configs[i].mod_compr_csf = csf;
4668 sect_config->configs[i].mod_compr_scaler = mcScaleOffset_value;
4669 sect_config->num_configs++;
4670 }
4671 }
4672
4673 proto_item_set_end(pattern_ti, tvb, offset);
4674 }
4675 break;
4676 }
4677
4678 case 24: /* SE 24: PUSCH DMRS configuration */
4679 {
4680 /* Hidden filter for bf (DMRS BF) */
4681 bf_ti = proto_tree_add_item(tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
4682 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
4683
4684 /* alpnPerSym (1 bit) */
4685 proto_tree_add_item(extension_tree, hf_oran_alpn_per_sym, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4686 /* antDmrsSnr (1 bit) */
4687 proto_tree_add_item(extension_tree, hf_oran_ant_dmrs_snr, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4688 /* reserved (1 bit) */
4689 add_reserved_field(extension_tree, hf_oran_reserved_bit2, tvb, offset, 1);
4690 /* userGroupSize (5 bits) */
4691 uint32_t user_group_size;
4692 proto_item *ugs_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_user_group_size, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &user_group_size);
4693 if (user_group_size == 0) {
4694 proto_item_append_text(ugs_ti, " (not used)");
4695 }
4696 else if (user_group_size > 12) {
4697 proto_item_append_text(ugs_ti, " (reserved)");
4698 }
4699 offset += 1;
4700 /* userGroupId (8 bits)*/
4701 uint32_t user_group_id;
4702 proto_item *ugi_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_user_group_id, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &user_group_id);
4703 if (user_group_id == 0) {
4704 /* TODO: Value 0 can happen in several cases, described in 7.7.24.7.. */
4705 }
4706 if (user_group_id == 255) {
4707 /* Value 255 is reserved */
4708 expert_add_info(pinfo, ugi_ti, &ei_oran_user_group_id_reserved_value);
4709 }
4710 offset += 1;
4711
4712 bool_Bool seen_value_to_inherit = false0;
4713 bool_Bool inherited_config_has_transform_precoding = false0;
4714 int dmrs_configs_seen = 0;
4715
4716 /* Dissect each entry until reach number of configured ueIds (or run out of extlen bytes..) */
4717 uint32_t ueid_index = 0;
4718 while ((offset < (extension_start_offset + extlen*4)) && (ueid_index < number_of_ueids)) {
4719 dmrs_configs_seen++;
4720
4721 /* Subtree */
4722 proto_item *entry_ti = proto_tree_add_string_format(extension_tree, hf_oran_dmrs_entry,
4723 tvb, offset, 0, "",
4724 "Entry");
4725 proto_tree *entry_tree = proto_item_add_subtree(entry_ti, ett_oran_dmrs_entry);
4726
4727 /* entryType (3 bits) */
4728 uint32_t entry_type;
4729 proto_item *entry_type_ti;
4730 entry_type_ti = proto_tree_add_item_ret_uint(entry_tree, hf_oran_entry_type, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &entry_type);
4731 if (entry_type > 3) {
4732 proto_item_append_text(entry_type_ti, " (reserved)");
4733 }
4734
4735 /* dmrsPortNumber (5 bits). Values 0-11 allowed */
4736 unsigned int dmrs_port_number;
4737 proto_item *dpn_ti = proto_tree_add_item_ret_uint(entry_tree, hf_oran_dmrs_port_number, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &dmrs_port_number);
4738 if (dmrs_port_number > 11) {
4739 proto_item_append_text(dpn_ti, " (12-31 are reserved)");
4740 }
4741 offset += 1;
4742
4743 /* What follows depends upon entryType */
4744 switch (entry_type) {
4745 case 0: /* dmrsPortNumber config same as previous, ueId ueIdReset=0 */
4746 case 1: /* dmrsPortNumber config same as previous, ueId ueIdReset=1 */
4747 /* No further fields for these */
4748 /* Error here if no previous values to inherit!! */
4749 if (!seen_value_to_inherit) {
4750 expert_add_info_format(pinfo, entry_type_ti, &ei_oran_se24_nothing_to_inherit,
4751 "SE24: have seen entry type %u, but no previous config (type 2 or 3) to inherit config from", entry_type);
4752
4753 }
4754 /* TODO: would be useful to repeat whole inherited config here? */
4755 break;
4756
4757 case 2: /* transform precoding disabled */
4758 case 3: /* transform precoding enabled */
4759 {
4760 /* Type 2/3 are very similar.. */
4761
4762 /* ueIdReset (1 bit) */
4763 proto_tree_add_item(entry_tree, hf_oran_ueid_reset, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4764 /* posMeas (1 bit) */
4765 proto_tree_add_item(entry_tree, hf_oran_pos_meas, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4766
4767 /* dmrsSymbolMask (14 bits) */
4768 static int * const dmrs_symbol_mask_flags[] = {
4769 &hf_oran_dmrs_symbol_mask_s13,
4770 &hf_oran_dmrs_symbol_mask_s12,
4771 &hf_oran_dmrs_symbol_mask_s11,
4772 &hf_oran_dmrs_symbol_mask_s10,
4773 &hf_oran_dmrs_symbol_mask_s9,
4774 &hf_oran_dmrs_symbol_mask_s8,
4775 &hf_oran_dmrs_symbol_mask_s7,
4776 &hf_oran_dmrs_symbol_mask_s6,
4777 &hf_oran_dmrs_symbol_mask_s5,
4778 &hf_oran_dmrs_symbol_mask_s4,
4779 &hf_oran_dmrs_symbol_mask_s3,
4780 &hf_oran_dmrs_symbol_mask_s2,
4781 &hf_oran_dmrs_symbol_mask_s1,
4782 &hf_oran_dmrs_symbol_mask_s0,
4783 NULL((void*)0)
4784 };
4785 proto_tree_add_bitmask(entry_tree, tvb, offset,
4786 hf_oran_dmrs_symbol_mask, ett_oran_dmrs_symbol_mask, dmrs_symbol_mask_flags, ENC_BIG_ENDIAN0x00000000);
4787 offset += 2;
4788
4789 /* scrambling */
4790 proto_tree_add_item(entry_tree, hf_oran_scrambling, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4791 offset += 2;
4792
4793 /* nscid (1 bit) */
4794 proto_tree_add_item(entry_tree, hf_oran_nscid, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4795
4796 /* These 5 bits differ depending upon entry type */
4797 if (entry_type == 2) { /* type 2 */
4798 /* dType (1 bit) */
4799 proto_tree_add_item(entry_tree, hf_oran_dtype, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4800 /* cdmWithoutData (2 bits) */
4801 proto_tree_add_item(entry_tree, hf_oran_cmd_without_data, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4802 /* lambda (2 bits) */
4803 proto_tree_add_item(entry_tree, hf_oran_lambda, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4804 }
4805 else { /* type 3 */
4806 /* reserved (1 bit) */
4807 add_reserved_field(entry_tree, hf_oran_reserved_bit1, tvb, offset, 1);
4808 /* lowPaprType (2 bits) */
4809 proto_tree_add_item(entry_tree, hf_oran_low_papr_type, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4810 /* hoppingMode (2 bits) */
4811 proto_tree_add_item(entry_tree, hf_oran_hopping_mode, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4812 }
4813
4814 /* firstPrb (9 bits) */
4815 proto_tree_add_item(entry_tree, hf_oran_first_prb, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4816 offset += 1;
4817 /* lastPrb (9 bits) */
4818 proto_tree_add_item(entry_tree, hf_oran_last_prb, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4819 offset += 2;
4820 /* Reserved (16 bits) */
4821 add_reserved_field(entry_tree, hf_oran_reserved_16bits, tvb, offset, 2);
4822 offset += 2;
4823
4824 /* Could now see entry types 0 or 1 - they have these values to inherit */
4825 seen_value_to_inherit = true1;
4826 inherited_config_has_transform_precoding = (entry_type == 3);
4827 break;
4828 }
4829
4830 default:
4831 /* reserved - expert info */
4832 break;
4833 }
4834
4835 proto_item_append_text(entry_ti, " [UEId=%u] (dmrsPortNumber=%2u) (type %u - %s) ",
4836 ueids[ueid_index++], dmrs_port_number, entry_type, val_to_str_const(entry_type, entry_type_vals, "Unknown"));
4837 proto_item_set_end(entry_ti, tvb, offset);
4838
4839 if (entry_type <= 1) {
4840 proto_item_append_text(entry_ti, " [transform-precoding %s]",
4841 inherited_config_has_transform_precoding ? "enabled" : "disabled");
4842 }
4843 }
4844
4845 proto_item_append_text(extension_ti, " (%d DMRS configs seen)", dmrs_configs_seen);
4846 break;
4847 }
4848
4849 case 25: /* SE 25: Symbol reordering for DMRS-BF */
4850 /* Just dissect each available block of 7 bytes as the 14 symbols for a layer,
4851 where each layer could be one or apply to all layers. */
4852 {
4853 /* TODO: should only appear in one section of a message - check? */
4854 unsigned layer = 0;
4855 proto_item *layer_ti;
4856 while (offset+7 <= (extension_start_offset + extlen*4)) {
4857 /* Layer subtree */
4858 layer_ti = proto_tree_add_string_format(extension_tree, hf_oran_symbol_reordering_layer,
4859 tvb, offset, 7, "",
4860 "Layer");
4861 proto_tree *layer_tree = proto_item_add_subtree(layer_ti, ett_oran_symbol_reordering_layer);
4862
4863 /* All 14 symbols for a layer (or all layers) */
4864 for (unsigned s=0; s < 14; s++) {
4865 proto_item *sym_ti;
4866 /* txWinForOnAirSymbol */
4867 unsigned int tx_win_for_on_air_symbol;
4868 sym_ti = proto_tree_add_item_ret_uint(layer_tree,
4869 (s % 2) ? hf_oran_tx_win_for_on_air_symbol_r : hf_oran_tx_win_for_on_air_symbol_l,
4870 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &tx_win_for_on_air_symbol);
4871 if (tx_win_for_on_air_symbol == 0x0F) {
4872 /* Ordering not affected */
4873 proto_item_append_text(sym_ti, " (sym %u - no info)", s);
4874 }
4875 else {
4876 proto_item_append_text(sym_ti, " (sym %u)", s);
4877 }
4878 if (s % 2) {
4879 offset += 1;
4880 }
4881 }
4882
4883 proto_item_append_text(layer_ti, " (layer %u)", ++layer);
4884 proto_item_append_text(extension_ti, " (layer %u)", layer);
4885 }
4886 /* Set layer subtree label */
4887 if (layer == 1) {
4888 proto_item_append_text(layer_ti, " (all)");
4889 proto_item_append_text(extension_ti, " (all)");
4890 }
4891 if (layer == 0) {
4892 /* TODO: are no layers valid? What does it mean? */
4893 proto_item_append_text(extension_ti, " (none)");
4894 }
4895 break;
4896 }
4897
4898 case 26: /* SE 26: Frequency offset feedback */
4899 /* Reserved (8 bits) */
4900 add_reserved_field(extension_tree, hf_oran_reserved_8bits, tvb, offset, 1);
4901 offset += 1;
4902 /* Reserved (1 bit) */
4903 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
4904 /* numFoFb (7 bits) */
4905 unsigned num_fo_fb;
4906 proto_tree_add_item_ret_uint(extension_tree, hf_oran_num_fo_fb, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &num_fo_fb);
4907 offset += 1;
4908
4909 /* Add each freqOffsetFb value */
4910 for (unsigned n=0; n < num_fo_fb; n++) {
4911 unsigned freq_offset_fb;
4912 /* freqOffsetFb (16 bits) */
4913 proto_item *offset_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_freq_offset_fb,
4914 tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &freq_offset_fb);
4915 /* Show if maps onto a -ve number */
4916 if ((freq_offset_fb >= 0x8ad0) && (freq_offset_fb <= 0xffff)) {
4917 proto_item_append_text(offset_ti, "(value %d)", -1 - (0xffff-freq_offset_fb));
4918 }
4919 proto_item_append_text(offset_ti, " [#%u]", n+1);
4920 offset += 2;
4921 }
4922 break;
4923
4924 case 27: /* SE 27: O-DU controlled dimensionality reduction */
4925 {
4926 /* Hidden filter for bf (DMRS BF) */
4927 bf_ti = proto_tree_add_item(tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
4928 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
4929
4930 /* beamType (2 bits) */
4931 unsigned beam_type;
4932 proto_tree_add_item_ret_uint(extension_tree, hf_oran_beam_type, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &beam_type);
4933 /* reserved (6 bits) */
4934 add_reserved_field(extension_tree, hf_oran_reserved_last_6bits, tvb, offset, 1);
4935 offset += 1;
4936
4937 /* numElements */
4938 unsigned num_elements;
4939 proto_item *num_elements_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_num_elements, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &num_elements);
4940 if (num_elements == 0) {
4941 num_elements = 256;
4942 proto_item_append_text(num_elements_ti, " (256");
4943 }
4944
4945 offset += 1;
4946
4947 /* beamId value(s) */
4948 switch (beam_type) {
4949 case 0:
4950 for (unsigned n=0; n < num_elements; n++) {
4951 /* reserved (1 bit) + beamId */
4952 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
4953 proto_tree_add_item(c_section_tree, hf_oran_beamId, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4954 offset += 2;
4955 }
4956 break;
4957 case 1:
4958 /* reserved (1 bit) + beamId */
4959 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
4960 proto_tree_add_item(c_section_tree, hf_oran_beamId, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4961 offset += 2;
4962 break;
4963 default:
4964 /* Unknown type... */
4965 break;
4966 }
4967 break;
4968 }
4969
4970 case 28: /* SE 28: O-DU controlled frequency resolution for SINR reporting */
4971 {
4972 /* reserved (3 bits) */
4973 add_reserved_field(extension_tree, hf_oran_reserved_3bits, tvb, offset, 1);
4974 /* numUeSinrRpt (5 bits) */
4975 uint32_t num_ue_sinr_rpt;
4976 proto_tree_add_item_ret_uint(extension_tree, hf_oran_num_ue_sinr_rpt, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &num_ue_sinr_rpt);
4977 offset += 1;
4978
4979 for (uint32_t n=0; n < num_ue_sinr_rpt; n++) {
4980 /* reserved (1 bit) */
4981 add_reserved_field(extension_tree, (n % 2) ? hf_oran_reserved_bit4 : hf_oran_reserved_1bit,
4982 tvb, offset, 1);
4983
4984 /* numSinrPerPrb (3 bits). Taken from alternate nibbles within byte. */
4985 proto_tree_add_item(extension_tree, (n % 2) ? hf_oran_num_sinr_per_prb_right : hf_oran_num_sinr_per_prb,
4986 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4987 if (n % 2) {
4988 offset += 1;
4989 }
4990 }
4991
4992 /* May need to skip beyond half-used byte */
4993 if (num_ue_sinr_rpt % 2) {
4994 offset += 1;
4995 }
4996 break;
4997 }
4998
4999 case 29: /* SE 29: Cyclic delay adjustment */
5000 /* reserved (4 bits) */
5001 add_reserved_field(extension_tree, hf_oran_reserved_4bits, tvb, offset, 1);
5002 /* cdScgSize (4 bits) */
5003 proto_tree_add_item(extension_tree, hf_oran_cd_scg_size, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5004 offset += 1;
5005
5006 /* cdScgPhaseStep */
5007 proto_tree_add_item(extension_tree, hf_oran_cd_scg_phase_step, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5008 offset += 1;
5009 break;
5010
5011 case 30: /* SE 30: PUSCH repetition indication */
5012 {
5013 /* Only valid for UL */
5014 if (!tap_info->uplink) {
5015 expert_add_info(pinfo, extension_ti, &ei_oran_se30_not_ul);
5016 }
5017
5018 /* ueids[], number_of_ueids may have been rewritten by SE10 */
5019
5020 /* reserved (4 bits) */
5021 add_reserved_field(extension_tree, hf_oran_reserved_4bits, tvb, offset, 1);
5022 /* numRepUe (4 bits) */
5023 uint8_t num_rep_ue;
5024 proto_tree_add_item_ret_uint8(extension_tree, hf_oran_num_rep_ue, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &num_rep_ue);
5025 offset ++;
5026 /* reserved (8 bits) */
5027 add_reserved_field(extension_tree, hf_oran_reserved_8bits, tvb, offset, 1);
5028 offset += 1;
5029
5030 if (num_rep_ue == 1) {
5031 /* SE10 *not* present. N.B. this should tally with number_of_ueids being set to only 1? */
5032 /* reserved (1 bit) */
5033 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
5034 /* isLastRep (1 bit). Value meaningless here? */
5035 proto_tree_add_item(extension_tree, hf_oran_is_last_rep, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5036 /* repIndex (6 bits) */
5037 proto_tree_add_item(extension_tree, hf_oran_rep_index, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5038 offset += 1;
5039
5040 /* reserved (2 bits) */
5041 add_reserved_field(extension_tree, hf_oran_reserved_2bits, tvb, offset, 1);
5042 /* numReps (6 bits) */
5043 uint8_t num_reps;
5044 proto_tree_add_item_ret_uint8(extension_tree, hf_oran_num_reps, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &num_reps);
5045 /* TODO: should numReps be 0 here? */
5046 offset += 1;
5047
5048 /* reserved (2 bits) */
5049 add_reserved_field(extension_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5050 offset += 2;
5051
5052 }
5053 else {
5054 /* SE10 present */
5055 bool_Bool is_last_rep = false0;
5056 /* TODO: should is_last_rep (also) cause loop exit? */
5057 for (uint8_t ue_idx=0; (ue_idx < num_rep_ue) && !is_last_rep; ue_idx++) {
5058 /* reserved (1 bit) */
5059 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
5060 /* isLastRep (1 bit) */
5061 proto_tree_add_item_ret_boolean(extension_tree, hf_oran_is_last_rep, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &is_last_rep);
5062 /* repIndex (6 bits) */
5063 proto_tree_add_item(extension_tree, hf_oran_rep_index, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5064 offset += 1;
5065
5066 /* reserved (2 bits) */
5067 add_reserved_field(extension_tree, hf_oran_reserved_2bits, tvb, offset, 1);
5068 /* numReps (6 bits) */
5069 uint8_t num_reps;
5070 proto_item *num_reps_ti = proto_tree_add_item_ret_uint8(extension_tree, hf_oran_num_reps, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &num_reps);
5071 /* TODO: values 33-63 are reserved */
5072 if (num_reps > 32) {
5073 proto_item_append_text(num_reps_ti, " (reserved)");
5074 }
5075 offset += 1;
5076
5077 for (uint8_t rep=0; rep < num_reps; rep++) {
5078 /* reserved (1 bit) */
5079 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
5080 /* repUeId (15 bits) */
5081 /* TODO: should be fetching and comparing with ueids[] from SE10? */
5082 uint16_t ueid;
5083 proto_item *ueid_ti = proto_tree_add_item_ret_uint16(extension_tree, hf_oran_rep_ueid, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &ueid);
5084
5085 /* Check that this ueid is recognised (among ueids[], number_of_ueids) */
5086 bool_Bool matched = false0;
5087 for (unsigned u=0; u < number_of_ueids; u++) {
5088 if (ueid == ueids[u])
5089 matched = true1;
5090 }
5091 if (!matched) {
5092 expert_add_info_format(pinfo, ueid_ti, &ei_oran_se30_unknown_ueid,
5093 "SE 30 mentions UEId %u - not seen in SE10", ueid);
5094 }
5095 offset += 2;
5096 }
5097 }
5098 }
5099 break;
5100 }
5101 case 31: /* SE 31: MCS Information */
5102 /* TODO: */
5103 break;
5104
5105 case 32: /* SE 32: Rank and TPMI measurement request */
5106 /* TODO: */
5107 break;
5108
5109 default:
5110 /* Other/unexpected extension types */
5111 expert_add_info_format(pinfo, exttype_ti, &ei_oran_unhandled_se,
5112 "SE %u (%s) not supported by dissector",
5113 exttype, val_to_str_ext_const(exttype, &exttype_vals_ext, "Reserved"));
5114 ext_unhandled = true1;
5115 break;
5116 }
5117
5118 /* Check offset compared with extlen. There should be 0-3 bytes of padding */
5119 int num_padding_bytes = (extension_start_offset + (extlen*4) - offset);
5120 if (!ext_unhandled && ((num_padding_bytes<0) || (num_padding_bytes>3))) {
5121 expert_add_info_format(pinfo, extlen_ti, &ei_oran_extlen_wrong,
5122 "extlen signalled %u bytes (+ 0-3 bytes padding), but %u were dissected",
5123 extlen*4, offset-extension_start_offset);
5124 }
5125
5126 /* Move offset to beyond signalled length of extension */
5127 offset = extension_start_offset + (extlen*4);
5128
5129 /* Set length of extension header. */
5130 proto_item_set_len(extension_ti, extlen*4);
5131 }
5132 /* End of section extension handling */
5133
5134 /* Tap section beamId if not overwritten by SEs */
5135 if (!section_beamId_ignored && section_beamId != 0) {
5136 add_beam_id_to_tap(tap_info, section_beamId);
5137 }
5138
5139
5140 /* RRM measurement reports have measurement reports *after* extensions */
5141 if (sectionType == SEC_C_RRM_MEAS_REPORTS) /* Section Type 10 */
5142 {
5143 /* Hidden filter for bf (DMFS-BF). No BF weights though.. */
5144 bf_ti = proto_tree_add_item(c_section_tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
5145 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
5146
5147 bool_Bool mf;
5148 do {
5149 /* Measurement report subtree */
5150 proto_item *mr_ti = proto_tree_add_string_format(c_section_tree, hf_oran_measurement_report,
5151 tvb, offset, 1, "", "Measurement Report");
5152 proto_tree *mr_tree = proto_item_add_subtree(mr_ti, ett_oran_measurement_report);
5153 unsigned report_start_offset = offset;
5154
5155 /* measurement flag (i.e., more reports after this one) (1 bit) */
5156 proto_tree_add_item_ret_boolean(mr_tree, hf_oran_mf, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &mf);
5157
5158 /* measTypeId (7 bits) */
5159 uint32_t meas_type_id;
5160 proto_item *meas_type_id_ti;
5161 meas_type_id_ti = proto_tree_add_item_ret_uint(mr_tree, hf_oran_meas_type_id, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &meas_type_id);
5162 offset += 1;
5163
5164 /* Common to all measurement types */
5165 unsigned num_elements = 0;
5166 if (meas_type_id == 6) {
5167 /* numElements */
5168 proto_tree_add_item_ret_uint(mr_tree, hf_oran_num_elements, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &num_elements);
5169 }
5170 else {
5171 /* All other meas ids have a reserved byte */
5172 add_reserved_field(mr_tree, hf_oran_reserved_8bits, tvb, offset, 1);
5173 }
5174 offset += 1;
5175
5176 /* measDataSize (16 bits). N.B. begins at mf field, i.e. 2 bytes before this one */
5177 unsigned meas_data_size;
5178 proto_item *meas_data_size_ti;
5179 meas_data_size_ti = proto_tree_add_item_ret_uint(mr_tree, hf_oran_meas_data_size, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &meas_data_size);
5180 meas_data_size *= 4;
5181 proto_item_append_text(meas_data_size_ti, " (%u bytes)", meas_data_size);
5182 offset += 2;
5183
5184 /* Summary for measurement report root */
5185 proto_item_append_text(mr_ti, " (measTypeId=%u - %s)",
5186 meas_type_id, val_to_str_const(meas_type_id, meas_type_id_vals, "unknown"));
5187 /* And section header */
5188 proto_item_append_text(tree, " (%s)", val_to_str_const(meas_type_id, meas_type_id_vals, "unknown"));
5189 /* And Info column */
5190 col_append_fstr(pinfo->cinfo, COL_INFO, " (%s)", val_to_str_const(meas_type_id, meas_type_id_vals, "unknown"));
5191
5192 /* Handle specific message type fields */
5193 switch (meas_type_id) {
5194 case 1:
5195 {
5196 /* ueTae */
5197 unsigned ue_tae;
5198 proto_item *ue_tae_ti;
5199 ue_tae_ti = proto_tree_add_item_ret_uint(mr_tree, hf_oran_ue_tae, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &ue_tae);
5200 /* Show if maps onto a -ve number */
5201 if ((ue_tae >= 0x8ad0) && (ue_tae <= 0xffff)) {
5202 proto_item_append_text(ue_tae_ti, "(value %d)", -1 - (0xffff-ue_tae));
5203 }
5204 offset += 2;
5205
5206 /* Reserved (16 bits) */
5207 add_reserved_field(mr_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5208 offset += 2;
5209 break;
5210 }
5211 case 2:
5212 /* ueLayerPower entries (how many? for now just use up meas_data_size..) */
5213 /* TODO: add number of distinct dmrsPortNumber entries seen in SE24 and save in state? */
5214 /* Or would it make sense to use the preference 'pref_num_bf_antennas' ? */
5215 for (unsigned n=0; n < (meas_data_size-4)/2; n++) {
5216 unsigned ue_layer_power;
5217 proto_item *ue_layer_power_ti;
5218 ue_layer_power_ti = proto_tree_add_item_ret_uint(mr_tree, hf_oran_ue_layer_power, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &ue_layer_power);
5219 /* Show if maps onto a -ve number */
5220 if ((ue_layer_power >= 0x8ad0) && (ue_layer_power <= 0xffff)) {
5221 proto_item_append_text(ue_layer_power_ti, "(value %d)", -1 - (0xffff-ue_layer_power));
5222 }
5223 offset += 2;
5224 }
5225 /* padding out to 4 bytes */
5226 break;
5227 case 3:
5228 {
5229 /* ueFreqOffset */
5230 unsigned ue_freq_offset;
5231 proto_item *ue_freq_offset_ti;
5232 ue_freq_offset_ti = proto_tree_add_item_ret_uint(mr_tree, hf_oran_ue_freq_offset, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &ue_freq_offset);
5233 /* Show if maps onto a -ve number */
5234 if ((ue_freq_offset >= 0x8ad0) && (ue_freq_offset <= 0xffff)) {
5235 proto_item_append_text(ue_freq_offset_ti, "(value %d)", -1 - (0xffff-ue_freq_offset));
5236 }
5237 offset += 2;
5238
5239 /* Reserved (16 bits) */
5240 add_reserved_field(mr_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5241 offset += 2;
5242 break;
5243 }
5244 case 4:
5245 case 5:
5246 /* reserved (2 bits) */
5247 add_reserved_field(mr_tree, hf_oran_reserved_2bits, tvb, offset, 1);
5248 /* symbolMask (14 bits) */
5249 offset = dissect_symbolmask(tvb, mr_tree, offset, NULL((void*)0), NULL((void*)0));
5250
5251 /* 2 bytes for each PRB ipnPower */
5252 for (unsigned prb=0; prb<MAX_PRBS273; prb++) {
5253 /* Skip if should not be reported */
5254 if (!prbs_for_st10_type5[prb]) {
5255 continue;
5256 }
5257 unsigned ipn_power;
5258 proto_item *ipn_power_ti;
5259 /* ipnPower (2 bytes) */
5260 ipn_power_ti = proto_tree_add_item_ret_uint(mr_tree, hf_oran_ipn_power, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &ipn_power);
5261 proto_item_append_text(ipn_power_ti, " (PRB %3d)", prb);
5262 /* Show if maps onto a -ve number */
5263 if ((ipn_power >= 0x8ad0) && (ipn_power <= 0xffff)) {
5264 proto_item_append_text(ipn_power_ti, " (value %d)", -1 - (0xffff-ipn_power));
5265 }
5266 offset += 2;
5267 }
5268 /* padding out to 4 bytes */
5269 break;
5270 case 6:
5271 /* antDmrsSnrVal entries */
5272 for (unsigned n=0; n < num_elements; n++) {
5273 unsigned snr_value;
5274 proto_item *snr_value_ti;
5275 /* antDmrsSnrVal (2 bytes) */
5276 snr_value_ti = proto_tree_add_item_ret_uint(mr_tree, hf_oran_ant_dmrs_snr_val, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &snr_value);
5277 proto_item_append_text(snr_value_ti, " (elem %2u)", n+1);
5278 /* Show if maps onto a -ve number */
5279 if ((snr_value >= 0x8ad0) && (snr_value <= 0xffff)) {
5280 proto_item_append_text(snr_value_ti, " (value %d)", -1 - (0xffff-snr_value));
5281 }
5282 offset += 2;
5283 }
5284 break;
5285 case 7:
5286 {
5287 /* UE positioning measurement report */
5288 float start_value;
5289
5290 /* ueAzAoa (16 bits) */
5291 uint32_t ue_az_aoa;
5292 proto_item *ue_az_aoa_ti = proto_tree_add_item_ret_uint(mr_tree, hf_oran_ue_az_aoa, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &ue_az_aoa);
5293 if (ue_az_aoa <= 0xE0F) {
5294 if (ue_az_aoa >= 0x0708) {
5295 start_value = (ue_az_aoa-0x0708) * (float)0.1;
5296 proto_item_append_text(ue_az_aoa_ti, " (%.1f <= val < %.1f degrees)", start_value, start_value + (float)0.1);
5297 }
5298 else {
5299 start_value = 180 + (ue_az_aoa * (float)0.1);
5300 proto_item_append_text(ue_az_aoa_ti, " (%.1f <= val < %.1f degrees)", start_value, start_value + (float)0.1);
5301 }
5302 }
5303 else if (ue_az_aoa == 0xffff) {
5304 proto_item_append_text(ue_az_aoa_ti, " (invalid measurement result)");
5305 }
5306 else {
5307 proto_item_append_text(ue_az_aoa_ti, " (reserved)");
5308 }
5309 offset += 2;
5310
5311 /* Reserved (16 bits) */
5312 add_reserved_field(mr_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5313 offset += 2;
5314
5315 /* ueZeAoa (16 bits) */
5316 uint32_t ue_ze_aoa;
5317 proto_item *ue_ze_aoa_ti = proto_tree_add_item_ret_uint(mr_tree, hf_oran_ue_ze_aoa, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &ue_ze_aoa);
5318 if (ue_ze_aoa <= 0x707) {
5319 start_value = ue_ze_aoa * (float)0.1;
5320 proto_item_append_text(ue_ze_aoa_ti, " (%.1f <= val < %.1f degrees)", start_value, start_value + (float)0.1);
5321 }
5322 else if (ue_az_aoa == 0xffff) {
5323 proto_item_append_text(ue_ze_aoa_ti, " (invalid measurement result)");
5324 }
5325 else {
5326 proto_item_append_text(ue_ze_aoa_ti, " (reserved)");
5327 }
5328 offset += 2;
5329
5330 /* Reserved (16 bits) */
5331 add_reserved_field(mr_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5332 offset += 2;
5333
5334 /* uePosToaOffset (16 bits) */
5335 uint32_t ue_pos_toa_offset;
5336 proto_item *ue_pos_toa_offset_ti = proto_tree_add_item_ret_uint(mr_tree, hf_oran_ue_pos_toa_offset, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &ue_pos_toa_offset);
5337 if (ue_pos_toa_offset == 0) {
5338 proto_item_append_text(ue_pos_toa_offset_ti, " (no UE ToA offset, 0 symbols)");
5339 }
5340 else if (ue_pos_toa_offset <= 0x7fff) {
5341 proto_item_append_text(ue_pos_toa_offset_ti, " (+ve UE ToA offset)");
5342 }
5343 else if (ue_pos_toa_offset == 0x8000) {
5344 proto_item_append_text(ue_pos_toa_offset_ti, " (invalid measurement result)");
5345 }
5346 else {
5347 proto_item_append_text(ue_pos_toa_offset_ti, " (-ve UE ToA offset)");
5348 }
5349 offset += 2;
5350
5351 /* Reserved (16 bits) */
5352 add_reserved_field(mr_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5353 offset += 2;
5354 break;
5355 }
5356 case 8:
5357 {
5358 /* UE radial speed measurement report */
5359
5360 /* ueRadialSpeed (16 bits) */
5361 uint32_t radial_speed;
5362 proto_item *radial_speed_ti = proto_tree_add_item_ret_uint(mr_tree, hf_oran_ue_radial_speed, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &radial_speed);
5363 if (radial_speed <= 10000) {
5364 proto_item_append_text(radial_speed_ti, " (%.1f km/h)", radial_speed * (float)0.1);
5365 }
5366 else if (radial_speed == 0x8000) {
5367 proto_item_append_text(radial_speed_ti, " (invalid measurement result)");
5368 }
5369 else {
5370 proto_item_append_text(radial_speed_ti, " (reserved value)");
5371 }
5372 offset += 2;
5373
5374 /* Reserved (16 bits) */
5375 add_reserved_field(mr_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5376 offset += 2;
5377 break;
5378 }
5379 case 9:
5380 {
5381 /* TODO: UE post-equalization MU interference measurement */
5382 break;
5383 }
5384 case 10:
5385 {
5386 /* TODO: UE TPMI and rank recommendation measurement */
5387 break;
5388 }
5389 case 11:
5390 {
5391 /* TODO: UE layer pre-equalization SINR report */
5392 break;
5393 }
5394
5395 default:
5396 /* Anything else is not expected */
5397 expert_add_info_format(pinfo, meas_type_id_ti, &ei_oran_unexpected_measTypeId,
5398 "measTypeId %u (%s) not supported - only 1-6 are expected",
5399 meas_type_id,
5400 val_to_str_const(meas_type_id, meas_type_id_vals, "reserved"));
5401 break;
5402
5403 }
5404
5405 /* Pad out to next 4 bytes */
5406 offset += WS_PADDING_TO_4(offset-report_start_offset)((4U - ((offset-report_start_offset) % 4U)) % 4U);
5407
5408 /* TODO: verify dissected size of report vs meas_data_size? */
5409
5410 /* End of measurement report tree */
5411 proto_item_set_end(mr_ti, tvb, offset);
5412 } while (mf);
5413 }
5414
5415 /* Request for RRM Measurements has measurement commands after extensions */
5416 else if (sectionType == SEC_C_REQUEST_RRM_MEAS) /* Section Type 11 */
5417 {
5418 bool_Bool mf = true1;
5419 do {
5420 /* Measurement command subtree */
5421 proto_item *mc_ti = proto_tree_add_string_format(c_section_tree, hf_oran_measurement_command,
5422 tvb, offset, 8, "", "Measurement Command");
5423 proto_tree *mc_tree = proto_item_add_subtree(mc_ti, ett_oran_measurement_command);
5424
5425 /* mf (1 bit). 1st measurement command is always preset */
5426 proto_tree_add_item_ret_boolean(mc_tree, hf_oran_mf, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &mf);
5427
5428 /* measTypeId (7 bits) */
5429 uint32_t meas_type_id;
5430 proto_item *meas_type_id_ti;
5431 meas_type_id_ti = proto_tree_add_item_ret_uint(mc_tree, hf_oran_meas_type_id, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &meas_type_id);
5432 offset += 1;
5433
5434 proto_item *meas_command_ti;
5435 uint32_t meas_command_size;
5436
5437 switch (meas_type_id) {
5438 case 5: /* command for IpN for unallocated PRBs */
5439 /* reserved (1 byte) */
5440 add_reserved_field(mc_tree, hf_oran_reserved_8bits, tvb, offset, 1);
5441 offset += 1;
5442 /* measCmdSize. Presumably number of words so in future could skip unrecognised command types.. */
5443 meas_command_ti = proto_tree_add_item_ret_uint(mc_tree, hf_oran_meas_cmd_size, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &meas_command_size);
5444 proto_item_append_text(meas_command_ti, " (%u bytes)", meas_command_size*4);
5445 offset += 2;
5446 /* reserved (2 bits) */
5447 add_reserved_field(mc_tree, hf_oran_reserved_2bits, tvb, offset, 1);
5448 /* symbolMask (14 bits) */
5449 offset = dissect_symbolmask(tvb, mc_tree, offset, NULL((void*)0), NULL((void*)0));
5450 /* reserved (16 bits) */
5451 add_reserved_field(mc_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5452 offset += 2;
5453 break;
5454
5455 default:
5456 /* Anything else is not expected */
5457 expert_add_info_format(pinfo, meas_type_id_ti, &ei_oran_unexpected_measTypeId,
5458 "measTypeId %u (%s) not supported - only 5 is expected",
5459 meas_type_id,
5460 val_to_str_const(meas_type_id, meas_type_id_vals, "reserved"));
5461 break;
5462 }
5463 proto_item_append_text(mc_ti, " (%s)", val_to_str_const(meas_type_id, meas_type_id_vals, "unknown"));
5464
5465 } while (mf);
5466 }
5467
5468 /* Set extent of overall section */
5469 proto_item_set_len(sectionHeading, offset);
5470
5471 return offset;
5472}
5473
5474/* Dissect udCompHdr (user data compression header, 7.5.2.10) */
5475/* bit_width and comp_meth are out params */
5476static int dissect_udcomphdr(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset,
5477 bool_Bool cplane, bool_Bool ignore,
5478 unsigned *bit_width, unsigned *comp_meth, proto_item **comp_meth_ti,
5479 oran_tap_info *tap_info)
5480{
5481 /* Subtree */
5482 proto_item *udcomphdr_ti = proto_tree_add_string_format(tree, hf_oran_udCompHdr,
5483 tvb, offset, 1, "",
5484 "udCompHdr");
5485 proto_tree *udcomphdr_tree = proto_item_add_subtree(udcomphdr_ti, ett_oran_udcomphdr);
5486
5487 /* udIqWidth */
5488 uint32_t hdr_iq_width;
5489 proto_item *iq_width_item = proto_tree_add_item_ret_uint(udcomphdr_tree, hf_oran_udCompHdrIqWidth , tvb, offset, 1, ENC_NA0x00000000, &hdr_iq_width);
5490 *bit_width = (hdr_iq_width) ? hdr_iq_width : 16;
5491 proto_item_append_text(iq_width_item, " (%u bits)", *bit_width);
5492
5493 /* udCompMeth */
5494 uint32_t ud_comp_meth;
5495 *comp_meth_ti = proto_tree_add_item_ret_uint(udcomphdr_tree, hf_oran_udCompHdrMeth, tvb, offset, 1, ENC_NA0x00000000, &ud_comp_meth);
5496 if (comp_meth) {
5497 *comp_meth = ud_comp_meth;
5498 }
5499
5500 /* Populate tap header with compression settings */
5501 if (!ignore) {
5502 tap_info->compression_methods |= (1 << ud_comp_meth);
5503 tap_info->compression_width = MAX(tap_info->compression_width, hdr_iq_width)(((tap_info->compression_width) > (hdr_iq_width)) ? (tap_info
->compression_width) : (hdr_iq_width))
;
5504 /* Summary */
5505 proto_item_append_text(udcomphdr_ti, " (IqWidth=%u, udCompMeth=%s)",
5506 *bit_width, rval_to_str_const(ud_comp_meth, ud_comp_header_meth, "Unknown"));
5507 }
5508 else {
5509 proto_item_append_text(udcomphdr_ti, " (ignored)");
5510 if (hdr_iq_width || ud_comp_meth) {
5511 if (cplane) {
5512 /* Only ignore DL for cplane */
5513 expert_add_info_format(pinfo, udcomphdr_ti, &ei_oran_udpcomphdr_should_be_zero,
5514 "udCompHdr in C-Plane for DL should be 0 - found 0x%02x",
5515 tvb_get_uint8(tvb, offset));
5516 }
5517 else {
5518 /* TODO: Ignore UL if using m-plane/preference setting rather than c-plane, but wrong to be set? */
5519 /* expert_add_info_format(pinfo, udcomphdr_ti, &ei_oran_udpcomphdr_should_be_zero,
5520 "udCompHdr in C-Plane for UL should be 0 - found 0x%02x",
5521 tvb_get_uint8(tvb, offset));
5522 */
5523 }
5524
5525 }
5526 }
5527 return offset+1;
5528}
5529
5530/* Dissect udCompParam (user data compression parameter, 8.3.3.15) */
5531/* bit_width and comp_meth are out params */
5532static int dissect_udcompparam(tvbuff_t *tvb, packet_info *pinfo _U___attribute__((unused)), proto_tree *tree, unsigned offset,
5533 unsigned comp_meth,
5534 uint32_t *exponent, uint16_t *sReSMask,
5535 bool_Bool for_sinr)
5536{
5537 if (for_sinr && (comp_meth != COMP_BLOCK_FP1)) {
5538 /* sinrCompParam only present when bfp is used */
5539 return offset;
5540 }
5541
5542 if (comp_meth == COMP_NONE0 ||
5543 comp_meth == COMP_MODULATION4 ||
5544 comp_meth == MOD_COMPR_AND_SELECTIVE_RE_WITH_MASKS8) {
5545
5546 /* Not even creating a subtree for udCompMeth 0, 4, 8 */
5547 return offset;
5548 }
5549
5550 /* Subtree */
5551 unsigned start_offset = offset;
5552 proto_item *udcompparam_ti = proto_tree_add_string_format(tree, hf_oran_udCompParam,
5553 tvb, offset, 1, "",
5554 (for_sinr) ? "sinrCompParam" : "udCompParam");
5555 proto_tree *udcompparam_tree = proto_item_add_subtree(udcompparam_ti, ett_oran_udcompparam);
5556
5557 /* Show comp_meth as a generated field */
5558 proto_item *meth_ti = proto_tree_add_uint(udcompparam_tree, hf_oran_udCompHdrMeth_pref, tvb, 0, 0, comp_meth);
5559 proto_item_set_generated(meth_ti);
5560
5561 uint32_t param_exponent;
5562 uint64_t param_sresmask;
5563
5564 static int * const sres_mask_flags[] = {
5565 &hf_oran_sReSMask_re12,
5566 &hf_oran_sReSMask_re11,
5567 &hf_oran_sReSMask_re10,
5568 &hf_oran_sReSMask_re9,
5569 &hf_oran_sReSMask_re8,
5570 &hf_oran_sReSMask_re7,
5571 &hf_oran_sReSMask_re6,
5572 &hf_oran_sReSMask_re5,
5573 &hf_oran_sReSMask_re4,
5574 &hf_oran_sReSMask_re3,
5575 &hf_oran_sReSMask_re2,
5576 &hf_oran_sReSMask_re1,
5577 NULL((void*)0)
5578 };
5579
5580 switch (comp_meth) {
5581 case COMP_BLOCK_FP1: /* 1 */
5582 case BFP_AND_SELECTIVE_RE_WITH_MASKS7: /* 7 */
5583 /* reserved (4 bits) */
5584 add_reserved_field(udcompparam_tree, hf_oran_reserved_4bits, tvb, offset, 1);
5585 /* exponent (4 bits) */
5586 proto_tree_add_item_ret_uint(udcompparam_tree, hf_oran_exponent,
5587 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &param_exponent);
5588 *exponent = param_exponent;
5589 proto_item_append_text(udcompparam_ti, " (Exponent=%u)", param_exponent);
5590 offset += 1;
5591 break;
5592
5593 case COMP_BLOCK_SCALE2: /* 2 */
5594 /* Separate into integer and fractional bits? */
5595 proto_tree_add_item(udcompparam_tree, hf_oran_blockScaler,
5596 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5597 offset++;
5598 break;
5599
5600 case COMP_U_LAW3: /* 3 */
5601 /* compBitWidth, compShift */
5602 proto_tree_add_item(udcompparam_tree, hf_oran_compBitWidth,
5603 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5604 proto_tree_add_item(udcompparam_tree, hf_oran_compShift,
5605 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5606 offset += 1;
5607 break;
5608
5609 case BFP_AND_SELECTIVE_RE5: /* 5 */
5610 {
5611 /* sReSMask (exponent in middle!) */
5612 proto_item *sresmask_ti;
5613 sresmask_ti = proto_tree_add_bitmask_ret_uint64(udcompparam_tree, tvb, offset,
5614 hf_oran_sReSMask,
5615 ett_oran_sresmask,
5616 sres_mask_flags,
5617 ENC_NA0x00000000,
5618 &param_sresmask);
5619
5620 /* Get rid of exponent-shaped gap */
5621 param_sresmask = ((param_sresmask >> 4) & 0x0f00) | (param_sresmask & 0xff);
5622 unsigned res = 0;
5623 for (unsigned n=0; n < 12; n++) {
5624 if ((param_sresmask >> n) & 0x1) {
5625 res++;
5626 }
5627 }
5628 proto_item_append_text(sresmask_ti, " (%2u REs)", res);
5629
5630 /* exponent */
5631 proto_tree_add_item_ret_uint(udcompparam_tree, hf_oran_exponent,
5632 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &param_exponent);
5633 *sReSMask = (uint16_t)param_sresmask;
5634 *exponent = param_exponent;
5635
5636 proto_item_append_text(udcompparam_ti, " (exponent=%u, %u REs)", *exponent, res);
5637 offset += 2;
5638 break;
5639 }
5640
5641 case MOD_COMPR_AND_SELECTIVE_RE6: /* 6 */
5642 {
5643 /* sReSMask (exponent in middle!) */
5644 proto_item *sresmask_ti;
5645
5646 sresmask_ti = proto_tree_add_bitmask_ret_uint64(udcompparam_tree, tvb, offset,
5647 hf_oran_sReSMask,
5648 ett_oran_sresmask,
5649 sres_mask_flags,
5650 ENC_NA0x00000000,
5651 &param_sresmask);
5652
5653 /* Get rid of reserved-shaped gap */
5654 param_sresmask = ((param_sresmask >> 4) & 0x0f00) | (param_sresmask & 0xff);
5655 unsigned res = 0;
5656 for (unsigned n=0; n < 12; n++) {
5657 if ((param_sresmask >> n) & 0x1) {
5658 res++;
5659 }
5660 }
5661 proto_item_append_text(sresmask_ti, " (%u REs)", res);
5662
5663 /* reserved (4 bits) */
5664 add_reserved_field(udcompparam_tree, hf_oran_reserved_last_4bits, tvb, offset, 1);
5665 *sReSMask = (uint16_t)param_sresmask;
5666
5667 proto_item_append_text(udcompparam_ti, " (%u REs)", res);
5668 offset += 2;
5669 break;
5670 }
5671
5672 default:
5673 /* reserved (set to all zeros), but how many bytes?? */
5674 break;
5675 }
5676
5677 proto_item_set_len(udcompparam_ti, offset-start_offset);
5678 return offset;
5679}
5680
5681
5682/* Dissect ciCompHdr (channel information compression header, 7.5.2.15) */
5683/* bit_width and comp_meth are out params */
5684static int dissect_cicomphdr(tvbuff_t *tvb, packet_info *pinfo _U___attribute__((unused)), proto_tree *tree, unsigned offset,
5685 unsigned *bit_width, unsigned *comp_meth, uint8_t *comp_opt)
5686{
5687 /* Subtree */
5688 proto_item *cicomphdr_ti = proto_tree_add_string_format(tree, hf_oran_ciCompHdr,
5689 tvb, offset, 1, "",
5690 "ciCompHdr");
5691 proto_tree *cicomphdr_tree = proto_item_add_subtree(cicomphdr_ti, ett_oran_cicomphdr);
5692
5693 /* ciIqWidth */
5694 uint32_t hdr_iq_width;
5695 proto_item *iq_width_item = proto_tree_add_item_ret_uint(cicomphdr_tree, hf_oran_ciCompHdrIqWidth , tvb, offset, 1, ENC_NA0x00000000, &hdr_iq_width);
5696 hdr_iq_width = (hdr_iq_width) ? hdr_iq_width : 16;
5697 if (bit_width) {
5698 *bit_width = hdr_iq_width;
5699 }
5700 proto_item_append_text(iq_width_item, " (%u bits)", hdr_iq_width);
5701
5702 /* ciCompMeth */
5703 uint32_t ci_comp_meth;
5704 proto_tree_add_item_ret_uint(cicomphdr_tree, hf_oran_ciCompHdrMeth, tvb, offset, 1, ENC_NA0x00000000, &ci_comp_meth);
5705 if (comp_meth) {
5706 *comp_meth = ci_comp_meth;
5707 }
5708
5709 /* ciCompOpt */
5710 uint32_t opt;
5711 proto_tree_add_item_ret_uint(cicomphdr_tree, hf_oran_ciCompOpt, tvb, offset, 1, ENC_NA0x00000000, &opt);
5712 *comp_opt = opt;
5713 offset += 1;
5714
5715 /* Summary */
5716 proto_item_append_text(cicomphdr_ti, " (IqWidth=%u, ciCompMeth=%s, ciCompOpt=%s)",
5717 hdr_iq_width,
5718 rval_to_str_const(ci_comp_meth, ud_comp_header_meth, "Unknown"),
5719 (*comp_opt) ? "compression per PRB" : "compression per UE");
5720 return offset;
5721}
5722
5723static void dissect_payload_version(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, unsigned offset)
5724{
5725 unsigned version;
5726 proto_item *ti = proto_tree_add_item_ret_uint(tree, hf_oran_payload_version, tvb, offset, 1, ENC_NA0x00000000, &version);
5727 if (version != 1) {
5728 expert_add_info_format(pinfo, ti, &ei_oran_version_unsupported,
5729 "PayloadVersion %u not supported by dissector (only 1 is known)",
5730 version);
5731 /* TODO: should throw an exception? */
5732 }
5733}
5734
5735static void show_link_to_acknack_request(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo,
5736 ack_nack_request_t *request)
5737{
5738 /* Request frame */
5739 proto_item *ti = proto_tree_add_uint(tree, hf_oran_acknack_request_frame,
5740 tvb, 0, 0, request->request_frame_number);
5741 PROTO_ITEM_SET_GENERATED(ti)proto_item_set_generated((ti));
5742
5743 /* Work out gap between frames (in ms) */
5744 int seconds_between_packets = (int)
5745 (pinfo->abs_ts.secs - request->request_frame_time.secs);
5746 int nseconds_between_packets =
5747 pinfo->abs_ts.nsecs - request->request_frame_time.nsecs;
5748
5749 int total_gap = (seconds_between_packets*1000) +
5750 ((nseconds_between_packets+500000) / 1000000);
5751
5752 ti = proto_tree_add_uint(tree, hf_oran_acknack_request_time,
5753 tvb, 0, 0, total_gap);
5754 PROTO_ITEM_SET_GENERATED(ti)proto_item_set_generated((ti));
5755
5756 /* Type of request */
5757 ti = proto_tree_add_uint(tree, hf_oran_acknack_request_type,
5758 tvb, 0, 0, request->requestType);
5759 PROTO_ITEM_SET_GENERATED(ti)proto_item_set_generated((ti));
5760}
5761
5762static void show_link_to_acknack_response(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo,
5763 ack_nack_request_t *response)
5764{
5765 if (response->response_frame_number == 0) {
5766 /* Requests may not get a response, and can't always tell when to expect one */
5767 return;
5768 }
5769
5770 /* Response frame */
5771 proto_item *ti = proto_tree_add_uint(tree, hf_oran_acknack_response_frame,
5772 tvb, 0, 0, response->response_frame_number);
5773 PROTO_ITEM_SET_GENERATED(ti)proto_item_set_generated((ti));
5774
5775 /* Work out gap between frames (in ms) */
5776 int seconds_between_packets = (int)
5777 (response->response_frame_time.secs - pinfo->abs_ts.secs);
5778 int nseconds_between_packets =
5779 response->response_frame_time.nsecs - pinfo->abs_ts.nsecs;
5780
5781 int total_gap = (seconds_between_packets*1000) +
5782 ((nseconds_between_packets+500000) / 1000000);
5783
5784 ti = proto_tree_add_uint(tree, hf_oran_acknack_response_time,
5785 tvb, 0, 0, total_gap);
5786 PROTO_ITEM_SET_GENERATED(ti)proto_item_set_generated((ti));
5787}
5788
5789
5790
5791/* Control plane dissector (section 7). */
5792static int dissect_oran_c(tvbuff_t *tvb, packet_info *pinfo,
5793 proto_tree *tree, oran_tap_info *tap_info, void *data _U___attribute__((unused)))
5794{
5795 /* Hidden filter for plane */
5796 proto_item *plane_ti = proto_tree_add_item(tree, hf_oran_cplane, tvb, 0, 0, ENC_NA0x00000000);
5797 PROTO_ITEM_SET_HIDDEN(plane_ti)proto_item_set_hidden((plane_ti));
5798
5799 /* Set up structures needed to add the protocol subtree and manage it */
5800 unsigned offset = 0;
5801
5802 col_set_str(pinfo->cinfo, COL_PROTOCOL, "O-RAN-FH-C");
5803 col_set_str(pinfo->cinfo, COL_INFO, "C-Plane");
5804
5805 tap_info->userplane = false0;
5806
5807 /* Create display subtree for the protocol */
5808 proto_item *protocol_item = proto_tree_add_item(tree, proto_oran, tvb, 0, -1, ENC_NA0x00000000);
5809 proto_item_append_text(protocol_item, "-C");
5810 proto_tree *oran_tree = proto_item_add_subtree(protocol_item, ett_oran);
5811
5812 /* ecpriRtcid (eAxC ID) */
5813 uint16_t eAxC;
5814 addPcOrRtcid(tvb, oran_tree, &offset, hf_oran_ecpri_rtcid, &eAxC, tap_info);
5815 tap_info->eaxc = eAxC;
5816
5817 /* Look up any existing conversation state for eAxC+plane */
5818 uint32_t key = make_flow_key(pinfo, eAxC, ORAN_C_PLANE0, false0);
5819 flow_state_t* state = (flow_state_t*)wmem_tree_lookup32(flow_states_table, key);
5820
5821 /* Message identifier */
5822 uint32_t seq_id, sub_seq_id, e;
5823 proto_item *seq_id_ti;
5824 offset = addSeqid(tvb, oran_tree, offset, ORAN_C_PLANE0, &seq_id, &seq_id_ti, pinfo, &sub_seq_id, &e);
5825
5826 /* Section common subtree */
5827 int section_tree_offset = offset;
5828 proto_item *sectionHeading = proto_tree_add_string_format(oran_tree, hf_oran_c_section_common,
5829 tvb, offset, 0, "", "C-Plane Section Type ");
5830 proto_tree *section_tree = proto_item_add_subtree(sectionHeading, ett_oran_c_section_common);
5831
5832 /* Peek ahead at the section type */
5833 uint32_t sectionType = 0;
5834 sectionType = tvb_get_uint8(tvb, offset+5);
5835
5836 uint32_t scs = 0;
5837 proto_item *scs_ti = NULL((void*)0);
5838
5839 /* dataDirection */
5840 uint32_t direction = 0;
5841 proto_item *datadir_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_data_direction, tvb, offset, 1, ENC_NA0x00000000, &direction);
5842 tap_info->uplink = (direction==0);
5843
5844 /* Update/report status of conversation */
5845 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
5846
5847 if (state == NULL((void*)0)) {
5848 /* Allocate new state */
5849 state = wmem_new0(wmem_file_scope(), flow_state_t)((flow_state_t*)wmem_alloc0((wmem_file_scope()), sizeof(flow_state_t
)))
;
5850 state->ack_nack_requests = wmem_tree_new(wmem_file_scope());
5851 wmem_tree_insert32(flow_states_table, key, state);
5852 state->expected_dl_sections = wmem_tree_new(wmem_file_scope());
5853 }
5854
5855 /* Check sequence analysis status */
5856 if (state->last_frame_seen[direction] && (seq_id != state->next_expected_sequence_number[direction])) {
5857 /* Store this result */
5858 flow_result_t *result = wmem_new0(wmem_file_scope(), flow_result_t)((flow_result_t*)wmem_alloc0((wmem_file_scope()), sizeof(flow_result_t
)))
;
5859 result->unexpected_seq_number = true1;
5860 result->expected_sequence_number = state->next_expected_sequence_number[direction];
5861 result->previous_frame = state->last_frame[direction];
5862 wmem_tree_insert32(flow_results_table, pinfo->num, result);
5863 }
5864 /* Update conversation info */
5865 state->last_frame[direction] = pinfo->num;
5866 state->last_frame_seen[direction] = true1;
5867 state->next_expected_sequence_number[direction] = (seq_id+1) % 256;
5868 }
5869
5870 /* Show any issues associated with this frame number */
5871 flow_result_t *result = wmem_tree_lookup32(flow_results_table, pinfo->num);
5872 if (result!=NULL((void*)0) && result->unexpected_seq_number) {
5873 expert_add_info_format(pinfo, seq_id_ti,
5874 (direction == DIR_UPLINK0) ?
5875 &ei_oran_cplane_unexpected_sequence_number_ul :
5876 &ei_oran_cplane_unexpected_sequence_number_dl,
5877 "Sequence number %u expected, but got %u",
5878 result->expected_sequence_number, seq_id);
5879
5880 /* Update tap info */
5881 uint32_t missing_sns = (256 + seq_id - result->expected_sequence_number) % 256;
5882 /* Don't get confused by being slightly out of order.. */
5883 if (missing_sns < 128) {
5884 tap_info->missing_sns = missing_sns;
5885 }
5886 else {
5887 tap_info->missing_sns = 0;
5888 }
5889
5890 /* TODO: could add previous/next frames (in seqId tree?) ? */
5891 }
5892
5893 /* payloadVersion */
5894 dissect_payload_version(section_tree, tvb, pinfo, offset);
5895
5896 /* filterIndex */
5897 if (sectionType == SEC_C_SLOT_CONTROL || sectionType == SEC_C_ACK_NACK_FEEDBACK) {
5898 /* scs (for ST4 and ST8) */
5899 scs_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_frameStructure_subcarrier_spacing, tvb, offset, 1, ENC_NA0x00000000, &scs);
5900 }
5901 else if (sectionType == SEC_C_RRM_MEAS_REPORTS || sectionType == SEC_C_REQUEST_RRM_MEAS) {
5902 /* reserved (4 bits) */
5903 add_reserved_field(section_tree, hf_oran_reserved_last_4bits, tvb, offset, 1);
5904 }
5905 else if (sectionType != SEC_C_LAA) {
5906 /* filterIndex (most common case) */
5907 proto_tree_add_item(section_tree, hf_oran_filter_index, tvb, offset, 1, ENC_NA0x00000000);
5908 }
5909 offset += 1;
5910
5911 unsigned ref_a_offset = offset;
5912 /* frameId */
5913 uint32_t frameId = 0;
5914 proto_tree_add_item_ret_uint(section_tree, hf_oran_frame_id, tvb, offset, 1, ENC_NA0x00000000, &frameId);
5915 tap_info->frame = frameId;
5916 offset += 1;
5917
5918 /* subframeId */
5919 uint32_t subframeId = 0;
5920 proto_tree_add_item_ret_uint(section_tree, hf_oran_subframe_id, tvb, offset, 1, ENC_NA0x00000000, &subframeId);
5921 /* slotId */
5922 uint32_t slotId = 0;
5923 proto_tree_add_item_ret_uint(section_tree, hf_oran_slot_id, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &slotId);
5924 tap_info->slot = slotId;
5925 offset++;
5926
5927 /* startSymbolId */
5928 uint32_t startSymbolId = 0;
5929 proto_item *ssid_ti = NULL((void*)0);
5930 if ((sectionType == SEC_C_ACK_NACK_FEEDBACK) || /* Section Type 8 */
5931 (sectionType == SEC_C_SINR_REPORTING)) { /* Section Type 9 */
5932 /* symbolId */
5933 proto_tree_add_item_ret_uint(section_tree, hf_oran_symbolId, tvb, offset, 1, ENC_NA0x00000000, &startSymbolId);
5934 }
5935 else if (sectionType != SEC_C_LAA) {
5936 /* startSymbolId is in most section types */
5937 ssid_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_start_symbol_id, tvb, offset, 1, ENC_NA0x00000000, &startSymbolId);
5938 if (startSymbolId && (sectionType == SEC_C_RRM_MEAS_REPORTS)) { /* Section Type 10 */
5939 proto_item_append_text(ssid_ti, " (should be 0 for ST10!)");
5940 expert_add_info_format(pinfo, ssid_ti, &ei_oran_st10_startsymbolid_not_0,
5941 "startSymbolId should be 0 for ST10 - found %u", startSymbolId);
5942 }
5943 }
5944 else {
5945 /* reserved (6 bits) */
5946 add_reserved_field(section_tree, hf_oran_reserved_last_6bits, tvb, offset, 1);
5947 }
5948 offset++;
5949
5950
5951 char id[16];
5952 snprintf(id, 16, "%u-%u-%u-%u", frameId, subframeId, slotId, startSymbolId);
5953 proto_item *pi = proto_tree_add_string(section_tree, hf_oran_refa, tvb, ref_a_offset, 3, id);
5954 proto_item_set_generated(pi);
5955
5956 uint32_t cmd_scope = 0;
5957 bool_Bool st8_ready = false0;
5958
5959 /* numberOfSections (or whatever section has instead) */
5960 uint32_t nSections = 0;
5961 if (sectionType == SEC_C_SLOT_CONTROL) { /* Section Type 4 */
5962 /* Slot Control has these fields instead */
5963 /* reserved (4 bits) */
5964 add_reserved_field(section_tree, hf_oran_reserved_4bits, tvb, offset, 1);
5965 /* cmdScope (4 bits) */
5966 proto_tree_add_item_ret_uint(section_tree, hf_oran_cmd_scope, tvb, offset, 1, ENC_NA0x00000000, &cmd_scope);
5967 }
5968 else if (sectionType == SEC_C_ACK_NACK_FEEDBACK) { /* Section Type 8 */
5969 /* reserved (7 bits) */
5970 add_reserved_field(section_tree, hf_oran_reserved_7bits, tvb, offset, 1);
5971 /* ready (1 bit) */
5972 /* TODO: when set, ready in slotId+1.. */
5973 proto_tree_add_item_ret_boolean(section_tree, hf_oran_ready, tvb, offset, 1, ENC_NA0x00000000, &st8_ready);
5974 if (!st8_ready) {
5975 /* SCS value is ignored, and may be set to any value by O-RU */
5976 proto_item_append_text(scs_ti, " (ignored)");
5977 }
5978 }
5979 else if (sectionType != SEC_C_LAA) {
5980 /* numberOfSections */
5981 proto_tree_add_item_ret_uint(section_tree, hf_oran_numberOfSections, tvb, offset, 1, ENC_NA0x00000000, &nSections);
5982 }
5983 else {
5984 add_reserved_field(section_tree, hf_oran_reserved_8bits, tvb, offset, 1);
5985 }
5986 offset++;
5987
5988 /* sectionType */
5989 proto_tree_add_item_ret_uint(section_tree, hf_oran_sectionType, tvb, offset, 1, ENC_NA0x00000000, &sectionType);
5990 offset += 1;
5991
5992 /* Check that dataDirection is consistent with section type */
5993 if (sectionType == SEC_C_SINR_REPORTING && direction != 0) { /* Section Type 9 */
5994 expert_add_info(pinfo, datadir_ti, &ei_oran_st9_not_ul);
5995 }
5996 if (sectionType == SEC_C_RRM_MEAS_REPORTS && direction != 0) { /* Section Type 10 */
5997 expert_add_info(pinfo, datadir_ti, &ei_oran_st10_not_ul);
5998 }
5999
6000 /* Note this section type in stats */
6001 if (sectionType < SEC_C_MAX_INDEX) {
6002 tap_info->section_types[sectionType] = true1;
6003 }
6004
6005 /* Section-type-specific fields following common header (white entries in Section Type diagrams) */
6006 unsigned bit_width = 0;
6007 unsigned comp_meth = 0;
6008 proto_item *comp_meth_ti;
6009 unsigned ci_comp_method = 0;
6010 uint8_t ci_comp_opt = 0;
6011
6012 uint32_t num_ues = 0;
6013 uint32_t number_of_acks = 0, number_of_nacks = 0;
6014
6015 uint32_t num_sinr_per_prb = 0;
6016
6017 switch (sectionType) {
6018 case SEC_C_UNUSED_RB: /* Section Type 0 */
6019 /* timeOffset */
6020 proto_tree_add_item(section_tree, hf_oran_timeOffset, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6021 offset += 2;
6022 /* frameStructure */
6023 offset = dissect_frame_structure(section_tree, tvb, offset,
6024 subframeId, slotId);
6025
6026 /* cpLength */
6027 proto_tree_add_item(section_tree, hf_oran_cpLength, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6028 offset += 2;
6029 /* reserved (8 bits) */
6030 add_reserved_field(section_tree, hf_oran_reserved_8bits, tvb, offset, 1);
6031 offset += 1;
6032 break;
6033
6034 case SEC_C_NORMAL: /* Section Type 1 */
6035 case SEC_C_UE_SCHED: /* Section Type 5 */
6036 /* udCompHdr */
6037 offset = dissect_udcomphdr(tvb, pinfo, section_tree, offset,
6038 true1, direction==0 && pref_override_ul_compression, /* ignore for DL or if using mplane for UL settings */
6039 &bit_width, &comp_meth, &comp_meth_ti, tap_info);
6040 /* reserved (8 bits) */
6041 add_reserved_field(section_tree, hf_oran_reserved_8bits, tvb, offset, 1);
6042 offset += 1;
6043 break;
6044
6045 case SEC_C_SLOT_CONTROL: /* Section Type 4 */
6046 break;
6047
6048 case SEC_C_PRACH: /* Section Type 3 */
6049 /* timeOffset */
6050 proto_tree_add_item(section_tree, hf_oran_timeOffset, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6051 offset += 2;
6052 /* frameStructure */
6053 offset = dissect_frame_structure(section_tree, tvb, offset,
6054 subframeId, slotId);
6055 /* cpLength */
6056 proto_tree_add_item(section_tree, hf_oran_cpLength, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6057 offset += 2;
6058 /* udCompHdr */
6059 offset = dissect_udcomphdr(tvb, pinfo, section_tree, offset,
6060 true1, direction==0 && pref_override_ul_compression, /* ignore for DL or if using mplane for UL settings */
6061 &bit_width, &comp_meth, &comp_meth_ti, tap_info);
6062 break;
6063
6064 case SEC_C_CH_INFO: /* Section Type 6 */
6065 /* numberOfUEs */
6066 proto_tree_add_item_ret_uint(section_tree, hf_oran_numberOfUEs, tvb, offset, 1, ENC_NA0x00000000, &num_ues);
6067 offset += 1;
6068 /* ciCompHdr (was reserved) */
6069 offset = dissect_cicomphdr(tvb, pinfo, section_tree, offset, &bit_width, &ci_comp_method, &ci_comp_opt);
6070
6071 /* Number of sections may not be filled in (at all, or correctly), so set to the number of UEs.
6072 The data entries are per-UE... they don't have a sectionID, but they could have section extensions... */
6073 if (nSections == 0 || num_ues > nSections) {
6074 nSections = num_ues;
6075 }
6076 break;
6077
6078 case SEC_C_RSVD2:
6079 break;
6080
6081 case SEC_C_LAA: /* Section Type 7 */
6082 add_reserved_field(section_tree, hf_oran_reserved_16bits, tvb, offset, 2);
6083 offset += 2;
6084 break;
6085
6086 case SEC_C_ACK_NACK_FEEDBACK: /* Section Type 8 */
6087 /* numberOfAcks (1 byte) */
6088 proto_tree_add_item_ret_uint(section_tree, hf_oran_number_of_acks, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &number_of_acks);
6089 offset += 1;
6090 /* numberOfNacks (1 byte) */
6091 proto_tree_add_item_ret_uint(section_tree, hf_oran_number_of_nacks, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &number_of_nacks);
6092 offset += 1;
6093
6094 /* Show ACKs and NACKs. For both, try to link back to request. */
6095 for (unsigned int n=1; n <= number_of_acks; n++) {
6096 uint32_t ackid;
6097 proto_item *ack_ti;
6098 ack_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_ackid, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &ackid);
6099 offset += 2;
6100
6101 /* Look up request table in state (which really should be set by now, but test anyway). */
6102 if (state && state->ack_nack_requests) {
6103 ack_nack_request_t *request = wmem_tree_lookup32(state->ack_nack_requests, ackid);
6104 if (request != NULL((void*)0)) {
6105 /* On first pass, update with this response */
6106 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
6107 request->response_frame_number = pinfo->num;
6108 request->response_frame_time = pinfo->abs_ts;
6109 }
6110
6111 /* Show request details */
6112 show_link_to_acknack_request(section_tree, tvb, pinfo, request);
6113 }
6114 else {
6115 /* Request not found */
6116 expert_add_info_format(pinfo, ack_ti, &ei_oran_acknack_no_request,
6117 "Response for ackId=%u received, but no request found",
6118 ackid);
6119 }
6120 }
6121 }
6122 for (unsigned int m=1; m <= number_of_nacks; m++) {
6123 uint32_t nackid;
6124 proto_item *nack_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_nackid, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &nackid);
6125 offset += 2;
6126
6127 expert_add_info_format(pinfo, nack_ti, &ei_oran_st8_nackid,
6128 "Received Nack for ackNackId=%u",
6129 nackid);
6130
6131 /* Look up request table in state. */
6132 if (state && state->ack_nack_requests) {
6133 ack_nack_request_t *request = wmem_tree_lookup32(state->ack_nack_requests, nackid);
6134 if (request) {
6135 /* On first pass, update with this response */
6136 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
6137 request->response_frame_number = pinfo->num;
6138 request->response_frame_time = pinfo->abs_ts;
6139 }
6140
6141 /* Show request details */
6142 show_link_to_acknack_request(section_tree, tvb, pinfo, request);
6143 }
6144 else {
6145 /* Request not found */
6146 expert_add_info_format(pinfo, nack_ti, &ei_oran_acknack_no_request,
6147 "Response for nackId=%u received, but no request found",
6148 nackid);
6149 }
6150 }
6151 }
6152 break;
6153
6154 case SEC_C_SINR_REPORTING: /* Section Type 9 */
6155 {
6156 /* numSinrPerPrb (3 bits) */
6157 proto_item *nspp_ti;
6158 nspp_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_num_sinr_per_prb, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &num_sinr_per_prb);
6159 switch (num_sinr_per_prb) {
6160 case 0:
6161 num_sinr_per_prb = 1; break;
6162 case 1:
6163 num_sinr_per_prb = 2; break;
6164 case 2:
6165 num_sinr_per_prb = 3; break;
6166 case 3:
6167 num_sinr_per_prb = 4; break;
6168 case 4:
6169 num_sinr_per_prb = 6; break;
6170 case 5:
6171 num_sinr_per_prb = 12; break;
6172
6173 default:
6174 proto_item_append_text(nspp_ti, " (invalid)");
6175 num_sinr_per_prb = 1;
6176 expert_add_info_format(pinfo, nspp_ti, &ei_oran_num_sinr_per_prb_unknown,
6177 "Invalid numSinrPerPrb value (%u)",
6178 num_sinr_per_prb);
6179 }
6180
6181 /* oruControlSinrSlotMaskId (5 bits) */
6182 proto_tree_add_item(section_tree, hf_oran_oru_control_sinr_slot_mask_id, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6183 offset += 1;
6184 /* reserved (8 bits) */
6185 add_reserved_field(section_tree, hf_oran_reserved_8bits, tvb, offset, 1);
6186 offset += 1;
6187 break;
6188 }
6189
6190 case SEC_C_RRM_MEAS_REPORTS: /* Section Type 10 */
6191 case SEC_C_REQUEST_RRM_MEAS: /* Section Type 11 */
6192 /* reserved (16 bits) */
6193 add_reserved_field(section_tree, hf_oran_reserved_16bits, tvb, offset, 2);
6194 offset += 2;
6195 break;
6196 };
6197
6198 /* Update udCompHdr details in state for UL U-Plane */
6199 if (state && direction==0) {
6200 switch (sectionType) {
6201 case SEC_C_NORMAL: /* Section Type 1 */
6202 case SEC_C_PRACH: /* Section Type 3 */
6203 case SEC_C_UE_SCHED: /* Section Type 5 */
6204 state->ul_ud_comp_hdr_set = true1;
6205 state->ul_ud_comp_hdr_bit_width = bit_width;
6206 state->ul_ud_comp_hdr_compression = comp_meth;
6207 state->ul_ud_comp_hdr_frame = pinfo->num;
6208 break;
6209 default:
6210 break;
6211 }
6212 }
6213
6214
6215 proto_item_append_text(sectionHeading, "%d, %s, frameId: %d, subframeId: %d, slotId: %d, startSymbolId: %d",
6216 sectionType, val_to_str_const(direction, data_direction_vals, "Unknown"),
6217 frameId, subframeId, slotId, startSymbolId);
6218 if (nSections) {
6219 proto_item_append_text(sectionHeading, ", numberOfSections=%u", nSections);
6220 }
6221
6222 write_pdu_label_and_info(protocol_item, NULL((void*)0), pinfo, ", Type: %2d %s", sectionType,
6223 rval_to_str_const(sectionType, section_types_short, "Unknown"));
6224
6225 /* Set actual length of C-Plane section header */
6226 proto_item_set_len(section_tree, offset - section_tree_offset);
6227
6228 if (sectionType == SEC_C_ACK_NACK_FEEDBACK) {
6229 write_pdu_label_and_info(oran_tree, section_tree, pinfo,
6230 (st8_ready) ? " (Ready)" : " (ACK)");
6231 }
6232
6233
6234 /* Section type 4 doesn't have normal sections, so deal with here before normal sections */
6235 if (sectionType == SEC_C_SLOT_CONTROL) {
6236 /* numberOfST4Cmds */
6237 uint32_t no_st4_cmds, st4_cmd_len, num_slots, ack_nack_req_id, st4_cmd_type;
6238 proto_item *no_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_number_of_st4_cmds,
6239 tvb, offset, 1, ENC_NA0x00000000, &no_st4_cmds);
6240 if (no_st4_cmds == 0) {
6241 expert_add_info(pinfo, no_ti, &ei_oran_st4_no_cmds);
6242 }
6243 offset += 1;
6244
6245 /* reserved (1 byte) */
6246 add_reserved_field(section_tree, hf_oran_reserved_8bits, tvb, offset, 1);
6247 offset += 1;
6248
6249 /* Loop over commands. Each has 8-byte common header, followed by cmd-specific payload */
6250 proto_item *len_ti;
6251 for (uint32_t n=0; n < no_st4_cmds; n++) {
6252 /* Table 7.4.6-2: Section Type 4 Command common header format */
6253 proto_item *hdr_ti = proto_tree_add_string_format(section_tree, hf_oran_st4_cmd_header,
6254 tvb, offset, 8, "",
6255 "Type 4 Command common header");
6256 proto_tree *hdr_tree = proto_item_add_subtree(hdr_ti, ett_oran_st4_cmd_header);
6257
6258 /* st4CmdType */
6259 proto_tree_add_item_ret_uint(hdr_tree, hf_oran_st4_cmd_type, tvb, offset, 1, ENC_NA0x00000000, &st4_cmd_type);
6260 offset += 1;
6261
6262 /* st4CmdLen */
6263 len_ti = proto_tree_add_item_ret_uint(hdr_tree, hf_oran_st4_cmd_len, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &st4_cmd_len);
6264 if (st4_cmd_len == 0) {
6265 /* Meaning of 0 not yet defined (v15.00) */
6266 proto_item_append_text(len_ti, " (reserved)");
6267 expert_add_info(pinfo, len_ti, &ei_oran_st4_zero_len_cmd);
6268 }
6269 else {
6270 proto_item_append_text(len_ti, " (%u bytes)", st4_cmd_len*4);
6271 }
6272 offset += 2;
6273
6274 /* numSlots */
6275 proto_item *slots_ti = proto_tree_add_item_ret_uint(hdr_tree, hf_oran_st4_cmd_num_slots, tvb, offset, 1, ENC_NA0x00000000, &num_slots);
6276 if (num_slots == 0) {
6277 proto_item_append_text(slots_ti, " (until changed)");
6278 }
6279 offset += 1;
6280
6281 /* ackNackReqId */
6282 proto_item *ack_nack_req_id_ti;
6283 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_BIG_ENDIAN0x00000000, &ack_nack_req_id);
6284 offset += 2;
6285 if (ack_nack_req_id == 0) {
6286 proto_item_append_text(ack_nack_req_id_ti, " (no Section type 8 response expected)");
6287 }
6288
6289 /* reserved (16 bits) */
6290 add_reserved_field(hdr_tree, hf_oran_reserved_16bits, tvb, offset, 2);
6291 offset += 2;
6292
6293 /* Set common header summary */
6294 proto_item_append_text(hdr_ti, " (cmd=%s, len=%u, slots=%u, ackNackReqId=%u)",
6295 rval_to_str_const(st4_cmd_type, st4_cmd_type_vals, "Unknown"),
6296 st4_cmd_len, num_slots, ack_nack_req_id);
6297
6298 col_append_fstr(pinfo->cinfo, COL_INFO, " (%s)",
6299 rval_to_str_const(st4_cmd_type, st4_cmd_type_vals, "Unknown"));
6300
6301
6302 /* Subtree for this command body */
6303 proto_item *command_ti = proto_tree_add_string_format(section_tree, hf_oran_st4_cmd,
6304 tvb, offset, 0, "",
6305 "Type 4 Command (%s)", rval_to_str_const(st4_cmd_type, st4_cmd_type_vals, "Unknown"));
6306 proto_tree *command_tree = proto_item_add_subtree(command_ti, ett_oran_st4_cmd);
6307
6308 unsigned command_start_offset = offset;
6309
6310 /* Check fields compatible with chosen command. */
6311 if (st4_cmd_type==1) {
6312 if (num_slots != 0) {
6313 /* "the value of numSlots should be set to zero for this command type" */
6314 expert_add_info_format(pinfo, slots_ti, &ei_oran_numslots_not_zero,
6315 "numSlots should be zero for ST4 command 1 - found %u",
6316 num_slots);
6317 }
6318 }
6319
6320 if (st4_cmd_type==3 || st4_cmd_type==4) {
6321 if (startSymbolId != 0) {
6322 /* "expected reception window for the commands is the symbol zero reception window" */
6323 expert_add_info_format(pinfo, ssid_ti, &ei_oran_start_symbol_id_not_zero,
6324 "startSymbolId should be zero for ST4 commands 3&4 - found %u",
6325 startSymbolId);
6326 }
6327 }
6328
6329 /* Add format for this command */
6330 switch (st4_cmd_type) {
6331 case 1: /* TIME_DOMAIN_BEAM_CONFIG */
6332 {
6333 bool_Bool disable_tdbfns;
6334 uint32_t bfwcomphdr_iq_width, bfwcomphdr_comp_meth;
6335
6336 /* Hidden filter for bf */
6337 proto_item *bf_ti = proto_tree_add_item(command_tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
6338 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
6339
6340 /* reserved (2 bits) */
6341 add_reserved_field(command_tree, hf_oran_reserved_2bits, tvb, offset, 1);
6342 /* symbolMask (14 bits) */
6343 uint32_t symbol_mask;
6344 proto_item *symbol_mask_ti;
6345 offset = dissect_symbolmask(tvb, command_tree, offset, &symbol_mask, &symbol_mask_ti);
6346 /* 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 */
6347 /* lsb is symbol 0 */
6348 for (unsigned s=0; s < 14; s++) {
6349 if ((startSymbolId & (1 << s)) && (startSymbolId > s)) {
6350 proto_item_append_text(symbol_mask_ti, " (startSymbolId is %u, so some lower symbol bits ignored!)", startSymbolId);
6351 expert_add_info(pinfo, symbol_mask_ti, &ei_oran_start_symbol_id_bits_ignored);
6352 break;
6353 }
6354 }
6355
6356 /* disableTDBFNs (1 bit) */
6357 proto_tree_add_item_ret_boolean(command_tree, hf_oran_disable_tdbfns, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &disable_tdbfns);
6358
6359 /* tdBeamNum (15 bits) */
6360 proto_tree_add_item(command_tree, hf_oran_td_beam_num, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6361 offset += 2;
6362
6363 /* bfwCompHdr (2 subheaders - bfwIqWidth and bfwCompMeth)*/
6364 offset = dissect_bfwCompHdr(tvb, command_tree, offset,
6365 &bfwcomphdr_iq_width, &bfwcomphdr_comp_meth, &comp_meth_ti);
6366 /* reserved (3 bytes) */
6367 proto_tree_add_bits_item(command_tree, hf_oran_reserved, tvb, offset*8, 24, ENC_BIG_ENDIAN0x00000000);
6368 offset += 3;
6369
6370 if (disable_tdbfns) {
6371 /* No beamnum information to show so get out. */
6372 break;
6373 }
6374
6375 /* Read beam entries until reach end of command length */
6376 while ((offset - command_start_offset) < (st4_cmd_len * 4)) {
6377
6378 /* disableTDBFWs (1 bit) */
6379 bool_Bool disable_tdbfws;
6380 proto_tree_add_item_ret_boolean(command_tree, hf_oran_disable_tdbfws, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &disable_tdbfws);
6381
6382 /* tdBeamNum (15 bits) */
6383 proto_tree_add_item(command_tree, hf_oran_td_beam_num, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6384 offset += 2;
6385
6386 /* Showing BFWs? */
6387 if (!disable_tdbfws) {
6388
6389 /* bfwCompParam */
6390 unsigned exponent = 0;
6391 bool_Bool supported = false0;
6392 unsigned num_trx_entries;
6393 uint16_t *trx_entries;
6394 offset = dissect_bfwCompParam(tvb, command_tree, pinfo, offset, comp_meth_ti,
6395 &bfwcomphdr_comp_meth, &exponent, &supported,
6396 &num_trx_entries, &trx_entries);
6397
6398 /* Antenna count from preference */
6399 unsigned num_trx = pref_num_bf_antennas;
6400 int bit_offset = offset*8;
6401
6402 for (unsigned trx=0; trx < num_trx; trx++) {
6403 /* Create antenna subtree */
6404 int bfw_offset = bit_offset / 8;
6405 proto_item *bfw_ti = proto_tree_add_string_format(command_tree, hf_oran_bfw,
6406 tvb, bfw_offset, 0, "", "TRX %3u: (", trx);
6407 proto_tree *bfw_tree = proto_item_add_subtree(bfw_ti, ett_oran_bfw);
6408
6409 /* I value */
6410 /* Get bits, and convert to float. */
6411 uint32_t bits = tvb_get_bits32(tvb, bit_offset, bfwcomphdr_iq_width, ENC_BIG_ENDIAN0x00000000);
6412 float value = decompress_value(bits, bfwcomphdr_comp_meth, bfwcomphdr_iq_width, exponent, NULL((void*)0) /* no ModCompr*/, 0 /* RE */);
6413 /* Add to tree. */
6414 proto_tree_add_float(bfw_tree, hf_oran_bfw_i, tvb, bit_offset/8,
6415 (bfwcomphdr_iq_width+7)/8, value);
6416 bit_offset += bfwcomphdr_iq_width;
6417 proto_item_append_text(bfw_ti, "I=%f ", value);
6418
6419 /* Leave a gap between I and Q values */
6420 proto_item_append_text(bfw_ti, " ");
6421
6422 /* Q value */
6423 /* Get bits, and convert to float. */
6424 bits = tvb_get_bits32(tvb, bit_offset, bfwcomphdr_iq_width, ENC_BIG_ENDIAN0x00000000);
6425 value = decompress_value(bits, bfwcomphdr_comp_meth, bfwcomphdr_iq_width, exponent, NULL((void*)0) /* no ModCompr*/, 0 /* RE */);
6426 /* Add to tree. */
6427 proto_tree_add_float(bfw_tree, hf_oran_bfw_q, tvb, bit_offset/8,
6428 (bfwcomphdr_iq_width+7)/8, value);
6429 bit_offset += bfwcomphdr_iq_width;
6430 proto_item_append_text(bfw_ti, "Q=%f", value);
6431
6432 proto_item_append_text(bfw_ti, ")");
6433 proto_item_set_len(bfw_ti, (bit_offset+7)/8 - bfw_offset);
6434 }
6435 /* Need to round to next byte */
6436 offset = (bit_offset+7)/8;
6437 }
6438 }
6439 break;
6440 }
6441 case 2: /* TDD_CONFIG_PATTERN */
6442 /* reserved (2 bits) */
6443 add_reserved_field(command_tree, hf_oran_reserved_2bits, tvb, offset, 1);
6444 /* dirPattern (14 bits) */
6445 proto_tree_add_item(command_tree, hf_oran_dir_pattern, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6446 offset += 2;
6447
6448 /* reserved (2 bits) */
6449 add_reserved_field(command_tree, hf_oran_reserved_2bits, tvb, offset, 1);
6450 /* guardPattern (14 bits) */
6451 proto_tree_add_item(command_tree, hf_oran_guard_pattern, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6452 offset += 2;
6453 break;
6454
6455 case 3: /* TRX_CONTROL */
6456 case 5: /* TRX_CONTROL_BIDIR */
6457 {
6458 /* Only allowed cmdScope is ARRAY-COMMAND */
6459 if (cmd_scope != 0) {
6460 expert_add_info(pinfo, command_tree, &ei_oran_trx_control_cmd_scope);
6461 }
6462
6463 /* reserved (2 bits) */
6464 add_reserved_field(command_tree, hf_oran_reserved_2bits, tvb, offset, 1);
6465 /* log2MaskBits (4 bits) */
6466 unsigned log2maskbits;
6467 proto_tree_add_item_ret_uint(command_tree, hf_oran_log2maskbits, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &log2maskbits);
6468 /* sleepMode (2 bits) */
6469 uint32_t sleep_mode;
6470 proto_tree_add_item_ret_uint(command_tree, hf_oran_sleepmode_trx, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &sleep_mode);
6471 offset += 1;
6472
6473 /* reserved (4 bits) */
6474 add_reserved_field(command_tree, hf_oran_reserved_4bits, tvb, offset, 1);
6475 /* numSlotsExt (20 bits) */
6476 uint32_t num_slots_ext;
6477 proto_item *num_slots_ext_ti = proto_tree_add_item_ret_uint(command_tree, hf_oran_num_slots_ext, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000, &num_slots_ext);
6478 if (num_slots==0 && num_slots_ext==0) {
6479 proto_item_append_text(num_slots_ext_ti, " (undefined sleep period)");
6480 }
6481 else {
6482 /* Time should be rounded up according to SCS */
6483 float total = (float)(num_slots + num_slots_ext);
6484 /* From table 7.5.2.13-3 */
6485 const float slot_length_by_scs[16] = { 1000, 500, 250, 125, 62.5, 31.25,
6486 0, 0, 0, 0, 0, 0, /* reserved */
6487 1000, 1000, 1000, 1000 };
6488 float slot_length = slot_length_by_scs[scs];
6489 /* Only using valid SCS. TODO: is this test ok? */
6490 if (slot_length != 0) {
6491 /* Round up to next slot */
6492 total = ((int)(total / slot_length) + 1) * slot_length;
6493 proto_item_append_text(num_slots_ext_ti, " (defined sleep period of %f us)", total);
6494 }
6495 }
6496 offset += 3;
6497
6498 /* reserved (2 bits) */
6499 add_reserved_field(command_tree, hf_oran_reserved_2bits, tvb, offset, 1);
6500
6501 /* symbolMask (14 bits) */
6502 uint32_t symbol_mask;
6503 proto_item *sm_ti;
6504 offset = dissect_symbolmask(tvb, command_tree, offset, &symbol_mask, &sm_ti);
6505 if (symbol_mask == 0x0) {
6506 proto_item_append_text(sm_ti, " (wake)");
6507 col_append_str(pinfo->cinfo, COL_INFO, " (wake)");
6508 }
6509 else if (symbol_mask == 0x3fff) {
6510 proto_item_append_text(sm_ti, " (sleep)");
6511 col_append_str(pinfo->cinfo, COL_INFO, " (sleep)");
6512 }
6513 else {
6514 expert_add_info_format(pinfo, sm_ti, &ei_oran_bad_symbolmask,
6515 "For non-zero sleepMode (%u), symbolMask should be 0x0 or 0x3fff - found 0x%05x",
6516 sleep_mode, symbol_mask);
6517 }
6518 offset += 2;
6519
6520 /* antMask (16-2048 bits). Size is lookup from log2MaskBits enum.. */
6521 unsigned antmask_length = 2;
6522 if (log2maskbits >= 4) {
6523 antmask_length = (1 << log2maskbits) / 8;
6524 }
6525 proto_item *ant_mask_ti = proto_tree_add_item(command_tree, hf_oran_antMask_trx_control, tvb, offset, antmask_length, ENC_NA0x00000000);
6526 /* show count */
6527 unsigned antenna_count = 0;
6528 for (unsigned b=0; b < antmask_length; b++) {
6529 uint8_t byte = tvb_get_uint8(tvb, offset+b);
6530 for (unsigned bit=0; bit < 8; bit++) {
6531 if ((1 << bit) & byte) {
6532 antenna_count++;
6533 }
6534 }
6535 }
6536 proto_item_append_text(ant_mask_ti, " (%u antennas)", antenna_count);
6537 offset += antmask_length;
6538
6539 /* Pad to next 4-byte boundary */
6540 offset = WS_ROUNDUP_4(offset)(((offset) + ((unsigned)(4U-1U))) & (~((unsigned)(4U-1U))
))
;
6541 break;
6542 }
6543
6544 case 4: /* ASM (advanced sleep mode) */
6545 /* reserved (2+4=6 bits) */
6546 add_reserved_field(command_tree, hf_oran_reserved_6bits, tvb, offset, 1);
6547 /* sleepMode (2 bits) */
6548 uint32_t sleep_mode;
6549 proto_tree_add_item_ret_uint(command_tree, hf_oran_sleepmode_asm, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &sleep_mode);
6550 offset += 1;
6551
6552 /* reserved (4 bits) */
6553 add_reserved_field(command_tree, hf_oran_reserved_4bits, tvb, offset, 1);
6554 /* numSlotsExt (20 bits) */
6555 proto_tree_add_item(command_tree, hf_oran_num_slots_ext, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6556 offset += 3;
6557
6558 /* reserved (2 bits) */
6559 add_reserved_field(command_tree, hf_oran_reserved_2bits, tvb, offset, 1);
6560 /* symbolMask (14 bits) */
6561 uint32_t symbol_mask;
6562 proto_item *sm_ti;
6563 offset = dissect_symbolmask(tvb, command_tree, offset, &symbol_mask, &sm_ti);
6564 if (symbol_mask == 0x0) {
6565 proto_item_append_text(sm_ti, " (wake)");
6566 col_append_str(pinfo->cinfo, COL_INFO, " (wake)");
6567 }
6568 else if (symbol_mask == 0x3fff) {
6569 proto_item_append_text(sm_ti, " (sleep)");
6570 col_append_str(pinfo->cinfo, COL_INFO, " (sleep)");
6571 }
6572 else {
6573 expert_add_info_format(pinfo, sm_ti, &ei_oran_bad_symbolmask,
6574 "For non-zero sleepMode (%u), symbolMask should be 0x0 or 0x3fff - found 0x%05x",
6575 sleep_mode, symbol_mask);
6576 }
6577 offset += 2;
6578
6579 /* reserved (2 bytes) */
6580 add_reserved_field(command_tree, hf_oran_reserved_16bits, tvb, offset, 2);
6581 offset += 2;
6582 break;
6583
6584 default:
6585 /* Error! */
6586 expert_add_info_format(pinfo, len_ti, &ei_oran_st4_unknown_cmd,
6587 "Dissected ST4 command (%u) not recognised",
6588 st4_cmd_type);
6589 break;
6590 }
6591
6592 /* Check apparent size of padding (0-3 bytes ok) */
6593 long padding_remaining = command_start_offset + (st4_cmd_len * 4) - offset;
6594 if (padding_remaining > 3) {
6595 expert_add_info_format(pinfo, len_ti, &ei_oran_st4_wrong_len_cmd,
6596 "Dissected ST4 command does not match signalled st4CmdLen - set to %u (%u bytes) but dissected %u bytes",
6597 st4_cmd_len, st4_cmd_len*4, offset-command_start_offset);
6598 }
6599
6600 /* Advance by signalled length (needs to be aligned on 4-byte boundary) */
6601 offset = command_start_offset + (st4_cmd_len * 4);
6602
6603 /* Set end of command tree */
6604 proto_item_set_end(command_ti, tvb, offset);
6605
6606 if (ack_nack_req_id != 0 && state && state->ack_nack_requests) {
6607 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
6608 /* Add this request into conversation state on first pass */
6609 ack_nack_request_t *request_details = wmem_new0(wmem_file_scope(), ack_nack_request_t)((ack_nack_request_t*)wmem_alloc0((wmem_file_scope()), sizeof
(ack_nack_request_t)))
;
6610 request_details->request_frame_number = pinfo->num;
6611 request_details->request_frame_time = pinfo->abs_ts;
6612 request_details->requestType = ST4Cmd1+st4_cmd_type-1;
6613
6614 wmem_tree_insert32(state->ack_nack_requests,
6615 ack_nack_req_id,
6616 request_details);
6617 }
6618 else {
6619 /* On later passes, try to link forward to ST8 response */
6620 ack_nack_request_t *response = wmem_tree_lookup32(state->ack_nack_requests,
6621 ack_nack_req_id);
6622 if (response) {
6623 show_link_to_acknack_response(section_tree, tvb, pinfo, response);
6624 }
6625 }
6626 }
6627 }
6628 }
6629 /* LAA doesn't have sections either.. */
6630 else if (sectionType == SEC_C_LAA) { /* Section Type 7 */
6631 /* 7.2.5 Table 6.4-6 */
6632 unsigned mcot;
6633 proto_item *mcot_ti;
6634
6635 /* laaMsgType */
6636 uint32_t laa_msg_type;
6637 proto_item *laa_msg_type_ti;
6638 laa_msg_type_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_laaMsgType, tvb, offset, 1, ENC_NA0x00000000, &laa_msg_type);
6639 /* laaMsgLen */
6640 uint32_t laa_msg_len;
6641 proto_item *len_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_laaMsgLen, tvb, offset, 1, ENC_NA0x00000000, &laa_msg_len);
6642 proto_item_append_text(len_ti, " (%u bytes)", 4*laa_msg_len);
6643 if (laa_msg_len == 0) {
6644 proto_item_append_text(len_ti, " (reserved)");
6645 }
6646 offset += 1;
6647
6648 int payload_offset = offset;
6649
6650 /* Payload */
6651 switch (laa_msg_type) {
6652 case 0:
6653 /* LBT_PDSCH_REQ */
6654 /* lbtHandle (16 bits) */
6655 proto_tree_add_item(section_tree, hf_oran_lbtHandle, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6656 offset += 2;
6657 /* lbtOffset (10 bits) */
6658 proto_tree_add_item(section_tree, hf_oran_lbtOffset, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6659 offset += 1;
6660 /* lbtMode (2 bits) */
6661 proto_tree_add_bits_item(section_tree, hf_oran_lbtMode, tvb, offset*8+2, 2, ENC_BIG_ENDIAN0x00000000);
6662 /* reserved (1 bit) */
6663 add_reserved_field(section_tree, hf_oran_reserved_bit4, tvb, offset, 1);
6664 /* lbtDeferFactor (3 bits) */
6665 proto_tree_add_item(section_tree, hf_oran_lbtDeferFactor, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6666 offset += 1;
6667 /* lbtBackoffCounter (10 bits) */
6668 proto_tree_add_item(section_tree, hf_oran_lbtBackoffCounter, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6669 offset += 1;
6670 /* MCOT (4 bits) */
6671 mcot_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_MCOT, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &mcot);
6672 if (mcot<1 || mcot>10) {
6673 proto_item_append_text(mcot_ti, " (should be in range 1-10!)");
6674 expert_add_info_format(pinfo, mcot_ti, &ei_oran_mcot_out_of_range,
6675 "MCOT seen with value %u (must be 1-10)", mcot);
6676
6677 }
6678 /* reserved (10 bits) */
6679 proto_tree_add_bits_item(section_tree, hf_oran_reserved, tvb, (offset*8)+6, 10, ENC_BIG_ENDIAN0x00000000);
6680 break;
6681 case 1:
6682 /* LBT_DRS_REQ */
6683 /* lbtHandle (16 bits) */
6684 proto_tree_add_item(section_tree, hf_oran_lbtHandle, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6685 offset += 2;
6686 /* lbtOffset (10 bits) */
6687 proto_tree_add_item(section_tree, hf_oran_lbtOffset, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6688 offset += 1;
6689 /* lbtMode (2 bits) */
6690 proto_tree_add_bits_item(section_tree, hf_oran_lbtMode, tvb, offset*8+2, 2, ENC_BIG_ENDIAN0x00000000);
6691 /* reserved (28 bits) */
6692 proto_tree_add_bits_item(section_tree, hf_oran_reserved, tvb, (offset*8)+4, 28, ENC_BIG_ENDIAN0x00000000);
6693 break;
6694 case 2:
6695 /* LBT_PDSCH_RSP */
6696 /* lbtHandle (16 bits) */
6697 proto_tree_add_item(section_tree, hf_oran_lbtHandle, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6698 offset += 2;
6699 /* lbtPdschRes (2 bits) */
6700 proto_tree_add_item(section_tree, hf_oran_lbtPdschRes, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6701 /* inParSF (1 bit) */
6702 proto_tree_add_item(section_tree, hf_oran_initialPartialSF, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6703 /* sfStatus (1 bit) */
6704 proto_tree_add_item(section_tree, hf_oran_sfStatus, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6705 /* sfnSf (12 bits) */
6706 proto_tree_add_item(section_tree, hf_oran_sfnSfEnd, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6707 offset += 2;
6708 /* reserved (24 bits) */
6709 proto_tree_add_bits_item(section_tree, hf_oran_reserved, tvb, (offset*8), 24, ENC_BIG_ENDIAN0x00000000);
6710 break;
6711 case 3:
6712 /* LBT_DRS_RSP */
6713 /* lbtHandle (16 bits) */
6714 proto_tree_add_item(section_tree, hf_oran_lbtHandle, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6715 offset += 2;
6716 /* lbtDrsRes (1 bit) */
6717 proto_tree_add_item(section_tree, hf_oran_lbtDrsRes, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6718 /* reserved (7 bits) */
6719 add_reserved_field(section_tree, hf_oran_reserved_last_7bits, tvb, offset, 1);
6720 break;
6721 case 4:
6722 /* LBT_Buffer_Error */
6723 /* lbtHandle (16 bits) */
6724 proto_tree_add_item(section_tree, hf_oran_lbtHandle, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6725 offset += 2;
6726 /* lbtBufErr (1 bit) */
6727 proto_tree_add_item(section_tree, hf_oran_lbtBufErr, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6728 /* reserved (7 bits) */
6729 add_reserved_field(section_tree, hf_oran_reserved_last_7bits, tvb, offset, 1);
6730 break;
6731 case 5:
6732 /* LBT_CWCONFIG_REQ */
6733 /* lbtHandle (16 bits) */
6734 proto_tree_add_item(section_tree, hf_oran_lbtHandle, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6735 offset += 2;
6736 /* lbtCWConfig_H (8 bits) */
6737 proto_tree_add_item(section_tree, hf_oran_lbtCWConfig_H, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6738 offset += 1;
6739 /* lbtCWConfig_T (8 bits) */
6740 proto_tree_add_item(section_tree, hf_oran_lbtCWConfig_T, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6741 offset += 1;
6742 /* lbtMode (2 bits) */
6743 proto_tree_add_bits_item(section_tree, hf_oran_lbtMode, tvb, offset*8, 2, ENC_BIG_ENDIAN0x00000000);
6744 /* lbtTrafficClass (3 bits) */
6745 proto_tree_add_item(section_tree, hf_oran_lbtTrafficClass, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6746 /* reserved (19 bits) */
6747 proto_tree_add_bits_item(section_tree, hf_oran_reserved, tvb, (offset*8)+5, 19, ENC_BIG_ENDIAN0x00000000);
6748 break;
6749 case 6:
6750 /* LBT_CWCONFIG_RSP */
6751 /* lbtHandle (16 bits) */
6752 proto_tree_add_item(section_tree, hf_oran_lbtHandle, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6753 offset += 2;
6754 /* lbtCWR_Rst (1 bit) */
6755 proto_tree_add_item(section_tree, hf_oran_lbtCWR_Rst, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6756 /* reserved (7 bits) */
6757 add_reserved_field(section_tree, hf_oran_reserved_last_7bits, tvb, offset, 1);
6758 break;
6759
6760 default:
6761 /* Unhandled! */
6762 expert_add_info_format(pinfo, laa_msg_type_ti, &ei_oran_laa_msg_type_unsupported,
6763 "laaMsgType %u not supported by dissector",
6764 laa_msg_type);
6765
6766 break;
6767 }
6768 /* For now just skip indicated length of bytes */
6769 offset = payload_offset + 4*(laa_msg_len+1);
6770 }
6771
6772
6773 /* Dissect each C section */
6774 for (uint32_t i = 0; i < nSections; ++i) {
6775 tvbuff_t *section_tvb = tvb_new_subset_remaining(tvb, offset);
6776 offset += dissect_oran_c_section(section_tvb, oran_tree, pinfo, state, sectionType, tap_info,
6777 protocol_item,
6778 subframeId, frameId, slotId, startSymbolId,
6779 bit_width, ci_comp_method, ci_comp_opt,
6780 num_sinr_per_prb);
6781 }
6782
6783 /* Expert error if we are short of tvb by > 3 bytes */
6784 if (tvb_reported_length_remaining(tvb, offset) > 3) {
6785 expert_add_info_format(pinfo, protocol_item, &ei_oran_frame_length,
6786 "%u bytes remain at end of frame - should be 0-3",
6787 tvb_reported_length_remaining(tvb, offset));
6788 }
6789
6790 return tvb_captured_length(tvb);
6791}
6792
6793static int dissect_oran_u_re(tvbuff_t *tvb, proto_tree *tree,
6794 unsigned sample_number, int samples_offset,
6795 oran_tap_info *tap_info,
6796 unsigned sample_bit_width,
6797 int comp_meth,
6798 uint32_t exponent,
6799 section_mod_compr_config_t *mod_compr_params,
6800 uint8_t re)
6801{
6802 /* I */
6803 unsigned i_bits = tvb_get_bits32(tvb, samples_offset, sample_bit_width, ENC_BIG_ENDIAN0x00000000);
6804 float i_value = decompress_value(i_bits, comp_meth, sample_bit_width, exponent, mod_compr_params, re);
6805 unsigned sample_len_in_bytes = ((samples_offset%8)+sample_bit_width+7)/8;
6806 proto_item *i_ti = proto_tree_add_float(tree, hf_oran_iSample, tvb, samples_offset/8, sample_len_in_bytes, i_value);
6807 proto_item_set_text(i_ti, "iSample: % 0.7f 0x%04x (RE-%2u in the PRB)", i_value, i_bits, sample_number);
6808 samples_offset += sample_bit_width;
6809 /* Q */
6810 unsigned q_bits = tvb_get_bits32(tvb, samples_offset, sample_bit_width, ENC_BIG_ENDIAN0x00000000);
6811 float q_value = decompress_value(q_bits, comp_meth, sample_bit_width, exponent, mod_compr_params, re);
6812 sample_len_in_bytes = ((samples_offset%8)+sample_bit_width+7)/8;
6813 proto_item *q_ti = proto_tree_add_float(tree, hf_oran_qSample, tvb, samples_offset/8, sample_len_in_bytes, q_value);
6814 proto_item_set_text(q_ti, "qSample: % 0.7f 0x%04x (RE-%2u in the PRB)", q_value, q_bits, sample_number);
6815 samples_offset += sample_bit_width;
6816
6817 /* Update RE stats */
6818 tap_info->num_res++;
6819 /* if (i_value == 0.0 && q_value == 0.0) { */
6820 /* TODO: is just checking bits from frame good enough - assuming this always corresponds to a zero value? */
6821 if (i_bits == 0 && q_bits == 0) {
6822 tap_info->num_res_zero++;
6823 }
6824 else {
6825 tap_info->non_zero_re_in_current_prb = true1;
6826 }
6827 return samples_offset;
6828}
6829
6830
6831static bool_Bool udcomplen_appears_present(bool_Bool udcomphdr_present, tvbuff_t *tvb, int offset)
6832{
6833 if (!udcomplen_heuristic_result_set) {
6834 /* All sections will start the same way */
6835 unsigned int section_bytes_before_field = (udcomphdr_present) ? 6 : 4;
6836
6837 /* Move offset back to the start of the section */
6838 offset -= section_bytes_before_field;
6839
6840 do {
6841 /* This field appears several bytes into the U-plane section */
6842 uint32_t length_remaining = tvb_reported_length_remaining(tvb, offset);
6843 /* Are there enough bytes to still read the length field? */
6844 if (section_bytes_before_field+2 > length_remaining) {
6845 udcomplen_heuristic_result = false0;
6846 udcomplen_heuristic_result_set = true1;
6847 break;
6848 }
6849
6850 /* Read the length field */
6851 uint16_t udcomplen = tvb_get_ntohs(tvb, offset+section_bytes_before_field);
6852
6853 /* Is this less than a valid section? Realistic minimal section will be bigger than this..
6854 * Could take into account numPrbU, etc */
6855 if (udcomplen < section_bytes_before_field+2) {
6856 udcomplen_heuristic_result = false0;
6857 udcomplen_heuristic_result_set = true1;
6858 break;
6859 }
6860
6861 /* Does this section fit into the frame? */
6862 if (udcomplen > length_remaining) {
6863 udcomplen_heuristic_result = false0;
6864 udcomplen_heuristic_result_set = true1;
6865 break;
6866 }
6867
6868 /* Move past this section */
6869 offset += udcomplen;
6870
6871 /* Are we at the end of the frame? */
6872 /* TODO: if frame is less than 60 bytes, there may be > 4 bytes, likely zeros.. */
6873 if (tvb_reported_length_remaining(tvb, offset) < 4) {
6874 udcomplen_heuristic_result = true1;
6875 udcomplen_heuristic_result_set = true1;
6876 }
6877 } while (!udcomplen_heuristic_result_set);
6878 }
6879 return udcomplen_heuristic_result;
6880}
6881
6882static bool_Bool at_udcomphdr(tvbuff_t *tvb, int offset)
6883{
6884 if (tvb_captured_length_remaining(tvb, offset) < 2) {
6885 return false0;
6886 }
6887 uint8_t first_byte = tvb_get_uint8(tvb, offset);
6888 uint8_t reserved_byte = tvb_get_uint8(tvb, offset+1);
6889
6890 /* - iq width could be anything, though unlikely to be signalled as (say) < 1-3? */
6891 /* - meth should be 0-8 */
6892 /* - reserved byte should be 0 */
6893 return (((first_byte & 0x0f) <= MOD_COMPR_AND_SELECTIVE_RE_WITH_MASKS8) && (reserved_byte == 0));
6894}
6895
6896static bool_Bool udcomphdr_appears_present(flow_state_t *flow, uint32_t direction, tvbuff_t *tvb, int offset)
6897{
6898 /* Should really not happen, but guard against this anyway. */
6899 if (flow == NULL((void*)0)) {
6900 /* No state to update. */
6901 return false0;
6902 }
6903
6904 if (direction == DIR_UPLINK0) {
6905 if (flow->udcomphdrUplink_heuristic_result_set) {
6906 /* Return cached value */
6907 return flow->udcomphdrUplink_heuristic_result;
6908 }
6909 else {
6910 /* Work it out, and save answer for next time */
6911 flow->udcomphdrUplink_heuristic_result_set = true1;
6912 flow->udcomphdrUplink_heuristic_result = at_udcomphdr(tvb, offset);
6913 return flow->udcomphdrUplink_heuristic_result;
6914 }
6915 }
6916 else {
6917 /* Downlink */
6918 if (flow->udcomphdrDownlink_heuristic_result_set) {
6919 /* Return cached value */
6920 return flow->udcomphdrDownlink_heuristic_result;
6921 }
6922 else {
6923 /* Work it out, and save answer for next time */
6924 flow->udcomphdrDownlink_heuristic_result_set = true1;
6925 flow->udcomphdrDownlink_heuristic_result = at_udcomphdr(tvb, offset);
6926 return flow->udcomphdrDownlink_heuristic_result;
6927 }
6928 }
6929}
6930
6931bool_Bool copy_section_entry(const void *key, void* value, void *userdata)
6932{
6933 /* Cast parameters to their types */
6934 uint32_t sectionId = GPOINTER_TO_UINT(key)((guint) (gulong) (key));
6935 expected_section_data_t *result_value = (expected_section_data_t *)value;
6936 wmem_tree_t *result_tree = (wmem_tree_t*)userdata;
6937
6938 /* Deep copy of section data */
6939 expected_section_data_t *copy = wmem_new0(wmem_file_scope(), expected_section_data_t)((expected_section_data_t*)wmem_alloc0((wmem_file_scope()), sizeof
(expected_section_data_t)))
;
6940 *copy = *result_value;
6941
6942 /* Add into result tree */
6943 wmem_tree_insert32(result_tree, sectionId, copy);
6944
6945 return false0;
6946}
6947
6948/* User plane dissector (section 8) */
6949static int
6950dissect_oran_u(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
6951 oran_tap_info *tap_info, void *data _U___attribute__((unused)))
6952{
6953 /* Hidden filter for plane */
6954 proto_item *plane_ti = proto_tree_add_item(tree, hf_oran_uplane, tvb, 0, 0, ENC_NA0x00000000);
6955 PROTO_ITEM_SET_HIDDEN(plane_ti)proto_item_set_hidden((plane_ti));
6956
6957 /* Set up structures needed to add the protocol subtree and manage it */
6958 unsigned offset = 0;
6959
6960 col_set_str(pinfo->cinfo, COL_PROTOCOL, "O-RAN-FH-U");
6961 col_set_str(pinfo->cinfo, COL_INFO, "U-Plane");
6962
6963 tap_info->userplane = true1;
6964
6965 /* Create display subtree for the protocol */
6966 proto_item *protocol_item = proto_tree_add_item(tree, proto_oran, tvb, 0, -1, ENC_NA0x00000000);
6967 proto_item_append_text(protocol_item, "-U");
6968 proto_tree *oran_tree = proto_item_add_subtree(protocol_item, ett_oran);
6969
6970 /* Transport header */
6971 /* Real-time control data / IQ data transfer message series identifier */
6972 uint16_t eAxC;
6973 addPcOrRtcid(tvb, oran_tree, &offset, hf_oran_ecpri_pcid, &eAxC, tap_info);
6974 tap_info->eaxc = eAxC;
6975
6976 /* Update/report status of conversation */
6977 uint32_t key = make_flow_key(pinfo, eAxC, ORAN_U_PLANE1, false0);
6978 flow_state_t* state = (flow_state_t*)wmem_tree_lookup32(flow_states_table, key);
6979
6980 flow_result_t *result = NULL((void*)0);
6981
6982 /* Message identifier */
6983 proto_item *seqIdItem;
6984 uint32_t seqId, subSeqId, e;
6985 offset = addSeqid(tvb, oran_tree, offset, ORAN_U_PLANE1, &seqId, &seqIdItem, pinfo, &subSeqId, &e);
6986
6987 /* Common header for time reference */
6988 proto_item *timingHeader = proto_tree_add_string_format(oran_tree, hf_oran_timing_header,
6989 tvb, offset, 4, "", "Timing Header (");
6990 proto_tree *timing_header_tree = proto_item_add_subtree(timingHeader, ett_oran_u_timing);
6991
6992 /* dataDirection */
6993 uint32_t direction;
6994 proto_tree_add_item_ret_uint(timing_header_tree, hf_oran_data_direction, tvb, offset, 1, ENC_NA0x00000000, &direction);
6995 tap_info->uplink = (direction==0);
1
Assuming 'direction' is not equal to 0
6996 /* payloadVersion */
6997 dissect_payload_version(timing_header_tree, tvb, pinfo, offset);
6998 /* filterIndex */
6999 proto_tree_add_item(timing_header_tree, hf_oran_filter_index, tvb, offset, 1, ENC_NA0x00000000);
7000 offset += 1;
7001
7002 int ref_a_offset = offset;
7003
7004 /* frameId */
7005 uint32_t frameId = 0;
7006 proto_tree_add_item_ret_uint(timing_header_tree, hf_oran_frame_id, tvb, offset, 1, ENC_NA0x00000000, &frameId);
7007 tap_info->frame = frameId;
7008 offset += 1;
7009
7010 /* subframeId */
7011 uint32_t subframeId = 0;
7012 proto_tree_add_item_ret_uint(timing_header_tree, hf_oran_subframe_id, tvb, offset, 1, ENC_NA0x00000000, &subframeId);
7013 /* slotId */
7014 uint32_t slotId = 0;
7015 proto_tree_add_item_ret_uint(timing_header_tree, hf_oran_slot_id, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &slotId);
7016 tap_info->slot = slotId;
7017 offset++;
7018 /* symbolId */
7019 uint32_t symbolId = 0;
7020 proto_tree_add_item_ret_uint(timing_header_tree, hf_oran_symbolId, tvb, offset, 1, ENC_NA0x00000000, &symbolId);
7021 offset++;
7022
7023 char id[16];
7024 snprintf(id, 16, "%u-%u-%u-%u", frameId, subframeId, slotId, symbolId);
7025 proto_item *pi = proto_tree_add_string(timing_header_tree, hf_oran_refa, tvb, ref_a_offset, 3, id);
7026 proto_item_set_generated(pi);
7027
7028 proto_item_append_text(timingHeader, "%s, frameId: %d, subframeId: %d, slotId: %d, symbolId: %d)",
7029 val_to_str_const(direction, data_direction_vals, "Unknown"), frameId, subframeId, slotId, symbolId);
7030
7031 unsigned sample_bit_width;
7032 unsigned compression;
7033 int includeUdCompHeader;
7034
7035 /* Also look up C-PLANE state (sent in opposite direction) so may check current compression settings */
7036 uint32_t cplane_key = make_flow_key(pinfo, eAxC, ORAN_C_PLANE0, true1);
7037 flow_state_t* cplane_state = (flow_state_t*)wmem_tree_lookup32(flow_states_table, cplane_key);
7038 uint32_t cplane_samedir_key = make_flow_key(pinfo, eAxC, ORAN_C_PLANE0, false0);
7039 flow_state_t* cplane_samedir_state = (flow_state_t*)wmem_tree_lookup32(flow_states_table, cplane_samedir_key);
7040
7041
7042 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
2
Assuming field 'visited' is not equal to 0
3
Taking false branch
7043 /* Create state/conversation if doesn't exist yet */
7044 if (!state) {
7045 /* Allocate new state */
7046 state = wmem_new0(wmem_file_scope(), flow_state_t)((flow_state_t*)wmem_alloc0((wmem_file_scope()), sizeof(flow_state_t
)))
;
7047 state->ack_nack_requests = wmem_tree_new(wmem_file_scope());
7048 wmem_tree_insert32(flow_states_table, key, state);
7049 }
7050
7051 result = wmem_new0(wmem_file_scope(), flow_result_t)((flow_result_t*)wmem_alloc0((wmem_file_scope()), sizeof(flow_result_t
)))
;
7052 result->expected_dl_sections = wmem_tree_new(wmem_file_scope());
7053 wmem_tree_insert32(flow_results_table, pinfo->num, result);
7054
7055 /* Check sequence analysis status (but not if later part of radio layer fragmentation) */
7056 if (state->last_frame_seen[direction] && (subSeqId==0) && (seqId != state->next_expected_sequence_number[direction])) {
7057 /* Store this result */
7058 result->unexpected_seq_number = true1;
7059 result->expected_sequence_number = state->next_expected_sequence_number[direction];
7060 result->previous_frame = state->last_frame[direction];
7061 }
7062 /* Update sequence analysis state */
7063 state->last_frame[direction] = pinfo->num;
7064 state->last_frame_seen[direction] = true1;
7065 state->next_expected_sequence_number[direction] = (seqId+1) % 256;
7066 }
7067
7068 /* Show any issues associated with this frame number */
7069 result = wmem_tree_lookup32(flow_results_table, pinfo->num);
4
Value assigned to 'result'
7070 if (result) {
5
Assuming 'result' is null
7071 if (result->unexpected_seq_number) {
7072 expert_add_info_format(pinfo, seqIdItem,
7073 (direction == DIR_UPLINK0) ?
7074 &ei_oran_uplane_unexpected_sequence_number_ul :
7075 &ei_oran_uplane_unexpected_sequence_number_dl,
7076 "Sequence number %u expected, but got %u",
7077 result->expected_sequence_number, seqId);
7078 tap_info->missing_sns = (256 + seqId - result->expected_sequence_number) % 256;
7079 /* TODO: could add previous/next frame (in seqId tree?) ? */
7080 }
7081 }
7082
7083 /* Checking UL timing within current slot. Disabled if limit set to 0. */
7084 /* N.B., timing is relative to first seen frame,
7085 not some notion of the beginning of the slot from sync, offset by some timing.. */
7086 if (direction
5.1
'direction' is not equal to DIR_UPLINK
== DIR_UPLINK0 && us_allowed_for_ul_in_symbol > 0) {
7087 uint32_t timing_key = get_timing_key(frameId, subframeId, slotId, symbolId);
7088 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
7089 /* Set state on first pass */
7090 ul_timing_for_slot* timing = (ul_timing_for_slot*)wmem_tree_lookup32(ul_symbol_timing, timing_key);
7091 if (!timing) {
7092 /* Allocate new state */
7093 timing = wmem_new0(wmem_file_scope(), ul_timing_for_slot)((ul_timing_for_slot*)wmem_alloc0((wmem_file_scope()), sizeof
(ul_timing_for_slot)))
;
7094 timing->first_frame = pinfo->num;
7095 timing->first_frame_time = pinfo->abs_ts;
7096 timing->frames_seen_in_symbol = 1;
7097 timing->last_frame_in_symbol = pinfo->num;
7098 wmem_tree_insert32(ul_symbol_timing, timing_key, timing);
7099 }
7100 else {
7101 /* Update existing state */
7102 timing->frames_seen_in_symbol++;
7103 timing->last_frame_in_symbol = pinfo->num;
7104 }
7105 }
7106 else {
7107 /* Subsequent passes - look up result */
7108 ul_timing_for_slot* timing = (ul_timing_for_slot*)wmem_tree_lookup32(ul_symbol_timing, timing_key);
7109 if (timing) { /* Really shouldn't fail! */
7110 if (timing->frames_seen_in_symbol > 1) {
7111 /* Work out gap between frames (in microseconds) back to frame carrying first seen symbol */
7112 int seconds_between_packets = (int)
7113 (pinfo->abs_ts.secs - timing->first_frame_time.secs);
7114 int nseconds_between_packets =
7115 pinfo->abs_ts.nsecs - timing->first_frame_time.nsecs;
7116
7117
7118 /* Round to nearest microsecond. */
7119 uint32_t total_gap = (seconds_between_packets*1000000) +
7120 ((nseconds_between_packets+500) / 1000);
7121
7122 /* Show how long it has been */
7123 proto_item *ti = NULL((void*)0);
7124 if (pinfo->num != timing->first_frame) {
7125 ti = proto_tree_add_uint(timingHeader, hf_oran_u_section_ul_symbol_time, tvb, 0, 0, total_gap);
7126 proto_item_set_generated(ti);
7127 }
7128
7129 if (total_gap > us_allowed_for_ul_in_symbol) {
7130 expert_add_info_format(pinfo, ti, &ei_oran_ul_uplane_symbol_too_long,
7131 "UL U-Plane Tx took longer (%u us) than limit set in preferences (%u us)",
7132 total_gap, us_allowed_for_ul_in_symbol);
7133 proto_item_append_text(timingHeader, " (%uus since first frame seen for symbol)", total_gap);
7134 }
7135
7136 /* Show how many frames were received */
7137 ti = proto_tree_add_uint(timingHeader, hf_oran_u_section_ul_symbol_frames, tvb, 0, 0, timing->frames_seen_in_symbol);
7138 proto_item_set_generated(ti);
7139
7140 /* Link to first frame for this symbol */
7141 if (pinfo->num != timing->first_frame) {
7142 ti = proto_tree_add_uint(timingHeader, hf_oran_u_section_ul_symbol_first_frame, tvb, 0, 0, timing->first_frame);
7143 proto_item_set_generated(ti);
7144 }
7145
7146 /* And also last frame */
7147 if (pinfo->num != timing->last_frame_in_symbol) {
7148 ti = proto_tree_add_uint(timingHeader, hf_oran_u_section_ul_symbol_last_frame, tvb, 0, 0, timing->last_frame_in_symbol);
7149 proto_item_set_generated(ti);
7150 }
7151
7152 tap_info->ul_delay_in_us = total_gap;
7153 }
7154 }
7155 }
7156 }
7157
7158
7159 /* Look up preferences for samples */
7160 if (direction
5.2
'direction' is not equal to DIR_UPLINK
== DIR_UPLINK0) {
6
Taking false branch
7161 sample_bit_width = pref_sample_bit_width_uplink;
7162 compression = pref_iqCompressionUplink;
7163 includeUdCompHeader = pref_includeUdCompHeaderUplink;
7164 } else {
7165 sample_bit_width = pref_sample_bit_width_downlink;
7166 compression = pref_iqCompressionDownlink;
7167 includeUdCompHeader = pref_includeUdCompHeaderDownlink;
7168 }
7169
7170 /* If uplink, load any udCompHdr settings written by C-Plane */
7171 bool_Bool ud_cmp_hdr_cplane = false0;
7172 if (cplane_state && direction == 0) {
7
Assuming 'cplane_state' is null
7173 /* Initialise settings from udpCompHdr from C-Plane */
7174 if (cplane_state->ul_ud_comp_hdr_set && !pref_override_ul_compression) {
7175 sample_bit_width = cplane_state->ul_ud_comp_hdr_bit_width;
7176 compression = cplane_state->ul_ud_comp_hdr_compression;
7177 ud_cmp_hdr_cplane = true1;
7178 }
7179 }
7180
7181 /* Need a valid value (e.g. 9, 14). 0 definitely won't work, as won't progress around loop! */
7182 /* N.B. may yet be overwritten by udCompHdr settings in sections below! */
7183 if (sample_bit_width == 0) {
8
Assuming 'sample_bit_width' is not equal to 0
9
Taking false branch
7184 expert_add_info_format(pinfo, protocol_item, &ei_oran_invalid_sample_bit_width,
7185 "%cL Sample bit width from %s (%u) not valid, so can't decode sections",
7186 (direction == DIR_UPLINK0) ? 'U' : 'D',
7187 !ud_cmp_hdr_cplane ? "preference" : "C-Plane",
7188 sample_bit_width);
7189 return offset;
7190 }
7191
7192 unsigned bytesLeft;
7193 unsigned number_of_sections = 0;
7194 unsigned nBytesPerPrb =0;
7195
7196
7197 if (link_planes_together && !PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited) && cplane_samedir_state) {
10
Assuming 'link_planes_together' is false
7198 /* Take a deep-copy of this state on first pass */
7199 wmem_tree_foreach(cplane_samedir_state->expected_dl_sections, copy_section_entry, result->expected_dl_sections);
7200 }
7201
7202 /* Add each section (not from count, just keep parsing until payload used) */
7203 do {
7204 /* Section subtree */
7205 unsigned section_start_offset = offset;
7206 proto_item *sectionHeading = proto_tree_add_string_format(oran_tree, hf_oran_u_section,
7207 tvb, offset, 0, "", "Section");
7208 proto_tree *section_tree = proto_item_add_subtree(sectionHeading, ett_oran_u_section);
7209
7210 /* Section Header fields (darker green part) */
7211
7212 /* sectionId */
7213 uint32_t sectionId = 0;
7214 proto_item *ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_section_id, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &sectionId);
7215 if (sectionId == 4095) {
11
Assuming 'sectionId' is not equal to 4095
12
Taking false branch
7216 proto_item_append_text(ti, " (not default coupling C/U planes using sectionId)");
7217 }
7218 offset++;
7219
7220 if (tap_info->num_section_ids < MAX_SECTION_IDs32) {
13
Assuming field 'num_section_ids' is >= MAX_SECTION_IDs
14
Taking false branch
7221 tap_info->section_ids[tap_info->num_section_ids++] = sectionId;
7222 }
7223
7224 section_details_t *section_details = NULL((void*)0);
7225
7226 /* For DL, lookup corresponding C-plane frame/info */
7227 if (link_planes_together && direction == 1) {
15
Assuming 'link_planes_together' is true
16
Assuming 'direction' is equal to 1
17
Taking true branch
7228 if (cplane_samedir_state != NULL((void*)0)) {
18
Assuming 'cplane_samedir_state' is not equal to NULL
19
Taking true branch
7229
7230 expected_section_data_t *section_data = NULL((void*)0);
7231 section_data = wmem_tree_lookup32(result->expected_dl_sections, sectionId);
20
Access to field 'expected_dl_sections' results in a dereference of a null pointer (loaded from variable 'result')
7232
7233 if (section_data) {
7234 /* Need to work out which of 2 entries is in use for this data frame */
7235 unsigned index_to_use = 0;
7236
7237 /* Does the first entry match the timing for this frame? */
7238 if (section_data->details[0].frame == frameId &&
7239 section_data->details[0].subframe == subframeId &&
7240 section_data->details[0].slot == slotId &&
7241 /* Check that symbolId is in range */
7242 section_data->details[0].startSymbol <= symbolId &&
7243 (unsigned)(section_data->details[0].startSymbol + section_data->details[0].numSymbols) <= (unsigned)symbolId) {
7244
7245 index_to_use = 0;
7246 }
7247 else if (section_data->details[1].frame == frameId &&
7248 section_data->details[1].subframe == subframeId &&
7249 section_data->details[1].slot == slotId &&
7250 /* Check that symbolId is in range */
7251 section_data->details[1].startSymbol <= symbolId &&
7252 (unsigned)(section_data->details[1].startSymbol + section_data->details[1].numSymbols) <= (unsigned)symbolId) {
7253
7254 index_to_use = 1;
7255 }
7256 else {
7257 /* TODO: expert info warning? */
7258 }
7259
7260 section_details = &section_data->details[index_to_use];
7261
7262 /* Cplane frame number */
7263 proto_item *cplane_frame_ti = proto_tree_add_uint(section_tree, hf_oran_corresponding_cplane_frame, tvb, 0, 0,
7264 section_details->frame_number);
7265 proto_item_set_generated(cplane_frame_ti);
7266
7267 /* usecs since cplane frame */
7268 time_t total_gap = 0;
7269
7270 if ((pinfo->abs_ts.secs == section_details->frame_time.secs) || (pinfo->abs_ts.secs == section_details->frame_time.secs+1)) {
7271 total_gap = ((pinfo->abs_ts.secs - section_details->frame_time.secs) * 1000000) +
7272 ((pinfo->abs_ts.nsecs - section_details->frame_time.nsecs)/1000);
7273 }
7274
7275 if (total_gap > 0) {
7276 proto_item *cplane_delta_ti = proto_tree_add_uint(section_tree, hf_oran_corresponding_cplane_frame_time_delta, tvb, 0, 0, (uint32_t)total_gap);
7277 proto_item_set_generated(cplane_delta_ti);
7278 }
7279 }
7280 }
7281
7282 }
7283
7284 /* rb */
7285 uint32_t rb;
7286 proto_tree_add_item_ret_uint(section_tree, hf_oran_rb, tvb, offset, 1, ENC_NA0x00000000, &rb);
7287 /* symInc. "use of symInc=1 shall be prohibited in the U-plane" */
7288 uint8_t syminc;
7289 proto_item *syminc_ti = proto_tree_add_item_ret_uint8(section_tree, hf_oran_symInc, tvb, offset, 1, ENC_NA0x00000000, &syminc);
7290 if (syminc) {
7291 expert_add_info(NULL((void*)0), syminc_ti, &ei_oran_syminc_set_for_uplane);
7292 }
7293 /* startPrbu */
7294 uint32_t startPrbu = 0;
7295 proto_tree_add_item_ret_uint(section_tree, hf_oran_startPrbu, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &startPrbu);
7296 offset += 2;
7297
7298 /* numPrbu */
7299 uint32_t numPrbu = 0;
7300 proto_tree_add_item_ret_uint(section_tree, hf_oran_numPrbu, tvb, offset, 1, ENC_NA0x00000000, &numPrbu);
7301 offset += 1;
7302
7303 proto_item *ud_comp_meth_item, *ud_comp_len_ti=NULL((void*)0);
7304 uint32_t ud_comp_len = 0;
7305
7306 /* udCompHdr (if preferences indicate will be present) */
7307 bool_Bool included = (includeUdCompHeader==1) || /* 1 means present.. */
7308 (includeUdCompHeader==2 && udcomphdr_appears_present(state, direction, tvb, offset));
7309 if (included) {
7310 /* 7.5.2.10 */
7311 /* Extract these values to inform how wide IQ samples in each PRB will be. */
7312 offset = dissect_udcomphdr(tvb, pinfo, section_tree, offset, false0, direction == 0, &sample_bit_width,
7313 &compression, &ud_comp_meth_item, tap_info);
7314
7315 /* Not part of udCompHdr */
7316 uint32_t reserved;
7317 proto_item *res_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_reserved_8bits, tvb, offset, 1, ENC_NA0x00000000, &reserved);
7318 offset += 1;
7319 if (reserved != 0) {
7320 expert_add_info_format(pinfo, res_ti, &ei_oran_reserved_not_zero,
7321 "reserved field (0x%x) not zero - perhaps udCompHdr is not really present?",
7322 reserved);
7323 }
7324 }
7325 else {
7326 /* No fields to dissect - just showing comp values from prefs */
7327 /* iqWidth */
7328 proto_item *iq_width_item = proto_tree_add_uint(section_tree, hf_oran_udCompHdrIqWidth_pref, tvb, 0, 0, sample_bit_width);
7329 proto_item_append_text(iq_width_item, (ud_cmp_hdr_cplane) ? " (from c-plane)" : " (from preferences)");
7330 proto_item_set_generated(iq_width_item);
7331
7332 /* udCompMethod */
7333 ud_comp_meth_item = proto_tree_add_uint(section_tree, hf_oran_udCompHdrMeth_pref, tvb, 0, 0, compression);
7334 proto_item_append_text(ud_comp_meth_item, (ud_cmp_hdr_cplane) ? " (from c-plane)" : " (from preferences)");
7335 proto_item_set_generated(ud_comp_meth_item);
7336
7337 /* Point back to C-Plane, if used */
7338 /* TODO: doesn't work with multiple port mappings using SE10.. */
7339 if (ud_cmp_hdr_cplane) {
7340 proto_item *cplane_ti = proto_tree_add_uint(section_tree, hf_oran_ul_cplane_ud_comp_hdr_frame, tvb, offset, 0, cplane_state->ul_ud_comp_hdr_frame);
7341 proto_item_set_generated(cplane_ti);
7342 }
7343
7344 tap_info->compression_methods |= (1 << compression);
7345 tap_info->compression_width = sample_bit_width;
7346 }
7347
7348 /* Consider fragmentation after first section header */
7349 if (do_radio_transport_layer_reassembly && (number_of_sections == 0) && (e !=1 || subSeqId!= 0)) {
7350
7351 /* Set fragmented flag. */
7352 bool_Bool save_fragmented = pinfo->fragmented;
7353 pinfo->fragmented = true1;
7354 fragment_head *fh;
7355 unsigned frag_data_len = tvb_reported_length_remaining(tvb, offset);
7356
7357 /* Add this fragment into reassembly table */
7358 uint32_t reassembly_id = make_reassembly_id(seqId, direction, eAxC,
7359 frameId, subframeId, slotId, symbolId);
7360 fh = fragment_add_seq(&oran_reassembly_table, tvb, offset, pinfo,
7361 reassembly_id, /* id */
7362 GUINT_TO_POINTER(reassembly_id)((gpointer) (gulong) (reassembly_id)), /* data */
7363 subSeqId, /* frag_number */
7364 frag_data_len, /* frag_data_len */
7365 !e, /* more_frags */
7366 0);
7367
7368 bool_Bool update_col_info = true1;
7369
7370 /* See if this completes an SDU */
7371 tvbuff_t *original_tvb = tvb;
7372 tvbuff_t *next_tvb = process_reassembled_data(tvb, offset, pinfo, "Reassembled O-RAN FH CUS Payload",
7373 fh, &oran_frag_items,
7374 &update_col_info, oran_tree);
7375 if (next_tvb) {
7376 /* Have reassembled data */
7377 proto_tree_add_item(oran_tree, hf_oran_payload, next_tvb, 0, -1, ENC_NA0x00000000);
7378 col_append_fstr(pinfo->cinfo, COL_INFO, " Reassembled Data (%u bytes)", tvb_reported_length(next_tvb));
7379 /* Dissection should resume at start of reassembled tvb */
7380 offset = 0;
7381 }
7382 /* Will continue with either reassembled tvb or NULL */
7383 tvb = next_tvb;
7384
7385 /* Restore fragmented flag */
7386 pinfo->fragmented = save_fragmented;
7387
7388 /* Don't dissect any more if not complete yet.. */
7389 if (tvb == NULL((void*)0)) {
7390 return tvb_captured_length(original_tvb);
7391 }
7392 }
7393
7394
7395 /* Not supported! TODO: other places where comp method is looked up (e.g., bfw?) */
7396 switch (compression) {
7397 case COMP_NONE0:
7398 case COMP_BLOCK_FP1:
7399 case BFP_AND_SELECTIVE_RE5:
7400 case COMP_MODULATION4:
7401 case MOD_COMPR_AND_SELECTIVE_RE6:
7402 break;
7403 default:
7404 expert_add_info_format(pinfo, ud_comp_meth_item, &ei_oran_unsupported_compression_method,
7405 "Compression method %u (%s) not supported by dissector",
7406 compression,
7407 rval_to_str_const(compression, ud_comp_header_meth, "reserved"));
7408 }
7409
7410 /* udCompLen (when supported, methods 5,6,7,8) */
7411 if (compression >= BFP_AND_SELECTIVE_RE5) {
7412 bool_Bool supported = (pref_support_udcompLen==1) || /* supported */
7413 (pref_support_udcompLen==2 && udcomplen_appears_present(includeUdCompHeader, tvb, offset));
7414
7415 if (supported) {
7416 ud_comp_len_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_udCompLen, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &ud_comp_len);
7417 if (ud_comp_len <= 1) {
7418 proto_item_append_text(ud_comp_len_ti, " (reserved)");
7419 }
7420 /* TODO: report if less than a viable section in frame? */
7421 /* Check that there is this much length left in the frame */
7422 if (ud_comp_len > tvb_reported_length_remaining(tvb, section_start_offset)) {
7423 expert_add_info_format(pinfo, ud_comp_len_ti, &ei_oran_ud_comp_len_wrong_size,
7424 "udCompLen indicates %u bytes in section, but only %u are left in frame",
7425 ud_comp_len, tvb_reported_length_remaining(tvb, section_start_offset));
7426 }
7427 /* Actual length of section will be checked below, at the end of the section */
7428 offset += 2;
7429 }
7430 }
7431
7432 /* sReSMask1 + sReSMask2 (depends upon compression method) */
7433 uint64_t sresmask1=0, sresmask2=0;
7434 if (compression == BFP_AND_SELECTIVE_RE_WITH_MASKS7 ||
7435 compression == MOD_COMPR_AND_SELECTIVE_RE_WITH_MASKS8)
7436 {
7437 static int * const sres_mask1_2_flags[] = {
7438 &hf_oran_sReSMask1_2_re12,
7439 &hf_oran_sReSMask1_2_re11,
7440 &hf_oran_sReSMask1_2_re10,
7441 &hf_oran_sReSMask1_2_re9,
7442 &hf_oran_sReSMask_re8,
7443 &hf_oran_sReSMask_re7,
7444 &hf_oran_sReSMask_re6,
7445 &hf_oran_sReSMask_re5,
7446 &hf_oran_sReSMask_re4,
7447 &hf_oran_sReSMask_re3,
7448 &hf_oran_sReSMask_re2,
7449 &hf_oran_sReSMask_re1,
7450 NULL((void*)0)
7451 };
7452
7453 /* reserved (4 bits) */
7454 add_reserved_field(section_tree, hf_oran_reserved_4bits, tvb, offset, 1);
7455 /* sReSMask1 (12 bits) */
7456 proto_item *sresmask_ti;
7457 sresmask_ti = proto_tree_add_bitmask_ret_uint64(section_tree, tvb, offset,
7458 hf_oran_sReSMask1,
7459 ett_oran_sresmask,
7460 sres_mask1_2_flags,
7461 ENC_NA0x00000000,
7462 &sresmask1);
7463 offset += 2;
7464 /* Count REs present */
7465 unsigned res = 0;
7466 for (unsigned n=0; n < 12; n++) {
7467 if ((sresmask1 >> n) & 0x1) {
7468 res++;
7469 }
7470 }
7471 proto_item_append_text(sresmask_ti, " (%u REs)", res);
7472
7473
7474 /* reserved (4 bits) */
7475 add_reserved_field(section_tree, hf_oran_reserved_4bits, tvb, offset, 1);
7476 /* sReSMask2 (12 bits) */
7477 sresmask_ti = proto_tree_add_bitmask_ret_uint64(section_tree, tvb, offset,
7478 hf_oran_sReSMask2,
7479 ett_oran_sresmask,
7480 sres_mask1_2_flags,
7481 ENC_NA0x00000000,
7482 &sresmask2);
7483 offset += 2;
7484
7485 if (rb == 1) {
7486 proto_item_append_text(sresmask_ti, " (ignored)");
7487 if (sresmask2 != 0) {
7488 expert_add_info(pinfo, ud_comp_len_ti, &ei_oran_sresmask2_not_zero_with_rb);
7489 }
7490 }
7491 else {
7492 /* Count REs present */
7493 res = 0;
7494 for (unsigned n=0; n < 12; n++) {
7495 if ((sresmask2 >> n) & 0x1) {
7496 res++;
7497 }
7498 }
7499 proto_item_append_text(sresmask_ti, " (%u REs)", res);
7500 }
7501 }
7502
7503 write_section_info(sectionHeading, pinfo, protocol_item, sectionId, startPrbu, numPrbu, rb);
7504
7505 /* TODO: should this use the same pref as c-plane? */
7506 if (numPrbu == 0) {
7507 /* Special case for all PRBs (NR: the total number of PRBs may be > 255) */
7508 numPrbu = pref_data_plane_section_total_rbs;
7509 startPrbu = 0; /* may already be 0... */
7510 }
7511
7512 section_mod_compr_config_t* mod_compr_config = get_mod_compr_section_to_read(cplane_samedir_state, sectionId);
7513
7514 /* Add each PRB */
7515 for (unsigned i = 0; i < numPrbu; i++) {
7516 /* Create subtree */
7517 proto_item *prbHeading = proto_tree_add_string_format(section_tree, hf_oran_samples_prb,
7518 tvb, offset, 0,
7519 "", "PRB");
7520 proto_tree *rb_tree = proto_item_add_subtree(prbHeading, ett_oran_u_prb);
7521 uint32_t exponent = 0;
7522 uint16_t sresmask = 0;
7523
7524 /* udCompParam (depends upon compression method) */
7525 int before = offset;
7526 offset = dissect_udcompparam(tvb, pinfo, rb_tree, offset, compression, &exponent, &sresmask, false0);
7527 int udcompparam_len = offset-before;
7528
7529 /* Show PRB number in root */
7530 proto_item_append_text(prbHeading, " %3u", startPrbu + i*(1+rb));
7531
7532 /* Work out how many REs / PRB */
7533 unsigned res_per_prb = 12;
7534 uint16_t sresmask_to_use = 0x0fff;
7535
7536 if (compression >= BFP_AND_SELECTIVE_RE5) {
7537 /* Work out which mask should be used */
7538 if (compression==BFP_AND_SELECTIVE_RE5 || compression==MOD_COMPR_AND_SELECTIVE_RE6) {
7539 /* Selective RE cases, use value from compModParam */
7540 sresmask_to_use = (uint16_t)sresmask;
7541 }
7542 else {
7543 /* With masks (in section). Choose between sresmask1 and sresmask2 */
7544 if (rb==1 || (i%2)==0) {
7545 /* Even values */
7546 sresmask_to_use = (uint16_t)sresmask1;
7547 }
7548 else {
7549 /* Odd values */
7550 sresmask_to_use = (uint16_t)sresmask2;
7551 }
7552 }
7553
7554 /* Count REs present using sresmask */
7555 res_per_prb = 0;
7556 /* Use sresmask to pick out which REs are present */
7557 for (unsigned n=0; n<12; n++) {
7558 if (sresmask_to_use & (1<<n)) {
7559 res_per_prb++;
7560 }
7561 }
7562 }
7563
7564 /* N.B. bytes for samples need to be padded out to next byte
7565 (certainly where there aren't 12 REs in PRB..) */
7566 unsigned nBytesForSamples = (sample_bit_width * res_per_prb * 2 + 7) / 8;
7567 nBytesPerPrb = nBytesForSamples + udcompparam_len;
7568
7569 proto_tree_add_item(rb_tree, hf_oran_iq_user_data, tvb, offset, nBytesForSamples, ENC_NA0x00000000);
7570
7571 if (section_details) {
7572 if ((startPrbu + i*(1+rb)) < 273) {
7573 proto_item *beamid_ti = proto_tree_add_uint(rb_tree, hf_oran_beamId, tvb, 0, 0,
7574 section_details->beamIds[startPrbu + i*(1+rb)]);
7575 proto_item_set_generated(beamid_ti);
7576 }
7577 }
7578
7579
7580 tap_info->non_zero_re_in_current_prb = false0;
7581
7582 /* Optionally trying to show I/Q RE values */
7583 if (pref_showIQSampleValues) {
7584 /* Individual values */
7585 unsigned samples_offset = offset*8;
7586 unsigned samples_start = offset;
7587 unsigned samples = 0;
7588
7589 if (compression >= BFP_AND_SELECTIVE_RE5) {
7590 /* Use sresmask to pick out which REs are present */
7591 for (unsigned n=1; n<=12; n++) {
7592 if (sresmask_to_use & (1<<(n-1))) {
7593 samples_offset = dissect_oran_u_re(tvb, rb_tree,
7594 n, samples_offset, tap_info, sample_bit_width, compression, exponent, mod_compr_config, n);
7595 samples++;
7596 }
7597 }
7598 }
7599 else {
7600 /* All 12 REs are present */
7601 for (unsigned n=1; n<=12; n++) {
7602 samples_offset = dissect_oran_u_re(tvb, rb_tree,
7603 n, samples_offset, tap_info, sample_bit_width, compression, exponent, mod_compr_config, n);
7604 samples++;
7605 }
7606 }
7607 proto_item_append_text(prbHeading, " (%u REs)", samples);
7608 if (section_details) {
7609 if ((startPrbu + i*(1+rb)) < 273) {
7610 proto_item_append_text(prbHeading, " [BeamId:%u]", section_details->beamIds[startPrbu + i*(1+rb)]);
7611 }
7612 }
7613
7614 /* Was this PRB all zeros? */
7615 if (!tap_info->non_zero_re_in_current_prb) {
7616 tap_info->num_prbs_zero++;
7617 /* Add a filter to make zero-valued PRBs more findable */
7618 proto_item *zero_ti = proto_tree_add_item(rb_tree, hf_oran_zero_prb, tvb,
7619 samples_start, nBytesForSamples, ENC_NA0x00000000);
7620 proto_item_set_hidden(zero_ti);
7621 proto_item_append_text(prbHeading, " (all zeros)");
7622 }
7623 else {
7624 proto_item *nonzero_ti = proto_tree_add_item(rb_tree, hf_oran_nonzero_prb, tvb, samples_start, nBytesForSamples, ENC_NA0x00000000);
7625 proto_item_set_hidden(nonzero_ti);
7626 }
7627 }
7628
7629 tap_info->num_prbs++;
7630
7631
7632 /* Advance past samples */
7633 offset += nBytesForSamples;
7634
7635 /* Set end of prb subtree */
7636 proto_item_set_end(prbHeading, tvb, offset);
7637 }
7638
7639 /* Set extent of section */
7640 proto_item_set_len(sectionHeading, offset-section_start_offset);
7641 if (ud_comp_len_ti != NULL((void*)0) && ((offset-section_start_offset != ud_comp_len))) {
7642 expert_add_info_format(pinfo, ud_comp_len_ti, &ei_oran_ud_comp_len_wrong_size,
7643 "udCompLen indicates %u bytes in section, but dissected %u instead",
7644 ud_comp_len, offset-section_start_offset);
7645 }
7646
7647 bytesLeft = tvb_captured_length(tvb) - offset;
7648 number_of_sections++;
7649 } while (bytesLeft >= (4 + nBytesPerPrb)); /* FIXME: bad heuristic */
7650
7651 /* Show number of sections found */
7652 proto_item *ti = proto_tree_add_uint(oran_tree, hf_oran_numberOfSections, tvb, 0, 0, number_of_sections);
7653 proto_item_set_generated(ti);
7654
7655 /* Expert error if we are short of tvb by > 3 bytes */
7656 if (tvb_reported_length_remaining(tvb, offset) > 3) {
7657 expert_add_info_format(pinfo, protocol_item, &ei_oran_frame_length,
7658 "%u bytes remain at end of frame - should be 0-3",
7659 tvb_reported_length_remaining(tvb, offset));
7660 }
7661
7662 return tvb_captured_length(tvb);
7663}
7664
7665
7666/**********************************************************************/
7667/* Main dissection function. */
7668/* N.B. ecpri message type passed in as 'data' arg by eCPRI dissector */
7669static int
7670dissect_oran(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
7671{
7672 uint32_t ecpri_message_type = *(uint32_t *)data;
7673 unsigned offset = 0;
7674
7675 /* Allocate and zero tap struct */
7676 oran_tap_info *tap_info = wmem_new0(wmem_file_scope(), oran_tap_info)((oran_tap_info*)wmem_alloc0((wmem_file_scope()), sizeof(oran_tap_info
)))
;
7677 tap_info->pdu_size = pinfo->fd->pkt_len;
7678 tap_info->ul_delay_configured_max = us_allowed_for_ul_in_symbol;
7679
7680 switch (ecpri_message_type) {
7681 case ECPRI_MT_IQ_DATA0:
7682 offset = dissect_oran_u(tvb, pinfo, tree, tap_info, data);
7683 break;
7684 case ECPRI_MT_RT_CTRL_DATA2:
7685 offset = dissect_oran_c(tvb, pinfo, tree, tap_info, data);
7686 break;
7687 default:
7688 /* Not dissecting other types - assume these are handled by eCPRI dissector */
7689 return 0;
7690 }
7691
7692 tap_queue_packet(oran_tap, pinfo, tap_info);
7693
7694 return offset;
7695}
7696
7697static void oran_init_protocol(void)
7698{
7699 udcomplen_heuristic_result_set = false0;
7700 udcomplen_heuristic_result = false0;
7701}
7702
7703
7704/* Register the protocol with Wireshark. */
7705void
7706proto_register_oran(void)
7707{
7708 static hf_register_info hf[] = {
7709
7710 /* Section 5.1.3.2.7 */
7711 { &hf_oran_du_port_id,
7712 { "DU Port ID", "oran_fh_cus.du_port_id",
7713 FT_UINT16, BASE_DEC,
7714 NULL((void*)0), 0x0,
7715 "Processing unit at O-RU - width set in dissector preference", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
7716 },
7717
7718 /* Section 5.1.3.2.7 */
7719 { &hf_oran_bandsector_id,
7720 { "BandSector ID", "oran_fh_cus.bandsector_id",
7721 FT_UINT16, BASE_DEC,
7722 NULL((void*)0), 0x0,
7723 "Aggregated cell identified - width set in dissector preference", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
7724 },
7725
7726 /* Section 5.1.3.2.7 */
7727 { &hf_oran_cc_id,
7728 { "CC ID", "oran_fh_cus.cc_id",
7729 FT_UINT16, BASE_DEC,
7730 NULL((void*)0), 0x0,
7731 "Component Carrier - width set in dissector preference", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
7732 },
7733
7734 /* Section 5.1.3.2.7 */
7735 { &hf_oran_ru_port_id,
7736 { "RU Port ID", "oran_fh_cus.ru_port_id",
7737 FT_UINT16, BASE_DEC,
7738 NULL((void*)0), 0x0,
7739 "Logical flow - width set in dissector preference", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
7740 },
7741
7742 /* Section 5.1.3.2.8 */
7743 { &hf_oran_sequence_id,
7744 { "Sequence ID", "oran_fh_cus.sequence_id",
7745 FT_UINT8, BASE_DEC,
7746 NULL((void*)0), 0x0,
7747 "The Sequence ID wraps around individually per eAxC", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
7748 },
7749
7750 /* Section 5.1.3.2.8 */
7751 { &hf_oran_e_bit,
7752 { "E Bit", "oran_fh_cus.e_bit",
7753 FT_UINT8, BASE_DEC,
7754 VALS(e_bit)((0 ? (const struct _value_string*)0 : ((e_bit)))), 0x80,
7755 "Indicate the last message of a subsequence (U-Plane only)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
7756 },
7757
7758 /* Section 5.1.3.2.8 */
7759 { &hf_oran_subsequence_id,
7760 { "Subsequence ID", "oran_fh_cus.subsequence_id",
7761 FT_UINT8, BASE_DEC,
7762 NULL((void*)0), 0x7f,
7763 "The subsequence ID (for eCPRI layer fragmentation)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
7764 },
7765
7766 { &hf_oran_previous_frame,
7767 { "Previous frame in stream", "oran_fh_cus.previous-frame",
7768 FT_FRAMENUM, BASE_NONE,
7769 FRAMENUM_TYPE(FT_FRAMENUM_NONE)((gpointer) (glong) (FT_FRAMENUM_NONE)), 0x0,
7770 "Previous frame in sequence", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
7771 },
7772
7773 /* Section 7.5.2.1 */
7774 { &hf_oran_data_direction,
7775 { "Data Direction", "oran_fh_cus.data_direction",
7776 FT_UINT8, BASE_DEC,
7777 VALS(data_direction_vals)((0 ? (const struct _value_string*)0 : ((data_direction_vals)
)))
, 0x80,
7778 "gNB data direction", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
7779 },
7780
7781 /* Section 7.5.2.2 */
7782 { &hf_oran_payload_version,
7783 { "Payload Version", "oran_fh_cus.payloadVersion",
7784 FT_UINT8, BASE_DEC,
7785 NULL((void*)0), 0x70,
7786 "Payload protocol version the following IEs", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7787 },
7788
7789 /* Section 7.5.2.3 */
7790 { &hf_oran_filter_index,
7791 { "Filter Index", "oran_fh_cus.filterIndex",
7792 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
7793 RVALS(filter_indices)((0 ? (const struct _range_string*)0 : ((filter_indices)))), 0x0f,
7794 "used between IQ data and air interface, both in DL and UL", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7795 },
7796
7797 /* Section 7.5.2.4 */
7798 { &hf_oran_frame_id,
7799 { "Frame ID", "oran_fh_cus.frameId",
7800 FT_UINT8, BASE_DEC,
7801 NULL((void*)0), 0x0,
7802 "A counter for 10 ms frames (wrapping period 2.56 seconds)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7803 },
7804
7805 /* Section 7.5.2.5 */
7806 { &hf_oran_subframe_id,
7807 { "Subframe ID", "oran_fh_cus.subframe_id",
7808 FT_UINT8, BASE_DEC,
7809 NULL((void*)0), 0xf0,
7810 "A counter for 1 ms sub-frames within 10ms frame", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7811 },
7812
7813 /* Section 7.5.2.6 */
7814 { &hf_oran_slot_id,
7815 { "Slot ID", "oran_fh_cus.slotId",
7816 FT_UINT16, BASE_DEC,
7817 NULL((void*)0), 0x0fc0,
7818 "Slot number within a 1ms sub-frame", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7819 },
7820
7821 /* Generated for convenience */
7822 { &hf_oran_slot_within_frame,
7823 { "Slot within frame", "oran_fh_cus.slot-within-frame",
7824 FT_UINT16, BASE_DEC,
7825 NULL((void*)0), 0x0,
7826 "Slot within frame, to match DCT logs", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7827 },
7828
7829 /* Section 7.5.2.7 */
7830 { &hf_oran_start_symbol_id,
7831 { "Start Symbol ID", "oran_fh_cus.startSymbolId",
7832 FT_UINT8, BASE_DEC,
7833 NULL((void*)0), 0x3f,
7834 "The first symbol number within slot affected", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7835 },
7836
7837 /* Section 7.5.2.8 */
7838 { &hf_oran_numberOfSections,
7839 { "Number of Sections", "oran_fh_cus.numberOfSections",
7840 FT_UINT8, BASE_DEC,
7841 NULL((void*)0), 0x0,
7842 "The number of section IDs included in this message", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7843 },
7844
7845 /* Section 7.5.2.9 */
7846 { &hf_oran_sectionType,
7847 { "Section Type", "oran_fh_cus.sectionType",
7848 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
7849 RVALS(section_types)((0 ? (const struct _range_string*)0 : ((section_types)))), 0x0,
7850 "Determines the characteristics of U-plane data", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7851 },
7852
7853 /* Section 7.5.2.10 */
7854 { &hf_oran_udCompHdr,
7855 { "udCompHdr", "oran_fh_cus.udCompHdr",
7856 FT_STRING, BASE_NONE,
7857 NULL((void*)0), 0x0,
7858 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7859 },
7860
7861 /* Section 7.5.2.11 */
7862 { &hf_oran_numberOfUEs,
7863 { "Number Of UEs", "oran_fh_cus.numberOfUEs",
7864 FT_UINT8, BASE_DEC,
7865 NULL((void*)0), 0x0,
7866 "Indicates number of UEs for which channel info is provided", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7867 },
7868
7869 /* Section 7.5.2.12 */
7870 { &hf_oran_timeOffset,
7871 { "Time Offset", "oran_fh_cus.timeOffset",
7872 FT_UINT16, BASE_DEC,
7873 NULL((void*)0), 0x0,
7874 "from start of the slot to start of CP in samples", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7875 },
7876
7877 /* Section 7.5.2.13 */
7878 { &hf_oran_frameStructure_fft,
7879 { "FFT Size", "oran_fh_cus.frameStructure.fft",
7880 FT_UINT8, BASE_HEX | BASE_RANGE_STRING0x00000100,
7881 RVALS(frame_structure_fft)((0 ? (const struct _range_string*)0 : ((frame_structure_fft)
)))
, 0xf0,
7882 "The FFT/iFFT size being used for all IQ data processing related to this message", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
7883 },
7884
7885 /* Section 7.5.2.13 */
7886 { &hf_oran_frameStructure_subcarrier_spacing,
7887 { "Subcarrier Spacing", "oran_fh_cus.frameStructure.spacing",
7888 FT_UINT8, BASE_HEX | BASE_RANGE_STRING0x00000100,
7889 RVALS(subcarrier_spacings)((0 ? (const struct _range_string*)0 : ((subcarrier_spacings)
)))
, 0x0f,
7890 "The sub carrier spacing as well as the number of slots per 1ms sub-frame",
7891 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
7892 },
7893
7894 /* Section 7.5.2.14 */
7895 { &hf_oran_cpLength,
7896 { "cpLength", "oran_fh_cus.cpLength",
7897 FT_UINT16, BASE_DEC,
7898 NULL((void*)0), 0x0,
7899 "cyclic prefix length", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7900 },
7901
7902 { &hf_oran_timing_header,
7903 { "Timing Header", "oran_fh_cus.timingHeader",
7904 FT_STRING, BASE_NONE,
7905 NULL((void*)0), 0x0,
7906 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7907 },
7908
7909 /* Section 7.5.3.1 */
7910 { &hf_oran_section_id,
7911 { "sectionId", "oran_fh_cus.sectionId",
7912 FT_UINT16, BASE_DEC,
7913 NULL((void*)0), 0xfff0,
7914 "section identifier of data", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7915 },
7916
7917 /* Section 7.5.3.2 */
7918 { &hf_oran_rb,
7919 { "rb", "oran_fh_cus.rb",
7920 FT_UINT8, BASE_DEC,
7921 VALS(rb_vals)((0 ? (const struct _value_string*)0 : ((rb_vals)))), 0x08,
7922 "resource block indicator", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7923 },
7924
7925 /* Section 7.5.5.3 */
7926 { &hf_oran_symInc,
7927 { "symInc", "oran_fh_cus.symInc",
7928 FT_UINT8, BASE_DEC,
7929 VALS(sym_inc_vals)((0 ? (const struct _value_string*)0 : ((sym_inc_vals)))), 0x04,
7930 "Symbol Number Increment Command", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7931 },
7932
7933 /* Section 7.5.3.4 */
7934 { &hf_oran_startPrbc,
7935 { "startPrbc", "oran_fh_cus.startPrbc",
7936 FT_UINT16, BASE_DEC,
7937 NULL((void*)0), 0x03ff,
7938 "Starting PRB of Control Plane Section", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7939 },
7940
7941 /* Section 7.5.3.5 */
7942 { &hf_oran_reMask_re1,
7943 { "RE 1", "oran_fh_cus.reMask-RE1",
7944 FT_BOOLEAN, 16,
7945 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x8000,
7946 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7947 },
7948 { &hf_oran_reMask_re2,
7949 { "RE 2", "oran_fh_cus.reMask-RE2",
7950 FT_BOOLEAN, 16,
7951 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x4000,
7952 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7953 },
7954 { &hf_oran_reMask_re3,
7955 { "RE 3", "oran_fh_cus.reMask-RE3",
7956 FT_BOOLEAN, 16,
7957 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x2000,
7958 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7959 },
7960 { &hf_oran_reMask_re4,
7961 { "RE 4", "oran_fh_cus.reMask-RE4",
7962 FT_BOOLEAN, 16,
7963 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x1000,
7964 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7965 },
7966 { &hf_oran_reMask_re5,
7967 { "RE 5", "oran_fh_cus.reMask-RE5",
7968 FT_BOOLEAN, 16,
7969 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0800,
7970 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7971 },
7972 { &hf_oran_reMask_re6,
7973 { "RE 6", "oran_fh_cus.reMask-RE6",
7974 FT_BOOLEAN, 16,
7975 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0400,
7976 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7977 },
7978 { &hf_oran_reMask_re7,
7979 { "RE 7", "oran_fh_cus.reMask-RE7",
7980 FT_BOOLEAN, 16,
7981 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0200,
7982 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7983 },
7984 { &hf_oran_reMask_re8,
7985 { "RE 8", "oran_fh_cus.reMask-RE8",
7986 FT_BOOLEAN, 16,
7987 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0100,
7988 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7989 },
7990 { &hf_oran_reMask_re9,
7991 { "RE 9", "oran_fh_cus.reMask-RE9",
7992 FT_BOOLEAN, 16,
7993 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0080,
7994 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7995 },
7996 { &hf_oran_reMask_re10,
7997 { "RE 10", "oran_fh_cus.reMask-RE10",
7998 FT_BOOLEAN, 16,
7999 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0040,
8000 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8001 },
8002 { &hf_oran_reMask_re11,
8003 { "RE 11", "oran_fh_cus.reMask-RE11",
8004 FT_BOOLEAN, 16,
8005 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0020,
8006 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8007 },
8008 { &hf_oran_reMask_re12,
8009 { "RE 12", "oran_fh_cus.reMask-RE12",
8010 FT_BOOLEAN, 16,
8011 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0010,
8012 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8013 },
8014 { &hf_oran_reMask,
8015 { "RE Mask", "oran_fh_cus.reMask",
8016 FT_UINT16, BASE_HEX,
8017 NULL((void*)0), 0xfff0,
8018 "The Resource Element (RE) mask within a PRB", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8019 },
8020
8021 /* Section 7.5.3.6 */
8022 { &hf_oran_numPrbc,
8023 { "numPrbc", "oran_fh_cus.numPrbc",
8024 FT_UINT8, BASE_DEC,
8025 NULL((void*)0), 0x0,
8026 "Number of contiguous PRBs per data section description", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8027 },
8028 /* Section 7.5.3.7 */
8029 { &hf_oran_numSymbol,
8030 { "Number of Symbols", "oran_fh_cus.numSymbol",
8031 FT_UINT8, BASE_DEC,
8032 NULL((void*)0), 0x0f,
8033 "Defines number of symbols to which the section control is applicable", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8034 },
8035 /* Section 7.5.3.8 */
8036 { &hf_oran_ef,
8037 { "Extension Flag", "oran_fh_cus.ef",
8038 FT_BOOLEAN, 8,
8039 NULL((void*)0), 0x80,
8040 "Indicates if more section extensions follow", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8041 },
8042 /* Section 7.5.3.9 */
8043 { &hf_oran_beamId,
8044 { "Beam ID", "oran_fh_cus.beamId",
8045 FT_UINT16, BASE_DEC,
8046 NULL((void*)0), 0x7fff,
8047 "Defines the beam pattern to be applied to the U-Plane data", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8048 },
8049
8050 { &hf_oran_extension,
8051 { "Extension", "oran_fh_cus.extension",
8052 FT_STRING, BASE_NONE,
8053 NULL((void*)0), 0x0,
8054 "Section extension", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8055 },
8056
8057 /* Section 7.6.2.1 */
8058 { &hf_oran_exttype,
8059 { "extType", "oran_fh_cus.extType",
8060 FT_UINT8, BASE_DEC|BASE_EXT_STRING0x00000200,
8061 &exttype_vals_ext, 0x7f,
8062 "The extension type, which provides additional parameters specific to subject data extension", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8063 },
8064
8065 /* Section 7.6.2.3 */
8066 { &hf_oran_extlen,
8067 { "extLen", "oran_fh_cus.extLen",
8068 FT_UINT16, BASE_DEC,
8069 NULL((void*)0), 0x0,
8070 "Extension length in 32-bit words", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8071 },
8072
8073 /* Section 7.7.1 */
8074 { &hf_oran_bfw,
8075 { "bfw", "oran_fh_cus.bfw",
8076 FT_STRING, BASE_NONE,
8077 NULL((void*)0), 0x0,
8078 "Set of weights for a particular antenna", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8079 },
8080 { &hf_oran_bfw_bundle,
8081 { "Bundle", "oran_fh_cus.bfw.bundle",
8082 FT_STRING, BASE_NONE,
8083 NULL((void*)0), 0x0,
8084 "Bundle of BFWs", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8085 },
8086 { &hf_oran_bfw_bundle_id,
8087 { "Bundle Id", "oran_fh_cus.bfw.bundleId",
8088 FT_UINT32, BASE_DEC,
8089 NULL((void*)0), 0x0,
8090 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8091 },
8092 /* Section 7.7.1.4 */
8093 { &hf_oran_bfw_i,
8094 { "bfwI", "oran_fh_cus.bfwI",
8095 FT_FLOAT, BASE_NONE,
8096 NULL((void*)0), 0x0,
8097 "In-phase", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8098 },
8099 /* Section 7.7.1.5 */
8100 { &hf_oran_bfw_q,
8101 { "bfwQ", "oran_fh_cus.bfwQ",
8102 FT_FLOAT, BASE_NONE,
8103 NULL((void*)0), 0x0,
8104 "Quadrature", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8105 },
8106
8107 /* Section 7.5.3.10 */
8108 { &hf_oran_ueId,
8109 { "UE ID", "oran_fh_cus.ueId",
8110 FT_UINT16, BASE_DEC,
8111 NULL((void*)0), 0x7fff,
8112 "logical identifier for set of channel info", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8113 },
8114 /* Section 7.5.3.11 */
8115 { &hf_oran_freqOffset,
8116 { "Frequency Offset", "oran_fh_cus.freqOffset",
8117 FT_UINT24, BASE_DEC,
8118 NULL((void*)0), 0x0,
8119 "with respect to the carrier center frequency before additional filtering", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8120 },
8121
8122 /* Section 7.5.3.12 */
8123 { &hf_oran_regularizationFactor,
8124 { "Regularization Factor", "oran_fh_cus.regularizationFactor",
8125 FT_INT16, BASE_DEC,
8126 NULL((void*)0), 0x0,
8127 "Signed value to support MMSE operation within O-RU", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8128 },
8129 /* Section 7.5.3.14 */
8130 { &hf_oran_laaMsgType,
8131 { "LAA Message Type", "oran_fh_cus.laaMsgType",
8132 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
8133 RVALS(laaMsgTypes)((0 ? (const struct _range_string*)0 : ((laaMsgTypes)))), 0xf0,
8134 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8135 },
8136 /* Section 7.5.3.15 */
8137 { &hf_oran_laaMsgLen,
8138 { "LAA Message Length", "oran_fh_cus.laaMsgLen",
8139 FT_UINT8, BASE_DEC,
8140 NULL((void*)0), 0x0f,
8141 "number of 32-bit words in the LAA section", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8142 },
8143 /* Section 7.5.3.16 */
8144 { &hf_oran_lbtHandle,
8145 { "LBT Handle", "oran_fh_cus.lbtHandle",
8146 FT_UINT16, BASE_HEX,
8147 NULL((void*)0), 0x0,
8148 "label to identify transaction", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8149 },
8150 /* Section 7.5.3.17 */
8151 { &hf_oran_lbtDeferFactor,
8152 { "Defer Factor", "oran_fh_cus.lbtDeferFactor",
8153 FT_UINT8, BASE_DEC,
8154 NULL((void*)0), 0x07,
8155 "Defer factor in sensing slots as described in 3GPP TS 36.213 Section 15.1.1", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8156 },
8157 /* Section 7.5.3.18 */
8158 { &hf_oran_lbtBackoffCounter,
8159 { "Backoff Counter", "oran_fh_cus.lbtBackoffCounter",
8160 FT_UINT16, BASE_DEC,
8161 NULL((void*)0), 0xffc0,
8162 "LBT backoff counter in sensing slots as described in 3GPP TS 36.213 Section 15.1.1", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8163 },
8164 /* Section 7.5.3.19 */
8165 { &hf_oran_lbtOffset,
8166 { "LBT Offset", "oran_fh_cus.lbtOffset",
8167 FT_UINT16, BASE_DEC,
8168 NULL((void*)0), 0xffc0,
8169 "LBT start time in microseconds from the beginning of the subframe scheduled by this message", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8170 },
8171 /* Section 7.5.3.20 */
8172 { &hf_oran_MCOT,
8173 { "Maximum Channel Occupancy Time", "oran_fh_cus.MCOT",
8174 FT_UINT8, BASE_DEC,
8175 NULL((void*)0), 0x3c,
8176 "LTE TXOP duration in subframes as described in 3GPP TS 36.213 Section 15.1.1", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8177 },
8178 /* Section 7.5.3.21 */
8179 { &hf_oran_lbtMode,
8180 { "LBT Mode", "oran_fh_cus.lbtMode",
8181 FT_UINT8, BASE_DEC,
8182 VALS(lbtMode_vals)((0 ? (const struct _value_string*)0 : ((lbtMode_vals)))), 0x0,
8183 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8184 },
8185 /* Section 7.5.3.22 */
8186 { &hf_oran_lbtPdschRes,
8187 { "lbtPdschRes", "oran_fh_cus.lbtPdschRes",
8188 FT_UINT8, BASE_DEC,
8189 VALS(lbtPdschRes_vals)((0 ? (const struct _value_string*)0 : ((lbtPdschRes_vals)))), 0xc0,
8190 "LBT result of SFN/SF", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8191 },
8192 /* Section 7.5.3.23 */
8193 { &hf_oran_sfStatus,
8194 { "sfStatus", "oran_fh_cus.sfStatus",
8195 FT_BOOLEAN, 8,
8196 TFS(&tfs_sfStatus)((0 ? (const struct true_false_string*)0 : ((&tfs_sfStatus
))))
, 0x10,
8197 "Indicates whether the subframe was dropped or transmitted", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8198 },
8199 /* Section 7.5.3.24 */
8200 { &hf_oran_lbtDrsRes,
8201 { "lbtDrsRes", "oran_fh_cus.lbtDrsRes",
8202 FT_BOOLEAN, 8,
8203 TFS(&tfs_fail_success)((0 ? (const struct true_false_string*)0 : ((&tfs_fail_success
))))
, 0x80,
8204 "Indicates whether the subframe was dropped or transmitted", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8205 },
8206 /* Section 7.5.3.25 */
8207 { &hf_oran_initialPartialSF,
8208 { "Initial partial SF", "oran_fh_cus.initialPartialSF",
8209 FT_BOOLEAN, 8,
8210 TFS(&tfs_partial_full_sf)((0 ? (const struct true_false_string*)0 : ((&tfs_partial_full_sf
))))
, 0x40,
8211 "Indicates whether the initial SF in the LBT process is full or partial", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8212 },
8213 /* Section 7.5.3.26. */
8214 { &hf_oran_lbtBufErr,
8215 { "lbtBufErr", "oran_fh_cus.lbtBufErr",
8216 FT_BOOLEAN, 8,
8217 TFS(&tfs_lbtBufErr)((0 ? (const struct true_false_string*)0 : ((&tfs_lbtBufErr
))))
, 0x80,
8218 "LBT buffer error", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8219 },
8220 /* Section 7.5.3.27 */
8221 { &hf_oran_sfnSfEnd,
8222 { "SFN/SF End", "oran_fh_cus.sfnSfEnd",
8223 FT_UINT16, BASE_DEC,
8224 NULL((void*)0), 0x0fff,
8225 "SFN/SF by which the DRS window must end", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8226 },
8227 /* Section 7.5.3.28 */
8228 { &hf_oran_lbtCWConfig_H,
8229 { "lbtCWConfig_H", "oran_fh_cus.lbtCWConfig_H",
8230 FT_UINT8, BASE_DEC,
8231 NULL((void*)0), 0x0,
8232 "HARQ parameters for congestion window management", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8233 },
8234 /* Section 7.5.3.29 */
8235 { &hf_oran_lbtCWConfig_T,
8236 { "lbtCWConfig_T", "oran_fh_cus.lbtCWConfig_T",
8237 FT_UINT8, BASE_DEC,
8238 NULL((void*)0), 0x0,
8239 "TB parameters for congestion window management", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8240 },
8241 /* Section 7.5.3.30 */
8242 { &hf_oran_lbtTrafficClass,
8243 { "lbtTrafficClass", "oran_fh_cus.lbtTrafficClass",
8244 FT_UINT8, BASE_DEC,
8245 VALS(lbtTrafficClass_vals)((0 ? (const struct _value_string*)0 : ((lbtTrafficClass_vals
))))
, 0x38,
8246 "Traffic class priority for congestion window management", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8247 },
8248 /* Section 7.5.3.31 */
8249 { &hf_oran_lbtCWR_Rst,
8250 { "lbtCWR_Rst", "oran_fh_cus.lbtCWR_Rst",
8251 FT_BOOLEAN, 8,
8252 TFS(&tfs_fail_success)((0 ? (const struct true_false_string*)0 : ((&tfs_fail_success
))))
, 0x80,
8253 "notification about packet reception successful or not", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8254 },
8255
8256 /* Reserved fields */
8257 { &hf_oran_reserved,
8258 { "reserved", "oran_fh_cus.reserved",
8259 FT_UINT64, BASE_HEX,
8260 NULL((void*)0), 0x0,
8261 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8262 },
8263 { &hf_oran_reserved_1bit,
8264 { "reserved", "oran_fh_cus.reserved",
8265 FT_UINT8, BASE_HEX,
8266 NULL((void*)0), 0x80,
8267 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8268 },
8269 { &hf_oran_reserved_2bits,
8270 { "reserved", "oran_fh_cus.reserved",
8271 FT_UINT8, BASE_HEX,
8272 NULL((void*)0), 0xc0,
8273 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8274 },
8275 { &hf_oran_reserved_3bits,
8276 { "reserved", "oran_fh_cus.reserved",
8277 FT_UINT8, BASE_HEX,
8278 NULL((void*)0), 0xe0,
8279 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8280 },
8281 { &hf_oran_reserved_4bits,
8282 { "reserved", "oran_fh_cus.reserved",
8283 FT_UINT8, BASE_HEX,
8284 NULL((void*)0), 0xf0,
8285 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8286 },
8287 { &hf_oran_reserved_last_4bits,
8288 { "reserved", "oran_fh_cus.reserved",
8289 FT_UINT8, BASE_HEX,
8290 NULL((void*)0), 0x0f,
8291 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8292 },
8293 { &hf_oran_reserved_last_5bits,
8294 { "reserved", "oran_fh_cus.reserved",
8295 FT_UINT8, BASE_HEX,
8296 NULL((void*)0), 0x1f,
8297 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8298 },
8299 { &hf_oran_reserved_6bits,
8300 { "reserved", "oran_fh_cus.reserved",
8301 FT_UINT8, BASE_HEX,
8302 NULL((void*)0), 0xfc,
8303 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8304 },
8305 { &hf_oran_reserved_last_6bits,
8306 { "reserved", "oran_fh_cus.reserved",
8307 FT_UINT8, BASE_HEX,
8308 NULL((void*)0), 0x3f,
8309 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8310 },
8311 { &hf_oran_reserved_7bits,
8312 { "reserved", "oran_fh_cus.reserved",
8313 FT_UINT8, BASE_HEX,
8314 NULL((void*)0), 0xfe,
8315 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8316 },
8317 { &hf_oran_reserved_last_7bits,
8318 { "reserved", "oran_fh_cus.reserved",
8319 FT_UINT8, BASE_HEX,
8320 NULL((void*)0), 0x7f,
8321 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8322 },
8323 { &hf_oran_reserved_8bits,
8324 { "reserved", "oran_fh_cus.reserved",
8325 FT_UINT8, BASE_HEX,
8326 NULL((void*)0), 0x0,
8327 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8328 },
8329 { &hf_oran_reserved_16bits,
8330 { "reserved", "oran_fh_cus.reserved",
8331 FT_UINT16, BASE_HEX,
8332 NULL((void*)0), 0x0,
8333 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8334 },
8335 { &hf_oran_reserved_15bits,
8336 { "reserved", "oran_fh_cus.reserved",
8337 FT_UINT16, BASE_HEX,
8338 NULL((void*)0), 0x7fff,
8339 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8340 },
8341 { &hf_oran_reserved_bit1,
8342 { "reserved", "oran_fh_cus.reserved",
8343 FT_UINT8, BASE_HEX,
8344 NULL((void*)0), 0x40,
8345 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8346 },
8347 { &hf_oran_reserved_bit2,
8348 { "reserved", "oran_fh_cus.reserved",
8349 FT_UINT8, BASE_HEX,
8350 NULL((void*)0), 0x20,
8351 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8352 },
8353 { &hf_oran_reserved_bit4,
8354 { "reserved", "oran_fh_cus.reserved",
8355 FT_UINT8, BASE_HEX,
8356 NULL((void*)0), 0x08,
8357 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8358 },
8359 { &hf_oran_reserved_bit5,
8360 { "reserved", "oran_fh_cus.reserved",
8361 FT_UINT8, BASE_HEX,
8362 NULL((void*)0), 0x04,
8363 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8364 },
8365 { &hf_oran_reserved_bits123,
8366 { "reserved", "oran_fh_cus.reserved",
8367 FT_UINT8, BASE_HEX,
8368 NULL((void*)0), 0x70,
8369 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8370 },
8371 { &hf_oran_reserved_bits456,
8372 { "reserved", "oran_fh_cus.reserved",
8373 FT_UINT8, BASE_HEX,
8374 NULL((void*)0), 0x0e,
8375 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8376 },
8377
8378 /* 7.7.11.9 */
8379 { &hf_oran_cont_ind,
8380 { "contInd", "oran_fh_cus.contInd",
8381 FT_BOOLEAN, 8,
8382 TFS(&continuity_indication_tfs)((0 ? (const struct true_false_string*)0 : ((&continuity_indication_tfs
))))
, 0x80,
8383 "PRB region continuity flag", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8384 },
8385 /* 7.7.11.10 */
8386 { &hf_oran_bundle_offset,
8387 { "BundleOffset", "oran_fh_cus.bundleOffset",
8388 FT_UINT8, BASE_DEC,
8389 NULL((void*)0), 0x3f,
8390 "offset between start of first PRB bundle and startPrbc", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8391 },
8392
8393 /* 7.7.1.2 bfwCompHdr (beamforming weight compression header) */
8394 { &hf_oran_bfwCompHdr,
8395 { "bfwCompHdr", "oran_fh_cus.bfwCompHdr",
8396 FT_STRING, BASE_NONE,
8397 NULL((void*)0), 0x0,
8398 "Compression method and IQ bit width for beamforming weights", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8399 },
8400 { &hf_oran_bfwCompHdr_iqWidth,
8401 { "IQ Bit Width", "oran_fh_cus.bfwCompHdr_iqWidth",
8402 FT_UINT8, BASE_HEX,
8403 VALS(bfw_comp_headers_iq_width)((0 ? (const struct _value_string*)0 : ((bfw_comp_headers_iq_width
))))
, 0xf0,
8404 "IQ bit width for the beamforming weights", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8405 },
8406 { &hf_oran_bfwCompHdr_compMeth,
8407 { "Compression Method", "oran_fh_cus.bfwCompHdr_compMeth",
8408 FT_UINT8, BASE_HEX,
8409 VALS(bfw_comp_headers_comp_meth)((0 ? (const struct _value_string*)0 : ((bfw_comp_headers_comp_meth
))))
, 0x0f,
8410 "compression method for the beamforming weights", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8411 },
8412
8413 /* 7.5.3.32 */
8414 { &hf_oran_ciCompParam,
8415 { "ciCompParam", "oran_fh_cus.ciCompParam",
8416 FT_STRING, BASE_NONE,
8417 NULL((void*)0), 0x0,
8418 "channel information compression parameter", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8419 },
8420
8421 /* Table 7.5.3.32-1 */
8422 { &hf_oran_blockScaler,
8423 { "blockScaler", "oran_fh_cus.blockScaler",
8424 FT_UINT8, BASE_HEX,
8425 NULL((void*)0), 0x0,
8426 "unsigned, 1 integer bit, 7 fractional bits", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8427 },
8428 { &hf_oran_compBitWidth,
8429 { "compBitWidth", "oran_fh_cus.compBitWidth",
8430 FT_UINT8, BASE_DEC,
8431 NULL((void*)0), 0xf0,
8432 "Length of I bits and length of Q bits after compression over entire PRB", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8433 },
8434 { &hf_oran_compShift,
8435 { "compShift", "oran_fh_cus.compShift",
8436 FT_UINT8, BASE_DEC,
8437 NULL((void*)0), 0x0f,
8438 "The shift applied to the entire PRB", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8439 },
8440
8441 { &hf_oran_active_beamspace_coefficient_n1,
8442 { "N1", "oran_fh_cus.activeBeamspace_Coefficient_n1",
8443 FT_BOOLEAN, 8,
8444 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x80,
8445 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8446 },
8447 { &hf_oran_active_beamspace_coefficient_n2,
8448 { "N2", "oran_fh_cus.activeBeamspace_Coefficient_n2",
8449 FT_BOOLEAN, 8,
8450 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x40,
8451 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8452 },
8453 { &hf_oran_active_beamspace_coefficient_n3,
8454 { "N3", "oran_fh_cus.activeBeamspace_Coefficient_n3",
8455 FT_BOOLEAN, 8,
8456 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x20,
8457 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8458 },
8459 { &hf_oran_active_beamspace_coefficient_n4,
8460 { "N4", "oran_fh_cus.activeBeamspace_Coefficient_n4",
8461 FT_BOOLEAN, 8,
8462 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x10,
8463 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8464 },
8465 { &hf_oran_active_beamspace_coefficient_n5,
8466 { "N5", "oran_fh_cus.activeBeamspace_Coefficient_n5",
8467 FT_BOOLEAN, 8,
8468 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x08,
8469 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8470 },
8471 { &hf_oran_active_beamspace_coefficient_n6,
8472 { "N6", "oran_fh_cus.activeBeamspace_Coefficient_n6",
8473 FT_BOOLEAN, 8,
8474 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x04,
8475 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8476 },
8477 { &hf_oran_active_beamspace_coefficient_n7,
8478 { "N7", "oran_fh_cus.activeBeamspace_Coefficient_n7",
8479 FT_BOOLEAN, 8,
8480 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x02,
8481 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8482 },
8483 { &hf_oran_active_beamspace_coefficient_n8,
8484 { "N8", "oran_fh_cus.activeBeamspace_Coefficient_n8",
8485 FT_BOOLEAN, 8,
8486 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x01,
8487 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8488 },
8489
8490 { &hf_oran_activeBeamspaceCoefficientMask,
8491 { "activeBeamspaceCoefficientMask", "oran_fh_cus.activeBeamspaceCoefficientMask",
8492 FT_UINT8, BASE_HEX,
8493 NULL((void*)0), 0xff,
8494 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8495 },
8496 { &hf_oran_activeBeamspaceCoefficientMask_bits_set,
8497 { "Array elements set", "oran_fh_cus.activeBeamspaceCoefficientMask.bits-set",
8498 FT_UINT32, BASE_DEC,
8499 NULL((void*)0), 0x0,
8500 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8501 },
8502
8503 /* Section 7.7.6.6 */
8504 { &hf_oran_se6_repetition,
8505 { "repetition", "oran_fh_cus.repetition",
8506 FT_BOOLEAN, BASE_NONE,
8507 TFS(&repetition_se6_tfs)((0 ? (const struct true_false_string*)0 : ((&repetition_se6_tfs
))))
, 0x0,
8508 "Repetition of a highest priority data section for C-Plane", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8509 },
8510 /* 7.7.20.9 */
8511 { &hf_oran_rbgSize,
8512 { "rbgSize", "oran_fh_cus.rbgSize",
8513 FT_UINT8, BASE_HEX,
8514 VALS(rbg_size_vals)((0 ? (const struct _value_string*)0 : ((rbg_size_vals)))), 0x70,
8515 "Number of PRBs of the resource block groups allocated by the bit mask", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8516 },
8517 /* 7.7.20.10 */
8518 { &hf_oran_rbgMask,
8519 { "rbgMask", "oran_fh_cus.rbgMask",
8520 FT_UINT32, BASE_HEX,
8521 NULL((void*)0), 0x0fffffff,
8522 "Each bit indicates whether a corresponding resource block group is present", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8523 },
8524 /* 7.7.6.5. Also 7.7.12.3 and 7.7.19.5 */
8525 { &hf_oran_noncontig_priority,
8526 { "priority", "oran_fh_cus.priority",
8527 FT_UINT8, BASE_HEX,
8528 VALS(priority_vals)((0 ? (const struct _value_string*)0 : ((priority_vals)))), 0xc0,
8529 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8530 },
8531
8532 /* 7.7.6.4 */
8533 { &hf_oran_symbol_mask,
8534 { "symbolMask", "oran_fh_cus.symbolMask",
8535 FT_UINT16, BASE_HEX,
8536 NULL((void*)0), 0x3fff,
8537 "Each bit indicates whether the rbgMask applies to a given symbol in the slot", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8538 },
8539 { &hf_oran_symbol_mask_s13,
8540 { "symbol 13", "oran_fh_cus.symbolMask.symbol-13",
8541 FT_BOOLEAN, 16,
8542 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x2000,
8543 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8544 },
8545 { &hf_oran_symbol_mask_s12,
8546 { "symbol 12", "oran_fh_cus.symbolMask.symbol-12",
8547 FT_BOOLEAN, 16,
8548 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x1000,
8549 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8550 },
8551 { &hf_oran_symbol_mask_s11,
8552 { "symbol 11", "oran_fh_cus.symbolMask.symbol-11",
8553 FT_BOOLEAN, 16,
8554 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0800,
8555 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8556 },
8557 { &hf_oran_symbol_mask_s10,
8558 { "symbol 10", "oran_fh_cus.symbolMask.symbol-10",
8559 FT_BOOLEAN, 16,
8560 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0400,
8561 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8562 },
8563 { &hf_oran_symbol_mask_s9,
8564 { "symbol 9", "oran_fh_cus.symbolMask.symbol-9",
8565 FT_BOOLEAN, 16,
8566 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0200,
8567 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8568 },
8569 { &hf_oran_symbol_mask_s8,
8570 { "symbol 8", "oran_fh_cus.symbolMask.symbol-8",
8571 FT_BOOLEAN, 16,
8572 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0100,
8573 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8574 },
8575 { &hf_oran_symbol_mask_s7,
8576 { "symbol 7", "oran_fh_cus.symbolMask.symbol-7",
8577 FT_BOOLEAN, 16,
8578 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0080,
8579 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8580 },
8581 { &hf_oran_symbol_mask_s6,
8582 { "symbol 6", "oran_fh_cus.symbolMask.symbol-6",
8583 FT_BOOLEAN, 16,
8584 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0040,
8585 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8586 },
8587 { &hf_oran_symbol_mask_s5,
8588 { "symbol 5", "oran_fh_cus.symbolMask.symbol-5",
8589 FT_BOOLEAN, 16,
8590 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0020,
8591 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8592 },
8593 { &hf_oran_symbol_mask_s4,
8594 { "symbol 4", "oran_fh_cus.symbolMask.symbol-4",
8595 FT_BOOLEAN, 16,
8596 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0010,
8597 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8598 },
8599 { &hf_oran_symbol_mask_s3,
8600 { "symbol 3", "oran_fh_cus.symbolMask.symbol-3",
8601 FT_BOOLEAN, 16,
8602 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0008,
8603 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8604 },
8605 { &hf_oran_symbol_mask_s2,
8606 { "symbol 2", "oran_fh_cus.symbolMask.symbol-2",
8607 FT_BOOLEAN, 16,
8608 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0004,
8609 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8610 },
8611 { &hf_oran_symbol_mask_s1,
8612 { "symbol 1", "oran_fh_cus.symbolMask.symbol-1",
8613 FT_BOOLEAN, 16,
8614 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0002,
8615 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8616 },
8617 { &hf_oran_symbol_mask_s0,
8618 { "symbol 0", "oran_fh_cus.symbolMask.symbol-0",
8619 FT_BOOLEAN, 16,
8620 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0001,
8621 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8622 },
8623
8624
8625 /* 7.7.22.2 */
8626 { &hf_oran_ack_nack_req_id,
8627 { "ackNackReqId", "oran_fh_cus.ackNackReqId",
8628 FT_UINT16, BASE_HEX,
8629 NULL((void*)0), 0x0,
8630 "Indicates the ACK/NACK request ID of a section description", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8631 },
8632
8633 /* Subtree for next 2 items */
8634 { &hf_oran_frequency_range,
8635 { "Frequency Range", "oran_fh_cus.frequencyRange",
8636 FT_STRING, BASE_NONE,
8637 NULL((void*)0), 0x0,
8638 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8639 },
8640
8641 /* 7.7.12.4 */
8642 { &hf_oran_off_start_prb,
8643 { "offStartPrb", "oran_fh_cus.offStartPrb",
8644 FT_UINT8, BASE_DEC,
8645 NULL((void*)0), 0x0,
8646 "Offset of PRB range start", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8647 },
8648 /* 7.7.12.5 */
8649 { &hf_oran_num_prb,
8650 { "numPrb", "oran_fh_cus.numPrb",
8651 FT_UINT8, BASE_DEC,
8652 NULL((void*)0), 0x0,
8653 "Number of PRBs in PRB range", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8654 },
8655
8656 /* symbolId 8.3.3.7 */
8657 { &hf_oran_symbolId,
8658 { "Symbol Identifier", "oran_fh_cus.symbolId",
8659 FT_UINT8, BASE_DEC,
8660 NULL((void*)0), 0x3f,
8661 "Identifies a symbol number within a slot", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8662 },
8663
8664 /* startPrbu 8.3.3.11 */
8665 { &hf_oran_startPrbu,
8666 { "startPrbu", "oran_fh_cus.startPrbu",
8667 FT_UINT16, BASE_DEC,
8668 NULL((void*)0), 0x03ff,
8669 "starting PRB of user plane section", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8670 },
8671
8672 /* numPrbu 8.3.3.12 */
8673 { &hf_oran_numPrbu,
8674 { "numPrbu", "oran_fh_cus.numPrbu",
8675 FT_UINT8, BASE_DEC,
8676 NULL((void*)0), 0x0,
8677 "number of PRBs per user plane section", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8678 },
8679
8680 /* 7.7.1.3 */
8681 { &hf_oran_bfwCompParam,
8682 { "bfwCompParam", "oran_fh_cus.bfwCompParam",
8683 FT_STRING, BASE_NONE,
8684 NULL((void*)0), 0x0,
8685 "Beamforming weight compression parameter", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8686 },
8687
8688 /* 6.3.3.13 */
8689 { &hf_oran_udCompHdrMeth,
8690 { "User Data Compression Method", "oran_fh_cus.udCompHdrMeth",
8691 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
8692 RVALS(ud_comp_header_meth)((0 ? (const struct _range_string*)0 : ((ud_comp_header_meth)
)))
, 0x0f,
8693 "Defines the compression method for the user data in every section in the C-Plane message", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8694 },
8695 { &hf_oran_udCompHdrMeth_pref,
8696 { "User Data Compression Method", "oran_fh_cus.udCompHdrMeth",
8697 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
8698 RVALS(ud_comp_header_meth)((0 ? (const struct _range_string*)0 : ((ud_comp_header_meth)
)))
, 0x0,
8699 "Defines the compression method for the user data in every section in the C-Plane message", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8700 },
8701 /* 8.3.3.18 */
8702 { &hf_oran_udCompLen,
8703 { "udCompLen", "oran_fh_cus.udCompLen",
8704 FT_UINT16, BASE_DEC,
8705 NULL((void*)0), 0x0,
8706 "PRB field length in octets", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8707 },
8708
8709 /* 7.5.2.10 */
8710 { &hf_oran_udCompHdrIqWidth,
8711 { "User Data IQ width", "oran_fh_cus.udCompHdrWidth",
8712 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
8713 RVALS(ud_comp_header_width)((0 ? (const struct _range_string*)0 : ((ud_comp_header_width
))))
, 0xf0,
8714 "Defines the IQ bit width for the user data in every section in the C-Plane message", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8715 },
8716 { &hf_oran_udCompHdrIqWidth_pref,
8717 { "User Data IQ width", "oran_fh_cus.udCompHdrWidth.pref",
8718 FT_UINT8, BASE_DEC,
8719 NULL((void*)0), 0x0,
8720 "IQ bit width for the user data in every section in the C-Plane message, from preference", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8721 },
8722
8723 { &hf_oran_sinrCompHdrIqWidth_pref,
8724 { "SINR IQ width", "oran_fh_cus.sinrCompHdrWidth",
8725 FT_UINT8, BASE_DEC,
8726 NULL((void*)0), 0x0,
8727 "Defines the IQ bit width for SINR data in section type 9", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8728 },
8729 { &hf_oran_sinrCompHdrMeth_pref,
8730 { "SINR Compression Method", "oran_fh_cus.sinrCompHdrMeth",
8731 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
8732 RVALS(ud_comp_header_meth)((0 ? (const struct _range_string*)0 : ((ud_comp_header_meth)
)))
, 0x0,
8733 "Defines the compression method for SINR data in section type 9", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8734 },
8735
8736 /* Section 8.3.3.15 (not always present - depends upon meth) */
8737 { &hf_oran_udCompParam,
8738 { "User Data Compression Parameter", "oran_fh_cus.udCompParam",
8739 FT_STRING, BASE_NONE,
8740 NULL((void*)0), 0x0,
8741 "Applies to whatever compression method is specified by the associated sectionID's compMeth value", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8742 },
8743 /* 8.3.3.18 */
8744 { &hf_oran_sReSMask,
8745 { "sReSMask", "oran_fh_cus.sReSMask",
8746 FT_UINT16, BASE_HEX,
8747 NULL((void*)0), 0xf0ff,
8748 "selective RE sending mask", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8749 },
8750
8751 { &hf_oran_sReSMask_re12,
8752 { "RE-12", "oran_fh_cus.sReSMask-re12",
8753 FT_BOOLEAN, 16,
8754 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x8000,
8755 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8756 },
8757 { &hf_oran_sReSMask_re11,
8758 { "RE-11", "oran_fh_cus.sReSMask-re11",
8759 FT_BOOLEAN, 16,
8760 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x4000,
8761 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8762 },
8763 { &hf_oran_sReSMask_re10,
8764 { "RE-10", "oran_fh_cus.sReSMask-re10",
8765 FT_BOOLEAN, 16,
8766 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x2000,
8767 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8768 },
8769 { &hf_oran_sReSMask_re9,
8770 { "RE-9", "oran_fh_cus.sReSMask-re9",
8771 FT_BOOLEAN, 16,
8772 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x1000,
8773 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8774 },
8775 { &hf_oran_sReSMask_re8,
8776 { "RE-8", "oran_fh_cus.sReSMask-re8",
8777 FT_BOOLEAN, 16,
8778 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0080,
8779 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8780 },
8781 { &hf_oran_sReSMask_re7,
8782 { "RE-7", "oran_fh_cus.sReSMask-re7",
8783 FT_BOOLEAN, 16,
8784 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0040,
8785 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8786 },
8787 { &hf_oran_sReSMask_re6,
8788 { "RE-6", "oran_fh_cus.sReSMask-re6",
8789 FT_BOOLEAN, 16,
8790 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0020,
8791 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8792 },
8793 { &hf_oran_sReSMask_re5,
8794 { "RE-5", "oran_fh_cus.sReSMask-re5",
8795 FT_BOOLEAN, 16,
8796 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0010,
8797 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8798 },
8799 { &hf_oran_sReSMask_re4,
8800 { "RE-4", "oran_fh_cus.sReSMask-re4",
8801 FT_BOOLEAN, 16,
8802 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0008,
8803 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8804 },
8805 { &hf_oran_sReSMask_re3,
8806 { "RE-3", "oran_fh_cus.sReSMask-re3",
8807 FT_BOOLEAN, 16,
8808 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0004,
8809 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8810 },
8811 { &hf_oran_sReSMask_re2,
8812 { "RE-2", "oran_fh_cus.sReSMask-re2",
8813 FT_BOOLEAN, 16,
8814 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0002,
8815 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8816 },
8817 { &hf_oran_sReSMask_re1,
8818 { "RE-1", "oran_fh_cus.sReSMask-re1",
8819 FT_BOOLEAN, 16,
8820 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0001,
8821 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8822 },
8823
8824 /* 8.3.3.20 */
8825 { &hf_oran_sReSMask1,
8826 { "sReSMask1", "oran_fh_cus.sReSMask1",
8827 FT_UINT16, BASE_HEX,
8828 NULL((void*)0), 0x0fff,
8829 "selective RE sending mask 1", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8830 },
8831 /* 8.3.3.21 */
8832 { &hf_oran_sReSMask2,
8833 { "sReSMask2", "oran_fh_cus.sReSMask2",
8834 FT_UINT16, BASE_HEX,
8835 NULL((void*)0), 0x0fff,
8836 "selective RE sending mask 2", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8837 },
8838
8839 { &hf_oran_sReSMask1_2_re12,
8840 { "RE-12", "oran_fh_cus.sReSMask-re12",
8841 FT_BOOLEAN, 16,
8842 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0800,
8843 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8844 },
8845 { &hf_oran_sReSMask1_2_re11,
8846 { "RE-11", "oran_fh_cus.sReSMask-re11",
8847 FT_BOOLEAN, 16,
8848 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0400,
8849 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8850 },
8851 { &hf_oran_sReSMask1_2_re10,
8852 { "RE-10", "oran_fh_cus.sReSMask-re10",
8853 FT_BOOLEAN, 16,
8854 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0200,
8855 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8856 },
8857 { &hf_oran_sReSMask1_2_re9,
8858 { "RE-9", "oran_fh_cus.sReSMask-re9",
8859 FT_BOOLEAN, 16,
8860 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0100,
8861 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8862 },
8863
8864 /* Section 6.3.3.15 */
8865 { &hf_oran_iSample,
8866 { "iSample", "oran_fh_cus.iSample",
8867 FT_FLOAT, BASE_NONE,
8868 NULL((void*)0), 0x0,
8869 "In-phase Sample value", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8870 },
8871
8872 /* Section 6.3.3.16 */
8873 { &hf_oran_qSample,
8874 { "qSample", "oran_fh_cus.qSample",
8875 FT_FLOAT, BASE_NONE,
8876 NULL((void*)0), 0x0,
8877 "Quadrature Sample value", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8878 },
8879
8880 { &hf_oran_exponent,
8881 { "Exponent", "oran_fh_cus.exponent",
8882 FT_UINT8, BASE_DEC,
8883 NULL((void*)0), 0x0f,
8884 "Exponent applicable to the I & Q mantissas", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
8885 },
8886
8887 { &hf_oran_iq_user_data,
8888 { "IQ User Data", "oran_fh_cus.iq_user_data",
8889 FT_BYTES, BASE_NONE,
8890 NULL((void*)0), 0x0,
8891 "Used for the In-phase and Quadrature sample mantissa", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
8892 },
8893
8894
8895 { &hf_oran_u_section_ul_symbol_time,
8896 { "Microseconds since first UL U-plane frame for this symbol", "oran_fh_cus.us-since-first-ul-frame",
8897 FT_UINT32, BASE_DEC,
8898 NULL((void*)0), 0x0,
8899 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
8900 },
8901 { &hf_oran_u_section_ul_symbol_frames,
8902 { "Number of UL frames sent for this symbol", "oran_fh_cus.number-ul-frames-in-symbol",
8903 FT_UINT32, BASE_DEC,
8904 NULL((void*)0), 0x0,
8905 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
8906 },
8907 { &hf_oran_u_section_ul_symbol_first_frame,
8908 { "First UL frame for this symbol", "oran_fh_cus.first-ul-frame-in-symbol",
8909 FT_FRAMENUM, BASE_NONE,
8910 FRAMENUM_TYPE(FT_FRAMENUM_NONE)((gpointer) (glong) (FT_FRAMENUM_NONE)), 0x0,
8911 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
8912 },
8913 { &hf_oran_u_section_ul_symbol_last_frame,
8914 { "Last UL frame for this symbol", "oran_fh_cus.last-ul-frame-in-symbol",
8915 FT_FRAMENUM, BASE_NONE,
8916 FRAMENUM_TYPE(FT_FRAMENUM_NONE)((gpointer) (glong) (FT_FRAMENUM_NONE)), 0x0,
8917 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
8918 },
8919
8920 { &hf_oran_c_eAxC_ID,
8921 { "c_eAxC_ID", "oran_fh_cus.c_eaxc_id",
8922 FT_STRING, BASE_NONE,
8923 NULL((void*)0), 0x0,
8924 "This is a calculated field for the c_eAxC ID, which identifies the message stream", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
8925 },
8926
8927 { &hf_oran_refa,
8928 { "RefA", "oran_fh_cus.refa",
8929 FT_STRING, BASE_NONE,
8930 NULL((void*)0), 0x0,
8931 "This is a calculated field for the RefA ID, which provides a reference in time", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
8932 },
8933
8934
8935 /* Section 7.5.2.15 */
8936 { &hf_oran_ciCompHdr,
8937 { "ciCompHdr", "oran_fh_cus.ciCompHdr",
8938 FT_STRING, BASE_NONE,
8939 NULL((void*)0), 0x0,
8940 "Channel Information Compression Header", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8941 },
8942 { &hf_oran_ciCompHdrMeth,
8943 { "User Data Compression Method", "oran_fh_cus.ciCompHdrMeth",
8944 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
8945 RVALS(ud_comp_header_meth)((0 ? (const struct _range_string*)0 : ((ud_comp_header_meth)
)))
, 0x0e,
8946 "Compression method for Channel Information", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8947 },
8948 { &hf_oran_ciCompHdrIqWidth,
8949 { "User Data IQ width", "oran_fh_cus.ciCompHdrWidth",
8950 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
8951 RVALS(ud_comp_header_width)((0 ? (const struct _range_string*)0 : ((ud_comp_header_width
))))
, 0xf0,
8952 "IQ bit width for Channel Information", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8953 },
8954 { &hf_oran_ciCompOpt,
8955 { "ciCompOpt", "oran_fh_cus.ciCompOpt",
8956 FT_UINT8, BASE_DEC,
8957 VALS(ci_comp_opt_vals)((0 ? (const struct _value_string*)0 : ((ci_comp_opt_vals)))), 0x01,
8958 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
8959 },
8960
8961 /* 7.7.11.7 */
8962 { &hf_oran_disable_bfws,
8963 { "disableBFWs", "oran_fh_cus.disableBFWs",
8964 FT_BOOLEAN, 8,
8965 NULL((void*)0), 0x80,
8966 "Indicate if BFWs under section extension are disabled", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
8967 },
8968 /* 7.7.11.8 */
8969 { &hf_oran_rad,
8970 { "RAD", "oran_fh_cus.rad",
8971 FT_BOOLEAN, 8,
8972 NULL((void*)0), 0x40,
8973 "Reset After PRB Discontinuity", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
8974 },
8975 /* 7.7.11.4 */
8976 { &hf_oran_num_bund_prbs,
8977 { "numBundPrb", "oran_fh_cus.numBundPrb",
8978 FT_UINT8, BASE_DEC,
8979 NULL((void*)0), 0x0,
8980 "Number of bundled PRBs per BFWs", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
8981 },
8982 { &hf_oran_beam_id,
8983 { "beamId", "oran_fh_cus.beamId",
8984 FT_UINT16, BASE_DEC,
8985 NULL((void*)0), 0x7fff,
8986 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
8987 },
8988 { &hf_oran_num_weights_per_bundle,
8989 { "Num weights per bundle", "oran_fh_cus.num_weights_per_bundle",
8990 FT_UINT16, BASE_DEC,
8991 NULL((void*)0), 0x0,
8992 "From dissector preference", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
8993 },
8994
8995 { &hf_oran_samples_prb,
8996 {"PRB", "oran_fh_cus.prb",
8997 FT_STRING, BASE_NONE,
8998 NULL((void*)0), 0x0,
8999 "Grouping of samples for a particular Physical Resource Block", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9000 },
9001
9002 /* 7.5.3.13 */
9003 { &hf_oran_ciSample,
9004 { "ciSample", "oran_fh_cus.ciSample",
9005 FT_STRING, BASE_NONE,
9006 NULL((void*)0), 0x0,
9007 "Sample (I and Q values)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9008 },
9009 { &hf_oran_ciIsample,
9010 { "ciIsample", "oran_fh_cus.ciISample",
9011 FT_FLOAT, BASE_NONE,
9012 NULL((void*)0), 0x0,
9013 "Channel information complex value - I part", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9014 },
9015 { &hf_oran_ciQsample,
9016 { "ciQsample", "oran_fh_cus.ciQSample",
9017 FT_FLOAT, BASE_NONE,
9018 NULL((void*)0), 0x0,
9019 "Channel information complex value - Q part", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9020 },
9021
9022 /* 7.7.10.2 */
9023 { &hf_oran_beamGroupType,
9024 { "beamGroupType", "oran_fh_cus.beamGroupType",
9025 FT_UINT8, BASE_DEC,
9026 VALS(beam_group_type_vals)((0 ? (const struct _value_string*)0 : ((beam_group_type_vals
))))
, 0xc0,
9027 "The type of beam grouping", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9028 },
9029 /* 7.7.10.3 */
9030 { &hf_oran_numPortc,
9031 { "numPortc", "oran_fh_cus.numPortc",
9032 FT_UINT8, BASE_DEC,
9033 NULL((void*)0), 0x3f,
9034 "The number of eAxC ports", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9035 },
9036
9037 /* 7.7.4.2 (1 bit) */
9038 { &hf_oran_csf,
9039 { "csf", "oran_fh_cus.csf",
9040 FT_BOOLEAN, BASE_NONE,
9041 NULL((void*)0), 0x0,
9042 "constellation shift flag", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9043 },
9044 /* 7.7.4.3 */
9045 { &hf_oran_modcompscaler,
9046 { "modCompScaler", "oran_fh_cus.modcompscaler",
9047 FT_UINT16, BASE_DEC,
9048 NULL((void*)0), 0x7fff,
9049 "modulation compression scaler value", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9050 },
9051
9052 /* 7.7.5.1 */
9053 { &hf_oran_modcomp_param_set,
9054 { "Set", "oran_fh_cus.modcomp-param-set",
9055 FT_STRING, BASE_NONE,
9056 NULL((void*)0), 0x0,
9057 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9058 },
9059
9060
9061
9062 /* mcScaleReMask 7.7.5.2 (12 bits) */
9063
9064 /* First entry (starts with msb within byte) */
9065 { &hf_oran_mc_scale_re_mask_re1,
9066 { "RE 1", "oran_fh_cus.mcscalermask-RE1",
9067 FT_BOOLEAN, 16,
9068 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x8000,
9069 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9070 },
9071 { &hf_oran_mc_scale_re_mask_re2,
9072 { "RE 2", "oran_fh_cus.mcscalermask-RE2",
9073 FT_BOOLEAN, 16,
9074 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x4000,
9075 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9076 },
9077 { &hf_oran_mc_scale_re_mask_re3,
9078 { "RE 3", "oran_fh_cus.mcscalermask-RE3",
9079 FT_BOOLEAN, 16,
9080 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x2000,
9081 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9082 },
9083 { &hf_oran_mc_scale_re_mask_re4,
9084 { "RE 4", "oran_fh_cus.mcscalermask-RE4",
9085 FT_BOOLEAN, 16,
9086 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x1000,
9087 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9088 },
9089 { &hf_oran_mc_scale_re_mask_re5,
9090 { "RE 5", "oran_fh_cus.mcscalermask-RE5",
9091 FT_BOOLEAN, 16,
9092 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0800,
9093 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9094 },
9095 { &hf_oran_mc_scale_re_mask_re6,
9096 { "RE 6", "oran_fh_cus.mcscalermask-RE6",
9097 FT_BOOLEAN, 16,
9098 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0400,
9099 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9100 },
9101 { &hf_oran_mc_scale_re_mask_re7,
9102 { "RE 7", "oran_fh_cus.mcscalermask-RE7",
9103 FT_BOOLEAN, 16,
9104 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0200,
9105 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9106 },
9107 { &hf_oran_mc_scale_re_mask_re8,
9108 { "RE 8", "oran_fh_cus.mcscalermask-RE8",
9109 FT_BOOLEAN, 16,
9110 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0100,
9111 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9112 },
9113 { &hf_oran_mc_scale_re_mask_re9,
9114 { "RE 9", "oran_fh_cus.mcscalermask-RE9",
9115 FT_BOOLEAN, 16,
9116 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0080,
9117 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9118 },
9119 { &hf_oran_mc_scale_re_mask_re10,
9120 { "RE 10", "oran_fh_cus.mcscalermask-RE10",
9121 FT_BOOLEAN, 16,
9122 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0040,
9123 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9124 },
9125 { &hf_oran_mc_scale_re_mask_re11,
9126 { "RE 11", "oran_fh_cus.mcscalermask-RE11",
9127 FT_BOOLEAN, 16,
9128 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0020,
9129 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9130 },
9131 { &hf_oran_mc_scale_re_mask_re12,
9132 { "RE 12", "oran_fh_cus.mcscalermask-RE12",
9133 FT_BOOLEAN, 16,
9134 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0010,
9135 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9136 },
9137
9138 /* Even tries entry (starts with 5th bit within byte) */
9139 { &hf_oran_mc_scale_re_mask_re1_even,
9140 { "RE 1", "oran_fh_cus.mcscalermask-RE1",
9141 FT_BOOLEAN, 16,
9142 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0800,
9143 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9144 },
9145 { &hf_oran_mc_scale_re_mask_re2_even,
9146 { "RE 2", "oran_fh_cus.mcscalermask-RE2",
9147 FT_BOOLEAN, 16,
9148 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0400,
9149 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9150 },
9151 { &hf_oran_mc_scale_re_mask_re3_even,
9152 { "RE 3", "oran_fh_cus.mcscalermask-RE3",
9153 FT_BOOLEAN, 16,
9154 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0200,
9155 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9156 },
9157 { &hf_oran_mc_scale_re_mask_re4_even,
9158 { "RE 4", "oran_fh_cus.mcscalermask-RE4",
9159 FT_BOOLEAN, 16,
9160 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0100,
9161 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9162 },
9163 { &hf_oran_mc_scale_re_mask_re5_even,
9164 { "RE 5", "oran_fh_cus.mcscalermask-RE5",
9165 FT_BOOLEAN, 16,
9166 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0080,
9167 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9168 },
9169 { &hf_oran_mc_scale_re_mask_re6_even,
9170 { "RE 6", "oran_fh_cus.mcscalermask-RE6",
9171 FT_BOOLEAN, 16,
9172 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0040,
9173 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9174 },
9175 { &hf_oran_mc_scale_re_mask_re7_even,
9176 { "RE 7", "oran_fh_cus.mcscalermask-RE7",
9177 FT_BOOLEAN, 16,
9178 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0020,
9179 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9180 },
9181 { &hf_oran_mc_scale_re_mask_re8_even,
9182 { "RE 8", "oran_fh_cus.mcscalermask-RE8",
9183 FT_BOOLEAN, 16,
9184 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0010,
9185 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9186 },
9187 { &hf_oran_mc_scale_re_mask_re9_even,
9188 { "RE 9", "oran_fh_cus.mcscalermask-RE9",
9189 FT_BOOLEAN, 16,
9190 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0008,
9191 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9192 },
9193 { &hf_oran_mc_scale_re_mask_re10_even,
9194 { "RE 10", "oran_fh_cus.mcscalermask-RE10",
9195 FT_BOOLEAN, 16,
9196 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0004,
9197 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9198 },
9199 { &hf_oran_mc_scale_re_mask_re11_even,
9200 { "RE 11", "oran_fh_cus.mcscalermask-RE11",
9201 FT_BOOLEAN, 16,
9202 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0002,
9203 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9204 },
9205 { &hf_oran_mc_scale_re_mask_re12_even,
9206 { "RE 12", "oran_fh_cus.mcscalermask-RE12",
9207 FT_BOOLEAN, 16,
9208 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0001,
9209 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9210 },
9211
9212 { &hf_oran_mc_scale_re_mask,
9213 { "mcScaleReMask", "oran_fh_cus.mcscaleremask",
9214 FT_UINT16, BASE_HEX,
9215 NULL((void*)0), 0xfff0,
9216 "modulation compression power scale RE mask", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9217 },
9218 { &hf_oran_mc_scale_re_mask_even,
9219 { "mcScaleReMask", "oran_fh_cus.mcscaleremask",
9220 FT_UINT16, BASE_HEX,
9221 NULL((void*)0), 0x0fff,
9222 "modulation compression power scale RE mask", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9223 },
9224
9225 /* mcScaleOffset 7.7.5.4 (15 bits) */
9226 { &hf_oran_mc_scale_offset,
9227 { "mcScaleOffset", "oran_fh_cus.mcscaleoffset",
9228 FT_UINT24, BASE_DEC,
9229 NULL((void*)0), 0x0,
9230 "scaling value for modulation compression", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9231 },
9232 /* eAxCmask (7.7.7.2) */
9233 { &hf_oran_eAxC_mask,
9234 { "eAxC Mask", "oran_fh_cus.eaxcmask",
9235 FT_UINT16, BASE_HEX,
9236 NULL((void*)0), 0xffff,
9237 "Which eAxC_ID values the C-Plane message applies to", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9238 },
9239 /* technology (interface name) 7.7.9.2 */
9240 { &hf_oran_technology,
9241 { "Technology", "oran_fh_cus.technology",
9242 FT_UINT8, BASE_DEC,
9243 VALS(interface_name_vals)((0 ? (const struct _value_string*)0 : ((interface_name_vals)
)))
, 0x0,
9244 "Interface name (that C-PLane section applies to)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9245 },
9246 /* Exttype 14 (7.7.14.2) */
9247 { &hf_oran_nullLayerInd,
9248 { "nullLayerInd", "oran_fh_cus.nulllayerind",
9249 FT_BOOLEAN, BASE_NONE,
9250 NULL((void*)0), 0x0,
9251 "Whether corresponding layer is nulling-layer or not", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9252 },
9253
9254 /* Exttype 19 */
9255 /* 7.7.19.3 */
9256 { &hf_oran_se19_repetition,
9257 { "repetition", "oran_fh_cus.repetition",
9258 FT_BOOLEAN, BASE_NONE,
9259 TFS(&repetition_se19_tfs)((0 ? (const struct true_false_string*)0 : ((&repetition_se19_tfs
))))
, 0x0,
9260 "repeat port info flag", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9261 },
9262 /* 7.7.19.8 */
9263 /* TODO: break down into each RE as done for 7.5.3.5 ? */
9264 { &hf_oran_portReMask,
9265 { "portReMask", "oran_fh_cus.portReMask",
9266 FT_BOOLEAN, 16,
9267 TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, 0x0fff,
9268 "RE bitmask per port", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9269 },
9270 /* 7.7.19.9 */
9271 { &hf_oran_portSymbolMask,
9272 { "portSymbolMask", "oran_fh_cus.portSymbolMask",
9273 FT_BOOLEAN, 16,
9274 TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, 0x3fff,
9275 "Symbol bitmask port port", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9276 },
9277
9278 { &hf_oran_ext19_port,
9279 {"Port", "oran_fh_cus.ext19.port",
9280 FT_STRING, BASE_NONE,
9281 NULL((void*)0), 0x0,
9282 "Entry for a given port in ext19", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9283 },
9284
9285 /* Ext 13 */
9286 { &hf_oran_prb_allocation,
9287 {"PRB allocation", "oran_fh_cus.prb-allocation",
9288 FT_STRING, BASE_NONE,
9289 NULL((void*)0), 0x0,
9290 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9291 },
9292 /* 7.7.13.2 */
9293 { &hf_oran_nextSymbolId,
9294 { "nextSymbolId", "oran_fh_cus.nextSymbolId",
9295 FT_UINT8, BASE_DEC,
9296 NULL((void*)0), 0x3c,
9297 "offset of PRB range start", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9298 },
9299 /* 7.7.13.3 */
9300 { &hf_oran_nextStartPrbc,
9301 { "nextStartPrbc", "oran_fh_cus.nextStartPrbc",
9302 FT_UINT16, BASE_DEC,
9303 NULL((void*)0), 0x03ff,
9304 "number of PRBs in PRB range", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9305 },
9306
9307 /* Puncturing patters as appears in SE 20 */
9308 { &hf_oran_puncPattern,
9309 { "puncPattern", "oran_fh_cus.puncPattern",
9310 FT_STRING, BASE_NONE,
9311 NULL((void*)0), 0x0,
9312 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9313 },
9314
9315 /* 7.7.20.2 numPuncPatterns */
9316 { &hf_oran_numPuncPatterns,
9317 { "numPuncPatterns", "oran_fh_cus.numPuncPatterns",
9318 FT_UINT8, BASE_DEC,
9319 NULL((void*)0), 0x0,
9320 "number of puncturing patterns", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9321 },
9322 /* 7.7.20.3 symbolMask */
9323 { &hf_oran_symbolMask_ext20,
9324 { "symbolMask", "oran_fh_cus.symbolMask",
9325 FT_UINT16, BASE_HEX,
9326 NULL((void*)0), 0xfffc,
9327 "Bitmask where each bit indicates the symbols associated with the puncturing pattern", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9328 },
9329 /* 7.7.20.4 startPuncPrb */
9330 { &hf_oran_startPuncPrb,
9331 { "startPuncPrb", "oran_fh_cus.startPuncPrb",
9332 FT_UINT16, BASE_DEC,
9333 NULL((void*)0), 0x03ff,
9334 "starting PRB to which one puncturing pattern applies", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9335 },
9336 /* 7.7.20.5 numPuncPrb */
9337 { &hf_oran_numPuncPrb,
9338 { "numPuncPrb", "oran_fh_cus.numPuncPrb",
9339 FT_UINT8, BASE_DEC,
9340 NULL((void*)0), 0x0,
9341 "the number of PRBs of the puncturing pattern", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9342 },
9343 /* 7.7.20.6 puncReMask */
9344 { &hf_oran_puncReMask,
9345 { "puncReMask", "oran_fh_cus.puncReMask",
9346 FT_UINT16, BASE_DEC,
9347 NULL((void*)0), 0xffc0,
9348 "puncturing pattern RE mask", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9349 },
9350 /* 7.7.20.12 multiSDScope */
9351 { &hf_oran_multiSDScope,
9352 { "multiSDScope", "oran_fh_cus.multiSDScope",
9353 FT_BOOLEAN, 8,
9354 TFS(&multi_sd_scope_tfs)((0 ? (const struct true_false_string*)0 : ((&multi_sd_scope_tfs
))))
, 0x02,
9355 "multiple section description scope flag", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9356 },
9357 /* 7.7.20.4 rbgIncl */
9358 { &hf_oran_RbgIncl,
9359 { "rbgIncl", "oran_fh_cus.rbgIncl",
9360 FT_BOOLEAN, 8,
9361 NULL((void*)0), 0x01,
9362 "rbg included flag", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9363 },
9364
9365 /* 7.7.21.2 ciPrbGroupSize */
9366 { &hf_oran_ci_prb_group_size,
9367 { "ciPrbGroupSize", "oran_fh_cus.ciPrbGroupSize",
9368 FT_UINT8, BASE_DEC,
9369 NULL((void*)0), 0x0,
9370 "channel information PRB group size", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9371 },
9372 /* 7.21.3 */
9373 { &hf_oran_prg_size_st5,
9374 { "prgSize", "oran_fh_cus.prgSize",
9375 FT_UINT8, BASE_DEC,
9376 VALS(prg_size_st5_vals)((0 ? (const struct _value_string*)0 : ((prg_size_st5_vals)))
)
, 0x03,
9377 "precoding resource block group size", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9378 },
9379 { &hf_oran_prg_size_st6,
9380 { "prgSize", "oran_fh_cus.prgSize",
9381 FT_UINT8, BASE_DEC,
9382 VALS(prg_size_st6_vals)((0 ? (const struct _value_string*)0 : ((prg_size_st6_vals)))
)
, 0x03,
9383 "precoding resource block group size", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9384 },
9385
9386 /* 7.7.17.2 numUeID */
9387 { &hf_oran_num_ueid,
9388 { "numUeID", "oran_fh_cus.numUeID",
9389 FT_UINT8, BASE_DEC,
9390 NULL((void*)0), 0x0,
9391 "number of ueIDs per user", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9392 },
9393
9394 /* 7.7.16.2 antMask */
9395 { &hf_oran_antMask,
9396 { "antMask", "oran_fh_cus.antMask",
9397 FT_UINT64, BASE_HEX,
9398 NULL((void*)0), 0xffffffffffffffff,
9399 "indices of antennas to be pre-combined per RX endpoint", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9400 },
9401
9402 /* 7.7.18.2 transmissionWindowOffset */
9403 { &hf_oran_transmissionWindowOffset,
9404 { "transmissionWindowOffset", "oran_fh_cus.transmissionWindowOffset",
9405 FT_UINT16, BASE_DEC,
9406 NULL((void*)0), 0x0,
9407 "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-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9408 },
9409 /* 7.7.18.3 transmissionWindowSize */
9410 { &hf_oran_transmissionWindowSize,
9411 { "transmissionWindowSize", "oran_fh_cus.transmissionWindowSize",
9412 FT_UINT16, BASE_DEC,
9413 NULL((void*)0), 0x3fff,
9414 "size of the transmission window in resolution µs", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9415 },
9416 /* 7.7.18.4 toT */
9417 { &hf_oran_toT,
9418 { "toT", "oran_fh_cus.toT",
9419 FT_UINT8, BASE_DEC,
9420 VALS(type_of_transmission_vals)((0 ? (const struct _value_string*)0 : ((type_of_transmission_vals
))))
, 0x03,
9421 "type of transmission", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9422 },
9423
9424 /* 7.7.2.2 bfaCompHdr */
9425 { &hf_oran_bfaCompHdr,
9426 { "bfaCompHdr", "oran_fh_cus.bfaCompHdr",
9427 FT_STRING, BASE_NONE,
9428 NULL((void*)0), 0x0,
9429 "beamforming attributes compression header", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9430 },
9431 /* 7.7.2.2-2: bfAzPtWidth */
9432 { &hf_oran_bfAzPtWidth,
9433 { "bfAzPtWidth", "oran_fh_cus.bfAzPtWidth",
9434 FT_UINT8, BASE_DEC,
9435 VALS(bfa_bw_vals)((0 ? (const struct _value_string*)0 : ((bfa_bw_vals)))), 0x38,
9436 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9437 },
9438 /* 7.7.2.2-3: bfZePtWidth */
9439 { &hf_oran_bfZePtWidth,
9440 { "bfZePtWidth", "oran_fh_cus.bfZePtWidth",
9441 FT_UINT8, BASE_DEC,
9442 VALS(bfa_bw_vals)((0 ? (const struct _value_string*)0 : ((bfa_bw_vals)))), 0x07,
9443 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9444 },
9445 /* 7.7.2.2-4: bfAz3ddWidth */
9446 { &hf_oran_bfAz3ddWidth,
9447 { "bfAz3ddWidth", "oran_fh_cus.bfAz3ddWidth",
9448 FT_UINT8, BASE_DEC,
9449 VALS(bfa_bw_vals)((0 ? (const struct _value_string*)0 : ((bfa_bw_vals)))), 0x38,
9450 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9451 },
9452 /* 7.7.2.2-5: bfZe3ddWidth */
9453 { &hf_oran_bfZe3ddWidth,
9454 { "bfZe3ddWidth", "oran_fh_cus.bfZe3ddWidth",
9455 FT_UINT8, BASE_DEC,
9456 VALS(bfa_bw_vals)((0 ? (const struct _value_string*)0 : ((bfa_bw_vals)))), 0x07,
9457 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9458 },
9459
9460 /* 7.7.2.3 bfAzPt */
9461 { &hf_oran_bfAzPt,
9462 { "bfAzPt", "oran_fh_cus.bfAzPt",
9463 FT_UINT8, BASE_DEC,
9464 NULL((void*)0), 0x0,
9465 "beamforming azimuth pointing parameter", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9466 },
9467 /* 7.7.2.4 bfZePt */
9468 { &hf_oran_bfZePt,
9469 { "bfZePt", "oran_fh_cus.bfZePt",
9470 FT_UINT8, BASE_DEC,
9471 NULL((void*)0), 0x0,
9472 "beamforming zenith pointing parameter", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9473 },
9474 /* 7.7.2.5 bfAz3dd */
9475 { &hf_oran_bfAz3dd,
9476 { "bfAz3dd", "oran_fh_cus.bfAz3dd",
9477 FT_UINT8, BASE_DEC,
9478 NULL((void*)0), 0x0,
9479 "beamforming azimuth beamwidth parameter", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9480 },
9481 /* 7.7.2.6 bfZe3dd */
9482 { &hf_oran_bfZe3dd,
9483 { "bfZe3dd", "oran_fh_cus.bfZe3dd",
9484 FT_UINT8, BASE_DEC,
9485 NULL((void*)0), 0x0,
9486 "beamforming zenith beamwidth parameter", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9487 },
9488
9489 /* 7.7.2.7 bfAzSl */
9490 { &hf_oran_bfAzSl,
9491 { "bfAzSl", "oran_fh_cus.bfAzSl",
9492 FT_UINT8, BASE_DEC,
9493 VALS(sidelobe_suppression_vals)((0 ? (const struct _value_string*)0 : ((sidelobe_suppression_vals
))))
, 0x38,
9494 "beamforming azimuth sidelobe parameter", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9495 },
9496 /* 7.7.2.8 bfZeSl */
9497 { &hf_oran_bfZeSl,
9498 { "bfZeSl", "oran_fh_cus.bfZeSl",
9499 FT_UINT8, BASE_DEC,
9500 VALS(sidelobe_suppression_vals)((0 ? (const struct _value_string*)0 : ((sidelobe_suppression_vals
))))
, 0x07,
9501 "beamforming zenith sidelobe parameter", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9502 },
9503
9504 /* 7.5.2.17 */
9505 { &hf_oran_cmd_scope,
9506 { "cmdScope", "oran_fh_cus.cmdScope",
9507 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
9508 RVALS(cmd_scope_vals)((0 ? (const struct _range_string*)0 : ((cmd_scope_vals)))), 0x0f,
9509 "command scope", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9510 },
9511 /* 7.5.2.18 */
9512 { &hf_oran_number_of_st4_cmds,
9513 { "numberOfST4Cmds", "oran_fh_cus.numberOfST4Cmds",
9514 FT_UINT8, BASE_DEC,
9515 NULL((void*)0), 0x0,
9516 "Number of Section Type 4 commands", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9517 },
9518
9519 { &hf_oran_st4_cmd_header,
9520 { "Command common header", "oran_fh_cus.st4CmdCommonHeader",
9521 FT_STRING, BASE_NONE,
9522 NULL((void*)0), 0x0,
9523 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9524 },
9525
9526 /* 7.5.3.38 */
9527 { &hf_oran_st4_cmd_type,
9528 { "st4CmdType", "oran_fh_cus.st4CmdType",
9529 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
9530 RVALS(st4_cmd_type_vals)((0 ? (const struct _range_string*)0 : ((st4_cmd_type_vals)))
)
, 0x0,
9531 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9532 },
9533 /* 7.5.3.39 */
9534 { &hf_oran_st4_cmd_len,
9535 { "st4CmdLen", "oran_fh_cus.st4CmdLen",
9536 FT_UINT16, BASE_DEC,
9537 NULL((void*)0), 0x0,
9538 "Length of command in 32-bit words", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9539 },
9540 /* 7.5.3.40 */
9541 { &hf_oran_st4_cmd_num_slots,
9542 { "numSlots", "oran_fh_cus.st4NumSlots",
9543 FT_UINT8, BASE_DEC,
9544 NULL((void*)0), 0x0,
9545 "Contiguous slots for which command is applicable", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9546 },
9547 /* 7.5.3.41 */
9548 { &hf_oran_st4_cmd_ack_nack_req_id,
9549 { "ackNackReqId", "oran_fh_cus.ackNackReqId",
9550 FT_UINT16, BASE_DEC,
9551 NULL((void*)0), 0x0,
9552 "ACK/NACK Request Id", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9553 },
9554
9555 { &hf_oran_st4_cmd,
9556 { "Command", "oran_fh_cus.st4Cmd",
9557 FT_STRING, BASE_NONE,
9558 NULL((void*)0), 0x0,
9559 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9560 },
9561
9562 /* 7.5.3.52 */
9563 { &hf_oran_sleepmode_trx,
9564 { "sleepMode", "oran_fh_cus.sleepMode",
9565 FT_UINT8, BASE_HEX,
9566 VALS(sleep_mode_trx_vals)((0 ? (const struct _value_string*)0 : ((sleep_mode_trx_vals)
)))
, 0x03,
9567 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9568 },
9569 { &hf_oran_sleepmode_asm,
9570 { "sleepMode", "oran_fh_cus.sleepMode",
9571 FT_UINT8, BASE_HEX,
9572 VALS(sleep_mode_asm_vals)((0 ? (const struct _value_string*)0 : ((sleep_mode_asm_vals)
)))
, 0x03,
9573 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9574 },
9575
9576 /* 7.5.3.51 */
9577 { &hf_oran_log2maskbits,
9578 { "log2MaskBits", "oran_fh_cus.log2MaskBits",
9579 FT_UINT8, BASE_HEX,
9580 VALS(log2maskbits_vals)((0 ? (const struct _value_string*)0 : ((log2maskbits_vals)))
)
, 0x3c,
9581 "Number of bits to appear in antMask", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9582 },
9583 /* 7.5.3.53 */
9584 { &hf_oran_num_slots_ext,
9585 { "numSlotsExt", "oran_fh_cus.numSlotsExt",
9586 FT_UINT24, BASE_HEX,
9587 NULL((void*)0), 0x0fffff,
9588 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9589 },
9590 /* 7.5.3.54 */
9591 { &hf_oran_antMask_trx_control,
9592 { "antMask", "oran_fh_cus.trxControl.antMask",
9593 FT_BYTES, BASE_NONE,
9594 NULL((void*)0), 0x0,
9595 "which antennas should sleep or wake-up", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9596 },
9597 /* 7.5.3.55 */
9598 { &hf_oran_ready,
9599 { "ready", "oran_fh_cus.ready",
9600 FT_BOOLEAN, 8,
9601 TFS(&ready_tfs)((0 ? (const struct true_false_string*)0 : ((&ready_tfs))
))
, 0x01,
9602 "wake-up ready indicator", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9603 },
9604 /* 7.5.3.34 */
9605 { &hf_oran_number_of_acks,
9606 { "numberOfAcks", "oran_fh_cus.numberOfAcks",
9607 FT_UINT8, BASE_DEC,
9608 NULL((void*)0), 0x0,
9609 "number of ACKs for one eAxC_ID", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9610 },
9611 /* 7.5.3.35 */
9612 { &hf_oran_number_of_nacks,
9613 { "numberOfNacks", "oran_fh_cus.numberOfNacks",
9614 FT_UINT8, BASE_DEC,
9615 NULL((void*)0), 0x0,
9616 "number of NACKs for one eAxC_ID", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9617 },
9618 /* 7.5.3.36 */
9619 { &hf_oran_ackid,
9620 { "ackId", "oran_fh_cus.ackId",
9621 FT_UINT16, BASE_DEC,
9622 NULL((void*)0), 0x0,
9623 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9624 },
9625 /* 7.5.3.37 */
9626 { &hf_oran_nackid,
9627 { "nackId", "oran_fh_cus.nackId",
9628 FT_UINT16, BASE_DEC,
9629 NULL((void*)0), 0x0,
9630 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9631 },
9632
9633 /* Links between acknack requests & responses */
9634 { &hf_oran_acknack_request_frame,
9635 { "Request Frame", "oran_fh_cus.ackNackId.request-frame",
9636 FT_FRAMENUM, BASE_NONE,
9637 FRAMENUM_TYPE(FT_FRAMENUM_REQUEST)((gpointer) (glong) (FT_FRAMENUM_REQUEST)), 0x0,
9638 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9639 },
9640 { &hf_oran_acknack_request_time,
9641 { "Time since request in ms", "oran_fh_cus.ackNackId.time-since-request",
9642 FT_UINT32, BASE_DEC,
9643 NULL((void*)0), 0x0,
9644 "Time between request and response", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9645 },
9646 { &hf_oran_acknack_request_type,
9647 { "Request Type", "oran_fh_cus.ackNackId.request-type",
9648 FT_UINT32, BASE_DEC,
9649 VALS(acknack_type_vals)((0 ? (const struct _value_string*)0 : ((acknack_type_vals)))
)
, 0x0,
9650 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9651 },
9652 { &hf_oran_acknack_response_frame,
9653 { "Response Frame", "oran_fh_cus.ackNackId.response-frame",
9654 FT_FRAMENUM, BASE_NONE,
9655 FRAMENUM_TYPE(FT_FRAMENUM_RESPONSE)((gpointer) (glong) (FT_FRAMENUM_RESPONSE)), 0x0,
9656 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9657 },
9658 { &hf_oran_acknack_response_time,
9659 { "Time to response in ms", "oran_fh_cus.ackNackId.time-to-response",
9660 FT_UINT32, BASE_DEC,
9661 NULL((void*)0), 0x0,
9662 "Time between request and response", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9663 },
9664
9665 /* 7.5.3.43 */
9666 { &hf_oran_disable_tdbfns,
9667 { "disableTDBFNs", "oran_fh_cus.disableTDBFNs",
9668 FT_BOOLEAN, 8,
9669 TFS(&disable_tdbfns_tfs)((0 ? (const struct true_false_string*)0 : ((&disable_tdbfns_tfs
))))
, 0x80,
9670 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9671 },
9672
9673 /* 7.5.3.44 */
9674 { &hf_oran_td_beam_group,
9675 { "tdBeamGrp", "oran_fh_cus.tdBeamGrp",
9676 FT_UINT16, BASE_HEX,
9677 NULL((void*)0), 0x7fff,
9678 "Applies to symbolMask in command header", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9679 },
9680 /* 7.5.3.43 */
9681 { &hf_oran_disable_tdbfws,
9682 { "disableTDBFWs", "oran_fh_cus.disableTDBFWs",
9683 FT_BOOLEAN, 8,
9684 TFS(&beam_numbers_included_tfs)((0 ? (const struct true_false_string*)0 : ((&beam_numbers_included_tfs
))))
, 0x80,
9685 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9686 },
9687
9688 /* 7.5.3.56 */
9689 { &hf_oran_td_beam_num,
9690 { "tdBeamNum", "oran_fh_cus.tdBeamNum",
9691 FT_UINT16, BASE_HEX,
9692 NULL((void*)0), 0x7fff,
9693 "time-domain beam number", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9694 },
9695
9696 /* 7.5.3.49 */
9697 { &hf_oran_dir_pattern,
9698 { "dirPattern", "oran_fh_cus.dirPattern",
9699 FT_BOOLEAN, 16,
9700 TFS(&symbol_direction_tfs)((0 ? (const struct true_false_string*)0 : ((&symbol_direction_tfs
))))
, 0x3fff,
9701 "symbol data direction (gNB Tx/Rx) pattern", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9702 },
9703 /* 7.5.3.50 */
9704 { &hf_oran_guard_pattern,
9705 { "guardPattern", "oran_fh_cus.guardPattern",
9706 FT_BOOLEAN, 16,
9707 TFS(&symbol_guard_tfs)((0 ? (const struct true_false_string*)0 : ((&symbol_guard_tfs
))))
, 0x3fff,
9708 "guard pattern bitmask", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9709 },
9710
9711 /* For convenient filtering */
9712 { &hf_oran_cplane,
9713 { "C-Plane", "oran_fh_cus.c-plane",
9714 FT_NONE, BASE_NONE,
9715 NULL((void*)0), 0x0,
9716 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9717 },
9718 { &hf_oran_uplane,
9719 { "U-Plane", "oran_fh_cus.u-plane",
9720 FT_NONE, BASE_NONE,
9721 NULL((void*)0), 0x0,
9722 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9723 },
9724 { &hf_oran_bf,
9725 { "BeamForming", "oran_fh_cus.bf",
9726 FT_NONE, BASE_NONE,
9727 NULL((void*)0), 0x0,
9728 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9729 },
9730 { &hf_oran_zero_prb,
9731 { "Zero PRB", "oran_fh_cus.zero-prb",
9732 FT_NONE, BASE_NONE,
9733 NULL((void*)0), 0x0,
9734 "All of the REs in this PRB are zero", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9735 },
9736 { &hf_oran_nonzero_prb,
9737 { "Non-Zero PRB", "oran_fh_cus.nonzero-prb",
9738 FT_NONE, BASE_NONE,
9739 NULL((void*)0), 0x0,
9740 "Not all of the REs in this PRB are zero", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9741 },
9742 { &hf_oran_bundle_weights_all_zero,
9743 { "Bundle Weights all zero", "oran_fh_cus.zero-bundle",
9744 FT_NONE, BASE_NONE,
9745 NULL((void*)0), 0x0,
9746 "All of the weights in a bundle are zero", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9747 },
9748
9749
9750 /* 5.1.3.2.7 */
9751 { &hf_oran_ecpri_pcid,
9752 { "ecpriPcid", "oran_fh_cus.ecpriPcid",
9753 FT_NONE, BASE_NONE,
9754 NULL((void*)0), 0x0,
9755 "IQ data transfer message series identifier", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9756 },
9757 { &hf_oran_ecpri_rtcid,
9758 { "ecpriRtcid", "oran_fh_cus.ecpriRtcid",
9759 FT_NONE, BASE_NONE,
9760 NULL((void*)0), 0x0,
9761 "Real time control data identifier", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9762 },
9763 /* 5.1.3.2.8 */
9764 { &hf_oran_ecpri_seqid,
9765 { "ecpriSeqid", "oran_fh_cus.ecpriSeqid",
9766 FT_NONE, BASE_NONE,
9767 NULL((void*)0), 0x0,
9768 "message identifier", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9769 },
9770
9771 /* 7.7.23.2 */
9772 { &hf_oran_num_sym_prb_pattern,
9773 { "numSymPrbPattern", "oran_fh_cus.numSymPrbPattern",
9774 FT_UINT8, BASE_DEC,
9775 NULL((void*)0), 0xf0,
9776 "number of symbol and resource block patterns", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9777 },
9778 /* 7.7.23.11 */
9779 { &hf_oran_prb_mode,
9780 { "prbMode", "oran_fh_cus.prbMode",
9781 FT_BOOLEAN, 8,
9782 TFS(&prb_mode_tfs)((0 ? (const struct true_false_string*)0 : ((&prb_mode_tfs
))))
, 0x01,
9783 "PRB Mode", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9784 },
9785
9786 { &hf_oran_sym_prb_pattern,
9787 { "symPrbPattern", "oran_fh_cus.symPrbPattern",
9788 FT_STRING, BASE_NONE,
9789 NULL((void*)0), 0x0,
9790 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9791 },
9792
9793 /* 7.7.23.3 */
9794 { &hf_oran_sym_mask,
9795 { "symMask", "oran_fh_cus.symMask",
9796 FT_UINT16, BASE_HEX,
9797 NULL((void*)0), 0x3fff,
9798 "symbol mask part of symPrbPattern", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9799 },
9800 /* 7.7.23.5 */
9801 {&hf_oran_num_mc_scale_offset,
9802 {"numMcScaleOffset", "oran_fh_cus.numMcScaleOffset",
9803 FT_UINT8, BASE_DEC,
9804 NULL((void*)0), 0xf0,
9805 "number of modulation compression scaling value per symPrbPattern",
9806 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9807 },
9808 /* 7.7.23.4 */
9809 { &hf_oran_prb_pattern,
9810 { "prbPattern", "oran_fh_cus.prbPattern",
9811 FT_UINT8, BASE_DEC,
9812 NULL((void*)0), 0x0f,
9813 "resource block pattern part of symPrbPattern", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9814 },
9815
9816 /* 7.7.3.2 */
9817 { &hf_oran_codebook_index,
9818 { "codebookIndex", "oran_fh_cus.codebookIndex",
9819 FT_UINT8, BASE_DEC,
9820 NULL((void*)0), 0x0,
9821 "precoder codebook used for transmission", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9822 },
9823 /* 7.7.3.3 */
9824 { &hf_oran_layerid,
9825 { "layerID", "oran_fh_cus.layerID",
9826 FT_UINT8, BASE_DEC,
9827 NULL((void*)0), 0xf0,
9828 "Layer ID for DL transmission", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9829 },
9830 /* 7.7.3.5 */
9831 { &hf_oran_numlayers,
9832 { "numLayers", "oran_fh_cus.numLayers",
9833 FT_UINT8, BASE_DEC,
9834 NULL((void*)0), 0x0f,
9835 "number of layers for DL transmission", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9836 },
9837 /* 7.7.3.4 */
9838 { &hf_oran_txscheme,
9839 { "txScheme", "oran_fh_cus.txScheme",
9840 FT_UINT8, BASE_DEC,
9841 NULL((void*)0), 0xf0,
9842 "transmission scheme", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9843 },
9844 /* 7.7.3.6 */
9845 { &hf_oran_crs_remask,
9846 { "crsReMask", "oran_fh_cus.crsReMask",
9847 FT_UINT16, BASE_HEX,
9848 NULL((void*)0), 0x0fff,
9849 "CRS resource element mask", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9850 },
9851 /* 7.7.3.8 */
9852 { &hf_oran_crs_shift,
9853 { "crsShift", "oran_fh_cus.crsShift",
9854 FT_UINT8, BASE_HEX,
9855 NULL((void*)0), 0x80,
9856 "CRS resource element mask", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9857 },
9858 /* 7.7.3.7 */
9859 { &hf_oran_crs_symnum,
9860 { "crsSymNum", "oran_fh_cus.crsSymNum",
9861 FT_UINT8, BASE_DEC,
9862 NULL((void*)0), 0x0f,
9863 "CRS symbol number indication", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9864 },
9865 /* 7.7.3.9 */
9866 { &hf_oran_beamid_ap1,
9867 { "beamIdAP1", "oran_fh_cus.beamIdAP1",
9868 FT_UINT16, BASE_DEC,
9869 NULL((void*)0), 0x7f,
9870 "beam id to be used for antenna port 1", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9871 },
9872 /* 7.7.3.10 */
9873 { &hf_oran_beamid_ap2,
9874 { "beamIdAP2", "oran_fh_cus.beamIdAP2",
9875 FT_UINT16, BASE_DEC,
9876 NULL((void*)0), 0x7f,
9877 "beam id to be used for antenna port 2", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9878 },
9879 /* 7.7.3.11 */
9880 { &hf_oran_beamid_ap3,
9881 { "beamIdAP3", "oran_fh_cus.beamIdAP3",
9882 FT_UINT16, BASE_DEC,
9883 NULL((void*)0), 0x7f,
9884 "beam id to be used for antenna port 3", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9885 },
9886
9887 /* 7.7.10.3a */
9888 { &hf_oran_port_list_index,
9889 { "portListIndex", "oran_fh_cus.portListIndex",
9890 FT_UINT8, BASE_DEC,
9891 NULL((void*)0), 0x0,
9892 "the index of an eAxC_ID in the port-list", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9893 },
9894
9895 { &hf_oran_alpn_per_sym,
9896 { "alpnPerSym", "oran_fh_cus.alpnPerSym",
9897 FT_UINT8, BASE_HEX,
9898 VALS(alpn_per_sym_vals)((0 ? (const struct _value_string*)0 : ((alpn_per_sym_vals)))
)
, 0x80,
9899 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9900 },
9901 { &hf_oran_ant_dmrs_snr,
9902 { "antDmrsSnr", "oran_fh_cus.antDmrsSnr",
9903 FT_UINT8, BASE_HEX,
9904 VALS(ant_dmrs_snr_vals)((0 ? (const struct _value_string*)0 : ((ant_dmrs_snr_vals)))
)
, 0x40,
9905 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9906 },
9907
9908 /* 7.7.24.6 */
9909 { &hf_oran_user_group_size,
9910 { "userGroupSize", "oran_fh_cus.userGroupSize",
9911 FT_UINT8, BASE_DEC,
9912 NULL((void*)0), 0x1f,
9913 "number of UE data layers in the user group identified by userGroupId", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9914 },
9915 /* 7.7.24.7 */
9916 { &hf_oran_user_group_id,
9917 { "userGroupId", "oran_fh_cus.userGroupId",
9918 FT_UINT8, BASE_DEC,
9919 NULL((void*)0), 0x0,
9920 "indicates user group described by the section", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9921 },
9922 /* 7.7.24.8 */
9923 { &hf_oran_entry_type,
9924 { "entryType", "oran_fh_cus.entryType",
9925 FT_UINT8, BASE_DEC,
9926 VALS(entry_type_vals)((0 ? (const struct _value_string*)0 : ((entry_type_vals)))), 0xe0,
9927 "indicates format of the entry", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9928 },
9929 /* 7.7.24.9 */
9930 { &hf_oran_dmrs_port_number,
9931 { "dmrsPortNumber", "oran_fh_cus.dmrsPortNumber",
9932 FT_UINT8, BASE_DEC,
9933 NULL((void*)0), 0x1f,
9934 "DMRS antenna port number for the associated ueId", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9935 },
9936 /* 7.7.24.10 */
9937 { &hf_oran_ueid_reset,
9938 { "ueidReset", "oran_fh_cus.ueidReset",
9939 FT_BOOLEAN, 8,
9940 TFS(&tfs_ueid_reset)((0 ? (const struct true_false_string*)0 : ((&tfs_ueid_reset
))))
, 0x80,
9941 "same UEID as the previous slot", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9942 },
9943 /* 7.7.24.11 */
9944 { &hf_oran_dmrs_symbol_mask,
9945 { "dmrsSymbolMask", "oran_fh_cus.dmrsSymbolMask",
9946 FT_UINT16, BASE_HEX,
9947 NULL((void*)0), 0x3fff,
9948 "symbols within the slot containing DMRS", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9949 },
9950 { &hf_oran_dmrs_symbol_mask_s13,
9951 { "symbol 13", "oran_fh_cus.dmrsSymbolMask.symbol-13",
9952 FT_BOOLEAN, 16,
9953 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x2000,
9954 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9955 },
9956 { &hf_oran_dmrs_symbol_mask_s12,
9957 { "symbol 12", "oran_fh_cus.dmrsSymbolMask.symbol-12",
9958 FT_BOOLEAN, 16,
9959 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x1000,
9960 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9961 },
9962 { &hf_oran_dmrs_symbol_mask_s11,
9963 { "symbol 11", "oran_fh_cus.dmrsSymbolMask.symbol-11",
9964 FT_BOOLEAN, 16,
9965 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0800,
9966 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9967 },
9968 { &hf_oran_dmrs_symbol_mask_s10,
9969 { "symbol 10", "oran_fh_cus.dmrsSymbolMask.symbol-10",
9970 FT_BOOLEAN, 16,
9971 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0400,
9972 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9973 },
9974 { &hf_oran_dmrs_symbol_mask_s9,
9975 { "symbol 9", "oran_fh_cus.dmrsSymbolMask.symbol-9",
9976 FT_BOOLEAN, 16,
9977 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0200,
9978 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9979 },
9980 { &hf_oran_dmrs_symbol_mask_s8,
9981 { "symbol 8", "oran_fh_cus.dmrsSymbolMask.symbol-8",
9982 FT_BOOLEAN, 16,
9983 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0100,
9984 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9985 },
9986 { &hf_oran_dmrs_symbol_mask_s7,
9987 { "symbol 7", "oran_fh_cus.dmrsSymbolMask.symbol-7",
9988 FT_BOOLEAN, 16,
9989 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0080,
9990 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9991 },
9992 { &hf_oran_dmrs_symbol_mask_s6,
9993 { "symbol 6", "oran_fh_cus.dmrsSymbolMask.symbol-6",
9994 FT_BOOLEAN, 16,
9995 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0040,
9996 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9997 },
9998 { &hf_oran_dmrs_symbol_mask_s5,
9999 { "symbol 5", "oran_fh_cus.dmrsSymbolMask.symbol-5",
10000 FT_BOOLEAN, 16,
10001 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0020,
10002 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10003 },
10004 { &hf_oran_dmrs_symbol_mask_s4,
10005 { "symbol 4", "oran_fh_cus.dmrsSymbolMask.symbol-4",
10006 FT_BOOLEAN, 16,
10007 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0010,
10008 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10009 },
10010 { &hf_oran_dmrs_symbol_mask_s3,
10011 { "symbol 3", "oran_fh_cus.dmrsSymbolMask.symbol-3",
10012 FT_BOOLEAN, 16,
10013 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0008,
10014 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10015 },
10016 { &hf_oran_dmrs_symbol_mask_s2,
10017 { "symbol 2", "oran_fh_cus.dmrsSymbolMask.symbol-2",
10018 FT_BOOLEAN, 16,
10019 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0004,
10020 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10021 },
10022 { &hf_oran_dmrs_symbol_mask_s1,
10023 { "symbol 1", "oran_fh_cus.dmrsSymbolMask.symbol-1",
10024 FT_BOOLEAN, 16,
10025 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0002,
10026 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10027 },
10028 { &hf_oran_dmrs_symbol_mask_s0,
10029 { "symbol 0", "oran_fh_cus.dmrsSymbolMask.symbol-0",
10030 FT_BOOLEAN, 16,
10031 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0001,
10032 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10033 },
10034
10035 /* 7.7.24.12 */
10036 { &hf_oran_scrambling,
10037 { "scrambling", "oran_fh_cus.scrambling",
10038 FT_UINT16, BASE_HEX,
10039 NULL((void*)0), 0x0,
10040 "used to calculate the seed value required to initialize pseudo-random generator", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10041 },
10042 /* 7.7.24.13 */
10043 { &hf_oran_nscid,
10044 { "nscid", "oran_fh_cus.nscid",
10045 FT_UINT8, BASE_HEX,
10046 NULL((void*)0), 0x80,
10047 "used to calculate the seed value for pseudo-random generator", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10048 },
10049 /* 7.7.24.14 */
10050 { &hf_oran_dtype,
10051 { "dType", "oran_fh_cus.dType",
10052 FT_UINT8, BASE_HEX,
10053 VALS(dtype_vals)((0 ? (const struct _value_string*)0 : ((dtype_vals)))), 0x40,
10054 "PUSCH DMRS configuration type", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10055 },
10056 /* 7.7.24.15 */
10057 { &hf_oran_cmd_without_data,
10058 { "cmdWithoutData", "oran_fh_cus.cmdWithoutData",
10059 FT_UINT8, BASE_HEX,
10060 NULL((void*)0), 0x30,
10061 "number of DMRS CDM groups without data", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10062 },
10063 /* 7.7.24.16 */
10064 { &hf_oran_lambda,
10065 { "lambda", "oran_fh_cus.lambda",
10066 FT_UINT8, BASE_HEX,
10067 NULL((void*)0), 0x0c,
10068 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10069 },
10070 /* 7.7.24.19 */
10071 { &hf_oran_first_prb,
10072 { "firstPrb", "oran_fh_cus.firstPrb",
10073 FT_UINT16, BASE_DEC,
10074 NULL((void*)0), 0x03fe,
10075 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10076 },
10077 /* 7.7.24.20 */
10078 { &hf_oran_last_prb,
10079 { "lastPrb", "oran_fh_cus.lastPrb",
10080 FT_UINT16, BASE_DEC,
10081 NULL((void*)0), 0x01ff,
10082 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10083 },
10084
10085 /* 7.7.24.17 */
10086 /* TODO: add value_string */
10087 { &hf_oran_low_papr_type,
10088 { "lowPaprType", "oran_fh_cus.lowPaprType",
10089 FT_UINT8, BASE_HEX,
10090 VALS(papr_type_vals)((0 ? (const struct _value_string*)0 : ((papr_type_vals)))), 0x30,
10091 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10092 },
10093 /* 7.7.24.18 */
10094 { &hf_oran_hopping_mode,
10095 { "hoppingMode", "oran_fh_cus.hoppingMode",
10096 FT_UINT8, BASE_HEX,
10097 VALS(hopping_mode_vals)((0 ? (const struct _value_string*)0 : ((hopping_mode_vals)))
)
, 0x0c,
10098 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10099 },
10100
10101 { &hf_oran_tx_win_for_on_air_symbol_l,
10102 { "txWinForOnAirSymbol", "oran_fh_cus.txWinForOnAirSymbol",
10103 FT_UINT8, BASE_DEC,
10104 NULL((void*)0), 0xf0,
10105 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10106 },
10107 { &hf_oran_tx_win_for_on_air_symbol_r,
10108 { "txWinForOnAirSymbol", "oran_fh_cus.txWinForOnAirSymbol",
10109 FT_UINT8, BASE_DEC,
10110 NULL((void*)0), 0x0f,
10111 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10112 },
10113 /* 7.7.26.2 */
10114 { &hf_oran_num_fo_fb,
10115 { "numFoFb", "oran_fh_cus.numFoFb",
10116 FT_UINT8, BASE_DEC,
10117 NULL((void*)0), 0x7f,
10118 "number of frequency offset feedback", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10119 },
10120 /* 7.7.26.3 */
10121 { &hf_oran_freq_offset_fb,
10122 { "freqOffsetFb", "oran_fh_cus.freqOffsetFb",
10123 FT_UINT16, BASE_HEX_DEC | BASE_RANGE_STRING0x00000100,
10124 RVALS(freq_offset_fb_values)((0 ? (const struct _range_string*)0 : ((freq_offset_fb_values
))))
, 0x0,
10125 "UE frequency offset feedback", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10126 },
10127
10128 /* 7.7.28.2 */
10129 { &hf_oran_num_ue_sinr_rpt,
10130 { "numUeSinrRpt", "oran_fh_cus.numUeSinrRpt",
10131 FT_UINT8, BASE_DEC,
10132 NULL((void*)0), 0x1f,
10133 "number of sinr reported UEs {1 - 12}", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10134 },
10135
10136 /* 7.5.2.19 */
10137 { &hf_oran_num_sinr_per_prb,
10138 { "numSinrPerPrb", "oran_fh_cus.numSinrPerPrb",
10139 FT_UINT8, BASE_DEC,
10140 VALS(num_sinr_per_prb_vals)((0 ? (const struct _value_string*)0 : ((num_sinr_per_prb_vals
))))
, 0x70,
10141 "number of SINR values per PRB", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10142 },
10143 { &hf_oran_num_sinr_per_prb_right,
10144 { "numSinrPerPrb", "oran_fh_cus.numSinrPerPrb",
10145 FT_UINT8, BASE_DEC,
10146 VALS(num_sinr_per_prb_vals)((0 ? (const struct _value_string*)0 : ((num_sinr_per_prb_vals
))))
, 0x07,
10147 "number of SINR values per PRB", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10148 },
10149
10150 /* 7.5.3.68 */
10151 { &hf_oran_sinr_value,
10152 { "sinrValue", "oran_fh_cus.sinrValue",
10153 FT_FLOAT, BASE_NONE,
10154 NULL((void*)0), 0x0,
10155 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10156 },
10157
10158 { &hf_oran_measurement_report,
10159 { "Measurement Report", "oran_fh_cus.measurement-report",
10160 FT_STRING, BASE_NONE,
10161 NULL((void*)0), 0x0,
10162 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10163 },
10164 /* 7.5.3.57 */
10165 { &hf_oran_mf,
10166 { "mf", "oran_fh_cus.mf",
10167 FT_BOOLEAN, 8,
10168 TFS(&measurement_flag_tfs)((0 ? (const struct true_false_string*)0 : ((&measurement_flag_tfs
))))
, 0x80,
10169 "measurement flag", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10170 },
10171 /* 7.5.3.59 */
10172 { &hf_oran_meas_data_size,
10173 { "measDataSize", "oran_fh_cus.measDataSize",
10174 FT_UINT16, BASE_DEC,
10175 NULL((void*)0), 0x0,
10176 "measurement data size (in words)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10177 },
10178
10179 /* 7.5.3.58 */
10180 { &hf_oran_meas_type_id,
10181 { "measTypeId", "oran_fh_cus.measTypeId",
10182 FT_UINT8, BASE_DEC,
10183 VALS(meas_type_id_vals)((0 ? (const struct _value_string*)0 : ((meas_type_id_vals)))
)
, 0x7F,
10184 "measurement report type identifier", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10185 },
10186 /* 7.5.3.66 */
10187 { &hf_oran_num_elements,
10188 { "numElements", "oran_fh_cus.numElements",
10189 FT_UINT8, BASE_DEC,
10190 NULL((void*)0), 0x0,
10191 "measurement report type identifier", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10192 },
10193 /* 7.5.3.60 */
10194 { &hf_oran_ue_tae,
10195 { "ueTae", "oran_fh_cus.ueTae",
10196 FT_UINT16, BASE_DEC | BASE_RANGE_STRING0x00000100,
10197 RVALS(freq_offset_fb_values)((0 ? (const struct _range_string*)0 : ((freq_offset_fb_values
))))
, 0x0,
10198 "UE Timing Advance Error", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10199 },
10200 /* 7.5.3.61 */
10201 { &hf_oran_ue_layer_power,
10202 { "ueLayerPower", "oran_fh_cus.ueLayerPower",
10203 FT_UINT16, BASE_DEC | BASE_RANGE_STRING0x00000100,
10204 RVALS(freq_offset_fb_values)((0 ? (const struct _range_string*)0 : ((freq_offset_fb_values
))))
, 0x0,
10205 "UE Layer Power", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10206 },
10207
10208 /* 7.5.3.62 */
10209 { &hf_oran_ue_freq_offset,
10210 { "ueFreqOffset", "oran_fh_cus.ueFreqOffset",
10211 FT_UINT16, BASE_DEC | BASE_RANGE_STRING0x00000100,
10212 RVALS(freq_offset_fb_values)((0 ? (const struct _range_string*)0 : ((freq_offset_fb_values
))))
, 0x0,
10213 "UE frequency offset", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10214 },
10215 /* 7.5.3.63 */
10216 { &hf_oran_ipn_power,
10217 { "ipnPower", "oran_fh_cus.ipnPower",
10218 FT_UINT16, BASE_DEC | BASE_RANGE_STRING0x00000100,
10219 RVALS(freq_offset_fb_values)((0 ? (const struct _range_string*)0 : ((freq_offset_fb_values
))))
, 0x0,
10220 "Interference plus Noise power", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10221 },
10222 /* 7.5.3.64 */
10223 { &hf_oran_ant_dmrs_snr_val,
10224 { "antDmrsSnrVal", "oran_fh_cus.antDmrsSnrVal",
10225 FT_UINT16, BASE_DEC | BASE_RANGE_STRING0x00000100,
10226 RVALS(freq_offset_fb_values)((0 ? (const struct _range_string*)0 : ((freq_offset_fb_values
))))
, 0x0,
10227 "antenna DMRS-SNR", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10228 },
10229
10230 { &hf_oran_measurement_command,
10231 { "Measurement Command", "oran_fh_cus.measurement-command",
10232 FT_STRING, BASE_NONE,
10233 NULL((void*)0), 0x0,
10234 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10235 },
10236
10237 /* 7.5.27.2 */
10238 { &hf_oran_beam_type,
10239 {"beamType", "oran_fh_cus.beamType",
10240 FT_UINT16, BASE_DEC,
10241 VALS(beam_type_vals)((0 ? (const struct _value_string*)0 : ((beam_type_vals)))), 0xc0,
10242 NULL((void*)0),
10243 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10244 },
10245 /* 7.5.3.65 */
10246 { &hf_oran_meas_cmd_size,
10247 {"measCmdSize", "oran_fh_cus.measCmdSize",
10248 FT_UINT16, BASE_DEC,
10249 NULL((void*)0), 0x0,
10250 "measurement command size in words",
10251 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10252 },
10253
10254 { &hf_oran_symbol_reordering_layer,
10255 { "Layer", "oran_fh_cus.layer",
10256 FT_STRING, BASE_NONE,
10257 NULL((void*)0), 0x0,
10258 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10259 },
10260 { &hf_oran_dmrs_entry,
10261 { "Entry", "oran_fh_cus.dmrs-entry",
10262 FT_STRING, BASE_NONE,
10263 NULL((void*)0), 0x0,
10264 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10265 },
10266
10267 /* 7.7.29.3 */
10268 { &hf_oran_cd_scg_size,
10269 {"cdScgSize", "oran_fh_cus.cdScgSize",
10270 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
10271 RVALS(cd_scg_size_vals)((0 ? (const struct _range_string*)0 : ((cd_scg_size_vals)))), 0x0f,
10272 "Cyclic delay subcarrier group size",
10273 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10274 },
10275 /* 7.7.29.4 */
10276 { &hf_oran_cd_scg_phase_step,
10277 {"cdScgPhaseStep", "oran_fh_cus.cdScgPhaseStep",
10278 FT_INT8, BASE_DEC,
10279 NULL((void*)0), 0x0,
10280 "Cyclic delay subcarrier group phase step",
10281 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10282 },
10283
10284 { &hf_oran_sinr_prb,
10285 { "PRB", "oran_fh_cus.sinr.prb",
10286 FT_STRING, BASE_NONE,
10287 NULL((void*)0), 0x0,
10288 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10289 },
10290 /* 7.5.2.20 */
10291 { &hf_oran_oru_control_sinr_slot_mask_id,
10292 {"oruControlSinrSlotMaskId", "oran_fh_cus.oruControlSinrSlotMaskId",
10293 FT_UINT8, BASE_DEC,
10294 NULL((void*)0), 0x1f,
10295 "SINR time resolution",
10296 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10297 },
10298 /* 7.7.24.21 */
10299 { &hf_oran_pos_meas,
10300 {"posMeas", "oran_fh_cus.posMeas",
10301 FT_BOOLEAN, 8,
10302 TFS(&tfs_report_no_report_pos_meas)((0 ? (const struct true_false_string*)0 : ((&tfs_report_no_report_pos_meas
))))
, 0x40,
10303 "Positioning measurement report request",
10304 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10305 },
10306
10307 /* 7.5.3.69 */
10308 { &hf_oran_ue_radial_speed,
10309 {"ueRadialSpeed", "oran_fh_cus.ueRadialSpeed",
10310 FT_UINT16, BASE_DEC,
10311 NULL((void*)0), 0x0,
10312 "UE radial speed",
10313 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10314 },
10315 /* 7.5.3.70 */
10316 { &hf_oran_ue_az_aoa,
10317 {"ueAzAoa", "oran_fh_cus.ueAzAoa",
10318 FT_UINT16, BASE_DEC,
10319 NULL((void*)0), 0x0,
10320 "UE azimuth angle of arrival",
10321 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10322 },
10323 /* 7.5.3.71 */
10324 { &hf_oran_ue_ze_aoa,
10325 {"ueZeAoa", "oran_fh_cus.ueZeAoa",
10326 FT_UINT16, BASE_DEC,
10327 NULL((void*)0), 0x0,
10328 "UE zenith angle of arrival",
10329 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10330 },
10331 /* 7.5.3.72 */
10332 { &hf_oran_ue_pos_toa_offset,
10333 {"uePosToaOffset", "oran_fh_cus.uePosToaOffset",
10334 FT_UINT16, BASE_DEC,
10335 NULL((void*)0), 0x0,
10336 "UE positioning time of arrival offset",
10337 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10338 },
10339
10340 /* 7.7.30.2 */
10341 { &hf_oran_num_rep_ue,
10342 {"numRepUe", "oran_fh_cus.numRepUe",
10343 FT_UINT8, BASE_DEC,
10344 NULL((void*)0), 0x0f,
10345 "Number of UEs with PUSCH repetition",
10346 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10347 },
10348 /* 7.7.30.3 */
10349 { &hf_oran_rep_ueid,
10350 {"repUeId", "oran_fh_cus.repUeId",
10351 FT_UINT16, BASE_DEC,
10352 NULL((void*)0), 0x7fff,
10353 "UEId the PUSCH is part of",
10354 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10355 },
10356 /* 7.7.30.4 */
10357 { &hf_oran_is_last_rep,
10358 {"isLastRep", "oran_fh_cus.isLastRep",
10359 FT_BOOLEAN, 8,
10360 NULL((void*)0), 0x40,
10361 "Last transmission in the repetition",
10362 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10363 },
10364 /* 7.7.30.5 */
10365 { &hf_oran_rep_index,
10366 {"repIndex", "oran_fh_cus.repIndex",
10367 FT_UINT8, BASE_DEC,
10368 NULL((void*)0), 0x3f,
10369 "Repetition index of the PUSCH transmission",
10370 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10371 },
10372 /* 7.7.30.6 */
10373 { &hf_oran_num_reps,
10374 {"numReps", "oran_fh_cus.numReps",
10375 FT_UINT8, BASE_DEC,
10376 NULL((void*)0), 0x3f,
10377 "The number of total PUSCH repetitions",
10378 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10379 },
10380
10381
10382 { &hf_oran_c_section_common,
10383 { "Common Section", "oran_fh_cus.c-plane.section.common",
10384 FT_STRING, BASE_NONE,
10385 NULL((void*)0), 0x0,
10386 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10387 },
10388 { &hf_oran_c_section,
10389 { "Section", "oran_fh_cus.c-plane.section",
10390 FT_STRING, BASE_NONE,
10391 NULL((void*)0), 0x0,
10392 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10393 },
10394 { &hf_oran_u_section,
10395 { "Section", "oran_fh_cus.u-plane.section",
10396 FT_STRING, BASE_NONE,
10397 NULL((void*)0), 0x0,
10398 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10399 },
10400
10401 /* Link back to UL C-plane where udCompHdr was recorded */
10402 { &hf_oran_ul_cplane_ud_comp_hdr_frame,
10403 { "C-Plane UL udCompHdr frame", "oran_fh_cus.ul-cplane.udCompHdr",
10404 FT_FRAMENUM, BASE_NONE,
10405 FRAMENUM_TYPE(FT_FRAMENUM_REQUEST)((gpointer) (glong) (FT_FRAMENUM_REQUEST)), 0x0,
10406 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10407 },
10408
10409 /* For ext11, where was a beamId (last) defined? */
10410 { &hf_oran_bfws_frame_defined,
10411 { "Beam defined in frame", "oran_fh_cus.bfw-defined",
10412 FT_FRAMENUM, BASE_NONE,
10413 FRAMENUM_TYPE(FT_FRAMENUM_RETRANS_PREV)((gpointer) (glong) (FT_FRAMENUM_RETRANS_PREV)), 0x0,
10414 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10415 },
10416 { &hf_oran_bfws_symbols_since_defined,
10417 { "Symbols since BFWs defined", "oran_fh_cus.symbols-since-bfw-defined",
10418 FT_UINT32, BASE_DEC,
10419 NULL((void*)0), 0x0,
10420 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10421 },
10422
10423 /* Corresponding C-plane frame for DL U-plane */
10424 { &hf_oran_corresponding_cplane_frame,
10425 { "C-plane frame", "oran_fh_cus.cplane-frame",
10426 FT_FRAMENUM, BASE_NONE,
10427 FRAMENUM_TYPE(FT_FRAMENUM_REQUEST)((gpointer) (glong) (FT_FRAMENUM_REQUEST)), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10428 },
10429 /* Time since corresponding C-plane frame for DL U-plane */
10430 { &hf_oran_corresponding_cplane_frame_time_delta,
10431 { "Time since C-plane frame", "oran_fh_cus.cplane-frame-time-delta",
10432 FT_UINT32, BASE_DEC, NULL((void*)0), 0x0,
10433 "Microseconds since C-plane frame", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10434 },
10435
10436 /* Reassembly */
10437 { &hf_oran_fragment,
10438 { "Fragment", "oran_fh_cus.fragment", FT_FRAMENUM, BASE_NONE,
10439 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10440 { &hf_oran_fragments,
10441 { "Fragments", "oran_fh_cus.fragments", FT_BYTES, BASE_NONE,
10442 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10443 { &hf_oran_fragment_overlap,
10444 { "Fragment overlap", "oran_fh_cus.fragment.overlap", FT_BOOLEAN, BASE_NONE,
10445 NULL((void*)0), 0x0, "Fragment overlaps with other fragments", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10446 { &hf_oran_fragment_overlap_conflict,
10447 { "Conflicting data in fragment overlap", "oran_fh_cus.fragment.overlap.conflict",
10448 FT_BOOLEAN, BASE_NONE, NULL((void*)0), 0x0,
10449 "Overlapping fragments contained conflicting data", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10450 { &hf_oran_fragment_multiple_tails,
10451 { "Multiple tail fragments found", "oran_fh_cus.fragment.multipletails",
10452 FT_BOOLEAN, BASE_NONE, NULL((void*)0), 0x0,
10453 "Several tails were found when defragmenting the packet", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10454 { &hf_oran_fragment_too_long_fragment,
10455 { "Fragment too long", "oran_fh_cus.fragment.toolongfragment",
10456 FT_BOOLEAN, BASE_NONE, NULL((void*)0), 0x0,
10457 "Fragment contained data past end of packet", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10458 { &hf_oran_fragment_error,
10459 { "Defragmentation error", "oran_fh_cus.fragment.error", FT_FRAMENUM, BASE_NONE,
10460 NULL((void*)0), 0x0, "Defragmentation error due to illegal fragments", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10461 { &hf_oran_fragment_count,
10462 { "Fragment count", "oran_fh_cus.fragment.count", FT_UINT32, BASE_DEC,
10463 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10464 { &hf_oran_reassembled_in,
10465 { "Reassembled payload in frame", "oran_fh_cus.reassembled_in", FT_FRAMENUM, BASE_NONE,
10466 NULL((void*)0), 0x0, "This payload packet is reassembled in this frame", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10467 { &hf_oran_reassembled_length,
10468 { "Reassembled payload length", "oran_fh_cus.reassembled.length", FT_UINT32, BASE_DEC,
10469 NULL((void*)0), 0x0, "The total length of the reassembled payload", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10470 { &hf_oran_reassembled_data,
10471 { "Reassembled data", "oran_fh_cus.reassembled.data", FT_BYTES, BASE_NONE,
10472 NULL((void*)0), 0x0, "The reassembled payload", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10473
10474 { &hf_oran_payload,
10475 { "Payload", "oran_fh_cus.payload", FT_BYTES, BASE_SHOW_ASCII_PRINTABLE0x00010000,
10476 NULL((void*)0), 0x0, "Complete or reassembled payload", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10477 };
10478
10479 /* Setup protocol subtree array */
10480 static int *ett[] = {
10481 &ett_oran,
10482 &ett_oran_ecpri_pcid,
10483 &ett_oran_ecpri_rtcid,
10484 &ett_oran_ecpri_seqid,
10485 &ett_oran_section_type,
10486 &ett_oran_u_timing,
10487 &ett_oran_u_section,
10488 &ett_oran_u_prb,
10489 &ett_oran_section,
10490 &ett_oran_iq,
10491 &ett_oran_bfw_bundle,
10492 &ett_oran_bfw,
10493 &ett_oran_frequency_range,
10494 &ett_oran_prb_cisamples,
10495 &ett_oran_cisample,
10496 &ett_oran_udcomphdr,
10497 &ett_oran_udcompparam,
10498 &ett_oran_cicomphdr,
10499 &ett_oran_cicompparam,
10500 &ett_oran_bfwcomphdr,
10501 &ett_oran_bfwcompparam,
10502 &ett_oran_ext19_port,
10503 &ett_oran_prb_allocation,
10504 &ett_oran_punc_pattern,
10505 &ett_oran_bfacomphdr,
10506 &ett_oran_modcomp_param_set,
10507 &ett_oran_st4_cmd_header,
10508 &ett_oran_st4_cmd,
10509 &ett_oran_sym_prb_pattern,
10510 &ett_oran_measurement_report,
10511 &ett_oran_measurement_command,
10512 &ett_oran_sresmask,
10513 &ett_oran_c_section_common,
10514 &ett_oran_c_section,
10515 &ett_oran_remask,
10516 &ett_oran_mc_scale_remask,
10517 &ett_oran_symbol_reordering_layer,
10518 &ett_oran_dmrs_entry,
10519 &ett_oran_dmrs_symbol_mask,
10520 &ett_oran_symbol_mask,
10521 &ett_oran_active_beamspace_coefficient_mask,
10522 &ett_oran_sinr_prb,
10523
10524 &ett_oran_fragment,
10525 &ett_oran_fragments
10526 };
10527
10528 /* Separate subtree array for extensions. Used with [ext-1] */
10529 static int *ext_ett[HIGHEST_EXTTYPE32];
10530 for (unsigned extno=0; extno<HIGHEST_EXTTYPE32; extno++) {
10531 ext_ett[extno] = &ett_oran_c_section_extension[extno];
10532 }
10533
10534 expert_module_t* expert_oran;
10535
10536 static ei_register_info ei[] = {
10537 { &ei_oran_unsupported_bfw_compression_method, { "oran_fh_cus.unsupported_bfw_compression_method", PI_UNDECODED0x05000000, PI_WARN0x00600000, "Unsupported BFW Compression Method", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE
, BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE
, -1, ((void*)0)}}
}},
10538 { &ei_oran_invalid_sample_bit_width, { "oran_fh_cus.invalid_sample_bit_width", PI_UNDECODED0x05000000, PI_ERROR0x00800000, "Unsupported sample bit width", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE
, BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE
, -1, ((void*)0)}}
}},
10539 { &ei_oran_reserved_numBundPrb, { "oran_fh_cus.reserved_numBundPrb", PI_MALFORMED0x07000000, PI_ERROR0x00800000, "Reserved value 0 for numBundPrb seen - not valid", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE
, BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE
, -1, ((void*)0)}}
}},
10540 { &ei_oran_extlen_wrong, { "oran_fh_cus.extlen_wrong", PI_MALFORMED0x07000000, PI_ERROR0x00800000, "extlen doesn't match number of dissected bytes", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE
, BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE
, -1, ((void*)0)}}
}},
10541 { &ei_oran_invalid_eaxc_bit_width, { "oran_fh_cus.invalid_eaxc_bit_width", PI_UNDECODED0x05000000, PI_ERROR0x00800000, "Inconsistent eAxC bit width", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE
, BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE
, -1, ((void*)0)}}
}},
10542 { &ei_oran_extlen_zero, { "oran_fh_cus.extlen_zero", PI_MALFORMED0x07000000, PI_ERROR0x00800000, "extlen value of 0 is reserved", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE
, BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE
, -1, ((void*)0)}}
}},
10543 { &ei_oran_rbg_size_reserved, { "oran_fh_cus.rbg_size_reserved", PI_MALFORMED0x07000000, PI_ERROR0x00800000, "rbgSize value of 0 is reserved", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE
, BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE
, -1, ((void*)0)}}
}},
10544 { &ei_oran_frame_length, { "oran_fh_cus.frame_length", PI_MALFORMED0x07000000, PI_ERROR0x00800000, "there should be 0-3 bytes remaining after PDU in frame", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE
, BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE
, -1, ((void*)0)}}
}},
10545 { &ei_oran_numprbc_ext21_zero, { "oran_fh_cus.numprbc_ext21_zero", PI_MALFORMED0x07000000, PI_ERROR0x00800000, "numPrbc shall not be set to 0 when ciPrbGroupSize is configured", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE
, BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE
, -1, ((void*)0)}}
}},
10546 { &ei_oran_ci_prb_group_size_reserved, { "oran_fh_cus.ci_prb_group_size_reserved", PI_MALFORMED0x07000000, PI_WARN0x00600000, "ciPrbGroupSize should be 2-254", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE
, BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE
, -1, ((void*)0)}}
}},
10547 { &ei_oran_st8_nackid, { "oran_fh_cus.st8_nackid", PI_SEQUENCE0x02000000, PI_WARN0x00600000, "operation for this ackId failed", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE
, BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE
, -1, ((void*)0)}}
}},
10548 { &ei_oran_st4_no_cmds, { "oran_fh_cus.st4_nackid", PI_MALFORMED0x07000000, PI_ERROR0x00800000, "Not valid for ST4 to carry no commands", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE
, BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE
, -1, ((void*)0)}}
}},
10549 { &ei_oran_st4_zero_len_cmd, { "oran_fh_cus.st4_zero_len_cmd", PI_MALFORMED0x07000000, PI_WARN0x00600000, "ST4 cmd with length 0 is reserved", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE
, BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE
, -1, ((void*)0)}}
}},
10550 { &ei_oran_st4_wrong_len_cmd, { "oran_fh_cus.st4_wrong_len_cmd", PI_MALFORMED0x07000000, PI_ERROR0x00800000, "ST4 cmd with length not matching contents", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE
, BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE
, -1, ((void*)0)}}
}},
10551 { &ei_oran_st4_unknown_cmd, { "oran_fh_cus.st4_unknown_cmd", PI_MALFORMED0x07000000, PI_ERROR0x00800000, "ST4 cmd with unknown command code", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE
, BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE
, -1, ((void*)0)}}
}},
10552 { &ei_oran_mcot_out_of_range, { "oran_fh_cus.mcot_out_of_range", PI_MALFORMED0x07000000, PI_ERROR0x00800000, "MCOT should be 1-10", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE
, BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE
, -1, ((void*)0)}}
}},
10553 { &ei_oran_se10_unknown_beamgrouptype, { "oran_fh_cus.se10_unknown_beamgrouptype", PI_MALFORMED0x07000000, PI_WARN0x00600000, "SE10 - unknown BeamGroupType value", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE
, BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE
, -1, ((void*)0)}}
}},
10554 { &ei_oran_se10_not_allowed, { "oran_fh_cus.se10_not_allowed", PI_MALFORMED0x07000000, PI_WARN0x00600000, "SE10 - type not allowed for sectionType", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE
, BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE
, -1, ((void*)0)}}
}},
10555 { &ei_oran_start_symbol_id_not_zero, { "oran_fh_cus.startsymbolid_shall_be_zero", PI_MALFORMED0x07000000, PI_WARN0x00600000, "For ST4 commands 3&4, startSymbolId shall be 0", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE
, BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE
, -1, ((void*)0)}}
}},
10556 { &ei_oran_trx_control_cmd_scope, { "oran_fh_cus.trx_command.bad_cmdscope", PI_MALFORMED0x07000000, PI_WARN0x00600000, "TRX command must have cmdScope of ARRAY-COMMAND", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE
, BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE
, -1, ((void*)0)}}
}},
10557 { &ei_oran_unhandled_se, { "oran_fh_cus.se_not_handled", PI_UNDECODED0x05000000, PI_WARN0x00600000, "SE not recognised/handled by dissector", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE
, BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE
, -1, ((void*)0)}}
}},
10558 { &ei_oran_bad_symbolmask, { "oran_fh_cus.bad_symbol_mask", PI_MALFORMED0x07000000, PI_WARN0x00600000, "For non-zero sleepMode, symbolMask must be 0x0 or 0x3ffff", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE
, BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE
, -1, ((void*)0)}}
}},
10559 { &ei_oran_numslots_not_zero, { "oran_fh_cus.numslots_not_zero", PI_MALFORMED0x07000000, PI_WARN0x00600000, "For ST4 TIME_DOMAIN_BEAM_WEIGHTS, numSlots should be 0", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE
, BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE
, -1, ((void*)0)}}
}},
10560 { &ei_oran_version_unsupported, { "oran_fh_cus.version_unsupported", PI_UNDECODED0x05000000, PI_WARN0x00600000, "Protocol version unsupported", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE
, BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE
, -1, ((void*)0)}}
}},
10561 { &ei_oran_laa_msg_type_unsupported, { "oran_fh_cus.laa_msg_type_unsupported", PI_UNDECODED0x05000000, PI_WARN0x00600000, "laaMsgType unsupported", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE
, BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE
, -1, ((void*)0)}}
}},
10562 { &ei_oran_se_on_unsupported_st, { "oran_fh_cus.se_on_unsupported_st", PI_MALFORMED0x07000000, PI_WARN0x00600000, "Section Extension should not appear on this Section Type", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE
, BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE
, -1, ((void*)0)}}
}},
10563 { &ei_oran_cplane_unexpected_sequence_number_ul, { "oran_fh_cus.unexpected_seq_no_cplane.ul", PI_SEQUENCE0x02000000, PI_WARN0x00600000, "Unexpected sequence number seen in C-Plane UL", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE
, BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE
, -1, ((void*)0)}}
}},
10564 { &ei_oran_cplane_unexpected_sequence_number_dl, { "oran_fh_cus.unexpected_seq_no_cplane.dl", PI_SEQUENCE0x02000000, PI_WARN0x00600000, "Unexpected sequence number seen in C-Plane DL", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE
, BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE
, -1, ((void*)0)}}
}},
10565 { &ei_oran_uplane_unexpected_sequence_number_ul, { "oran_fh_cus.unexpected_seq_no_uplane.ul", PI_SEQUENCE0x02000000, PI_WARN0x00600000, "Unexpected sequence number seen in U-Plane UL", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE
, BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE
, -1, ((void*)0)}}
}},
10566 { &ei_oran_uplane_unexpected_sequence_number_dl, { "oran_fh_cus.unexpected_seq_no_uplane.dl", PI_SEQUENCE0x02000000, PI_WARN0x00600000, "Unexpected sequence number seen in U-Plane DL", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE
, BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE
, -1, ((void*)0)}}
}},
10567 { &ei_oran_acknack_no_request, { "oran_fh_cus.acknack_no_request", PI_SEQUENCE0x02000000, PI_WARN0x00600000, "Have ackNackId response, but no request", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE
, BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE
, -1, ((void*)0)}}
}},
10568 { &ei_oran_udpcomphdr_should_be_zero, { "oran_fh_cus.udcomphdr_should_be_zero", PI_MALFORMED0x07000000, PI_WARN0x00600000, "C-Plane udCompHdr in DL should be set to 0", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE
, BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE
, -1, ((void*)0)}}
}},
10569 { &ei_oran_radio_fragmentation_c_plane, { "oran_fh_cus.radio_fragmentation_c_plane", PI_MALFORMED0x07000000, PI_ERROR0x00800000, "Radio fragmentation not allowed in C-PLane", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE
, BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE
, -1, ((void*)0)}}
}},
10570 { &ei_oran_lastRbdid_out_of_range, { "oran_fh_cus.lastrbdid_out_of_range", PI_MALFORMED0x07000000, PI_WARN0x00600000, "SE 6 has bad rbgSize", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE
, BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE
, -1, ((void*)0)}}
}},
10571 { &ei_oran_rbgMask_beyond_last_rbdid, { "oran_fh_cus.rbgmask_beyond_lastrbdid", PI_MALFORMED0x07000000, PI_WARN0x00600000, "rbgMask has bits set beyond lastRbgId", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE
, BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE
, -1, ((void*)0)}}
}},
10572 { &ei_oran_unexpected_measTypeId, { "oran_fh_cus.unexpected_meastypeid", PI_MALFORMED0x07000000, PI_WARN0x00600000, "unexpected measTypeId", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE
, BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE
, -1, ((void*)0)}}
}},
10573 { &ei_oran_unsupported_compression_method, { "oran_fh_cus.compression_type_unsupported", PI_UNDECODED0x05000000, PI_WARN0x00600000, "Unsupported compression type", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE
, BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE
, -1, ((void*)0)}}
}},
10574 { &ei_oran_ud_comp_len_wrong_size, { "oran_fh_cus.ud_comp_len_wrong_size", PI_MALFORMED0x07000000, PI_WARN0x00600000, "udCompLen does not match length of U-Plane section", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE
, BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE
, -1, ((void*)0)}}
}},
10575 { &ei_oran_sresmask2_not_zero_with_rb, { "oran_fh_cus.sresmask2_not_zero", PI_MALFORMED0x07000000, PI_WARN0x00600000, "sReSMask2 should be zero when rb set", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE
, BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE
, -1, ((void*)0)}}
}},
10576 { &ei_oran_st6_rb_shall_be_0, { "oran_fh_cus.st6_rb_set", PI_MALFORMED0x07000000, PI_WARN0x00600000, "rb should not be set for Section Type 6", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE
, BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE
, -1, ((void*)0)}}
}},
10577 { &ei_oran_st9_not_ul, { "oran_fh_cus.st9_not_ul", PI_MALFORMED0x07000000, PI_WARN0x00600000, "Section Type 9 should only be sent in uplink direction", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE
, BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE
, -1, ((void*)0)}}
}},
10578 { &ei_oran_st10_numsymbol_not_14, { "oran_fh_cus.st10_numsymbol_not_14", PI_MALFORMED0x07000000, PI_WARN0x00600000, "numSymbol should be 14 for Section Type 10", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE
, BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE
, -1, ((void*)0)}}
}},
10579 { &ei_oran_st10_startsymbolid_not_0, { "oran_fh_cus.st10_startsymbolid_not_0", PI_MALFORMED0x07000000, PI_WARN0x00600000, "startSymbolId should be 0 for Section Type 10", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE
, BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE
, -1, ((void*)0)}}
}},
10580 { &ei_oran_st10_not_ul, { "oran_fh_cus.st10_not_ul", PI_MALFORMED0x07000000, PI_WARN0x00600000, "Section Type 10 should only be sent in uplink direction", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE
, BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE
, -1, ((void*)0)}}
}},
10581 { &ei_oran_se24_nothing_to_inherit, { "oran_fh_cus.se24_nothing_to_inherit", PI_MALFORMED0x07000000, PI_WARN0x00600000, "SE10 doesn't have type 2 or 3 before trying to inherit", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE
, BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE
, -1, ((void*)0)}}
}},
10582 { &ei_oran_num_sinr_per_prb_unknown, { "oran_fh_cus.unexpected_num_sinr_per_prb", PI_MALFORMED0x07000000, PI_WARN0x00600000, "invalid numSinrPerPrb value", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE
, BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE
, -1, ((void*)0)}}
}},
10583 { &ei_oran_start_symbol_id_bits_ignored, { "oran_fh_cus.start_symbol_id_bits_ignored", PI_MALFORMED0x07000000, PI_WARN0x00600000, "some startSymbolId lower bits ignored", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE
, BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE
, -1, ((void*)0)}}
}},
10584 { &ei_oran_user_group_id_reserved_value, { "oran_fh_cus.user_group_id.reserved_value", PI_MALFORMED0x07000000, PI_WARN0x00600000, "userGroupId value 255 is reserved", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE
, BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE
, -1, ((void*)0)}}
}},
10585 { &ei_oran_port_list_index_zero, { "oran_fh_cus.port_list_index.zero", PI_MALFORMED0x07000000, PI_WARN0x00600000, "portListIndex should not be zero", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE
, BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE
, -1, ((void*)0)}}
}},
10586 { &ei_oran_ul_uplane_symbol_too_long, { "oran_fh_cus.ul_uplane_symbol_tx_too_slow", PI_RECEIVE0x0f000000, PI_WARN0x00600000, "UL U-Plane Tx took too long for symbol (limit set in preference)", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE
, BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE
, -1, ((void*)0)}}
}},
10587 { &ei_oran_reserved_not_zero, { "oran_fh_cus.reserved_not_zero", PI_MALFORMED0x07000000, PI_WARN0x00600000, "Reserved field is not zero", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE
, BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE
, -1, ((void*)0)}}
}},
10588 { &ei_oran_too_many_symbols, { "oran_fh_cus.too_many_symbols", PI_MALFORMED0x07000000, PI_ERROR0x00800000, "Range of symbols in slot exceeds 14", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE
, BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE
, -1, ((void*)0)}}
}},
10589 { &ei_oran_se30_not_ul, { "oran_fh_cus.se30_not_ul", PI_MALFORMED0x07000000, PI_WARN0x00600000, "SE30 should only be sent in uplink direction", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE
, BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE
, -1, ((void*)0)}}
}},
10590 { &ei_oran_se30_unknown_ueid, { "oran_fh_cus.se30_unknown_ue", PI_MALFORMED0x07000000, PI_WARN0x00600000, "SE30 UEId not recognised from SE10", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE
, BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE
, -1, ((void*)0)}}
}},
10591 { &ei_oran_beamid_bfws_not_found, { "oran_fh_cus.beamid_bfws_not_found", PI_SEQUENCE0x02000000, PI_WARN0x00600000, "Have bundle with disableBFWs but no definition found", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE
, BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE
, -1, ((void*)0)}}
}},
10592 { &ei_oran_syminc_set_for_uplane, { "oran_fh_cus.syminc_set_for_uplane", PI_MALFORMED0x07000000, PI_ERROR0x00800000, "symcInc is prohibited in the U-Plane", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE
, BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE
, -1, ((void*)0)}}
}}
10593 };
10594
10595 /* Register the protocol name and description */
10596 proto_oran = proto_register_protocol("O-RAN Fronthaul CUS", "O-RAN FH CUS", "oran_fh_cus");
10597
10598 /* Allow dissector to find be found by name. */
10599 register_dissector("oran_fh_cus", dissect_oran, proto_oran);
10600
10601 /* Register the tap name. */
10602 oran_tap = register_tap("oran-fh-cus");
10603
10604 /* Required function calls to register the header fields and subtrees */
10605 proto_register_field_array(proto_oran, hf, array_length(hf)(sizeof (hf) / sizeof (hf)[0]));
10606 proto_register_subtree_array(ett, array_length(ett)(sizeof (ett) / sizeof (ett)[0]));
10607 proto_register_subtree_array(ext_ett, array_length(ext_ett)(sizeof (ext_ett) / sizeof (ext_ett)[0]));
10608
10609 expert_oran = expert_register_protocol(proto_oran);
10610 expert_register_field_array(expert_oran, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
10611
10612
10613 /* Preferences */
10614 module_t * oran_module = prefs_register_protocol(proto_oran, NULL((void*)0));
10615
10616 /* Register bit width/compression preferences separately by direction. */
10617 prefs_register_uint_preference(oran_module, "oran.du_port_id_bits", "DU Port ID bits [a]",
10618 "The bit width of DU Port ID - sum of a,b,c&d (eAxC) must be 16", 10, &pref_du_port_id_bits);
10619 prefs_register_uint_preference(oran_module, "oran.bandsector_id_bits", "BandSector ID bits [b]",
10620 "The bit width of BandSector ID - sum of a,b,c&d (eAxC) must be 16", 10, &pref_bandsector_id_bits);
10621 prefs_register_uint_preference(oran_module, "oran.cc_id_bits", "CC ID bits [c]",
10622 "The bit width of CC ID - sum of a,b,c&d (eAxC) must be 16", 10, &pref_cc_id_bits);
10623 prefs_register_uint_preference(oran_module, "oran.ru_port_id_bits", "RU Port ID bits [d]",
10624 "The bit width of RU Port ID - sum of a,b,c&d (eAxC) must be 16", 10, &pref_ru_port_id_bits);
10625
10626 /* Uplink userplane */
10627 prefs_register_static_text_preference(oran_module, "oran.ul", "", "");
10628 prefs_register_uint_preference(oran_module, "oran.iq_bitwidth_up", "IQ Bitwidth Uplink",
10629 "The bit width of a sample in the Uplink (if no udcompHdr and no C-Plane)", 10, &pref_sample_bit_width_uplink);
10630 prefs_register_enum_preference(oran_module, "oran.ud_comp_up", "Uplink User Data Compression",
10631 "Uplink User Data Compression (if no udcompHdr and no C-Plane)", &pref_iqCompressionUplink, ul_compression_options, false0);
10632 prefs_register_enum_preference(oran_module, "oran.ud_comp_hdr_up", "udCompHdr field is present for uplink",
10633 "The udCompHdr field in U-Plane messages may or may not be present, depending on the "
10634 "configuration of the O-RU. This preference instructs the dissector to expect "
10635 "this field to be present in uplink messages",
10636 &pref_includeUdCompHeaderUplink, udcomphdr_present_options, false0);
10637 prefs_register_bool_preference(oran_module, "oran.ignore_cplane_ul_udcomphdr", "Ignore UL compression settings from C-plane",
10638 "When set, override udCompHdr from UL C-Plane with compression method and width configured here", &pref_override_ul_compression);
10639 prefs_register_uint_preference(oran_module, "oran.ul_slot_us_limit", "Microseconds allowed for UL tx in symbol",
10640 "Maximum number of microseconds allowed for UL slot transmission before expert warning (zero to disable). N.B. timing relative to first frame seen for same symbol",
10641 10, &us_allowed_for_ul_in_symbol);
10642
10643 /* Downlink userplane */
10644 prefs_register_static_text_preference(oran_module, "oran.dl", "", "");
10645 prefs_register_uint_preference(oran_module, "oran.iq_bitwidth_down", "IQ Bitwidth Downlink",
10646 "The bit width of a sample in the Downlink (if no udcompHdr)", 10, &pref_sample_bit_width_downlink);
10647 prefs_register_enum_preference(oran_module, "oran.ud_comp_down", "Downlink User Data Compression",
10648 "Downlink User Data Compression", &pref_iqCompressionDownlink, dl_compression_options, false0);
10649 prefs_register_enum_preference(oran_module, "oran.ud_comp_hdr_down", "udCompHdr field is present for downlink",
10650 "The udCompHdr field in U-Plane messages may or may not be present, depending on the "
10651 "configuration of the O-RU. This preference instructs the dissector to expect "
10652 "this field to be present in downlink messages",
10653 &pref_includeUdCompHeaderDownlink, udcomphdr_present_options, false0);
10654
10655 /* SINR */
10656 prefs_register_static_text_preference(oran_module, "oran.sinr", "", "");
10657 prefs_register_uint_preference(oran_module, "oran.iq_bitwidth_sinr", "IQ Bitwidth SINR",
10658 "The bit width of a sample in SINR", 10, &pref_sample_bit_width_sinr);
10659 prefs_register_enum_preference(oran_module, "oran.ud_comp_sinr", "SINR Compression",
10660 "SINR Compression", &pref_iqCompressionSINR, ul_compression_options, false0);
10661
10662 /* BF-related */
10663 prefs_register_static_text_preference(oran_module, "oran.bf", "", "");
10664 prefs_register_uint_preference(oran_module, "oran.num_bf_antennas", "Number of beam weights",
10665 "Number of array elements that BF weights will be provided for", 10, &pref_num_bf_antennas);
10666 prefs_register_obsolete_preference(oran_module, "oran.num_weights_per_bundle");
10667 prefs_register_obsolete_preference(oran_module, "oran.num_bf_weights");
10668 prefs_register_bool_preference(oran_module, "oran.st6_4byte_alignment_required", "Use 4-byte alignment for ST6 sections",
10669 "Default is 1-byte alignment", &st6_4byte_alignment);
10670
10671 /* Misc (and will seldom need to be accessed) */
10672 prefs_register_static_text_preference(oran_module, "oran.misc", "", "");
10673 prefs_register_bool_preference(oran_module, "oran.show_iq_samples", "Show IQ Sample values",
10674 "When enabled, for U-Plane frames show each I and Q value in PRB", &pref_showIQSampleValues);
10675 prefs_register_enum_preference(oran_module, "oran.support_udcomplen", "udCompLen supported",
10676 "When enabled, U-Plane messages with relevant compression schemes will include udCompLen",
10677 &pref_support_udcompLen, udcomplen_support_options, false0);
10678 prefs_register_uint_preference(oran_module, "oran.rbs_in_uplane_section", "Total RBs in User-Plane data section",
10679 "This is used if numPrbu is signalled as 0", 10, &pref_data_plane_section_total_rbs);
10680 prefs_register_bool_preference(oran_module, "oran.unscaled_iq", "Show unscaled I/Q values",
10681 "", &show_unscaled_values);
10682 prefs_register_bool_preference(oran_module, "oran.attempt_reassembly",
10683 "Attempt Radio Transport layer reassembly", "",
10684 &do_radio_transport_layer_reassembly);
10685 prefs_register_obsolete_preference(oran_module, "oran.k_antenna_ports");
10686
10687 prefs_register_bool_preference(oran_module, "oran.link_planes",
10688 "Link C-plane and U-plane using sectionId", "",
10689 &link_planes_together);
10690
10691
10692 flow_states_table = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
10693 flow_results_table = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
10694 ul_symbol_timing = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
10695
10696 dl_beam_ids_defined = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
10697 dl_beam_ids_results = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
10698
10699 register_init_routine(&oran_init_protocol);
10700
10701 /* Register reassembly table. */
10702 reassembly_table_register(&oran_reassembly_table,
10703 &oran_reassembly_table_functions);
10704}
10705
10706/*
10707* Editor modelines - http://www.wireshark.org/tools/modelines.html
10708*
10709* Local Variables:
10710* c-basic-offset: 4
10711* tab-width: 8
10712* indent-tabs-mode: nil
10713* End:
10714*
10715* ex: set shiftwidth=4 tabstop=8 expandtab:
10716* :indentSize=4:tabSize=8:noTabs=true:
10717*/