Bug Summary

File:builds/wireshark/wireshark/epan/dissectors/packet-oran.c
Warning:line 7201, 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-06-29-100418-3576-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 <gerald@wireshark.org>
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_EXTTYPE30];
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 { 0, NULL((void*)0)}
975};
976
977static const value_string beam_type_vals[] = {
978 { 0, "List of beamId values" },
979 { 1, "Range of beamId values" },
980 { 0, NULL((void*)0)}
981};
982
983/* 7.7.24.3 */
984static const value_string entry_type_vals[] = {
985 { 0, "inherit config from preceding entry (2 or 3) ueIdReset=0" },
986 { 1, "inherit config from preceding entry (2 or 3) ueIdReset=1" },
987 { 2, "related parameters if have transform precoding disabled " },
988 { 3, "related parameters if have transform precoding enabled " },
989 { 0, NULL((void*)0)}
990};
991
992/* Table 7.7.29.3-1 */
993static const range_string cd_scg_size_vals[] = {
994 { 0, 0, "1 subcarrier" },
995 { 1, 1, "1 RB x N subcarriers" },
996 { 2, 2, "2 RB x N subcarriers" },
997 { 3, 3, "4 RB x N subcarriers" },
998 { 4, 4, "8 RB x N subcarriers" },
999 { 5, 5, "16 RB x N subcarriers" },
1000 { 6, 6, "32 RB x N subcarriers" },
1001 { 7, 15, "reserved"},
1002 { 0, 0, NULL((void*)0)}
1003};
1004
1005
1006/* Table 7.6.1-1 */
1007static const value_string exttype_vals[] = {
1008 {0, "Reserved"},
1009 {1, "Beamforming weights"},
1010 {2, "Beamforming attributes"},
1011 {3, "DL Precoding configuration parameters and indications"},
1012 {4, "Modulation compr. params"},
1013 {5, "Modulation compression additional scaling parameters"},
1014 {6, "Non-contiguous PRB allocation"},
1015 {7, "Multiple-eAxC designation"},
1016 {8, "Regularization factor"},
1017 {9, "Dynamic Spectrum Sharing parameters"},
1018 {10, "Multiple ports grouping"},
1019 {11, "Flexible BF weights"},
1020 {12, "Non-Contiguous PRB Allocation with Frequency Ranges"},
1021 {13, "PRB Allocation with Frequency Hopping"},
1022 {14, "Nulling-layer Info. for ueId-based beamforming"},
1023 {15, "Mixed-numerology Info. for ueId-based beamforming"},
1024 {16, "Section description for antenna mapping in UE channel information based UL beamforming"},
1025 {17, "Section description for indication of user port group"},
1026 {18, "Section description for Uplink Transmission Management"},
1027 {19, "Compact beamforming information for multiple port"},
1028 {20, "Puncturing extension"},
1029 {21, "Variable PRB group size for channel information"},
1030 {22, "ACK/NACK request"},
1031 {23, "Multiple symbol modulation compression parameters"},
1032 {24, "PUSCH DMRS configuration"},
1033 {25, "Symbol reordering for DMRS-BF"},
1034 {26, "Frequency offset feedback"},
1035 {27, "O-DU controlled dimensionality reduction"},
1036 {28, "O-DU controlled frequency resolution for SINR reporting"},
1037 {29, "Cyclic delay adjustment"},
1038 {30, "PUSCH repetition indication"},
1039 {0, NULL((void*)0)}
1040};
1041static 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) }
;
1042
1043
1044/**************************************************************************************/
1045/* Keep track for each Section Extension, which section types are allowed to carry it */
1046typedef struct {
1047 bool_Bool ST0;
1048 bool_Bool ST1;
1049 bool_Bool ST3;
1050 bool_Bool ST5;
1051 bool_Bool ST6;
1052 bool_Bool ST10;
1053 bool_Bool ST11;
1054} AllowedCTs_t;
1055
1056
1057static const AllowedCTs_t ext_cts[HIGHEST_EXTTYPE30] = {
1058 /* ST0 ST1 ST3 ST5 ST6 ST10 ST11 */
1059 { false0, true1, true1, false0, false0, false0, false0}, // SE 1 (1,3)
1060 { false0, true1, true1, false0, false0, false0, false0}, // SE 2 (1,3)
1061 { false0, true1, true1, false0, false0, false0, false0}, // SE 3 (1,3)
1062 { false0, true1, true1, true1, false0, false0, false0}, // SE 4 (1,3,5)
1063 { false0, true1, true1, true1, false0, false0, false0}, // SE 5 (1,3,5)
1064 { false0, true1, true1, true1, false0, true1, true1 }, // SE 6 (1,3,5,10,11)
1065 { true1, false0, false0, false0, false0, false0, false0}, // SE 7 (0)
1066 { false0, false0, false0, true1, false0, false0, false0}, // SE 8 (5)
1067 { true1, true1, true1, true1, true1, true1, true1 }, // SE 9 (all)
1068 { false0, true1, true1, true1, false0, false0, false0}, // SE 10 (1,3,5)
1069 { false0, true1, true1, false0, false0, false0, false0}, // SE 11 (1,3)
1070 { false0, true1, true1, true1, false0, true1, true1 }, // SE 12 (1,3,5,10,11)
1071 { false0, true1, true1, true1, false0, false0, false0}, // SE 13 (1,3,5)
1072 { false0, false0, false0, true1, false0, false0, false0}, // SE 14 (5)
1073 { false0, false0, false0, true1, true1, false0, false0}, // SE 15 (5,6)
1074 { false0, false0, false0, true1, false0, false0, false0}, // SE 16 (5)
1075 { false0, false0, false0, true1, false0, false0, false0}, // SE 17 (5)
1076 { false0, true1, true1, true1, false0, false0, false0}, // SE 18 (1,3,5)
1077 { false0, true1, true1, false0, false0, false0, false0}, // SE 19 (1,3)
1078 { true1, true1, true1, true1, true1, true1, true1 }, // SE 20 (0,1,3,5,10,11)
1079 { false0, false0, false0, true1, true1, false0, false0}, // SE 21 (5,6)
1080 { true1, true1, true1, true1, true1, true1, true1 }, // SE 22 (all)
1081 { false0, true1, true1, true1, false0, false0, false0}, // SE 23 (1,3,5)
1082 { false0, false0, false0, true1, false0, false0, false0}, // SE 24 (5)
1083 { false0, false0, false0, true1, false0, false0, false0}, // SE 25 (5)
1084 { false0, false0, false0, true1, false0, false0, false0}, // SE 26 (5)
1085 { false0, false0, false0, true1, false0, false0, false0}, // SE 27 (5)
1086 { false0, false0, false0, true1, false0, false0, false0}, // SE 28 (5)
1087 { false0, true1, true1, true1, false0, false0, false0}, // SE 29 (1,3,5)
1088 { false0, false0, false0, true1, false0, false0, false0}, // SE 30 (5)
1089};
1090
1091static bool_Bool se_allowed_in_st(unsigned se, unsigned st)
1092{
1093 if (se==0 || se>HIGHEST_EXTTYPE30) {
1094 /* Don't know about new SE, so don't complain.. */
1095 return true1;
1096 }
1097
1098 switch (st) {
1099 case 0:
1100 return ext_cts[se-1].ST0;
1101 case 1:
1102 return ext_cts[se-1].ST1;
1103 case 3:
1104 return ext_cts[se-1].ST3;
1105 case 5:
1106 return ext_cts[se-1].ST5;
1107 case 6:
1108 return ext_cts[se-1].ST6;
1109 case 10:
1110 return ext_cts[se-1].ST10;
1111 case 11:
1112 return ext_cts[se-1].ST11;
1113 default:
1114 /* New/unknown section type that includes 'ef'.. assume ok */
1115 return true1;
1116 }
1117}
1118
1119/************************************************************************************/
1120
1121/* Table 7.7.1.2-2 */
1122static const value_string bfw_comp_headers_iq_width[] = {
1123 {0, "I and Q are 16 bits wide"},
1124 {1, "I and Q are 1 bit wide"},
1125 {2, "I and Q are 2 bits wide"},
1126 {3, "I and Q are 3 bits wide"},
1127 {4, "I and Q are 4 bits wide"},
1128 {5, "I and Q are 5 bits wide"},
1129 {6, "I and Q are 6 bits wide"},
1130 {7, "I and Q are 7 bits wide"},
1131 {8, "I and Q are 8 bits wide"},
1132 {9, "I and Q are 9 bits wide"},
1133 {10, "I and Q are 10 bits wide"},
1134 {11, "I and Q are 11 bits wide"},
1135 {12, "I and Q are 12 bits wide"},
1136 {13, "I and Q are 13 bits wide"},
1137 {14, "I and Q are 14 bits wide"},
1138 {15, "I and Q are 15 bits wide"},
1139 {0, NULL((void*)0)}
1140};
1141
1142/* Table 7.7.1.2-3 */
1143static const value_string bfw_comp_headers_comp_meth[] = {
1144 {COMP_NONE0, "no compression"},
1145 {COMP_BLOCK_FP1, "block floating point"},
1146 {COMP_BLOCK_SCALE2, "block scaling"},
1147 {COMP_U_LAW3, "u-law"},
1148 {4, "beamspace compression type I"},
1149 {5, "beamspace compression type II"},
1150 {0, NULL((void*)0)}
1151};
1152
1153/* 7.7.6.2 rbgSize (resource block group size) */
1154static const value_string rbg_size_vals[] = {
1155 {0, "reserved"},
1156 {1, "1"},
1157 {2, "2"},
1158 {3, "3"},
1159 {4, "4"},
1160 {5, "6"},
1161 {6, "8"},
1162 {7, "16"},
1163 {0, NULL((void*)0)}
1164};
1165
1166/* 7.7.6.5 */
1167static const value_string priority_vals[] = {
1168 {0, "0"},
1169 {1, "+1"},
1170 {2, "-2 (reserved, should not be used)"},
1171 {3, "-1"},
1172 {0, NULL((void*)0)}
1173};
1174
1175/* 7.7.10.2 beamGroupType */
1176static const value_string beam_group_type_vals[] = {
1177 {0x0, "common beam"},
1178 {0x1, "beam matrix indication"},
1179 {0x2, "beam vector listing"},
1180 {0x3, "beamId/ueId listing with associated port-list index"},
1181 {0, NULL((void*)0)}
1182};
1183
1184/* 7.7.9.2 technology (interface name) */
1185static const value_string interface_name_vals[] = {
1186 {0x0, "LTE"},
1187 {0x1, "NR"},
1188 {0, NULL((void*)0)}
1189};
1190
1191/* 7.7.18.4 toT (type of transmission) */
1192static const value_string type_of_transmission_vals[] = {
1193 {0x0, "normal transmission mode, data can be distributed in any way the O-RU is implemented to transmit data"},
1194 {0x1, "uniformly distributed over the transmission window"},
1195 {0x2, "Reserved"},
1196 {0x3, "Reserved"},
1197 {0, NULL((void*)0)}
1198};
1199
1200/* 7.7.2.2 (width of bfa parameters) */
1201static const value_string bfa_bw_vals[] = {
1202 {0, "no bits, the field is not applicable (e.g., O-RU does not support it) or the default value shall be used"},
1203 {1, "2-bit bitwidth"},
1204 {2, "3-bit bitwidth"},
1205 {3, "4-bit bitwidth"},
1206 {4, "5-bit bitwidth"},
1207 {5, "6-bit bitwidth"},
1208 {6, "7-bit bitwidth"},
1209 {7, "8-bit bitwidth"},
1210 {0, NULL((void*)0)}
1211};
1212
1213/* 7.7.2.7 & 7.7.2.8 */
1214static const value_string sidelobe_suppression_vals[] = {
1215 {0, "10 dB"},
1216 {1, "15 dB"},
1217 {2, "20 dB"},
1218 {3, "25 dB"},
1219 {4, "30 dB"},
1220 {5, "35 dB"},
1221 {6, "40 dB"},
1222 {7, ">= 45 dB"},
1223 {0, NULL((void*)0)}
1224};
1225
1226static const value_string lbtTrafficClass_vals[] = {
1227 {1, "Priority 1"},
1228 {2, "Priority 2"},
1229 {3, "Priority 3"},
1230 {4, "Priority 4"},
1231 {0, NULL((void*)0)}
1232};
1233
1234/* 7.5.3.22 */
1235static const value_string lbtPdschRes_vals[] = {
1236 {0, "not sensing – indicates that the O-RU is transmitting data"},
1237 {1, "currently sensing – indicates the O-RU has not yet acquired the channel"},
1238 {2, "success – indicates that the channel was successfully acquired"},
1239 {3, "Failure – indicates expiration of the LBT timer. The LBT process should be reset"},
1240 {0, NULL((void*)0)}
1241};
1242
1243/* Table 7.5.2.15-3 */
1244static const value_string ci_comp_opt_vals[] = {
1245 {0, "compression per UE, one ciCompParam exists before the I/Q value of each UE"},
1246 {1, "compression per PRB, one ciCompParam exists before the I/Q value of each PRB"},
1247 {0, NULL((void*)0)}
1248};
1249
1250/* 7.5.2.17 */
1251static const range_string cmd_scope_vals[] = {
1252 {0, 0, "ARRAY-COMMAND"},
1253 {1, 1, "CARRIER-COMMAND"},
1254 {2, 2, "O-RU-COMMAND"},
1255 {3, 15, "reserved"},
1256 {0, 0, NULL((void*)0)}
1257};
1258
1259/* N.B., table in 7.5.3.38 is truncated.. */
1260static const range_string st4_cmd_type_vals[] = {
1261 {0, 0, "reserved for future command types"},
1262 {1, 1, "TIME_DOMAIN_BEAM_CONFIG"},
1263 {2, 2, "TDD_CONFIG_PATTERN"},
1264 {3, 3, "TRX_CONTROL"},
1265 {4, 4, "ASM"},
1266 {5, 255, "reserved for future command types"},
1267 {0, 0, NULL((void*)0)}
1268};
1269
1270/* Table 7.5.3.51-1 */
1271static const value_string log2maskbits_vals[] = {
1272 {0, "reserved"},
1273 {1, "min antMask size is 16 bits.."},
1274 {2, "min antMask size is 16 bits.."},
1275 {3, "min antMask size is 16 bits.."},
1276 {4, "16 bits"},
1277 {5, "32 bits"},
1278 {6, "64 bits"},
1279 {7, "128 bits"},
1280 {8, "256 bits"},
1281 {9, "512 bits"},
1282 {10, "1024 bits"},
1283 {11, "2048 bits"},
1284 {12, "4096 bits"},
1285 {13, "8192 bits"},
1286 {14, "16384 bits"},
1287 {15, "reserved"},
1288 {0, NULL((void*)0)}
1289};
1290
1291/* Table 16.1-1 Sleep modes */
1292static const value_string sleep_mode_trx_vals[] = {
1293 { 0, "TRXC-mode0-wake-up-duration (symbol)"},
1294 { 1, "TRXC-mode1-wake-up-duration (L)"},
1295 { 2, "TRXC-mode2-wake-up-duration (M)"},
1296 { 3, "TRXC-mode3-wake-up-duration (N)"},
1297 { 0, NULL((void*)0)}
1298};
1299
1300static const value_string sleep_mode_asm_vals[] = {
1301 { 0, "ASM-mode0-wake-up-duration (symbol)"},
1302 { 1, "ASM-mode1-wake-up-duration (L)"},
1303 { 2, "ASM-mode2-wake-up-duration (M)"},
1304 { 3, "ASM-mode3-wake-up-duration (N)"},
1305 { 0, NULL((void*)0)}
1306};
1307
1308/* 7.7.21.3.1 */
1309static const value_string prg_size_st5_vals[] = {
1310 { 0, "reserved"},
1311 { 1, "Precoding resource block group size as WIDEBAND"},
1312 { 2, "Precoding resource block group size 2"},
1313 { 3, "Precoding resource block group size 4"},
1314 { 0, NULL((void*)0)}
1315};
1316
1317/* 7.7.21.3.2 */
1318static const value_string prg_size_st6_vals[] = {
1319 { 0, "if ciPrbGroupSize is 2 or 4, then ciPrbGroupSize, else WIDEBAND"},
1320 { 1, "Precoding resource block group size as WIDEBAND"},
1321 { 2, "Precoding resource block group size 2"},
1322 { 3, "Precoding resource block group size 4"},
1323 { 0, NULL((void*)0)}
1324};
1325
1326/* 7.7.24.4 */
1327static const value_string alpn_per_sym_vals[] = {
1328 { 0, "report one allocated IPN value per all allocated symbols with DMRS"},
1329 { 1, "report one allocated IPN value per group of consecutive DMRS symbols"},
1330 { 0, NULL((void*)0)}
1331};
1332
1333/* 7.7.24.5 */
1334static const value_string ant_dmrs_snr_vals[] = {
1335 { 0, "O-RU shall not report the MEAS_ANT_DMRS_SNR"},
1336 { 1, "O-RU shall report the MEAS_ANT_DMRS_SNR"},
1337 { 0, NULL((void*)0)}
1338};
1339
1340/* 7.7.24.14 */
1341static const value_string dtype_vals[] = {
1342 { 0, "assume DMRS configuration type 1"},
1343 { 1, "assume DMRS configuration type 2"},
1344 { 0, NULL((void*)0)}
1345};
1346
1347/* 7.7.24.17 */
1348static const value_string papr_type_vals[] = {
1349 { 0, "sequence generator type 1 for short sequence lengths"},
1350 { 1, "sequence generator type 1 for long sequence lengths"},
1351 { 2, "sequence generator type 2 for short sequence lengths"},
1352 { 3, "sequence generator type 2 for long sequence lengths"},
1353 { 0, NULL((void*)0)}
1354};
1355
1356/* 7.7.24.18 */
1357static const value_string hopping_mode_vals[] = {
1358 { 0, "neither group, nor sequence hopping is enabled"},
1359 { 1, "group hopping is enabled and sequence hopping is disabled"},
1360 { 2, "sequence hopping is enabled and group hopping is disabled"},
1361 { 3, "reserved"},
1362 { 0, NULL((void*)0)}
1363};
1364
1365
1366static const true_false_string tfs_sfStatus =
1367{
1368 "subframe was transmitted",
1369 "subframe was dropped"
1370};
1371
1372static const true_false_string tfs_lbtBufErr =
1373{
1374 "buffer overflow – data received at O-RU is larger than the available buffer size",
1375 "reserved"
1376};
1377
1378static const true_false_string tfs_partial_full_sf = {
1379 "partial SF",
1380 "full SF"
1381};
1382
1383static const true_false_string disable_tdbfns_tfs = {
1384 "beam numbers excluded",
1385 "beam numbers included"
1386};
1387
1388static const true_false_string continuity_indication_tfs = {
1389 "continuity between current and next bundle",
1390 "discontinuity between current and next bundle"
1391};
1392
1393static const true_false_string prb_mode_tfs = {
1394 "PRB-BLOCK mode",
1395 "PRB-MASK mode"
1396};
1397
1398static const true_false_string symbol_direction_tfs = {
1399 "DL symbol",
1400 "UL symbol"
1401};
1402
1403static const true_false_string symbol_guard_tfs = {
1404 "guard symbol",
1405 "non-guard symbol"
1406};
1407
1408static const true_false_string beam_numbers_included_tfs = {
1409 "time-domain beam numbers excluded in this command",
1410 "time-domain beam numbers included in this command"
1411};
1412
1413static const true_false_string measurement_flag_tfs = {
1414 "at least one additional measurement report or command after the current one",
1415 "no additional measurement report or command"
1416};
1417
1418static const true_false_string repetition_se6_tfs = {
1419 "repeated highest priority data section in the C-Plane message",
1420 "no repetition"
1421};
1422
1423static const true_false_string repetition_se19_tfs = {
1424 "per port information not present in the extension",
1425 "per port info present in the extension"
1426};
1427
1428static const true_false_string tfs_report_no_report_pos_meas =
1429{
1430 "Report MEAS_UE_POS for UE",
1431 "Do not report UE_POS for UE"
1432};
1433
1434
1435/* Forward declaration */
1436static int dissect_udcompparam(tvbuff_t *tvb, packet_info *pinfo _U___attribute__((unused)), proto_tree *tree, unsigned offset,
1437 unsigned comp_meth,
1438 uint32_t *exponent, uint16_t *sReSMask, bool_Bool for_sinr);
1439
1440
1441static const true_false_string ready_tfs = {
1442 "message is a \"ready\" message",
1443 "message is a ACK message"
1444};
1445
1446static const true_false_string multi_sd_scope_tfs = {
1447 "Puncturing pattern applies to current and following sections",
1448 "Puncturing pattern applies to current section"
1449};
1450
1451static const true_false_string tfs_ueid_reset = {
1452 "cannot assume same UE as in preceding slot",
1453 "can assume same UE as in preceding slot"
1454};
1455
1456
1457/* Config for (and later, worked-out allocations) bundles for ext11 (dynamic BFW) */
1458typedef struct {
1459 /* Ext 6 config */
1460 bool_Bool ext6_set;
1461 uint8_t ext6_rbg_size; /* number of PRBs allocated by bitmask */
1462
1463 uint8_t ext6_num_bits_set;
1464 uint8_t ext6_bits_set[28]; /* Which bit position this entry has */
1465 /* TODO: store an f value for each bit position? */
1466
1467 /* Ext 12 config */
1468 bool_Bool ext12_set;
1469 unsigned ext12_num_pairs;
1470#define MAX_BFW_EXT12_PAIRS128 128
1471 struct {
1472 uint8_t off_start_prb;
1473 uint8_t num_prb;
1474 } ext12_pairs[MAX_BFW_EXT12_PAIRS128];
1475
1476 /* Ext 13 config */
1477 bool_Bool ext13_set;
1478 unsigned ext13_num_start_prbs;
1479#define MAX_BFW_EXT13_ALLOCATIONS128 128
1480 unsigned ext13_start_prbs[MAX_BFW_EXT13_ALLOCATIONS128];
1481 /* TODO: store nextSymbolId here too? */
1482
1483 /* Ext 21 config */
1484 bool_Bool ext21_set;
1485 uint8_t ext21_ci_prb_group_size;
1486
1487 /* Results/settings (after calling ext11_work_out_bundles()) */
1488 uint32_t num_bundles;
1489#define MAX_BFW_BUNDLES512 512
1490 struct {
1491 uint32_t start; /* first prb of bundle */
1492 uint32_t end; /* last prb of bundle*/
1493 bool_Bool is_orphan; /* true if not complete (i.e., end-start < numBundPrb) */
1494 } bundles[MAX_BFW_BUNDLES512];
1495} ext11_settings_t;
1496
1497
1498/* Work out bundle allocation for ext 11. Take into account ext6/ext21, ext12 or ext13 in this section before ext 11. */
1499/* Won't be called with numBundPrb=0 */
1500static void ext11_work_out_bundles(unsigned startPrbc,
1501 unsigned numPrbc,
1502 unsigned numBundPrb, /* number of PRBs per (full) bundle */
1503 ext11_settings_t *settings)
1504{
1505 /* Allocation configured by ext 6 */
1506 if (settings->ext6_set) {
1507 unsigned bundles_per_entry = (settings->ext6_rbg_size / numBundPrb);
1508
1509 /* Need to cope with these not dividing exactly, or even having more PRbs in a bundle that
1510 rbg size. i.e. each bundle gets the correct number of PRBs until
1511 all rbg entries are consumed... */
1512
1513 /* TODO: need to check 7.9.4.2. Different cases depending upon value of RAD */
1514
1515 if (bundles_per_entry == 0) {
1516 bundles_per_entry = 1;
1517 }
1518
1519 /* Ext6 behaviour may also be affected by ext 21 */
1520 if (settings->ext21_set) {
1521 /* N.B., have already checked that numPrbc is not 0 */
1522
1523 /* ciPrbGroupSize overrides number of contiguous PRBs in group */
1524 bundles_per_entry = (settings->ext6_rbg_size / settings->ext21_ci_prb_group_size);
1525
1526 /* numPrbc is the number of PRB groups per antenna - handled in call to dissect_bfw_bundle() */
1527 }
1528
1529 unsigned bundles_set = 0;
1530 bool_Bool reached_orphan = false0;
1531 /* For each bit set in ext6 rbg mask.. */
1532 for (unsigned n=0;
1533 !reached_orphan && n < (settings->ext6_num_bits_set * settings->ext6_rbg_size) / numBundPrb;
1534 n++) {
1535
1536 /* Watch out for array bound */
1537 if (n >= 28) {
1538 break;
1539 }
1540
1541 /* For each bundle... */
1542
1543 /* TODO: Work out where first PRB is */
1544 /* May not be the start of an rbg block... */
1545 uint32_t prb_start = (settings->ext6_bits_set[n] * settings->ext6_rbg_size);
1546
1547 /* For each bundle within identified rbgSize block */
1548 for (unsigned m=0; !reached_orphan && m < bundles_per_entry; m++) {
1549
1550 settings->bundles[bundles_set].start = startPrbc+prb_start+(m*numBundPrb);
1551
1552 /* Start already beyond end, so doesn't count. */
1553 if (settings->bundles[bundles_set].start > (startPrbc+numPrbc-1)) {
1554 settings->num_bundles = bundles_set;
1555 return;
1556 }
1557
1558 /* Bundle consists of numBundPrb bundles */
1559 /* TODO: may involve PRBs from >1 rbg blocks.. */
1560 settings->bundles[bundles_set].end = startPrbc+prb_start+((m+1)*numBundPrb)-1;
1561 if (settings->bundles[bundles_set].end > (startPrbc+numPrbc-1)) {
1562 /* Extends beyond end, so counts but is an orphan bundle */
1563 settings->bundles[bundles_set].end = startPrbc+numPrbc-1;
1564 settings->bundles[bundles_set].is_orphan = true1;
1565 reached_orphan = true1;
1566 }
1567
1568 /* Get out if have reached array bound */
1569 if (++bundles_set == MAX_BFW_BUNDLES512) {
1570 return;
1571 }
1572 }
1573 }
1574 settings->num_bundles = bundles_set;
1575 }
1576
1577 /* Allocation configured by ext 12 */
1578 else if (settings->ext12_set) {
1579 /* First, allocate normally from startPrbc, numPrbc */
1580 settings->num_bundles = (numPrbc+numBundPrb-1) / numBundPrb;
1581
1582 /* Don't overflow settings->bundles[] ! */
1583 settings->num_bundles = MIN(MAX_BFW_BUNDLES, settings->num_bundles)(((512) < (settings->num_bundles)) ? (512) : (settings->
num_bundles))
;
1584
1585 for (uint32_t n=0; n < settings->num_bundles; n++) {
1586 settings->bundles[n].start = startPrbc + n*numBundPrb;
1587 settings->bundles[n].end = settings->bundles[n].start + numBundPrb-1;
1588 /* Does it go beyond the end? */
1589 if (settings->bundles[n].end > startPrbc+numPrbc) {
1590 settings->bundles[n].end = startPrbc+numPrbc;
1591 settings->bundles[n].is_orphan = true1;
1592 }
1593 }
1594 if (settings->num_bundles == MAX_BFW_BUNDLES512) {
1595 return;
1596 }
1597
1598 unsigned prb_offset = startPrbc + numPrbc;
1599
1600 /* Loop over pairs, adding bundles for each */
1601 for (unsigned p=0; p < settings->ext12_num_pairs; p++) {
1602 prb_offset += settings->ext12_pairs[p].off_start_prb;
1603 unsigned pair_bundles = (settings->ext12_pairs[p].num_prb+numBundPrb-1) / numBundPrb;
1604
1605 for (uint32_t n=0; n < pair_bundles; n++) {
1606 unsigned idx = settings->num_bundles;
1607
1608 settings->bundles[idx].start = prb_offset + n*numBundPrb;
1609 settings->bundles[idx].end = settings->bundles[idx].start + numBundPrb-1;
1610 /* Does it go beyond the end? */
1611 if (settings->bundles[idx].end > prb_offset + settings->ext12_pairs[p].num_prb) {
1612 settings->bundles[idx].end = prb_offset + settings->ext12_pairs[p].num_prb;
1613 settings->bundles[idx].is_orphan = true1;
1614 }
1615 /* Range check / return */
1616 settings->num_bundles++;
1617 if (settings->num_bundles == MAX_BFW_BUNDLES512) {
1618 return;
1619 }
1620 }
1621
1622 prb_offset += settings->ext12_pairs[p].num_prb;
1623 }
1624 }
1625
1626 /* Allocation configured by ext 13 */
1627 else if (settings->ext13_set) {
1628 unsigned alloc_size = (numPrbc+numBundPrb-1) / numBundPrb;
1629 settings->num_bundles = alloc_size * settings->ext13_num_start_prbs;
1630
1631 /* Don't overflow settings->bundles[] ! */
1632 settings->num_bundles = MIN(MAX_BFW_BUNDLES, settings->num_bundles)(((512) < (settings->num_bundles)) ? (512) : (settings->
num_bundles))
;
1633
1634 for (unsigned alloc=0; alloc < settings->ext13_num_start_prbs; alloc++) {
1635 unsigned alloc_start = alloc * alloc_size;
1636 for (uint32_t n=0; n < alloc_size; n++) {
1637 if ((alloc_start+n) >= MAX_BFW_BUNDLES512) {
1638 /* ERROR */
1639 return;
1640 }
1641 settings->bundles[alloc_start+n].start = settings->ext13_start_prbs[alloc] + startPrbc + n*numBundPrb;
1642 settings->bundles[alloc_start+n].end = settings->bundles[alloc_start+n].start + numBundPrb-1;
1643 if (settings->bundles[alloc_start+n].end > settings->ext13_start_prbs[alloc] + numPrbc) {
1644 settings->bundles[alloc_start+n].end = settings->ext13_start_prbs[alloc] + numPrbc;
1645 settings->bundles[alloc_start+n].is_orphan = true1;
1646 }
1647 }
1648 }
1649 }
1650
1651 /* Case where bundles are not controlled by other extensions - just divide up range into bundles we have */
1652 else {
1653 settings->num_bundles = (numPrbc+numBundPrb-1) / numBundPrb; /* rounded up */
1654
1655 /* Don't overflow settings->bundles[] */
1656 settings->num_bundles = MIN(MAX_BFW_BUNDLES, settings->num_bundles)(((512) < (settings->num_bundles)) ? (512) : (settings->
num_bundles))
;
1657
1658 /* For each bundle.. */
1659 for (uint32_t n=0; n < settings->num_bundles; n++) {
1660 /* Allocate start and end */
1661 settings->bundles[n].start = startPrbc + n*numBundPrb;
1662 settings->bundles[n].end = settings->bundles[n].start + numBundPrb - 1;
1663 /* If would go beyond end of PRBs, limit and identify as orphan */
1664 if (settings->bundles[n].end > startPrbc+numPrbc) {
1665 settings->bundles[n].end = startPrbc+numPrbc;
1666 settings->bundles[n].is_orphan = true1;
1667 }
1668 }
1669 }
1670}
1671
1672
1673/* Modulation Compression configuration */
1674typedef struct {
1675 /* Application of each entry is filtered by RE.
1676 * TODO: should also be filtered by PRB + symbol... */
1677 uint16_t mod_compr_re_mask;
1678
1679 /* Settings to apply */
1680 bool_Bool mod_compr_csf;
1681 float mod_compr_scaler;
1682} mod_compr_config_t;
1683
1684/* Multiple configs with a section */
1685typedef struct {
1686 uint16_t section_id;
1687 uint32_t num_configs;
1688
1689 #define MAX_MOD_COMPR_CONFIGS12 12
1690 mod_compr_config_t configs[MAX_MOD_COMPR_CONFIGS12];
1691} section_mod_compr_config_t;
1692
1693/* Flow has separate configs for each section */
1694typedef struct {
1695 uint16_t num_sections;
1696
1697 /* Separate config for each section */
1698 section_mod_compr_config_t sections[MAX_SECTION_IDs32];
1699} mod_compr_params_t;
1700
1701
1702typedef struct {
1703 uint32_t frame_number;
1704 nstime_t frame_time;
1705
1706 /* Timing to match */
1707 uint8_t frame;
1708 uint8_t subframe;
1709 uint8_t slot;
1710 uint8_t startSymbol;
1711
1712 bool_Bool in_use;
1713 uint16_t startPrb;
1714 uint16_t numPrb;
1715 uint16_t numSymbols;
1716 uint16_t beamIds[273];
1717} section_details_t;
1718
1719typedef struct {
1720 uint16_t sectionId;
1721 /* For the same sectionId, can have 2 currently active entries.. */
1722 section_details_t details[2];
1723} expected_section_data_t;
1724
1725
1726/*******************************************************/
1727/* Overall state of a flow (eAxC/plane) */
1728typedef struct {
1729 /* State for sequence analysis [each direction] */
1730 bool_Bool last_frame_seen[2];
1731 uint32_t last_frame[2];
1732 uint8_t next_expected_sequence_number[2];
1733
1734 /* DL expected frames. sectionId -> expected_section_data_t* */
1735 wmem_tree_t *expected_dl_sections;
1736
1737 /* Table recording ackNack requests (ackNackId -> ack_nack_request_t*)
1738 Note that this assumes that the same ackNackId will not be reused within a state,
1739 which may well not be valid */
1740 wmem_tree_t *ack_nack_requests;
1741
1742 /* Store udCompHdr seen in C-Plane for UL - can be looked up and used by U-PLane.
1743 Note that this appears in the common section header parts of ST1, ST3, ST5,
1744 so can still be over-written per sectionId in the U-Plane */
1745 unsigned ul_ud_comp_hdr_frame;
1746 bool_Bool ul_ud_comp_hdr_set;
1747 unsigned ul_ud_comp_hdr_bit_width;
1748 int ul_ud_comp_hdr_compression;
1749
1750 bool_Bool udcomphdrDownlink_heuristic_result_set;
1751 bool_Bool udcomphdrDownlink_heuristic_result;
1752 bool_Bool udcomphdrUplink_heuristic_result_set;
1753 bool_Bool udcomphdrUplink_heuristic_result;
1754
1755 /* Modulation compression params */
1756 mod_compr_params_t mod_comp_params;
1757} flow_state_t;
1758
1759static section_mod_compr_config_t* get_mod_compr_section_to_write(flow_state_t *flow,
1760 unsigned sectionId)
1761{
1762 if (flow == NULL((void*)0)) {
1763 return NULL((void*)0);
1764 }
1765
1766 /* Look for this section among existing entries */
1767 for (unsigned s=0; s < flow->mod_comp_params.num_sections; s++) {
1768 if (flow->mod_comp_params.sections[s].section_id == sectionId) {
1769 return &flow->mod_comp_params.sections[s];
1770 }
1771 }
1772
1773 /* Not found, so try to add a new one */
1774 if (flow->mod_comp_params.num_sections >= MAX_SECTION_IDs32) {
1775 /* Can't allocate one! */
1776 return NULL((void*)0);
1777 }
1778 else {
1779 flow->mod_comp_params.sections[flow->mod_comp_params.num_sections].section_id = sectionId;
1780 return &flow->mod_comp_params.sections[flow->mod_comp_params.num_sections++];
1781 }
1782}
1783
1784static section_mod_compr_config_t* get_mod_compr_section_to_read(flow_state_t *flow,
1785 unsigned sectionId)
1786{
1787 if (flow == NULL((void*)0)) {
1788 return NULL((void*)0);
1789 }
1790
1791 /* Look for this section among existing entries */
1792 for (unsigned s=0; s < flow->mod_comp_params.num_sections; s++) {
1793 if (flow->mod_comp_params.sections[s].section_id == sectionId) {
1794 return &flow->mod_comp_params.sections[s];
1795 }
1796 }
1797
1798 /* Not found */
1799 return NULL((void*)0);
1800}
1801
1802
1803
1804typedef struct {
1805 uint32_t request_frame_number;
1806 nstime_t request_frame_time;
1807 enum {
1808 SE22,
1809 ST4Cmd1,
1810 ST4Cmd2,
1811 ST4Cmd3,
1812 ST4Cmd4
1813 } requestType;
1814
1815 uint32_t response_frame_number;
1816 nstime_t response_frame_time;
1817} ack_nack_request_t;
1818
1819static const value_string acknack_type_vals[] = {
1820 { SE22, "SE 22" },
1821 { ST4Cmd1, "ST4 (TIME_DOMAIN_BEAM_CONFIG)" },
1822 { ST4Cmd2, "ST4 (TDD_CONFIG_PATTERN)" },
1823 { ST4Cmd3, "ST4 (TRX_CONTROL)" },
1824 { ST4Cmd4, "ST4 (ASM)" },
1825 { 0, NULL((void*)0)}
1826};
1827
1828#define ORAN_C_PLANE0 0
1829#define ORAN_U_PLANE1 1
1830
1831/* Using parts of src/dst MAC address, so don't confuse UL messages with DL messages configuring UL.. */
1832static uint32_t make_flow_key(packet_info *pinfo, uint16_t eaxc_id, uint8_t plane, bool_Bool opposite_dir)
1833{
1834 uint16_t eth_bits = 0;
1835 if (pinfo->dl_src.len == 6 && pinfo->dl_dst.len == 6) {
1836 /* Only using (most of) 2 bytes from addresses for now, but reluctant to make key longer.. */
1837 const uint8_t *src_eth = (uint8_t*)pinfo->dl_src.data;
1838 const uint8_t *dst_eth = (uint8_t*)pinfo->dl_dst.data;
1839 if (!opposite_dir) {
1840 eth_bits = (src_eth[0]<<8) | dst_eth[5];
1841 }
1842 else {
1843 eth_bits = (dst_eth[0]<<8) | src_eth[5];
1844 }
1845 }
1846 return eaxc_id | (plane << 16) | (eth_bits << 17);
1847}
1848
1849
1850/* Table maintained on first pass from flow_key(uint32_t) -> flow_state_t* */
1851static wmem_tree_t *flow_states_table;
1852
1853/* Table consulted on subsequent passes: frame_num -> flow_result_t* */
1854static wmem_tree_t *flow_results_table;
1855
1856typedef struct {
1857 /* Sequence analysis */
1858 bool_Bool unexpected_seq_number;
1859 uint8_t expected_sequence_number;
1860 uint32_t previous_frame;
1861
1862 /* sectionId -> expected_section_data_t* */
1863 wmem_tree_t *expected_dl_sections;
1864
1865} flow_result_t;
1866
1867
1868/* Uplink timing */
1869/* For a given symbol, track first to last UL frame to find out first-last time */
1870/* frameId (8) + subframeId (4) + slotId (6) + symbolId (6) = 24 bits */
1871/* N.B. if a capture lasts > 2.5s, may see same timing come around again... */
1872static uint32_t get_timing_key(uint8_t frameId, uint8_t subframeId, uint8_t slotId, uint8_t symbolId)
1873{
1874 return symbolId + (slotId<<8) + (subframeId<<14) + (frameId<<18);
1875}
1876
1877typedef struct {
1878 uint32_t first_frame;
1879 nstime_t first_frame_time;
1880 uint32_t frames_seen_in_symbol;
1881 uint32_t last_frame_in_symbol;
1882} ul_timing_for_slot;
1883
1884/* Set during first pass. timing_key -> ul_timing_for_slot* */
1885static wmem_tree_t *ul_symbol_timing;
1886
1887
1888/* Tracking lifetimes of DL beamIds */
1889typedef struct {
1890 uint32_t frame_defined;
1891 uint32_t symbol_when_defined;
1892} bfw_definition;
1893
1894/* Maintained during first pass: beamId (from ext11) -> bfw_definition */
1895static wmem_tree_t *dl_beam_ids_defined;
1896/* Lookup where/when beamIds were defined (frameid:beamid) -> bfw_definition */
1897static wmem_tree_t *dl_beam_ids_results;
1898
1899
1900static void show_link_to_acknack_response(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo,
1901 ack_nack_request_t *response);
1902
1903
1904
1905
1906static void write_pdu_label_and_info(proto_item *ti1, proto_item *ti2,
1907 packet_info *pinfo, const char *format, ...) G_GNUC_PRINTF(4, 5)__attribute__((__format__ (__printf__, 4, 5)));
1908
1909 /* Write the given formatted text to:
1910 - the info column (if pinfo != NULL)
1911 - 1 or 2 other labels (optional)
1912 */
1913static void write_pdu_label_and_info(proto_item *ti1, proto_item *ti2,
1914 packet_info *pinfo, const char *format, ...)
1915{
1916#define MAX_INFO_BUFFER256 256
1917 char info_buffer[MAX_INFO_BUFFER256];
1918 va_list ap;
1919
1920 if ((ti1 == NULL((void*)0)) && (ti2 == NULL((void*)0)) && (pinfo == NULL((void*)0))) {
1921 return;
1922 }
1923
1924 va_start(ap, format)__builtin_va_start(ap, format);
1925 vsnprintf(info_buffer, MAX_INFO_BUFFER256, format, ap);
1926 va_end(ap)__builtin_va_end(ap);
1927
1928 /* Add to indicated places */
1929 if (pinfo != NULL((void*)0)) {
1930 col_append_str(pinfo->cinfo, COL_INFO, info_buffer);
1931 }
1932 if (ti1 != NULL((void*)0)) {
1933 proto_item_append_text(ti1, "%s", info_buffer);
1934 }
1935 if (ti2 != NULL((void*)0)) {
1936 proto_item_append_text(ti2, "%s", info_buffer);
1937 }
1938}
1939
1940/* Add section labels (type + PRB range) for C-Plane, U-Plane */
1941static void
1942write_section_info(proto_item *section_heading, packet_info *pinfo, proto_item *protocol_item,
1943 uint32_t section_id, uint32_t start_prbx, uint32_t num_prbx, uint32_t rb)
1944{
1945 switch (num_prbx) {
1946 case 0:
1947 /* None -> all */
1948 write_pdu_label_and_info(section_heading, protocol_item, pinfo, ", Id: %4d (all PRBs)", section_id);
1949 break;
1950 case 1:
1951 /* Single PRB */
1952 write_pdu_label_and_info(section_heading, protocol_item, pinfo, ", Id: %4d (PRB: %7u)", section_id, start_prbx);
1953 break;
1954 default:
1955 /* Range */
1956 write_pdu_label_and_info(section_heading, protocol_item, pinfo, ", Id: %4d (PRB: %3u-%3u%s)", section_id, start_prbx,
1957 start_prbx + (num_prbx-1)*(1+rb), rb ? " (every-other)" : "");
1958 }
1959}
1960
1961static void
1962write_channel_section_info(proto_item *section_heading, packet_info *pinfo,
1963 uint32_t section_id, uint32_t ueId, uint32_t start_prbx, uint32_t num_prbx,
1964 uint32_t num_trx)
1965{
1966 switch (num_prbx) {
1967 case 0:
1968 /* TODO: ?? */
1969 break;
1970 case 1:
1971 /* Single PRB */
1972 write_pdu_label_and_info(section_heading, NULL((void*)0), pinfo,
1973 ", Id: %4d (UEId=%5u PRB %7u, %2u antennas)",
1974 section_id, ueId, start_prbx, num_trx);
1975 break;
1976 default:
1977 /* Range */
1978 write_pdu_label_and_info(section_heading, NULL((void*)0), pinfo,
1979 ", Id: %4d (UEId=%5u PRBs %3u-%3u, %2u antennas)",
1980 section_id, ueId, start_prbx, start_prbx+num_prbx-1, num_trx);
1981 }
1982}
1983
1984/* Add a reserved field, and warn if value isn't 0 */
1985/* TODO: maybe add a pref not to output expert warning if becomes too annoying? */
1986static void add_reserved_field(proto_tree *tree, int hf, tvbuff_t *tvb, int offset, int len)
1987{
1988 uint32_t reserved;
1989 proto_item *res_ti = proto_tree_add_item_ret_uint(tree, hf, tvb, offset, len, ENC_NA0x00000000, &reserved);
1990 if (reserved != 0) {
1991 expert_add_info_format(NULL((void*)0), res_ti, &ei_oran_reserved_not_zero,
1992 "reserved field saw value of 0x%x", reserved);
1993 }
1994}
1995
1996/* 5.1.3.2.7 (real time control data / IQ data transfer message series identifier) */
1997static void
1998addPcOrRtcid(tvbuff_t *tvb, proto_tree *tree, unsigned *offset, int hf, uint16_t *eAxC, oran_tap_info *tap_info)
1999{
2000 /* Subtree */
2001 proto_item *oran_pcid_ti = proto_tree_add_item(tree, hf,
2002 tvb, *offset, 2, ENC_NA0x00000000);
2003 proto_tree *oran_pcid_tree = proto_item_add_subtree(oran_pcid_ti, ett_oran_ecpri_pcid);
2004
2005 uint64_t duPortId, bandSectorId, ccId, ruPortId = 0;
2006 int id_offset = *offset;
2007
2008 /* All parts of eAxC should be above 0, and should total 16 bits (breakdown controlled by preferences) */
2009 if (!((pref_du_port_id_bits > 0) && (pref_bandsector_id_bits > 0) && (pref_cc_id_bits > 0) && (pref_ru_port_id_bits > 0) &&
2010 ((pref_du_port_id_bits + pref_bandsector_id_bits + pref_cc_id_bits + pref_ru_port_id_bits) == 16))) {
2011 expert_add_info(NULL((void*)0), tree, &ei_oran_invalid_eaxc_bit_width);
2012 *eAxC = 0;
2013 *offset += 2;
2014 return;
2015 }
2016
2017 unsigned bit_offset = *offset * 8;
2018
2019 /* N.B. For sequence analysis / tapping, just interpret these 2 bytes as eAxC ID... */
2020 *eAxC = tvb_get_uint16(tvb, *offset, ENC_BIG_ENDIAN0x00000000);
2021
2022 /* DU Port ID */
2023 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);
2024 bit_offset += pref_du_port_id_bits;
2025 /* BandSector ID */
2026 proto_tree_add_bits_ret_val(oran_pcid_tree, hf_oran_bandsector_id, tvb, bit_offset, pref_bandsector_id_bits, &bandSectorId, ENC_BIG_ENDIAN0x00000000);
2027 bit_offset += pref_bandsector_id_bits;
2028 /* CC ID */
2029 proto_tree_add_bits_ret_val(oran_pcid_tree, hf_oran_cc_id, tvb, bit_offset, pref_cc_id_bits, &ccId, ENC_BIG_ENDIAN0x00000000);
2030 bit_offset += pref_cc_id_bits;
2031 /* RU Port ID */
2032 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);
2033 *offset += 2;
2034
2035 proto_item_append_text(oran_pcid_ti, " (DU_Port_ID: %d, BandSector_ID: %d, CC_ID: %d, RU_Port_ID: %d)",
2036 (int)duPortId, (int)bandSectorId, (int)ccId, (int)ruPortId);
2037 char id[16];
2038 snprintf(id, 16, "%x:%x:%x:%x", (int)duPortId, (int)bandSectorId, (int)ccId, (int)ruPortId);
2039 proto_item *pi = proto_tree_add_string(oran_pcid_tree, hf_oran_c_eAxC_ID, tvb, id_offset, 2, id);
2040 proto_item_set_generated(pi);
2041
2042 tap_info->eaxc = *eAxC;
2043 tap_info->eaxc_du_port_id = (uint16_t)duPortId;
2044 tap_info->eaxc_bandsector_id = (uint16_t)bandSectorId;
2045 tap_info->eaxc_cc_id = (uint16_t)ccId;
2046 tap_info->eaxc_ru_port_id = (uint16_t)ruPortId;
2047}
2048
2049/* Uniquely identify the U-plane stream that may need to be reassembled */
2050static uint32_t make_reassembly_id(uint32_t seqid, uint32_t direction, uint16_t eAxC,
2051 uint8_t frameid, uint8_t subframeid,
2052 uint8_t slotid, uint8_t symbolid)
2053{
2054 /* N.B., no room in 32-bits for all of this info, so cut down some of the fields
2055 and hope for no collisions */
2056 return (seqid << 24) | (direction << 23) | (slotid << 22) | (subframeid << 18) |
2057 (frameid << 9) | (symbolid << 6) | (eAxC & 0x3f);
2058}
2059
2060/* 5.1.3.2.8 ecpriSeqid (message identifier) */
2061/* Return out info that may be used for sequence number analysis and reassembly */
2062static int
2063addSeqid(tvbuff_t *tvb, proto_tree *oran_tree, int offset, int plane, uint32_t *seq_id, proto_item **seq_id_ti, packet_info *pinfo,
2064 uint32_t *subseqid, uint32_t *e)
2065{
2066 /* Subtree */
2067 proto_item *seqIdItem = proto_tree_add_item(oran_tree, hf_oran_ecpri_seqid, tvb, offset, 2, ENC_NA0x00000000);
2068 proto_tree *oran_seqid_tree = proto_item_add_subtree(seqIdItem, ett_oran_ecpri_seqid);
2069
2070 /* Sequence ID (8 bits) */
2071 *seq_id_ti = proto_tree_add_item_ret_uint(oran_seqid_tree, hf_oran_sequence_id, tvb, offset, 1, ENC_NA0x00000000, seq_id);
2072 offset += 1;
2073
2074 /* Show link back to previous sequence ID, if set */
2075 flow_result_t *result = wmem_tree_lookup32(flow_results_table, pinfo->num);
2076 if (result) {
2077 proto_item *prev_ti = proto_tree_add_uint(oran_seqid_tree, hf_oran_previous_frame, tvb, 0, 0, result->previous_frame);
2078 proto_item_set_generated(prev_ti);
2079 }
2080
2081 /* E bit */
2082 proto_tree_add_item_ret_uint(oran_seqid_tree, hf_oran_e_bit, tvb, offset, 1, ENC_NA0x00000000, e);
2083 /* Subsequence ID (7 bits) */
2084 proto_tree_add_item_ret_uint(oran_seqid_tree, hf_oran_subsequence_id, tvb, offset, 1, ENC_NA0x00000000, subseqid);
2085 offset += 1;
2086
2087 /* radio-transport fragmentation not allowed for C-Plane messages */
2088 if (plane == ORAN_C_PLANE0) {
2089 if (*e !=1 || *subseqid != 0) {
2090 expert_add_info(NULL((void*)0), seqIdItem, &ei_oran_radio_fragmentation_c_plane);
2091 }
2092 }
2093
2094 /* Summary */
2095 proto_item_append_text(seqIdItem, " (SeqId: %3d, E: %d, SubSeqId: %d)", *seq_id, *e, *subseqid);
2096 return offset;
2097}
2098
2099static int dissect_symbolmask(tvbuff_t *tvb, proto_tree *tree, int offset, uint32_t *symbol_mask, proto_item **ti)
2100{
2101 uint64_t temp_val;
2102
2103 static int * const symbol_mask_flags[] = {
2104 &hf_oran_symbol_mask_s13,
2105 &hf_oran_symbol_mask_s12,
2106 &hf_oran_symbol_mask_s11,
2107 &hf_oran_symbol_mask_s10,
2108 &hf_oran_symbol_mask_s9,
2109 &hf_oran_symbol_mask_s8,
2110 &hf_oran_symbol_mask_s7,
2111 &hf_oran_symbol_mask_s6,
2112 &hf_oran_symbol_mask_s5,
2113 &hf_oran_symbol_mask_s4,
2114 &hf_oran_symbol_mask_s3,
2115 &hf_oran_symbol_mask_s2,
2116 &hf_oran_symbol_mask_s1,
2117 &hf_oran_symbol_mask_s0,
2118 NULL((void*)0)
2119 };
2120
2121 proto_item *temp_ti = proto_tree_add_bitmask_ret_uint64(tree, tvb, offset,
2122 hf_oran_symbol_mask,
2123 ett_oran_symbol_mask, symbol_mask_flags,
2124 ENC_BIG_ENDIAN0x00000000, &temp_val);
2125 /* Set out parameters */
2126 if (symbol_mask) {
2127 *symbol_mask = (uint32_t)temp_val;
2128 }
2129 if (ti) {
2130 *ti = temp_ti;
2131 }
2132 return offset+2;
2133}
2134
2135/* 7.7.1.2 bfwCompHdr (beamforming weight compression header) */
2136static int dissect_bfwCompHdr(tvbuff_t *tvb, proto_tree *tree, int offset,
2137 uint32_t *iq_width, uint32_t *comp_meth, proto_item **comp_meth_ti)
2138{
2139 /* Subtree */
2140 proto_item *bfwcomphdr_ti = proto_tree_add_string_format(tree, hf_oran_bfwCompHdr,
2141 tvb, offset, 1, "",
2142 "bfwCompHdr");
2143 proto_tree *bfwcomphdr_tree = proto_item_add_subtree(bfwcomphdr_ti, ett_oran_bfwcomphdr);
2144
2145 /* Width and method */
2146 proto_tree_add_item_ret_uint(bfwcomphdr_tree, hf_oran_bfwCompHdr_iqWidth,
2147 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, iq_width);
2148 /* Special case: 0 -> 16 */
2149 *iq_width = (*iq_width==0) ? 16 : *iq_width;
2150 *comp_meth_ti = proto_tree_add_item_ret_uint(bfwcomphdr_tree, hf_oran_bfwCompHdr_compMeth,
2151 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, comp_meth);
2152 offset++;
2153
2154 /* Summary */
2155 proto_item_append_text(bfwcomphdr_ti, " (IqWidth=%u, compMeth=%s)",
2156 *iq_width,
2157 val_to_str_const(*comp_meth, bfw_comp_headers_comp_meth, "reserved"));
2158
2159 return offset;
2160}
2161
2162/* Return offset */
2163/* Returning number of entries set - would be good to also return an array of set TRX# so could show which array element
2164 each BFW is actually for.. */
2165static int dissect_active_beamspace_coefficient_mask(tvbuff_t *tvb, proto_tree *tree, int offset, unsigned *num_trx_entries, uint16_t **trx_entries)
2166{
2167 /* activeBeamspaceCoefficientMask - ceil(K/8) octets */
2168 /* K is the number of elements in uncompressed beamforming weight vector.
2169 * Calculated from parameters describing tx-array or tx-array */
2170 unsigned k_octets = (pref_num_bf_antennas + 7) / 8;
2171
2172 static uint16_t trx_enabled[1024];
2173
2174 /* TODO: could use a bigger bitmask array, but for now just uses this bytes-worth for each byte */
2175 static int * const mask_bits[] = {
2176 &hf_oran_active_beamspace_coefficient_n1,
2177 &hf_oran_active_beamspace_coefficient_n2,
2178 &hf_oran_active_beamspace_coefficient_n3,
2179 &hf_oran_active_beamspace_coefficient_n4,
2180 &hf_oran_active_beamspace_coefficient_n5,
2181 &hf_oran_active_beamspace_coefficient_n6,
2182 &hf_oran_active_beamspace_coefficient_n7,
2183 &hf_oran_active_beamspace_coefficient_n8,
2184 NULL((void*)0)
2185 };
2186
2187 *num_trx_entries = 0;
2188 uint64_t val;
2189 for (unsigned n=0; n < k_octets; n++) {
2190 proto_tree_add_bitmask_ret_uint64(tree, tvb, offset,
2191 hf_oran_activeBeamspaceCoefficientMask,
2192 ett_oran_active_beamspace_coefficient_mask, mask_bits,
2193 ENC_BIG_ENDIAN0x00000000, &val);
2194 offset++;
2195 /* Add up the set bits for this byte (but be careful not to count beyond last real K bit..) */
2196 for (unsigned b=0; b < 8; b++) {
2197 if ((1 << b) & (unsigned)val) {
2198 if (((n*8)+b) < pref_num_bf_antennas) {
2199 if (*num_trx_entries < 1024-1) { /* Don't write beyond array (which should be plenty big) */
2200 trx_enabled[(*num_trx_entries)++] = (n*8) + b + 1;
2201 }
2202 }
2203 }
2204 }
2205 }
2206 /* Set pointer to static array */
2207 *trx_entries = trx_enabled;
2208
2209 /* Show how many bits set */
2210 proto_item *ti = proto_tree_add_uint(tree, hf_oran_activeBeamspaceCoefficientMask_bits_set, tvb,
2211 offset-k_octets, k_octets, *num_trx_entries);
2212 proto_item_set_generated(ti);
2213
2214 return offset;
2215}
2216
2217static void add_beam_id_to_tap(oran_tap_info *tap_info, uint16_t beam_id)
2218{
2219 if (tap_info->num_beams < MAX_BEAMS_IN_FRAME32) {
2220 tap_info->beams[tap_info->num_beams++] = beam_id;
2221 }
2222}
2223
2224
2225/* 7.7.1.3 bfwCompParam (beamforming weight compression parameter).
2226 * Depends upon passed-in bfwCompMeth (field may be empty) */
2227static int dissect_bfwCompParam(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, int offset,
2228 proto_item *meth_ti, uint32_t *bfw_comp_method,
2229 uint32_t *exponent, bool_Bool *supported, unsigned *num_trx_entries, uint16_t **trx_entries)
2230{
2231 if (*bfw_comp_method == COMP_NONE0) {
2232 /* Absent! */
2233 *num_trx_entries = 0;
2234 *supported = true1;
2235 return offset;
2236 }
2237
2238 /* Subtree */
2239 proto_item *bfwcompparam_ti = proto_tree_add_string_format(tree, hf_oran_bfwCompParam,
2240 tvb, offset, 1, "",
2241 "bfwCompParam");
2242 proto_tree *bfwcompparam_tree = proto_item_add_subtree(bfwcompparam_ti, ett_oran_bfwcompparam);
2243
2244 proto_item_append_text(bfwcompparam_ti,
2245 " (meth=%s)", val_to_str_const(*bfw_comp_method, bfw_comp_headers_comp_meth, "reserved"));
2246
2247 *num_trx_entries = 0;
2248 *supported = false0;
2249 switch (*bfw_comp_method) {
2250 case COMP_BLOCK_FP1: /* block floating point */
2251 /* 4 reserved bits + exponent */
2252 add_reserved_field(bfwcompparam_tree, hf_oran_reserved_4bits, tvb, offset, 1);
2253 proto_tree_add_item_ret_uint(bfwcompparam_tree, hf_oran_exponent,
2254 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, exponent);
2255 proto_item_append_text(bfwcompparam_ti, " exponent=%u", *exponent);
2256 *supported = true1;
2257 offset++;
2258 break;
2259 case COMP_BLOCK_SCALE2: /* block scaling */
2260 /* Separate into integer and fractional bits? */
2261 proto_tree_add_item(bfwcompparam_tree, hf_oran_blockScaler,
2262 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
2263 offset++;
2264 break;
2265 case COMP_U_LAW3: /* u-law */
2266 /* compBitWidth, compShift */
2267 proto_tree_add_item(bfwcompparam_tree, hf_oran_compBitWidth,
2268 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
2269 proto_tree_add_item(bfwcompparam_tree, hf_oran_compShift,
2270 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
2271 offset++;
2272 break;
2273 case 4: /* beamspace I (BLOCK SCALING) */
2274 /* activeBeamspaceCoefficientMask */
2275 offset = dissect_active_beamspace_coefficient_mask(tvb, bfwcompparam_tree, offset, num_trx_entries, trx_entries);
2276 *bfw_comp_method = COMP_BLOCK_SCALE2;
2277 *supported = false0; /* TODO: true once BLOCK SCALE is supported */
2278 proto_tree_add_item(bfwcompparam_tree, hf_oran_blockScaler,
2279 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
2280 offset++;
2281 break;
2282 case 5: /* beamspace II (BLOCK FLOATING POINT) */
2283 /* activeBeamspaceCoefficientMask */
2284 offset = dissect_active_beamspace_coefficient_mask(tvb, bfwcompparam_tree, offset, num_trx_entries, trx_entries);
2285 /* reserved (4 bits) + exponent (4 bits) */
2286 add_reserved_field(bfwcompparam_tree, hf_oran_reserved_4bits, tvb, offset, 1);
2287 proto_tree_add_item_ret_uint(bfwcompparam_tree, hf_oran_exponent, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, exponent);
2288 offset += 1;
2289 *bfw_comp_method = COMP_BLOCK_FP1;
2290 *supported = true1;
2291 break;
2292
2293 default:
2294 /* Not handled */
2295 break;
2296 }
2297
2298 proto_item_set_end(bfwcompparam_ti, tvb, offset);
2299
2300 /* Can't go on if compression scheme not supported */
2301 if (!(*supported) && meth_ti) {
2302 expert_add_info_format(pinfo, meth_ti, &ei_oran_unsupported_bfw_compression_method,
2303 "BFW Compression method %u (%s) not decompressed by dissector",
2304 *bfw_comp_method,
2305 val_to_str_const(*bfw_comp_method, bfw_comp_headers_comp_meth, "reserved"));
2306 }
2307 return offset;
2308}
2309
2310
2311/* Special case for uncompressed/16-bit value */
2312static float uncompressed_to_float(uint32_t h)
2313{
2314 int16_t i16 = h & 0x0000ffff;
2315 if (show_unscaled_values) {
2316 return (float)i16;
2317 }
2318 return ((float)i16) / 0x7fff;
2319}
2320
2321/* Decompress I/Q value, taking into account method, width, exponent, other input-specific methods */
2322static float decompress_value(uint32_t bits, uint32_t comp_method, uint8_t iq_width,
2323 uint32_t exponent,
2324 /* Modulation compression settings. N.B. should also pass in PRB + symbol? */
2325 section_mod_compr_config_t *m_c_p, uint8_t re)
2326{
2327 switch (comp_method) {
2328 case COMP_NONE0: /* no compression */
2329 return uncompressed_to_float(bits);
2330
2331 case COMP_BLOCK_FP1: /* block floating point */
2332 case BFP_AND_SELECTIVE_RE5:
2333 {
2334 /* A.1.3 Block Floating Point Decompression Algorithm */
2335 int32_t cPRB = bits;
2336 uint32_t scaler = 1 << exponent; /* i.e. 2^exponent */
2337
2338 /* Check last bit, in case we need to flip to -ve */
2339 if (cPRB >= (1<<(iq_width-1))) {
2340 cPRB -= (1<<iq_width);
2341 }
2342
2343 /* Unscale (8.1.3.1) */
2344 cPRB *= scaler;
2345 if (show_unscaled_values) {
2346 return (float)cPRB;
2347 }
2348
2349 uint32_t mantissa_scale_factor = 1 << (iq_width-1); /* 2^(mantissabits-1) */
2350 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 */
2351
2352 float ret = cPRB / ((float)(mantissa_scale_factor*exp_scale_factor));
2353 return ret;
2354 }
2355
2356 case COMP_BLOCK_SCALE2:
2357 case COMP_U_LAW3:
2358 /* Not supported! But will be reported as expert info outside of this function! */
2359 return 0.0;
2360
2361 case COMP_MODULATION4:
2362 case MOD_COMPR_AND_SELECTIVE_RE6:
2363 {
2364 /* Described in A.5 (with pseudo code) */
2365 /* N.B., Applies to downlink data only - is not used for BFW */
2366
2367 /* Defaults if not overridden. TODO: what should these be? */
2368 bool_Bool csf = false0;
2369 float mcScaler = (float)(1 << 11);
2370
2371 /* Find csf + mcScaler to use. Non-default configs gleaned from SE 4,5,23 */
2372 /* TODO: should ideally be filtering by symbol and PRB too (as configured from SE23) */
2373 if (re > 0 && m_c_p && m_c_p->num_configs > 0) {
2374 for (unsigned c=0; c<m_c_p->num_configs; c++) {
2375 if (m_c_p->configs[c].mod_compr_re_mask & (1 << (12-re))) {
2376 /* Return first (should be only) found */
2377 csf = m_c_p->configs[c].mod_compr_csf;
2378 mcScaler = m_c_p->configs[c].mod_compr_scaler;
2379 break;
2380 }
2381 }
2382 }
2383
2384 int32_t cPRB = bits;
2385
2386 /* 2) Map iqSample to iqSampleFx */
2387 /* Check last bit, in case we need to flip to -ve */
2388 if (cPRB >= (1<<(iq_width-1))) {
2389 cPRB -= (1<<iq_width);
2390 }
2391 float iqSampleFx = (float)cPRB / (1 << (iq_width-1));
2392
2393
2394 /* 3) or 4) (b) - add unshifted value if csf set */
2395 float csf_to_add = 0.0;
2396 if (csf) {
2397 /* Unshift the constellation point */
2398 csf_to_add = (float)1.0 / (1 << (iq_width));
2399 }
2400 iqSampleFx += csf_to_add;
2401
2402 /* 3) or 4) (c) - unscaling */
2403 float iqSampleScaled = mcScaler * iqSampleFx * (float)sqrt(2);
2404 return iqSampleScaled;
2405 }
2406
2407 default:
2408 /* Not supported! But will be reported as expert info outside of this function! */
2409 return 0.0;
2410 }
2411}
2412
2413/* Out-of-range value used for special case */
2414#define ORPHAN_BUNDLE_NUMBER999 999
2415
2416/* Bundle of PRBs/TRX I/Q samples (ext 11) */
2417static uint32_t dissect_bfw_bundle(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, unsigned offset,
2418 proto_item *comp_meth_ti, uint32_t bfwcomphdr_comp_meth,
2419 section_mod_compr_config_t *mod_compr_params,
2420 uint32_t num_weights_per_bundle,
2421 uint8_t iq_width,
2422 unsigned bundle_number,
2423 unsigned first_prb, unsigned last_prb, bool_Bool is_orphan,
2424 uint32_t symbol_count,
2425 section_details_t *section_details,
2426 oran_tap_info *tap_info)
2427{
2428 /* Set bundle name */
2429 char bundle_name[32];
2430 if (!is_orphan) {
2431 snprintf(bundle_name, 32, "Bundle %3u", bundle_number);
2432 }
2433 else {
2434 (void) g_strlcpy(bundle_name, "Orphaned ", 32);
2435 }
2436
2437 /* Create Bundle root */
2438 proto_item *bundle_ti;
2439 if (first_prb != last_prb) {
2440 bundle_ti = proto_tree_add_string_format(tree, hf_oran_bfw_bundle,
2441 tvb, offset, 0, "",
2442 "%s: (PRBs %3u-%3u)",
2443 bundle_name,
2444 first_prb, last_prb);
2445 }
2446 else {
2447 bundle_ti = proto_tree_add_string_format(tree, hf_oran_bfw_bundle,
2448 tvb, offset, 0, "",
2449 "%s: (PRB %3u)",
2450 bundle_name,
2451 first_prb);
2452 }
2453 proto_tree *bundle_tree = proto_item_add_subtree(bundle_ti, ett_oran_bfw_bundle);
2454
2455 /* Generated bundle id */
2456 proto_item *bundleid_ti = proto_tree_add_uint(bundle_tree, hf_oran_bfw_bundle_id, tvb, 0, 0,
2457 bundle_number);
2458 proto_item_set_generated(bundleid_ti);
2459 proto_item_set_hidden(bundleid_ti);
2460
2461 /* bfwCompParam */
2462 bool_Bool compression_method_supported = false0;
2463 unsigned exponent = 0;
2464 unsigned num_trx_entries = 0;
2465 uint16_t *trx_entries;
2466 offset = dissect_bfwCompParam(tvb, bundle_tree, pinfo, offset, comp_meth_ti,
2467 &bfwcomphdr_comp_meth, &exponent, &compression_method_supported,
2468 &num_trx_entries, &trx_entries);
2469
2470 /* Create Bundle subtree */
2471 int bit_offset = offset*8;
2472 int bfw_offset;
2473
2474 /* contInd */
2475 proto_tree_add_item(bundle_tree, hf_oran_cont_ind,
2476 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
2477 /* beamId */
2478 uint32_t beam_id;
2479 proto_tree_add_item_ret_uint(bundle_tree, hf_oran_beam_id, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &beam_id);
2480 proto_item_append_text(bundle_ti, " (beamId:%u) ", beam_id);
2481 bit_offset += 16;
2482 add_beam_id_to_tap(tap_info, beam_id);
2483
2484 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
2485 if (section_details) {
2486 for (unsigned prb = first_prb; prb <= last_prb; prb++) {
2487 if (prb < 273) {
2488 section_details->beamIds[prb] = beam_id;
2489 }
2490 }
2491 }
2492 }
2493
2494 /* On first pass, record that beamId was defined here */
2495 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
2496 bfw_definition *definition = wmem_new0(wmem_file_scope(), bfw_definition)((bfw_definition*)wmem_alloc0((wmem_file_scope()), sizeof(bfw_definition
)))
;
2497 definition->frame_defined = pinfo->num;
2498 definition->symbol_when_defined = symbol_count;
2499 wmem_tree_insert32(dl_beam_ids_defined, beam_id, definition);
2500 }
2501
2502
2503 /* Number of weights per bundle (from preference) */
2504 proto_item *wpb_ti = proto_tree_add_uint(bundle_tree, hf_oran_num_weights_per_bundle, tvb, 0, 0,
2505 num_weights_per_bundle);
2506 proto_item_set_generated(wpb_ti);
2507
2508 /* Add the weights for this bundle. Overwrite with what was seen in bfwCompParam if beamspace */
2509 if (num_trx_entries != 0) {
2510 num_weights_per_bundle = num_trx_entries;
2511 }
2512
2513 bool_Bool non_zero_weights_seen = false0;
2514 int bit_offset_before_weights = bit_offset;
2515 for (unsigned w=0; w < num_weights_per_bundle; w++) {
2516
2517 uint16_t trx_index = (num_trx_entries) ? trx_entries[w] : w+1;
2518
2519 /* Create subtree */
2520 bfw_offset = bit_offset / 8;
2521 uint8_t bfw_extent = ((bit_offset + (iq_width*2)) / 8) - bfw_offset;
2522 proto_item *bfw_ti = proto_tree_add_string_format(bundle_tree, hf_oran_bfw,
2523 tvb, bfw_offset, bfw_extent,
2524 "", "TRX %3u: (", trx_index);
2525 proto_tree *bfw_tree = proto_item_add_subtree(bfw_ti, ett_oran_bfw);
2526
2527 /* I */
2528 /* Get bits, and convert to float. */
2529 uint32_t bits = tvb_get_bits32(tvb, bit_offset, iq_width, ENC_BIG_ENDIAN0x00000000);
2530 if (bits) {
2531 non_zero_weights_seen = true1;
2532 }
2533 float value = decompress_value(bits, bfwcomphdr_comp_meth, iq_width,
2534 exponent, mod_compr_params, 0 /* RE */);
2535 /* Add to tree. */
2536 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);
2537 bit_offset += iq_width;
2538 proto_item_append_text(bfw_ti, "I%u=%f ", w, value);
2539
2540 /* Q */
2541 /* Get bits, and convert to float. */
2542 bits = tvb_get_bits32(tvb, bit_offset, iq_width, ENC_BIG_ENDIAN0x00000000);
2543 if (bits) {
2544 non_zero_weights_seen = true1;
2545 }
2546
2547 value = decompress_value(bits, bfwcomphdr_comp_meth, iq_width,
2548 exponent, mod_compr_params, 0 /* RE */);
2549 /* Add to tree. */
2550 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);
2551 bit_offset += iq_width;
2552 proto_item_append_text(bfw_ti, "Q%u=%f)", w, value);
2553 }
2554
2555 if (!non_zero_weights_seen) {
2556 proto_tree_add_item(bundle_tree, hf_oran_bundle_weights_all_zero, tvb,
2557 bit_offset_before_weights, (bit_offset+7)/8 - (bit_offset_before_weights/8), ENC_NA0x00000000);
2558 }
2559
2560 /* Set extent of bundle */
2561 proto_item_set_end(bundle_ti, tvb, (bit_offset+7)/8);
2562
2563 return (bit_offset+7)/8;
2564}
2565
2566/* Return new bit offset. in/out will always be byte-aligned.. */
2567static int dissect_ciCompParam(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U___attribute__((unused)), unsigned bit_offset,
2568 unsigned comp_meth, uint8_t *exponent)
2569{
2570 if (comp_meth == COMP_NONE0) {
2571 /* Nothing in frame so don't even create subtree */
2572 return bit_offset;
2573 }
2574
2575 /* Subtree */
2576 proto_item *cicompparam_ti = proto_tree_add_string_format(tree, hf_oran_ciCompParam,
2577 tvb, bit_offset/8, 1, "",
2578 "ciCompParam");
2579 proto_tree *cicompparam_tree = proto_item_add_subtree(cicompparam_ti, ett_oran_cicompparam);
2580 uint32_t ci_exponent;
2581
2582 /* Contents differ by compression method */
2583 switch (comp_meth) {
2584 case COMP_BLOCK_FP1:
2585 add_reserved_field(cicompparam_tree, hf_oran_reserved_4bits, tvb, bit_offset/8, 1);
2586 proto_tree_add_item_ret_uint(cicompparam_tree, hf_oran_exponent,
2587 tvb, bit_offset/8, 1, ENC_BIG_ENDIAN0x00000000, &ci_exponent);
2588 *exponent = ci_exponent;
2589 proto_item_append_text(cicompparam_ti, " (Exponent=%u)", ci_exponent);
2590 bit_offset += 8; /* one byte */
2591 break;
2592 case COMP_BLOCK_SCALE2:
2593 /* Separate into integer (1) and fractional (7) bits? */
2594 proto_tree_add_item(cicompparam_tree, hf_oran_blockScaler,
2595 tvb, bit_offset/8, 1, ENC_BIG_ENDIAN0x00000000);
2596 bit_offset += 8;
2597 break;
2598 case COMP_U_LAW3:
2599 /* compBitWidth, compShift (4 bits each) */
2600 proto_tree_add_item(cicompparam_tree, hf_oran_compBitWidth,
2601 tvb, bit_offset/8, 1, ENC_BIG_ENDIAN0x00000000);
2602 proto_tree_add_item(cicompparam_tree, hf_oran_compShift,
2603 tvb, bit_offset/8, 1, ENC_BIG_ENDIAN0x00000000);
2604 bit_offset += 8;
2605 break;
2606
2607 default:
2608 /* reserved, ? bytes of zeros.. */
2609 break;
2610 }
2611
2612 return bit_offset;
2613}
2614
2615/* frameStructure (7.5.2.13) */
2616static unsigned dissect_frame_structure(proto_item *tree, tvbuff_t *tvb, unsigned offset,
2617 uint32_t subframeId, uint32_t slotId)
2618{
2619 uint32_t scs;
2620 /* FFT Size (4 bits) */
2621 proto_tree_add_item(tree, hf_oran_frameStructure_fft, tvb, offset, 1, ENC_NA0x00000000);
2622 /* Subcarrier spacing (SCS) */
2623 proto_tree_add_item_ret_uint(tree, hf_oran_frameStructure_subcarrier_spacing, tvb, offset, 1, ENC_NA0x00000000, &scs);
2624
2625 /* Show slot within frame as a generated field. See table 7.5.13-3 */
2626 uint32_t slots_per_subframe = 1;
2627 if (scs <= 4) {
2628 slots_per_subframe = 1 << scs;
2629 }
2630 if (scs <= 4 || scs >= 12) {
2631 proto_item *ti = proto_tree_add_uint(tree, hf_oran_slot_within_frame, tvb, 0, 0,
2632 (slots_per_subframe*subframeId) + slotId);
2633 proto_item_set_generated(ti);
2634 }
2635 return offset + 1;
2636}
2637
2638static unsigned dissect_csf(proto_item *tree, tvbuff_t *tvb, unsigned bit_offset,
2639 unsigned iq_width, bool_Bool *p_csf)
2640{
2641 proto_item *csf_ti;
2642 uint64_t csf;
2643 csf_ti = proto_tree_add_bits_ret_val(tree, hf_oran_csf, tvb, bit_offset, 1, &csf, ENC_BIG_ENDIAN0x00000000);
2644 if (csf) {
2645 /* Table 7.7.4.2-1 Constellation shift definition (index is udIqWidth) */
2646 const char* shift_value[] = { "n/a", "1/2", "1/4", "1/8", "1/16", "1/32" };
2647 if (iq_width >=1 && iq_width <= 5) {
2648 proto_item_append_text(csf_ti, " (Shift Value is %s)", shift_value[iq_width]);
2649 }
2650 }
2651
2652 /* Set out parameter */
2653 if (p_csf != NULL((void*)0)) {
2654 *p_csf = (csf!=0);
2655 }
2656 return bit_offset+1;
2657}
2658
2659
2660/* Section 7.
2661 * N.B. these are the green parts of the tables showing Section Types, differing by section Type */
2662static int dissect_oran_c_section(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo,
2663 flow_state_t* state,
2664 uint32_t sectionType, oran_tap_info *tap_info, proto_item *protocol_item,
2665 uint32_t subframeId, uint32_t frameId, uint32_t slotId, uint32_t startSymbolId,
2666 uint8_t ci_iq_width, uint8_t ci_comp_meth, unsigned ci_comp_opt,
2667 unsigned num_sinr_per_prb)
2668{
2669 unsigned offset = 0;
2670 proto_tree *c_section_tree = NULL((void*)0);
2671 proto_item *sectionHeading = NULL((void*)0);
2672
2673 /* Section subtree */
2674 sectionHeading = proto_tree_add_string_format(tree, hf_oran_c_section,
2675 tvb, offset, 0, "", "Section");
2676 c_section_tree = proto_item_add_subtree(sectionHeading, ett_oran_c_section);
2677
2678 uint32_t sectionId = 0;
2679
2680 uint32_t startPrbc=0, startPrbu=0;
2681 uint32_t numPrbc=0, numPrbu=0;
2682 uint32_t ueId = 0;
2683 proto_item *ueId_ti = NULL((void*)0);
2684 uint32_t section_beamId = 0;
2685 proto_item *section_beamId_ti = NULL((void*)0);
2686 bool_Bool section_beamId_ignored = false0;
2687
2688 proto_item *numsymbol_ti = NULL((void*)0);
2689 bool_Bool numsymbol_ignored = false0;
2690
2691 proto_item *numprbc_ti = NULL((void*)0);
2692
2693 /* Config affecting ext11 bundles (initially unset) */
2694 ext11_settings_t ext11_settings;
2695 memset(&ext11_settings, 0, sizeof(ext11_settings));
2696
2697 /* Section Type 10 needs to keep track of PRB range that should be reported
2698 for msgTypeId=5 (Interference plus Noise for unallocated PRBs) */
2699 /* All PRBs start as false */
2700#define MAX_PRBS273 273
2701 bool_Bool prbs_for_st10_type5[MAX_PRBS273];
2702 memset(&prbs_for_st10_type5, 0, sizeof(prbs_for_st10_type5));
2703
2704 /* These UEIds are set by ST5, ST10 (single value), and extended by SE10 */
2705#define MAX_UEIDS16 16
2706 uint32_t ueids[MAX_UEIDS16];
2707 uint32_t number_of_ueids = 0;
2708
2709
2710 bool_Bool extension_flag = false0;
2711
2712 /* These sections (ST0, ST1, ST2, ST3, ST5, ST9, ST10, ST11) are similar, so handle as common with per-type differences */
2713 if (((sectionType <= SEC_C_UE_SCHED) || (sectionType >= SEC_C_SINR_REPORTING)) &&
2714 (sectionType != SEC_C_SLOT_CONTROL)) {
2715
2716 /* sectionID */
2717 proto_item *ti = proto_tree_add_item_ret_uint(c_section_tree, hf_oran_section_id, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &sectionId);
2718 if (sectionId == 4095) {
2719 proto_item_append_text(ti, " (not default coupling C/U planes using sectionId)");
2720 }
2721 offset++;
2722
2723 if (tap_info->num_section_ids < MAX_SECTION_IDs32) {
2724 tap_info->section_ids[tap_info->num_section_ids++] = sectionId;
2725 }
2726
2727 /* rb */
2728 uint32_t rb;
2729 proto_tree_add_item_ret_uint(c_section_tree, hf_oran_rb, tvb, offset, 1, ENC_NA0x00000000, &rb);
2730 /* symInc (1 bit) */
2731 /* TODO: mark as ignored if SE6, SE12 or SE19 present */
2732 if (sectionType != SEC_C_RRM_MEAS_REPORTS && /* Section Type 10 */
2733 sectionType != SEC_C_REQUEST_RRM_MEAS) { /* Section Type 11 */
2734 unsigned int sym_inc;
2735 proto_item *sym_inc_ti = proto_tree_add_item_ret_uint(c_section_tree, hf_oran_symInc, tvb, offset, 1, ENC_NA0x00000000, &sym_inc);
2736 if (sym_inc !=0 && (sectionType == SEC_C_SINR_REPORTING)) { /* Section Type 9 */
2737 /* "0 shall be used" */
2738 proto_item_append_text(sym_inc_ti, " (should be 0)");
2739 }
2740 }
2741 else {
2742 /* reserved (1 bit) */
2743 add_reserved_field(c_section_tree, hf_oran_reserved_bit5, tvb, offset, 1);
2744 }
2745
2746 /* startPrbx and numPrbx */
2747 if (sectionType == SEC_C_SINR_REPORTING) {
2748 /* startPrbu (10 bits) */
2749 proto_tree_add_item_ret_uint(c_section_tree, hf_oran_startPrbu, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &startPrbu);
2750 offset += 2;
2751
2752 /* numPrbu */
2753 numprbc_ti = proto_tree_add_item_ret_uint(c_section_tree, hf_oran_numPrbu, tvb, offset, 1, ENC_NA0x00000000, &numPrbu);
2754 if (numPrbu == 0) {
2755 proto_item_append_text(numprbc_ti, " (all PRBs - configured as %u)", pref_data_plane_section_total_rbs);
2756 numPrbu = pref_data_plane_section_total_rbs;
2757 }
2758 offset += 1;
2759 }
2760 else {
2761 /* startPrbc (10 bits) */
2762 proto_tree_add_item_ret_uint(c_section_tree, hf_oran_startPrbc, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &startPrbc);
2763 offset += 2;
2764
2765 /* numPrbc */
2766 numprbc_ti = proto_tree_add_item_ret_uint(c_section_tree, hf_oran_numPrbc, tvb, offset, 1, ENC_NA0x00000000, &numPrbc);
2767 if (numPrbc == 0) {
2768 proto_item_append_text(numprbc_ti, " (all PRBs - configured as %u)", pref_data_plane_section_total_rbs);
2769 /* TODO: should probably set to pref_data_plane_section_total_rbs, and define MAX_PRBS to > 273 ? */
2770 numPrbc = MAX_PRBS273;
2771 }
2772 offset += 1;
2773 }
2774
2775 /* Start with range from section. May get changed by SE6, SE12, SE20 */
2776 for (unsigned n=startPrbc; n < startPrbc+numPrbc; n++) {
2777 if (n < MAX_PRBS273) {
2778 prbs_for_st10_type5[n] = true1;
2779 }
2780 }
2781
2782 if (sectionType != SEC_C_SINR_REPORTING) { /* *NOT* Section Type 9 */
2783 static int * const remask_flags[] = {
2784 &hf_oran_reMask_re1,
2785 &hf_oran_reMask_re2,
2786 &hf_oran_reMask_re3,
2787 &hf_oran_reMask_re4,
2788 &hf_oran_reMask_re5,
2789 &hf_oran_reMask_re6,
2790 &hf_oran_reMask_re7,
2791 &hf_oran_reMask_re8,
2792 &hf_oran_reMask_re9,
2793 &hf_oran_reMask_re10,
2794 &hf_oran_reMask_re11,
2795 &hf_oran_reMask_re12,
2796 NULL((void*)0)
2797 };
2798
2799 /* reMask */
2800 uint64_t remask;
2801 proto_tree_add_bitmask_ret_uint64(c_section_tree, tvb, offset,
2802 hf_oran_reMask, ett_oran_remask, remask_flags, ENC_BIG_ENDIAN0x00000000, &remask);
2803 offset++;
2804 /* numSymbol */
2805 uint32_t numSymbol;
2806 numsymbol_ti = proto_tree_add_item_ret_uint(c_section_tree, hf_oran_numSymbol, tvb, offset, 1, ENC_NA0x00000000, &numSymbol);
2807 if ((sectionType == SEC_C_RRM_MEAS_REPORTS) && (numSymbol != 14)) { /* Section type 10 must have 14 symbols */
2808 proto_item_append_text(numsymbol_ti, " (for ST10, should be 14!)");
2809 expert_add_info_format(pinfo, numsymbol_ti, &ei_oran_st10_numsymbol_not_14,
2810 "numSymbol should be 14 for ST10 - found %u", numSymbol);
2811 }
2812 if ((startSymbolId + numSymbol) > 14) {
2813 /* Warn if startSymbol + numSymbol would be > 14 */
2814 expert_add_info_format(pinfo, numsymbol_ti, &ei_oran_too_many_symbols,
2815 "startSymbolId (%u) + numSymbol (%u) exceeds max of 14",
2816 startSymbolId, numSymbol);
2817 }
2818 offset++;
2819
2820 /* [ef] (extension flag) */
2821 switch (sectionType) {
2822 case SEC_C_UNUSED_RB: /* Section Type 0 */
2823 case SEC_C_NORMAL: /* Section Type 1 */
2824 case SEC_C_PRACH: /* Section Type 3 */
2825 case SEC_C_UE_SCHED: /* Section Type 5 */
2826 case SEC_C_RRM_MEAS_REPORTS: /* Section Type 10 */
2827 case SEC_C_REQUEST_RRM_MEAS: /* Section Type 11 */
2828 proto_tree_add_item_ret_boolean(c_section_tree, hf_oran_ef, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &extension_flag);
2829 break;
2830 default:
2831 /* Other section types don't support extensions */
2832 break;
2833 }
2834
2835 write_section_info(sectionHeading, pinfo, protocol_item, sectionId, startPrbc, numPrbc, rb);
2836 proto_item_append_text(sectionHeading, ", Symbols: %2u", numSymbol);
2837
2838 if (numPrbc == 0) {
2839 /* Special case for all PRBs */
2840 numPrbc = pref_data_plane_section_total_rbs;
2841 startPrbc = 0; /* may already be 0... */
2842 }
2843 }
2844 else {
2845 /* Section Type 9 */
2846 write_section_info(sectionHeading, pinfo, protocol_item, sectionId, startPrbu, numPrbu, rb);
2847 proto_item_append_text(sectionHeading, ", numSinrPerPrb: %2u", num_sinr_per_prb);
2848 }
2849
2850 /* Section type specific fields (after 'numSymbol') */
2851 switch (sectionType) {
2852 case SEC_C_UNUSED_RB: /* Section Type 0 - Table 7.4.2-1 */
2853 /* reserved (15 bits) */
2854 add_reserved_field(c_section_tree, hf_oran_reserved_15bits, tvb, offset, 2);
2855 offset += 2;
2856 break;
2857
2858 case SEC_C_NORMAL: /* Section Type 1 - Table 7.4.3-1 */
2859 /* beamId */
2860 section_beamId_ti = proto_tree_add_item_ret_uint(c_section_tree, hf_oran_beamId, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &section_beamId);
2861 offset += 2;
2862
2863 /* beamId might get invalidated by e.g., ext-6, ext-11, so unused value will still be shown here.. */
2864 proto_item_append_text(sectionHeading, ", BeamId: %d", section_beamId);
2865 break;
2866
2867 case SEC_C_PRACH: /* Section Type 3 - Table 7.4.5-1 */
2868 {
2869 /* beamId */
2870 section_beamId_ti = proto_tree_add_item_ret_uint(c_section_tree, hf_oran_beamId, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &section_beamId);
2871 offset += 2;
2872
2873 /* freqOffset */
2874 int32_t freqOffset; /* Yes, this is signed, so the cast is intentional. */
2875 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);
2876 freqOffset |= 0xff000000; /* Must sign-extend */
2877 proto_item_set_text(freq_offset_item, "Frequency offset: %d \u0394f", freqOffset);
2878 offset += 3;
2879
2880 /* reserved (8 bits) */
2881 add_reserved_field(c_section_tree, hf_oran_reserved_8bits, tvb, offset, 1);
2882 offset += 1;
2883
2884 /* beamId might get invalidated by e.g., ext-6, ext-11, so unused value will still be shown here.. */
2885 proto_item_append_text(sectionHeading, ", BeamId: %d, FreqOffset: %d \u0394f", section_beamId, freqOffset);
2886 break;
2887 }
2888
2889 case SEC_C_UE_SCHED: /* Section Type 5 - Table 7.4.7-1 */
2890 case SEC_C_RRM_MEAS_REPORTS: /* Section Type 10 - Table 7.4.12-1 */
2891 /* ueId */
2892 ueId_ti = proto_tree_add_item_ret_uint(c_section_tree, hf_oran_ueId, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &ueId);
2893 offset += 2;
2894 if (ueId == 0x7fff) {
2895 proto_item_append_text(ueId_ti, " (PRBs not scheduled for eAxC ID in transport header)");
2896 }
2897 else {
2898 ueids[number_of_ueids++] = ueId;
2899 }
2900
2901 proto_item_append_text(sectionHeading, ", UEId: %d", ueId);
2902 break;
2903
2904 case SEC_C_SINR_REPORTING: /* Section Type 9 - SINR Reporting */
2905 {
2906 /* Hidden filter for bf (DMFS-BF) */
2907 proto_item *bf_ti = proto_tree_add_item(tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
2908 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
2909
2910 unsigned bit_offset = offset*8;
2911
2912 /* sinr iqWidth */
2913 proto_item *iq_width_item = proto_tree_add_uint(c_section_tree, hf_oran_sinrCompHdrIqWidth_pref, tvb, 0, 0, pref_sample_bit_width_sinr);
2914 proto_item_append_text(iq_width_item, " (from preferences)");
2915 proto_item_set_generated(iq_width_item);
2916
2917 /* sinr compMethod */
2918 proto_item *sinr_comp_meth_item = proto_tree_add_uint(c_section_tree, hf_oran_sinrCompHdrMeth_pref, tvb, 0, 0, pref_iqCompressionSINR);
2919 proto_item_append_text(sinr_comp_meth_item, " (from preferences)");
2920 proto_item_set_generated(sinr_comp_meth_item);
2921
2922 /* Add SINR entries for each PRB */
2923 for (unsigned prb=startPrbu; prb < startPrbu+numPrbu; prb++) {
2924 /* Create a subtree for each PRB */
2925 proto_item *prb_ti = proto_tree_add_string_format(c_section_tree, hf_oran_sinr_prb,
2926 tvb, offset, 0, "", "PRB %3u (", prb);
2927 proto_tree *prb_tree = proto_item_add_subtree(prb_ti, ett_oran_sinr_prb);
2928
2929 /* Each prb starts byte-aligned */
2930 bit_offset = ((bit_offset+7)/8) * 8;
2931
2932 /* N.B., using width/method from UL U-plane preferences, not certain that this is correct.. */
2933
2934 /* sinrCompParam (udCompParam format, may be empty) */
2935 uint32_t exponent = 0; /* N.B. init to silence warnings, but will always be set if read in COMP_BLOCK_FP case */
2936 uint16_t sReSMask;
2937 bit_offset = dissect_udcompparam(tvb, pinfo, prb_tree, bit_offset/8,
2938 pref_iqCompressionSINR, &exponent, &sReSMask,
2939 true1) * 8; /* last param is for_sinr */
2940
2941 /* sinrValues for this PRB. */
2942 /* TODO: not sure how numSinrPerPrb interacts with rb==1... */
2943 for (unsigned n=0; n < num_sinr_per_prb; n++) {
2944 unsigned sinr_bits = tvb_get_bits32(tvb, bit_offset, pref_sample_bit_width_sinr, ENC_BIG_ENDIAN0x00000000);
2945
2946 /* Using SINR compression settings from preferences */
2947 float value = decompress_value(sinr_bits,
2948 pref_iqCompressionSINR, pref_sample_bit_width_sinr,
2949 exponent,
2950 NULL((void*)0) /* no ModCompr for SINR */, 0 /* RE */);
2951 unsigned sample_len_in_bytes = ((bit_offset%8)+pref_sample_bit_width_sinr+7)/8;
2952 proto_item *val_ti = proto_tree_add_float(prb_tree, hf_oran_sinr_value, tvb,
2953 bit_offset/8, sample_len_in_bytes, value);
2954 proto_item_append_text(prb_ti, " %8f", value);
2955
2956 /* Show here which subcarriers share which values (they all divide 12..) */
2957 if (num_sinr_per_prb == 12) {
2958 proto_item_append_text(val_ti, " (PRB=%u, subcarrier %u)",
2959 startPrbu+((prb-startPrbu)*(rb+1)), n*(12/num_sinr_per_prb));
2960 }
2961 else {
2962 proto_item_append_text(val_ti, " (PRB=%u, subcarriers %u-%u)",
2963 startPrbu+((prb-startPrbu)*(rb+1)),
2964 n*(12/num_sinr_per_prb), (n+1)*(12/num_sinr_per_prb)-1);
2965 }
2966 bit_offset += pref_sample_bit_width_sinr;
2967 }
2968
2969 /* 1-byte alignment per PRB (7.2.11) */
2970 offset = (bit_offset+7)/8;
2971 bit_offset = offset*8;
2972
2973 proto_item_append_text(prb_ti, ")");
2974 proto_item_set_end(prb_ti, tvb, offset);
2975 }
2976 break;
2977 }
2978 case SEC_C_REQUEST_RRM_MEAS: /* Section Type 11 - Request RRM Measurements */
2979 /* Reserved (15 bits) */
2980 add_reserved_field(c_section_tree, hf_oran_reserved_15bits, tvb, offset, 2);
2981 offset += 2;
2982 break;
2983
2984 default:
2985 break;
2986 }
2987 }
2988 else if (sectionType == SEC_C_CH_INFO) { /* Section Type 6 */
2989 /* ef */
2990 proto_tree_add_item_ret_boolean(c_section_tree, hf_oran_ef, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &extension_flag);
2991 /* ueId */
2992 proto_tree_add_item_ret_uint(c_section_tree, hf_oran_ueId, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &ueId);
2993 offset += 2;
2994 /* regularizationFactor */
2995 proto_tree_add_item(c_section_tree, hf_oran_regularizationFactor, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
2996 offset += 2;
2997 /* reserved (4 bits) */
2998 add_reserved_field(c_section_tree, hf_oran_reserved_4bits, tvb, offset, 1);
2999 /* rb ("Value=0 shall be set") */
3000 uint32_t rb;
3001 proto_item *rb_ti = proto_tree_add_item_ret_uint(c_section_tree, hf_oran_rb, tvb, offset, 1, ENC_NA0x00000000, &rb);
3002 if (rb != 0) {
3003 proto_item_append_text(rb_ti, " (should be set to 0)");
3004 expert_add_info(pinfo, rb_ti, &ei_oran_st6_rb_shall_be_0);
3005 }
3006 /* symInc */
3007 proto_tree_add_item(c_section_tree, hf_oran_symInc, tvb, offset, 1, ENC_NA0x00000000);
3008 /* startPrbc */
3009 proto_tree_add_item_ret_uint(c_section_tree, hf_oran_startPrbc, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &startPrbc);
3010 offset += 2;
3011 /* numPrbc */
3012 proto_tree_add_item_ret_uint(c_section_tree, hf_oran_numPrbc, tvb, offset, 1, ENC_NA0x00000000, &numPrbc);
3013 offset += 1;
3014
3015 /* Hidden filter for bf */
3016 proto_item *bf_ti = proto_tree_add_item(tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
3017 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
3018
3019 /* ciIsample,ciQsample pairs */
3020 unsigned m;
3021 unsigned prb;
3022 uint32_t bit_offset = offset*8;
3023
3024 /* Antenna count from preference */
3025 unsigned num_trx = pref_num_bf_antennas;
3026
3027 write_channel_section_info(sectionHeading, pinfo,
3028 sectionId, ueId, startPrbc, numPrbc, num_trx);
3029
3030 bool_Bool first_prb = true1;
3031 uint8_t exponent = 0;
3032 for (prb=startPrbc; prb < startPrbc+numPrbc; prb++) {
3033
3034 /* PRB subtree */
3035 unsigned prb_start_offset = bit_offset;
3036 proto_item *prb_ti = proto_tree_add_string_format(c_section_tree, hf_oran_samples_prb,
3037 tvb, bit_offset/8, 0,
3038 "", "PRB=%u", prb);
3039 proto_tree *prb_tree = proto_item_add_subtree(prb_ti, ett_oran_prb_cisamples);
3040
3041 /* There may be a ciCompParam here.. */
3042 if (first_prb || ci_comp_opt==1) {
3043 bit_offset = dissect_ciCompParam(tvb, prb_tree, pinfo, bit_offset, ci_comp_meth, &exponent);
3044 }
3045 first_prb = false0;
3046
3047 /* Antennas */
3048 for (m=0; m < num_trx; m++) {
3049
3050 unsigned sample_offset = bit_offset / 8;
3051 uint8_t sample_extent = ((bit_offset + (ci_iq_width*2)) / 8) - sample_offset;
3052
3053 /* Create subtree for antenna */
3054 proto_item *sample_ti = proto_tree_add_string_format(prb_tree, hf_oran_ciSample,
3055 tvb, sample_offset, sample_extent,
3056 "", "TRX=%2u: ", m);
3057 proto_tree *sample_tree = proto_item_add_subtree(sample_ti, ett_oran_cisample);
3058
3059 /* I */
3060 /* Get bits, and convert to float. */
3061 uint32_t bits = tvb_get_bits32(tvb, bit_offset, ci_iq_width, ENC_BIG_ENDIAN0x00000000);
3062 float value = decompress_value(bits, ci_comp_meth, ci_iq_width, exponent, NULL((void*)0) /* no ModCompr for ST6 */, 0 /* RE */);
3063
3064 /* Add to tree. */
3065 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);
3066 bit_offset += ci_iq_width;
3067 proto_item_append_text(sample_ti, "I%u=%f ", m, value);
3068
3069 /* Q */
3070 /* Get bits, and convert to float. */
3071 bits = tvb_get_bits32(tvb, bit_offset, ci_iq_width, ENC_BIG_ENDIAN0x00000000);
3072 value = decompress_value(bits, ci_comp_meth, ci_iq_width, exponent, NULL((void*)0) /* no ModCompr for ST6 */, 0 /* RE */);
3073
3074 /* Add to tree. */
3075 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);
3076 bit_offset += ci_iq_width;
3077 proto_item_append_text(sample_ti, "Q%u=%f ", m, value);
3078 }
3079 proto_item_set_len(prb_ti, (bit_offset-prb_start_offset+7)/8);
3080 }
3081
3082 /* Pad out by 1 or 4 bytes, according to preference */
3083 if (!st6_4byte_alignment) {
3084 offset = (bit_offset + 7) / 8;
3085 }
3086 else {
3087 int mode = bit_offset % 32;
3088 if (mode != 0) {
3089 offset = (bit_offset + (32-mode))/8;
3090 }
3091 else {
3092 offset = bit_offset/8;
3093 }
3094 }
3095 proto_item_set_end(c_section_tree, tvb, offset);
3096 }
3097
3098
3099 expected_section_data_t *dl_data_section = NULL((void*)0);
3100 unsigned index_to_use = 0;
3101
3102 /* On first pass, allocate a section entry to use */
3103 if (link_planes_together && !PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
3104
3105 if (!tap_info->uplink) {
3106 /* Look for existing entry for sectionId to overwrite first. */
3107 dl_data_section = wmem_tree_lookup32(state->expected_dl_sections,
3108 sectionId);
3109 if (dl_data_section == NULL((void*)0)) {
3110 /* None, so create */
3111 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)))
;
3112 wmem_tree_insert32(state->expected_dl_sections,
3113 sectionId,
3114 dl_data_section);
3115 }
3116
3117 /* If 2nd entry not in use, use that one */
3118 if (!dl_data_section->details[1].in_use) {
3119 index_to_use = 1;
3120 }
3121 else {
3122 /* Both in use, so replace the older of the 2 entries */
3123 if (dl_data_section->details[1].frame_number < dl_data_section->details[0].frame_number) {
3124 index_to_use = 1;
3125 }
3126 }
3127
3128 if (dl_data_section) {
3129 section_details_t *details = &dl_data_section->details[index_to_use];
3130
3131 details->in_use = true1;
3132 details->frame = frameId;
3133 details->subframe = subframeId;
3134 details->slot = slotId;
3135 details->startSymbol = startSymbolId;
3136
3137 details->frame_number = pinfo->num;
3138 details->frame_time = pinfo->abs_ts;
3139 dl_data_section->sectionId = sectionId;
3140 details->startPrb = startPrbc;
3141 details->numPrb = numPrbc;
3142 for (unsigned prb = startPrbc; prb <= startPrbc+numPrbc; prb++) {
3143 if (prb < 273) {
3144 details->beamIds[prb] = section_beamId;
3145 }
3146 }
3147 }
3148 }
3149 }
3150
3151 bool_Bool seen_se10 = false0;
3152 uint32_t numPortc = 0;
3153 proto_item *bf_ti = NULL((void*)0);
3154
3155 /* Section extension commands */
3156 while (extension_flag) {
3157 int extension_start_offset = offset;
3158
3159 /* Prefetch extType so can use specific extension type ett */
3160 uint32_t exttype = tvb_get_uint8(tvb, offset) & 0x7f;
3161 uint32_t exttype_ett_index = exttype;
3162 if (exttype == 0 || exttype > HIGHEST_EXTTYPE30) {
3163 /* Just use first one if out of range */
3164 exttype_ett_index = 1;
3165 }
3166
3167 /* Create subtree for each extension (with summary) */
3168 proto_item *extension_ti = proto_tree_add_string_format(c_section_tree, hf_oran_extension,
3169 tvb, offset, 0, "", "Extension");
3170 proto_tree *extension_tree = proto_item_add_subtree(extension_ti, ett_oran_c_section_extension[exttype_ett_index-1]);
3171
3172 /* ef (i.e. another extension after this one?) */
3173 proto_tree_add_item_ret_boolean(extension_tree, hf_oran_ef, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &extension_flag);
3174
3175 /* extType */
3176 proto_item *exttype_ti;
3177 exttype_ti = proto_tree_add_item(extension_tree, hf_oran_exttype, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3178 offset++;
3179 proto_item_append_text(sectionHeading, " (ext-%u)", exttype);
3180
3181 proto_item_append_text(extension_ti, " (ext-%u: %s)", exttype, val_to_str_ext_const(exttype, &exttype_vals_ext, "Reserved"));
3182
3183 /* Don't tap if out of range. */
3184 if (exttype > 0 && exttype <= HIGHEST_EXTTYPE30) {
3185 tap_info->extensions[exttype] = true1;
3186 }
3187
3188 /* Is this SE allowed for this section type? */
3189 if (!se_allowed_in_st(exttype, sectionType)) {
3190 expert_add_info_format(pinfo, extension_tree, &ei_oran_se_on_unsupported_st,
3191 "SE %u (%s) should not appear in ST %u (%s)!",
3192 exttype, val_to_str_ext_const(exttype, &exttype_vals_ext, "Reserved"),
3193 sectionType, rval_to_str_const(sectionType, section_types, "Unknown"));
3194 }
3195
3196
3197 /* extLen (number of 32-bit words) */
3198 uint32_t extlen_len = ((exttype==11)||(exttype==19)||(exttype==20)) ? 2 : 1; /* Extensions 11/19/20 are special */
3199 uint32_t extlen;
3200 proto_item *extlen_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_extlen, tvb,
3201 offset, extlen_len, ENC_BIG_ENDIAN0x00000000, &extlen);
3202 proto_item_append_text(extlen_ti, " (%u bytes)", extlen*4);
3203 offset += extlen_len;
3204 if (extlen == 0) {
3205 expert_add_info(pinfo, extlen_ti, &ei_oran_extlen_zero);
3206 /* Break out to avoid infinitely looping! */
3207 break;
3208 }
3209
3210 bool_Bool ext_unhandled = false0;
3211
3212 switch (exttype) {
3213
3214 case 1: /* SE 1: Beamforming Weights */
3215 {
3216 uint32_t bfwcomphdr_iq_width, bfwcomphdr_comp_meth;
3217 proto_item *comp_meth_ti = NULL((void*)0);
3218
3219 /* Hidden filter for bf */
3220 bf_ti = proto_tree_add_item(tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
3221 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
3222
3223 /* bfwCompHdr (2 subheaders - bfwIqWidth and bfwCompMeth)*/
3224 offset = dissect_bfwCompHdr(tvb, extension_tree, offset,
3225 &bfwcomphdr_iq_width, &bfwcomphdr_comp_meth, &comp_meth_ti);
3226
3227 /* bfwCompParam */
3228 uint32_t exponent = 0;
3229 bool_Bool compression_method_supported = false0;
3230 unsigned num_trx = 0;
3231 uint16_t *trx; /* ptr to array */
3232 offset = dissect_bfwCompParam(tvb, extension_tree, pinfo, offset, comp_meth_ti,
3233 &bfwcomphdr_comp_meth, &exponent, &compression_method_supported,
3234 &num_trx, &trx);
3235
3236 /* Can't show details of unsupported compression method */
3237 if (!compression_method_supported) {
3238 break;
3239 }
3240
3241 /* We know:
3242 - iq_width (above)
3243 - numBfWeights (taken from preference)
3244 - remaining bytes in extension
3245 We can therefore derive TRX (number of antennas).
3246 */
3247
3248 bool_Bool using_array = false0;
3249
3250 /* I & Q samples
3251 May know how many entries from activeBeamspaceCoefficientMask. */
3252 if (num_trx == 0) {
3253 /* Don't know how many there will be, so just fill available bytes... */
3254 unsigned weights_bytes = (extlen*4)-3;
3255 unsigned num_weights_pairs = (weights_bytes*8) / (bfwcomphdr_iq_width*2);
3256 num_trx = num_weights_pairs;
3257 }
3258 else {
3259 using_array = true1;
3260 num_trx = pref_num_bf_antennas;
3261 }
3262
3263 int bit_offset = offset*8;
3264
3265 for (unsigned n=0; n < num_trx; n++) {
3266 /* Create antenna subtree */
3267 int bfw_offset = bit_offset / 8;
3268
3269 uint16_t trx_index = (using_array) ? trx[n] : n+1;
3270
3271 proto_item *bfw_ti = proto_tree_add_string_format(extension_tree, hf_oran_bfw,
3272 tvb, bfw_offset, 0, "", "TRX %3u: (", trx_index);
3273 proto_tree *bfw_tree = proto_item_add_subtree(bfw_ti, ett_oran_bfw);
3274
3275 /* I value */
3276 /* Get bits, and convert to float. */
3277 uint32_t bits = tvb_get_bits32(tvb, bit_offset, bfwcomphdr_iq_width, ENC_BIG_ENDIAN0x00000000);
3278 float value = decompress_value(bits, bfwcomphdr_comp_meth, bfwcomphdr_iq_width, exponent,
3279 NULL((void*)0) /* no ModCompr */, 0 /* RE */);
3280 /* Add to tree. */
3281 proto_tree_add_float(bfw_tree, hf_oran_bfw_i, tvb, bit_offset/8,
3282 (bfwcomphdr_iq_width+7)/8, value);
3283 bit_offset += bfwcomphdr_iq_width;
3284 proto_item_append_text(bfw_ti, "I=%f ", value);
3285
3286 /* Leave a gap between I and Q values */
3287 proto_item_append_text(bfw_ti, " ");
3288
3289 /* Q value */
3290 /* Get bits, and convert to float. */
3291 bits = tvb_get_bits32(tvb, bit_offset, bfwcomphdr_iq_width, ENC_BIG_ENDIAN0x00000000);
3292 value = decompress_value(bits, bfwcomphdr_comp_meth, bfwcomphdr_iq_width, exponent,
3293 NULL((void*)0) /* no ModCompr */, 0 /* RE */);
3294 /* Add to tree. */
3295 proto_tree_add_float(bfw_tree, hf_oran_bfw_q, tvb, bit_offset/8,
3296 (bfwcomphdr_iq_width+7)/8, value);
3297 bit_offset += bfwcomphdr_iq_width;
3298 proto_item_append_text(bfw_ti, "Q=%f", value);
3299
3300 proto_item_append_text(bfw_ti, ")");
3301 proto_item_set_len(bfw_ti, (bit_offset+7)/8 - bfw_offset);
3302 }
3303 /* Need to round to next byte */
3304 offset = (bit_offset+7)/8;
3305
3306 break;
3307 }
3308
3309 case 2: /* SE 2: Beamforming attributes */
3310 {
3311 /* Hidden filter for bf */
3312 bf_ti = proto_tree_add_item(tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
3313 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
3314
3315 /* bfaCompHdr (get widths of fields to follow) */
3316 uint32_t bfAzPtWidth, bfZePtWidth, bfAz3ddWidth, bfZe3ddWidth;
3317 /* subtree */
3318 proto_item *bfa_ti = proto_tree_add_string_format(extension_tree, hf_oran_bfaCompHdr,
3319 tvb, offset, 2, "", "bfaCompHdr");
3320 proto_tree *bfa_tree = proto_item_add_subtree(bfa_ti, ett_oran_bfacomphdr);
3321
3322 /* reserved (2 bits) */
3323 add_reserved_field(bfa_tree, hf_oran_reserved_2bits, tvb, offset, 1);
3324 /* bfAzPtWidth (3 bits) */
3325 proto_tree_add_item_ret_uint(bfa_tree, hf_oran_bfAzPtWidth, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &bfAzPtWidth);
3326 /* bfZePtWidth (3 bits) */
3327 proto_tree_add_item_ret_uint(bfa_tree, hf_oran_bfZePtWidth, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &bfZePtWidth);
3328 offset += 1;
3329
3330 /* reserved (2 bits) */
3331 add_reserved_field(bfa_tree, hf_oran_reserved_2bits, tvb, offset, 1);
3332 /* bfAz3ddWidth (3 bits) */
3333 proto_tree_add_item_ret_uint(bfa_tree, hf_oran_bfAz3ddWidth, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &bfAz3ddWidth);
3334 /* bfZe3ddWidth (3 bits) */
3335 proto_tree_add_item_ret_uint(bfa_tree, hf_oran_bfZe3ddWidth, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &bfZe3ddWidth);
3336 offset += 1;
3337
3338 unsigned bit_offset = offset*8;
3339
3340 /* bfAzPt */
3341 if (bfAzPtWidth > 0) {
3342 proto_tree_add_bits_item(extension_tree, hf_oran_bfAzPt, tvb, bit_offset, bfAzPtWidth+1, ENC_BIG_ENDIAN0x00000000);
3343 bit_offset += (bfAzPtWidth+1);
3344 }
3345 /* bfZePt */
3346 if (bfZePtWidth > 0) {
3347 proto_tree_add_bits_item(extension_tree, hf_oran_bfZePt, tvb, bit_offset, bfZePtWidth+1, ENC_BIG_ENDIAN0x00000000);
3348 bit_offset += (bfZePtWidth+1);
3349 }
3350 /* bfAz3dd */
3351 if (bfAz3ddWidth > 0) {
3352 proto_tree_add_bits_item(extension_tree, hf_oran_bfAz3dd, tvb, bit_offset, bfAz3ddWidth+1, ENC_BIG_ENDIAN0x00000000);
3353 bit_offset += (bfAz3ddWidth+1);
3354 }
3355 /* bfZe3dd */
3356 if (bfZe3ddWidth > 0) {
3357 proto_tree_add_bits_item(extension_tree, hf_oran_bfZe3dd, tvb, bit_offset, bfZe3ddWidth+1, ENC_BIG_ENDIAN0x00000000);
3358 bit_offset += (bfZe3ddWidth+1);
3359 }
3360
3361 /* Pad to next byte (unless last 2 fields already fit in this one) */
3362 if ((bit_offset % 8) > 2) {
3363 offset = (bit_offset+7) / 8;
3364 }
3365 else {
3366 offset = bit_offset / 8;
3367 }
3368
3369 /* bfAzSl (3 bits) */
3370 proto_tree_add_item(extension_tree, hf_oran_bfAzSl, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3371 /* bfZeSl (3 bits) */
3372 proto_tree_add_item(extension_tree, hf_oran_bfZeSl, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3373 offset += 1;
3374 break;
3375 }
3376
3377 case 3: /* SE 3: DL precoding parameters */
3378 {
3379 /* codebookindex (8 bits) */
3380 /* "This parameter is not used and shall be set to zero." */
3381 proto_tree_add_item(extension_tree, hf_oran_codebook_index, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3382 offset += 1;
3383 /* layerid */
3384 uint32_t layerid;
3385 proto_tree_add_item_ret_uint(extension_tree, hf_oran_layerid, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &layerid);
3386 /* numLayers */
3387 proto_tree_add_item(extension_tree, hf_oran_numlayers, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3388 offset += 1;
3389
3390 /* Stop here for non-first data layer */
3391 if (layerid != 0 && layerid != 0xf) {
3392 break;
3393 }
3394
3395 /* First data layer case */
3396 /* txScheme */
3397 proto_tree_add_item(extension_tree, hf_oran_txscheme, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3398 /* crsReMask */
3399 proto_tree_add_item(extension_tree, hf_oran_crs_remask, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
3400 offset += 2;
3401
3402 /* crsShift (1 bit) */
3403 proto_tree_add_item(extension_tree, hf_oran_crs_shift, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3404 /* reserved (3 bits) */
3405 add_reserved_field(extension_tree, hf_oran_reserved_bits123, tvb, offset, 1);
3406 /* crsSymNum (4 bits) */
3407 proto_tree_add_item(extension_tree, hf_oran_crs_symnum, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3408 offset += 1;
3409 /* reserved (8 bits) */
3410 add_reserved_field(extension_tree, hf_oran_reserved_8bits, tvb, offset, 1);
3411 offset += 1;
3412
3413 /* reserved (1 bit) */
3414 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
3415 /* beamIdAP1 (15 bits) */
3416 proto_tree_add_item(extension_tree, hf_oran_beamid_ap1, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
3417 offset += 2;
3418 /* reserved (1 bit) */
3419 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
3420 /* beamIdAP2 (15 bits) */
3421 proto_tree_add_item(extension_tree, hf_oran_beamid_ap2, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
3422 offset += 2;
3423 /* reserved (1 bit) */
3424 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
3425 /* beamIdAP3 (15 bits) */
3426 proto_tree_add_item(extension_tree, hf_oran_beamid_ap3, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
3427 offset += 2;
3428 break;
3429 }
3430
3431 case 4: /* SE 4: Modulation compression params (5.4.7.4) (single sets) */
3432 {
3433 /* csf */
3434 bool_Bool csf;
3435 dissect_csf(extension_tree, tvb, offset*8, ci_iq_width, &csf);
3436
3437 /* modCompScaler */
3438 uint32_t modCompScaler;
3439 proto_item *ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_modcompscaler,
3440 tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &modCompScaler);
3441 offset += 2;
3442
3443 /* Work out and show floating point value too. exponent and mantissa are both unsigned */
3444 uint16_t exponent = (modCompScaler >> 11) & 0x000f; /* m.s. 4 bits */
3445 uint16_t mantissa = modCompScaler & 0x07ff; /* l.s. 11 bits */
3446 float value = ((float)mantissa/(1<<11)) * ((float)1.0 / (1 << exponent));
3447 proto_item_append_text(ti, " (%f)", value);
3448
3449 section_mod_compr_config_t* sect_config = get_mod_compr_section_to_write(state, sectionId);
3450
3451 /* Store these params in this flow's state */
3452 if (sect_config && sect_config->num_configs < MAX_MOD_COMPR_CONFIGS12) {
3453 unsigned i = sect_config->num_configs;
3454 sect_config->configs[i].mod_compr_re_mask = 0xfff; /* Covers all REs */
3455 sect_config->configs[i].mod_compr_csf = csf;
3456 sect_config->configs[i].mod_compr_scaler = value;
3457 sect_config->num_configs++;
3458 }
3459 break;
3460 }
3461
3462 case 5: /* SE 5: Modulation Compression Additional Parameters (7.7.5) (multiple sets) */
3463 {
3464 /* Applies only to section types 1,3 and 5 */
3465 /* N.B. there may be multiple instances of this SE in the same frame */
3466
3467 /* There may be one or 2 entries, depending upon extlen */
3468 int sets = 1, reserved_bits = 0;
3469 switch (extlen) {
3470 case 2:
3471 sets = 1;
3472 reserved_bits = 20;
3473 break;
3474 case 3:
3475 sets = 2;
3476 reserved_bits = 24;
3477 break;
3478 case 4:
3479 /* sets can be 3 or 4, depending upon whether last 28 bits are 0.. */
3480 if ((tvb_get_ntohl(tvb, offset+10) & 0x0fffffff) == 0) {
3481 sets = 3;
3482 reserved_bits = 28;
3483 }
3484 else {
3485 sets = 4;
3486 reserved_bits = 0;
3487 }
3488 break;
3489
3490 default:
3491 /* Malformed error!!! */
3492 expert_add_info_format(pinfo, extlen_ti, &ei_oran_extlen_wrong,
3493 "For section 5, extlen must be 2, 3 or 4, but %u was dissected",
3494 extlen);
3495 break;
3496 }
3497
3498 unsigned bit_offset = offset*8;
3499 /* Dissect each set */
3500 for (int n=0; n < sets; n++) {
3501 /* Subtree for each set */
3502 unsigned set_start_offset = bit_offset/8;
3503 proto_item *set_ti = proto_tree_add_string(extension_tree, hf_oran_modcomp_param_set,
3504 tvb, set_start_offset, 0, "");
3505 proto_tree *set_tree = proto_item_add_subtree(set_ti, ett_oran_modcomp_param_set);
3506
3507 uint64_t mcScaleReMask, mcScaleOffset;
3508 bool_Bool csf;
3509
3510 /* mcScaleReMask (12 bits). Defines which REs the following csf and mcScaleOffset apply to */
3511 static int * const remask_flags[] = {
3512 &hf_oran_mc_scale_re_mask_re1,
3513 &hf_oran_mc_scale_re_mask_re2,
3514 &hf_oran_mc_scale_re_mask_re3,
3515 &hf_oran_mc_scale_re_mask_re4,
3516 &hf_oran_mc_scale_re_mask_re5,
3517 &hf_oran_mc_scale_re_mask_re6,
3518 &hf_oran_mc_scale_re_mask_re7,
3519 &hf_oran_mc_scale_re_mask_re8,
3520 &hf_oran_mc_scale_re_mask_re9,
3521 &hf_oran_mc_scale_re_mask_re10,
3522 &hf_oran_mc_scale_re_mask_re11,
3523 &hf_oran_mc_scale_re_mask_re12,
3524 NULL((void*)0)
3525 };
3526 /* Same as above, but offset by 4 bits */
3527 static int * const remask_flags_even[] = {
3528 &hf_oran_mc_scale_re_mask_re1_even,
3529 &hf_oran_mc_scale_re_mask_re2_even,
3530 &hf_oran_mc_scale_re_mask_re3_even,
3531 &hf_oran_mc_scale_re_mask_re4_even,
3532 &hf_oran_mc_scale_re_mask_re5_even,
3533 &hf_oran_mc_scale_re_mask_re6_even,
3534 &hf_oran_mc_scale_re_mask_re7_even,
3535 &hf_oran_mc_scale_re_mask_re8_even,
3536 &hf_oran_mc_scale_re_mask_re9_even,
3537 &hf_oran_mc_scale_re_mask_re10_even,
3538 &hf_oran_mc_scale_re_mask_re11_even,
3539 &hf_oran_mc_scale_re_mask_re12_even,
3540 NULL((void*)0)
3541 };
3542
3543 /* RE Mask (12 bits) */
3544 proto_tree_add_bitmask_ret_uint64(set_tree, tvb, bit_offset / 8,
3545 (n % 2) ? hf_oran_mc_scale_re_mask_even : hf_oran_mc_scale_re_mask,
3546 ett_oran_mc_scale_remask,
3547 (n % 2) ? remask_flags_even : remask_flags, ENC_BIG_ENDIAN0x00000000, &mcScaleReMask);
3548 bit_offset += 12;
3549
3550 /* csf (1 bit) */
3551 bit_offset = dissect_csf(set_tree, tvb, bit_offset, ci_iq_width, &csf);
3552 /* mcScaleOffset (15 bits) */
3553 proto_item *ti = proto_tree_add_bits_ret_val(set_tree, hf_oran_mc_scale_offset, tvb, bit_offset, 15, &mcScaleOffset, ENC_BIG_ENDIAN0x00000000);
3554 uint16_t exponent = (mcScaleOffset >> 11) & 0x000f; /* m.s. 4 bits */
3555 uint16_t mantissa = mcScaleOffset & 0x07ff; /* l.s. 11 bits */
3556 float mcScaleOffset_value = ((float)mantissa/(1<<11)) * ((float)1.0 / (1 << exponent));
3557 proto_item_append_text(ti, " (%f)", mcScaleOffset_value);
3558 bit_offset += 15;
3559
3560 section_mod_compr_config_t* sect_config = get_mod_compr_section_to_write(state, sectionId);
3561
3562 /* Record this config */
3563 if (sect_config && sect_config->num_configs < MAX_MOD_COMPR_CONFIGS12) {
3564 unsigned i = sect_config->num_configs;
3565 sect_config->configs[i].mod_compr_re_mask = (uint16_t)mcScaleReMask;
3566 sect_config->configs[i].mod_compr_csf = csf;
3567 sect_config->configs[i].mod_compr_scaler = mcScaleOffset_value;
3568 sect_config->num_configs++;
3569 }
3570
3571 /* Summary */
3572 proto_item_set_len(set_ti, (bit_offset+7)/8 - set_start_offset);
3573 proto_item_append_text(set_ti, " (mcScaleReMask=0x%03x csf=%5s mcScaleOffset=%f)",
3574 (unsigned)mcScaleReMask, tfs_get_true_false(csf)tfs_get_string(csf, ((void*)0)), mcScaleOffset_value);
3575 }
3576
3577 proto_item_append_text(extension_ti, " (%u sets)", sets);
3578
3579 /* Reserved (variable-length) */
3580 if (reserved_bits) {
3581 proto_tree_add_bits_item(extension_tree, hf_oran_reserved, tvb, bit_offset, reserved_bits, ENC_BIG_ENDIAN0x00000000);
3582 bit_offset += reserved_bits;
3583 }
3584
3585 offset = bit_offset/8;
3586 break;
3587 }
3588
3589 case 6: /* SE 6: Non-contiguous PRB allocation in time and frequency domain */
3590 {
3591 /* numSymbol not used in this case */
3592 if (numsymbol_ti && !numsymbol_ignored) {
3593 proto_item_append_text(numsymbol_ti, " (ignored)");
3594 numsymbol_ignored = true1;
3595 }
3596
3597 /* Will update ext6 recorded info */
3598 ext11_settings.ext6_set = true1;
3599
3600 /* repetition */
3601 proto_tree_add_bits_item(extension_tree, hf_oran_se6_repetition, tvb, offset*8, 1, ENC_BIG_ENDIAN0x00000000);
3602 /* rbgSize (PRBs per bit set in rbgMask) */
3603 uint32_t rbgSize;
3604 proto_item *rbg_size_ti;
3605 rbg_size_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_rbgSize, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &rbgSize);
3606 if (rbgSize == 0) {
3607 /* N.B. this is only true if "se6-rb-bit-supported" is set... */
3608 expert_add_info(pinfo, rbg_size_ti, &ei_oran_rbg_size_reserved);
3609 }
3610 /* rbgMask (28 bits) */
3611 uint32_t rbgMask;
3612 proto_item *rbgmask_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_rbgMask, tvb, offset, 4, ENC_BIG_ENDIAN0x00000000, &rbgMask);
3613 if (rbgSize == 0) {
3614 proto_item_append_text(rbgmask_ti, " (value ignored since rbgSize is 0)");
3615 }
3616
3617 /* TODO: if receiver detects non-zero bits outside the valid range, those shall be ignored. */
3618 offset += 4;
3619 /* priority */
3620 proto_tree_add_item(extension_tree, hf_oran_noncontig_priority, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3621 /* symbolMask */
3622 offset = dissect_symbolmask(tvb, extension_tree, offset, NULL((void*)0), NULL((void*)0));
3623
3624 /* Look up rbg_size enum -> value */
3625 switch (rbgSize) {
3626 case 0:
3627 /* N.B. reserved, but covered above with expert info (would remain 0) */
3628 break;
3629 case 1:
3630 ext11_settings.ext6_rbg_size = 1; break;
3631 case 2:
3632 ext11_settings.ext6_rbg_size = 2; break;
3633 case 3:
3634 ext11_settings.ext6_rbg_size = 3; break;
3635 case 4:
3636 ext11_settings.ext6_rbg_size = 4; break;
3637 case 5:
3638 ext11_settings.ext6_rbg_size = 6; break;
3639 case 6:
3640 ext11_settings.ext6_rbg_size = 8; break;
3641 case 7:
3642 ext11_settings.ext6_rbg_size = 16; break;
3643 /* N.B., encoded in 3 bits, so no other values are possible */
3644 }
3645
3646 /* Set to looked-up value */
3647 rbgSize = ext11_settings.ext6_rbg_size;
3648
3649 uint32_t lastRbgid = 0;
3650 if (rbgSize != 0) {
3651 /* The O-DU shall not use combinations of startPrbc, numPrbc and rbgSize leading to a value of lastRbgid larger than 27 */
3652 /* i.e., leftmost bit used should not need to go off left end of rbgMask! */
3653 lastRbgid = (uint32_t)ceil((numPrbc + (startPrbc % rbgSize)) / (float)rbgSize) - 1;
3654 if (lastRbgid > 27) {
3655 expert_add_info_format(pinfo, rbg_size_ti, &ei_oran_lastRbdid_out_of_range,
3656 "SE6: rbgSize (%u) not compatible with startPrbc(%u) and numPrbc(%u)",
3657 rbgSize, startPrbc, numPrbc);
3658 break;
3659 }
3660 }
3661
3662 /* Record (and count) which bits are set in rbgMask */
3663 bool_Bool first_seen = false0;
3664 unsigned first_seen_pos=0, last_seen_pos=0;
3665 for (unsigned n=0; n < 28 && ext11_settings.ext6_num_bits_set < 28; n++) {
3666 if ((rbgMask >> n) & 0x01) {
3667 ext11_settings.ext6_bits_set[ext11_settings.ext6_num_bits_set++] = n;
3668 if (!first_seen) {
3669 first_seen = true1;
3670 first_seen_pos = n;
3671 }
3672 last_seen_pos = n;
3673 }
3674 }
3675
3676 /* Show how many bits were set in rbgMask */
3677 proto_item_append_text(rbgmask_ti, " (%u bits set)", ext11_settings.ext6_num_bits_set);
3678 /* Also, that is the range of bits */
3679 if (first_seen) {
3680 proto_item_append_text(rbgmask_ti, " (%u bits spread)", last_seen_pos-first_seen_pos+1);
3681
3682 /* Complain if last set bit is beyond lastRbgid */
3683 if (last_seen_pos > lastRbgid) {
3684 expert_add_info_format(pinfo, rbgmask_ti, &ei_oran_rbgMask_beyond_last_rbdid,
3685 "SE6: rbgMask (0x%07x) has bit %u set, but lastRbgId is %u",
3686 rbgMask, last_seen_pos, lastRbgid);
3687 }
3688 }
3689
3690 /* Also update prbs_for_st10_type5[] */
3691 if (sectionType == 10 && rbgSize != 0) {
3692 /* Unset all entries */
3693 memset(&prbs_for_st10_type5, 0, sizeof(prbs_for_st10_type5));
3694
3695 /* Work out which PRB first bit corresponds to */
3696 unsigned firstPrbStart = (startPrbc/rbgSize) * rbgSize;
3697
3698 /* Add PRBs corresponding to each bit set */
3699 for (unsigned n=0; n < 28 ; n++) {
3700 if ((rbgMask >> n) & 0x01) {
3701 /* Lazy way to clip any values that lie outside of range for section */
3702 for (unsigned p=0; p < rbgSize; p++) {
3703 unsigned start = firstPrbStart + (n*rbgSize);
3704 if ((start+p < MAX_PRBS273) && (start+p >= startPrbc) && (start+p <= startPrbc+numPrbc-1)) {
3705 prbs_for_st10_type5[start+p] = true1;
3706 }
3707 }
3708 }
3709 }
3710 }
3711
3712 break;
3713 }
3714
3715 case 7: /* SE 7: eAxC mask */
3716 /* Allow ST0 to address multiple eAxC_ID values for transmission blanking */
3717 proto_tree_add_item(extension_tree, hf_oran_eAxC_mask, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
3718 offset += 2;
3719 break;
3720
3721 case 8: /* SE 8: Regularization factor */
3722 proto_tree_add_item(extension_tree, hf_oran_regularizationFactor, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
3723 offset += 2;
3724 break;
3725
3726 case 9: /* SE 9: Dynamic Spectrum Sharing parameters */
3727 proto_tree_add_item(extension_tree, hf_oran_technology, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3728 offset += 1;
3729 add_reserved_field(extension_tree, hf_oran_reserved_8bits, tvb, offset, 1);
3730 offset += 1;
3731 break;
3732
3733 case 10: /* SE 10: Group configuration of multiple ports */
3734 {
3735 seen_se10 = true1;
3736
3737 /* beamGroupType */
3738 uint32_t beam_group_type = 0;
3739 proto_item *bgt_ti;
3740 bgt_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_beamGroupType,
3741 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &beam_group_type);
3742 proto_item_append_text(extension_ti, " (%s)", val_to_str_const(beam_group_type, beam_group_type_vals, "Unknown"));
3743
3744 /* numPortc */
3745 proto_tree_add_item_ret_uint(extension_tree, hf_oran_numPortc,
3746 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &numPortc);
3747 offset++;
3748
3749 /* Will append all beamId values to extension_ti, regardless of beamGroupType */
3750 unsigned n;
3751
3752 switch (beam_group_type) {
3753 case 0x0: /* common beam */
3754 case 0x1: /* beam matrix indication */
3755 /* Reserved byte */
3756 add_reserved_field(extension_tree, hf_oran_reserved_8bits, tvb, offset, 1);
3757 offset++;
3758
3759 /* Explain how entries are allocated */
3760 if (beam_group_type == 0x0) {
3761 proto_item_append_text(extension_ti, " (all %u ueid/Beam entries are %u)", numPortc, ueId);
3762 }
3763 else {
3764 /* 'numPortc' consecutive BeamIds from section header */
3765 proto_item_append_text(extension_ti, " (ueId/beam entries are %u -> %u)", ueId, ueId+numPortc);
3766 }
3767
3768 if (sectionType == 5) {
3769 /* These types are not allowed */
3770 expert_add_info_format(pinfo, bgt_ti, &ei_oran_se10_not_allowed,
3771 "SE10: beamGroupType %u is not allowed for section type 5", beam_group_type);
3772 }
3773 break;
3774
3775 case 0x2: /* beam vector listing */
3776 {
3777 proto_item_append_text(extension_ti, " [ ");
3778
3779 /* Beam listing vector case */
3780 /* Work out how many port beam entries there is room for */
3781 /* Using numPortC as visible in issue 18116 */
3782 for (n=0; n < numPortc; n++) {
3783 /* 1 reserved bit */
3784 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
3785
3786 /* port beam ID (or UEID) (15 bits) */
3787 uint32_t id;
3788 proto_item *beamid_or_ueid_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_beamId,
3789 tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &id);
3790 proto_item_append_text(beamid_or_ueid_ti, " port #%u beam ID (or UEId) %u", n, id);
3791 offset += 2;
3792
3793 if (id != 0x7fff) {
3794 if (number_of_ueids < MAX_UEIDS16) {
3795 ueids[number_of_ueids++] = id;
3796 }
3797 }
3798
3799 proto_item_append_text(extension_ti, "%u ", id);
3800 }
3801
3802 proto_item_append_text(extension_ti, "]");
3803 break;
3804 }
3805 case 0x3: /* beamId/ueId listing with associated port-list index */
3806 {
3807 proto_item_append_text(extension_ti, " [ ");
3808
3809 if (numPortc > 0) {
3810 /* first portListIndex is outside loop */
3811 uint32_t port_list_index;
3812 proto_item *pli_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_port_list_index, tvb,
3813 offset, 1, ENC_BIG_ENDIAN0x00000000, &port_list_index);
3814 if (port_list_index == 0) {
3815 /* Value 0 is reserved */
3816 expert_add_info(pinfo, pli_ti, &ei_oran_port_list_index_zero);
3817 }
3818 offset += 1;
3819
3820 for (n=0; n < numPortc-1; n++) {
3821 /* 1 reserved bit */
3822 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
3823
3824 /* port beam ID (or UEID) */
3825 uint32_t id;
3826 proto_item *beamid_or_ueid_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_beamId,
3827 tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &id);
3828 proto_item_append_text(beamid_or_ueid_ti, " port #%u beam ID (or UEId) %u", n, id);
3829 offset += 2;
3830
3831 if (id != 0x7fff) {
3832 if (number_of_ueids < MAX_UEIDS16) {
3833 ueids[number_of_ueids++] = id;
3834 }
3835 }
3836
3837 /* subsequent portListIndex */
3838 pli_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_port_list_index, tvb,
3839 offset, 1, ENC_BIG_ENDIAN0x00000000, &port_list_index);
3840 if (port_list_index == 0) {
3841 /* Value 0 is reserved */
3842 expert_add_info(pinfo, pli_ti, &ei_oran_port_list_index_zero);
3843 }
3844 offset += 1;
3845
3846 proto_item_append_text(extension_ti, "%u:%u ", port_list_index, id);
3847 }
3848 }
3849
3850 proto_item_append_text(extension_ti, "]");
3851 break;
3852 }
3853
3854
3855 default:
3856 /* Warning for unsupported/reserved value */
3857 expert_add_info(NULL((void*)0), bgt_ti, &ei_oran_se10_unknown_beamgrouptype);
3858 break;
3859 }
3860 break;
3861 }
3862
3863 case 11: /* SE 11: Flexible Weights Extension Type */
3864 {
3865 /* Hidden filter for bf */
3866 bf_ti = proto_tree_add_item(tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
3867 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
3868
3869 /* beamId in section header should be ignored. Guard against appending multiple times.. */
3870 if (section_beamId_ti && !section_beamId_ignored) {
3871 proto_item_append_text(section_beamId_ti, " (ignored)");
3872 section_beamId_ignored = true1;
3873 }
3874
3875 bool_Bool disableBFWs;
3876 uint32_t numBundPrb;
3877 bool_Bool rad;
3878
3879 /* disableBFWs */
3880 proto_tree_add_item_ret_boolean(extension_tree, hf_oran_disable_bfws,
3881 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &disableBFWs);
3882 if (disableBFWs) {
3883 proto_item_append_text(extension_ti, " (disableBFWs)");
3884 }
3885
3886 /* RAD */
3887 proto_tree_add_item_ret_boolean(extension_tree, hf_oran_rad,
3888 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &rad);
3889 /* bundleOffset (6 bits) */
3890 proto_tree_add_item(extension_tree, hf_oran_bundle_offset, tvb,
3891 offset, 1, ENC_BIG_ENDIAN0x00000000);
3892 offset++;
3893
3894 /* numBundPrb (number of prbs in each bundle) */
3895 proto_item *num_bund_prb_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_num_bund_prbs,
3896 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &numBundPrb);
3897 offset++;
3898 /* value zero is reserved.. */
3899 if (numBundPrb == 0) {
3900 expert_add_info(pinfo, num_bund_prb_ti, &ei_oran_reserved_numBundPrb);
3901 }
3902
3903 uint32_t num_bundles;
3904 bool_Bool orphaned_prbs = false0;
3905
3906 /* N.B. glibly assuming that Mu=1 */
3907 uint32_t symbol_count = (frameId*20 + slotId) * 14 + startSymbolId;
3908
3909 if (!disableBFWs) {
3910 /********************************************/
3911 /* Table 7.7.1.1-1 */
3912 /********************************************/
3913
3914 uint32_t bfwcomphdr_iq_width, bfwcomphdr_comp_meth;
3915 proto_item *comp_meth_ti = NULL((void*)0);
3916
3917 /* bfwCompHdr (2 subheaders - bfwIqWidth and bfwCompMeth)*/
3918 offset = dissect_bfwCompHdr(tvb, extension_tree, offset,
3919 &bfwcomphdr_iq_width, &bfwcomphdr_comp_meth, &comp_meth_ti);
3920
3921 /* Work out number of bundles, but take care not to divide by zero. */
3922 if (numBundPrb == 0) {
3923 break;
3924 }
3925
3926 /* Work out bundles! */
3927 ext11_work_out_bundles(startPrbc, numPrbc, numBundPrb, &ext11_settings);
3928 num_bundles = ext11_settings.num_bundles;
3929
3930 /* Add (complete) bundles */
3931 for (unsigned b=0; b < num_bundles; b++) {
3932 offset = dissect_bfw_bundle(tvb, extension_tree, pinfo, offset,
3933 comp_meth_ti, bfwcomphdr_comp_meth,
3934 NULL((void*)0) /* no ModCompr */,
3935 (ext11_settings.ext21_set) ?
3936 numPrbc :
3937 pref_num_bf_antennas,
3938 bfwcomphdr_iq_width,
3939 b, /* bundle number */
3940 ext11_settings.bundles[b].start,
3941 ext11_settings.bundles[b].end,
3942 ext11_settings.bundles[b].is_orphan,
3943 symbol_count,
3944 (link_planes_together && dl_data_section) ? &dl_data_section->details[index_to_use] : NULL((void*)0),
3945 tap_info);
3946 if (!offset) {
3947 break;
3948 }
3949 }
3950 if (num_bundles > 0) {
3951 /* Set flag from last bundle entry */
3952 orphaned_prbs = ext11_settings.bundles[num_bundles-1].is_orphan;
3953 }
3954 }
3955 else {
3956 /********************************************/
3957 /* Table 7.7.1.1-2 */
3958 /* No weights in this case */
3959 /********************************************/
3960
3961 /* Work out number of bundles, but take care not to divide by zero. */
3962 if (numBundPrb == 0) {
3963 break;
3964 }
3965
3966 ext11_work_out_bundles(startPrbc, numPrbc, numBundPrb, &ext11_settings);
3967 num_bundles = ext11_settings.num_bundles;
3968
3969 for (unsigned n=0; n < num_bundles; n++) {
3970 /* contInd */
3971 proto_tree_add_item(extension_tree, hf_oran_cont_ind,
3972 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3973 /* beamId */
3974 /* N.B., only added to tap_info if not 0 or ignored (after SEs seen) */
3975 uint32_t beam_id;
3976 proto_item *beamid_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_beam_id,
3977 tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &beam_id);
3978 if (!ext11_settings.bundles[n].is_orphan) {
3979 proto_item_append_text(beamid_ti, " (PRBs %3u-%3u) (Bundle %2u)",
3980 ext11_settings.bundles[n].start,
3981 ext11_settings.bundles[n].end,
3982 n);
3983 }
3984 else {
3985 orphaned_prbs = true1;
3986 proto_item_append_text(beamid_ti, " (PRBs %3u-%3u) (Orphaned PRBs)",
3987 ext11_settings.bundles[n].start,
3988 ext11_settings.bundles[n].end);
3989 }
3990 offset += 2;
3991
3992 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
3993 if (dl_data_section) {
3994 /* Set beamId only for range of PRBs */
3995 for (unsigned prb = ext11_settings.bundles[n].start; prb <= ext11_settings.bundles[n].end; prb++) {
3996 if (prb < 273) {
3997 dl_data_section->details[index_to_use].beamIds[prb] = beam_id;
3998 }
3999 }
4000 }
4001 }
4002
4003 /* Look for where BFWs were sent for this beamId */
4004 bfw_definition *definition;
4005
4006 wmem_tree_key_t key[3];
4007 key[0].length = 1;
4008 key[0].key = &pinfo->num;
4009 key[1].length = 1;
4010 key[1].key = &beam_id;
4011 key[2].length = 0;
4012 key[2].key = NULL((void*)0);
4013
4014 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
4015 /* Look up current result */
4016 definition = wmem_tree_lookup32(dl_beam_ids_defined, beam_id);
4017 if (definition != NULL((void*)0)) {
4018 /* Add to results table for this frame */
4019 wmem_tree_insert32_array(dl_beam_ids_results, key, definition);
4020 }
4021 }
4022 else {
4023 /* Look up from result table */
4024 definition = wmem_tree_lookup32_array(dl_beam_ids_results, key);
4025 }
4026
4027 /* Show link back to frame where/when beamId was defined */
4028 if (definition && definition->frame_defined != 0 && definition->frame_defined != pinfo->num) {
4029 proto_item *defined_ti = proto_tree_add_uint(extension_tree, hf_oran_bfws_frame_defined, tvb, offset, 0, definition->frame_defined);
4030 proto_item_set_generated(defined_ti);
4031 proto_item *since_ti = proto_tree_add_uint(extension_tree, hf_oran_bfws_symbols_since_defined, tvb, offset, 0,
4032 symbol_count - definition->symbol_when_defined);
4033 proto_item_set_generated(since_ti);
4034 }
4035 else {
4036 expert_add_info_format(NULL((void*)0), beamid_ti, &ei_oran_beamid_bfws_not_found,
4037 "ext11 for beamId %u and disableBFWs set, but can't find definition", beam_id);
4038 }
4039 }
4040
4041 }
4042
4043 /* Add summary to extension root */
4044 if (orphaned_prbs) {
4045 proto_item_append_text(extension_ti, " (%u full bundles + orphaned)", num_bundles-1);
4046 }
4047 else {
4048 proto_item_append_text(extension_ti, " (%u bundles)", num_bundles);
4049 }
4050 }
4051
4052 break;
4053
4054 case 12: /* SE 12: Non-Contiguous PRB Allocation with Frequency Ranges */
4055 {
4056 /* numSymbol not used in this case */
4057 if (numsymbol_ti && !numsymbol_ignored) {
4058 proto_item_append_text(numsymbol_ti, " (ignored)");
4059 numsymbol_ignored = true1;
4060 }
4061
4062 ext11_settings.ext12_set = true1;
4063
4064 /* priority */
4065 proto_tree_add_item(extension_tree, hf_oran_noncontig_priority, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4066
4067 /* symbolMask */
4068 offset = dissect_symbolmask(tvb, extension_tree, offset, NULL((void*)0), NULL((void*)0));
4069
4070 /* There are now 'R' pairs of (offStartPrb, numPrb) values. Fill extlen bytes with values. If last one is not set,
4071 should be populated with 0s. */
4072 uint32_t extlen_remaining_bytes = (extlen*4) - 4;
4073 uint8_t prb_index;
4074
4075 /* This is for ST10/ST11. First pair starts after frames signalled there */
4076 uint16_t st10_st11_offset = startPrbc + numPrbc;
4077
4078 for (prb_index = 1; extlen_remaining_bytes > 0; prb_index++)
4079 {
4080 /* Create a subtree for each pair */
4081 proto_item *pair_ti = proto_tree_add_string(extension_tree, hf_oran_frequency_range,
4082 tvb, offset, 2, "");
4083 proto_tree *pair_tree = proto_item_add_subtree(pair_ti, ett_oran_frequency_range);
4084
4085 /* offStartPrb */
4086 uint32_t off_start_prb;
4087 proto_tree_add_item_ret_uint(pair_tree, hf_oran_off_start_prb, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &off_start_prb);
4088 offset++;
4089
4090 /* numPrb */
4091 uint32_t num_prb;
4092 proto_tree_add_item_ret_uint(pair_tree, hf_oran_num_prb, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &num_prb);
4093 offset++;
4094
4095 extlen_remaining_bytes -= 2;
4096
4097 /* Last pair may be 0,0 if not used. Check for this */
4098 if ((extlen_remaining_bytes == 0) && (off_start_prb == 0) && (num_prb == 0)) {
4099 proto_item_append_text(pair_ti, " (not used)");
4100 }
4101 /* Add summary to pair root item, and configure details in ext11_settings */
4102 else {
4103 proto_item_append_text(pair_ti, "(%u) [%u : %u]",
4104 prb_index, off_start_prb, num_prb);
4105 proto_item_append_text(extension_ti, "[%u : %u]",
4106 off_start_prb, num_prb);
4107 if (ext11_settings.ext12_num_pairs < MAX_BFW_EXT12_PAIRS128) {
4108 ext11_settings.ext12_pairs[ext11_settings.ext12_num_pairs].off_start_prb = off_start_prb;
4109 ext11_settings.ext12_pairs[ext11_settings.ext12_num_pairs++].num_prb = num_prb;
4110 }
4111
4112 /* Also update PRBs to be covered for ST10 type 5 */
4113 /* Original range from section is added to.. */
4114 /* TODO: I don't think this is quite right.. */
4115 for (unsigned prb=st10_st11_offset+off_start_prb; prb < st10_st11_offset+off_start_prb+num_prb; prb++) {
4116 if (prb < MAX_PRBS273) {
4117 prbs_for_st10_type5[prb] = true1;
4118 }
4119 }
4120
4121 /* Any next pair will begin after this one */
4122 st10_st11_offset += (off_start_prb + num_prb);
4123 }
4124 }
4125 break;
4126 }
4127
4128 case 13: /* SE 13: PRB Allocation with Frequency Hopping */
4129 {
4130 /* Will update settings for ext11 */
4131 ext11_settings.ext13_set = true1;
4132
4133 uint32_t extlen_remaining_bytes = (extlen*4) - 2;
4134 uint8_t allocation_index;
4135
4136 unsigned prev_next_symbol_id = 0, prev_next_start_prbc = 0;
4137
4138 for (allocation_index = 1; extlen_remaining_bytes > 0; allocation_index++)
4139 {
4140 /* Subtree for allocation */
4141 proto_item *allocation_ti = proto_tree_add_string(extension_tree, hf_oran_prb_allocation,
4142 tvb, offset, 2, "");
4143 proto_tree *allocation_tree = proto_item_add_subtree(allocation_ti, ett_oran_prb_allocation);
4144
4145 /* Reserved (2 bits) */
4146 add_reserved_field(allocation_tree, hf_oran_reserved_2bits, tvb, offset, 1);
4147
4148 /* nextSymbolId (4 bits) */
4149 uint32_t next_symbol_id;
4150 proto_tree_add_item_ret_uint(allocation_tree, hf_oran_nextSymbolId, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &next_symbol_id);
4151
4152 /* nextStartPrbc (10 bits) */
4153 uint32_t next_start_prbc;
4154 proto_tree_add_item_ret_uint(allocation_tree, hf_oran_nextStartPrbc, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &next_start_prbc);
4155 offset += 2;
4156
4157 /* Add summary to allocation root item */
4158 proto_item_append_text(allocation_ti, "(%u) nextSymbolId=%3u, nextStartPrbc=%u",
4159 allocation_index, next_symbol_id, next_start_prbc);
4160
4161 /* Checking for duplicates (expected if e.g. had only 2 entries but extlen bytes still to fill */
4162 if ((allocation_index > 1) && (next_symbol_id == prev_next_symbol_id) && (next_start_prbc == prev_next_start_prbc)) {
4163 proto_item_append_text(allocation_ti, " (repeated - to fill up extlen)");
4164 }
4165 else {
4166 /* Add entry for configuring ext11. don't store out of range */
4167 if (ext11_settings.ext13_num_start_prbs < MAX_BFW_EXT13_ALLOCATIONS128) {
4168 ext11_settings.ext13_start_prbs[ext11_settings.ext13_num_start_prbs++] = next_start_prbc;
4169 }
4170 }
4171 prev_next_symbol_id = next_symbol_id;
4172 prev_next_start_prbc = next_start_prbc;
4173
4174 extlen_remaining_bytes -= 2;
4175 }
4176 break;
4177 }
4178
4179 case 14: /* SE 14: Nulling-layer Info. for ueId-based beamforming */
4180 /* Hidden filter for bf (DMRS BF) */
4181 bf_ti = proto_tree_add_item(tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
4182 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
4183
4184 if (!seen_se10) {
4185 proto_tree_add_item(extension_tree, hf_oran_nullLayerInd, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4186 offset += 1;
4187 add_reserved_field(extension_tree, hf_oran_reserved_8bits, tvb, offset, 1);
4188 offset += 1;
4189 }
4190 else {
4191 /* Loop over numPortc++1 (from SE 10) nullLayerInd fields */
4192 for (unsigned port=0; port < numPortc+1; port++) {
4193 proto_tree_add_item(extension_tree, hf_oran_nullLayerInd, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4194 offset += 1;
4195 }
4196 }
4197 break;
4198
4199 case 15: /* SE 15: Mixed-numerology Info. for ueId-based beamforming */
4200 {
4201 /* frameStructure */
4202 offset = dissect_frame_structure(extension_tree, tvb, offset,
4203 subframeId, slotId);
4204 /* freqOffset */
4205 proto_tree_add_item(extension_tree, hf_oran_freqOffset, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
4206 offset += 3;
4207 /* cpLength */
4208 proto_item *cplength_ti = proto_tree_add_item(extension_tree, hf_oran_cpLength, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4209 if (sectionType != 0 && sectionType != 3) {
4210 proto_item_append_text(cplength_ti, " (ignored - used only with ST0 and ST3)");
4211 }
4212 offset += 2;
4213 break;
4214 }
4215
4216 case 16: /* SE 16: Antenna mapping in UE channel information based UL beamforming */
4217 {
4218 /* Just filling available bytes with antMask entries.
4219 N.B., if SE 10 also used, could associate each antMask with (beamId or UEId) RX eAxC */
4220 uint32_t extlen_remaining_bytes = (extlen*4) - 2;
4221 unsigned num_ant_masks = extlen_remaining_bytes / 8;
4222 for (unsigned n=0; n < num_ant_masks; n++) {
4223 proto_item *ti = proto_tree_add_item(extension_tree, hf_oran_antMask, tvb, offset, 8, ENC_BIG_ENDIAN0x00000000);
4224 proto_item_append_text(ti, " (RX eAxC #%u)", n+1);
4225 offset += 8;
4226 }
4227 break;
4228 }
4229
4230 case 17: /* SE 17: Indication of user port group. Applies to ST5 + SE10 with group type 1 (beam matrix indication) */
4231 {
4232 uint32_t extlen_remaining_bytes = (extlen*4) - 2;
4233 uint32_t end_bit = (offset+extlen_remaining_bytes) * 8;
4234 uint32_t ueid_index = 1;
4235
4236 /* "the preceding Section Type and extension messages implicitly provide the number of scheduled users" */
4237 for (uint32_t bit_offset=offset*8; (bit_offset < end_bit) && (ueid_index <= number_of_ueids); bit_offset+=4, ueid_index++) {
4238 /* numUeId (Number of UE Ids per user) */
4239 proto_item *ti = proto_tree_add_bits_item(extension_tree, hf_oran_num_ueid, tvb, bit_offset, 4, ENC_BIG_ENDIAN0x00000000);
4240 /* TODO: show ueids[ueid_index] here too? */
4241 proto_item_append_text(ti, " (user #%u)", ueid_index);
4242 }
4243 break;
4244 }
4245
4246 case 18: /* SE 18: Uplink transmission management */
4247 /* transmissionWindowOffset */
4248 proto_tree_add_item(extension_tree, hf_oran_transmissionWindowOffset, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4249 offset += 2;
4250 /* reserved (2 bits) */
4251 add_reserved_field(extension_tree, hf_oran_reserved_2bits, tvb, offset, 1);
4252 /* transmissionWindowSize (14 bits) */
4253 proto_tree_add_item(extension_tree, hf_oran_transmissionWindowSize, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4254 offset += 2;
4255
4256 /* reserved (6 bits) */
4257 add_reserved_field(extension_tree, hf_oran_reserved_6bits, tvb, offset, 1);
4258 /* toT (2 bits) */
4259 proto_tree_add_item(extension_tree, hf_oran_toT, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4260 offset += 1;
4261 break;
4262
4263 case 19: /* SE 19: Compact beamforming information for multiple port */
4264 {
4265 /* beamId in section header should be ignored. Guard against appending multiple times.. */
4266 if (section_beamId_ti && !section_beamId_ignored) {
4267 proto_item_append_text(section_beamId_ti, " (ignored)");
4268 section_beamId_ignored = true1;
4269 }
4270
4271 /* numSymbol not used in this case */
4272 if (numsymbol_ti && !numsymbol_ignored) {
4273 proto_item_append_text(numsymbol_ti, " (ignored)");
4274 numsymbol_ignored = true1;
4275 }
4276
4277 /* disableBFWs */
4278 bool_Bool disableBFWs;
4279 proto_tree_add_item_ret_boolean(extension_tree, hf_oran_disable_bfws,
4280 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &disableBFWs);
4281 if (disableBFWs) {
4282 proto_item_append_text(extension_ti, " (disableBFWs)");
4283 }
4284 /* repetition (1 bit) */
4285 uint64_t repetition;
4286 proto_tree_add_bits_ret_val(extension_tree, hf_oran_se19_repetition, tvb, (offset*8)+1, 1, &repetition, ENC_BIG_ENDIAN0x00000000);
4287 /* numPortc (6 bits) */
4288 proto_tree_add_item_ret_uint(extension_tree, hf_oran_numPortc,
4289 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &numPortc);
4290 offset++;
4291
4292 /* priority (2 bits) */
4293 proto_tree_add_item(extension_tree, hf_oran_noncontig_priority, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4294 /* symbolMask (14 bits) */
4295 offset = dissect_symbolmask(tvb, extension_tree, offset, NULL((void*)0), NULL((void*)0));
4296
4297 uint32_t bfwcomphdr_iq_width, bfwcomphdr_comp_meth;
4298 proto_item *comp_meth_ti = NULL((void*)0);
4299
4300 if (!repetition) {
4301
4302 if (!disableBFWs) {
4303 /* bfwCompHdr */
4304 offset = dissect_bfwCompHdr(tvb, extension_tree, offset,
4305 &bfwcomphdr_iq_width, &bfwcomphdr_comp_meth, &comp_meth_ti);
4306 }
4307
4308 /* Add entries for each port */
4309 for (unsigned port=0; port < numPortc; port++) {
4310
4311 /* Create subtree for port entry*/
4312 int port_start_offset = offset;
4313 proto_item *port_ti = proto_tree_add_string_format(extension_tree, hf_oran_ext19_port,
4314 tvb, offset, 0,
4315 "", "Port %u: ", port);
4316 proto_tree *port_tree = proto_item_add_subtree(port_ti, ett_oran_ext19_port);
4317
4318 /* Reserved (4 bits) */
4319 add_reserved_field(port_tree, hf_oran_reserved_4bits, tvb, offset, 1);
4320 /* portReMask (12 bits) */
4321 proto_tree_add_item(port_tree, hf_oran_portReMask, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4322 offset += 2;
4323
4324 /* Reserved (2 bits) */
4325 add_reserved_field(port_tree, hf_oran_reserved_2bits, tvb, offset, 1);
4326 /* portSymbolMask (14 bits) */
4327 proto_tree_add_item(port_tree, hf_oran_portSymbolMask, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4328 offset += 2;
4329
4330 /* Reserved (1 bit) */
4331 add_reserved_field(port_tree, hf_oran_reserved_1bit, tvb, offset, 1);
4332 /* beamID (15 bits) */
4333 uint16_t beamId;
4334 proto_tree_add_item_ret_uint16(port_tree, hf_oran_beamId, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &beamId);
4335 proto_item_append_text(port_ti, " (beamId=%u)", beamId);
4336 offset += 2;
4337
4338 /* No weights present */
4339 if (!disableBFWs) {
4340 /*******************************************************************/
4341 /* Table 7.7.19.1-1 (there is no part -2 for disableBFWs case...), */
4342 /* but for SE 11, bfwCompParam was only present for !disableBFWs */
4343 /*******************************************************************/
4344
4345 /* bfwCompParam */
4346 bool_Bool compression_method_supported = false0;
4347 uint32_t exponent = 0;
4348 unsigned num_trx_entries = 0;
4349 uint16_t *trx;
4350 offset = dissect_bfwCompParam(tvb, port_tree, pinfo, offset, comp_meth_ti,
4351 &bfwcomphdr_comp_meth, &exponent, &compression_method_supported,
4352 &num_trx_entries, &trx);
4353
4354 int bit_offset = offset*8;
4355 int bfw_offset;
4356
4357 /* Add weights for each TRX */
4358 unsigned trx_to_add = (num_trx_entries==0) ? pref_num_bf_antennas : num_trx_entries;
4359 for (unsigned b=0; b < trx_to_add; b++) {
4360
4361 uint16_t trx_index = (num_trx_entries) ? trx[b] : b+1;
4362
4363 /* Create BFW subtree */
4364 bfw_offset = bit_offset / 8;
4365 uint8_t bfw_extent = ((bit_offset + (bfwcomphdr_iq_width*2)) / 8) - bfw_offset;
4366 proto_item *bfw_ti = proto_tree_add_string_format(port_tree, hf_oran_bfw,
4367 tvb, bfw_offset, bfw_extent,
4368 "", "TRX %u: (", trx_index);
4369 proto_tree *bfw_tree = proto_item_add_subtree(bfw_ti, ett_oran_bfw);
4370
4371 /* I */
4372 uint32_t bits = tvb_get_bits32(tvb, bit_offset, bfwcomphdr_iq_width, ENC_BIG_ENDIAN0x00000000);
4373 float value = decompress_value(bits, bfwcomphdr_comp_meth, bfwcomphdr_iq_width, exponent, NULL((void*)0) /* no ModCompr */, 0 /* RE */);
4374 /* Add to tree. */
4375 proto_tree_add_float_format_value(bfw_tree, hf_oran_bfw_i, tvb, bit_offset/8,
4376 (bfwcomphdr_iq_width+7)/8, value, "#%u=%f", b, value);
4377 bit_offset += bfwcomphdr_iq_width;
4378 proto_item_append_text(bfw_ti, "I%u=%f ", b, value);
4379
4380 /* Q */
4381 bits = tvb_get_bits32(tvb, bit_offset, bfwcomphdr_iq_width, ENC_BIG_ENDIAN0x00000000);
4382 value = decompress_value(bits, bfwcomphdr_comp_meth, bfwcomphdr_iq_width, exponent, NULL((void*)0) /* no ModCompr */, 0 /* RE */);
4383 /* Add to tree. */
4384 proto_tree_add_float_format_value(bfw_tree, hf_oran_bfw_q, tvb, bit_offset/8,
4385 (bfwcomphdr_iq_width+7)/8, value, "#%u=%f", b, value);
4386 bit_offset += bfwcomphdr_iq_width;
4387 proto_item_append_text(bfw_ti, "Q%u=%f)", b, value);
4388 }
4389
4390 offset = (bit_offset+7)/8;
4391 }
4392 else {
4393 /* No weights... */
4394 }
4395
4396 /* Set length of this port entry */
4397 proto_item_set_len(port_ti, offset-port_start_offset);
4398 }
4399 }
4400 break;
4401 }
4402
4403 case 20: /* SE 20: Puncturing extension */
4404 {
4405 /* numPuncPatterns */
4406 uint32_t numPuncPatterns;
4407 proto_tree_add_item_ret_uint(extension_tree, hf_oran_numPuncPatterns, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &numPuncPatterns);
4408 offset += 1;
4409
4410 /* Add each puncturing pattern */
4411 for (uint32_t n=0; n < numPuncPatterns; n++) {
4412 unsigned pattern_start_offset = offset;
4413
4414 /* Subtree for this puncturing pattern */
4415 proto_item *pattern_ti = proto_tree_add_string_format(extension_tree, hf_oran_puncPattern,
4416 tvb, offset, 0,
4417 "", "Puncturing Pattern: %u/%u", n+1, numPuncPatterns);
4418 proto_tree *pattern_tree = proto_item_add_subtree(pattern_ti, ett_oran_punc_pattern);
4419
4420 /* SymbolMask (14 bits) */
4421 proto_tree_add_item(pattern_tree, hf_oran_symbolMask_ext20, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4422 offset += 1;
4423
4424 uint32_t startPuncPrb, numPuncPrb;
4425
4426 /* startPuncPrb (10 bits) */
4427 proto_tree_add_item_ret_uint(pattern_tree, hf_oran_startPuncPrb, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &startPuncPrb);
4428 offset += 2;
4429 /* numPuncPrb (8 bits) */
4430 proto_tree_add_item_ret_uint(pattern_tree, hf_oran_numPuncPrb, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &numPuncPrb);
4431 offset += 1;
4432
4433 proto_item_append_text(pattern_ti, " [%u->%u]", startPuncPrb, startPuncPrb+numPuncPrb-1);
4434
4435 /* Make a hole in range of PRBs to report */
4436 for (unsigned p=startPuncPrb; p < startPuncPrb+numPuncPrb; p++) {
4437 if (p < MAX_PRBS273) {
4438 prbs_for_st10_type5[p] = false0;
4439 }
4440 }
4441
4442 /* puncReMask (12 bits) */
4443 proto_tree_add_item(pattern_tree, hf_oran_puncReMask, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4444 offset += 1;
4445 /* rb (1 bit) */
4446 proto_item *rb_ti = proto_tree_add_item(pattern_tree, hf_oran_rb, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4447 /* reserved (1 bit) */
4448 add_reserved_field(pattern_tree, hf_oran_reserved_bit5, tvb, offset, 1);
4449 /* multiSDScope (1 bit) */
4450 proto_tree_add_item(pattern_tree, hf_oran_multiSDScope, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4451 /* rbgIncl (1 bit) */
4452 bool_Bool rbgIncl;
4453 proto_tree_add_item_ret_boolean(pattern_tree, hf_oran_RbgIncl, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &rbgIncl);
4454 offset += 1;
4455
4456 if (rbgIncl) {
4457 /* reserved (1 bit) */
4458 add_reserved_field(pattern_tree, hf_oran_reserved_1bit, tvb, offset, 1);
4459 /* rbgSize(3 bits) */
4460 proto_tree_add_item(pattern_tree, hf_oran_rbgSize, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4461 /* rbgMask (28 bits) */
4462 proto_tree_add_item(pattern_tree, hf_oran_rbgMask, tvb, offset, 4, ENC_BIG_ENDIAN0x00000000);
4463 offset += 4;
4464
4465 proto_item_append_text(rb_ti, " (ignored)");
4466 }
4467
4468 proto_item_set_len(pattern_ti, offset-pattern_start_offset);
4469 }
4470
4471 break;
4472 }
4473 case 21: /* SE 21: Variable PRB group size for channel information */
4474 {
4475 /* ciPrbGroupSize */
4476 uint32_t ci_prb_group_size;
4477 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);
4478 offset += 1;
4479
4480 switch (ci_prb_group_size) {
4481 case 0:
4482 case 1:
4483 case 255:
4484 /* Reserved value */
4485 expert_add_info_format(pinfo, prb_group_size_ti, &ei_oran_ci_prb_group_size_reserved,
4486 "SE 11 ciPrbGroupSize is reserved value %u - must be 2-254",
4487 ci_prb_group_size);
4488 break;
4489 default:
4490 /* This value affects how SE 11 is interpreted */
4491 ext11_settings.ext21_set = true1;
4492 ext11_settings.ext21_ci_prb_group_size = ci_prb_group_size;
4493
4494 if (numPrbc == 0) {
4495 expert_add_info(pinfo, numprbc_ti, &ei_oran_numprbc_ext21_zero);
4496 }
4497 break;
4498 }
4499
4500 /* reserved (6 bits) */
4501 add_reserved_field(extension_tree, hf_oran_reserved_6bits, tvb, offset, 1);
4502
4503 /* prgSize (2 bits). Interpretation depends upon section type (5 or 6), but also mplane parameters? */
4504 if (sectionType == SEC_C_UE_SCHED) { /* Section Type 5 */
4505 proto_tree_add_item(extension_tree, hf_oran_prg_size_st5, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4506 }
4507 else if (sectionType == SEC_C_CH_INFO) { /* Section Type 6 */
4508 proto_tree_add_item(extension_tree, hf_oran_prg_size_st6, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4509 }
4510 offset += 1;
4511 break;
4512 }
4513
4514 case 22: /* SE 22: ACK/NACK request */
4515 {
4516 uint32_t ack_nack_req_id;
4517 proto_tree_add_item_ret_uint(extension_tree, hf_oran_ack_nack_req_id, tvb, offset, 2,
4518 ENC_BIG_ENDIAN0x00000000, &ack_nack_req_id);
4519 offset += 2;
4520
4521 if (state) {
4522 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
4523 /* Add this request into conversation state on first pass */
4524 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)))
;
4525 request_details->request_frame_number = pinfo->num;
4526 request_details->request_frame_time = pinfo->abs_ts;
4527 request_details->requestType = SE22;
4528 /* Insert into flow's tree */
4529 wmem_tree_insert32(state->ack_nack_requests, ack_nack_req_id, request_details);
4530 }
4531 else {
4532 /* Try to link forward to ST8 response */
4533 ack_nack_request_t *response = wmem_tree_lookup32(state->ack_nack_requests,
4534 ack_nack_req_id);
4535 if (response) {
4536 show_link_to_acknack_response(extension_tree, tvb, pinfo, response);
4537 }
4538 }
4539 }
4540 break;
4541 }
4542
4543 case 23: /* SE 23: Arbitrary symbol pattern modulation compression parameters */
4544 {
4545 /* Green common header */
4546
4547 /* numSymPrbPattern (4 bits) */
4548 uint32_t num_sym_prb_pattern;
4549 proto_tree_add_item_ret_uint(extension_tree, hf_oran_num_sym_prb_pattern, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &num_sym_prb_pattern);
4550 /* reserved (3 bits) */
4551 add_reserved_field(extension_tree, hf_oran_reserved_bits456, tvb, offset, 1);
4552 /* prbMode (1 bit) */
4553 bool_Bool prb_mode;
4554 proto_tree_add_item_ret_boolean(extension_tree, hf_oran_prb_mode, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &prb_mode);
4555 offset += 1;
4556
4557 /* reserved (8 bits) */
4558 add_reserved_field(extension_tree, hf_oran_reserved_8bits, tvb, offset, 1);
4559 offset += 1;
4560
4561 /* Dissect each SymPrbPattern */
4562 for (uint32_t n=0; n < num_sym_prb_pattern; n++) {
4563
4564 /* Subtree */
4565 proto_item *pattern_ti = proto_tree_add_string_format(extension_tree, hf_oran_sym_prb_pattern,
4566 tvb, offset, 1, "",
4567 prb_mode ? "PRB-BLOCK" : "PRB-MASK");
4568 proto_tree *pattern_tree = proto_item_add_subtree(pattern_ti, ett_oran_sym_prb_pattern);
4569
4570
4571 /* Orange part */
4572
4573 /* Reserved (2 bits) */
4574 add_reserved_field(pattern_tree, hf_oran_reserved_2bits, tvb, offset, 1);
4575 /* symMask (14 bits) */
4576 proto_tree_add_item(pattern_tree, hf_oran_sym_mask, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4577 offset += 2;
4578 /* numMcScaleOffset (4 bits) */
4579 uint32_t numMcScaleOffset;
4580 proto_tree_add_item_ret_uint(pattern_tree, hf_oran_num_mc_scale_offset, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &numMcScaleOffset);
4581
4582 if (!prb_mode) { /* PRB-MASK */
4583 /* prbPattern (4 bits) */
4584 proto_tree_add_item(pattern_tree, hf_oran_prb_pattern, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4585 offset += 1;
4586 /* reserved (8 bits) */
4587 add_reserved_field(pattern_tree, hf_oran_reserved_8bits, tvb, offset, 1);
4588 offset += 1;
4589 }
4590 else { /* PRB-BLOCK */
4591 /* prbBlkOffset (8 bits) */
4592 proto_tree_add_item(pattern_tree, hf_oran_prb_block_offset, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4593 offset += 1;
4594 /* prbBlkSize (4 bits) */
4595 proto_tree_add_item(pattern_tree, hf_oran_prb_block_size, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4596 offset += 1;
4597 }
4598
4599 /* Yellowish part */
4600 if (prb_mode) { /* PRB-BLOCK */
4601 /* prbBlkSize (4 bits) */
4602 proto_tree_add_item(pattern_tree, hf_oran_prb_block_size, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4603 }
4604 else {
4605 /* reserved (4 bits) */
4606 add_reserved_field(pattern_tree, hf_oran_reserved_4bits, tvb, offset, 1);
4607 }
4608
4609 for (unsigned c=0; c < numMcScaleOffset; c++) {
4610
4611 if (c > 0) {
4612 /* reserved (4 bits) */
4613 add_reserved_field(pattern_tree, hf_oran_reserved_4bits, tvb, offset, 1);
4614 }
4615
4616 static int * const remask_flags_even[] = {
4617 &hf_oran_mc_scale_re_mask_re1_even,
4618 &hf_oran_mc_scale_re_mask_re2_even,
4619 &hf_oran_mc_scale_re_mask_re3_even,
4620 &hf_oran_mc_scale_re_mask_re4_even,
4621 &hf_oran_mc_scale_re_mask_re5_even,
4622 &hf_oran_mc_scale_re_mask_re6_even,
4623 &hf_oran_mc_scale_re_mask_re7_even,
4624 &hf_oran_mc_scale_re_mask_re8_even,
4625 &hf_oran_mc_scale_re_mask_re9_even,
4626 &hf_oran_mc_scale_re_mask_re10_even,
4627 &hf_oran_mc_scale_re_mask_re11_even,
4628 &hf_oran_mc_scale_re_mask_re12_even,
4629 NULL((void*)0)
4630 };
4631
4632 /* mcScaleReMask (12 bits). Defines which REs the following csf and mcScaleOffset apply to */
4633 uint64_t mcScaleReMask, mcScaleOffset;
4634 proto_tree_add_bitmask_ret_uint64(pattern_tree, tvb, offset,
4635 hf_oran_mc_scale_re_mask_even,
4636 ett_oran_mc_scale_remask,
4637 remask_flags_even, ENC_BIG_ENDIAN0x00000000, &mcScaleReMask);
4638
4639 offset += 2;
4640 /* csf (1 bit) */
4641 bool_Bool csf;
4642 dissect_csf(pattern_tree, tvb, offset*8, ci_iq_width, &csf);
4643 /* mcScaleOffset (15 bits) */
4644 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);
4645 uint16_t exponent = (mcScaleOffset >> 11) & 0x000f; /* m.s. 4 bits */
4646 uint16_t mantissa = mcScaleOffset & 0x07ff; /* l.s. 11 bits */
4647 float mcScaleOffset_value = ((float)mantissa/(1<<11)) * ((float)1.0 / (1 << exponent));
4648 proto_item_append_text(ti, " (%f)", mcScaleOffset_value);
4649
4650 offset += 2;
4651
4652 /* Record this config. */
4653 /* TODO: at some point, will also want to store/use PRB + symbol filters */
4654 section_mod_compr_config_t* sect_config = get_mod_compr_section_to_write(state, sectionId);
4655
4656 if (sect_config && sect_config->num_configs < MAX_MOD_COMPR_CONFIGS12) {
4657 unsigned i = sect_config->num_configs;
4658 sect_config->configs[i].mod_compr_re_mask = (uint16_t)mcScaleReMask;
4659 sect_config->configs[i].mod_compr_csf = csf;
4660 sect_config->configs[i].mod_compr_scaler = mcScaleOffset_value;
4661 sect_config->num_configs++;
4662 }
4663 }
4664
4665 proto_item_set_end(pattern_ti, tvb, offset);
4666 }
4667 break;
4668 }
4669
4670 case 24: /* SE 24: PUSCH DMRS configuration */
4671 {
4672 /* Hidden filter for bf (DMRS BF) */
4673 bf_ti = proto_tree_add_item(tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
4674 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
4675
4676 /* alpnPerSym (1 bit) */
4677 proto_tree_add_item(extension_tree, hf_oran_alpn_per_sym, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4678 /* antDmrsSnr (1 bit) */
4679 proto_tree_add_item(extension_tree, hf_oran_ant_dmrs_snr, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4680 /* reserved (1 bit) */
4681 add_reserved_field(extension_tree, hf_oran_reserved_bit2, tvb, offset, 1);
4682 /* userGroupSize (5 bits) */
4683 uint32_t user_group_size;
4684 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);
4685 if (user_group_size == 0) {
4686 proto_item_append_text(ugs_ti, " (not used)");
4687 }
4688 else if (user_group_size > 12) {
4689 proto_item_append_text(ugs_ti, " (reserved)");
4690 }
4691 offset += 1;
4692 /* userGroupId (8 bits)*/
4693 uint32_t user_group_id;
4694 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);
4695 if (user_group_id == 0) {
4696 /* TODO: Value 0 can happen in several cases, described in 7.7.24.7.. */
4697 }
4698 if (user_group_id == 255) {
4699 /* Value 255 is reserved */
4700 expert_add_info(pinfo, ugi_ti, &ei_oran_user_group_id_reserved_value);
4701 }
4702 offset += 1;
4703
4704 bool_Bool seen_value_to_inherit = false0;
4705 bool_Bool inherited_config_has_transform_precoding = false0;
4706 int dmrs_configs_seen = 0;
4707
4708 /* Dissect each entry until reach number of configured ueIds (or run out of extlen bytes..) */
4709 uint32_t ueid_index = 0;
4710 while ((offset < (extension_start_offset + extlen*4)) && (ueid_index < number_of_ueids)) {
4711 dmrs_configs_seen++;
4712
4713 /* Subtree */
4714 proto_item *entry_ti = proto_tree_add_string_format(extension_tree, hf_oran_dmrs_entry,
4715 tvb, offset, 0, "",
4716 "Entry");
4717 proto_tree *entry_tree = proto_item_add_subtree(entry_ti, ett_oran_dmrs_entry);
4718
4719 /* entryType (3 bits) */
4720 uint32_t entry_type;
4721 proto_item *entry_type_ti;
4722 entry_type_ti = proto_tree_add_item_ret_uint(entry_tree, hf_oran_entry_type, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &entry_type);
4723 if (entry_type > 3) {
4724 proto_item_append_text(entry_type_ti, " (reserved)");
4725 }
4726
4727 /* dmrsPortNumber (5 bits). Values 0-11 allowed */
4728 unsigned int dmrs_port_number;
4729 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);
4730 if (dmrs_port_number > 11) {
4731 proto_item_append_text(dpn_ti, " (12-31 are reserved)");
4732 }
4733 offset += 1;
4734
4735 /* What follows depends upon entryType */
4736 switch (entry_type) {
4737 case 0: /* dmrsPortNumber config same as previous, ueId ueIdReset=0 */
4738 case 1: /* dmrsPortNumber config same as previous, ueId ueIdReset=1 */
4739 /* No further fields for these */
4740 /* Error here if no previous values to inherit!! */
4741 if (!seen_value_to_inherit) {
4742 expert_add_info_format(pinfo, entry_type_ti, &ei_oran_se24_nothing_to_inherit,
4743 "SE24: have seen entry type %u, but no previous config (type 2 or 3) to inherit config from", entry_type);
4744
4745 }
4746 /* TODO: would be useful to repeat whole inherited config here? */
4747 break;
4748
4749 case 2: /* transform precoding disabled */
4750 case 3: /* transform precoding enabled */
4751 {
4752 /* Type 2/3 are very similar.. */
4753
4754 /* ueIdReset (1 bit) */
4755 proto_tree_add_item(entry_tree, hf_oran_ueid_reset, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4756 /* posMeas (1 bit) */
4757 proto_tree_add_item(entry_tree, hf_oran_pos_meas, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4758
4759 /* dmrsSymbolMask (14 bits) */
4760 static int * const dmrs_symbol_mask_flags[] = {
4761 &hf_oran_dmrs_symbol_mask_s13,
4762 &hf_oran_dmrs_symbol_mask_s12,
4763 &hf_oran_dmrs_symbol_mask_s11,
4764 &hf_oran_dmrs_symbol_mask_s10,
4765 &hf_oran_dmrs_symbol_mask_s9,
4766 &hf_oran_dmrs_symbol_mask_s8,
4767 &hf_oran_dmrs_symbol_mask_s7,
4768 &hf_oran_dmrs_symbol_mask_s6,
4769 &hf_oran_dmrs_symbol_mask_s5,
4770 &hf_oran_dmrs_symbol_mask_s4,
4771 &hf_oran_dmrs_symbol_mask_s3,
4772 &hf_oran_dmrs_symbol_mask_s2,
4773 &hf_oran_dmrs_symbol_mask_s1,
4774 &hf_oran_dmrs_symbol_mask_s0,
4775 NULL((void*)0)
4776 };
4777 proto_tree_add_bitmask(entry_tree, tvb, offset,
4778 hf_oran_dmrs_symbol_mask, ett_oran_dmrs_symbol_mask, dmrs_symbol_mask_flags, ENC_BIG_ENDIAN0x00000000);
4779 offset += 2;
4780
4781 /* scrambling */
4782 proto_tree_add_item(entry_tree, hf_oran_scrambling, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4783 offset += 2;
4784
4785 /* nscid (1 bit) */
4786 proto_tree_add_item(entry_tree, hf_oran_nscid, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4787
4788 /* These 5 bits differ depending upon entry type */
4789 if (entry_type == 2) { /* type 2 */
4790 /* dType (1 bit) */
4791 proto_tree_add_item(entry_tree, hf_oran_dtype, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4792 /* cdmWithoutData (2 bits) */
4793 proto_tree_add_item(entry_tree, hf_oran_cmd_without_data, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4794 /* lambda (2 bits) */
4795 proto_tree_add_item(entry_tree, hf_oran_lambda, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4796 }
4797 else { /* type 3 */
4798 /* reserved (1 bit) */
4799 add_reserved_field(entry_tree, hf_oran_reserved_bit1, tvb, offset, 1);
4800 /* lowPaprType (2 bits) */
4801 proto_tree_add_item(entry_tree, hf_oran_low_papr_type, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4802 /* hoppingMode (2 bits) */
4803 proto_tree_add_item(entry_tree, hf_oran_hopping_mode, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4804 }
4805
4806 /* firstPrb (9 bits) */
4807 proto_tree_add_item(entry_tree, hf_oran_first_prb, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4808 offset += 1;
4809 /* lastPrb (9 bits) */
4810 proto_tree_add_item(entry_tree, hf_oran_last_prb, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4811 offset += 2;
4812 /* Reserved (16 bits) */
4813 add_reserved_field(entry_tree, hf_oran_reserved_16bits, tvb, offset, 2);
4814 offset += 2;
4815
4816 /* Could now see entry types 0 or 1 - they have these values to inherit */
4817 seen_value_to_inherit = true1;
4818 inherited_config_has_transform_precoding = (entry_type == 3);
4819 break;
4820 }
4821
4822 default:
4823 /* reserved - expert info */
4824 break;
4825 }
4826
4827 proto_item_append_text(entry_ti, " [UEId=%u] (dmrsPortNumber=%2u) (type %u - %s) ",
4828 ueids[ueid_index++], dmrs_port_number, entry_type, val_to_str_const(entry_type, entry_type_vals, "Unknown"));
4829 proto_item_set_end(entry_ti, tvb, offset);
4830
4831 if (entry_type <= 1) {
4832 proto_item_append_text(entry_ti, " [transform-precoding %s]",
4833 inherited_config_has_transform_precoding ? "enabled" : "disabled");
4834 }
4835 }
4836
4837 proto_item_append_text(extension_ti, " (%d DMRS configs seen)", dmrs_configs_seen);
4838 break;
4839 }
4840
4841 case 25: /* SE 25: Symbol reordering for DMRS-BF */
4842 /* Just dissect each available block of 7 bytes as the 14 symbols for a layer,
4843 where each layer could be one or apply to all layers. */
4844 {
4845 /* TODO: should only appear in one section of a message - check? */
4846 unsigned layer = 0;
4847 proto_item *layer_ti;
4848 while (offset+7 <= (extension_start_offset + extlen*4)) {
4849 /* Layer subtree */
4850 layer_ti = proto_tree_add_string_format(extension_tree, hf_oran_symbol_reordering_layer,
4851 tvb, offset, 7, "",
4852 "Layer");
4853 proto_tree *layer_tree = proto_item_add_subtree(layer_ti, ett_oran_symbol_reordering_layer);
4854
4855 /* All 14 symbols for a layer (or all layers) */
4856 for (unsigned s=0; s < 14; s++) {
4857 proto_item *sym_ti;
4858 /* txWinForOnAirSymbol */
4859 unsigned int tx_win_for_on_air_symbol;
4860 sym_ti = proto_tree_add_item_ret_uint(layer_tree,
4861 (s % 2) ? hf_oran_tx_win_for_on_air_symbol_r : hf_oran_tx_win_for_on_air_symbol_l,
4862 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &tx_win_for_on_air_symbol);
4863 if (tx_win_for_on_air_symbol == 0x0F) {
4864 /* Ordering not affected */
4865 proto_item_append_text(sym_ti, " (sym %u - no info)", s);
4866 }
4867 else {
4868 proto_item_append_text(sym_ti, " (sym %u)", s);
4869 }
4870 if (s % 2) {
4871 offset += 1;
4872 }
4873 }
4874
4875 proto_item_append_text(layer_ti, " (layer %u)", ++layer);
4876 proto_item_append_text(extension_ti, " (layer %u)", layer);
4877 }
4878 /* Set layer subtree label */
4879 if (layer == 1) {
4880 proto_item_append_text(layer_ti, " (all)");
4881 proto_item_append_text(extension_ti, " (all)");
4882 }
4883 if (layer == 0) {
4884 /* TODO: are no layers valid? What does it mean? */
4885 proto_item_append_text(extension_ti, " (none)");
4886 }
4887 break;
4888 }
4889
4890 case 26: /* SE 26: Frequency offset feedback */
4891 /* Reserved (8 bits) */
4892 add_reserved_field(extension_tree, hf_oran_reserved_8bits, tvb, offset, 1);
4893 offset += 1;
4894 /* Reserved (1 bit) */
4895 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
4896 /* numFoFb (7 bits) */
4897 unsigned num_fo_fb;
4898 proto_tree_add_item_ret_uint(extension_tree, hf_oran_num_fo_fb, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &num_fo_fb);
4899 offset += 1;
4900
4901 /* Add each freqOffsetFb value */
4902 for (unsigned n=0; n < num_fo_fb; n++) {
4903 unsigned freq_offset_fb;
4904 /* freqOffsetFb (16 bits) */
4905 proto_item *offset_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_freq_offset_fb,
4906 tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &freq_offset_fb);
4907 /* Show if maps onto a -ve number */
4908 if ((freq_offset_fb >= 0x8ad0) && (freq_offset_fb <= 0xffff)) {
4909 proto_item_append_text(offset_ti, "(value %d)", -1 - (0xffff-freq_offset_fb));
4910 }
4911 proto_item_append_text(offset_ti, " [#%u]", n+1);
4912 offset += 2;
4913 }
4914 break;
4915
4916 case 27: /* SE 27: O-DU controlled dimensionality reduction */
4917 {
4918 /* Hidden filter for bf (DMRS BF) */
4919 bf_ti = proto_tree_add_item(tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
4920 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
4921
4922 /* beamType (2 bits) */
4923 unsigned beam_type;
4924 proto_tree_add_item_ret_uint(extension_tree, hf_oran_beam_type, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &beam_type);
4925 /* reserved (6 bits) */
4926 add_reserved_field(extension_tree, hf_oran_reserved_last_6bits, tvb, offset, 1);
4927 offset += 1;
4928
4929 /* numElements */
4930 unsigned num_elements;
4931 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);
4932 if (num_elements == 0) {
4933 num_elements = 256;
4934 proto_item_append_text(num_elements_ti, " (256");
4935 }
4936
4937 offset += 1;
4938
4939 /* beamId value(s) */
4940 switch (beam_type) {
4941 case 0:
4942 for (unsigned n=0; n < num_elements; n++) {
4943 /* reserved (1 bit) + beamId */
4944 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
4945 proto_tree_add_item(c_section_tree, hf_oran_beamId, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4946 offset += 2;
4947 }
4948 break;
4949 case 1:
4950 /* reserved (1 bit) + beamId */
4951 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
4952 proto_tree_add_item(c_section_tree, hf_oran_beamId, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4953 offset += 2;
4954 break;
4955 default:
4956 /* Unknown type... */
4957 break;
4958 }
4959 break;
4960 }
4961
4962 case 28: /* SE 28: O-DU controlled frequency resolution for SINR reporting */
4963 {
4964 /* reserved (3 bits) */
4965 add_reserved_field(extension_tree, hf_oran_reserved_3bits, tvb, offset, 1);
4966 /* numUeSinrRpt (5 bits) */
4967 uint32_t num_ue_sinr_rpt;
4968 proto_tree_add_item_ret_uint(extension_tree, hf_oran_num_ue_sinr_rpt, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &num_ue_sinr_rpt);
4969 offset += 1;
4970
4971 for (uint32_t n=0; n < num_ue_sinr_rpt; n++) {
4972 /* reserved (1 bit) */
4973 add_reserved_field(extension_tree, (n % 2) ? hf_oran_reserved_bit4 : hf_oran_reserved_1bit,
4974 tvb, offset, 1);
4975
4976 /* numSinrPerPrb (3 bits). Taken from alternate nibbles within byte. */
4977 proto_tree_add_item(extension_tree, (n % 2) ? hf_oran_num_sinr_per_prb_right : hf_oran_num_sinr_per_prb,
4978 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4979 if (n % 2) {
4980 offset += 1;
4981 }
4982 }
4983
4984 /* May need to skip beyond half-used byte */
4985 if (num_ue_sinr_rpt % 2) {
4986 offset += 1;
4987 }
4988 break;
4989 }
4990
4991 case 29: /* SE 29: Cyclic delay adjustment */
4992 /* reserved (4 bits) */
4993 add_reserved_field(extension_tree, hf_oran_reserved_4bits, tvb, offset, 1);
4994 /* cdScgSize (4 bits) */
4995 proto_tree_add_item(extension_tree, hf_oran_cd_scg_size, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4996 offset += 1;
4997
4998 /* cdScgPhaseStep */
4999 proto_tree_add_item(extension_tree, hf_oran_cd_scg_phase_step, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5000 offset += 1;
5001 break;
5002
5003 case 30: /* SE 30: PUSCH repetition indication */
5004 {
5005 /* Only valid for UL */
5006 if (!tap_info->uplink) {
5007 expert_add_info(pinfo, extension_ti, &ei_oran_se30_not_ul);
5008 }
5009
5010 /* ueids[], number_of_ueids may have been rewritten by SE10 */
5011
5012 /* reserved (4 bits) */
5013 add_reserved_field(extension_tree, hf_oran_reserved_4bits, tvb, offset, 1);
5014 /* numRepUe (4 bits) */
5015 uint8_t num_rep_ue;
5016 proto_tree_add_item_ret_uint8(extension_tree, hf_oran_num_rep_ue, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &num_rep_ue);
5017 offset ++;
5018 /* reserved (8 bits) */
5019 add_reserved_field(extension_tree, hf_oran_reserved_8bits, tvb, offset, 1);
5020 offset += 1;
5021
5022 if (num_rep_ue == 1) {
5023 /* SE10 *not* present. N.B. this should tally with number_of_ueids being set to only 1? */
5024 /* reserved (1 bit) */
5025 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
5026 /* isLastRep (1 bit). Value meaningless here? */
5027 proto_tree_add_item(extension_tree, hf_oran_is_last_rep, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5028 /* repIndex (6 bits) */
5029 proto_tree_add_item(extension_tree, hf_oran_rep_index, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5030 offset += 1;
5031
5032 /* reserved (2 bits) */
5033 add_reserved_field(extension_tree, hf_oran_reserved_2bits, tvb, offset, 1);
5034 /* numReps (6 bits) */
5035 uint8_t num_reps;
5036 proto_tree_add_item_ret_uint8(extension_tree, hf_oran_num_reps, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &num_reps);
5037 /* TODO: should numReps be 0 here? */
5038 offset += 1;
5039
5040 /* reserved (2 bits) */
5041 add_reserved_field(extension_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5042 offset += 2;
5043
5044 }
5045 else {
5046 /* SE10 present */
5047 bool_Bool is_last_rep = false0;
5048 /* TODO: should is_last_rep (also) cause loop exit? */
5049 for (uint8_t ue_idx=0; (ue_idx < num_rep_ue) && !is_last_rep; ue_idx++) {
5050 /* reserved (1 bit) */
5051 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
5052 /* isLastRep (1 bit) */
5053 proto_tree_add_item_ret_boolean(extension_tree, hf_oran_is_last_rep, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &is_last_rep);
5054 /* repIndex (6 bits) */
5055 proto_tree_add_item(extension_tree, hf_oran_rep_index, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5056 offset += 1;
5057
5058 /* reserved (2 bits) */
5059 add_reserved_field(extension_tree, hf_oran_reserved_2bits, tvb, offset, 1);
5060 /* numReps (6 bits) */
5061 uint8_t num_reps;
5062 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);
5063 /* TODO: values 33-63 are reserved */
5064 if (num_reps > 32) {
5065 proto_item_append_text(num_reps_ti, " (reserved)");
5066 }
5067 offset += 1;
5068
5069 for (uint8_t rep=0; rep < num_reps; rep++) {
5070 /* reserved (1 bit) */
5071 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
5072 /* repUeId (15 bits) */
5073 /* TODO: should be fetching and comparing with ueids[] from SE10? */
5074 uint16_t ueid;
5075 proto_item *ueid_ti = proto_tree_add_item_ret_uint16(extension_tree, hf_oran_rep_ueid, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &ueid);
5076
5077 /* Check that this ueid is recognised (among ueids[], number_of_ueids) */
5078 bool_Bool matched = false0;
5079 for (unsigned u=0; u < number_of_ueids; u++) {
5080 if (ueid == ueids[u])
5081 matched = true1;
5082 }
5083 if (!matched) {
5084 expert_add_info_format(pinfo, ueid_ti, &ei_oran_se30_unknown_ueid,
5085 "SE 30 mentions UEId %u - not seen in SE10", ueid);
5086 }
5087 offset += 2;
5088 }
5089 }
5090 }
5091 break;
5092 }
5093
5094
5095 default:
5096 /* Other/unexpected extension types */
5097 expert_add_info_format(pinfo, exttype_ti, &ei_oran_unhandled_se,
5098 "SE %u (%s) not supported by dissector",
5099 exttype, val_to_str_ext_const(exttype, &exttype_vals_ext, "Reserved"));
5100 ext_unhandled = true1;
5101 break;
5102 }
5103
5104 /* Check offset compared with extlen. There should be 0-3 bytes of padding */
5105 int num_padding_bytes = (extension_start_offset + (extlen*4) - offset);
5106 if (!ext_unhandled && ((num_padding_bytes<0) || (num_padding_bytes>3))) {
5107 expert_add_info_format(pinfo, extlen_ti, &ei_oran_extlen_wrong,
5108 "extlen signalled %u bytes (+ 0-3 bytes padding), but %u were dissected",
5109 extlen*4, offset-extension_start_offset);
5110 }
5111
5112 /* Move offset to beyond signalled length of extension */
5113 offset = extension_start_offset + (extlen*4);
5114
5115 /* Set length of extension header. */
5116 proto_item_set_len(extension_ti, extlen*4);
5117 }
5118 /* End of section extension handling */
5119
5120 /* Tap section beamId if not overwritten by SEs */
5121 if (!section_beamId_ignored && section_beamId != 0) {
5122 add_beam_id_to_tap(tap_info, section_beamId);
5123 }
5124
5125
5126 /* RRM measurement reports have measurement reports *after* extensions */
5127 if (sectionType == SEC_C_RRM_MEAS_REPORTS) /* Section Type 10 */
5128 {
5129 /* Hidden filter for bf (DMFS-BF). No BF weights though.. */
5130 bf_ti = proto_tree_add_item(c_section_tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
5131 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
5132
5133 bool_Bool mf;
5134 do {
5135 /* Measurement report subtree */
5136 proto_item *mr_ti = proto_tree_add_string_format(c_section_tree, hf_oran_measurement_report,
5137 tvb, offset, 1, "", "Measurement Report");
5138 proto_tree *mr_tree = proto_item_add_subtree(mr_ti, ett_oran_measurement_report);
5139 unsigned report_start_offset = offset;
5140
5141 /* measurement flag (i.e., more reports after this one) (1 bit) */
5142 proto_tree_add_item_ret_boolean(mr_tree, hf_oran_mf, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &mf);
5143
5144 /* measTypeId (7 bits) */
5145 uint32_t meas_type_id;
5146 proto_item *meas_type_id_ti;
5147 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);
5148 offset += 1;
5149
5150 /* Common to all measurement types */
5151 unsigned num_elements = 0;
5152 if (meas_type_id == 6) {
5153 /* numElements */
5154 proto_tree_add_item_ret_uint(mr_tree, hf_oran_num_elements, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &num_elements);
5155 }
5156 else {
5157 /* All other meas ids have a reserved byte */
5158 add_reserved_field(mr_tree, hf_oran_reserved_8bits, tvb, offset, 1);
5159 }
5160 offset += 1;
5161
5162 /* measDataSize (16 bits). N.B. begins at mf field, i.e. 2 bytes before this one */
5163 unsigned meas_data_size;
5164 proto_item *meas_data_size_ti;
5165 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);
5166 meas_data_size *= 4;
5167 proto_item_append_text(meas_data_size_ti, " (%u bytes)", meas_data_size);
5168 offset += 2;
5169
5170 /* Summary for measurement report root */
5171 proto_item_append_text(mr_ti, " (measTypeId=%u - %s)",
5172 meas_type_id, val_to_str_const(meas_type_id, meas_type_id_vals, "unknown"));
5173 /* And section header */
5174 proto_item_append_text(tree, " (%s)", val_to_str_const(meas_type_id, meas_type_id_vals, "unknown"));
5175 /* And Info column */
5176 col_append_fstr(pinfo->cinfo, COL_INFO, " (%s)", val_to_str_const(meas_type_id, meas_type_id_vals, "unknown"));
5177
5178 /* Handle specific message type fields */
5179 switch (meas_type_id) {
5180 case 1:
5181 {
5182 /* ueTae */
5183 unsigned ue_tae;
5184 proto_item *ue_tae_ti;
5185 ue_tae_ti = proto_tree_add_item_ret_uint(mr_tree, hf_oran_ue_tae, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &ue_tae);
5186 /* Show if maps onto a -ve number */
5187 if ((ue_tae >= 0x8ad0) && (ue_tae <= 0xffff)) {
5188 proto_item_append_text(ue_tae_ti, "(value %d)", -1 - (0xffff-ue_tae));
5189 }
5190 offset += 2;
5191
5192 /* Reserved (16 bits) */
5193 add_reserved_field(mr_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5194 offset += 2;
5195 break;
5196 }
5197 case 2:
5198 /* ueLayerPower entries (how many? for now just use up meas_data_size..) */
5199 /* TODO: add number of distinct dmrsPortNumber entries seen in SE24 and save in state? */
5200 /* Or would it make sense to use the preference 'pref_num_bf_antennas' ? */
5201 for (unsigned n=0; n < (meas_data_size-4)/2; n++) {
5202 unsigned ue_layer_power;
5203 proto_item *ue_layer_power_ti;
5204 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);
5205 /* Show if maps onto a -ve number */
5206 if ((ue_layer_power >= 0x8ad0) && (ue_layer_power <= 0xffff)) {
5207 proto_item_append_text(ue_layer_power_ti, "(value %d)", -1 - (0xffff-ue_layer_power));
5208 }
5209 offset += 2;
5210 }
5211 /* padding out to 4 bytes */
5212 break;
5213 case 3:
5214 {
5215 /* ueFreqOffset */
5216 unsigned ue_freq_offset;
5217 proto_item *ue_freq_offset_ti;
5218 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);
5219 /* Show if maps onto a -ve number */
5220 if ((ue_freq_offset >= 0x8ad0) && (ue_freq_offset <= 0xffff)) {
5221 proto_item_append_text(ue_freq_offset_ti, "(value %d)", -1 - (0xffff-ue_freq_offset));
5222 }
5223 offset += 2;
5224
5225 /* Reserved (16 bits) */
5226 add_reserved_field(mr_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5227 offset += 2;
5228 break;
5229 }
5230 case 4:
5231 case 5:
5232 /* reserved (2 bits) */
5233 add_reserved_field(mr_tree, hf_oran_reserved_2bits, tvb, offset, 1);
5234 /* symbolMask (14 bits) */
5235 offset = dissect_symbolmask(tvb, mr_tree, offset, NULL((void*)0), NULL((void*)0));
5236
5237 /* 2 bytes for each PRB ipnPower */
5238 for (unsigned prb=0; prb<MAX_PRBS273; prb++) {
5239 /* Skip if should not be reported */
5240 if (!prbs_for_st10_type5[prb]) {
5241 continue;
5242 }
5243 unsigned ipn_power;
5244 proto_item *ipn_power_ti;
5245 /* ipnPower (2 bytes) */
5246 ipn_power_ti = proto_tree_add_item_ret_uint(mr_tree, hf_oran_ipn_power, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &ipn_power);
5247 proto_item_append_text(ipn_power_ti, " (PRB %3d)", prb);
5248 /* Show if maps onto a -ve number */
5249 if ((ipn_power >= 0x8ad0) && (ipn_power <= 0xffff)) {
5250 proto_item_append_text(ipn_power_ti, " (value %d)", -1 - (0xffff-ipn_power));
5251 }
5252 offset += 2;
5253 }
5254 /* padding out to 4 bytes */
5255 break;
5256 case 6:
5257 /* antDmrsSnrVal entries */
5258 for (unsigned n=0; n < num_elements; n++) {
5259 unsigned snr_value;
5260 proto_item *snr_value_ti;
5261 /* antDmrsSnrVal (2 bytes) */
5262 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);
5263 proto_item_append_text(snr_value_ti, " (elem %2u)", n+1);
5264 /* Show if maps onto a -ve number */
5265 if ((snr_value >= 0x8ad0) && (snr_value <= 0xffff)) {
5266 proto_item_append_text(snr_value_ti, " (value %d)", -1 - (0xffff-snr_value));
5267 }
5268 offset += 2;
5269 }
5270 break;
5271 case 7:
5272 {
5273 /* UE positioning measurement report */
5274 float start_value;
5275
5276 /* ueAzAoa (16 bits) */
5277 uint32_t ue_az_aoa;
5278 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);
5279 if (ue_az_aoa <= 0xE0F) {
5280 if (ue_az_aoa >= 0x0708) {
5281 start_value = (ue_az_aoa-0x0708) * (float)0.1;
5282 proto_item_append_text(ue_az_aoa_ti, " (%.1f <= val < %.1f degrees)", start_value, start_value + (float)0.1);
5283 }
5284 else {
5285 start_value = 180 + (ue_az_aoa * (float)0.1);
5286 proto_item_append_text(ue_az_aoa_ti, " (%.1f <= val < %.1f degrees)", start_value, start_value + (float)0.1);
5287 }
5288 }
5289 else if (ue_az_aoa == 0xffff) {
5290 proto_item_append_text(ue_az_aoa_ti, " (invalid measurement result)");
5291 }
5292 else {
5293 proto_item_append_text(ue_az_aoa_ti, " (reserved)");
5294 }
5295 offset += 2;
5296
5297 /* Reserved (16 bits) */
5298 add_reserved_field(mr_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5299 offset += 2;
5300
5301 /* ueZeAoa (16 bits) */
5302 uint32_t ue_ze_aoa;
5303 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);
5304 if (ue_ze_aoa <= 0x707) {
5305 start_value = ue_ze_aoa * (float)0.1;
5306 proto_item_append_text(ue_ze_aoa_ti, " (%.1f <= val < %.1f degrees)", start_value, start_value + (float)0.1);
5307 }
5308 else if (ue_az_aoa == 0xffff) {
5309 proto_item_append_text(ue_ze_aoa_ti, " (invalid measurement result)");
5310 }
5311 else {
5312 proto_item_append_text(ue_ze_aoa_ti, " (reserved)");
5313 }
5314 offset += 2;
5315
5316 /* Reserved (16 bits) */
5317 add_reserved_field(mr_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5318 offset += 2;
5319
5320 /* uePosToaOffset (16 bits) */
5321 uint32_t ue_pos_toa_offset;
5322 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);
5323 if (ue_pos_toa_offset == 0) {
5324 proto_item_append_text(ue_pos_toa_offset_ti, " (no UE ToA offset, 0 symbols)");
5325 }
5326 else if (ue_pos_toa_offset <= 0x7fff) {
5327 proto_item_append_text(ue_pos_toa_offset_ti, " (+ve UE ToA offset)");
5328 }
5329 else if (ue_pos_toa_offset == 0x8000) {
5330 proto_item_append_text(ue_pos_toa_offset_ti, " (invalid measurement result)");
5331 }
5332 else {
5333 proto_item_append_text(ue_pos_toa_offset_ti, " (-ve UE ToA offset)");
5334 }
5335 offset += 2;
5336
5337 /* Reserved (16 bits) */
5338 add_reserved_field(mr_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5339 offset += 2;
5340 break;
5341 }
5342 case 8:
5343 {
5344 /* UE radial speed measurement report */
5345
5346 /* ueRadialSpeed (16 bits) */
5347 uint32_t radial_speed;
5348 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);
5349 if (radial_speed <= 10000) {
5350 proto_item_append_text(radial_speed_ti, " (%.1f km/h)", radial_speed * (float)0.1);
5351 }
5352 else if (radial_speed == 0x8000) {
5353 proto_item_append_text(radial_speed_ti, " (invalid measurement result)");
5354 }
5355 else {
5356 proto_item_append_text(radial_speed_ti, " (reserved value)");
5357 }
5358 offset += 2;
5359
5360 /* Reserved (16 bits) */
5361 add_reserved_field(mr_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5362 offset += 2;
5363 break;
5364 }
5365
5366 default:
5367 /* Anything else is not expected */
5368 expert_add_info_format(pinfo, meas_type_id_ti, &ei_oran_unexpected_measTypeId,
5369 "measTypeId %u (%s) not supported - only 1-6 are expected",
5370 meas_type_id,
5371 val_to_str_const(meas_type_id, meas_type_id_vals, "reserved"));
5372 break;
5373
5374 }
5375
5376 /* Pad out to next 4 bytes */
5377 offset += WS_PADDING_TO_4(offset-report_start_offset)((4U - ((offset-report_start_offset) % 4U)) % 4U);
5378
5379 /* TODO: verify dissected size of report vs meas_data_size? */
5380
5381 /* End of measurement report tree */
5382 proto_item_set_end(mr_ti, tvb, offset);
5383 } while (mf);
5384 }
5385
5386 /* Request for RRM Measurements has measurement commands after extensions */
5387 else if (sectionType == SEC_C_REQUEST_RRM_MEAS) /* Section Type 11 */
5388 {
5389 bool_Bool mf = true1;
5390 do {
5391 /* Measurement command subtree */
5392 proto_item *mc_ti = proto_tree_add_string_format(c_section_tree, hf_oran_measurement_command,
5393 tvb, offset, 8, "", "Measurement Command");
5394 proto_tree *mc_tree = proto_item_add_subtree(mc_ti, ett_oran_measurement_command);
5395
5396 /* mf (1 bit). 1st measurement command is always preset */
5397 proto_tree_add_item_ret_boolean(mc_tree, hf_oran_mf, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &mf);
5398
5399 /* measTypeId (7 bits) */
5400 uint32_t meas_type_id;
5401 proto_item *meas_type_id_ti;
5402 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);
5403 offset += 1;
5404
5405 proto_item *meas_command_ti;
5406 uint32_t meas_command_size;
5407
5408 switch (meas_type_id) {
5409 case 5: /* command for IpN for unallocated PRBs */
5410 /* reserved (1 byte) */
5411 add_reserved_field(mc_tree, hf_oran_reserved_8bits, tvb, offset, 1);
5412 offset += 1;
5413 /* measCmdSize. Presumably number of words so in future could skip unrecognised command types.. */
5414 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);
5415 proto_item_append_text(meas_command_ti, " (%u bytes)", meas_command_size*4);
5416 offset += 2;
5417 /* reserved (2 bits) */
5418 add_reserved_field(mc_tree, hf_oran_reserved_2bits, tvb, offset, 1);
5419 /* symbolMask (14 bits) */
5420 offset = dissect_symbolmask(tvb, mc_tree, offset, NULL((void*)0), NULL((void*)0));
5421 /* reserved (16 bits) */
5422 add_reserved_field(mc_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5423 offset += 2;
5424 break;
5425
5426 default:
5427 /* Anything else is not expected */
5428 expert_add_info_format(pinfo, meas_type_id_ti, &ei_oran_unexpected_measTypeId,
5429 "measTypeId %u (%s) not supported - only 5 is expected",
5430 meas_type_id,
5431 val_to_str_const(meas_type_id, meas_type_id_vals, "reserved"));
5432 break;
5433 }
5434 proto_item_append_text(mc_ti, " (%s)", val_to_str_const(meas_type_id, meas_type_id_vals, "unknown"));
5435
5436 } while (mf);
5437 }
5438
5439 /* Set extent of overall section */
5440 proto_item_set_len(sectionHeading, offset);
5441
5442 return offset;
5443}
5444
5445/* Dissect udCompHdr (user data compression header, 7.5.2.10) */
5446/* bit_width and comp_meth are out params */
5447static int dissect_udcomphdr(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset,
5448 bool_Bool cplane, bool_Bool ignore,
5449 unsigned *bit_width, unsigned *comp_meth, proto_item **comp_meth_ti,
5450 oran_tap_info *tap_info)
5451{
5452 /* Subtree */
5453 proto_item *udcomphdr_ti = proto_tree_add_string_format(tree, hf_oran_udCompHdr,
5454 tvb, offset, 1, "",
5455 "udCompHdr");
5456 proto_tree *udcomphdr_tree = proto_item_add_subtree(udcomphdr_ti, ett_oran_udcomphdr);
5457
5458 /* udIqWidth */
5459 uint32_t hdr_iq_width;
5460 proto_item *iq_width_item = proto_tree_add_item_ret_uint(udcomphdr_tree, hf_oran_udCompHdrIqWidth , tvb, offset, 1, ENC_NA0x00000000, &hdr_iq_width);
5461 *bit_width = (hdr_iq_width) ? hdr_iq_width : 16;
5462 proto_item_append_text(iq_width_item, " (%u bits)", *bit_width);
5463
5464 /* udCompMeth */
5465 uint32_t ud_comp_meth;
5466 *comp_meth_ti = proto_tree_add_item_ret_uint(udcomphdr_tree, hf_oran_udCompHdrMeth, tvb, offset, 1, ENC_NA0x00000000, &ud_comp_meth);
5467 if (comp_meth) {
5468 *comp_meth = ud_comp_meth;
5469 }
5470
5471 /* Populate tap header with compression settings */
5472 if (!ignore) {
5473 tap_info->compression_methods |= (1 << ud_comp_meth);
5474 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))
;
5475 /* Summary */
5476 proto_item_append_text(udcomphdr_ti, " (IqWidth=%u, udCompMeth=%s)",
5477 *bit_width, rval_to_str_const(ud_comp_meth, ud_comp_header_meth, "Unknown"));
5478 }
5479 else {
5480 proto_item_append_text(udcomphdr_ti, " (ignored)");
5481 if (hdr_iq_width || ud_comp_meth) {
5482 if (cplane) {
5483 /* Only ignore DL for cplane */
5484 expert_add_info_format(pinfo, udcomphdr_ti, &ei_oran_udpcomphdr_should_be_zero,
5485 "udCompHdr in C-Plane for DL should be 0 - found 0x%02x",
5486 tvb_get_uint8(tvb, offset));
5487 }
5488 else {
5489 /* TODO: Ignore UL if using m-plane/preference setting rather than c-plane, but wrong to be set? */
5490 /* expert_add_info_format(pinfo, udcomphdr_ti, &ei_oran_udpcomphdr_should_be_zero,
5491 "udCompHdr in C-Plane for UL should be 0 - found 0x%02x",
5492 tvb_get_uint8(tvb, offset));
5493 */
5494 }
5495
5496 }
5497 }
5498 return offset+1;
5499}
5500
5501/* Dissect udCompParam (user data compression parameter, 8.3.3.15) */
5502/* bit_width and comp_meth are out params */
5503static int dissect_udcompparam(tvbuff_t *tvb, packet_info *pinfo _U___attribute__((unused)), proto_tree *tree, unsigned offset,
5504 unsigned comp_meth,
5505 uint32_t *exponent, uint16_t *sReSMask,
5506 bool_Bool for_sinr)
5507{
5508 if (for_sinr && (comp_meth != COMP_BLOCK_FP1)) {
5509 /* sinrCompParam only present when bfp is used */
5510 return offset;
5511 }
5512
5513 if (comp_meth == COMP_NONE0 ||
5514 comp_meth == COMP_MODULATION4 ||
5515 comp_meth == MOD_COMPR_AND_SELECTIVE_RE_WITH_MASKS8) {
5516
5517 /* Not even creating a subtree for udCompMeth 0, 4, 8 */
5518 return offset;
5519 }
5520
5521 /* Subtree */
5522 unsigned start_offset = offset;
5523 proto_item *udcompparam_ti = proto_tree_add_string_format(tree, hf_oran_udCompParam,
5524 tvb, offset, 1, "",
5525 (for_sinr) ? "sinrCompParam" : "udCompParam");
5526 proto_tree *udcompparam_tree = proto_item_add_subtree(udcompparam_ti, ett_oran_udcompparam);
5527
5528 /* Show comp_meth as a generated field */
5529 proto_item *meth_ti = proto_tree_add_uint(udcompparam_tree, hf_oran_udCompHdrMeth_pref, tvb, 0, 0, comp_meth);
5530 proto_item_set_generated(meth_ti);
5531
5532 uint32_t param_exponent;
5533 uint64_t param_sresmask;
5534
5535 static int * const sres_mask_flags[] = {
5536 &hf_oran_sReSMask_re12,
5537 &hf_oran_sReSMask_re11,
5538 &hf_oran_sReSMask_re10,
5539 &hf_oran_sReSMask_re9,
5540 &hf_oran_sReSMask_re8,
5541 &hf_oran_sReSMask_re7,
5542 &hf_oran_sReSMask_re6,
5543 &hf_oran_sReSMask_re5,
5544 &hf_oran_sReSMask_re4,
5545 &hf_oran_sReSMask_re3,
5546 &hf_oran_sReSMask_re2,
5547 &hf_oran_sReSMask_re1,
5548 NULL((void*)0)
5549 };
5550
5551 switch (comp_meth) {
5552 case COMP_BLOCK_FP1: /* 1 */
5553 case BFP_AND_SELECTIVE_RE_WITH_MASKS7: /* 7 */
5554 /* reserved (4 bits) */
5555 add_reserved_field(udcompparam_tree, hf_oran_reserved_4bits, tvb, offset, 1);
5556 /* exponent (4 bits) */
5557 proto_tree_add_item_ret_uint(udcompparam_tree, hf_oran_exponent,
5558 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &param_exponent);
5559 *exponent = param_exponent;
5560 proto_item_append_text(udcompparam_ti, " (Exponent=%u)", param_exponent);
5561 offset += 1;
5562 break;
5563
5564 case COMP_BLOCK_SCALE2: /* 2 */
5565 /* Separate into integer and fractional bits? */
5566 proto_tree_add_item(udcompparam_tree, hf_oran_blockScaler,
5567 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5568 offset++;
5569 break;
5570
5571 case COMP_U_LAW3: /* 3 */
5572 /* compBitWidth, compShift */
5573 proto_tree_add_item(udcompparam_tree, hf_oran_compBitWidth,
5574 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5575 proto_tree_add_item(udcompparam_tree, hf_oran_compShift,
5576 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5577 offset += 1;
5578 break;
5579
5580 case BFP_AND_SELECTIVE_RE5: /* 5 */
5581 {
5582 /* sReSMask (exponent in middle!) */
5583 proto_item *sresmask_ti;
5584 sresmask_ti = proto_tree_add_bitmask_ret_uint64(udcompparam_tree, tvb, offset,
5585 hf_oran_sReSMask,
5586 ett_oran_sresmask,
5587 sres_mask_flags,
5588 ENC_NA0x00000000,
5589 &param_sresmask);
5590
5591 /* Get rid of exponent-shaped gap */
5592 param_sresmask = ((param_sresmask >> 4) & 0x0f00) | (param_sresmask & 0xff);
5593 unsigned res = 0;
5594 for (unsigned n=0; n < 12; n++) {
5595 if ((param_sresmask >> n) & 0x1) {
5596 res++;
5597 }
5598 }
5599 proto_item_append_text(sresmask_ti, " (%2u REs)", res);
5600
5601 /* exponent */
5602 proto_tree_add_item_ret_uint(udcompparam_tree, hf_oran_exponent,
5603 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &param_exponent);
5604 *sReSMask = (uint16_t)param_sresmask;
5605 *exponent = param_exponent;
5606
5607 proto_item_append_text(udcompparam_ti, " (exponent=%u, %u REs)", *exponent, res);
5608 offset += 2;
5609 break;
5610 }
5611
5612 case MOD_COMPR_AND_SELECTIVE_RE6: /* 6 */
5613 {
5614 /* sReSMask (exponent in middle!) */
5615 proto_item *sresmask_ti;
5616
5617 sresmask_ti = proto_tree_add_bitmask_ret_uint64(udcompparam_tree, tvb, offset,
5618 hf_oran_sReSMask,
5619 ett_oran_sresmask,
5620 sres_mask_flags,
5621 ENC_NA0x00000000,
5622 &param_sresmask);
5623
5624 /* Get rid of reserved-shaped gap */
5625 param_sresmask = ((param_sresmask >> 4) & 0x0f00) | (param_sresmask & 0xff);
5626 unsigned res = 0;
5627 for (unsigned n=0; n < 12; n++) {
5628 if ((param_sresmask >> n) & 0x1) {
5629 res++;
5630 }
5631 }
5632 proto_item_append_text(sresmask_ti, " (%u REs)", res);
5633
5634 /* reserved (4 bits) */
5635 add_reserved_field(udcompparam_tree, hf_oran_reserved_last_4bits, tvb, offset, 1);
5636 *sReSMask = (uint16_t)param_sresmask;
5637
5638 proto_item_append_text(udcompparam_ti, " (%u REs)", res);
5639 offset += 2;
5640 break;
5641 }
5642
5643 default:
5644 /* reserved (set to all zeros), but how many bytes?? */
5645 break;
5646 }
5647
5648 proto_item_set_len(udcompparam_ti, offset-start_offset);
5649 return offset;
5650}
5651
5652
5653/* Dissect ciCompHdr (channel information compression header, 7.5.2.15) */
5654/* bit_width and comp_meth are out params */
5655static int dissect_cicomphdr(tvbuff_t *tvb, packet_info *pinfo _U___attribute__((unused)), proto_tree *tree, unsigned offset,
5656 unsigned *bit_width, unsigned *comp_meth, uint8_t *comp_opt)
5657{
5658 /* Subtree */
5659 proto_item *cicomphdr_ti = proto_tree_add_string_format(tree, hf_oran_ciCompHdr,
5660 tvb, offset, 1, "",
5661 "ciCompHdr");
5662 proto_tree *cicomphdr_tree = proto_item_add_subtree(cicomphdr_ti, ett_oran_cicomphdr);
5663
5664 /* ciIqWidth */
5665 uint32_t hdr_iq_width;
5666 proto_item *iq_width_item = proto_tree_add_item_ret_uint(cicomphdr_tree, hf_oran_ciCompHdrIqWidth , tvb, offset, 1, ENC_NA0x00000000, &hdr_iq_width);
5667 hdr_iq_width = (hdr_iq_width) ? hdr_iq_width : 16;
5668 if (bit_width) {
5669 *bit_width = hdr_iq_width;
5670 }
5671 proto_item_append_text(iq_width_item, " (%u bits)", hdr_iq_width);
5672
5673 /* ciCompMeth */
5674 uint32_t ci_comp_meth;
5675 proto_tree_add_item_ret_uint(cicomphdr_tree, hf_oran_ciCompHdrMeth, tvb, offset, 1, ENC_NA0x00000000, &ci_comp_meth);
5676 if (comp_meth) {
5677 *comp_meth = ci_comp_meth;
5678 }
5679
5680 /* ciCompOpt */
5681 uint32_t opt;
5682 proto_tree_add_item_ret_uint(cicomphdr_tree, hf_oran_ciCompOpt, tvb, offset, 1, ENC_NA0x00000000, &opt);
5683 *comp_opt = opt;
5684 offset += 1;
5685
5686 /* Summary */
5687 proto_item_append_text(cicomphdr_ti, " (IqWidth=%u, ciCompMeth=%s, ciCompOpt=%s)",
5688 hdr_iq_width,
5689 rval_to_str_const(ci_comp_meth, ud_comp_header_meth, "Unknown"),
5690 (*comp_opt) ? "compression per PRB" : "compression per UE");
5691 return offset;
5692}
5693
5694static void dissect_payload_version(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, unsigned offset)
5695{
5696 unsigned version;
5697 proto_item *ti = proto_tree_add_item_ret_uint(tree, hf_oran_payload_version, tvb, offset, 1, ENC_NA0x00000000, &version);
5698 if (version != 1) {
5699 expert_add_info_format(pinfo, ti, &ei_oran_version_unsupported,
5700 "PayloadVersion %u not supported by dissector (only 1 is known)",
5701 version);
5702 /* TODO: should throw an exception? */
5703 }
5704}
5705
5706static void show_link_to_acknack_request(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo,
5707 ack_nack_request_t *request)
5708{
5709 /* Request frame */
5710 proto_item *ti = proto_tree_add_uint(tree, hf_oran_acknack_request_frame,
5711 tvb, 0, 0, request->request_frame_number);
5712 PROTO_ITEM_SET_GENERATED(ti)proto_item_set_generated((ti));
5713
5714 /* Work out gap between frames (in ms) */
5715 int seconds_between_packets = (int)
5716 (pinfo->abs_ts.secs - request->request_frame_time.secs);
5717 int nseconds_between_packets =
5718 pinfo->abs_ts.nsecs - request->request_frame_time.nsecs;
5719
5720 int total_gap = (seconds_between_packets*1000) +
5721 ((nseconds_between_packets+500000) / 1000000);
5722
5723 ti = proto_tree_add_uint(tree, hf_oran_acknack_request_time,
5724 tvb, 0, 0, total_gap);
5725 PROTO_ITEM_SET_GENERATED(ti)proto_item_set_generated((ti));
5726
5727 /* Type of request */
5728 ti = proto_tree_add_uint(tree, hf_oran_acknack_request_type,
5729 tvb, 0, 0, request->requestType);
5730 PROTO_ITEM_SET_GENERATED(ti)proto_item_set_generated((ti));
5731}
5732
5733static void show_link_to_acknack_response(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo,
5734 ack_nack_request_t *response)
5735{
5736 if (response->response_frame_number == 0) {
5737 /* Requests may not get a response, and can't always tell when to expect one */
5738 return;
5739 }
5740
5741 /* Response frame */
5742 proto_item *ti = proto_tree_add_uint(tree, hf_oran_acknack_response_frame,
5743 tvb, 0, 0, response->response_frame_number);
5744 PROTO_ITEM_SET_GENERATED(ti)proto_item_set_generated((ti));
5745
5746 /* Work out gap between frames (in ms) */
5747 int seconds_between_packets = (int)
5748 (response->response_frame_time.secs - pinfo->abs_ts.secs);
5749 int nseconds_between_packets =
5750 response->response_frame_time.nsecs - pinfo->abs_ts.nsecs;
5751
5752 int total_gap = (seconds_between_packets*1000) +
5753 ((nseconds_between_packets+500000) / 1000000);
5754
5755 ti = proto_tree_add_uint(tree, hf_oran_acknack_response_time,
5756 tvb, 0, 0, total_gap);
5757 PROTO_ITEM_SET_GENERATED(ti)proto_item_set_generated((ti));
5758}
5759
5760
5761
5762/* Control plane dissector (section 7). */
5763static int dissect_oran_c(tvbuff_t *tvb, packet_info *pinfo,
5764 proto_tree *tree, oran_tap_info *tap_info, void *data _U___attribute__((unused)))
5765{
5766 /* Hidden filter for plane */
5767 proto_item *plane_ti = proto_tree_add_item(tree, hf_oran_cplane, tvb, 0, 0, ENC_NA0x00000000);
5768 PROTO_ITEM_SET_HIDDEN(plane_ti)proto_item_set_hidden((plane_ti));
5769
5770 /* Set up structures needed to add the protocol subtree and manage it */
5771 unsigned offset = 0;
5772
5773 col_set_str(pinfo->cinfo, COL_PROTOCOL, "O-RAN-FH-C");
5774 col_set_str(pinfo->cinfo, COL_INFO, "C-Plane");
5775
5776 tap_info->userplane = false0;
5777
5778 /* Create display subtree for the protocol */
5779 proto_item *protocol_item = proto_tree_add_item(tree, proto_oran, tvb, 0, -1, ENC_NA0x00000000);
5780 proto_item_append_text(protocol_item, "-C");
5781 proto_tree *oran_tree = proto_item_add_subtree(protocol_item, ett_oran);
5782
5783 /* ecpriRtcid (eAxC ID) */
5784 uint16_t eAxC;
5785 addPcOrRtcid(tvb, oran_tree, &offset, hf_oran_ecpri_rtcid, &eAxC, tap_info);
5786 tap_info->eaxc = eAxC;
5787
5788 /* Look up any existing conversation state for eAxC+plane */
5789 uint32_t key = make_flow_key(pinfo, eAxC, ORAN_C_PLANE0, false0);
5790 flow_state_t* state = (flow_state_t*)wmem_tree_lookup32(flow_states_table, key);
5791
5792 /* Message identifier */
5793 uint32_t seq_id, sub_seq_id, e;
5794 proto_item *seq_id_ti;
5795 offset = addSeqid(tvb, oran_tree, offset, ORAN_C_PLANE0, &seq_id, &seq_id_ti, pinfo, &sub_seq_id, &e);
5796
5797 /* Section common subtree */
5798 int section_tree_offset = offset;
5799 proto_item *sectionHeading = proto_tree_add_string_format(oran_tree, hf_oran_c_section_common,
5800 tvb, offset, 0, "", "C-Plane Section Type ");
5801 proto_tree *section_tree = proto_item_add_subtree(sectionHeading, ett_oran_c_section_common);
5802
5803 /* Peek ahead at the section type */
5804 uint32_t sectionType = 0;
5805 sectionType = tvb_get_uint8(tvb, offset+5);
5806
5807 uint32_t scs = 0;
5808 proto_item *scs_ti = NULL((void*)0);
5809
5810 /* dataDirection */
5811 uint32_t direction = 0;
5812 proto_item *datadir_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_data_direction, tvb, offset, 1, ENC_NA0x00000000, &direction);
5813 tap_info->uplink = (direction==0);
5814
5815 /* Update/report status of conversation */
5816 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
5817
5818 if (state == NULL((void*)0)) {
5819 /* Allocate new state */
5820 state = wmem_new0(wmem_file_scope(), flow_state_t)((flow_state_t*)wmem_alloc0((wmem_file_scope()), sizeof(flow_state_t
)))
;
5821 state->ack_nack_requests = wmem_tree_new(wmem_file_scope());
5822 wmem_tree_insert32(flow_states_table, key, state);
5823 state->expected_dl_sections = wmem_tree_new(wmem_file_scope());
5824 }
5825
5826 /* Check sequence analysis status */
5827 if (state->last_frame_seen[direction] && (seq_id != state->next_expected_sequence_number[direction])) {
5828 /* Store this result */
5829 flow_result_t *result = wmem_new0(wmem_file_scope(), flow_result_t)((flow_result_t*)wmem_alloc0((wmem_file_scope()), sizeof(flow_result_t
)))
;
5830 result->unexpected_seq_number = true1;
5831 result->expected_sequence_number = state->next_expected_sequence_number[direction];
5832 result->previous_frame = state->last_frame[direction];
5833 wmem_tree_insert32(flow_results_table, pinfo->num, result);
5834 }
5835 /* Update conversation info */
5836 state->last_frame[direction] = pinfo->num;
5837 state->last_frame_seen[direction] = true1;
5838 state->next_expected_sequence_number[direction] = (seq_id+1) % 256;
5839 }
5840
5841 /* Show any issues associated with this frame number */
5842 flow_result_t *result = wmem_tree_lookup32(flow_results_table, pinfo->num);
5843 if (result!=NULL((void*)0) && result->unexpected_seq_number) {
5844 expert_add_info_format(pinfo, seq_id_ti,
5845 (direction == DIR_UPLINK0) ?
5846 &ei_oran_cplane_unexpected_sequence_number_ul :
5847 &ei_oran_cplane_unexpected_sequence_number_dl,
5848 "Sequence number %u expected, but got %u",
5849 result->expected_sequence_number, seq_id);
5850
5851 /* Update tap info */
5852 uint32_t missing_sns = (256 + seq_id - result->expected_sequence_number) % 256;
5853 /* Don't get confused by being slightly out of order.. */
5854 if (missing_sns < 128) {
5855 tap_info->missing_sns = missing_sns;
5856 }
5857 else {
5858 tap_info->missing_sns = 0;
5859 }
5860
5861 /* TODO: could add previous/next frames (in seqId tree?) ? */
5862 }
5863
5864 /* payloadVersion */
5865 dissect_payload_version(section_tree, tvb, pinfo, offset);
5866
5867 /* filterIndex */
5868 if (sectionType == SEC_C_SLOT_CONTROL || sectionType == SEC_C_ACK_NACK_FEEDBACK) {
5869 /* scs (for ST4 and ST8) */
5870 scs_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_frameStructure_subcarrier_spacing, tvb, offset, 1, ENC_NA0x00000000, &scs);
5871 }
5872 else if (sectionType == SEC_C_RRM_MEAS_REPORTS || sectionType == SEC_C_REQUEST_RRM_MEAS) {
5873 /* reserved (4 bits) */
5874 add_reserved_field(section_tree, hf_oran_reserved_last_4bits, tvb, offset, 1);
5875 }
5876 else if (sectionType != SEC_C_LAA) {
5877 /* filterIndex (most common case) */
5878 proto_tree_add_item(section_tree, hf_oran_filter_index, tvb, offset, 1, ENC_NA0x00000000);
5879 }
5880 offset += 1;
5881
5882 unsigned ref_a_offset = offset;
5883 /* frameId */
5884 uint32_t frameId = 0;
5885 proto_tree_add_item_ret_uint(section_tree, hf_oran_frame_id, tvb, offset, 1, ENC_NA0x00000000, &frameId);
5886 tap_info->frame = frameId;
5887 offset += 1;
5888
5889 /* subframeId */
5890 uint32_t subframeId = 0;
5891 proto_tree_add_item_ret_uint(section_tree, hf_oran_subframe_id, tvb, offset, 1, ENC_NA0x00000000, &subframeId);
5892 /* slotId */
5893 uint32_t slotId = 0;
5894 proto_tree_add_item_ret_uint(section_tree, hf_oran_slot_id, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &slotId);
5895 tap_info->slot = slotId;
5896 offset++;
5897
5898 /* startSymbolId */
5899 uint32_t startSymbolId = 0;
5900 proto_item *ssid_ti = NULL((void*)0);
5901 if ((sectionType == SEC_C_ACK_NACK_FEEDBACK) || /* Section Type 8 */
5902 (sectionType == SEC_C_SINR_REPORTING)) { /* Section Type 9 */
5903 /* symbolId */
5904 proto_tree_add_item_ret_uint(section_tree, hf_oran_symbolId, tvb, offset, 1, ENC_NA0x00000000, &startSymbolId);
5905 }
5906 else if (sectionType != SEC_C_LAA) {
5907 /* startSymbolId is in most section types */
5908 ssid_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_start_symbol_id, tvb, offset, 1, ENC_NA0x00000000, &startSymbolId);
5909 if (startSymbolId && (sectionType == SEC_C_RRM_MEAS_REPORTS)) { /* Section Type 10 */
5910 proto_item_append_text(ssid_ti, " (should be 0 for ST10!)");
5911 expert_add_info_format(pinfo, ssid_ti, &ei_oran_st10_startsymbolid_not_0,
5912 "startSymbolId should be 0 for ST10 - found %u", startSymbolId);
5913 }
5914 }
5915 else {
5916 /* reserved (6 bits) */
5917 add_reserved_field(section_tree, hf_oran_reserved_last_6bits, tvb, offset, 1);
5918 }
5919 offset++;
5920
5921
5922 char id[16];
5923 snprintf(id, 16, "%u-%u-%u-%u", frameId, subframeId, slotId, startSymbolId);
5924 proto_item *pi = proto_tree_add_string(section_tree, hf_oran_refa, tvb, ref_a_offset, 3, id);
5925 proto_item_set_generated(pi);
5926
5927 uint32_t cmd_scope = 0;
5928 bool_Bool st8_ready = false0;
5929
5930 /* numberOfSections (or whatever section has instead) */
5931 uint32_t nSections = 0;
5932 if (sectionType == SEC_C_SLOT_CONTROL) { /* Section Type 4 */
5933 /* Slot Control has these fields instead */
5934 /* reserved (4 bits) */
5935 add_reserved_field(section_tree, hf_oran_reserved_4bits, tvb, offset, 1);
5936 /* cmdScope (4 bits) */
5937 proto_tree_add_item_ret_uint(section_tree, hf_oran_cmd_scope, tvb, offset, 1, ENC_NA0x00000000, &cmd_scope);
5938 }
5939 else if (sectionType == SEC_C_ACK_NACK_FEEDBACK) { /* Section Type 8 */
5940 /* reserved (7 bits) */
5941 add_reserved_field(section_tree, hf_oran_reserved_7bits, tvb, offset, 1);
5942 /* ready (1 bit) */
5943 /* TODO: when set, ready in slotId+1.. */
5944 proto_tree_add_item_ret_boolean(section_tree, hf_oran_ready, tvb, offset, 1, ENC_NA0x00000000, &st8_ready);
5945 if (!st8_ready) {
5946 /* SCS value is ignored, and may be set to any value by O-RU */
5947 proto_item_append_text(scs_ti, " (ignored)");
5948 }
5949 }
5950 else if (sectionType != SEC_C_LAA) {
5951 /* numberOfSections */
5952 proto_tree_add_item_ret_uint(section_tree, hf_oran_numberOfSections, tvb, offset, 1, ENC_NA0x00000000, &nSections);
5953 }
5954 else {
5955 add_reserved_field(section_tree, hf_oran_reserved_8bits, tvb, offset, 1);
5956 }
5957 offset++;
5958
5959 /* sectionType */
5960 proto_tree_add_item_ret_uint(section_tree, hf_oran_sectionType, tvb, offset, 1, ENC_NA0x00000000, &sectionType);
5961 offset += 1;
5962
5963 /* Check that dataDirection is consistent with section type */
5964 if (sectionType == SEC_C_SINR_REPORTING && direction != 0) { /* Section Type 9 */
5965 expert_add_info(pinfo, datadir_ti, &ei_oran_st9_not_ul);
5966 }
5967 if (sectionType == SEC_C_RRM_MEAS_REPORTS && direction != 0) { /* Section Type 10 */
5968 expert_add_info(pinfo, datadir_ti, &ei_oran_st10_not_ul);
5969 }
5970
5971 /* Note this section type in stats */
5972 if (sectionType < SEC_C_MAX_INDEX) {
5973 tap_info->section_types[sectionType] = true1;
5974 }
5975
5976 /* Section-type-specific fields following common header (white entries in Section Type diagrams) */
5977 unsigned bit_width = 0;
5978 unsigned comp_meth = 0;
5979 proto_item *comp_meth_ti;
5980 unsigned ci_comp_method = 0;
5981 uint8_t ci_comp_opt = 0;
5982
5983 uint32_t num_ues = 0;
5984 uint32_t number_of_acks = 0, number_of_nacks = 0;
5985
5986 uint32_t num_sinr_per_prb = 0;
5987
5988 switch (sectionType) {
5989 case SEC_C_UNUSED_RB: /* Section Type 0 */
5990 /* timeOffset */
5991 proto_tree_add_item(section_tree, hf_oran_timeOffset, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
5992 offset += 2;
5993 /* frameStructure */
5994 offset = dissect_frame_structure(section_tree, tvb, offset,
5995 subframeId, slotId);
5996
5997 /* cpLength */
5998 proto_tree_add_item(section_tree, hf_oran_cpLength, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
5999 offset += 2;
6000 /* reserved (8 bits) */
6001 add_reserved_field(section_tree, hf_oran_reserved_8bits, tvb, offset, 1);
6002 offset += 1;
6003 break;
6004
6005 case SEC_C_NORMAL: /* Section Type 1 */
6006 case SEC_C_UE_SCHED: /* Section Type 5 */
6007 /* udCompHdr */
6008 offset = dissect_udcomphdr(tvb, pinfo, section_tree, offset,
6009 true1, direction==0 && pref_override_ul_compression, /* ignore for DL or if using mplane for UL settings */
6010 &bit_width, &comp_meth, &comp_meth_ti, tap_info);
6011 /* reserved (8 bits) */
6012 add_reserved_field(section_tree, hf_oran_reserved_8bits, tvb, offset, 1);
6013 offset += 1;
6014 break;
6015
6016 case SEC_C_SLOT_CONTROL: /* Section Type 4 */
6017 break;
6018
6019 case SEC_C_PRACH: /* Section Type 3 */
6020 /* timeOffset */
6021 proto_tree_add_item(section_tree, hf_oran_timeOffset, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6022 offset += 2;
6023 /* frameStructure */
6024 offset = dissect_frame_structure(section_tree, tvb, offset,
6025 subframeId, slotId);
6026 /* cpLength */
6027 proto_tree_add_item(section_tree, hf_oran_cpLength, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6028 offset += 2;
6029 /* udCompHdr */
6030 offset = dissect_udcomphdr(tvb, pinfo, section_tree, offset,
6031 true1, direction==0 && pref_override_ul_compression, /* ignore for DL or if using mplane for UL settings */
6032 &bit_width, &comp_meth, &comp_meth_ti, tap_info);
6033 break;
6034
6035 case SEC_C_CH_INFO: /* Section Type 6 */
6036 /* numberOfUEs */
6037 proto_tree_add_item_ret_uint(section_tree, hf_oran_numberOfUEs, tvb, offset, 1, ENC_NA0x00000000, &num_ues);
6038 offset += 1;
6039 /* ciCompHdr (was reserved) */
6040 offset = dissect_cicomphdr(tvb, pinfo, section_tree, offset, &bit_width, &ci_comp_method, &ci_comp_opt);
6041
6042 /* Number of sections may not be filled in (at all, or correctly), so set to the number of UEs.
6043 The data entries are per-UE... they don't have a sectionID, but they could have section extensions... */
6044 if (nSections == 0 || num_ues > nSections) {
6045 nSections = num_ues;
6046 }
6047 break;
6048
6049 case SEC_C_RSVD2:
6050 break;
6051
6052 case SEC_C_LAA: /* Section Type 7 */
6053 add_reserved_field(section_tree, hf_oran_reserved_16bits, tvb, offset, 2);
6054 offset += 2;
6055 break;
6056
6057 case SEC_C_ACK_NACK_FEEDBACK: /* Section Type 8 */
6058 /* numberOfAcks (1 byte) */
6059 proto_tree_add_item_ret_uint(section_tree, hf_oran_number_of_acks, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &number_of_acks);
6060 offset += 1;
6061 /* numberOfNacks (1 byte) */
6062 proto_tree_add_item_ret_uint(section_tree, hf_oran_number_of_nacks, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &number_of_nacks);
6063 offset += 1;
6064
6065 /* Show ACKs and NACKs. For both, try to link back to request. */
6066 for (unsigned int n=1; n <= number_of_acks; n++) {
6067 uint32_t ackid;
6068 proto_item *ack_ti;
6069 ack_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_ackid, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &ackid);
6070 offset += 2;
6071
6072 /* Look up request table in state (which really should be set by now, but test anyway). */
6073 if (state && state->ack_nack_requests) {
6074 ack_nack_request_t *request = wmem_tree_lookup32(state->ack_nack_requests, ackid);
6075 if (request != NULL((void*)0)) {
6076 /* On first pass, update with this response */
6077 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
6078 request->response_frame_number = pinfo->num;
6079 request->response_frame_time = pinfo->abs_ts;
6080 }
6081
6082 /* Show request details */
6083 show_link_to_acknack_request(section_tree, tvb, pinfo, request);
6084 }
6085 else {
6086 /* Request not found */
6087 expert_add_info_format(pinfo, ack_ti, &ei_oran_acknack_no_request,
6088 "Response for ackId=%u received, but no request found",
6089 ackid);
6090 }
6091 }
6092 }
6093 for (unsigned int m=1; m <= number_of_nacks; m++) {
6094 uint32_t nackid;
6095 proto_item *nack_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_nackid, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &nackid);
6096 offset += 2;
6097
6098 expert_add_info_format(pinfo, nack_ti, &ei_oran_st8_nackid,
6099 "Received Nack for ackNackId=%u",
6100 nackid);
6101
6102 /* Look up request table in state. */
6103 if (state && state->ack_nack_requests) {
6104 ack_nack_request_t *request = wmem_tree_lookup32(state->ack_nack_requests, nackid);
6105 if (request) {
6106 /* On first pass, update with this response */
6107 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
6108 request->response_frame_number = pinfo->num;
6109 request->response_frame_time = pinfo->abs_ts;
6110 }
6111
6112 /* Show request details */
6113 show_link_to_acknack_request(section_tree, tvb, pinfo, request);
6114 }
6115 else {
6116 /* Request not found */
6117 expert_add_info_format(pinfo, nack_ti, &ei_oran_acknack_no_request,
6118 "Response for nackId=%u received, but no request found",
6119 nackid);
6120 }
6121 }
6122 }
6123 break;
6124
6125 case SEC_C_SINR_REPORTING: /* Section Type 9 */
6126 {
6127 /* numSinrPerPrb (3 bits) */
6128 proto_item *nspp_ti;
6129 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);
6130 switch (num_sinr_per_prb) {
6131 case 0:
6132 num_sinr_per_prb = 1; break;
6133 case 1:
6134 num_sinr_per_prb = 2; break;
6135 case 2:
6136 num_sinr_per_prb = 3; break;
6137 case 3:
6138 num_sinr_per_prb = 4; break;
6139 case 4:
6140 num_sinr_per_prb = 6; break;
6141 case 5:
6142 num_sinr_per_prb = 12; break;
6143
6144 default:
6145 proto_item_append_text(nspp_ti, " (invalid)");
6146 num_sinr_per_prb = 1;
6147 expert_add_info_format(pinfo, nspp_ti, &ei_oran_num_sinr_per_prb_unknown,
6148 "Invalid numSinrPerPrb value (%u)",
6149 num_sinr_per_prb);
6150 }
6151
6152 /* oruControlSinrSlotMaskId (5 bits) */
6153 proto_tree_add_item(section_tree, hf_oran_oru_control_sinr_slot_mask_id, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6154 offset += 1;
6155 /* reserved (8 bits) */
6156 add_reserved_field(section_tree, hf_oran_reserved_8bits, tvb, offset, 1);
6157 offset += 1;
6158 break;
6159 }
6160
6161 case SEC_C_RRM_MEAS_REPORTS: /* Section Type 10 */
6162 case SEC_C_REQUEST_RRM_MEAS: /* Section Type 11 */
6163 /* reserved (16 bits) */
6164 add_reserved_field(section_tree, hf_oran_reserved_16bits, tvb, offset, 2);
6165 offset += 2;
6166 break;
6167 };
6168
6169 /* Update udCompHdr details in state for UL U-Plane */
6170 if (state && direction==0) {
6171 switch (sectionType) {
6172 case SEC_C_NORMAL: /* Section Type 1 */
6173 case SEC_C_PRACH: /* Section Type 3 */
6174 case SEC_C_UE_SCHED: /* Section Type 5 */
6175 state->ul_ud_comp_hdr_set = true1;
6176 state->ul_ud_comp_hdr_bit_width = bit_width;
6177 state->ul_ud_comp_hdr_compression = comp_meth;
6178 state->ul_ud_comp_hdr_frame = pinfo->num;
6179 break;
6180 default:
6181 break;
6182 }
6183 }
6184
6185
6186 proto_item_append_text(sectionHeading, "%d, %s, frameId: %d, subframeId: %d, slotId: %d, startSymbolId: %d",
6187 sectionType, val_to_str_const(direction, data_direction_vals, "Unknown"),
6188 frameId, subframeId, slotId, startSymbolId);
6189 if (nSections) {
6190 proto_item_append_text(sectionHeading, ", numberOfSections=%u", nSections);
6191 }
6192
6193 write_pdu_label_and_info(protocol_item, NULL((void*)0), pinfo, ", Type: %2d %s", sectionType,
6194 rval_to_str_const(sectionType, section_types_short, "Unknown"));
6195
6196 /* Set actual length of C-Plane section header */
6197 proto_item_set_len(section_tree, offset - section_tree_offset);
6198
6199 if (sectionType == SEC_C_ACK_NACK_FEEDBACK) {
6200 write_pdu_label_and_info(oran_tree, section_tree, pinfo,
6201 (st8_ready) ? " (Ready)" : " (ACK)");
6202 }
6203
6204
6205 /* Section type 4 doesn't have normal sections, so deal with here before normal sections */
6206 if (sectionType == SEC_C_SLOT_CONTROL) {
6207 /* numberOfST4Cmds */
6208 uint32_t no_st4_cmds, st4_cmd_len, num_slots, ack_nack_req_id, st4_cmd_type;
6209 proto_item *no_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_number_of_st4_cmds,
6210 tvb, offset, 1, ENC_NA0x00000000, &no_st4_cmds);
6211 if (no_st4_cmds == 0) {
6212 expert_add_info(pinfo, no_ti, &ei_oran_st4_no_cmds);
6213 }
6214 offset += 1;
6215
6216 /* reserved (1 byte) */
6217 add_reserved_field(section_tree, hf_oran_reserved_8bits, tvb, offset, 1);
6218 offset += 1;
6219
6220 /* Loop over commands. Each has 8-byte common header, followed by cmd-specific payload */
6221 proto_item *len_ti;
6222 for (uint32_t n=0; n < no_st4_cmds; n++) {
6223 /* Table 7.4.6-2: Section Type 4 Command common header format */
6224 proto_item *hdr_ti = proto_tree_add_string_format(section_tree, hf_oran_st4_cmd_header,
6225 tvb, offset, 8, "",
6226 "Type 4 Command common header");
6227 proto_tree *hdr_tree = proto_item_add_subtree(hdr_ti, ett_oran_st4_cmd_header);
6228
6229 /* st4CmdType */
6230 proto_tree_add_item_ret_uint(hdr_tree, hf_oran_st4_cmd_type, tvb, offset, 1, ENC_NA0x00000000, &st4_cmd_type);
6231 offset += 1;
6232
6233 /* st4CmdLen */
6234 len_ti = proto_tree_add_item_ret_uint(hdr_tree, hf_oran_st4_cmd_len, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &st4_cmd_len);
6235 if (st4_cmd_len == 0) {
6236 /* Meaning of 0 not yet defined (v15.00) */
6237 proto_item_append_text(len_ti, " (reserved)");
6238 expert_add_info(pinfo, len_ti, &ei_oran_st4_zero_len_cmd);
6239 }
6240 else {
6241 proto_item_append_text(len_ti, " (%u bytes)", st4_cmd_len*4);
6242 }
6243 offset += 2;
6244
6245 /* numSlots */
6246 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);
6247 if (num_slots == 0) {
6248 proto_item_append_text(slots_ti, " (until changed)");
6249 }
6250 offset += 1;
6251
6252 /* ackNackReqId */
6253 proto_item *ack_nack_req_id_ti;
6254 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);
6255 offset += 2;
6256 if (ack_nack_req_id == 0) {
6257 proto_item_append_text(ack_nack_req_id_ti, " (no Section type 8 response expected)");
6258 }
6259
6260 /* reserved (16 bits) */
6261 add_reserved_field(hdr_tree, hf_oran_reserved_16bits, tvb, offset, 2);
6262 offset += 2;
6263
6264 /* Set common header summary */
6265 proto_item_append_text(hdr_ti, " (cmd=%s, len=%u, slots=%u, ackNackReqId=%u)",
6266 rval_to_str_const(st4_cmd_type, st4_cmd_type_vals, "Unknown"),
6267 st4_cmd_len, num_slots, ack_nack_req_id);
6268
6269 col_append_fstr(pinfo->cinfo, COL_INFO, " (%s)",
6270 rval_to_str_const(st4_cmd_type, st4_cmd_type_vals, "Unknown"));
6271
6272
6273 /* Subtree for this command body */
6274 proto_item *command_ti = proto_tree_add_string_format(section_tree, hf_oran_st4_cmd,
6275 tvb, offset, 0, "",
6276 "Type 4 Command (%s)", rval_to_str_const(st4_cmd_type, st4_cmd_type_vals, "Unknown"));
6277 proto_tree *command_tree = proto_item_add_subtree(command_ti, ett_oran_st4_cmd);
6278
6279 unsigned command_start_offset = offset;
6280
6281 /* Check fields compatible with chosen command. */
6282 if (st4_cmd_type==1) {
6283 if (num_slots != 0) {
6284 /* "the value of numSlots should be set to zero for this command type" */
6285 expert_add_info_format(pinfo, slots_ti, &ei_oran_numslots_not_zero,
6286 "numSlots should be zero for ST4 command 1 - found %u",
6287 num_slots);
6288 }
6289 }
6290
6291 if (st4_cmd_type==3 || st4_cmd_type==4) {
6292 if (startSymbolId != 0) {
6293 /* "expected reception window for the commands is the symbol zero reception window" */
6294 expert_add_info_format(pinfo, ssid_ti, &ei_oran_start_symbol_id_not_zero,
6295 "startSymbolId should be zero for ST4 commands 3&4 - found %u",
6296 startSymbolId);
6297 }
6298 }
6299
6300 /* Add format for this command */
6301 switch (st4_cmd_type) {
6302 case 1: /* TIME_DOMAIN_BEAM_CONFIG */
6303 {
6304 bool_Bool disable_tdbfns;
6305 uint32_t bfwcomphdr_iq_width, bfwcomphdr_comp_meth;
6306
6307 /* Hidden filter for bf */
6308 proto_item *bf_ti = proto_tree_add_item(command_tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
6309 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
6310
6311 /* reserved (2 bits) */
6312 add_reserved_field(command_tree, hf_oran_reserved_2bits, tvb, offset, 1);
6313 /* symbolMask (14 bits) */
6314 uint32_t symbol_mask;
6315 proto_item *symbol_mask_ti;
6316 offset = dissect_symbolmask(tvb, command_tree, offset, &symbol_mask, &symbol_mask_ti);
6317 /* 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 */
6318 /* lsb is symbol 0 */
6319 for (unsigned s=0; s < 14; s++) {
6320 if ((startSymbolId & (1 << s)) && (startSymbolId > s)) {
6321 proto_item_append_text(symbol_mask_ti, " (startSymbolId is %u, so some lower symbol bits ignored!)", startSymbolId);
6322 expert_add_info(pinfo, symbol_mask_ti, &ei_oran_start_symbol_id_bits_ignored);
6323 break;
6324 }
6325 }
6326
6327 /* disableTDBFNs (1 bit) */
6328 proto_tree_add_item_ret_boolean(command_tree, hf_oran_disable_tdbfns, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &disable_tdbfns);
6329
6330 /* tdBeamNum (15 bits) */
6331 proto_tree_add_item(command_tree, hf_oran_td_beam_num, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6332 offset += 2;
6333
6334 /* bfwCompHdr (2 subheaders - bfwIqWidth and bfwCompMeth)*/
6335 offset = dissect_bfwCompHdr(tvb, command_tree, offset,
6336 &bfwcomphdr_iq_width, &bfwcomphdr_comp_meth, &comp_meth_ti);
6337 /* reserved (3 bytes) */
6338 proto_tree_add_bits_item(command_tree, hf_oran_reserved, tvb, offset*8, 24, ENC_BIG_ENDIAN0x00000000);
6339 offset += 3;
6340
6341 if (disable_tdbfns) {
6342 /* No beamnum information to show so get out. */
6343 break;
6344 }
6345
6346 /* Read beam entries until reach end of command length */
6347 while ((offset - command_start_offset) < (st4_cmd_len * 4)) {
6348
6349 /* disableTDBFWs (1 bit) */
6350 bool_Bool disable_tdbfws;
6351 proto_tree_add_item_ret_boolean(command_tree, hf_oran_disable_tdbfws, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &disable_tdbfws);
6352
6353 /* tdBeamNum (15 bits) */
6354 proto_tree_add_item(command_tree, hf_oran_td_beam_num, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6355 offset += 2;
6356
6357 /* Showing BFWs? */
6358 if (!disable_tdbfws) {
6359
6360 /* bfwCompParam */
6361 unsigned exponent = 0;
6362 bool_Bool supported = false0;
6363 unsigned num_trx_entries;
6364 uint16_t *trx_entries;
6365 offset = dissect_bfwCompParam(tvb, command_tree, pinfo, offset, comp_meth_ti,
6366 &bfwcomphdr_comp_meth, &exponent, &supported,
6367 &num_trx_entries, &trx_entries);
6368
6369 /* Antenna count from preference */
6370 unsigned num_trx = pref_num_bf_antennas;
6371 int bit_offset = offset*8;
6372
6373 for (unsigned trx=0; trx < num_trx; trx++) {
6374 /* Create antenna subtree */
6375 int bfw_offset = bit_offset / 8;
6376 proto_item *bfw_ti = proto_tree_add_string_format(command_tree, hf_oran_bfw,
6377 tvb, bfw_offset, 0, "", "TRX %3u: (", trx);
6378 proto_tree *bfw_tree = proto_item_add_subtree(bfw_ti, ett_oran_bfw);
6379
6380 /* I value */
6381 /* Get bits, and convert to float. */
6382 uint32_t bits = tvb_get_bits32(tvb, bit_offset, bfwcomphdr_iq_width, ENC_BIG_ENDIAN0x00000000);
6383 float value = decompress_value(bits, bfwcomphdr_comp_meth, bfwcomphdr_iq_width, exponent, NULL((void*)0) /* no ModCompr*/, 0 /* RE */);
6384 /* Add to tree. */
6385 proto_tree_add_float(bfw_tree, hf_oran_bfw_i, tvb, bit_offset/8,
6386 (bfwcomphdr_iq_width+7)/8, value);
6387 bit_offset += bfwcomphdr_iq_width;
6388 proto_item_append_text(bfw_ti, "I=%f ", value);
6389
6390 /* Leave a gap between I and Q values */
6391 proto_item_append_text(bfw_ti, " ");
6392
6393 /* Q value */
6394 /* Get bits, and convert to float. */
6395 bits = tvb_get_bits32(tvb, bit_offset, bfwcomphdr_iq_width, ENC_BIG_ENDIAN0x00000000);
6396 value = decompress_value(bits, bfwcomphdr_comp_meth, bfwcomphdr_iq_width, exponent, NULL((void*)0) /* no ModCompr*/, 0 /* RE */);
6397 /* Add to tree. */
6398 proto_tree_add_float(bfw_tree, hf_oran_bfw_q, tvb, bit_offset/8,
6399 (bfwcomphdr_iq_width+7)/8, value);
6400 bit_offset += bfwcomphdr_iq_width;
6401 proto_item_append_text(bfw_ti, "Q=%f", value);
6402
6403 proto_item_append_text(bfw_ti, ")");
6404 proto_item_set_len(bfw_ti, (bit_offset+7)/8 - bfw_offset);
6405 }
6406 /* Need to round to next byte */
6407 offset = (bit_offset+7)/8;
6408 }
6409 }
6410 break;
6411 }
6412 case 2: /* TDD_CONFIG_PATTERN */
6413 /* reserved (2 bits) */
6414 add_reserved_field(command_tree, hf_oran_reserved_2bits, tvb, offset, 1);
6415 /* dirPattern (14 bits) */
6416 proto_tree_add_item(command_tree, hf_oran_dir_pattern, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6417 offset += 2;
6418
6419 /* reserved (2 bits) */
6420 add_reserved_field(command_tree, hf_oran_reserved_2bits, tvb, offset, 1);
6421 /* guardPattern (14 bits) */
6422 proto_tree_add_item(command_tree, hf_oran_guard_pattern, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6423 offset += 2;
6424 break;
6425
6426 case 3: /* TRX_CONTROL */
6427 {
6428 /* Only allowed cmdScope is ARRAY-COMMAND */
6429 if (cmd_scope != 0) {
6430 expert_add_info(pinfo, command_tree, &ei_oran_trx_control_cmd_scope);
6431 }
6432
6433 /* reserved (2 bits) */
6434 add_reserved_field(command_tree, hf_oran_reserved_2bits, tvb, offset, 1);
6435 /* log2MaskBits (4 bits) */
6436 unsigned log2maskbits;
6437 proto_tree_add_item_ret_uint(command_tree, hf_oran_log2maskbits, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &log2maskbits);
6438 /* sleepMode (2 bits) */
6439 uint32_t sleep_mode;
6440 proto_tree_add_item_ret_uint(command_tree, hf_oran_sleepmode_trx, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &sleep_mode);
6441 offset += 1;
6442
6443 /* reserved (4 bits) */
6444 add_reserved_field(command_tree, hf_oran_reserved_4bits, tvb, offset, 1);
6445 /* numSlotsExt (20 bits) */
6446 uint32_t num_slots_ext;
6447 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);
6448 if (num_slots==0 && num_slots_ext==0) {
6449 proto_item_append_text(num_slots_ext_ti, " (undefined sleep period)");
6450 }
6451 else {
6452 /* Time should be rounded up according to SCS */
6453 float total = (float)(num_slots + num_slots_ext);
6454 /* From table 7.5.2.13-3 */
6455 const float slot_length_by_scs[16] = { 1000, 500, 250, 125, 62.5, 31.25,
6456 0, 0, 0, 0, 0, 0, /* reserved */
6457 1000, 1000, 1000, 1000 };
6458 float slot_length = slot_length_by_scs[scs];
6459 /* Only using valid SCS. TODO: is this test ok? */
6460 if (slot_length != 0) {
6461 /* Round up to next slot */
6462 total = ((int)(total / slot_length) + 1) * slot_length;
6463 proto_item_append_text(num_slots_ext_ti, " (defined sleep period of %f us)", total);
6464 }
6465 }
6466 offset += 3;
6467
6468 /* reserved (2 bits) */
6469 add_reserved_field(command_tree, hf_oran_reserved_2bits, tvb, offset, 1);
6470
6471 /* symbolMask (14 bits) */
6472 uint32_t symbol_mask;
6473 proto_item *sm_ti;
6474 offset = dissect_symbolmask(tvb, command_tree, offset, &symbol_mask, &sm_ti);
6475 if (symbol_mask == 0x0) {
6476 proto_item_append_text(sm_ti, " (wake)");
6477 col_append_str(pinfo->cinfo, COL_INFO, " (wake)");
6478 }
6479 else if (symbol_mask == 0x3fff) {
6480 proto_item_append_text(sm_ti, " (sleep)");
6481 col_append_str(pinfo->cinfo, COL_INFO, " (sleep)");
6482 }
6483 else {
6484 expert_add_info_format(pinfo, sm_ti, &ei_oran_bad_symbolmask,
6485 "For non-zero sleepMode (%u), symbolMask should be 0x0 or 0x3fff - found 0x%05x",
6486 sleep_mode, symbol_mask);
6487 }
6488 offset += 2;
6489
6490 /* antMask (16-2048 bits). Size is lookup from log2MaskBits enum.. */
6491 unsigned antmask_length = 2;
6492 if (log2maskbits >= 4) {
6493 antmask_length = (1 << log2maskbits) / 8;
6494 }
6495 proto_item *ant_mask_ti = proto_tree_add_item(command_tree, hf_oran_antMask_trx_control, tvb, offset, antmask_length, ENC_NA0x00000000);
6496 /* show count */
6497 unsigned antenna_count = 0;
6498 for (unsigned b=0; b < antmask_length; b++) {
6499 uint8_t byte = tvb_get_uint8(tvb, offset+b);
6500 for (unsigned bit=0; bit < 8; bit++) {
6501 if ((1 << bit) & byte) {
6502 antenna_count++;
6503 }
6504 }
6505 }
6506 proto_item_append_text(ant_mask_ti, " (%u antennas)", antenna_count);
6507 offset += antmask_length;
6508
6509 /* Pad to next 4-byte boundary */
6510 offset = WS_ROUNDUP_4(offset)(((offset) + ((unsigned)(4U-1U))) & (~((unsigned)(4U-1U))
))
;
6511 break;
6512 }
6513
6514 case 4: /* ASM (advanced sleep mode) */
6515 /* reserved (2+4=6 bits) */
6516 add_reserved_field(command_tree, hf_oran_reserved_6bits, tvb, offset, 1);
6517 /* sleepMode (2 bits) */
6518 uint32_t sleep_mode;
6519 proto_tree_add_item_ret_uint(command_tree, hf_oran_sleepmode_asm, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &sleep_mode);
6520 offset += 1;
6521
6522 /* reserved (4 bits) */
6523 add_reserved_field(command_tree, hf_oran_reserved_4bits, tvb, offset, 1);
6524 /* numSlotsExt (20 bits) */
6525 proto_tree_add_item(command_tree, hf_oran_num_slots_ext, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6526 offset += 3;
6527
6528 /* reserved (2 bits) */
6529 add_reserved_field(command_tree, hf_oran_reserved_2bits, tvb, offset, 1);
6530 /* symbolMask (14 bits) */
6531 uint32_t symbol_mask;
6532 proto_item *sm_ti;
6533 offset = dissect_symbolmask(tvb, command_tree, offset, &symbol_mask, &sm_ti);
6534 if (symbol_mask == 0x0) {
6535 proto_item_append_text(sm_ti, " (wake)");
6536 col_append_str(pinfo->cinfo, COL_INFO, " (wake)");
6537 }
6538 else if (symbol_mask == 0x3fff) {
6539 proto_item_append_text(sm_ti, " (sleep)");
6540 col_append_str(pinfo->cinfo, COL_INFO, " (sleep)");
6541 }
6542 else {
6543 expert_add_info_format(pinfo, sm_ti, &ei_oran_bad_symbolmask,
6544 "For non-zero sleepMode (%u), symbolMask should be 0x0 or 0x3fff - found 0x%05x",
6545 sleep_mode, symbol_mask);
6546 }
6547 offset += 2;
6548
6549 /* reserved (2 bytes) */
6550 add_reserved_field(command_tree, hf_oran_reserved_16bits, tvb, offset, 2);
6551 offset += 2;
6552 break;
6553
6554 default:
6555 /* Error! */
6556 expert_add_info_format(pinfo, len_ti, &ei_oran_st4_unknown_cmd,
6557 "Dissected ST4 command (%u) not recognised",
6558 st4_cmd_type);
6559 break;
6560 }
6561
6562 /* Check apparent size of padding (0-3 bytes ok) */
6563 long padding_remaining = command_start_offset + (st4_cmd_len * 4) - offset;
6564 if (padding_remaining > 3) {
6565 expert_add_info_format(pinfo, len_ti, &ei_oran_st4_wrong_len_cmd,
6566 "Dissected ST4 command does not match signalled st4CmdLen - set to %u (%u bytes) but dissected %u bytes",
6567 st4_cmd_len, st4_cmd_len*4, offset-command_start_offset);
6568 }
6569
6570 /* Advance by signalled length (needs to be aligned on 4-byte boundary) */
6571 offset = command_start_offset + (st4_cmd_len * 4);
6572
6573 /* Set end of command tree */
6574 proto_item_set_end(command_ti, tvb, offset);
6575
6576 if (ack_nack_req_id != 0 && state && state->ack_nack_requests) {
6577 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
6578 /* Add this request into conversation state on first pass */
6579 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)))
;
6580 request_details->request_frame_number = pinfo->num;
6581 request_details->request_frame_time = pinfo->abs_ts;
6582 request_details->requestType = ST4Cmd1+st4_cmd_type-1;
6583
6584 wmem_tree_insert32(state->ack_nack_requests,
6585 ack_nack_req_id,
6586 request_details);
6587 }
6588 else {
6589 /* On later passes, try to link forward to ST8 response */
6590 ack_nack_request_t *response = wmem_tree_lookup32(state->ack_nack_requests,
6591 ack_nack_req_id);
6592 if (response) {
6593 show_link_to_acknack_response(section_tree, tvb, pinfo, response);
6594 }
6595 }
6596 }
6597 }
6598 }
6599 /* LAA doesn't have sections either.. */
6600 else if (sectionType == SEC_C_LAA) { /* Section Type 7 */
6601 /* 7.2.5 Table 6.4-6 */
6602 unsigned mcot;
6603 proto_item *mcot_ti;
6604
6605 /* laaMsgType */
6606 uint32_t laa_msg_type;
6607 proto_item *laa_msg_type_ti;
6608 laa_msg_type_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_laaMsgType, tvb, offset, 1, ENC_NA0x00000000, &laa_msg_type);
6609 /* laaMsgLen */
6610 uint32_t laa_msg_len;
6611 proto_item *len_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_laaMsgLen, tvb, offset, 1, ENC_NA0x00000000, &laa_msg_len);
6612 proto_item_append_text(len_ti, " (%u bytes)", 4*laa_msg_len);
6613 if (laa_msg_len == 0) {
6614 proto_item_append_text(len_ti, " (reserved)");
6615 }
6616 offset += 1;
6617
6618 int payload_offset = offset;
6619
6620 /* Payload */
6621 switch (laa_msg_type) {
6622 case 0:
6623 /* LBT_PDSCH_REQ */
6624 /* lbtHandle (16 bits) */
6625 proto_tree_add_item(section_tree, hf_oran_lbtHandle, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6626 offset += 2;
6627 /* lbtOffset (10 bits) */
6628 proto_tree_add_item(section_tree, hf_oran_lbtOffset, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6629 offset += 1;
6630 /* lbtMode (2 bits) */
6631 proto_tree_add_bits_item(section_tree, hf_oran_lbtMode, tvb, offset*8+2, 2, ENC_BIG_ENDIAN0x00000000);
6632 /* reserved (1 bit) */
6633 add_reserved_field(section_tree, hf_oran_reserved_bit4, tvb, offset, 1);
6634 /* lbtDeferFactor (3 bits) */
6635 proto_tree_add_item(section_tree, hf_oran_lbtDeferFactor, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6636 offset += 1;
6637 /* lbtBackoffCounter (10 bits) */
6638 proto_tree_add_item(section_tree, hf_oran_lbtBackoffCounter, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6639 offset += 1;
6640 /* MCOT (4 bits) */
6641 mcot_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_MCOT, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &mcot);
6642 if (mcot<1 || mcot>10) {
6643 proto_item_append_text(mcot_ti, " (should be in range 1-10!)");
6644 expert_add_info_format(pinfo, mcot_ti, &ei_oran_mcot_out_of_range,
6645 "MCOT seen with value %u (must be 1-10)", mcot);
6646
6647 }
6648 /* reserved (10 bits) */
6649 proto_tree_add_bits_item(section_tree, hf_oran_reserved, tvb, (offset*8)+6, 10, ENC_BIG_ENDIAN0x00000000);
6650 break;
6651 case 1:
6652 /* LBT_DRS_REQ */
6653 /* lbtHandle (16 bits) */
6654 proto_tree_add_item(section_tree, hf_oran_lbtHandle, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6655 offset += 2;
6656 /* lbtOffset (10 bits) */
6657 proto_tree_add_item(section_tree, hf_oran_lbtOffset, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6658 offset += 1;
6659 /* lbtMode (2 bits) */
6660 proto_tree_add_bits_item(section_tree, hf_oran_lbtMode, tvb, offset*8+2, 2, ENC_BIG_ENDIAN0x00000000);
6661 /* reserved (28 bits) */
6662 proto_tree_add_bits_item(section_tree, hf_oran_reserved, tvb, (offset*8)+4, 28, ENC_BIG_ENDIAN0x00000000);
6663 break;
6664 case 2:
6665 /* LBT_PDSCH_RSP */
6666 /* lbtHandle (16 bits) */
6667 proto_tree_add_item(section_tree, hf_oran_lbtHandle, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6668 offset += 2;
6669 /* lbtPdschRes (2 bits) */
6670 proto_tree_add_item(section_tree, hf_oran_lbtPdschRes, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6671 /* inParSF (1 bit) */
6672 proto_tree_add_item(section_tree, hf_oran_initialPartialSF, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6673 /* sfStatus (1 bit) */
6674 proto_tree_add_item(section_tree, hf_oran_sfStatus, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6675 /* sfnSf (12 bits) */
6676 proto_tree_add_item(section_tree, hf_oran_sfnSfEnd, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6677 offset += 2;
6678 /* reserved (24 bits) */
6679 proto_tree_add_bits_item(section_tree, hf_oran_reserved, tvb, (offset*8), 24, ENC_BIG_ENDIAN0x00000000);
6680 break;
6681 case 3:
6682 /* LBT_DRS_RSP */
6683 /* lbtHandle (16 bits) */
6684 proto_tree_add_item(section_tree, hf_oran_lbtHandle, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6685 offset += 2;
6686 /* lbtDrsRes (1 bit) */
6687 proto_tree_add_item(section_tree, hf_oran_lbtDrsRes, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6688 /* reserved (7 bits) */
6689 add_reserved_field(section_tree, hf_oran_reserved_last_7bits, tvb, offset, 1);
6690 break;
6691 case 4:
6692 /* LBT_Buffer_Error */
6693 /* lbtHandle (16 bits) */
6694 proto_tree_add_item(section_tree, hf_oran_lbtHandle, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6695 offset += 2;
6696 /* lbtBufErr (1 bit) */
6697 proto_tree_add_item(section_tree, hf_oran_lbtBufErr, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6698 /* reserved (7 bits) */
6699 add_reserved_field(section_tree, hf_oran_reserved_last_7bits, tvb, offset, 1);
6700 break;
6701 case 5:
6702 /* LBT_CWCONFIG_REQ */
6703 /* lbtHandle (16 bits) */
6704 proto_tree_add_item(section_tree, hf_oran_lbtHandle, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6705 offset += 2;
6706 /* lbtCWConfig_H (8 bits) */
6707 proto_tree_add_item(section_tree, hf_oran_lbtCWConfig_H, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6708 offset += 1;
6709 /* lbtCWConfig_T (8 bits) */
6710 proto_tree_add_item(section_tree, hf_oran_lbtCWConfig_T, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6711 offset += 1;
6712 /* lbtMode (2 bits) */
6713 proto_tree_add_bits_item(section_tree, hf_oran_lbtMode, tvb, offset*8, 2, ENC_BIG_ENDIAN0x00000000);
6714 /* lbtTrafficClass (3 bits) */
6715 proto_tree_add_item(section_tree, hf_oran_lbtTrafficClass, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6716 /* reserved (19 bits) */
6717 proto_tree_add_bits_item(section_tree, hf_oran_reserved, tvb, (offset*8)+5, 19, ENC_BIG_ENDIAN0x00000000);
6718 break;
6719 case 6:
6720 /* LBT_CWCONFIG_RSP */
6721 /* lbtHandle (16 bits) */
6722 proto_tree_add_item(section_tree, hf_oran_lbtHandle, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6723 offset += 2;
6724 /* lbtCWR_Rst (1 bit) */
6725 proto_tree_add_item(section_tree, hf_oran_lbtCWR_Rst, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6726 /* reserved (7 bits) */
6727 add_reserved_field(section_tree, hf_oran_reserved_last_7bits, tvb, offset, 1);
6728 break;
6729
6730 default:
6731 /* Unhandled! */
6732 expert_add_info_format(pinfo, laa_msg_type_ti, &ei_oran_laa_msg_type_unsupported,
6733 "laaMsgType %u not supported by dissector",
6734 laa_msg_type);
6735
6736 break;
6737 }
6738 /* For now just skip indicated length of bytes */
6739 offset = payload_offset + 4*(laa_msg_len+1);
6740 }
6741
6742
6743 /* Dissect each C section */
6744 for (uint32_t i = 0; i < nSections; ++i) {
6745 tvbuff_t *section_tvb = tvb_new_subset_remaining(tvb, offset);
6746 offset += dissect_oran_c_section(section_tvb, oran_tree, pinfo, state, sectionType, tap_info,
6747 protocol_item,
6748 subframeId, frameId, slotId, startSymbolId,
6749 bit_width, ci_comp_method, ci_comp_opt,
6750 num_sinr_per_prb);
6751 }
6752
6753 /* Expert error if we are short of tvb by > 3 bytes */
6754 if (tvb_reported_length_remaining(tvb, offset) > 3) {
6755 expert_add_info_format(pinfo, protocol_item, &ei_oran_frame_length,
6756 "%u bytes remain at end of frame - should be 0-3",
6757 tvb_reported_length_remaining(tvb, offset));
6758 }
6759
6760 return tvb_captured_length(tvb);
6761}
6762
6763static int dissect_oran_u_re(tvbuff_t *tvb, proto_tree *tree,
6764 unsigned sample_number, int samples_offset,
6765 oran_tap_info *tap_info,
6766 unsigned sample_bit_width,
6767 int comp_meth,
6768 uint32_t exponent,
6769 section_mod_compr_config_t *mod_compr_params,
6770 uint8_t re)
6771{
6772 /* I */
6773 unsigned i_bits = tvb_get_bits32(tvb, samples_offset, sample_bit_width, ENC_BIG_ENDIAN0x00000000);
6774 float i_value = decompress_value(i_bits, comp_meth, sample_bit_width, exponent, mod_compr_params, re);
6775 unsigned sample_len_in_bytes = ((samples_offset%8)+sample_bit_width+7)/8;
6776 proto_item *i_ti = proto_tree_add_float(tree, hf_oran_iSample, tvb, samples_offset/8, sample_len_in_bytes, i_value);
6777 proto_item_set_text(i_ti, "iSample: % 0.7f 0x%04x (RE-%2u in the PRB)", i_value, i_bits, sample_number);
6778 samples_offset += sample_bit_width;
6779 /* Q */
6780 unsigned q_bits = tvb_get_bits32(tvb, samples_offset, sample_bit_width, ENC_BIG_ENDIAN0x00000000);
6781 float q_value = decompress_value(q_bits, comp_meth, sample_bit_width, exponent, mod_compr_params, re);
6782 sample_len_in_bytes = ((samples_offset%8)+sample_bit_width+7)/8;
6783 proto_item *q_ti = proto_tree_add_float(tree, hf_oran_qSample, tvb, samples_offset/8, sample_len_in_bytes, q_value);
6784 proto_item_set_text(q_ti, "qSample: % 0.7f 0x%04x (RE-%2u in the PRB)", q_value, q_bits, sample_number);
6785 samples_offset += sample_bit_width;
6786
6787 /* Update RE stats */
6788 tap_info->num_res++;
6789 /* if (i_value == 0.0 && q_value == 0.0) { */
6790 /* TODO: is just checking bits from frame good enough - assuming this always corresponds to a zero value? */
6791 if (i_bits == 0 && q_bits == 0) {
6792 tap_info->num_res_zero++;
6793 }
6794 else {
6795 tap_info->non_zero_re_in_current_prb = true1;
6796 }
6797 return samples_offset;
6798}
6799
6800
6801static bool_Bool udcomplen_appears_present(bool_Bool udcomphdr_present, tvbuff_t *tvb, int offset)
6802{
6803 if (!udcomplen_heuristic_result_set) {
6804 /* All sections will start the same way */
6805 unsigned int section_bytes_before_field = (udcomphdr_present) ? 6 : 4;
6806
6807 /* Move offset back to the start of the section */
6808 offset -= section_bytes_before_field;
6809
6810 do {
6811 /* This field appears several bytes into the U-plane section */
6812 uint32_t length_remaining = tvb_reported_length_remaining(tvb, offset);
6813 /* Are there enough bytes to still read the length field? */
6814 if (section_bytes_before_field+2 > length_remaining) {
6815 udcomplen_heuristic_result = false0;
6816 udcomplen_heuristic_result_set = true1;
6817 break;
6818 }
6819
6820 /* Read the length field */
6821 uint16_t udcomplen = tvb_get_ntohs(tvb, offset+section_bytes_before_field);
6822
6823 /* Is this less than a valid section? Realistic minimal section will be bigger than this..
6824 * Could take into account numPrbU, etc */
6825 if (udcomplen < section_bytes_before_field+2) {
6826 udcomplen_heuristic_result = false0;
6827 udcomplen_heuristic_result_set = true1;
6828 break;
6829 }
6830
6831 /* Does this section fit into the frame? */
6832 if (udcomplen > length_remaining) {
6833 udcomplen_heuristic_result = false0;
6834 udcomplen_heuristic_result_set = true1;
6835 break;
6836 }
6837
6838 /* Move past this section */
6839 offset += udcomplen;
6840
6841 /* Are we at the end of the frame? */
6842 /* TODO: if frame is less than 60 bytes, there may be > 4 bytes, likely zeros.. */
6843 if (tvb_reported_length_remaining(tvb, offset) < 4) {
6844 udcomplen_heuristic_result = true1;
6845 udcomplen_heuristic_result_set = true1;
6846 }
6847 } while (!udcomplen_heuristic_result_set);
6848 }
6849 return udcomplen_heuristic_result;
6850}
6851
6852static bool_Bool at_udcomphdr(tvbuff_t *tvb, int offset)
6853{
6854 if (tvb_captured_length_remaining(tvb, offset) < 2) {
6855 return false0;
6856 }
6857 uint8_t first_byte = tvb_get_uint8(tvb, offset);
6858 uint8_t reserved_byte = tvb_get_uint8(tvb, offset+1);
6859
6860 /* - iq width could be anything, though unlikely to be signalled as (say) < 1-3? */
6861 /* - meth should be 0-8 */
6862 /* - reserved byte should be 0 */
6863 return (((first_byte & 0x0f) <= MOD_COMPR_AND_SELECTIVE_RE_WITH_MASKS8) && (reserved_byte == 0));
6864}
6865
6866static bool_Bool udcomphdr_appears_present(flow_state_t *flow, uint32_t direction, tvbuff_t *tvb, int offset)
6867{
6868 /* Should really not happen, but guard against this anyway. */
6869 if (flow == NULL((void*)0)) {
6870 /* No state to update. */
6871 return false0;
6872 }
6873
6874 if (direction == DIR_UPLINK0) {
6875 if (flow->udcomphdrUplink_heuristic_result_set) {
6876 /* Return cached value */
6877 return flow->udcomphdrUplink_heuristic_result;
6878 }
6879 else {
6880 /* Work it out, and save answer for next time */
6881 flow->udcomphdrUplink_heuristic_result_set = true1;
6882 flow->udcomphdrUplink_heuristic_result = at_udcomphdr(tvb, offset);
6883 return flow->udcomphdrUplink_heuristic_result;
6884 }
6885 }
6886 else {
6887 /* Downlink */
6888 if (flow->udcomphdrDownlink_heuristic_result_set) {
6889 /* Return cached value */
6890 return flow->udcomphdrDownlink_heuristic_result;
6891 }
6892 else {
6893 /* Work it out, and save answer for next time */
6894 flow->udcomphdrDownlink_heuristic_result_set = true1;
6895 flow->udcomphdrDownlink_heuristic_result = at_udcomphdr(tvb, offset);
6896 return flow->udcomphdrDownlink_heuristic_result;
6897 }
6898 }
6899}
6900
6901bool_Bool copy_section_entry(const void *key, void* value, void *userdata)
6902{
6903 /* Cast parameters to their types */
6904 uint32_t sectionId = GPOINTER_TO_UINT(key)((guint) (gulong) (key));
6905 expected_section_data_t *result_value = (expected_section_data_t *)value;
6906 wmem_tree_t *result_tree = (wmem_tree_t*)userdata;
6907
6908 /* Deep copy of section data */
6909 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)))
;
6910 *copy = *result_value;
6911
6912 /* Add into result tree */
6913 wmem_tree_insert32(result_tree, sectionId, copy);
6914
6915 return false0;
6916}
6917
6918/* User plane dissector (section 8) */
6919static int
6920dissect_oran_u(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
6921 oran_tap_info *tap_info, void *data _U___attribute__((unused)))
6922{
6923 /* Hidden filter for plane */
6924 proto_item *plane_ti = proto_tree_add_item(tree, hf_oran_uplane, tvb, 0, 0, ENC_NA0x00000000);
6925 PROTO_ITEM_SET_HIDDEN(plane_ti)proto_item_set_hidden((plane_ti));
6926
6927 /* Set up structures needed to add the protocol subtree and manage it */
6928 unsigned offset = 0;
6929
6930 col_set_str(pinfo->cinfo, COL_PROTOCOL, "O-RAN-FH-U");
6931 col_set_str(pinfo->cinfo, COL_INFO, "U-Plane");
6932
6933 tap_info->userplane = true1;
6934
6935 /* Create display subtree for the protocol */
6936 proto_item *protocol_item = proto_tree_add_item(tree, proto_oran, tvb, 0, -1, ENC_NA0x00000000);
6937 proto_item_append_text(protocol_item, "-U");
6938 proto_tree *oran_tree = proto_item_add_subtree(protocol_item, ett_oran);
6939
6940 /* Transport header */
6941 /* Real-time control data / IQ data transfer message series identifier */
6942 uint16_t eAxC;
6943 addPcOrRtcid(tvb, oran_tree, &offset, hf_oran_ecpri_pcid, &eAxC, tap_info);
6944 tap_info->eaxc = eAxC;
6945
6946 /* Update/report status of conversation */
6947 uint32_t key = make_flow_key(pinfo, eAxC, ORAN_U_PLANE1, false0);
6948 flow_state_t* state = (flow_state_t*)wmem_tree_lookup32(flow_states_table, key);
6949
6950 flow_result_t *result = NULL((void*)0);
6951
6952 /* Message identifier */
6953 proto_item *seqIdItem;
6954 uint32_t seqId, subSeqId, e;
6955 offset = addSeqid(tvb, oran_tree, offset, ORAN_U_PLANE1, &seqId, &seqIdItem, pinfo, &subSeqId, &e);
6956
6957 /* Common header for time reference */
6958 proto_item *timingHeader = proto_tree_add_string_format(oran_tree, hf_oran_timing_header,
6959 tvb, offset, 4, "", "Timing Header (");
6960 proto_tree *timing_header_tree = proto_item_add_subtree(timingHeader, ett_oran_u_timing);
6961
6962 /* dataDirection */
6963 uint32_t direction;
6964 proto_tree_add_item_ret_uint(timing_header_tree, hf_oran_data_direction, tvb, offset, 1, ENC_NA0x00000000, &direction);
6965 tap_info->uplink = (direction==0);
1
Assuming 'direction' is not equal to 0
6966 /* payloadVersion */
6967 dissect_payload_version(timing_header_tree, tvb, pinfo, offset);
6968 /* filterIndex */
6969 proto_tree_add_item(timing_header_tree, hf_oran_filter_index, tvb, offset, 1, ENC_NA0x00000000);
6970 offset += 1;
6971
6972 int ref_a_offset = offset;
6973
6974 /* frameId */
6975 uint32_t frameId = 0;
6976 proto_tree_add_item_ret_uint(timing_header_tree, hf_oran_frame_id, tvb, offset, 1, ENC_NA0x00000000, &frameId);
6977 tap_info->frame = frameId;
6978 offset += 1;
6979
6980 /* subframeId */
6981 uint32_t subframeId = 0;
6982 proto_tree_add_item_ret_uint(timing_header_tree, hf_oran_subframe_id, tvb, offset, 1, ENC_NA0x00000000, &subframeId);
6983 /* slotId */
6984 uint32_t slotId = 0;
6985 proto_tree_add_item_ret_uint(timing_header_tree, hf_oran_slot_id, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &slotId);
6986 tap_info->slot = slotId;
6987 offset++;
6988 /* symbolId */
6989 uint32_t symbolId = 0;
6990 proto_tree_add_item_ret_uint(timing_header_tree, hf_oran_symbolId, tvb, offset, 1, ENC_NA0x00000000, &symbolId);
6991 offset++;
6992
6993 char id[16];
6994 snprintf(id, 16, "%u-%u-%u-%u", frameId, subframeId, slotId, symbolId);
6995 proto_item *pi = proto_tree_add_string(timing_header_tree, hf_oran_refa, tvb, ref_a_offset, 3, id);
6996 proto_item_set_generated(pi);
6997
6998 proto_item_append_text(timingHeader, "%s, frameId: %d, subframeId: %d, slotId: %d, symbolId: %d)",
6999 val_to_str_const(direction, data_direction_vals, "Unknown"), frameId, subframeId, slotId, symbolId);
7000
7001 unsigned sample_bit_width;
7002 unsigned compression;
7003 int includeUdCompHeader;
7004
7005 /* Also look up C-PLANE state (sent in opposite direction) so may check current compression settings */
7006 uint32_t cplane_key = make_flow_key(pinfo, eAxC, ORAN_C_PLANE0, true1);
7007 flow_state_t* cplane_state = (flow_state_t*)wmem_tree_lookup32(flow_states_table, cplane_key);
7008 uint32_t cplane_samedir_key = make_flow_key(pinfo, eAxC, ORAN_C_PLANE0, false0);
7009 flow_state_t* cplane_samedir_state = (flow_state_t*)wmem_tree_lookup32(flow_states_table, cplane_samedir_key);
7010
7011
7012 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
2
Assuming field 'visited' is not equal to 0
3
Taking false branch
7013 /* Create state/conversation if doesn't exist yet */
7014 if (!state) {
7015 /* Allocate new state */
7016 state = wmem_new0(wmem_file_scope(), flow_state_t)((flow_state_t*)wmem_alloc0((wmem_file_scope()), sizeof(flow_state_t
)))
;
7017 state->ack_nack_requests = wmem_tree_new(wmem_file_scope());
7018 wmem_tree_insert32(flow_states_table, key, state);
7019 }
7020
7021 result = wmem_new0(wmem_file_scope(), flow_result_t)((flow_result_t*)wmem_alloc0((wmem_file_scope()), sizeof(flow_result_t
)))
;
7022 result->expected_dl_sections = wmem_tree_new(wmem_file_scope());
7023 wmem_tree_insert32(flow_results_table, pinfo->num, result);
7024
7025 /* Check sequence analysis status (but not if later part of radio layer fragmentation) */
7026 if (state->last_frame_seen[direction] && (subSeqId==0) && (seqId != state->next_expected_sequence_number[direction])) {
7027 /* Store this result */
7028 result->unexpected_seq_number = true1;
7029 result->expected_sequence_number = state->next_expected_sequence_number[direction];
7030 result->previous_frame = state->last_frame[direction];
7031 }
7032 /* Update sequence analysis state */
7033 state->last_frame[direction] = pinfo->num;
7034 state->last_frame_seen[direction] = true1;
7035 state->next_expected_sequence_number[direction] = (seqId+1) % 256;
7036 }
7037
7038 /* Show any issues associated with this frame number */
7039 result = wmem_tree_lookup32(flow_results_table, pinfo->num);
4
Value assigned to 'result'
7040 if (result) {
5
Assuming 'result' is null
7041 if (result->unexpected_seq_number) {
7042 expert_add_info_format(pinfo, seqIdItem,
7043 (direction == DIR_UPLINK0) ?
7044 &ei_oran_uplane_unexpected_sequence_number_ul :
7045 &ei_oran_uplane_unexpected_sequence_number_dl,
7046 "Sequence number %u expected, but got %u",
7047 result->expected_sequence_number, seqId);
7048 tap_info->missing_sns = (256 + seqId - result->expected_sequence_number) % 256;
7049 /* TODO: could add previous/next frame (in seqId tree?) ? */
7050 }
7051 }
7052
7053 /* Checking UL timing within current slot. Disabled if limit set to 0. */
7054 /* N.B., timing is relative to first seen frame,
7055 not some notion of the beginning of the slot from sync, offset by some timing.. */
7056 if (direction
5.1
'direction' is not equal to DIR_UPLINK
== DIR_UPLINK0 && us_allowed_for_ul_in_symbol > 0) {
7057 uint32_t timing_key = get_timing_key(frameId, subframeId, slotId, symbolId);
7058 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
7059 /* Set state on first pass */
7060 ul_timing_for_slot* timing = (ul_timing_for_slot*)wmem_tree_lookup32(ul_symbol_timing, timing_key);
7061 if (!timing) {
7062 /* Allocate new state */
7063 timing = wmem_new0(wmem_file_scope(), ul_timing_for_slot)((ul_timing_for_slot*)wmem_alloc0((wmem_file_scope()), sizeof
(ul_timing_for_slot)))
;
7064 timing->first_frame = pinfo->num;
7065 timing->first_frame_time = pinfo->abs_ts;
7066 timing->frames_seen_in_symbol = 1;
7067 timing->last_frame_in_symbol = pinfo->num;
7068 wmem_tree_insert32(ul_symbol_timing, timing_key, timing);
7069 }
7070 else {
7071 /* Update existing state */
7072 timing->frames_seen_in_symbol++;
7073 timing->last_frame_in_symbol = pinfo->num;
7074 }
7075 }
7076 else {
7077 /* Subsequent passes - look up result */
7078 ul_timing_for_slot* timing = (ul_timing_for_slot*)wmem_tree_lookup32(ul_symbol_timing, timing_key);
7079 if (timing) { /* Really shouldn't fail! */
7080 if (timing->frames_seen_in_symbol > 1) {
7081 /* Work out gap between frames (in microseconds) back to frame carrying first seen symbol */
7082 int seconds_between_packets = (int)
7083 (pinfo->abs_ts.secs - timing->first_frame_time.secs);
7084 int nseconds_between_packets =
7085 pinfo->abs_ts.nsecs - timing->first_frame_time.nsecs;
7086
7087
7088 /* Round to nearest microsecond. */
7089 uint32_t total_gap = (seconds_between_packets*1000000) +
7090 ((nseconds_between_packets+500) / 1000);
7091
7092 /* Show how long it has been */
7093 proto_item *ti = NULL((void*)0);
7094 if (pinfo->num != timing->first_frame) {
7095 ti = proto_tree_add_uint(timingHeader, hf_oran_u_section_ul_symbol_time, tvb, 0, 0, total_gap);
7096 proto_item_set_generated(ti);
7097 }
7098
7099 if (total_gap > us_allowed_for_ul_in_symbol) {
7100 expert_add_info_format(pinfo, ti, &ei_oran_ul_uplane_symbol_too_long,
7101 "UL U-Plane Tx took longer (%u us) than limit set in preferences (%u us)",
7102 total_gap, us_allowed_for_ul_in_symbol);
7103 proto_item_append_text(timingHeader, " (%uus since first frame seen for symbol)", total_gap);
7104 }
7105
7106 /* Show how many frames were received */
7107 ti = proto_tree_add_uint(timingHeader, hf_oran_u_section_ul_symbol_frames, tvb, 0, 0, timing->frames_seen_in_symbol);
7108 proto_item_set_generated(ti);
7109
7110 /* Link to first frame for this symbol */
7111 if (pinfo->num != timing->first_frame) {
7112 ti = proto_tree_add_uint(timingHeader, hf_oran_u_section_ul_symbol_first_frame, tvb, 0, 0, timing->first_frame);
7113 proto_item_set_generated(ti);
7114 }
7115
7116 /* And also last frame */
7117 if (pinfo->num != timing->last_frame_in_symbol) {
7118 ti = proto_tree_add_uint(timingHeader, hf_oran_u_section_ul_symbol_last_frame, tvb, 0, 0, timing->last_frame_in_symbol);
7119 proto_item_set_generated(ti);
7120 }
7121
7122 tap_info->ul_delay_in_us = total_gap;
7123 }
7124 }
7125 }
7126 }
7127
7128
7129 /* Look up preferences for samples */
7130 if (direction
5.2
'direction' is not equal to DIR_UPLINK
== DIR_UPLINK0) {
6
Taking false branch
7131 sample_bit_width = pref_sample_bit_width_uplink;
7132 compression = pref_iqCompressionUplink;
7133 includeUdCompHeader = pref_includeUdCompHeaderUplink;
7134 } else {
7135 sample_bit_width = pref_sample_bit_width_downlink;
7136 compression = pref_iqCompressionDownlink;
7137 includeUdCompHeader = pref_includeUdCompHeaderDownlink;
7138 }
7139
7140 /* If uplink, load any udCompHdr settings written by C-Plane */
7141 bool_Bool ud_cmp_hdr_cplane = false0;
7142 if (cplane_state && direction == 0) {
7
Assuming 'cplane_state' is null
7143 /* Initialise settings from udpCompHdr from C-Plane */
7144 if (cplane_state->ul_ud_comp_hdr_set && !pref_override_ul_compression) {
7145 sample_bit_width = cplane_state->ul_ud_comp_hdr_bit_width;
7146 compression = cplane_state->ul_ud_comp_hdr_compression;
7147 ud_cmp_hdr_cplane = true1;
7148 }
7149 }
7150
7151 /* Need a valid value (e.g. 9, 14). 0 definitely won't work, as won't progress around loop! */
7152 /* N.B. may yet be overwritten by udCompHdr settings in sections below! */
7153 if (sample_bit_width == 0) {
8
Assuming 'sample_bit_width' is not equal to 0
9
Taking false branch
7154 expert_add_info_format(pinfo, protocol_item, &ei_oran_invalid_sample_bit_width,
7155 "%cL Sample bit width from %s (%u) not valid, so can't decode sections",
7156 (direction == DIR_UPLINK0) ? 'U' : 'D',
7157 !ud_cmp_hdr_cplane ? "preference" : "C-Plane",
7158 sample_bit_width);
7159 return offset;
7160 }
7161
7162 unsigned bytesLeft;
7163 unsigned number_of_sections = 0;
7164 unsigned nBytesPerPrb =0;
7165
7166
7167 if (link_planes_together && !PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited) && cplane_samedir_state) {
10
Assuming 'link_planes_together' is false
7168 /* Take a deep-copy of this state on first pass */
7169 wmem_tree_foreach(cplane_samedir_state->expected_dl_sections, copy_section_entry, result->expected_dl_sections);
7170 }
7171
7172 /* Add each section (not from count, just keep parsing until payload used) */
7173 do {
7174 /* Section subtree */
7175 unsigned section_start_offset = offset;
7176 proto_item *sectionHeading = proto_tree_add_string_format(oran_tree, hf_oran_u_section,
7177 tvb, offset, 0, "", "Section");
7178 proto_tree *section_tree = proto_item_add_subtree(sectionHeading, ett_oran_u_section);
7179
7180 /* Section Header fields (darker green part) */
7181
7182 /* sectionId */
7183 uint32_t sectionId = 0;
7184 proto_item *ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_section_id, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &sectionId);
7185 if (sectionId == 4095) {
11
Assuming 'sectionId' is not equal to 4095
12
Taking false branch
7186 proto_item_append_text(ti, " (not default coupling C/U planes using sectionId)");
7187 }
7188 offset++;
7189
7190 if (tap_info->num_section_ids < MAX_SECTION_IDs32) {
13
Assuming field 'num_section_ids' is >= MAX_SECTION_IDs
14
Taking false branch
7191 tap_info->section_ids[tap_info->num_section_ids++] = sectionId;
7192 }
7193
7194 section_details_t *section_details = NULL((void*)0);
7195
7196 /* For DL, lookup corresponding C-plane frame/info */
7197 if (link_planes_together && direction == 1) {
15
Assuming 'link_planes_together' is true
16
Assuming 'direction' is equal to 1
17
Taking true branch
7198 if (cplane_samedir_state != NULL((void*)0)) {
18
Assuming 'cplane_samedir_state' is not equal to NULL
19
Taking true branch
7199
7200 expected_section_data_t *section_data = NULL((void*)0);
7201 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')
7202
7203 if (section_data) {
7204 /* Need to work out which of 2 entries is in use for this data frame */
7205 unsigned index_to_use = 0;
7206
7207 /* Does the first entry match the timing for this frame? */
7208 if (section_data->details[0].frame == frameId &&
7209 section_data->details[0].subframe == subframeId &&
7210 section_data->details[0].slot == slotId &&
7211 /* Check that symbolId is in range */
7212 section_data->details[0].startSymbol <= symbolId &&
7213 (unsigned)(section_data->details[0].startSymbol + section_data->details[0].numSymbols) <= (unsigned)symbolId) {
7214
7215 index_to_use = 0;
7216 }
7217 else if (section_data->details[1].frame == frameId &&
7218 section_data->details[1].subframe == subframeId &&
7219 section_data->details[1].slot == slotId &&
7220 /* Check that symbolId is in range */
7221 section_data->details[1].startSymbol <= symbolId &&
7222 (unsigned)(section_data->details[1].startSymbol + section_data->details[1].numSymbols) <= (unsigned)symbolId) {
7223
7224 index_to_use = 1;
7225 }
7226 else {
7227 /* TODO: expert info warning? */
7228 }
7229
7230 section_details = &section_data->details[index_to_use];
7231
7232 /* Cplane frame number */
7233 proto_item *cplane_frame_ti = proto_tree_add_uint(section_tree, hf_oran_corresponding_cplane_frame, tvb, 0, 0,
7234 section_details->frame_number);
7235 proto_item_set_generated(cplane_frame_ti);
7236
7237 /* usecs since cplane frame */
7238 time_t total_gap = 0;
7239
7240 if ((pinfo->abs_ts.secs == section_details->frame_time.secs) || (pinfo->abs_ts.secs == section_details->frame_time.secs+1)) {
7241 total_gap = ((pinfo->abs_ts.secs - section_details->frame_time.secs) * 1000000) +
7242 ((pinfo->abs_ts.nsecs - section_details->frame_time.nsecs)/1000);
7243 }
7244
7245 if (total_gap > 0) {
7246 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);
7247 proto_item_set_generated(cplane_delta_ti);
7248 }
7249 }
7250 }
7251
7252 }
7253
7254 /* rb */
7255 uint32_t rb;
7256 proto_tree_add_item_ret_uint(section_tree, hf_oran_rb, tvb, offset, 1, ENC_NA0x00000000, &rb);
7257 /* symInc. "use of symInc=1 shall be prohibited in the U-plane" */
7258 uint8_t syminc;
7259 proto_item *syminc_ti = proto_tree_add_item_ret_uint8(section_tree, hf_oran_symInc, tvb, offset, 1, ENC_NA0x00000000, &syminc);
7260 if (syminc) {
7261 expert_add_info(NULL((void*)0), syminc_ti, &ei_oran_syminc_set_for_uplane);
7262 }
7263 /* startPrbu */
7264 uint32_t startPrbu = 0;
7265 proto_tree_add_item_ret_uint(section_tree, hf_oran_startPrbu, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &startPrbu);
7266 offset += 2;
7267
7268 /* numPrbu */
7269 uint32_t numPrbu = 0;
7270 proto_tree_add_item_ret_uint(section_tree, hf_oran_numPrbu, tvb, offset, 1, ENC_NA0x00000000, &numPrbu);
7271 offset += 1;
7272
7273 proto_item *ud_comp_meth_item, *ud_comp_len_ti=NULL((void*)0);
7274 uint32_t ud_comp_len = 0;
7275
7276 /* udCompHdr (if preferences indicate will be present) */
7277 bool_Bool included = (includeUdCompHeader==1) || /* 1 means present.. */
7278 (includeUdCompHeader==2 && udcomphdr_appears_present(state, direction, tvb, offset));
7279 if (included) {
7280 /* 7.5.2.10 */
7281 /* Extract these values to inform how wide IQ samples in each PRB will be. */
7282 offset = dissect_udcomphdr(tvb, pinfo, section_tree, offset, false0, direction == 0, &sample_bit_width,
7283 &compression, &ud_comp_meth_item, tap_info);
7284
7285 /* Not part of udCompHdr */
7286 uint32_t reserved;
7287 proto_item *res_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_reserved_8bits, tvb, offset, 1, ENC_NA0x00000000, &reserved);
7288 offset += 1;
7289 if (reserved != 0) {
7290 expert_add_info_format(pinfo, res_ti, &ei_oran_reserved_not_zero,
7291 "reserved field (0x%x) not zero - perhaps udCompHdr is not really present?",
7292 reserved);
7293 }
7294 }
7295 else {
7296 /* No fields to dissect - just showing comp values from prefs */
7297 /* iqWidth */
7298 proto_item *iq_width_item = proto_tree_add_uint(section_tree, hf_oran_udCompHdrIqWidth_pref, tvb, 0, 0, sample_bit_width);
7299 proto_item_append_text(iq_width_item, (ud_cmp_hdr_cplane) ? " (from c-plane)" : " (from preferences)");
7300 proto_item_set_generated(iq_width_item);
7301
7302 /* udCompMethod */
7303 ud_comp_meth_item = proto_tree_add_uint(section_tree, hf_oran_udCompHdrMeth_pref, tvb, 0, 0, compression);
7304 proto_item_append_text(ud_comp_meth_item, (ud_cmp_hdr_cplane) ? " (from c-plane)" : " (from preferences)");
7305 proto_item_set_generated(ud_comp_meth_item);
7306
7307 /* Point back to C-Plane, if used */
7308 /* TODO: doesn't work with multiple port mappings using SE10.. */
7309 if (ud_cmp_hdr_cplane) {
7310 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);
7311 proto_item_set_generated(cplane_ti);
7312 }
7313
7314 tap_info->compression_methods |= (1 << compression);
7315 tap_info->compression_width = sample_bit_width;
7316 }
7317
7318 /* Consider fragmentation after first section header */
7319 if (do_radio_transport_layer_reassembly && (number_of_sections == 0) && (e !=1 || subSeqId!= 0)) {
7320
7321 /* Set fragmented flag. */
7322 bool_Bool save_fragmented = pinfo->fragmented;
7323 pinfo->fragmented = true1;
7324 fragment_head *fh;
7325 unsigned frag_data_len = tvb_reported_length_remaining(tvb, offset);
7326
7327 /* Add this fragment into reassembly table */
7328 uint32_t reassembly_id = make_reassembly_id(seqId, direction, eAxC,
7329 frameId, subframeId, slotId, symbolId);
7330 fh = fragment_add_seq(&oran_reassembly_table, tvb, offset, pinfo,
7331 reassembly_id, /* id */
7332 GUINT_TO_POINTER(reassembly_id)((gpointer) (gulong) (reassembly_id)), /* data */
7333 subSeqId, /* frag_number */
7334 frag_data_len, /* frag_data_len */
7335 !e, /* more_frags */
7336 0);
7337
7338 bool_Bool update_col_info = true1;
7339
7340 /* See if this completes an SDU */
7341 tvbuff_t *original_tvb = tvb;
7342 tvbuff_t *next_tvb = process_reassembled_data(tvb, offset, pinfo, "Reassembled O-RAN FH CUS Payload",
7343 fh, &oran_frag_items,
7344 &update_col_info, oran_tree);
7345 if (next_tvb) {
7346 /* Have reassembled data */
7347 proto_tree_add_item(oran_tree, hf_oran_payload, next_tvb, 0, -1, ENC_NA0x00000000);
7348 col_append_fstr(pinfo->cinfo, COL_INFO, " Reassembled Data (%u bytes)", tvb_reported_length(next_tvb));
7349 /* Dissection should resume at start of reassembled tvb */
7350 offset = 0;
7351 }
7352 /* Will continue with either reassembled tvb or NULL */
7353 tvb = next_tvb;
7354
7355 /* Restore fragmented flag */
7356 pinfo->fragmented = save_fragmented;
7357
7358 /* Don't dissect any more if not complete yet.. */
7359 if (tvb == NULL((void*)0)) {
7360 return tvb_captured_length(original_tvb);
7361 }
7362 }
7363
7364
7365 /* Not supported! TODO: other places where comp method is looked up (e.g., bfw?) */
7366 switch (compression) {
7367 case COMP_NONE0:
7368 case COMP_BLOCK_FP1:
7369 case BFP_AND_SELECTIVE_RE5:
7370 case COMP_MODULATION4:
7371 case MOD_COMPR_AND_SELECTIVE_RE6:
7372 break;
7373 default:
7374 expert_add_info_format(pinfo, ud_comp_meth_item, &ei_oran_unsupported_compression_method,
7375 "Compression method %u (%s) not supported by dissector",
7376 compression,
7377 rval_to_str_const(compression, ud_comp_header_meth, "reserved"));
7378 }
7379
7380 /* udCompLen (when supported, methods 5,6,7,8) */
7381 if (compression >= BFP_AND_SELECTIVE_RE5) {
7382 bool_Bool supported = (pref_support_udcompLen==1) || /* supported */
7383 (pref_support_udcompLen==2 && udcomplen_appears_present(includeUdCompHeader, tvb, offset));
7384
7385 if (supported) {
7386 ud_comp_len_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_udCompLen, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &ud_comp_len);
7387 if (ud_comp_len <= 1) {
7388 proto_item_append_text(ud_comp_len_ti, " (reserved)");
7389 }
7390 /* TODO: report if less than a viable section in frame? */
7391 /* Check that there is this much length left in the frame */
7392 if (ud_comp_len > tvb_reported_length_remaining(tvb, section_start_offset)) {
7393 expert_add_info_format(pinfo, ud_comp_len_ti, &ei_oran_ud_comp_len_wrong_size,
7394 "udCompLen indicates %u bytes in section, but only %u are left in frame",
7395 ud_comp_len, tvb_reported_length_remaining(tvb, section_start_offset));
7396 }
7397 /* Actual length of section will be checked below, at the end of the section */
7398 offset += 2;
7399 }
7400 }
7401
7402 /* sReSMask1 + sReSMask2 (depends upon compression method) */
7403 uint64_t sresmask1=0, sresmask2=0;
7404 if (compression == BFP_AND_SELECTIVE_RE_WITH_MASKS7 ||
7405 compression == MOD_COMPR_AND_SELECTIVE_RE_WITH_MASKS8)
7406 {
7407 static int * const sres_mask1_2_flags[] = {
7408 &hf_oran_sReSMask1_2_re12,
7409 &hf_oran_sReSMask1_2_re11,
7410 &hf_oran_sReSMask1_2_re10,
7411 &hf_oran_sReSMask1_2_re9,
7412 &hf_oran_sReSMask_re8,
7413 &hf_oran_sReSMask_re7,
7414 &hf_oran_sReSMask_re6,
7415 &hf_oran_sReSMask_re5,
7416 &hf_oran_sReSMask_re4,
7417 &hf_oran_sReSMask_re3,
7418 &hf_oran_sReSMask_re2,
7419 &hf_oran_sReSMask_re1,
7420 NULL((void*)0)
7421 };
7422
7423 /* reserved (4 bits) */
7424 add_reserved_field(section_tree, hf_oran_reserved_4bits, tvb, offset, 1);
7425 /* sReSMask1 (12 bits) */
7426 proto_item *sresmask_ti;
7427 sresmask_ti = proto_tree_add_bitmask_ret_uint64(section_tree, tvb, offset,
7428 hf_oran_sReSMask1,
7429 ett_oran_sresmask,
7430 sres_mask1_2_flags,
7431 ENC_NA0x00000000,
7432 &sresmask1);
7433 offset += 2;
7434 /* Count REs present */
7435 unsigned res = 0;
7436 for (unsigned n=0; n < 12; n++) {
7437 if ((sresmask1 >> n) & 0x1) {
7438 res++;
7439 }
7440 }
7441 proto_item_append_text(sresmask_ti, " (%u REs)", res);
7442
7443
7444 /* reserved (4 bits) */
7445 add_reserved_field(section_tree, hf_oran_reserved_4bits, tvb, offset, 1);
7446 /* sReSMask2 (12 bits) */
7447 sresmask_ti = proto_tree_add_bitmask_ret_uint64(section_tree, tvb, offset,
7448 hf_oran_sReSMask2,
7449 ett_oran_sresmask,
7450 sres_mask1_2_flags,
7451 ENC_NA0x00000000,
7452 &sresmask2);
7453 offset += 2;
7454
7455 if (rb == 1) {
7456 proto_item_append_text(sresmask_ti, " (ignored)");
7457 if (sresmask2 != 0) {
7458 expert_add_info(pinfo, ud_comp_len_ti, &ei_oran_sresmask2_not_zero_with_rb);
7459 }
7460 }
7461 else {
7462 /* Count REs present */
7463 res = 0;
7464 for (unsigned n=0; n < 12; n++) {
7465 if ((sresmask2 >> n) & 0x1) {
7466 res++;
7467 }
7468 }
7469 proto_item_append_text(sresmask_ti, " (%u REs)", res);
7470 }
7471 }
7472
7473 write_section_info(sectionHeading, pinfo, protocol_item, sectionId, startPrbu, numPrbu, rb);
7474
7475 /* TODO: should this use the same pref as c-plane? */
7476 if (numPrbu == 0) {
7477 /* Special case for all PRBs (NR: the total number of PRBs may be > 255) */
7478 numPrbu = pref_data_plane_section_total_rbs;
7479 startPrbu = 0; /* may already be 0... */
7480 }
7481
7482 section_mod_compr_config_t* mod_compr_config = get_mod_compr_section_to_read(cplane_samedir_state, sectionId);
7483
7484 /* Add each PRB */
7485 for (unsigned i = 0; i < numPrbu; i++) {
7486 /* Create subtree */
7487 proto_item *prbHeading = proto_tree_add_string_format(section_tree, hf_oran_samples_prb,
7488 tvb, offset, 0,
7489 "", "PRB");
7490 proto_tree *rb_tree = proto_item_add_subtree(prbHeading, ett_oran_u_prb);
7491 uint32_t exponent = 0;
7492 uint16_t sresmask = 0;
7493
7494 /* udCompParam (depends upon compression method) */
7495 int before = offset;
7496 offset = dissect_udcompparam(tvb, pinfo, rb_tree, offset, compression, &exponent, &sresmask, false0);
7497 int udcompparam_len = offset-before;
7498
7499 /* Show PRB number in root */
7500 proto_item_append_text(prbHeading, " %3u", startPrbu + i*(1+rb));
7501
7502 /* Work out how many REs / PRB */
7503 unsigned res_per_prb = 12;
7504 uint16_t sresmask_to_use = 0x0fff;
7505
7506 if (compression >= BFP_AND_SELECTIVE_RE5) {
7507 /* Work out which mask should be used */
7508 if (compression==BFP_AND_SELECTIVE_RE5 || compression==MOD_COMPR_AND_SELECTIVE_RE6) {
7509 /* Selective RE cases, use value from compModParam */
7510 sresmask_to_use = (uint16_t)sresmask;
7511 }
7512 else {
7513 /* With masks (in section). Choose between sresmask1 and sresmask2 */
7514 if (rb==1 || (i%2)==0) {
7515 /* Even values */
7516 sresmask_to_use = (uint16_t)sresmask1;
7517 }
7518 else {
7519 /* Odd values */
7520 sresmask_to_use = (uint16_t)sresmask2;
7521 }
7522 }
7523
7524 /* Count REs present using sresmask */
7525 res_per_prb = 0;
7526 /* Use sresmask to pick out which REs are present */
7527 for (unsigned n=0; n<12; n++) {
7528 if (sresmask_to_use & (1<<n)) {
7529 res_per_prb++;
7530 }
7531 }
7532 }
7533
7534 /* N.B. bytes for samples need to be padded out to next byte
7535 (certainly where there aren't 12 REs in PRB..) */
7536 unsigned nBytesForSamples = (sample_bit_width * res_per_prb * 2 + 7) / 8;
7537 nBytesPerPrb = nBytesForSamples + udcompparam_len;
7538
7539 proto_tree_add_item(rb_tree, hf_oran_iq_user_data, tvb, offset, nBytesForSamples, ENC_NA0x00000000);
7540
7541 if (section_details) {
7542 if ((startPrbu + i*(1+rb)) < 273) {
7543 proto_item *beamid_ti = proto_tree_add_uint(rb_tree, hf_oran_beamId, tvb, 0, 0,
7544 section_details->beamIds[startPrbu + i*(1+rb)]);
7545 proto_item_set_generated(beamid_ti);
7546 }
7547 }
7548
7549
7550 tap_info->non_zero_re_in_current_prb = false0;
7551
7552 /* Optionally trying to show I/Q RE values */
7553 if (pref_showIQSampleValues) {
7554 /* Individual values */
7555 unsigned samples_offset = offset*8;
7556 unsigned samples_start = offset;
7557 unsigned samples = 0;
7558
7559 if (compression >= BFP_AND_SELECTIVE_RE5) {
7560 /* Use sresmask to pick out which REs are present */
7561 for (unsigned n=1; n<=12; n++) {
7562 if (sresmask_to_use & (1<<(n-1))) {
7563 samples_offset = dissect_oran_u_re(tvb, rb_tree,
7564 n, samples_offset, tap_info, sample_bit_width, compression, exponent, mod_compr_config, n);
7565 samples++;
7566 }
7567 }
7568 }
7569 else {
7570 /* All 12 REs are present */
7571 for (unsigned n=1; n<=12; n++) {
7572 samples_offset = dissect_oran_u_re(tvb, rb_tree,
7573 n, samples_offset, tap_info, sample_bit_width, compression, exponent, mod_compr_config, n);
7574 samples++;
7575 }
7576 }
7577 proto_item_append_text(prbHeading, " (%u REs)", samples);
7578 if (section_details) {
7579 if ((startPrbu + i*(1+rb)) < 273) {
7580 proto_item_append_text(prbHeading, " [BeamId:%u]", section_details->beamIds[startPrbu + i*(1+rb)]);
7581 }
7582 }
7583
7584 /* Was this PRB all zeros? */
7585 if (!tap_info->non_zero_re_in_current_prb) {
7586 tap_info->num_prbs_zero++;
7587 /* Add a filter to make zero-valued PRBs more findable */
7588 proto_item *zero_ti = proto_tree_add_item(rb_tree, hf_oran_zero_prb, tvb,
7589 samples_start, nBytesForSamples, ENC_NA0x00000000);
7590 proto_item_set_hidden(zero_ti);
7591 proto_item_append_text(prbHeading, " (all zeros)");
7592 }
7593 else {
7594 proto_item *nonzero_ti = proto_tree_add_item(rb_tree, hf_oran_nonzero_prb, tvb, samples_start, nBytesForSamples, ENC_NA0x00000000);
7595 proto_item_set_hidden(nonzero_ti);
7596 }
7597 }
7598
7599 tap_info->num_prbs++;
7600
7601
7602 /* Advance past samples */
7603 offset += nBytesForSamples;
7604
7605 /* Set end of prb subtree */
7606 proto_item_set_end(prbHeading, tvb, offset);
7607 }
7608
7609 /* Set extent of section */
7610 proto_item_set_len(sectionHeading, offset-section_start_offset);
7611 if (ud_comp_len_ti != NULL((void*)0) && ((offset-section_start_offset != ud_comp_len))) {
7612 expert_add_info_format(pinfo, ud_comp_len_ti, &ei_oran_ud_comp_len_wrong_size,
7613 "udCompLen indicates %u bytes in section, but dissected %u instead",
7614 ud_comp_len, offset-section_start_offset);
7615 }
7616
7617 bytesLeft = tvb_captured_length(tvb) - offset;
7618 number_of_sections++;
7619 } while (bytesLeft >= (4 + nBytesPerPrb)); /* FIXME: bad heuristic */
7620
7621 /* Show number of sections found */
7622 proto_item *ti = proto_tree_add_uint(oran_tree, hf_oran_numberOfSections, tvb, 0, 0, number_of_sections);
7623 proto_item_set_generated(ti);
7624
7625 /* Expert error if we are short of tvb by > 3 bytes */
7626 if (tvb_reported_length_remaining(tvb, offset) > 3) {
7627 expert_add_info_format(pinfo, protocol_item, &ei_oran_frame_length,
7628 "%u bytes remain at end of frame - should be 0-3",
7629 tvb_reported_length_remaining(tvb, offset));
7630 }
7631
7632 return tvb_captured_length(tvb);
7633}
7634
7635
7636/**********************************************************************/
7637/* Main dissection function. */
7638/* N.B. ecpri message type passed in as 'data' arg by eCPRI dissector */
7639static int
7640dissect_oran(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
7641{
7642 uint32_t ecpri_message_type = *(uint32_t *)data;
7643 unsigned offset = 0;
7644
7645 /* Allocate and zero tap struct */
7646 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
)))
;
7647 tap_info->pdu_size = pinfo->fd->pkt_len;
7648 tap_info->ul_delay_configured_max = us_allowed_for_ul_in_symbol;
7649
7650 switch (ecpri_message_type) {
7651 case ECPRI_MT_IQ_DATA0:
7652 offset = dissect_oran_u(tvb, pinfo, tree, tap_info, data);
7653 break;
7654 case ECPRI_MT_RT_CTRL_DATA2:
7655 offset = dissect_oran_c(tvb, pinfo, tree, tap_info, data);
7656 break;
7657 default:
7658 /* Not dissecting other types - assume these are handled by eCPRI dissector */
7659 return 0;
7660 }
7661
7662 tap_queue_packet(oran_tap, pinfo, tap_info);
7663
7664 return offset;
7665}
7666
7667static void oran_init_protocol(void)
7668{
7669 udcomplen_heuristic_result_set = false0;
7670 udcomplen_heuristic_result = false0;
7671}
7672
7673
7674/* Register the protocol with Wireshark. */
7675void
7676proto_register_oran(void)
7677{
7678 static hf_register_info hf[] = {
7679
7680 /* Section 5.1.3.2.7 */
7681 { &hf_oran_du_port_id,
7682 { "DU Port ID", "oran_fh_cus.du_port_id",
7683 FT_UINT16, BASE_DEC,
7684 NULL((void*)0), 0x0,
7685 "Processing unit at O-RU - width set in dissector preference", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
7686 },
7687
7688 /* Section 5.1.3.2.7 */
7689 { &hf_oran_bandsector_id,
7690 { "BandSector ID", "oran_fh_cus.bandsector_id",
7691 FT_UINT16, BASE_DEC,
7692 NULL((void*)0), 0x0,
7693 "Aggregated cell identified - width set in dissector preference", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
7694 },
7695
7696 /* Section 5.1.3.2.7 */
7697 { &hf_oran_cc_id,
7698 { "CC ID", "oran_fh_cus.cc_id",
7699 FT_UINT16, BASE_DEC,
7700 NULL((void*)0), 0x0,
7701 "Component Carrier - width set in dissector preference", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
7702 },
7703
7704 /* Section 5.1.3.2.7 */
7705 { &hf_oran_ru_port_id,
7706 { "RU Port ID", "oran_fh_cus.ru_port_id",
7707 FT_UINT16, BASE_DEC,
7708 NULL((void*)0), 0x0,
7709 "Logical flow - width set in dissector preference", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
7710 },
7711
7712 /* Section 5.1.3.2.8 */
7713 { &hf_oran_sequence_id,
7714 { "Sequence ID", "oran_fh_cus.sequence_id",
7715 FT_UINT8, BASE_DEC,
7716 NULL((void*)0), 0x0,
7717 "The Sequence ID wraps around individually per eAxC", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
7718 },
7719
7720 /* Section 5.1.3.2.8 */
7721 { &hf_oran_e_bit,
7722 { "E Bit", "oran_fh_cus.e_bit",
7723 FT_UINT8, BASE_DEC,
7724 VALS(e_bit)((0 ? (const struct _value_string*)0 : ((e_bit)))), 0x80,
7725 "Indicate the last message of a subsequence (U-Plane only)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
7726 },
7727
7728 /* Section 5.1.3.2.8 */
7729 { &hf_oran_subsequence_id,
7730 { "Subsequence ID", "oran_fh_cus.subsequence_id",
7731 FT_UINT8, BASE_DEC,
7732 NULL((void*)0), 0x7f,
7733 "The subsequence ID (for eCPRI layer fragmentation)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
7734 },
7735
7736 { &hf_oran_previous_frame,
7737 { "Previous frame in stream", "oran_fh_cus.previous-frame",
7738 FT_FRAMENUM, BASE_NONE,
7739 FRAMENUM_TYPE(FT_FRAMENUM_NONE)((gpointer) (glong) (FT_FRAMENUM_NONE)), 0x0,
7740 "Previous frame in sequence", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
7741 },
7742
7743 /* Section 7.5.2.1 */
7744 { &hf_oran_data_direction,
7745 { "Data Direction", "oran_fh_cus.data_direction",
7746 FT_UINT8, BASE_DEC,
7747 VALS(data_direction_vals)((0 ? (const struct _value_string*)0 : ((data_direction_vals)
)))
, 0x80,
7748 "gNB data direction", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
7749 },
7750
7751 /* Section 7.5.2.2 */
7752 { &hf_oran_payload_version,
7753 { "Payload Version", "oran_fh_cus.payloadVersion",
7754 FT_UINT8, BASE_DEC,
7755 NULL((void*)0), 0x70,
7756 "Payload protocol version the following IEs", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7757 },
7758
7759 /* Section 7.5.2.3 */
7760 { &hf_oran_filter_index,
7761 { "Filter Index", "oran_fh_cus.filterIndex",
7762 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
7763 RVALS(filter_indices)((0 ? (const struct _range_string*)0 : ((filter_indices)))), 0x0f,
7764 "used between IQ data and air interface, both in DL and UL", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7765 },
7766
7767 /* Section 7.5.2.4 */
7768 { &hf_oran_frame_id,
7769 { "Frame ID", "oran_fh_cus.frameId",
7770 FT_UINT8, BASE_DEC,
7771 NULL((void*)0), 0x0,
7772 "A counter for 10 ms frames (wrapping period 2.56 seconds)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7773 },
7774
7775 /* Section 7.5.2.5 */
7776 { &hf_oran_subframe_id,
7777 { "Subframe ID", "oran_fh_cus.subframe_id",
7778 FT_UINT8, BASE_DEC,
7779 NULL((void*)0), 0xf0,
7780 "A counter for 1 ms sub-frames within 10ms frame", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7781 },
7782
7783 /* Section 7.5.2.6 */
7784 { &hf_oran_slot_id,
7785 { "Slot ID", "oran_fh_cus.slotId",
7786 FT_UINT16, BASE_DEC,
7787 NULL((void*)0), 0x0fc0,
7788 "Slot number within a 1ms sub-frame", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7789 },
7790
7791 /* Generated for convenience */
7792 { &hf_oran_slot_within_frame,
7793 { "Slot within frame", "oran_fh_cus.slot-within-frame",
7794 FT_UINT16, BASE_DEC,
7795 NULL((void*)0), 0x0,
7796 "Slot within frame, to match DCT logs", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7797 },
7798
7799 /* Section 7.5.2.7 */
7800 { &hf_oran_start_symbol_id,
7801 { "Start Symbol ID", "oran_fh_cus.startSymbolId",
7802 FT_UINT8, BASE_DEC,
7803 NULL((void*)0), 0x3f,
7804 "The first symbol number within slot affected", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7805 },
7806
7807 /* Section 7.5.2.8 */
7808 { &hf_oran_numberOfSections,
7809 { "Number of Sections", "oran_fh_cus.numberOfSections",
7810 FT_UINT8, BASE_DEC,
7811 NULL((void*)0), 0x0,
7812 "The number of section IDs included in this message", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7813 },
7814
7815 /* Section 7.5.2.9 */
7816 { &hf_oran_sectionType,
7817 { "Section Type", "oran_fh_cus.sectionType",
7818 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
7819 RVALS(section_types)((0 ? (const struct _range_string*)0 : ((section_types)))), 0x0,
7820 "Determines the characteristics of U-plane data", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7821 },
7822
7823 /* Section 7.5.2.10 */
7824 { &hf_oran_udCompHdr,
7825 { "udCompHdr", "oran_fh_cus.udCompHdr",
7826 FT_STRING, BASE_NONE,
7827 NULL((void*)0), 0x0,
7828 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7829 },
7830
7831 /* Section 7.5.2.11 */
7832 { &hf_oran_numberOfUEs,
7833 { "Number Of UEs", "oran_fh_cus.numberOfUEs",
7834 FT_UINT8, BASE_DEC,
7835 NULL((void*)0), 0x0,
7836 "Indicates number of UEs for which channel info is provided", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7837 },
7838
7839 /* Section 7.5.2.12 */
7840 { &hf_oran_timeOffset,
7841 { "Time Offset", "oran_fh_cus.timeOffset",
7842 FT_UINT16, BASE_DEC,
7843 NULL((void*)0), 0x0,
7844 "from start of the slot to start of CP in samples", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7845 },
7846
7847 /* Section 7.5.2.13 */
7848 { &hf_oran_frameStructure_fft,
7849 { "FFT Size", "oran_fh_cus.frameStructure.fft",
7850 FT_UINT8, BASE_HEX | BASE_RANGE_STRING0x00000100,
7851 RVALS(frame_structure_fft)((0 ? (const struct _range_string*)0 : ((frame_structure_fft)
)))
, 0xf0,
7852 "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) }
7853 },
7854
7855 /* Section 7.5.2.13 */
7856 { &hf_oran_frameStructure_subcarrier_spacing,
7857 { "Subcarrier Spacing", "oran_fh_cus.frameStructure.spacing",
7858 FT_UINT8, BASE_HEX | BASE_RANGE_STRING0x00000100,
7859 RVALS(subcarrier_spacings)((0 ? (const struct _range_string*)0 : ((subcarrier_spacings)
)))
, 0x0f,
7860 "The sub carrier spacing as well as the number of slots per 1ms sub-frame",
7861 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
7862 },
7863
7864 /* Section 7.5.2.14 */
7865 { &hf_oran_cpLength,
7866 { "cpLength", "oran_fh_cus.cpLength",
7867 FT_UINT16, BASE_DEC,
7868 NULL((void*)0), 0x0,
7869 "cyclic prefix length", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7870 },
7871
7872 { &hf_oran_timing_header,
7873 { "Timing Header", "oran_fh_cus.timingHeader",
7874 FT_STRING, BASE_NONE,
7875 NULL((void*)0), 0x0,
7876 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7877 },
7878
7879 /* Section 7.5.3.1 */
7880 { &hf_oran_section_id,
7881 { "sectionId", "oran_fh_cus.sectionId",
7882 FT_UINT16, BASE_DEC,
7883 NULL((void*)0), 0xfff0,
7884 "section identifier of data", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7885 },
7886
7887 /* Section 7.5.3.2 */
7888 { &hf_oran_rb,
7889 { "rb", "oran_fh_cus.rb",
7890 FT_UINT8, BASE_DEC,
7891 VALS(rb_vals)((0 ? (const struct _value_string*)0 : ((rb_vals)))), 0x08,
7892 "resource block indicator", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7893 },
7894
7895 /* Section 7.5.5.3 */
7896 { &hf_oran_symInc,
7897 { "symInc", "oran_fh_cus.symInc",
7898 FT_UINT8, BASE_DEC,
7899 VALS(sym_inc_vals)((0 ? (const struct _value_string*)0 : ((sym_inc_vals)))), 0x04,
7900 "Symbol Number Increment Command", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7901 },
7902
7903 /* Section 7.5.3.4 */
7904 { &hf_oran_startPrbc,
7905 { "startPrbc", "oran_fh_cus.startPrbc",
7906 FT_UINT16, BASE_DEC,
7907 NULL((void*)0), 0x03ff,
7908 "Starting PRB of Control Plane Section", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7909 },
7910
7911 /* Section 7.5.3.5 */
7912 { &hf_oran_reMask_re1,
7913 { "RE 1", "oran_fh_cus.reMask-RE1",
7914 FT_BOOLEAN, 16,
7915 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x8000,
7916 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7917 },
7918 { &hf_oran_reMask_re2,
7919 { "RE 2", "oran_fh_cus.reMask-RE2",
7920 FT_BOOLEAN, 16,
7921 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x4000,
7922 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7923 },
7924 { &hf_oran_reMask_re3,
7925 { "RE 3", "oran_fh_cus.reMask-RE3",
7926 FT_BOOLEAN, 16,
7927 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x2000,
7928 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7929 },
7930 { &hf_oran_reMask_re4,
7931 { "RE 4", "oran_fh_cus.reMask-RE4",
7932 FT_BOOLEAN, 16,
7933 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x1000,
7934 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7935 },
7936 { &hf_oran_reMask_re5,
7937 { "RE 5", "oran_fh_cus.reMask-RE5",
7938 FT_BOOLEAN, 16,
7939 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0800,
7940 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7941 },
7942 { &hf_oran_reMask_re6,
7943 { "RE 6", "oran_fh_cus.reMask-RE6",
7944 FT_BOOLEAN, 16,
7945 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0400,
7946 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7947 },
7948 { &hf_oran_reMask_re7,
7949 { "RE 7", "oran_fh_cus.reMask-RE7",
7950 FT_BOOLEAN, 16,
7951 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0200,
7952 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7953 },
7954 { &hf_oran_reMask_re8,
7955 { "RE 8", "oran_fh_cus.reMask-RE8",
7956 FT_BOOLEAN, 16,
7957 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0100,
7958 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7959 },
7960 { &hf_oran_reMask_re9,
7961 { "RE 9", "oran_fh_cus.reMask-RE9",
7962 FT_BOOLEAN, 16,
7963 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0080,
7964 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7965 },
7966 { &hf_oran_reMask_re10,
7967 { "RE 10", "oran_fh_cus.reMask-RE10",
7968 FT_BOOLEAN, 16,
7969 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0040,
7970 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7971 },
7972 { &hf_oran_reMask_re11,
7973 { "RE 11", "oran_fh_cus.reMask-RE11",
7974 FT_BOOLEAN, 16,
7975 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0020,
7976 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7977 },
7978 { &hf_oran_reMask_re12,
7979 { "RE 12", "oran_fh_cus.reMask-RE12",
7980 FT_BOOLEAN, 16,
7981 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0010,
7982 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7983 },
7984 { &hf_oran_reMask,
7985 { "RE Mask", "oran_fh_cus.reMask",
7986 FT_UINT16, BASE_HEX,
7987 NULL((void*)0), 0xfff0,
7988 "The Resource Element (RE) mask within a PRB", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7989 },
7990
7991 /* Section 7.5.3.6 */
7992 { &hf_oran_numPrbc,
7993 { "numPrbc", "oran_fh_cus.numPrbc",
7994 FT_UINT8, BASE_DEC,
7995 NULL((void*)0), 0x0,
7996 "Number of contiguous PRBs per data section description", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7997 },
7998 /* Section 7.5.3.7 */
7999 { &hf_oran_numSymbol,
8000 { "Number of Symbols", "oran_fh_cus.numSymbol",
8001 FT_UINT8, BASE_DEC,
8002 NULL((void*)0), 0x0f,
8003 "Defines number of symbols to which the section control is applicable", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8004 },
8005 /* Section 7.5.3.8 */
8006 { &hf_oran_ef,
8007 { "Extension Flag", "oran_fh_cus.ef",
8008 FT_BOOLEAN, 8,
8009 NULL((void*)0), 0x80,
8010 "Indicates if more section extensions follow", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8011 },
8012 /* Section 7.5.3.9 */
8013 { &hf_oran_beamId,
8014 { "Beam ID", "oran_fh_cus.beamId",
8015 FT_UINT16, BASE_DEC,
8016 NULL((void*)0), 0x7fff,
8017 "Defines the beam pattern to be applied to the U-Plane data", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8018 },
8019
8020 { &hf_oran_extension,
8021 { "Extension", "oran_fh_cus.extension",
8022 FT_STRING, BASE_NONE,
8023 NULL((void*)0), 0x0,
8024 "Section extension", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8025 },
8026
8027 /* Section 7.6.2.1 */
8028 { &hf_oran_exttype,
8029 { "extType", "oran_fh_cus.extType",
8030 FT_UINT8, BASE_DEC|BASE_EXT_STRING0x00000200,
8031 &exttype_vals_ext, 0x7f,
8032 "The extension type, which provides additional parameters specific to subject data extension", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8033 },
8034
8035 /* Section 7.6.2.3 */
8036 { &hf_oran_extlen,
8037 { "extLen", "oran_fh_cus.extLen",
8038 FT_UINT16, BASE_DEC,
8039 NULL((void*)0), 0x0,
8040 "Extension length in 32-bit words", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8041 },
8042
8043 /* Section 7.7.1 */
8044 { &hf_oran_bfw,
8045 { "bfw", "oran_fh_cus.bfw",
8046 FT_STRING, BASE_NONE,
8047 NULL((void*)0), 0x0,
8048 "Set of weights for a particular antenna", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8049 },
8050 { &hf_oran_bfw_bundle,
8051 { "Bundle", "oran_fh_cus.bfw.bundle",
8052 FT_STRING, BASE_NONE,
8053 NULL((void*)0), 0x0,
8054 "Bundle of BFWs", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8055 },
8056 { &hf_oran_bfw_bundle_id,
8057 { "Bundle Id", "oran_fh_cus.bfw.bundleId",
8058 FT_UINT32, BASE_DEC,
8059 NULL((void*)0), 0x0,
8060 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8061 },
8062 /* Section 7.7.1.4 */
8063 { &hf_oran_bfw_i,
8064 { "bfwI", "oran_fh_cus.bfwI",
8065 FT_FLOAT, BASE_NONE,
8066 NULL((void*)0), 0x0,
8067 "In-phase", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8068 },
8069 /* Section 7.7.1.5 */
8070 { &hf_oran_bfw_q,
8071 { "bfwQ", "oran_fh_cus.bfwQ",
8072 FT_FLOAT, BASE_NONE,
8073 NULL((void*)0), 0x0,
8074 "Quadrature", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8075 },
8076
8077 /* Section 7.5.3.10 */
8078 { &hf_oran_ueId,
8079 { "UE ID", "oran_fh_cus.ueId",
8080 FT_UINT16, BASE_DEC,
8081 NULL((void*)0), 0x7fff,
8082 "logical identifier for set of channel info", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8083 },
8084 /* Section 7.5.3.11 */
8085 { &hf_oran_freqOffset,
8086 { "Frequency Offset", "oran_fh_cus.freqOffset",
8087 FT_UINT24, BASE_DEC,
8088 NULL((void*)0), 0x0,
8089 "with respect to the carrier center frequency before additional filtering", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8090 },
8091
8092 /* Section 7.5.3.12 */
8093 { &hf_oran_regularizationFactor,
8094 { "Regularization Factor", "oran_fh_cus.regularizationFactor",
8095 FT_INT16, BASE_DEC,
8096 NULL((void*)0), 0x0,
8097 "Signed value to support MMSE operation within O-RU", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8098 },
8099 /* Section 7.5.3.14 */
8100 { &hf_oran_laaMsgType,
8101 { "LAA Message Type", "oran_fh_cus.laaMsgType",
8102 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
8103 RVALS(laaMsgTypes)((0 ? (const struct _range_string*)0 : ((laaMsgTypes)))), 0xf0,
8104 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8105 },
8106 /* Section 7.5.3.15 */
8107 { &hf_oran_laaMsgLen,
8108 { "LAA Message Length", "oran_fh_cus.laaMsgLen",
8109 FT_UINT8, BASE_DEC,
8110 NULL((void*)0), 0x0f,
8111 "number of 32-bit words in the LAA section", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8112 },
8113 /* Section 7.5.3.16 */
8114 { &hf_oran_lbtHandle,
8115 { "LBT Handle", "oran_fh_cus.lbtHandle",
8116 FT_UINT16, BASE_HEX,
8117 NULL((void*)0), 0x0,
8118 "label to identify transaction", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8119 },
8120 /* Section 7.5.3.17 */
8121 { &hf_oran_lbtDeferFactor,
8122 { "Defer Factor", "oran_fh_cus.lbtDeferFactor",
8123 FT_UINT8, BASE_DEC,
8124 NULL((void*)0), 0x07,
8125 "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)}
8126 },
8127 /* Section 7.5.3.18 */
8128 { &hf_oran_lbtBackoffCounter,
8129 { "Backoff Counter", "oran_fh_cus.lbtBackoffCounter",
8130 FT_UINT16, BASE_DEC,
8131 NULL((void*)0), 0xffc0,
8132 "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)}
8133 },
8134 /* Section 7.5.3.19 */
8135 { &hf_oran_lbtOffset,
8136 { "LBT Offset", "oran_fh_cus.lbtOffset",
8137 FT_UINT16, BASE_DEC,
8138 NULL((void*)0), 0xffc0,
8139 "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)}
8140 },
8141 /* Section 7.5.3.20 */
8142 { &hf_oran_MCOT,
8143 { "Maximum Channel Occupancy Time", "oran_fh_cus.MCOT",
8144 FT_UINT8, BASE_DEC,
8145 NULL((void*)0), 0x3c,
8146 "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)}
8147 },
8148 /* Section 7.5.3.21 */
8149 { &hf_oran_lbtMode,
8150 { "LBT Mode", "oran_fh_cus.lbtMode",
8151 FT_UINT8, BASE_DEC,
8152 VALS(lbtMode_vals)((0 ? (const struct _value_string*)0 : ((lbtMode_vals)))), 0x0,
8153 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8154 },
8155 /* Section 7.5.3.22 */
8156 { &hf_oran_lbtPdschRes,
8157 { "lbtPdschRes", "oran_fh_cus.lbtPdschRes",
8158 FT_UINT8, BASE_DEC,
8159 VALS(lbtPdschRes_vals)((0 ? (const struct _value_string*)0 : ((lbtPdschRes_vals)))), 0xc0,
8160 "LBT result of SFN/SF", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8161 },
8162 /* Section 7.5.3.23 */
8163 { &hf_oran_sfStatus,
8164 { "sfStatus", "oran_fh_cus.sfStatus",
8165 FT_BOOLEAN, 8,
8166 TFS(&tfs_sfStatus)((0 ? (const struct true_false_string*)0 : ((&tfs_sfStatus
))))
, 0x10,
8167 "Indicates whether the subframe was dropped or transmitted", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8168 },
8169 /* Section 7.5.3.24 */
8170 { &hf_oran_lbtDrsRes,
8171 { "lbtDrsRes", "oran_fh_cus.lbtDrsRes",
8172 FT_BOOLEAN, 8,
8173 TFS(&tfs_fail_success)((0 ? (const struct true_false_string*)0 : ((&tfs_fail_success
))))
, 0x80,
8174 "Indicates whether the subframe was dropped or transmitted", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8175 },
8176 /* Section 7.5.3.25 */
8177 { &hf_oran_initialPartialSF,
8178 { "Initial partial SF", "oran_fh_cus.initialPartialSF",
8179 FT_BOOLEAN, 8,
8180 TFS(&tfs_partial_full_sf)((0 ? (const struct true_false_string*)0 : ((&tfs_partial_full_sf
))))
, 0x40,
8181 "Indicates whether the initial SF in the LBT process is full or partial", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8182 },
8183 /* Section 7.5.3.26. */
8184 { &hf_oran_lbtBufErr,
8185 { "lbtBufErr", "oran_fh_cus.lbtBufErr",
8186 FT_BOOLEAN, 8,
8187 TFS(&tfs_lbtBufErr)((0 ? (const struct true_false_string*)0 : ((&tfs_lbtBufErr
))))
, 0x80,
8188 "LBT buffer error", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8189 },
8190 /* Section 7.5.3.27 */
8191 { &hf_oran_sfnSfEnd,
8192 { "SFN/SF End", "oran_fh_cus.sfnSfEnd",
8193 FT_UINT16, BASE_DEC,
8194 NULL((void*)0), 0x0fff,
8195 "SFN/SF by which the DRS window must end", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8196 },
8197 /* Section 7.5.3.28 */
8198 { &hf_oran_lbtCWConfig_H,
8199 { "lbtCWConfig_H", "oran_fh_cus.lbtCWConfig_H",
8200 FT_UINT8, BASE_DEC,
8201 NULL((void*)0), 0x0,
8202 "HARQ parameters for congestion window management", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8203 },
8204 /* Section 7.5.3.29 */
8205 { &hf_oran_lbtCWConfig_T,
8206 { "lbtCWConfig_T", "oran_fh_cus.lbtCWConfig_T",
8207 FT_UINT8, BASE_DEC,
8208 NULL((void*)0), 0x0,
8209 "TB parameters for congestion window management", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8210 },
8211 /* Section 7.5.3.30 */
8212 { &hf_oran_lbtTrafficClass,
8213 { "lbtTrafficClass", "oran_fh_cus.lbtTrafficClass",
8214 FT_UINT8, BASE_DEC,
8215 VALS(lbtTrafficClass_vals)((0 ? (const struct _value_string*)0 : ((lbtTrafficClass_vals
))))
, 0x38,
8216 "Traffic class priority for congestion window management", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8217 },
8218 /* Section 7.5.3.31 */
8219 { &hf_oran_lbtCWR_Rst,
8220 { "lbtCWR_Rst", "oran_fh_cus.lbtCWR_Rst",
8221 FT_BOOLEAN, 8,
8222 TFS(&tfs_fail_success)((0 ? (const struct true_false_string*)0 : ((&tfs_fail_success
))))
, 0x80,
8223 "notification about packet reception successful or not", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8224 },
8225
8226 /* Reserved fields */
8227 { &hf_oran_reserved,
8228 { "reserved", "oran_fh_cus.reserved",
8229 FT_UINT64, BASE_HEX,
8230 NULL((void*)0), 0x0,
8231 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8232 },
8233 { &hf_oran_reserved_1bit,
8234 { "reserved", "oran_fh_cus.reserved",
8235 FT_UINT8, BASE_HEX,
8236 NULL((void*)0), 0x80,
8237 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8238 },
8239 { &hf_oran_reserved_2bits,
8240 { "reserved", "oran_fh_cus.reserved",
8241 FT_UINT8, BASE_HEX,
8242 NULL((void*)0), 0xc0,
8243 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8244 },
8245 { &hf_oran_reserved_3bits,
8246 { "reserved", "oran_fh_cus.reserved",
8247 FT_UINT8, BASE_HEX,
8248 NULL((void*)0), 0xe0,
8249 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8250 },
8251 { &hf_oran_reserved_4bits,
8252 { "reserved", "oran_fh_cus.reserved",
8253 FT_UINT8, BASE_HEX,
8254 NULL((void*)0), 0xf0,
8255 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8256 },
8257 { &hf_oran_reserved_last_4bits,
8258 { "reserved", "oran_fh_cus.reserved",
8259 FT_UINT8, BASE_HEX,
8260 NULL((void*)0), 0x0f,
8261 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8262 },
8263 { &hf_oran_reserved_last_5bits,
8264 { "reserved", "oran_fh_cus.reserved",
8265 FT_UINT8, BASE_HEX,
8266 NULL((void*)0), 0x1f,
8267 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8268 },
8269 { &hf_oran_reserved_6bits,
8270 { "reserved", "oran_fh_cus.reserved",
8271 FT_UINT8, BASE_HEX,
8272 NULL((void*)0), 0xfc,
8273 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8274 },
8275 { &hf_oran_reserved_last_6bits,
8276 { "reserved", "oran_fh_cus.reserved",
8277 FT_UINT8, BASE_HEX,
8278 NULL((void*)0), 0x3f,
8279 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8280 },
8281 { &hf_oran_reserved_7bits,
8282 { "reserved", "oran_fh_cus.reserved",
8283 FT_UINT8, BASE_HEX,
8284 NULL((void*)0), 0xfe,
8285 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8286 },
8287 { &hf_oran_reserved_last_7bits,
8288 { "reserved", "oran_fh_cus.reserved",
8289 FT_UINT8, BASE_HEX,
8290 NULL((void*)0), 0x7f,
8291 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8292 },
8293 { &hf_oran_reserved_8bits,
8294 { "reserved", "oran_fh_cus.reserved",
8295 FT_UINT8, BASE_HEX,
8296 NULL((void*)0), 0x0,
8297 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8298 },
8299 { &hf_oran_reserved_16bits,
8300 { "reserved", "oran_fh_cus.reserved",
8301 FT_UINT16, BASE_HEX,
8302 NULL((void*)0), 0x0,
8303 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8304 },
8305 { &hf_oran_reserved_15bits,
8306 { "reserved", "oran_fh_cus.reserved",
8307 FT_UINT16, BASE_HEX,
8308 NULL((void*)0), 0x7fff,
8309 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8310 },
8311 { &hf_oran_reserved_bit1,
8312 { "reserved", "oran_fh_cus.reserved",
8313 FT_UINT8, BASE_HEX,
8314 NULL((void*)0), 0x40,
8315 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8316 },
8317 { &hf_oran_reserved_bit2,
8318 { "reserved", "oran_fh_cus.reserved",
8319 FT_UINT8, BASE_HEX,
8320 NULL((void*)0), 0x20,
8321 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8322 },
8323 { &hf_oran_reserved_bit4,
8324 { "reserved", "oran_fh_cus.reserved",
8325 FT_UINT8, BASE_HEX,
8326 NULL((void*)0), 0x08,
8327 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8328 },
8329 { &hf_oran_reserved_bit5,
8330 { "reserved", "oran_fh_cus.reserved",
8331 FT_UINT8, BASE_HEX,
8332 NULL((void*)0), 0x04,
8333 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8334 },
8335 { &hf_oran_reserved_bits123,
8336 { "reserved", "oran_fh_cus.reserved",
8337 FT_UINT8, BASE_HEX,
8338 NULL((void*)0), 0x70,
8339 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8340 },
8341 { &hf_oran_reserved_bits456,
8342 { "reserved", "oran_fh_cus.reserved",
8343 FT_UINT8, BASE_HEX,
8344 NULL((void*)0), 0x0e,
8345 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8346 },
8347
8348 /* 7.7.11.9 */
8349 { &hf_oran_cont_ind,
8350 { "contInd", "oran_fh_cus.contInd",
8351 FT_BOOLEAN, 8,
8352 TFS(&continuity_indication_tfs)((0 ? (const struct true_false_string*)0 : ((&continuity_indication_tfs
))))
, 0x80,
8353 "PRB region continuity flag", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8354 },
8355 /* 7.7.11.10 */
8356 { &hf_oran_bundle_offset,
8357 { "BundleOffset", "oran_fh_cus.bundleOffset",
8358 FT_UINT8, BASE_DEC,
8359 NULL((void*)0), 0x3f,
8360 "offset between start of first PRB bundle and startPrbc", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8361 },
8362
8363 /* 7.7.1.2 bfwCompHdr (beamforming weight compression header) */
8364 { &hf_oran_bfwCompHdr,
8365 { "bfwCompHdr", "oran_fh_cus.bfwCompHdr",
8366 FT_STRING, BASE_NONE,
8367 NULL((void*)0), 0x0,
8368 "Compression method and IQ bit width for beamforming weights", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8369 },
8370 { &hf_oran_bfwCompHdr_iqWidth,
8371 { "IQ Bit Width", "oran_fh_cus.bfwCompHdr_iqWidth",
8372 FT_UINT8, BASE_HEX,
8373 VALS(bfw_comp_headers_iq_width)((0 ? (const struct _value_string*)0 : ((bfw_comp_headers_iq_width
))))
, 0xf0,
8374 "IQ bit width for the beamforming weights", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8375 },
8376 { &hf_oran_bfwCompHdr_compMeth,
8377 { "Compression Method", "oran_fh_cus.bfwCompHdr_compMeth",
8378 FT_UINT8, BASE_HEX,
8379 VALS(bfw_comp_headers_comp_meth)((0 ? (const struct _value_string*)0 : ((bfw_comp_headers_comp_meth
))))
, 0x0f,
8380 "compression method for the beamforming weights", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8381 },
8382
8383 /* 7.5.3.32 */
8384 { &hf_oran_ciCompParam,
8385 { "ciCompParam", "oran_fh_cus.ciCompParam",
8386 FT_STRING, BASE_NONE,
8387 NULL((void*)0), 0x0,
8388 "channel information compression parameter", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8389 },
8390
8391 /* Table 7.5.3.32-1 */
8392 { &hf_oran_blockScaler,
8393 { "blockScaler", "oran_fh_cus.blockScaler",
8394 FT_UINT8, BASE_HEX,
8395 NULL((void*)0), 0x0,
8396 "unsigned, 1 integer bit, 7 fractional bits", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8397 },
8398 { &hf_oran_compBitWidth,
8399 { "compBitWidth", "oran_fh_cus.compBitWidth",
8400 FT_UINT8, BASE_DEC,
8401 NULL((void*)0), 0xf0,
8402 "Length of I bits and length of Q bits after compression over entire PRB", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8403 },
8404 { &hf_oran_compShift,
8405 { "compShift", "oran_fh_cus.compShift",
8406 FT_UINT8, BASE_DEC,
8407 NULL((void*)0), 0x0f,
8408 "The shift applied to the entire PRB", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8409 },
8410
8411 { &hf_oran_active_beamspace_coefficient_n1,
8412 { "N1", "oran_fh_cus.activeBeamspace_Coefficient_n1",
8413 FT_BOOLEAN, 8,
8414 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x80,
8415 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8416 },
8417 { &hf_oran_active_beamspace_coefficient_n2,
8418 { "N2", "oran_fh_cus.activeBeamspace_Coefficient_n2",
8419 FT_BOOLEAN, 8,
8420 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x40,
8421 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8422 },
8423 { &hf_oran_active_beamspace_coefficient_n3,
8424 { "N3", "oran_fh_cus.activeBeamspace_Coefficient_n3",
8425 FT_BOOLEAN, 8,
8426 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x20,
8427 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8428 },
8429 { &hf_oran_active_beamspace_coefficient_n4,
8430 { "N4", "oran_fh_cus.activeBeamspace_Coefficient_n4",
8431 FT_BOOLEAN, 8,
8432 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x10,
8433 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8434 },
8435 { &hf_oran_active_beamspace_coefficient_n5,
8436 { "N5", "oran_fh_cus.activeBeamspace_Coefficient_n5",
8437 FT_BOOLEAN, 8,
8438 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x08,
8439 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8440 },
8441 { &hf_oran_active_beamspace_coefficient_n6,
8442 { "N6", "oran_fh_cus.activeBeamspace_Coefficient_n6",
8443 FT_BOOLEAN, 8,
8444 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x04,
8445 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8446 },
8447 { &hf_oran_active_beamspace_coefficient_n7,
8448 { "N7", "oran_fh_cus.activeBeamspace_Coefficient_n7",
8449 FT_BOOLEAN, 8,
8450 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x02,
8451 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8452 },
8453 { &hf_oran_active_beamspace_coefficient_n8,
8454 { "N8", "oran_fh_cus.activeBeamspace_Coefficient_n8",
8455 FT_BOOLEAN, 8,
8456 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x01,
8457 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8458 },
8459
8460 { &hf_oran_activeBeamspaceCoefficientMask,
8461 { "activeBeamspaceCoefficientMask", "oran_fh_cus.activeBeamspaceCoefficientMask",
8462 FT_UINT8, BASE_HEX,
8463 NULL((void*)0), 0xff,
8464 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8465 },
8466 { &hf_oran_activeBeamspaceCoefficientMask_bits_set,
8467 { "Array elements set", "oran_fh_cus.activeBeamspaceCoefficientMask.bits-set",
8468 FT_UINT32, BASE_DEC,
8469 NULL((void*)0), 0x0,
8470 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8471 },
8472
8473 /* Section 7.7.6.6 */
8474 { &hf_oran_se6_repetition,
8475 { "repetition", "oran_fh_cus.repetition",
8476 FT_BOOLEAN, BASE_NONE,
8477 TFS(&repetition_se6_tfs)((0 ? (const struct true_false_string*)0 : ((&repetition_se6_tfs
))))
, 0x0,
8478 "Repetition of a highest priority data section for C-Plane", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8479 },
8480 /* 7.7.20.9 */
8481 { &hf_oran_rbgSize,
8482 { "rbgSize", "oran_fh_cus.rbgSize",
8483 FT_UINT8, BASE_HEX,
8484 VALS(rbg_size_vals)((0 ? (const struct _value_string*)0 : ((rbg_size_vals)))), 0x70,
8485 "Number of PRBs of the resource block groups allocated by the bit mask", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8486 },
8487 /* 7.7.20.10 */
8488 { &hf_oran_rbgMask,
8489 { "rbgMask", "oran_fh_cus.rbgMask",
8490 FT_UINT32, BASE_HEX,
8491 NULL((void*)0), 0x0fffffff,
8492 "Each bit indicates whether a corresponding resource block group is present", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8493 },
8494 /* 7.7.6.5. Also 7.7.12.3 and 7.7.19.5 */
8495 { &hf_oran_noncontig_priority,
8496 { "priority", "oran_fh_cus.priority",
8497 FT_UINT8, BASE_HEX,
8498 VALS(priority_vals)((0 ? (const struct _value_string*)0 : ((priority_vals)))), 0xc0,
8499 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8500 },
8501
8502 /* 7.7.6.4 */
8503 { &hf_oran_symbol_mask,
8504 { "symbolMask", "oran_fh_cus.symbolMask",
8505 FT_UINT16, BASE_HEX,
8506 NULL((void*)0), 0x3fff,
8507 "Each bit indicates whether the rbgMask applies to a given symbol in the slot", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8508 },
8509 { &hf_oran_symbol_mask_s13,
8510 { "symbol 13", "oran_fh_cus.symbolMask.symbol-13",
8511 FT_BOOLEAN, 16,
8512 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x2000,
8513 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8514 },
8515 { &hf_oran_symbol_mask_s12,
8516 { "symbol 12", "oran_fh_cus.symbolMask.symbol-12",
8517 FT_BOOLEAN, 16,
8518 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x1000,
8519 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8520 },
8521 { &hf_oran_symbol_mask_s11,
8522 { "symbol 11", "oran_fh_cus.symbolMask.symbol-11",
8523 FT_BOOLEAN, 16,
8524 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0800,
8525 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8526 },
8527 { &hf_oran_symbol_mask_s10,
8528 { "symbol 10", "oran_fh_cus.symbolMask.symbol-10",
8529 FT_BOOLEAN, 16,
8530 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0400,
8531 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8532 },
8533 { &hf_oran_symbol_mask_s9,
8534 { "symbol 9", "oran_fh_cus.symbolMask.symbol-9",
8535 FT_BOOLEAN, 16,
8536 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0200,
8537 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8538 },
8539 { &hf_oran_symbol_mask_s8,
8540 { "symbol 8", "oran_fh_cus.symbolMask.symbol-8",
8541 FT_BOOLEAN, 16,
8542 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0100,
8543 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8544 },
8545 { &hf_oran_symbol_mask_s7,
8546 { "symbol 7", "oran_fh_cus.symbolMask.symbol-7",
8547 FT_BOOLEAN, 16,
8548 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0080,
8549 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8550 },
8551 { &hf_oran_symbol_mask_s6,
8552 { "symbol 6", "oran_fh_cus.symbolMask.symbol-6",
8553 FT_BOOLEAN, 16,
8554 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0040,
8555 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8556 },
8557 { &hf_oran_symbol_mask_s5,
8558 { "symbol 5", "oran_fh_cus.symbolMask.symbol-5",
8559 FT_BOOLEAN, 16,
8560 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0020,
8561 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8562 },
8563 { &hf_oran_symbol_mask_s4,
8564 { "symbol 4", "oran_fh_cus.symbolMask.symbol-4",
8565 FT_BOOLEAN, 16,
8566 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0010,
8567 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8568 },
8569 { &hf_oran_symbol_mask_s3,
8570 { "symbol 3", "oran_fh_cus.symbolMask.symbol-3",
8571 FT_BOOLEAN, 16,
8572 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0008,
8573 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8574 },
8575 { &hf_oran_symbol_mask_s2,
8576 { "symbol 2", "oran_fh_cus.symbolMask.symbol-2",
8577 FT_BOOLEAN, 16,
8578 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0004,
8579 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8580 },
8581 { &hf_oran_symbol_mask_s1,
8582 { "symbol 1", "oran_fh_cus.symbolMask.symbol-1",
8583 FT_BOOLEAN, 16,
8584 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0002,
8585 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8586 },
8587 { &hf_oran_symbol_mask_s0,
8588 { "symbol 0", "oran_fh_cus.symbolMask.symbol-0",
8589 FT_BOOLEAN, 16,
8590 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0001,
8591 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8592 },
8593
8594
8595 /* 7.7.22.2 */
8596 { &hf_oran_ack_nack_req_id,
8597 { "ackNackReqId", "oran_fh_cus.ackNackReqId",
8598 FT_UINT16, BASE_HEX,
8599 NULL((void*)0), 0x0,
8600 "Indicates the ACK/NACK request ID of a section description", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8601 },
8602
8603 /* Subtree for next 2 items */
8604 { &hf_oran_frequency_range,
8605 { "Frequency Range", "oran_fh_cus.frequencyRange",
8606 FT_STRING, BASE_NONE,
8607 NULL((void*)0), 0x0,
8608 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8609 },
8610
8611 /* 7.7.12.4 */
8612 { &hf_oran_off_start_prb,
8613 { "offStartPrb", "oran_fh_cus.offStartPrb",
8614 FT_UINT8, BASE_DEC,
8615 NULL((void*)0), 0x0,
8616 "Offset of PRB range start", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8617 },
8618 /* 7.7.12.5 */
8619 { &hf_oran_num_prb,
8620 { "numPrb", "oran_fh_cus.numPrb",
8621 FT_UINT8, BASE_DEC,
8622 NULL((void*)0), 0x0,
8623 "Number of PRBs in PRB range", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8624 },
8625
8626 /* symbolId 8.3.3.7 */
8627 { &hf_oran_symbolId,
8628 { "Symbol Identifier", "oran_fh_cus.symbolId",
8629 FT_UINT8, BASE_DEC,
8630 NULL((void*)0), 0x3f,
8631 "Identifies a symbol number within a slot", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8632 },
8633
8634 /* startPrbu 8.3.3.11 */
8635 { &hf_oran_startPrbu,
8636 { "startPrbu", "oran_fh_cus.startPrbu",
8637 FT_UINT16, BASE_DEC,
8638 NULL((void*)0), 0x03ff,
8639 "starting PRB of user plane section", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8640 },
8641
8642 /* numPrbu 8.3.3.12 */
8643 { &hf_oran_numPrbu,
8644 { "numPrbu", "oran_fh_cus.numPrbu",
8645 FT_UINT8, BASE_DEC,
8646 NULL((void*)0), 0x0,
8647 "number of PRBs per user plane section", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8648 },
8649
8650 /* 7.7.1.3 */
8651 { &hf_oran_bfwCompParam,
8652 { "bfwCompParam", "oran_fh_cus.bfwCompParam",
8653 FT_STRING, BASE_NONE,
8654 NULL((void*)0), 0x0,
8655 "Beamforming weight compression parameter", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8656 },
8657
8658 /* 6.3.3.13 */
8659 { &hf_oran_udCompHdrMeth,
8660 { "User Data Compression Method", "oran_fh_cus.udCompHdrMeth",
8661 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
8662 RVALS(ud_comp_header_meth)((0 ? (const struct _range_string*)0 : ((ud_comp_header_meth)
)))
, 0x0f,
8663 "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)}
8664 },
8665 { &hf_oran_udCompHdrMeth_pref,
8666 { "User Data Compression Method", "oran_fh_cus.udCompHdrMeth",
8667 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
8668 RVALS(ud_comp_header_meth)((0 ? (const struct _range_string*)0 : ((ud_comp_header_meth)
)))
, 0x0,
8669 "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)}
8670 },
8671 /* 8.3.3.18 */
8672 { &hf_oran_udCompLen,
8673 { "udCompLen", "oran_fh_cus.udCompLen",
8674 FT_UINT16, BASE_DEC,
8675 NULL((void*)0), 0x0,
8676 "PRB field length in octets", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8677 },
8678
8679 /* 7.5.2.10 */
8680 { &hf_oran_udCompHdrIqWidth,
8681 { "User Data IQ width", "oran_fh_cus.udCompHdrWidth",
8682 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
8683 RVALS(ud_comp_header_width)((0 ? (const struct _range_string*)0 : ((ud_comp_header_width
))))
, 0xf0,
8684 "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)}
8685 },
8686 { &hf_oran_udCompHdrIqWidth_pref,
8687 { "User Data IQ width", "oran_fh_cus.udCompHdrWidth.pref",
8688 FT_UINT8, BASE_DEC,
8689 NULL((void*)0), 0x0,
8690 "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)}
8691 },
8692
8693 { &hf_oran_sinrCompHdrIqWidth_pref,
8694 { "SINR IQ width", "oran_fh_cus.sinrCompHdrWidth",
8695 FT_UINT8, BASE_DEC,
8696 NULL((void*)0), 0x0,
8697 "Defines the IQ bit width for SINR data in section type 9", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8698 },
8699 { &hf_oran_sinrCompHdrMeth_pref,
8700 { "SINR Compression Method", "oran_fh_cus.sinrCompHdrMeth",
8701 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
8702 RVALS(ud_comp_header_meth)((0 ? (const struct _range_string*)0 : ((ud_comp_header_meth)
)))
, 0x0,
8703 "Defines the compression method for SINR data in section type 9", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8704 },
8705
8706 /* Section 8.3.3.15 (not always present - depends upon meth) */
8707 { &hf_oran_udCompParam,
8708 { "User Data Compression Parameter", "oran_fh_cus.udCompParam",
8709 FT_STRING, BASE_NONE,
8710 NULL((void*)0), 0x0,
8711 "Applies to whatever compression method is specified by the associated sectionID's compMeth value", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8712 },
8713 /* 8.3.3.18 */
8714 { &hf_oran_sReSMask,
8715 { "sReSMask", "oran_fh_cus.sReSMask",
8716 FT_UINT16, BASE_HEX,
8717 NULL((void*)0), 0xf0ff,
8718 "selective RE sending mask", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8719 },
8720
8721 { &hf_oran_sReSMask_re12,
8722 { "RE-12", "oran_fh_cus.sReSMask-re12",
8723 FT_BOOLEAN, 16,
8724 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x8000,
8725 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8726 },
8727 { &hf_oran_sReSMask_re11,
8728 { "RE-11", "oran_fh_cus.sReSMask-re11",
8729 FT_BOOLEAN, 16,
8730 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x4000,
8731 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8732 },
8733 { &hf_oran_sReSMask_re10,
8734 { "RE-10", "oran_fh_cus.sReSMask-re10",
8735 FT_BOOLEAN, 16,
8736 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x2000,
8737 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8738 },
8739 { &hf_oran_sReSMask_re9,
8740 { "RE-9", "oran_fh_cus.sReSMask-re9",
8741 FT_BOOLEAN, 16,
8742 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x1000,
8743 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8744 },
8745 { &hf_oran_sReSMask_re8,
8746 { "RE-8", "oran_fh_cus.sReSMask-re8",
8747 FT_BOOLEAN, 16,
8748 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0080,
8749 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8750 },
8751 { &hf_oran_sReSMask_re7,
8752 { "RE-7", "oran_fh_cus.sReSMask-re7",
8753 FT_BOOLEAN, 16,
8754 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0040,
8755 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8756 },
8757 { &hf_oran_sReSMask_re6,
8758 { "RE-6", "oran_fh_cus.sReSMask-re6",
8759 FT_BOOLEAN, 16,
8760 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0020,
8761 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8762 },
8763 { &hf_oran_sReSMask_re5,
8764 { "RE-5", "oran_fh_cus.sReSMask-re5",
8765 FT_BOOLEAN, 16,
8766 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0010,
8767 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8768 },
8769 { &hf_oran_sReSMask_re4,
8770 { "RE-4", "oran_fh_cus.sReSMask-re4",
8771 FT_BOOLEAN, 16,
8772 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0008,
8773 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8774 },
8775 { &hf_oran_sReSMask_re3,
8776 { "RE-3", "oran_fh_cus.sReSMask-re3",
8777 FT_BOOLEAN, 16,
8778 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0004,
8779 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8780 },
8781 { &hf_oran_sReSMask_re2,
8782 { "RE-2", "oran_fh_cus.sReSMask-re2",
8783 FT_BOOLEAN, 16,
8784 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0002,
8785 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8786 },
8787 { &hf_oran_sReSMask_re1,
8788 { "RE-1", "oran_fh_cus.sReSMask-re1",
8789 FT_BOOLEAN, 16,
8790 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0001,
8791 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8792 },
8793
8794 /* 8.3.3.20 */
8795 { &hf_oran_sReSMask1,
8796 { "sReSMask1", "oran_fh_cus.sReSMask1",
8797 FT_UINT16, BASE_HEX,
8798 NULL((void*)0), 0x0fff,
8799 "selective RE sending mask 1", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8800 },
8801 /* 8.3.3.21 */
8802 { &hf_oran_sReSMask2,
8803 { "sReSMask2", "oran_fh_cus.sReSMask2",
8804 FT_UINT16, BASE_HEX,
8805 NULL((void*)0), 0x0fff,
8806 "selective RE sending mask 2", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8807 },
8808
8809 { &hf_oran_sReSMask1_2_re12,
8810 { "RE-12", "oran_fh_cus.sReSMask-re12",
8811 FT_BOOLEAN, 16,
8812 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0800,
8813 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8814 },
8815 { &hf_oran_sReSMask1_2_re11,
8816 { "RE-11", "oran_fh_cus.sReSMask-re11",
8817 FT_BOOLEAN, 16,
8818 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0400,
8819 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8820 },
8821 { &hf_oran_sReSMask1_2_re10,
8822 { "RE-10", "oran_fh_cus.sReSMask-re10",
8823 FT_BOOLEAN, 16,
8824 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0200,
8825 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8826 },
8827 { &hf_oran_sReSMask1_2_re9,
8828 { "RE-9", "oran_fh_cus.sReSMask-re9",
8829 FT_BOOLEAN, 16,
8830 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0100,
8831 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8832 },
8833
8834 /* Section 6.3.3.15 */
8835 { &hf_oran_iSample,
8836 { "iSample", "oran_fh_cus.iSample",
8837 FT_FLOAT, BASE_NONE,
8838 NULL((void*)0), 0x0,
8839 "In-phase Sample value", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8840 },
8841
8842 /* Section 6.3.3.16 */
8843 { &hf_oran_qSample,
8844 { "qSample", "oran_fh_cus.qSample",
8845 FT_FLOAT, BASE_NONE,
8846 NULL((void*)0), 0x0,
8847 "Quadrature Sample value", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8848 },
8849
8850 { &hf_oran_exponent,
8851 { "Exponent", "oran_fh_cus.exponent",
8852 FT_UINT8, BASE_DEC,
8853 NULL((void*)0), 0x0f,
8854 "Exponent applicable to the I & Q mantissas", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
8855 },
8856
8857 { &hf_oran_iq_user_data,
8858 { "IQ User Data", "oran_fh_cus.iq_user_data",
8859 FT_BYTES, BASE_NONE,
8860 NULL((void*)0), 0x0,
8861 "Used for the In-phase and Quadrature sample mantissa", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
8862 },
8863
8864
8865 { &hf_oran_u_section_ul_symbol_time,
8866 { "Microseconds since first UL U-plane frame for this symbol", "oran_fh_cus.us-since-first-ul-frame",
8867 FT_UINT32, BASE_DEC,
8868 NULL((void*)0), 0x0,
8869 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
8870 },
8871 { &hf_oran_u_section_ul_symbol_frames,
8872 { "Number of UL frames sent for this symbol", "oran_fh_cus.number-ul-frames-in-symbol",
8873 FT_UINT32, BASE_DEC,
8874 NULL((void*)0), 0x0,
8875 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
8876 },
8877 { &hf_oran_u_section_ul_symbol_first_frame,
8878 { "First UL frame for this symbol", "oran_fh_cus.first-ul-frame-in-symbol",
8879 FT_FRAMENUM, BASE_NONE,
8880 FRAMENUM_TYPE(FT_FRAMENUM_NONE)((gpointer) (glong) (FT_FRAMENUM_NONE)), 0x0,
8881 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
8882 },
8883 { &hf_oran_u_section_ul_symbol_last_frame,
8884 { "Last UL frame for this symbol", "oran_fh_cus.last-ul-frame-in-symbol",
8885 FT_FRAMENUM, BASE_NONE,
8886 FRAMENUM_TYPE(FT_FRAMENUM_NONE)((gpointer) (glong) (FT_FRAMENUM_NONE)), 0x0,
8887 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
8888 },
8889
8890 { &hf_oran_c_eAxC_ID,
8891 { "c_eAxC_ID", "oran_fh_cus.c_eaxc_id",
8892 FT_STRING, BASE_NONE,
8893 NULL((void*)0), 0x0,
8894 "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) }
8895 },
8896
8897 { &hf_oran_refa,
8898 { "RefA", "oran_fh_cus.refa",
8899 FT_STRING, BASE_NONE,
8900 NULL((void*)0), 0x0,
8901 "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) }
8902 },
8903
8904
8905 /* Section 7.5.2.15 */
8906 { &hf_oran_ciCompHdr,
8907 { "ciCompHdr", "oran_fh_cus.ciCompHdr",
8908 FT_STRING, BASE_NONE,
8909 NULL((void*)0), 0x0,
8910 "Channel Information Compression Header", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8911 },
8912 { &hf_oran_ciCompHdrMeth,
8913 { "User Data Compression Method", "oran_fh_cus.ciCompHdrMeth",
8914 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
8915 RVALS(ud_comp_header_meth)((0 ? (const struct _range_string*)0 : ((ud_comp_header_meth)
)))
, 0x0e,
8916 "Compression method for Channel Information", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8917 },
8918 { &hf_oran_ciCompHdrIqWidth,
8919 { "User Data IQ width", "oran_fh_cus.ciCompHdrWidth",
8920 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
8921 RVALS(ud_comp_header_width)((0 ? (const struct _range_string*)0 : ((ud_comp_header_width
))))
, 0xf0,
8922 "IQ bit width for Channel Information", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8923 },
8924 { &hf_oran_ciCompOpt,
8925 { "ciCompOpt", "oran_fh_cus.ciCompOpt",
8926 FT_UINT8, BASE_DEC,
8927 VALS(ci_comp_opt_vals)((0 ? (const struct _value_string*)0 : ((ci_comp_opt_vals)))), 0x01,
8928 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
8929 },
8930
8931 /* 7.7.11.7 */
8932 { &hf_oran_disable_bfws,
8933 { "disableBFWs", "oran_fh_cus.disableBFWs",
8934 FT_BOOLEAN, 8,
8935 NULL((void*)0), 0x80,
8936 "Indicate if BFWs under section extension are disabled", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
8937 },
8938 /* 7.7.11.8 */
8939 { &hf_oran_rad,
8940 { "RAD", "oran_fh_cus.rad",
8941 FT_BOOLEAN, 8,
8942 NULL((void*)0), 0x40,
8943 "Reset After PRB Discontinuity", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
8944 },
8945 /* 7.7.11.4 */
8946 { &hf_oran_num_bund_prbs,
8947 { "numBundPrb", "oran_fh_cus.numBundPrb",
8948 FT_UINT8, BASE_DEC,
8949 NULL((void*)0), 0x0,
8950 "Number of bundled PRBs per BFWs", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
8951 },
8952 { &hf_oran_beam_id,
8953 { "beamId", "oran_fh_cus.beamId",
8954 FT_UINT16, BASE_DEC,
8955 NULL((void*)0), 0x7fff,
8956 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
8957 },
8958 { &hf_oran_num_weights_per_bundle,
8959 { "Num weights per bundle", "oran_fh_cus.num_weights_per_bundle",
8960 FT_UINT16, BASE_DEC,
8961 NULL((void*)0), 0x0,
8962 "From dissector preference", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
8963 },
8964
8965 { &hf_oran_samples_prb,
8966 {"PRB", "oran_fh_cus.prb",
8967 FT_STRING, BASE_NONE,
8968 NULL((void*)0), 0x0,
8969 "Grouping of samples for a particular Physical Resource Block", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8970 },
8971
8972 /* 7.5.3.13 */
8973 { &hf_oran_ciSample,
8974 { "ciSample", "oran_fh_cus.ciSample",
8975 FT_STRING, BASE_NONE,
8976 NULL((void*)0), 0x0,
8977 "Sample (I and Q values)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8978 },
8979 { &hf_oran_ciIsample,
8980 { "ciIsample", "oran_fh_cus.ciISample",
8981 FT_FLOAT, BASE_NONE,
8982 NULL((void*)0), 0x0,
8983 "Channel information complex value - I part", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8984 },
8985 { &hf_oran_ciQsample,
8986 { "ciQsample", "oran_fh_cus.ciQSample",
8987 FT_FLOAT, BASE_NONE,
8988 NULL((void*)0), 0x0,
8989 "Channel information complex value - Q part", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8990 },
8991
8992 /* 7.7.10.2 */
8993 { &hf_oran_beamGroupType,
8994 { "beamGroupType", "oran_fh_cus.beamGroupType",
8995 FT_UINT8, BASE_DEC,
8996 VALS(beam_group_type_vals)((0 ? (const struct _value_string*)0 : ((beam_group_type_vals
))))
, 0xc0,
8997 "The type of beam grouping", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
8998 },
8999 /* 7.7.10.3 */
9000 { &hf_oran_numPortc,
9001 { "numPortc", "oran_fh_cus.numPortc",
9002 FT_UINT8, BASE_DEC,
9003 NULL((void*)0), 0x3f,
9004 "The number of eAxC ports", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9005 },
9006
9007 /* 7.7.4.2 (1 bit) */
9008 { &hf_oran_csf,
9009 { "csf", "oran_fh_cus.csf",
9010 FT_BOOLEAN, BASE_NONE,
9011 NULL((void*)0), 0x0,
9012 "constellation shift flag", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9013 },
9014 /* 7.7.4.3 */
9015 { &hf_oran_modcompscaler,
9016 { "modCompScaler", "oran_fh_cus.modcompscaler",
9017 FT_UINT16, BASE_DEC,
9018 NULL((void*)0), 0x7fff,
9019 "modulation compression scaler value", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9020 },
9021
9022 /* 7.7.5.1 */
9023 { &hf_oran_modcomp_param_set,
9024 { "Set", "oran_fh_cus.modcomp-param-set",
9025 FT_STRING, BASE_NONE,
9026 NULL((void*)0), 0x0,
9027 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9028 },
9029
9030
9031
9032 /* mcScaleReMask 7.7.5.2 (12 bits) */
9033
9034 /* First entry (starts with msb within byte) */
9035 { &hf_oran_mc_scale_re_mask_re1,
9036 { "RE 1", "oran_fh_cus.mcscalermask-RE1",
9037 FT_BOOLEAN, 16,
9038 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x8000,
9039 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9040 },
9041 { &hf_oran_mc_scale_re_mask_re2,
9042 { "RE 2", "oran_fh_cus.mcscalermask-RE2",
9043 FT_BOOLEAN, 16,
9044 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x4000,
9045 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9046 },
9047 { &hf_oran_mc_scale_re_mask_re3,
9048 { "RE 3", "oran_fh_cus.mcscalermask-RE3",
9049 FT_BOOLEAN, 16,
9050 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x2000,
9051 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9052 },
9053 { &hf_oran_mc_scale_re_mask_re4,
9054 { "RE 4", "oran_fh_cus.mcscalermask-RE4",
9055 FT_BOOLEAN, 16,
9056 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x1000,
9057 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9058 },
9059 { &hf_oran_mc_scale_re_mask_re5,
9060 { "RE 5", "oran_fh_cus.mcscalermask-RE5",
9061 FT_BOOLEAN, 16,
9062 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0800,
9063 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9064 },
9065 { &hf_oran_mc_scale_re_mask_re6,
9066 { "RE 6", "oran_fh_cus.mcscalermask-RE6",
9067 FT_BOOLEAN, 16,
9068 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0400,
9069 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9070 },
9071 { &hf_oran_mc_scale_re_mask_re7,
9072 { "RE 7", "oran_fh_cus.mcscalermask-RE7",
9073 FT_BOOLEAN, 16,
9074 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0200,
9075 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9076 },
9077 { &hf_oran_mc_scale_re_mask_re8,
9078 { "RE 8", "oran_fh_cus.mcscalermask-RE8",
9079 FT_BOOLEAN, 16,
9080 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0100,
9081 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9082 },
9083 { &hf_oran_mc_scale_re_mask_re9,
9084 { "RE 9", "oran_fh_cus.mcscalermask-RE9",
9085 FT_BOOLEAN, 16,
9086 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0080,
9087 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9088 },
9089 { &hf_oran_mc_scale_re_mask_re10,
9090 { "RE 10", "oran_fh_cus.mcscalermask-RE10",
9091 FT_BOOLEAN, 16,
9092 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0040,
9093 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9094 },
9095 { &hf_oran_mc_scale_re_mask_re11,
9096 { "RE 11", "oran_fh_cus.mcscalermask-RE11",
9097 FT_BOOLEAN, 16,
9098 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0020,
9099 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9100 },
9101 { &hf_oran_mc_scale_re_mask_re12,
9102 { "RE 12", "oran_fh_cus.mcscalermask-RE12",
9103 FT_BOOLEAN, 16,
9104 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0010,
9105 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9106 },
9107
9108 /* Even tries entry (starts with 5th bit within byte) */
9109 { &hf_oran_mc_scale_re_mask_re1_even,
9110 { "RE 1", "oran_fh_cus.mcscalermask-RE1",
9111 FT_BOOLEAN, 16,
9112 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0800,
9113 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9114 },
9115 { &hf_oran_mc_scale_re_mask_re2_even,
9116 { "RE 2", "oran_fh_cus.mcscalermask-RE2",
9117 FT_BOOLEAN, 16,
9118 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0400,
9119 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9120 },
9121 { &hf_oran_mc_scale_re_mask_re3_even,
9122 { "RE 3", "oran_fh_cus.mcscalermask-RE3",
9123 FT_BOOLEAN, 16,
9124 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0200,
9125 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9126 },
9127 { &hf_oran_mc_scale_re_mask_re4_even,
9128 { "RE 4", "oran_fh_cus.mcscalermask-RE4",
9129 FT_BOOLEAN, 16,
9130 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0100,
9131 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9132 },
9133 { &hf_oran_mc_scale_re_mask_re5_even,
9134 { "RE 5", "oran_fh_cus.mcscalermask-RE5",
9135 FT_BOOLEAN, 16,
9136 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0080,
9137 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9138 },
9139 { &hf_oran_mc_scale_re_mask_re6_even,
9140 { "RE 6", "oran_fh_cus.mcscalermask-RE6",
9141 FT_BOOLEAN, 16,
9142 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0040,
9143 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9144 },
9145 { &hf_oran_mc_scale_re_mask_re7_even,
9146 { "RE 7", "oran_fh_cus.mcscalermask-RE7",
9147 FT_BOOLEAN, 16,
9148 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0020,
9149 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9150 },
9151 { &hf_oran_mc_scale_re_mask_re8_even,
9152 { "RE 8", "oran_fh_cus.mcscalermask-RE8",
9153 FT_BOOLEAN, 16,
9154 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0010,
9155 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9156 },
9157 { &hf_oran_mc_scale_re_mask_re9_even,
9158 { "RE 9", "oran_fh_cus.mcscalermask-RE9",
9159 FT_BOOLEAN, 16,
9160 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0008,
9161 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9162 },
9163 { &hf_oran_mc_scale_re_mask_re10_even,
9164 { "RE 10", "oran_fh_cus.mcscalermask-RE10",
9165 FT_BOOLEAN, 16,
9166 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0004,
9167 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9168 },
9169 { &hf_oran_mc_scale_re_mask_re11_even,
9170 { "RE 11", "oran_fh_cus.mcscalermask-RE11",
9171 FT_BOOLEAN, 16,
9172 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0002,
9173 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9174 },
9175 { &hf_oran_mc_scale_re_mask_re12_even,
9176 { "RE 12", "oran_fh_cus.mcscalermask-RE12",
9177 FT_BOOLEAN, 16,
9178 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0001,
9179 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9180 },
9181
9182 { &hf_oran_mc_scale_re_mask,
9183 { "mcScaleReMask", "oran_fh_cus.mcscaleremask",
9184 FT_UINT16, BASE_HEX,
9185 NULL((void*)0), 0xfff0,
9186 "modulation compression power scale RE mask", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9187 },
9188 { &hf_oran_mc_scale_re_mask_even,
9189 { "mcScaleReMask", "oran_fh_cus.mcscaleremask",
9190 FT_UINT16, BASE_HEX,
9191 NULL((void*)0), 0x0fff,
9192 "modulation compression power scale RE mask", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9193 },
9194
9195 /* mcScaleOffset 7.7.5.4 (15 bits) */
9196 { &hf_oran_mc_scale_offset,
9197 { "mcScaleOffset", "oran_fh_cus.mcscaleoffset",
9198 FT_UINT24, BASE_DEC,
9199 NULL((void*)0), 0x0,
9200 "scaling value for modulation compression", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9201 },
9202 /* eAxCmask (7.7.7.2) */
9203 { &hf_oran_eAxC_mask,
9204 { "eAxC Mask", "oran_fh_cus.eaxcmask",
9205 FT_UINT16, BASE_HEX,
9206 NULL((void*)0), 0xffff,
9207 "Which eAxC_ID values the C-Plane message applies to", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9208 },
9209 /* technology (interface name) 7.7.9.2 */
9210 { &hf_oran_technology,
9211 { "Technology", "oran_fh_cus.technology",
9212 FT_UINT8, BASE_DEC,
9213 VALS(interface_name_vals)((0 ? (const struct _value_string*)0 : ((interface_name_vals)
)))
, 0x0,
9214 "Interface name (that C-PLane section applies to)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9215 },
9216 /* Exttype 14 (7.7.14.2) */
9217 { &hf_oran_nullLayerInd,
9218 { "nullLayerInd", "oran_fh_cus.nulllayerind",
9219 FT_BOOLEAN, BASE_NONE,
9220 NULL((void*)0), 0x0,
9221 "Whether corresponding layer is nulling-layer or not", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9222 },
9223
9224 /* Exttype 19 */
9225 /* 7.7.19.3 */
9226 { &hf_oran_se19_repetition,
9227 { "repetition", "oran_fh_cus.repetition",
9228 FT_BOOLEAN, BASE_NONE,
9229 TFS(&repetition_se19_tfs)((0 ? (const struct true_false_string*)0 : ((&repetition_se19_tfs
))))
, 0x0,
9230 "repeat port info flag", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9231 },
9232 /* 7.7.19.8 */
9233 /* TODO: break down into each RE as done for 7.5.3.5 ? */
9234 { &hf_oran_portReMask,
9235 { "portReMask", "oran_fh_cus.portReMask",
9236 FT_BOOLEAN, 16,
9237 TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, 0x0fff,
9238 "RE bitmask per port", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9239 },
9240 /* 7.7.19.9 */
9241 { &hf_oran_portSymbolMask,
9242 { "portSymbolMask", "oran_fh_cus.portSymbolMask",
9243 FT_BOOLEAN, 16,
9244 TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, 0x3fff,
9245 "Symbol bitmask port port", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9246 },
9247
9248 { &hf_oran_ext19_port,
9249 {"Port", "oran_fh_cus.ext19.port",
9250 FT_STRING, BASE_NONE,
9251 NULL((void*)0), 0x0,
9252 "Entry for a given port in ext19", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9253 },
9254
9255 /* Ext 13 */
9256 { &hf_oran_prb_allocation,
9257 {"PRB allocation", "oran_fh_cus.prb-allocation",
9258 FT_STRING, BASE_NONE,
9259 NULL((void*)0), 0x0,
9260 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9261 },
9262 /* 7.7.13.2 */
9263 { &hf_oran_nextSymbolId,
9264 { "nextSymbolId", "oran_fh_cus.nextSymbolId",
9265 FT_UINT8, BASE_DEC,
9266 NULL((void*)0), 0x3c,
9267 "offset of PRB range start", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9268 },
9269 /* 7.7.13.3 */
9270 { &hf_oran_nextStartPrbc,
9271 { "nextStartPrbc", "oran_fh_cus.nextStartPrbc",
9272 FT_UINT16, BASE_DEC,
9273 NULL((void*)0), 0x03ff,
9274 "number of PRBs in PRB range", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9275 },
9276
9277 /* Puncturing patters as appears in SE 20 */
9278 { &hf_oran_puncPattern,
9279 { "puncPattern", "oran_fh_cus.puncPattern",
9280 FT_STRING, BASE_NONE,
9281 NULL((void*)0), 0x0,
9282 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9283 },
9284
9285 /* 7.7.20.2 numPuncPatterns */
9286 { &hf_oran_numPuncPatterns,
9287 { "numPuncPatterns", "oran_fh_cus.numPuncPatterns",
9288 FT_UINT8, BASE_DEC,
9289 NULL((void*)0), 0x0,
9290 "number of puncturing patterns", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9291 },
9292 /* 7.7.20.3 symbolMask */
9293 { &hf_oran_symbolMask_ext20,
9294 { "symbolMask", "oran_fh_cus.symbolMask",
9295 FT_UINT16, BASE_HEX,
9296 NULL((void*)0), 0xfffc,
9297 "Bitmask where each bit indicates the symbols associated with the puncturing pattern", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9298 },
9299 /* 7.7.20.4 startPuncPrb */
9300 { &hf_oran_startPuncPrb,
9301 { "startPuncPrb", "oran_fh_cus.startPuncPrb",
9302 FT_UINT16, BASE_DEC,
9303 NULL((void*)0), 0x03ff,
9304 "starting PRB to which one puncturing pattern applies", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9305 },
9306 /* 7.7.20.5 numPuncPrb */
9307 { &hf_oran_numPuncPrb,
9308 { "numPuncPrb", "oran_fh_cus.numPuncPrb",
9309 FT_UINT8, BASE_DEC,
9310 NULL((void*)0), 0x0,
9311 "the number of PRBs of the puncturing pattern", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9312 },
9313 /* 7.7.20.6 puncReMask */
9314 { &hf_oran_puncReMask,
9315 { "puncReMask", "oran_fh_cus.puncReMask",
9316 FT_UINT16, BASE_DEC,
9317 NULL((void*)0), 0xffc0,
9318 "puncturing pattern RE mask", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9319 },
9320 /* 7.7.20.12 multiSDScope */
9321 { &hf_oran_multiSDScope,
9322 { "multiSDScope", "oran_fh_cus.multiSDScope",
9323 FT_BOOLEAN, 8,
9324 TFS(&multi_sd_scope_tfs)((0 ? (const struct true_false_string*)0 : ((&multi_sd_scope_tfs
))))
, 0x02,
9325 "multiple section description scope flag", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9326 },
9327 /* 7.7.20.4 rbgIncl */
9328 { &hf_oran_RbgIncl,
9329 { "rbgIncl", "oran_fh_cus.rbgIncl",
9330 FT_BOOLEAN, 8,
9331 NULL((void*)0), 0x01,
9332 "rbg included flag", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9333 },
9334
9335 /* 7.7.21.2 ciPrbGroupSize */
9336 { &hf_oran_ci_prb_group_size,
9337 { "ciPrbGroupSize", "oran_fh_cus.ciPrbGroupSize",
9338 FT_UINT8, BASE_DEC,
9339 NULL((void*)0), 0x0,
9340 "channel information PRB group size", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9341 },
9342 /* 7.21.3 */
9343 { &hf_oran_prg_size_st5,
9344 { "prgSize", "oran_fh_cus.prgSize",
9345 FT_UINT8, BASE_DEC,
9346 VALS(prg_size_st5_vals)((0 ? (const struct _value_string*)0 : ((prg_size_st5_vals)))
)
, 0x03,
9347 "precoding resource block group size", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9348 },
9349 { &hf_oran_prg_size_st6,
9350 { "prgSize", "oran_fh_cus.prgSize",
9351 FT_UINT8, BASE_DEC,
9352 VALS(prg_size_st6_vals)((0 ? (const struct _value_string*)0 : ((prg_size_st6_vals)))
)
, 0x03,
9353 "precoding resource block group size", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9354 },
9355
9356 /* 7.7.17.2 numUeID */
9357 { &hf_oran_num_ueid,
9358 { "numUeID", "oran_fh_cus.numUeID",
9359 FT_UINT8, BASE_DEC,
9360 NULL((void*)0), 0x0,
9361 "number of ueIDs per user", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9362 },
9363
9364 /* 7.7.16.2 antMask */
9365 { &hf_oran_antMask,
9366 { "antMask", "oran_fh_cus.antMask",
9367 FT_UINT64, BASE_HEX,
9368 NULL((void*)0), 0xffffffffffffffff,
9369 "indices of antennas to be pre-combined per RX endpoint", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9370 },
9371
9372 /* 7.7.18.2 transmissionWindowOffset */
9373 { &hf_oran_transmissionWindowOffset,
9374 { "transmissionWindowOffset", "oran_fh_cus.transmissionWindowOffset",
9375 FT_UINT16, BASE_DEC,
9376 NULL((void*)0), 0x0,
9377 "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)}
9378 },
9379 /* 7.7.18.3 transmissionWindowSize */
9380 { &hf_oran_transmissionWindowSize,
9381 { "transmissionWindowSize", "oran_fh_cus.transmissionWindowSize",
9382 FT_UINT16, BASE_DEC,
9383 NULL((void*)0), 0x3fff,
9384 "size of the transmission window in resolution µs", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9385 },
9386 /* 7.7.18.4 toT */
9387 { &hf_oran_toT,
9388 { "toT", "oran_fh_cus.toT",
9389 FT_UINT8, BASE_DEC,
9390 VALS(type_of_transmission_vals)((0 ? (const struct _value_string*)0 : ((type_of_transmission_vals
))))
, 0x03,
9391 "type of transmission", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9392 },
9393
9394 /* 7.7.2.2 bfaCompHdr */
9395 { &hf_oran_bfaCompHdr,
9396 { "bfaCompHdr", "oran_fh_cus.bfaCompHdr",
9397 FT_STRING, BASE_NONE,
9398 NULL((void*)0), 0x0,
9399 "beamforming attributes compression header", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9400 },
9401 /* 7.7.2.2-2: bfAzPtWidth */
9402 { &hf_oran_bfAzPtWidth,
9403 { "bfAzPtWidth", "oran_fh_cus.bfAzPtWidth",
9404 FT_UINT8, BASE_DEC,
9405 VALS(bfa_bw_vals)((0 ? (const struct _value_string*)0 : ((bfa_bw_vals)))), 0x38,
9406 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9407 },
9408 /* 7.7.2.2-3: bfZePtWidth */
9409 { &hf_oran_bfZePtWidth,
9410 { "bfZePtWidth", "oran_fh_cus.bfZePtWidth",
9411 FT_UINT8, BASE_DEC,
9412 VALS(bfa_bw_vals)((0 ? (const struct _value_string*)0 : ((bfa_bw_vals)))), 0x07,
9413 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9414 },
9415 /* 7.7.2.2-4: bfAz3ddWidth */
9416 { &hf_oran_bfAz3ddWidth,
9417 { "bfAz3ddWidth", "oran_fh_cus.bfAz3ddWidth",
9418 FT_UINT8, BASE_DEC,
9419 VALS(bfa_bw_vals)((0 ? (const struct _value_string*)0 : ((bfa_bw_vals)))), 0x38,
9420 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9421 },
9422 /* 7.7.2.2-5: bfZe3ddWidth */
9423 { &hf_oran_bfZe3ddWidth,
9424 { "bfZe3ddWidth", "oran_fh_cus.bfZe3ddWidth",
9425 FT_UINT8, BASE_DEC,
9426 VALS(bfa_bw_vals)((0 ? (const struct _value_string*)0 : ((bfa_bw_vals)))), 0x07,
9427 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9428 },
9429
9430 /* 7.7.2.3 bfAzPt */
9431 { &hf_oran_bfAzPt,
9432 { "bfAzPt", "oran_fh_cus.bfAzPt",
9433 FT_UINT8, BASE_DEC,
9434 NULL((void*)0), 0x0,
9435 "beamforming azimuth pointing parameter", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9436 },
9437 /* 7.7.2.4 bfZePt */
9438 { &hf_oran_bfZePt,
9439 { "bfZePt", "oran_fh_cus.bfZePt",
9440 FT_UINT8, BASE_DEC,
9441 NULL((void*)0), 0x0,
9442 "beamforming zenith pointing parameter", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9443 },
9444 /* 7.7.2.5 bfAz3dd */
9445 { &hf_oran_bfAz3dd,
9446 { "bfAz3dd", "oran_fh_cus.bfAz3dd",
9447 FT_UINT8, BASE_DEC,
9448 NULL((void*)0), 0x0,
9449 "beamforming azimuth beamwidth parameter", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9450 },
9451 /* 7.7.2.6 bfZe3dd */
9452 { &hf_oran_bfZe3dd,
9453 { "bfZe3dd", "oran_fh_cus.bfZe3dd",
9454 FT_UINT8, BASE_DEC,
9455 NULL((void*)0), 0x0,
9456 "beamforming zenith beamwidth parameter", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9457 },
9458
9459 /* 7.7.2.7 bfAzSl */
9460 { &hf_oran_bfAzSl,
9461 { "bfAzSl", "oran_fh_cus.bfAzSl",
9462 FT_UINT8, BASE_DEC,
9463 VALS(sidelobe_suppression_vals)((0 ? (const struct _value_string*)0 : ((sidelobe_suppression_vals
))))
, 0x38,
9464 "beamforming azimuth sidelobe parameter", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9465 },
9466 /* 7.7.2.8 bfZeSl */
9467 { &hf_oran_bfZeSl,
9468 { "bfZeSl", "oran_fh_cus.bfZeSl",
9469 FT_UINT8, BASE_DEC,
9470 VALS(sidelobe_suppression_vals)((0 ? (const struct _value_string*)0 : ((sidelobe_suppression_vals
))))
, 0x07,
9471 "beamforming zenith sidelobe parameter", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9472 },
9473
9474 /* 7.5.2.17 */
9475 { &hf_oran_cmd_scope,
9476 { "cmdScope", "oran_fh_cus.cmdScope",
9477 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
9478 RVALS(cmd_scope_vals)((0 ? (const struct _range_string*)0 : ((cmd_scope_vals)))), 0x0f,
9479 "command scope", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9480 },
9481 /* 7.5.2.18 */
9482 { &hf_oran_number_of_st4_cmds,
9483 { "numberOfST4Cmds", "oran_fh_cus.numberOfST4Cmds",
9484 FT_UINT8, BASE_DEC,
9485 NULL((void*)0), 0x0,
9486 "Number of Section Type 4 commands", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9487 },
9488
9489 { &hf_oran_st4_cmd_header,
9490 { "Command common header", "oran_fh_cus.st4CmdCommonHeader",
9491 FT_STRING, BASE_NONE,
9492 NULL((void*)0), 0x0,
9493 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9494 },
9495
9496 /* 7.5.3.38 */
9497 { &hf_oran_st4_cmd_type,
9498 { "st4CmdType", "oran_fh_cus.st4CmdType",
9499 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
9500 RVALS(st4_cmd_type_vals)((0 ? (const struct _range_string*)0 : ((st4_cmd_type_vals)))
)
, 0x0,
9501 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9502 },
9503 /* 7.5.3.39 */
9504 { &hf_oran_st4_cmd_len,
9505 { "st4CmdLen", "oran_fh_cus.st4CmdLen",
9506 FT_UINT16, BASE_DEC,
9507 NULL((void*)0), 0x0,
9508 "Length of command in 32-bit words", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9509 },
9510 /* 7.5.3.40 */
9511 { &hf_oran_st4_cmd_num_slots,
9512 { "numSlots", "oran_fh_cus.st4NumSlots",
9513 FT_UINT8, BASE_DEC,
9514 NULL((void*)0), 0x0,
9515 "Contiguous slots for which command is applicable", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9516 },
9517 /* 7.5.3.41 */
9518 { &hf_oran_st4_cmd_ack_nack_req_id,
9519 { "ackNackReqId", "oran_fh_cus.ackNackReqId",
9520 FT_UINT16, BASE_DEC,
9521 NULL((void*)0), 0x0,
9522 "ACK/NACK Request Id", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9523 },
9524
9525 { &hf_oran_st4_cmd,
9526 { "Command", "oran_fh_cus.st4Cmd",
9527 FT_STRING, BASE_NONE,
9528 NULL((void*)0), 0x0,
9529 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9530 },
9531
9532 /* 7.5.3.52 */
9533 { &hf_oran_sleepmode_trx,
9534 { "sleepMode", "oran_fh_cus.sleepMode",
9535 FT_UINT8, BASE_HEX,
9536 VALS(sleep_mode_trx_vals)((0 ? (const struct _value_string*)0 : ((sleep_mode_trx_vals)
)))
, 0x03,
9537 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9538 },
9539 { &hf_oran_sleepmode_asm,
9540 { "sleepMode", "oran_fh_cus.sleepMode",
9541 FT_UINT8, BASE_HEX,
9542 VALS(sleep_mode_asm_vals)((0 ? (const struct _value_string*)0 : ((sleep_mode_asm_vals)
)))
, 0x03,
9543 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9544 },
9545
9546 /* 7.5.3.51 */
9547 { &hf_oran_log2maskbits,
9548 { "log2MaskBits", "oran_fh_cus.log2MaskBits",
9549 FT_UINT8, BASE_HEX,
9550 VALS(log2maskbits_vals)((0 ? (const struct _value_string*)0 : ((log2maskbits_vals)))
)
, 0x3c,
9551 "Number of bits to appear in antMask", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9552 },
9553 /* 7.5.3.53 */
9554 { &hf_oran_num_slots_ext,
9555 { "numSlotsExt", "oran_fh_cus.numSlotsExt",
9556 FT_UINT24, BASE_HEX,
9557 NULL((void*)0), 0x0fffff,
9558 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9559 },
9560 /* 7.5.3.54 */
9561 { &hf_oran_antMask_trx_control,
9562 { "antMask", "oran_fh_cus.trxControl.antMask",
9563 FT_BYTES, BASE_NONE,
9564 NULL((void*)0), 0x0,
9565 "which antennas should sleep or wake-up", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9566 },
9567 /* 7.5.3.55 */
9568 { &hf_oran_ready,
9569 { "ready", "oran_fh_cus.ready",
9570 FT_BOOLEAN, 8,
9571 TFS(&ready_tfs)((0 ? (const struct true_false_string*)0 : ((&ready_tfs))
))
, 0x01,
9572 "wake-up ready indicator", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9573 },
9574 /* 7.5.3.34 */
9575 { &hf_oran_number_of_acks,
9576 { "numberOfAcks", "oran_fh_cus.numberOfAcks",
9577 FT_UINT8, BASE_DEC,
9578 NULL((void*)0), 0x0,
9579 "number of ACKs for one eAxC_ID", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9580 },
9581 /* 7.5.3.35 */
9582 { &hf_oran_number_of_nacks,
9583 { "numberOfNacks", "oran_fh_cus.numberOfNacks",
9584 FT_UINT8, BASE_DEC,
9585 NULL((void*)0), 0x0,
9586 "number of NACKs for one eAxC_ID", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9587 },
9588 /* 7.5.3.36 */
9589 { &hf_oran_ackid,
9590 { "ackId", "oran_fh_cus.ackId",
9591 FT_UINT16, BASE_DEC,
9592 NULL((void*)0), 0x0,
9593 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9594 },
9595 /* 7.5.3.37 */
9596 { &hf_oran_nackid,
9597 { "nackId", "oran_fh_cus.nackId",
9598 FT_UINT16, BASE_DEC,
9599 NULL((void*)0), 0x0,
9600 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9601 },
9602
9603 /* Links between acknack requests & responses */
9604 { &hf_oran_acknack_request_frame,
9605 { "Request Frame", "oran_fh_cus.ackNackId.request-frame",
9606 FT_FRAMENUM, BASE_NONE,
9607 FRAMENUM_TYPE(FT_FRAMENUM_REQUEST)((gpointer) (glong) (FT_FRAMENUM_REQUEST)), 0x0,
9608 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9609 },
9610 { &hf_oran_acknack_request_time,
9611 { "Time since request in ms", "oran_fh_cus.ackNackId.time-since-request",
9612 FT_UINT32, BASE_DEC,
9613 NULL((void*)0), 0x0,
9614 "Time between request and response", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9615 },
9616 { &hf_oran_acknack_request_type,
9617 { "Request Type", "oran_fh_cus.ackNackId.request-type",
9618 FT_UINT32, BASE_DEC,
9619 VALS(acknack_type_vals)((0 ? (const struct _value_string*)0 : ((acknack_type_vals)))
)
, 0x0,
9620 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9621 },
9622 { &hf_oran_acknack_response_frame,
9623 { "Response Frame", "oran_fh_cus.ackNackId.response-frame",
9624 FT_FRAMENUM, BASE_NONE,
9625 FRAMENUM_TYPE(FT_FRAMENUM_RESPONSE)((gpointer) (glong) (FT_FRAMENUM_RESPONSE)), 0x0,
9626 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9627 },
9628 { &hf_oran_acknack_response_time,
9629 { "Time to response in ms", "oran_fh_cus.ackNackId.time-to-response",
9630 FT_UINT32, BASE_DEC,
9631 NULL((void*)0), 0x0,
9632 "Time between request and response", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9633 },
9634
9635 /* 7.5.3.43 */
9636 { &hf_oran_disable_tdbfns,
9637 { "disableTDBFNs", "oran_fh_cus.disableTDBFNs",
9638 FT_BOOLEAN, 8,
9639 TFS(&disable_tdbfns_tfs)((0 ? (const struct true_false_string*)0 : ((&disable_tdbfns_tfs
))))
, 0x80,
9640 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9641 },
9642
9643 /* 7.5.3.44 */
9644 { &hf_oran_td_beam_group,
9645 { "tdBeamGrp", "oran_fh_cus.tdBeamGrp",
9646 FT_UINT16, BASE_HEX,
9647 NULL((void*)0), 0x7fff,
9648 "Applies to symbolMask in command header", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9649 },
9650 /* 7.5.3.43 */
9651 { &hf_oran_disable_tdbfws,
9652 { "disableTDBFWs", "oran_fh_cus.disableTDBFWs",
9653 FT_BOOLEAN, 8,
9654 TFS(&beam_numbers_included_tfs)((0 ? (const struct true_false_string*)0 : ((&beam_numbers_included_tfs
))))
, 0x80,
9655 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9656 },
9657
9658 /* 7.5.3.56 */
9659 { &hf_oran_td_beam_num,
9660 { "tdBeamNum", "oran_fh_cus.tdBeamNum",
9661 FT_UINT16, BASE_HEX,
9662 NULL((void*)0), 0x7fff,
9663 "time-domain beam number", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9664 },
9665
9666 /* 7.5.3.49 */
9667 { &hf_oran_dir_pattern,
9668 { "dirPattern", "oran_fh_cus.dirPattern",
9669 FT_BOOLEAN, 16,
9670 TFS(&symbol_direction_tfs)((0 ? (const struct true_false_string*)0 : ((&symbol_direction_tfs
))))
, 0x3fff,
9671 "symbol data direction (gNB Tx/Rx) pattern", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9672 },
9673 /* 7.5.3.50 */
9674 { &hf_oran_guard_pattern,
9675 { "guardPattern", "oran_fh_cus.guardPattern",
9676 FT_BOOLEAN, 16,
9677 TFS(&symbol_guard_tfs)((0 ? (const struct true_false_string*)0 : ((&symbol_guard_tfs
))))
, 0x3fff,
9678 "guard pattern bitmask", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9679 },
9680
9681 /* For convenient filtering */
9682 { &hf_oran_cplane,
9683 { "C-Plane", "oran_fh_cus.c-plane",
9684 FT_NONE, BASE_NONE,
9685 NULL((void*)0), 0x0,
9686 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9687 },
9688 { &hf_oran_uplane,
9689 { "U-Plane", "oran_fh_cus.u-plane",
9690 FT_NONE, BASE_NONE,
9691 NULL((void*)0), 0x0,
9692 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9693 },
9694 { &hf_oran_bf,
9695 { "BeamForming", "oran_fh_cus.bf",
9696 FT_NONE, BASE_NONE,
9697 NULL((void*)0), 0x0,
9698 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9699 },
9700 { &hf_oran_zero_prb,
9701 { "Zero PRB", "oran_fh_cus.zero-prb",
9702 FT_NONE, BASE_NONE,
9703 NULL((void*)0), 0x0,
9704 "All of the REs in this PRB are zero", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9705 },
9706 { &hf_oran_nonzero_prb,
9707 { "Non-Zero PRB", "oran_fh_cus.nonzero-prb",
9708 FT_NONE, BASE_NONE,
9709 NULL((void*)0), 0x0,
9710 "Not all of the REs in this PRB are zero", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9711 },
9712 { &hf_oran_bundle_weights_all_zero,
9713 { "Bundle Weights all zero", "oran_fh_cus.zero-bundle",
9714 FT_NONE, BASE_NONE,
9715 NULL((void*)0), 0x0,
9716 "All of the weights in a bundle are zero", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9717 },
9718
9719
9720 /* 5.1.3.2.7 */
9721 { &hf_oran_ecpri_pcid,
9722 { "ecpriPcid", "oran_fh_cus.ecpriPcid",
9723 FT_NONE, BASE_NONE,
9724 NULL((void*)0), 0x0,
9725 "IQ data transfer message series identifier", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9726 },
9727 { &hf_oran_ecpri_rtcid,
9728 { "ecpriRtcid", "oran_fh_cus.ecpriRtcid",
9729 FT_NONE, BASE_NONE,
9730 NULL((void*)0), 0x0,
9731 "Real time control data identifier", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9732 },
9733 /* 5.1.3.2.8 */
9734 { &hf_oran_ecpri_seqid,
9735 { "ecpriSeqid", "oran_fh_cus.ecpriSeqid",
9736 FT_NONE, BASE_NONE,
9737 NULL((void*)0), 0x0,
9738 "message identifier", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9739 },
9740
9741 /* 7.7.23.2 */
9742 { &hf_oran_num_sym_prb_pattern,
9743 { "numSymPrbPattern", "oran_fh_cus.numSymPrbPattern",
9744 FT_UINT8, BASE_DEC,
9745 NULL((void*)0), 0xf0,
9746 "number of symbol and resource block patterns", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9747 },
9748 /* 7.7.23.11 */
9749 { &hf_oran_prb_mode,
9750 { "prbMode", "oran_fh_cus.prbMode",
9751 FT_BOOLEAN, 8,
9752 TFS(&prb_mode_tfs)((0 ? (const struct true_false_string*)0 : ((&prb_mode_tfs
))))
, 0x01,
9753 "PRB Mode", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9754 },
9755
9756 { &hf_oran_sym_prb_pattern,
9757 { "symPrbPattern", "oran_fh_cus.symPrbPattern",
9758 FT_STRING, BASE_NONE,
9759 NULL((void*)0), 0x0,
9760 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9761 },
9762
9763 /* 7.7.23.3 */
9764 { &hf_oran_sym_mask,
9765 { "symMask", "oran_fh_cus.symMask",
9766 FT_UINT16, BASE_HEX,
9767 NULL((void*)0), 0x3fff,
9768 "symbol mask part of symPrbPattern", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9769 },
9770 /* 7.7.23.5 */
9771 {&hf_oran_num_mc_scale_offset,
9772 {"numMcScaleOffset", "oran_fh_cus.numMcScaleOffset",
9773 FT_UINT8, BASE_DEC,
9774 NULL((void*)0), 0xf0,
9775 "number of modulation compression scaling value per symPrbPattern",
9776 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9777 },
9778 /* 7.7.23.4 */
9779 { &hf_oran_prb_pattern,
9780 { "prbPattern", "oran_fh_cus.prbPattern",
9781 FT_UINT8, BASE_DEC,
9782 NULL((void*)0), 0x0f,
9783 "resource block pattern part of symPrbPattern", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9784 },
9785
9786 /* 7.7.3.2 */
9787 { &hf_oran_codebook_index,
9788 { "codebookIndex", "oran_fh_cus.codebookIndex",
9789 FT_UINT8, BASE_DEC,
9790 NULL((void*)0), 0x0,
9791 "precoder codebook used for transmission", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9792 },
9793 /* 7.7.3.3 */
9794 { &hf_oran_layerid,
9795 { "layerID", "oran_fh_cus.layerID",
9796 FT_UINT8, BASE_DEC,
9797 NULL((void*)0), 0xf0,
9798 "Layer ID for DL transmission", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9799 },
9800 /* 7.7.3.5 */
9801 { &hf_oran_numlayers,
9802 { "numLayers", "oran_fh_cus.numLayers",
9803 FT_UINT8, BASE_DEC,
9804 NULL((void*)0), 0x0f,
9805 "number of layers for DL transmission", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9806 },
9807 /* 7.7.3.4 */
9808 { &hf_oran_txscheme,
9809 { "txScheme", "oran_fh_cus.txScheme",
9810 FT_UINT8, BASE_DEC,
9811 NULL((void*)0), 0xf0,
9812 "transmission scheme", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9813 },
9814 /* 7.7.3.6 */
9815 { &hf_oran_crs_remask,
9816 { "crsReMask", "oran_fh_cus.crsReMask",
9817 FT_UINT16, BASE_HEX,
9818 NULL((void*)0), 0x0fff,
9819 "CRS resource element mask", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9820 },
9821 /* 7.7.3.8 */
9822 { &hf_oran_crs_shift,
9823 { "crsShift", "oran_fh_cus.crsShift",
9824 FT_UINT8, BASE_HEX,
9825 NULL((void*)0), 0x80,
9826 "CRS resource element mask", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9827 },
9828 /* 7.7.3.7 */
9829 { &hf_oran_crs_symnum,
9830 { "crsSymNum", "oran_fh_cus.crsSymNum",
9831 FT_UINT8, BASE_DEC,
9832 NULL((void*)0), 0x0f,
9833 "CRS symbol number indication", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9834 },
9835 /* 7.7.3.9 */
9836 { &hf_oran_beamid_ap1,
9837 { "beamIdAP1", "oran_fh_cus.beamIdAP1",
9838 FT_UINT16, BASE_DEC,
9839 NULL((void*)0), 0x7f,
9840 "beam id to be used for antenna port 1", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9841 },
9842 /* 7.7.3.10 */
9843 { &hf_oran_beamid_ap2,
9844 { "beamIdAP2", "oran_fh_cus.beamIdAP2",
9845 FT_UINT16, BASE_DEC,
9846 NULL((void*)0), 0x7f,
9847 "beam id to be used for antenna port 2", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9848 },
9849 /* 7.7.3.11 */
9850 { &hf_oran_beamid_ap3,
9851 { "beamIdAP3", "oran_fh_cus.beamIdAP3",
9852 FT_UINT16, BASE_DEC,
9853 NULL((void*)0), 0x7f,
9854 "beam id to be used for antenna port 3", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9855 },
9856
9857 /* 7.7.10.3a */
9858 { &hf_oran_port_list_index,
9859 { "portListIndex", "oran_fh_cus.portListIndex",
9860 FT_UINT8, BASE_DEC,
9861 NULL((void*)0), 0x0,
9862 "the index of an eAxC_ID in the port-list", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9863 },
9864
9865 { &hf_oran_alpn_per_sym,
9866 { "alpnPerSym", "oran_fh_cus.alpnPerSym",
9867 FT_UINT8, BASE_HEX,
9868 VALS(alpn_per_sym_vals)((0 ? (const struct _value_string*)0 : ((alpn_per_sym_vals)))
)
, 0x80,
9869 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9870 },
9871 { &hf_oran_ant_dmrs_snr,
9872 { "antDmrsSnr", "oran_fh_cus.antDmrsSnr",
9873 FT_UINT8, BASE_HEX,
9874 VALS(ant_dmrs_snr_vals)((0 ? (const struct _value_string*)0 : ((ant_dmrs_snr_vals)))
)
, 0x40,
9875 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9876 },
9877
9878 /* 7.7.24.6 */
9879 { &hf_oran_user_group_size,
9880 { "userGroupSize", "oran_fh_cus.userGroupSize",
9881 FT_UINT8, BASE_DEC,
9882 NULL((void*)0), 0x1f,
9883 "number of UE data layers in the user group identified by userGroupId", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9884 },
9885 /* 7.7.24.7 */
9886 { &hf_oran_user_group_id,
9887 { "userGroupId", "oran_fh_cus.userGroupId",
9888 FT_UINT8, BASE_DEC,
9889 NULL((void*)0), 0x0,
9890 "indicates user group described by the section", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9891 },
9892 /* 7.7.24.8 */
9893 { &hf_oran_entry_type,
9894 { "entryType", "oran_fh_cus.entryType",
9895 FT_UINT8, BASE_DEC,
9896 VALS(entry_type_vals)((0 ? (const struct _value_string*)0 : ((entry_type_vals)))), 0xe0,
9897 "indicates format of the entry", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9898 },
9899 /* 7.7.24.9 */
9900 { &hf_oran_dmrs_port_number,
9901 { "dmrsPortNumber", "oran_fh_cus.dmrsPortNumber",
9902 FT_UINT8, BASE_DEC,
9903 NULL((void*)0), 0x1f,
9904 "DMRS antenna port number for the associated ueId", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9905 },
9906 /* 7.7.24.10 */
9907 { &hf_oran_ueid_reset,
9908 { "ueidReset", "oran_fh_cus.ueidReset",
9909 FT_BOOLEAN, 8,
9910 TFS(&tfs_ueid_reset)((0 ? (const struct true_false_string*)0 : ((&tfs_ueid_reset
))))
, 0x80,
9911 "same UEID as the previous slot", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9912 },
9913 /* 7.7.24.11 */
9914 { &hf_oran_dmrs_symbol_mask,
9915 { "dmrsSymbolMask", "oran_fh_cus.dmrsSymbolMask",
9916 FT_UINT16, BASE_HEX,
9917 NULL((void*)0), 0x3fff,
9918 "symbols within the slot containing DMRS", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9919 },
9920 { &hf_oran_dmrs_symbol_mask_s13,
9921 { "symbol 13", "oran_fh_cus.dmrsSymbolMask.symbol-13",
9922 FT_BOOLEAN, 16,
9923 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x2000,
9924 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9925 },
9926 { &hf_oran_dmrs_symbol_mask_s12,
9927 { "symbol 12", "oran_fh_cus.dmrsSymbolMask.symbol-12",
9928 FT_BOOLEAN, 16,
9929 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x1000,
9930 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9931 },
9932 { &hf_oran_dmrs_symbol_mask_s11,
9933 { "symbol 11", "oran_fh_cus.dmrsSymbolMask.symbol-11",
9934 FT_BOOLEAN, 16,
9935 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0800,
9936 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9937 },
9938 { &hf_oran_dmrs_symbol_mask_s10,
9939 { "symbol 10", "oran_fh_cus.dmrsSymbolMask.symbol-10",
9940 FT_BOOLEAN, 16,
9941 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0400,
9942 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9943 },
9944 { &hf_oran_dmrs_symbol_mask_s9,
9945 { "symbol 9", "oran_fh_cus.dmrsSymbolMask.symbol-9",
9946 FT_BOOLEAN, 16,
9947 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0200,
9948 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9949 },
9950 { &hf_oran_dmrs_symbol_mask_s8,
9951 { "symbol 8", "oran_fh_cus.dmrsSymbolMask.symbol-8",
9952 FT_BOOLEAN, 16,
9953 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0100,
9954 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9955 },
9956 { &hf_oran_dmrs_symbol_mask_s7,
9957 { "symbol 7", "oran_fh_cus.dmrsSymbolMask.symbol-7",
9958 FT_BOOLEAN, 16,
9959 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0080,
9960 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9961 },
9962 { &hf_oran_dmrs_symbol_mask_s6,
9963 { "symbol 6", "oran_fh_cus.dmrsSymbolMask.symbol-6",
9964 FT_BOOLEAN, 16,
9965 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0040,
9966 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9967 },
9968 { &hf_oran_dmrs_symbol_mask_s5,
9969 { "symbol 5", "oran_fh_cus.dmrsSymbolMask.symbol-5",
9970 FT_BOOLEAN, 16,
9971 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0020,
9972 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9973 },
9974 { &hf_oran_dmrs_symbol_mask_s4,
9975 { "symbol 4", "oran_fh_cus.dmrsSymbolMask.symbol-4",
9976 FT_BOOLEAN, 16,
9977 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0010,
9978 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9979 },
9980 { &hf_oran_dmrs_symbol_mask_s3,
9981 { "symbol 3", "oran_fh_cus.dmrsSymbolMask.symbol-3",
9982 FT_BOOLEAN, 16,
9983 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0008,
9984 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9985 },
9986 { &hf_oran_dmrs_symbol_mask_s2,
9987 { "symbol 2", "oran_fh_cus.dmrsSymbolMask.symbol-2",
9988 FT_BOOLEAN, 16,
9989 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0004,
9990 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9991 },
9992 { &hf_oran_dmrs_symbol_mask_s1,
9993 { "symbol 1", "oran_fh_cus.dmrsSymbolMask.symbol-1",
9994 FT_BOOLEAN, 16,
9995 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0002,
9996 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9997 },
9998 { &hf_oran_dmrs_symbol_mask_s0,
9999 { "symbol 0", "oran_fh_cus.dmrsSymbolMask.symbol-0",
10000 FT_BOOLEAN, 16,
10001 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0001,
10002 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10003 },
10004
10005 /* 7.7.24.12 */
10006 { &hf_oran_scrambling,
10007 { "scrambling", "oran_fh_cus.scrambling",
10008 FT_UINT16, BASE_HEX,
10009 NULL((void*)0), 0x0,
10010 "used to calculate the seed value required to initialize pseudo-random generator", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10011 },
10012 /* 7.7.24.13 */
10013 { &hf_oran_nscid,
10014 { "nscid", "oran_fh_cus.nscid",
10015 FT_UINT8, BASE_HEX,
10016 NULL((void*)0), 0x80,
10017 "used to calculate the seed value for pseudo-random generator", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10018 },
10019 /* 7.7.24.14 */
10020 { &hf_oran_dtype,
10021 { "dType", "oran_fh_cus.dType",
10022 FT_UINT8, BASE_HEX,
10023 VALS(dtype_vals)((0 ? (const struct _value_string*)0 : ((dtype_vals)))), 0x40,
10024 "PUSCH DMRS configuration type", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10025 },
10026 /* 7.7.24.15 */
10027 { &hf_oran_cmd_without_data,
10028 { "cmdWithoutData", "oran_fh_cus.cmdWithoutData",
10029 FT_UINT8, BASE_HEX,
10030 NULL((void*)0), 0x30,
10031 "number of DMRS CDM groups without data", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10032 },
10033 /* 7.7.24.16 */
10034 { &hf_oran_lambda,
10035 { "lambda", "oran_fh_cus.lambda",
10036 FT_UINT8, BASE_HEX,
10037 NULL((void*)0), 0x0c,
10038 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10039 },
10040 /* 7.7.24.19 */
10041 { &hf_oran_first_prb,
10042 { "firstPrb", "oran_fh_cus.firstPrb",
10043 FT_UINT16, BASE_DEC,
10044 NULL((void*)0), 0x03fe,
10045 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10046 },
10047 /* 7.7.24.20 */
10048 { &hf_oran_last_prb,
10049 { "lastPrb", "oran_fh_cus.lastPrb",
10050 FT_UINT16, BASE_DEC,
10051 NULL((void*)0), 0x01ff,
10052 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10053 },
10054
10055 /* 7.7.24.17 */
10056 /* TODO: add value_string */
10057 { &hf_oran_low_papr_type,
10058 { "lowPaprType", "oran_fh_cus.lowPaprType",
10059 FT_UINT8, BASE_HEX,
10060 VALS(papr_type_vals)((0 ? (const struct _value_string*)0 : ((papr_type_vals)))), 0x30,
10061 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10062 },
10063 /* 7.7.24.18 */
10064 { &hf_oran_hopping_mode,
10065 { "hoppingMode", "oran_fh_cus.hoppingMode",
10066 FT_UINT8, BASE_HEX,
10067 VALS(hopping_mode_vals)((0 ? (const struct _value_string*)0 : ((hopping_mode_vals)))
)
, 0x0c,
10068 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10069 },
10070
10071 { &hf_oran_tx_win_for_on_air_symbol_l,
10072 { "txWinForOnAirSymbol", "oran_fh_cus.txWinForOnAirSymbol",
10073 FT_UINT8, BASE_DEC,
10074 NULL((void*)0), 0xf0,
10075 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10076 },
10077 { &hf_oran_tx_win_for_on_air_symbol_r,
10078 { "txWinForOnAirSymbol", "oran_fh_cus.txWinForOnAirSymbol",
10079 FT_UINT8, BASE_DEC,
10080 NULL((void*)0), 0x0f,
10081 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10082 },
10083 /* 7.7.26.2 */
10084 { &hf_oran_num_fo_fb,
10085 { "numFoFb", "oran_fh_cus.numFoFb",
10086 FT_UINT8, BASE_DEC,
10087 NULL((void*)0), 0x7f,
10088 "number of frequency offset feedback", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10089 },
10090 /* 7.7.26.3 */
10091 { &hf_oran_freq_offset_fb,
10092 { "freqOffsetFb", "oran_fh_cus.freqOffsetFb",
10093 FT_UINT16, BASE_HEX_DEC | BASE_RANGE_STRING0x00000100,
10094 RVALS(freq_offset_fb_values)((0 ? (const struct _range_string*)0 : ((freq_offset_fb_values
))))
, 0x0,
10095 "UE frequency offset feedback", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10096 },
10097
10098 /* 7.7.28.2 */
10099 { &hf_oran_num_ue_sinr_rpt,
10100 { "numUeSinrRpt", "oran_fh_cus.numUeSinrRpt",
10101 FT_UINT8, BASE_DEC,
10102 NULL((void*)0), 0x1f,
10103 "number of sinr reported UEs {1 - 12}", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10104 },
10105
10106 /* 7.5.2.19 */
10107 { &hf_oran_num_sinr_per_prb,
10108 { "numSinrPerPrb", "oran_fh_cus.numSinrPerPrb",
10109 FT_UINT8, BASE_DEC,
10110 VALS(num_sinr_per_prb_vals)((0 ? (const struct _value_string*)0 : ((num_sinr_per_prb_vals
))))
, 0x70,
10111 "number of SINR values per PRB", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10112 },
10113 { &hf_oran_num_sinr_per_prb_right,
10114 { "numSinrPerPrb", "oran_fh_cus.numSinrPerPrb",
10115 FT_UINT8, BASE_DEC,
10116 VALS(num_sinr_per_prb_vals)((0 ? (const struct _value_string*)0 : ((num_sinr_per_prb_vals
))))
, 0x07,
10117 "number of SINR values per PRB", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10118 },
10119
10120 /* 7.5.3.68 */
10121 { &hf_oran_sinr_value,
10122 { "sinrValue", "oran_fh_cus.sinrValue",
10123 FT_FLOAT, BASE_NONE,
10124 NULL((void*)0), 0x0,
10125 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10126 },
10127
10128 { &hf_oran_measurement_report,
10129 { "Measurement Report", "oran_fh_cus.measurement-report",
10130 FT_STRING, BASE_NONE,
10131 NULL((void*)0), 0x0,
10132 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10133 },
10134 /* 7.5.3.57 */
10135 { &hf_oran_mf,
10136 { "mf", "oran_fh_cus.mf",
10137 FT_BOOLEAN, 8,
10138 TFS(&measurement_flag_tfs)((0 ? (const struct true_false_string*)0 : ((&measurement_flag_tfs
))))
, 0x80,
10139 "measurement flag", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10140 },
10141 /* 7.5.3.59 */
10142 { &hf_oran_meas_data_size,
10143 { "measDataSize", "oran_fh_cus.measDataSize",
10144 FT_UINT16, BASE_DEC,
10145 NULL((void*)0), 0x0,
10146 "measurement data size (in words)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10147 },
10148
10149 /* 7.5.3.58 */
10150 { &hf_oran_meas_type_id,
10151 { "measTypeId", "oran_fh_cus.measTypeId",
10152 FT_UINT8, BASE_DEC,
10153 VALS(meas_type_id_vals)((0 ? (const struct _value_string*)0 : ((meas_type_id_vals)))
)
, 0x7F,
10154 "measurement report type identifier", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10155 },
10156 /* 7.5.3.66 */
10157 { &hf_oran_num_elements,
10158 { "numElements", "oran_fh_cus.numElements",
10159 FT_UINT8, BASE_DEC,
10160 NULL((void*)0), 0x0,
10161 "measurement report type identifier", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10162 },
10163 /* 7.5.3.60 */
10164 { &hf_oran_ue_tae,
10165 { "ueTae", "oran_fh_cus.ueTae",
10166 FT_UINT16, BASE_DEC | BASE_RANGE_STRING0x00000100,
10167 RVALS(freq_offset_fb_values)((0 ? (const struct _range_string*)0 : ((freq_offset_fb_values
))))
, 0x0,
10168 "UE Timing Advance Error", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10169 },
10170 /* 7.5.3.61 */
10171 { &hf_oran_ue_layer_power,
10172 { "ueLayerPower", "oran_fh_cus.ueLayerPower",
10173 FT_UINT16, BASE_DEC | BASE_RANGE_STRING0x00000100,
10174 RVALS(freq_offset_fb_values)((0 ? (const struct _range_string*)0 : ((freq_offset_fb_values
))))
, 0x0,
10175 "UE Layer Power", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10176 },
10177
10178 /* 7.5.3.62 */
10179 { &hf_oran_ue_freq_offset,
10180 { "ueFreqOffset", "oran_fh_cus.ueFreqOffset",
10181 FT_UINT16, BASE_DEC | BASE_RANGE_STRING0x00000100,
10182 RVALS(freq_offset_fb_values)((0 ? (const struct _range_string*)0 : ((freq_offset_fb_values
))))
, 0x0,
10183 "UE frequency offset", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10184 },
10185 /* 7.5.3.63 */
10186 { &hf_oran_ipn_power,
10187 { "ipnPower", "oran_fh_cus.ipnPower",
10188 FT_UINT16, BASE_DEC | BASE_RANGE_STRING0x00000100,
10189 RVALS(freq_offset_fb_values)((0 ? (const struct _range_string*)0 : ((freq_offset_fb_values
))))
, 0x0,
10190 "Interference plus Noise power", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10191 },
10192 /* 7.5.3.64 */
10193 { &hf_oran_ant_dmrs_snr_val,
10194 { "antDmrsSnrVal", "oran_fh_cus.antDmrsSnrVal",
10195 FT_UINT16, BASE_DEC | BASE_RANGE_STRING0x00000100,
10196 RVALS(freq_offset_fb_values)((0 ? (const struct _range_string*)0 : ((freq_offset_fb_values
))))
, 0x0,
10197 "antenna DMRS-SNR", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10198 },
10199
10200 { &hf_oran_measurement_command,
10201 { "Measurement Command", "oran_fh_cus.measurement-command",
10202 FT_STRING, BASE_NONE,
10203 NULL((void*)0), 0x0,
10204 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10205 },
10206
10207 /* 7.5.27.2 */
10208 { &hf_oran_beam_type,
10209 {"beamType", "oran_fh_cus.beamType",
10210 FT_UINT16, BASE_DEC,
10211 VALS(beam_type_vals)((0 ? (const struct _value_string*)0 : ((beam_type_vals)))), 0xc0,
10212 NULL((void*)0),
10213 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10214 },
10215 /* 7.5.3.65 */
10216 { &hf_oran_meas_cmd_size,
10217 {"measCmdSize", "oran_fh_cus.measCmdSize",
10218 FT_UINT16, BASE_DEC,
10219 NULL((void*)0), 0x0,
10220 "measurement command size in words",
10221 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10222 },
10223
10224 { &hf_oran_symbol_reordering_layer,
10225 { "Layer", "oran_fh_cus.layer",
10226 FT_STRING, BASE_NONE,
10227 NULL((void*)0), 0x0,
10228 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10229 },
10230 { &hf_oran_dmrs_entry,
10231 { "Entry", "oran_fh_cus.dmrs-entry",
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.7.29.3 */
10238 { &hf_oran_cd_scg_size,
10239 {"cdScgSize", "oran_fh_cus.cdScgSize",
10240 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
10241 RVALS(cd_scg_size_vals)((0 ? (const struct _range_string*)0 : ((cd_scg_size_vals)))), 0x0f,
10242 "Cyclic delay subcarrier group size",
10243 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10244 },
10245 /* 7.7.29.4 */
10246 { &hf_oran_cd_scg_phase_step,
10247 {"cdScgPhaseStep", "oran_fh_cus.cdScgPhaseStep",
10248 FT_INT8, BASE_DEC,
10249 NULL((void*)0), 0x0,
10250 "Cyclic delay subcarrier group phase step",
10251 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10252 },
10253
10254 { &hf_oran_sinr_prb,
10255 { "PRB", "oran_fh_cus.sinr.prb",
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 /* 7.5.2.20 */
10261 { &hf_oran_oru_control_sinr_slot_mask_id,
10262 {"oruControlSinrSlotMaskId", "oran_fh_cus.oruControlSinrSlotMaskId",
10263 FT_UINT8, BASE_DEC,
10264 NULL((void*)0), 0x1f,
10265 "SINR time resolution",
10266 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10267 },
10268 /* 7.7.24.21 */
10269 { &hf_oran_pos_meas,
10270 {"posMeas", "oran_fh_cus.posMeas",
10271 FT_BOOLEAN, 8,
10272 TFS(&tfs_report_no_report_pos_meas)((0 ? (const struct true_false_string*)0 : ((&tfs_report_no_report_pos_meas
))))
, 0x40,
10273 "Positioning measurement report request",
10274 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10275 },
10276
10277 /* 7.5.3.69 */
10278 { &hf_oran_ue_radial_speed,
10279 {"ueRadialSpeed", "oran_fh_cus.ueRadialSpeed",
10280 FT_UINT16, BASE_DEC,
10281 NULL((void*)0), 0x0,
10282 "UE radial speed",
10283 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10284 },
10285 /* 7.5.3.70 */
10286 { &hf_oran_ue_az_aoa,
10287 {"ueAzAoa", "oran_fh_cus.ueAzAoa",
10288 FT_UINT16, BASE_DEC,
10289 NULL((void*)0), 0x0,
10290 "UE azimuth angle of arrival",
10291 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10292 },
10293 /* 7.5.3.71 */
10294 { &hf_oran_ue_ze_aoa,
10295 {"ueZeAoa", "oran_fh_cus.ueZeAoa",
10296 FT_UINT16, BASE_DEC,
10297 NULL((void*)0), 0x0,
10298 "UE zenith angle of arrival",
10299 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10300 },
10301 /* 7.5.3.72 */
10302 { &hf_oran_ue_pos_toa_offset,
10303 {"uePosToaOffset", "oran_fh_cus.uePosToaOffset",
10304 FT_UINT16, BASE_DEC,
10305 NULL((void*)0), 0x0,
10306 "UE positioning time of arrival offset",
10307 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10308 },
10309
10310 /* 7.7.30.2 */
10311 { &hf_oran_num_rep_ue,
10312 {"numRepUe", "oran_fh_cus.numRepUe",
10313 FT_UINT8, BASE_DEC,
10314 NULL((void*)0), 0x0f,
10315 "Number of UEs with PUSCH repetition",
10316 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10317 },
10318 /* 7.7.30.3 */
10319 { &hf_oran_rep_ueid,
10320 {"repUeId", "oran_fh_cus.repUeId",
10321 FT_UINT16, BASE_DEC,
10322 NULL((void*)0), 0x7fff,
10323 "UEId the PUSCH is part of",
10324 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10325 },
10326 /* 7.7.30.4 */
10327 { &hf_oran_is_last_rep,
10328 {"isLastRep", "oran_fh_cus.isLastRep",
10329 FT_BOOLEAN, 8,
10330 NULL((void*)0), 0x40,
10331 "Last transmission in the repetition",
10332 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10333 },
10334 /* 7.7.30.5 */
10335 { &hf_oran_rep_index,
10336 {"repIndex", "oran_fh_cus.repIndex",
10337 FT_UINT8, BASE_DEC,
10338 NULL((void*)0), 0x3f,
10339 "Repetition index of the PUSCH transmission",
10340 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10341 },
10342 /* 7.7.30.6 */
10343 { &hf_oran_num_reps,
10344 {"numReps", "oran_fh_cus.numReps",
10345 FT_UINT8, BASE_DEC,
10346 NULL((void*)0), 0x3f,
10347 "The number of total PUSCH repetitions",
10348 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10349 },
10350
10351
10352 { &hf_oran_c_section_common,
10353 { "Common Section", "oran_fh_cus.c-plane.section.common",
10354 FT_STRING, BASE_NONE,
10355 NULL((void*)0), 0x0,
10356 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10357 },
10358 { &hf_oran_c_section,
10359 { "Section", "oran_fh_cus.c-plane.section",
10360 FT_STRING, BASE_NONE,
10361 NULL((void*)0), 0x0,
10362 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10363 },
10364 { &hf_oran_u_section,
10365 { "Section", "oran_fh_cus.u-plane.section",
10366 FT_STRING, BASE_NONE,
10367 NULL((void*)0), 0x0,
10368 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10369 },
10370
10371 /* Link back to UL C-plane where udCompHdr was recorded */
10372 { &hf_oran_ul_cplane_ud_comp_hdr_frame,
10373 { "C-Plane UL udCompHdr frame", "oran_fh_cus.ul-cplane.udCompHdr",
10374 FT_FRAMENUM, BASE_NONE,
10375 FRAMENUM_TYPE(FT_FRAMENUM_REQUEST)((gpointer) (glong) (FT_FRAMENUM_REQUEST)), 0x0,
10376 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10377 },
10378
10379 /* For ext11, where was a beamId (last) defined? */
10380 { &hf_oran_bfws_frame_defined,
10381 { "Beam defined in frame", "oran_fh_cus.bfw-defined",
10382 FT_FRAMENUM, BASE_NONE,
10383 FRAMENUM_TYPE(FT_FRAMENUM_RETRANS_PREV)((gpointer) (glong) (FT_FRAMENUM_RETRANS_PREV)), 0x0,
10384 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10385 },
10386 { &hf_oran_bfws_symbols_since_defined,
10387 { "Symbols since BFWs defined", "oran_fh_cus.symbols-since-bfw-defined",
10388 FT_UINT32, BASE_DEC,
10389 NULL((void*)0), 0x0,
10390 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10391 },
10392
10393 /* Corresponding C-plane frame for DL U-plane */
10394 { &hf_oran_corresponding_cplane_frame,
10395 { "C-plane frame", "oran_fh_cus.cplane-frame",
10396 FT_FRAMENUM, BASE_NONE,
10397 FRAMENUM_TYPE(FT_FRAMENUM_REQUEST)((gpointer) (glong) (FT_FRAMENUM_REQUEST)), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10398 },
10399 /* Time since corresponding C-plane frame for DL U-plane */
10400 { &hf_oran_corresponding_cplane_frame_time_delta,
10401 { "Time since C-plane frame", "oran_fh_cus.cplane-frame-time-delta",
10402 FT_UINT32, BASE_DEC, NULL((void*)0), 0x0,
10403 "Microseconds since C-plane frame", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10404 },
10405
10406 /* Reassembly */
10407 { &hf_oran_fragment,
10408 { "Fragment", "oran_fh_cus.fragment", FT_FRAMENUM, BASE_NONE,
10409 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10410 { &hf_oran_fragments,
10411 { "Fragments", "oran_fh_cus.fragments", FT_BYTES, BASE_NONE,
10412 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10413 { &hf_oran_fragment_overlap,
10414 { "Fragment overlap", "oran_fh_cus.fragment.overlap", FT_BOOLEAN, BASE_NONE,
10415 NULL((void*)0), 0x0, "Fragment overlaps with other fragments", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10416 { &hf_oran_fragment_overlap_conflict,
10417 { "Conflicting data in fragment overlap", "oran_fh_cus.fragment.overlap.conflict",
10418 FT_BOOLEAN, BASE_NONE, NULL((void*)0), 0x0,
10419 "Overlapping fragments contained conflicting data", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10420 { &hf_oran_fragment_multiple_tails,
10421 { "Multiple tail fragments found", "oran_fh_cus.fragment.multipletails",
10422 FT_BOOLEAN, BASE_NONE, NULL((void*)0), 0x0,
10423 "Several tails were found when defragmenting the packet", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10424 { &hf_oran_fragment_too_long_fragment,
10425 { "Fragment too long", "oran_fh_cus.fragment.toolongfragment",
10426 FT_BOOLEAN, BASE_NONE, NULL((void*)0), 0x0,
10427 "Fragment contained data past end of packet", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10428 { &hf_oran_fragment_error,
10429 { "Defragmentation error", "oran_fh_cus.fragment.error", FT_FRAMENUM, BASE_NONE,
10430 NULL((void*)0), 0x0, "Defragmentation error due to illegal fragments", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10431 { &hf_oran_fragment_count,
10432 { "Fragment count", "oran_fh_cus.fragment.count", FT_UINT32, BASE_DEC,
10433 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10434 { &hf_oran_reassembled_in,
10435 { "Reassembled payload in frame", "oran_fh_cus.reassembled_in", FT_FRAMENUM, BASE_NONE,
10436 NULL((void*)0), 0x0, "This payload packet is reassembled in this frame", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10437 { &hf_oran_reassembled_length,
10438 { "Reassembled payload length", "oran_fh_cus.reassembled.length", FT_UINT32, BASE_DEC,
10439 NULL((void*)0), 0x0, "The total length of the reassembled payload", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10440 { &hf_oran_reassembled_data,
10441 { "Reassembled data", "oran_fh_cus.reassembled.data", FT_BYTES, BASE_NONE,
10442 NULL((void*)0), 0x0, "The reassembled payload", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10443
10444 { &hf_oran_payload,
10445 { "Payload", "oran_fh_cus.payload", FT_BYTES, BASE_SHOW_ASCII_PRINTABLE0x00010000,
10446 NULL((void*)0), 0x0, "Complete or reassembled payload", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10447 };
10448
10449 /* Setup protocol subtree array */
10450 static int *ett[] = {
10451 &ett_oran,
10452 &ett_oran_ecpri_pcid,
10453 &ett_oran_ecpri_rtcid,
10454 &ett_oran_ecpri_seqid,
10455 &ett_oran_section_type,
10456 &ett_oran_u_timing,
10457 &ett_oran_u_section,
10458 &ett_oran_u_prb,
10459 &ett_oran_section,
10460 &ett_oran_iq,
10461 &ett_oran_bfw_bundle,
10462 &ett_oran_bfw,
10463 &ett_oran_frequency_range,
10464 &ett_oran_prb_cisamples,
10465 &ett_oran_cisample,
10466 &ett_oran_udcomphdr,
10467 &ett_oran_udcompparam,
10468 &ett_oran_cicomphdr,
10469 &ett_oran_cicompparam,
10470 &ett_oran_bfwcomphdr,
10471 &ett_oran_bfwcompparam,
10472 &ett_oran_ext19_port,
10473 &ett_oran_prb_allocation,
10474 &ett_oran_punc_pattern,
10475 &ett_oran_bfacomphdr,
10476 &ett_oran_modcomp_param_set,
10477 &ett_oran_st4_cmd_header,
10478 &ett_oran_st4_cmd,
10479 &ett_oran_sym_prb_pattern,
10480 &ett_oran_measurement_report,
10481 &ett_oran_measurement_command,
10482 &ett_oran_sresmask,
10483 &ett_oran_c_section_common,
10484 &ett_oran_c_section,
10485 &ett_oran_remask,
10486 &ett_oran_mc_scale_remask,
10487 &ett_oran_symbol_reordering_layer,
10488 &ett_oran_dmrs_entry,
10489 &ett_oran_dmrs_symbol_mask,
10490 &ett_oran_symbol_mask,
10491 &ett_oran_active_beamspace_coefficient_mask,
10492 &ett_oran_sinr_prb,
10493
10494 &ett_oran_fragment,
10495 &ett_oran_fragments
10496 };
10497
10498 /* Separate subtree array for extensions. Used with [ext-1] */
10499 static int *ext_ett[HIGHEST_EXTTYPE30];
10500 for (unsigned extno=0; extno<HIGHEST_EXTTYPE30; extno++) {
10501 ext_ett[extno] = &ett_oran_c_section_extension[extno];
10502 }
10503
10504 expert_module_t* expert_oran;
10505
10506 static ei_register_info ei[] = {
10507 { &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)}}
}},
10508 { &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)}}
}},
10509 { &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)}}
}},
10510 { &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)}}
}},
10511 { &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)}}
}},
10512 { &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)}}
}},
10513 { &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)}}
}},
10514 { &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)}}
}},
10515 { &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)}}
}},
10516 { &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)}}
}},
10517 { &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)}}
}},
10518 { &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)}}
}},
10519 { &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)}}
}},
10520 { &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)}}
}},
10521 { &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)}}
}},
10522 { &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)}}
}},
10523 { &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)}}
}},
10524 { &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)}}
}},
10525 { &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)}}
}},
10526 { &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)}}
}},
10527 { &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)}}
}},
10528 { &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)}}
}},
10529 { &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)}}
}},
10530 { &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)}}
}},
10531 { &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)}}
}},
10532 { &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)}}
}},
10533 { &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)}}
}},
10534 { &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)}}
}},
10535 { &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)}}
}},
10536 { &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)}}
}},
10537 { &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)}}
}},
10538 { &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)}}
}},
10539 { &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)}}
}},
10540 { &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)}}
}},
10541 { &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)}}
}},
10542 { &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)}}
}},
10543 { &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)}}
}},
10544 { &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)}}
}},
10545 { &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)}}
}},
10546 { &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)}}
}},
10547 { &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)}}
}},
10548 { &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)}}
}},
10549 { &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)}}
}},
10550 { &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)}}
}},
10551 { &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)}}
}},
10552 { &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)}}
}},
10553 { &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)}}
}},
10554 { &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)}}
}},
10555 { &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)}}
}},
10556 { &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)}}
}},
10557 { &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)}}
}},
10558 { &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)}}
}},
10559 { &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)}}
}},
10560 { &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)}}
}},
10561 { &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)}}
}},
10562 { &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)}}
}}
10563 };
10564
10565 /* Register the protocol name and description */
10566 proto_oran = proto_register_protocol("O-RAN Fronthaul CUS", "O-RAN FH CUS", "oran_fh_cus");
10567
10568 /* Allow dissector to find be found by name. */
10569 register_dissector("oran_fh_cus", dissect_oran, proto_oran);
10570
10571 /* Register the tap name. */
10572 oran_tap = register_tap("oran-fh-cus");
10573
10574 /* Required function calls to register the header fields and subtrees */
10575 proto_register_field_array(proto_oran, hf, array_length(hf)(sizeof (hf) / sizeof (hf)[0]));
10576 proto_register_subtree_array(ett, array_length(ett)(sizeof (ett) / sizeof (ett)[0]));
10577 proto_register_subtree_array(ext_ett, array_length(ext_ett)(sizeof (ext_ett) / sizeof (ext_ett)[0]));
10578
10579 expert_oran = expert_register_protocol(proto_oran);
10580 expert_register_field_array(expert_oran, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
10581
10582
10583 /* Preferences */
10584 module_t * oran_module = prefs_register_protocol(proto_oran, NULL((void*)0));
10585
10586 /* Register bit width/compression preferences separately by direction. */
10587 prefs_register_uint_preference(oran_module, "oran.du_port_id_bits", "DU Port ID bits [a]",
10588 "The bit width of DU Port ID - sum of a,b,c&d (eAxC) must be 16", 10, &pref_du_port_id_bits);
10589 prefs_register_uint_preference(oran_module, "oran.bandsector_id_bits", "BandSector ID bits [b]",
10590 "The bit width of BandSector ID - sum of a,b,c&d (eAxC) must be 16", 10, &pref_bandsector_id_bits);
10591 prefs_register_uint_preference(oran_module, "oran.cc_id_bits", "CC ID bits [c]",
10592 "The bit width of CC ID - sum of a,b,c&d (eAxC) must be 16", 10, &pref_cc_id_bits);
10593 prefs_register_uint_preference(oran_module, "oran.ru_port_id_bits", "RU Port ID bits [d]",
10594 "The bit width of RU Port ID - sum of a,b,c&d (eAxC) must be 16", 10, &pref_ru_port_id_bits);
10595
10596 /* Uplink userplane */
10597 prefs_register_static_text_preference(oran_module, "oran.ul", "", "");
10598 prefs_register_uint_preference(oran_module, "oran.iq_bitwidth_up", "IQ Bitwidth Uplink",
10599 "The bit width of a sample in the Uplink (if no udcompHdr and no C-Plane)", 10, &pref_sample_bit_width_uplink);
10600 prefs_register_enum_preference(oran_module, "oran.ud_comp_up", "Uplink User Data Compression",
10601 "Uplink User Data Compression (if no udcompHdr and no C-Plane)", &pref_iqCompressionUplink, ul_compression_options, false0);
10602 prefs_register_enum_preference(oran_module, "oran.ud_comp_hdr_up", "udCompHdr field is present for uplink",
10603 "The udCompHdr field in U-Plane messages may or may not be present, depending on the "
10604 "configuration of the O-RU. This preference instructs the dissector to expect "
10605 "this field to be present in uplink messages",
10606 &pref_includeUdCompHeaderUplink, udcomphdr_present_options, false0);
10607 prefs_register_bool_preference(oran_module, "oran.ignore_cplane_ul_udcomphdr", "Ignore UL compression settings from C-plane",
10608 "When set, override udCompHdr from UL C-Plane with compression method and width configured here", &pref_override_ul_compression);
10609 prefs_register_uint_preference(oran_module, "oran.ul_slot_us_limit", "Microseconds allowed for UL tx in symbol",
10610 "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",
10611 10, &us_allowed_for_ul_in_symbol);
10612
10613 /* Downlink userplane */
10614 prefs_register_static_text_preference(oran_module, "oran.dl", "", "");
10615 prefs_register_uint_preference(oran_module, "oran.iq_bitwidth_down", "IQ Bitwidth Downlink",
10616 "The bit width of a sample in the Downlink (if no udcompHdr)", 10, &pref_sample_bit_width_downlink);
10617 prefs_register_enum_preference(oran_module, "oran.ud_comp_down", "Downlink User Data Compression",
10618 "Downlink User Data Compression", &pref_iqCompressionDownlink, dl_compression_options, false0);
10619 prefs_register_enum_preference(oran_module, "oran.ud_comp_hdr_down", "udCompHdr field is present for downlink",
10620 "The udCompHdr field in U-Plane messages may or may not be present, depending on the "
10621 "configuration of the O-RU. This preference instructs the dissector to expect "
10622 "this field to be present in downlink messages",
10623 &pref_includeUdCompHeaderDownlink, udcomphdr_present_options, false0);
10624
10625 /* SINR */
10626 prefs_register_static_text_preference(oran_module, "oran.sinr", "", "");
10627 prefs_register_uint_preference(oran_module, "oran.iq_bitwidth_sinr", "IQ Bitwidth SINR",
10628 "The bit width of a sample in SINR", 10, &pref_sample_bit_width_sinr);
10629 prefs_register_enum_preference(oran_module, "oran.ud_comp_sinr", "SINR Compression",
10630 "SINR Compression", &pref_iqCompressionSINR, ul_compression_options, false0);
10631
10632 /* BF-related */
10633 prefs_register_static_text_preference(oran_module, "oran.bf", "", "");
10634 prefs_register_uint_preference(oran_module, "oran.num_bf_antennas", "Number of beam weights",
10635 "Number of array elements that BF weights will be provided for", 10, &pref_num_bf_antennas);
10636 prefs_register_obsolete_preference(oran_module, "oran.num_weights_per_bundle");
10637 prefs_register_obsolete_preference(oran_module, "oran.num_bf_weights");
10638 prefs_register_bool_preference(oran_module, "oran.st6_4byte_alignment_required", "Use 4-byte alignment for ST6 sections",
10639 "Default is 1-byte alignment", &st6_4byte_alignment);
10640
10641 /* Misc (and will seldom need to be accessed) */
10642 prefs_register_static_text_preference(oran_module, "oran.misc", "", "");
10643 prefs_register_bool_preference(oran_module, "oran.show_iq_samples", "Show IQ Sample values",
10644 "When enabled, for U-Plane frames show each I and Q value in PRB", &pref_showIQSampleValues);
10645 prefs_register_enum_preference(oran_module, "oran.support_udcomplen", "udCompLen supported",
10646 "When enabled, U-Plane messages with relevant compression schemes will include udCompLen",
10647 &pref_support_udcompLen, udcomplen_support_options, false0);
10648 prefs_register_uint_preference(oran_module, "oran.rbs_in_uplane_section", "Total RBs in User-Plane data section",
10649 "This is used if numPrbu is signalled as 0", 10, &pref_data_plane_section_total_rbs);
10650 prefs_register_bool_preference(oran_module, "oran.unscaled_iq", "Show unscaled I/Q values",
10651 "", &show_unscaled_values);
10652 prefs_register_bool_preference(oran_module, "oran.attempt_reassembly",
10653 "Attempt Radio Transport layer reassembly", "",
10654 &do_radio_transport_layer_reassembly);
10655 prefs_register_obsolete_preference(oran_module, "oran.k_antenna_ports");
10656
10657 prefs_register_bool_preference(oran_module, "oran.link_planes",
10658 "Link C-plane and U-plane using sectionId", "",
10659 &link_planes_together);
10660
10661
10662 flow_states_table = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
10663 flow_results_table = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
10664 ul_symbol_timing = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
10665
10666 dl_beam_ids_defined = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
10667 dl_beam_ids_results = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
10668
10669 register_init_routine(&oran_init_protocol);
10670
10671 /* Register reassembly table. */
10672 reassembly_table_register(&oran_reassembly_table,
10673 &oran_reassembly_table_functions);
10674}
10675
10676/*
10677* Editor modelines - http://www.wireshark.org/tools/modelines.html
10678*
10679* Local Variables:
10680* c-basic-offset: 4
10681* tab-width: 8
10682* indent-tabs-mode: nil
10683* End:
10684*
10685* ex: set shiftwidth=4 tabstop=8 expandtab:
10686* :indentSize=4:tabSize=8:noTabs=true:
10687*/