Bug Summary

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

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name packet-oran.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -fno-delete-null-pointer-checks -mframe-pointer=all -relaxed-aliasing -fmath-errno -ffp-contract=on -fno-rounding-math -ffloat16-excess-precision=fast -fbfloat16-excess-precision=fast -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/builds/wireshark/wireshark/build -fcoverage-compilation-dir=/builds/wireshark/wireshark/build -resource-dir /usr/lib/llvm-22/lib/clang/22 -isystem /usr/include/glib-2.0 -isystem /usr/lib/x86_64-linux-gnu/glib-2.0/include -isystem /builds/wireshark/wireshark/epan/dissectors -isystem /builds/wireshark/wireshark/build/epan/dissectors -isystem /usr/include/mit-krb5 -isystem /usr/include/libxml2 -isystem /builds/wireshark/wireshark/epan -D CARES_NO_DEPRECATED -D G_DISABLE_DEPRECATED -D G_DISABLE_SINGLE_INCLUDES -D WS_BUILD_DLL -D WS_DEBUG -D WS_DEBUG_UTF_8 -I /builds/wireshark/wireshark/build -I /builds/wireshark/wireshark -I /builds/wireshark/wireshark/include -D _GLIBCXX_ASSERTIONS -internal-isystem /usr/lib/llvm-22/lib/clang/22/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fmacro-prefix-map=/builds/wireshark/wireshark/= -fmacro-prefix-map=/builds/wireshark/wireshark/build/= -fmacro-prefix-map=../= -Wno-format-nonliteral -std=gnu17 -ferror-limit 19 -fvisibility=hidden -fwrapv -fwrapv-pointer -fstrict-flex-arrays=3 -stack-protector 2 -fstack-clash-protection -fcf-protection=full -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fexceptions -fcolor-diagnostics -analyzer-output=html -faddrsig -fdwarf2-cfi-asm -o /builds/wireshark/wireshark/sbout/2026-07-10-101034-3642-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_blk_offset;
403static int hf_oran_prb_blk_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
509static int hf_oran_mcs_table;
510static int hf_oran_mcs_index;
511
512static int hf_oran_num_meas_req;
513static int hf_oran_num_of_ue_ant_ports;
514static int hf_oran_ue_rank;
515static int hf_oran_codebook_subset;
516static int hf_oran_full_pwr_mode;
517static int hf_oran_full_pwr_mode_2_tpmi_group;
518
519static int hf_oran_num_cand_ranks;
520static int hf_oran_ue_pref_rank;
521static int hf_oran_ue_tpmi_rank_y;
522static int hf_oran_ue_tpmi_rank_y_sinr_lx;
523static int hf_oran_ue_layer_pre_eq_sinr;
524
525
526/* Computed fields */
527static int hf_oran_c_eAxC_ID;
528static int hf_oran_refa;
529
530static int hf_oran_bfws_frame_defined;
531static int hf_oran_bfws_symbols_since_defined;
532
533static int hf_oran_corresponding_cplane_frame;
534static int hf_oran_corresponding_cplane_frame_time_delta;
535static int hf_oran_corresponding_uplane_frame;
536static int hf_oran_corresponding_uplane_frames_total;
537
538
539/* Convenient fields for filtering, mostly shown as hidden */
540static int hf_oran_cplane;
541static int hf_oran_uplane;
542static int hf_oran_bf; /* to match frames that configure beamforming in any way */
543static int hf_oran_zero_prb;
544static int hf_oran_nonzero_prb;
545static int hf_oran_bundle_weights_all_zero;
546
547static int hf_oran_ul_cplane_ud_comp_hdr_frame;
548
549/* For reassembly */
550static int hf_oran_fragments;
551static int hf_oran_fragment;
552static int hf_oran_fragment_overlap;
553static int hf_oran_fragment_overlap_conflict;
554static int hf_oran_fragment_multiple_tails;
555static int hf_oran_fragment_too_long_fragment;
556static int hf_oran_fragment_error;
557static int hf_oran_fragment_count;
558static int hf_oran_reassembled_in;
559static int hf_oran_reassembled_length;
560static int hf_oran_reassembled_data;
561
562static int hf_oran_payload;
563
564
565/* Subtrees */
566static int ett_oran;
567static int ett_oran_ecpri_rtcid;
568static int ett_oran_ecpri_pcid;
569static int ett_oran_ecpri_seqid;
570static int ett_oran_section;
571static int ett_oran_section_type;
572static int ett_oran_u_timing;
573static int ett_oran_u_section;
574static int ett_oran_u_prb;
575static int ett_oran_iq;
576static int ett_oran_bfw_bundle;
577static int ett_oran_bfw;
578static int ett_oran_frequency_range;
579static int ett_oran_prb_cisamples;
580static int ett_oran_cisample;
581static int ett_oran_udcomphdr;
582static int ett_oran_udcompparam;
583static int ett_oran_cicomphdr;
584static int ett_oran_cicompparam;
585static int ett_oran_bfwcomphdr;
586static int ett_oran_bfwcompparam;
587static int ett_oran_ext19_port;
588static int ett_oran_prb_allocation;
589static int ett_oran_punc_pattern;
590static int ett_oran_bfacomphdr;
591static int ett_oran_modcomp_param_set;
592static int ett_oran_st4_cmd_header;
593static int ett_oran_st4_cmd;
594static int ett_oran_sym_prb_pattern;
595static int ett_oran_measurement_report;
596static int ett_oran_measurement_command;
597static int ett_oran_sresmask;
598static int ett_oran_c_section_common;
599static int ett_oran_c_section;
600static int ett_oran_remask;
601static int ett_oran_mc_scale_remask;
602static int ett_oran_symbol_reordering_layer;
603static int ett_oran_dmrs_entry;
604static int ett_oran_dmrs_symbol_mask;
605static int ett_oran_symbol_mask;
606static int ett_oran_active_beamspace_coefficient_mask;
607static int ett_oran_sinr_prb;
608
609static int ett_oran_fragment;
610static int ett_oran_fragments;
611
612/* Reassembly table. */
613static reassembly_table oran_reassembly_table;
614
615static void *oran_key(const packet_info *pinfo _U___attribute__((unused)), const uint32_t id _U___attribute__((unused)), const void *data)
616{
617 return (void *)data;
618}
619
620static void oran_free_key(void *ptr _U___attribute__((unused)))
621{
622}
623
624static reassembly_table_functions oran_reassembly_table_functions =
625{
626 g_direct_hash,
627 g_direct_equal,
628 oran_key,
629 oran_key,
630 oran_free_key,
631 oran_free_key
632};
633
634static const fragment_items oran_frag_items = {
635 &ett_oran_fragment,
636 &ett_oran_fragments,
637 &hf_oran_fragments,
638 &hf_oran_fragment,
639 &hf_oran_fragment_overlap,
640 &hf_oran_fragment_overlap_conflict,
641 &hf_oran_fragment_multiple_tails,
642 &hf_oran_fragment_too_long_fragment,
643 &hf_oran_fragment_error,
644 &hf_oran_fragment_count,
645 &hf_oran_reassembled_in,
646 &hf_oran_reassembled_length,
647 &hf_oran_reassembled_data,
648 "O-RAN FH CUS fragments"
649};
650
651
652
653/* Don't want all extensions to open and close together. Use [extType-1] entry */
654static int ett_oran_c_section_extension[HIGHEST_EXTTYPE32];
655
656/* Expert info */
657static expert_field ei_oran_unsupported_bfw_compression_method;
658static expert_field ei_oran_invalid_sample_bit_width;
659static expert_field ei_oran_reserved_numBundPrb;
660static expert_field ei_oran_extlen_wrong;
661static expert_field ei_oran_invalid_eaxc_bit_width;
662static expert_field ei_oran_extlen_zero;
663static expert_field ei_oran_rbg_size_reserved;
664static expert_field ei_oran_frame_length;
665static expert_field ei_oran_numprbc_ext21_zero;
666static expert_field ei_oran_ci_prb_group_size_reserved;
667static expert_field ei_oran_st8_nackid;
668static expert_field ei_oran_st4_no_cmds;
669static expert_field ei_oran_st4_zero_len_cmd;
670static expert_field ei_oran_st4_wrong_len_cmd;
671static expert_field ei_oran_st4_unknown_cmd;
672static expert_field ei_oran_mcot_out_of_range;
673static expert_field ei_oran_se10_unknown_beamgrouptype;
674static expert_field ei_oran_se10_not_allowed;
675static expert_field ei_oran_start_symbol_id_not_zero;
676static expert_field ei_oran_trx_control_cmd_scope;
677static expert_field ei_oran_unhandled_se;
678static expert_field ei_oran_bad_symbolmask;
679static expert_field ei_oran_numslots_not_zero;
680static expert_field ei_oran_version_unsupported;
681static expert_field ei_oran_laa_msg_type_unsupported;
682static expert_field ei_oran_se_on_unsupported_st;
683static expert_field ei_oran_cplane_unexpected_sequence_number_ul;
684static expert_field ei_oran_cplane_unexpected_sequence_number_dl;
685static expert_field ei_oran_uplane_unexpected_sequence_number_ul;
686static expert_field ei_oran_uplane_unexpected_sequence_number_dl;
687static expert_field ei_oran_acknack_no_request;
688static expert_field ei_oran_udpcomphdr_should_be_zero;
689static expert_field ei_oran_radio_fragmentation_c_plane;
690static expert_field ei_oran_lastRbdid_out_of_range;
691static expert_field ei_oran_rbgMask_beyond_last_rbdid;
692static expert_field ei_oran_unexpected_measTypeId;
693static expert_field ei_oran_unsupported_compression_method;
694static expert_field ei_oran_ud_comp_len_wrong_size;
695static expert_field ei_oran_sresmask2_not_zero_with_rb;
696static expert_field ei_oran_st6_rb_shall_be_0;
697static expert_field ei_oran_st9_not_ul;
698static expert_field ei_oran_st10_numsymbol_not_14;
699static expert_field ei_oran_st10_startsymbolid_not_0;
700static expert_field ei_oran_st10_not_ul;
701static expert_field ei_oran_se24_nothing_to_inherit;
702static expert_field ei_oran_num_sinr_per_prb_unknown;
703static expert_field ei_oran_start_symbol_id_bits_ignored;
704static expert_field ei_oran_user_group_id_reserved_value;
705static expert_field ei_oran_port_list_index_zero;
706static expert_field ei_oran_ul_uplane_symbol_too_long;
707static expert_field ei_oran_reserved_not_zero;
708static expert_field ei_oran_too_many_symbols;
709static expert_field ei_oran_se30_not_ul;
710static expert_field ei_oran_se30_unknown_ueid;
711static expert_field ei_oran_beamid_bfws_not_found;
712static expert_field ei_oran_syminc_set_for_uplane;
713
714
715
716/* These are the message types handled by this dissector. Others have handling in packet-ecpri.c */
717#define ECPRI_MT_IQ_DATA0 0
718#define ECPRI_MT_RT_CTRL_DATA2 2
719
720
721/* Preference settings - try to set reasonable defaults */
722static unsigned pref_du_port_id_bits = 4;
723static unsigned pref_bandsector_id_bits = 4;
724static unsigned pref_cc_id_bits = 4;
725static unsigned pref_ru_port_id_bits = 4;
726
727/* TODO: ideally should be per-flow */
728static unsigned pref_sample_bit_width_uplink = 14;
729static unsigned pref_sample_bit_width_downlink = 14;
730static unsigned pref_sample_bit_width_sinr = 14;
731
732/* TODO: these ideally should be per-flow too */
733static int pref_iqCompressionUplink = COMP_BLOCK_FP1;
734static int pref_iqCompressionDownlink = COMP_BLOCK_FP1;
735
736static int pref_iqCompressionSINR = COMP_BLOCK_FP1;
737
738
739/* Is udCompHeader present (both directions) */
740static int pref_includeUdCompHeaderUplink = 2; /* start using heuristic */
741static int pref_includeUdCompHeaderDownlink = 2; /* start using heuristic */
742
743/* Are we ignoring UL C-Plane udCompHdr? */
744static bool_Bool pref_override_ul_compression = false0;
745
746static unsigned pref_data_plane_section_total_rbs = 273;
747static unsigned pref_num_bf_antennas = 32;
748static bool_Bool pref_showIQSampleValues = true1;
749
750/* Based upon m-plane param, so will be system-wide */
751static int pref_support_udcompLen = 2; /* start heuristic, can force other settings if necessary */
752static bool_Bool udcomplen_heuristic_result_set = false0;
753static bool_Bool udcomplen_heuristic_result = false0;
754
755/* st6-4byte-alignment-required */
756static bool_Bool st6_4byte_alignment = false0;
757
758/* Requested, allows I/Q to be stored as integers.. */
759static bool_Bool show_unscaled_values = false0;
760
761/* Initialized off. Timing is in microseconds. */
762static unsigned us_allowed_for_ul_in_symbol = 0;
763
764/* Reassemble U-Plane (at Radio Transport layer) */
765static bool_Bool do_radio_transport_layer_reassembly = true1;
766
767/* Link U-plane back to C-plane using sectionIds */
768static bool_Bool link_planes_together = true1;
769
770static const enum_val_t dl_compression_options[] = {
771 { "COMP_NONE", "No Compression", COMP_NONE0 },
772 { "COMP_BLOCK_FP", "Block Floating Point Compression", COMP_BLOCK_FP1 },
773 { "COMP_BLOCK_SCALE", "Block Scaling Compression", COMP_BLOCK_SCALE2 },
774 { "COMP_U_LAW", "u-Law Compression", COMP_U_LAW3 },
775 { "COMP_MODULATION", "Modulation Compression", COMP_MODULATION4 },
776 { "BFP_AND_SELECTIVE_RE", "Block Floating Point + selective RE sending", BFP_AND_SELECTIVE_RE5 },
777 { "MOD_COMPR_AND_SELECTIVE_RE", "Modulation Compression + selective RE sending", MOD_COMPR_AND_SELECTIVE_RE6 },
778 { "BFP_AND_SELECTIVE_RE_WITH_MASKS", "Block Floating Point + selective RE sending with masks in section header", BFP_AND_SELECTIVE_RE_WITH_MASKS7 },
779 { "MOD_COMPR_AND_SELECTIVE_RE_WITH_MASKS", "Modulation Compression + selective RE sending with masks in section header", MOD_COMPR_AND_SELECTIVE_RE6 },
780 { NULL((void*)0), NULL((void*)0), 0 }
781};
782
783/* No Modulation compression in UL.. */
784static const enum_val_t ul_compression_options[] = {
785 { "COMP_NONE", "No Compression", COMP_NONE0 },
786 { "COMP_BLOCK_FP", "Block Floating Point Compression", COMP_BLOCK_FP1 },
787 { "COMP_BLOCK_SCALE", "Block Scaling Compression", COMP_BLOCK_SCALE2 },
788 { "COMP_U_LAW", "u-Law Compression", COMP_U_LAW3 },
789 { "BFP_AND_SELECTIVE_RE", "Block Floating Point + selective RE sending", BFP_AND_SELECTIVE_RE5 },
790 { "BFP_AND_SELECTIVE_RE_WITH_MASKS", "Block Floating Point + selective RE sending with masks in section header", BFP_AND_SELECTIVE_RE_WITH_MASKS7 },
791 { NULL((void*)0), NULL((void*)0), 0 }
792};
793
794static const enum_val_t udcomplen_support_options[] = {
795 { "NOT_SUPPORTED", "Not Supported", 0 },
796 { "SUPPORTED", "Supported", 1 },
797 { "HEURISTIC", "Attempt Heuristic", 2 },
798 { NULL((void*)0), NULL((void*)0), 0 }
799};
800
801static const enum_val_t udcomphdr_present_options[] = {
802 { "NOT_PRESENT", "Not Present", 0 },
803 { "PRESENT", "Present", 1 },
804 { "HEURISTIC", "Attempt Heuristic", 2 },
805 { NULL((void*)0), NULL((void*)0), 0 }
806};
807
808
809
810static const value_string e_bit[] = {
811 { 0, "More fragments follow" },
812 { 1, "Last fragment" },
813 { 0, NULL((void*)0)}
814};
815
816#define DIR_UPLINK0 0
817#define DIR_DOWNLINK1 1
818
819
820static const value_string data_direction_vals[] = {
821 { DIR_UPLINK0, "Uplink" }, /* gNB Rx */
822 { DIR_DOWNLINK1, "Downlink" }, /* gNB Tx */
823 { 0, NULL((void*)0)}
824};
825
826static const value_string rb_vals[] = {
827 { 0, "Every RB used" },
828 { 1, "Every other RB used" },
829 { 0, NULL((void*)0)}
830};
831
832static const value_string sym_inc_vals[] = {
833 { 0, "Use the current symbol number" },
834 { 1, "Increment the current symbol number" },
835 { 0, NULL((void*)0)}
836};
837
838static const value_string lbtMode_vals[] = {
839 { 0, "Full LBT (regular LBT, sending reservation signal until the beginning of the SF/slot)" },
840 { 1, "Partial LBT (looking back 25 usec prior to transmission" },
841 { 2, "Partial LBT (looking back 34 usec prior to transmission" },
842 { 3, "Full LBT and stop (regular LBT, without sending reservation signal" },
843 { 0, NULL((void*)0)}
844};
845
846static const value_string ue_rank_vals[] = {
847 { 1, "1" },
848 { 2, "2" },
849 { 3, "3" },
850 { 4, "4" },
851 { 0, NULL((void*)0)}
852};
853
854static const value_string num_of_ue_ant_ports_vals[] = {
855 { 2, "2" },
856 { 4, "4" },
857 { 0, NULL((void*)0)}
858};
859
860static const value_string codebook_subset_vals[] = {
861 { 0, "nonCoherent" },
862 { 1, "partialAndNonCoherent" },
863 { 2, "fullyAndPartialAndNonCoherent" },
864 { 3, "reserved" },
865 { 0, NULL((void*)0)}
866};
867
868
869static const range_string filter_indices[] = {
870 {0, 0, "standard channel filter"},
871 {1, 1, "UL filter for PRACH preamble formats 0, 1, 2; min. passband 839 x 1.25kHz = 1048.75 kHz"},
872 {2, 2, "UL filter for PRACH preamble format 3, min. passband 839 x 5 kHz = 4195 kHz"},
873 {3, 3, "UL filter for PRACH preamble formats A1, A2, A3, B1, B2, B3, B4, C0, C2; min. passband 139 x \u0394fRA"},
874 {4, 4, "UL filter for NPRACH 0, 1; min. passband 48 x 3.75KHz = 180 KHz"},
875 {5, 5, "UL filter for PRACH preamble formats"},
876 {8, 8, "UL filter NPUSCH"},
877 {9, 9, "Mixed numerology and other channels except PRACH and NB-IoT"},
878 {9, 15, "Reserved"},
879 {0, 0, NULL((void*)0)}
880};
881
882/* 7.3.1-1 */
883static const range_string section_types[] = {
884 { SEC_C_UNUSED_RB, SEC_C_UNUSED_RB, "Unused Resource Blocks or symbols in Downlink or Uplink" },
885 { SEC_C_NORMAL, SEC_C_NORMAL, "Most DL/UL radio channels" },
886 { SEC_C_RSVD2, SEC_C_RSVD2, "Reserved for future use" },
887 { SEC_C_PRACH, SEC_C_PRACH, "PRACH and mixed-numerology channels" },
888 { SEC_C_SLOT_CONTROL, SEC_C_SLOT_CONTROL, "Slot Configuration Control" },
889 { SEC_C_UE_SCHED, SEC_C_UE_SCHED, "UE scheduling information (UE-ID assignment to section)" },
890 { SEC_C_CH_INFO, SEC_C_CH_INFO, "Channel information" },
891 { SEC_C_LAA, SEC_C_LAA, "LAA (License Assisted Access)" },
892 { SEC_C_ACK_NACK_FEEDBACK, SEC_C_ACK_NACK_FEEDBACK, "ACK/NACK Feedback" },
893 { SEC_C_SINR_REPORTING, SEC_C_SINR_REPORTING, "SINR Reporting" },
894 { SEC_C_RRM_MEAS_REPORTS, SEC_C_RRM_MEAS_REPORTS, "RRM Measurement Reports" },
895 { SEC_C_REQUEST_RRM_MEAS, SEC_C_REQUEST_RRM_MEAS, "Request RRM Measurements" },
896 { 12, 255, "Reserved for future use" },
897 { 0, 0, NULL((void*)0)} };
898
899static const range_string section_types_short[] = {
900 { SEC_C_UNUSED_RB, SEC_C_UNUSED_RB, "(Unused RBs) " },
901 { SEC_C_NORMAL, SEC_C_NORMAL, "(Most channels) " },
902 { SEC_C_RSVD2, SEC_C_RSVD2, "(reserved) " },
903 { SEC_C_PRACH, SEC_C_PRACH, "(PRACH/mixed-\u03bc)" },
904 { SEC_C_SLOT_CONTROL, SEC_C_SLOT_CONTROL, "(Slot info) " },
905 { SEC_C_UE_SCHED, SEC_C_UE_SCHED, "(UE scheduling info)" },
906 { SEC_C_CH_INFO, SEC_C_CH_INFO, "(Channel info) " },
907 { SEC_C_LAA, SEC_C_LAA, "(LAA) " },
908 { SEC_C_ACK_NACK_FEEDBACK, SEC_C_ACK_NACK_FEEDBACK, "(ACK/NACK) " },
909 { SEC_C_SINR_REPORTING, SEC_C_SINR_REPORTING, "(SINR Reporting) " },
910 { SEC_C_RRM_MEAS_REPORTS, SEC_C_RRM_MEAS_REPORTS, "(RRM Meas Reports) " },
911 { SEC_C_REQUEST_RRM_MEAS, SEC_C_REQUEST_RRM_MEAS, "(Req RRM Meas) " },
912 { 12, 255, "Reserved for future use" },
913 { 0, 0, NULL((void*)0) }
914};
915
916static const range_string ud_comp_header_width[] = {
917 {0, 0, "I and Q are each 16 bits wide"},
918 {1, 15, "Bit width of I and Q"},
919 {0, 0, NULL((void*)0)} };
920
921/* Table 8.3.3.13-3 */
922static const range_string ud_comp_header_meth[] = {
923 {COMP_NONE0, COMP_NONE0, "No compression" },
924 {COMP_BLOCK_FP1, COMP_BLOCK_FP1, "Block floating point compression" },
925 {COMP_BLOCK_SCALE2, COMP_BLOCK_SCALE2, "Block scaling" },
926 {COMP_U_LAW3, COMP_U_LAW3, "Mu - law" },
927 {COMP_MODULATION4, COMP_MODULATION4, "Modulation compression" },
928 {BFP_AND_SELECTIVE_RE5, BFP_AND_SELECTIVE_RE5, "BFP + selective RE sending" },
929 {MOD_COMPR_AND_SELECTIVE_RE6, MOD_COMPR_AND_SELECTIVE_RE6, "mod-compr + selective RE sending" },
930 {BFP_AND_SELECTIVE_RE_WITH_MASKS7, BFP_AND_SELECTIVE_RE_WITH_MASKS7, "BFP + selective RE sending with masks in section header" },
931 {MOD_COMPR_AND_SELECTIVE_RE_WITH_MASKS8, MOD_COMPR_AND_SELECTIVE_RE_WITH_MASKS8, "mod-compr + selective RE sending with masks in section header"},
932 {9, 15, "Reserved"},
933 {0, 0, NULL((void*)0)}
934};
935
936/* Table 7.5.2.13-2 */
937static const range_string frame_structure_fft[] = {
938 {0, 0, "Reserved (no FFT/iFFT processing)"},
939 {1, 3, "Reserved"},
940 {4, 4, "FFT size 16"},
941 {5, 5, "FFT size 32"},
942 {6, 6, "FFT size 64"},
943 {7, 7, "FFT size 128"},
944 {8, 8, "FFT size 256"},
945 {9, 9, "FFT size 512"},
946 {10, 10, "FFT size 1024"},
947 {11, 11, "FFT size 2048"},
948 {12, 12, "FFT size 4096"},
949 {13, 13, "FFT size 1536"},
950 {14, 14, "FFT size 3072"},
951 {15, 15, "Reserved"},
952 {0, 0, NULL((void*)0)}
953};
954
955/* Table 7.5.2.13-3 */
956static const range_string subcarrier_spacings[] = {
957 { 0, 0, "SCS 15 kHz, 1 slot/subframe, slot length 1 ms" },
958 { 1, 1, "SCS 30 kHz, 2 slots/subframe, slot length 500 \u03bcs" },
959 { 2, 2, "SCS 60 kHz, 4 slots/subframe, slot length 250 \u03bcs" },
960 { 3, 3, "SCS 120 kHz, 8 slots/subframe, slot length 125 \u03bcs" },
961 { 4, 4, "SCS 240 kHz, 16 slots/subframe, slot length 62.5 \u03bcs" },
962 { 5, 11, "Reserved" }, /* N.B., 5 was 480kHz in early spec versions */
963 { 12, 12, "SCS 1.25 kHz, 1 slot/subframe, slot length 1 ms" },
964 { 13, 13, "SCS 3.75 kHz(LTE - specific), 1 slot/subframe, slot length 1 ms" },
965 { 14, 14, "SCS 5 kHz, 1 slot/subframe, slot length 1 ms" },
966 { 15, 15, "SCS 7.5 kHz(LTE - specific), 1 slot/subframe, slot length 1 ms" },
967 { 0, 0, NULL((void*)0) }
968};
969
970/* Table 7.5.3.14-1 laaMsgType definition */
971static const range_string laaMsgTypes[] = {
972 {0, 0, "LBT_PDSCH_REQ - lls - O-DU to O-RU request to obtain a PDSCH channel"},
973 {1, 1, "LBT_DRS_REQ - lls - O-DU to O-RU request to obtain the channel and send DRS"},
974 {2, 2, "LBT_PDSCH_RSP - O-RU to O-DU response, channel acq success or failure"},
975 {3, 3, "LBT_DRS_RSP - O-RU to O-DU response, DRS sending success or failure"},
976 {4, 4, "LBT_Buffer_Error - O-RU to O-DU response, reporting buffer overflow"},
977 {5, 5, "LBT_CWCONFIG_REQ - O-DU to O-RU request, congestion window configuration"},
978 {6, 6, "LBT_CWCONFIG_RST - O-RU to O-DU request, congestion window config, response"},
979 {7, 15, "reserved for future methods"},
980 {0, 0, NULL((void*)0)}
981};
982
983/* 7.7.26.3 */
984static const range_string freq_offset_fb_values[] = {
985 {0, 0, "no frequency offset"},
986 {8000, 8000, "value not provided"},
987 {1, 30000, "positive frequency offset, (0, +0.5] subcarrier"},
988 {0x8ad0, 0xffff, "negative frequency offset, [-0.5, 0) subcarrier"},
989 {0x0, 0xffff, "reserved"},
990 {0, 0, NULL((void*)0)}
991};
992
993/* 7.5.3.78 */
994static const range_string ue_tmpi_rank_sinr_vals[] = {
995 {0, 0, "0 dB SINR"},
996 {0x0001, 0x07ff, "positive SINR"},
997 {0xf800, 0xffff, "-ve SINR"},
998 {0x8000, 0x8000, "invalid measurement result"},
999 {0x0, 0xffff, "reserved"},
1000 {0, 0, NULL((void*)0)}
1001};
1002
1003
1004
1005/* Table 7.5.2.19-1 */
1006static const value_string num_sinr_per_prb_vals[] = {
1007 { 0, "1" },
1008 { 1, "2" },
1009 { 2, "3" },
1010 { 3, "4" },
1011 { 4, "6" },
1012 { 5, "12" },
1013 { 6, "1 SINR value per section for DFT-s-OFDM" },
1014 { 7, "reserved" },
1015 { 0, NULL((void*)0)}
1016};
1017
1018static const value_string meas_type_id_vals[] = {
1019 { 1, "UE Timing Advance Error" },
1020 { 2, "UE Layer power" },
1021 { 3, "UE frequency offset" },
1022 { 4, "Interference plus Noise for allocated PRBs" },
1023 { 5, "Interference plus Noise for unallocated PRBs" },
1024 { 6, "DMRS-SNR per antenna" },
1025 { 7, "UE positioning measurement report" },
1026 { 8, "UE radial speed measurement report" },
1027 { 9, "UE post-equalization MU inteference measurement" },
1028 { 10, "UE TPMI and rank recommendation measurement" },
1029 { 11, "UE layer pre-equalization SINR report" },
1030 { 0, NULL((void*)0)}
1031};
1032
1033static const value_string beam_type_vals[] = {
1034 { 0, "List of beamId values" },
1035 { 1, "Range of beamId values" },
1036 { 0, NULL((void*)0)}
1037};
1038
1039/* 7.7.24.3 */
1040static const value_string entry_type_vals[] = {
1041 { 0, "inherit config from preceding entry (2 or 3) ueIdReset=0" },
1042 { 1, "inherit config from preceding entry (2 or 3) ueIdReset=1" },
1043 { 2, "related parameters if have transform precoding disabled " },
1044 { 3, "related parameters if have transform precoding enabled " },
1045 { 0, NULL((void*)0)}
1046};
1047
1048/* Table 7.7.29.3-1 */
1049static const range_string cd_scg_size_vals[] = {
1050 { 0, 0, "1 subcarrier" },
1051 { 1, 1, "1 RB x N subcarriers" },
1052 { 2, 2, "2 RB x N subcarriers" },
1053 { 3, 3, "4 RB x N subcarriers" },
1054 { 4, 4, "8 RB x N subcarriers" },
1055 { 5, 5, "16 RB x N subcarriers" },
1056 { 6, 6, "32 RB x N subcarriers" },
1057 { 7, 15, "reserved"},
1058 { 0, 0, NULL((void*)0)}
1059};
1060
1061
1062/* Table 7.6.1-1 */
1063static const value_string exttype_vals[] = {
1064 {0, "Reserved"},
1065 {1, "Beamforming weights"},
1066 {2, "Beamforming attributes"},
1067 {3, "DL Precoding configuration parameters and indications"},
1068 {4, "Modulation compr. params"},
1069 {5, "Modulation compression additional scaling parameters"},
1070 {6, "Non-contiguous PRB allocation"},
1071 {7, "Multiple-eAxC designation"},
1072 {8, "Regularization factor"},
1073 {9, "Dynamic Spectrum Sharing parameters"},
1074 {10, "Multiple ports grouping"},
1075 {11, "Flexible BF weights"},
1076 {12, "Non-Contiguous PRB Allocation with Frequency Ranges"},
1077 {13, "PRB Allocation with Frequency Hopping"},
1078 {14, "Nulling-layer Info. for ueId-based beamforming"},
1079 {15, "Mixed-numerology Info. for ueId-based beamforming"},
1080 {16, "Section description for antenna mapping in UE channel information based UL beamforming"},
1081 {17, "Section description for indication of user port group"},
1082 {18, "Section description for Uplink Transmission Management"},
1083 {19, "Compact beamforming information for multiple port"},
1084 {20, "Puncturing extension"},
1085 {21, "Variable PRB group size for channel information"},
1086 {22, "ACK/NACK request"},
1087 {23, "Multiple symbol modulation compression parameters"},
1088 {24, "PUSCH DMRS configuration"},
1089 {25, "Symbol reordering for DMRS-BF"},
1090 {26, "Frequency offset feedback"},
1091 {27, "O-DU controlled dimensionality reduction"},
1092 {28, "O-DU controlled frequency resolution for SINR reporting"},
1093 {29, "Cyclic delay adjustment"},
1094 {30, "PUSCH repetition indication"},
1095 {31, "MCS Information"},
1096 {32, "Rank and TPMI measurement request"},
1097 {0, NULL((void*)0)}
1098};
1099static 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) }
;
1100
1101
1102/**************************************************************************************/
1103/* Keep track for each Section Extension, which section types are allowed to carry it */
1104typedef struct {
1105 bool_Bool ST0;
1106 bool_Bool ST1;
1107 bool_Bool ST3;
1108 bool_Bool ST5;
1109 bool_Bool ST6;
1110 bool_Bool ST10;
1111 bool_Bool ST11;
1112} AllowedCTs_t;
1113
1114
1115static const AllowedCTs_t ext_cts[HIGHEST_EXTTYPE32] = {
1116 /* ST0 ST1 ST3 ST5 ST6 ST10 ST11 */
1117 { false0, true1, true1, false0, false0, false0, false0}, // SE 1 (1,3)
1118 { false0, true1, true1, false0, false0, false0, false0}, // SE 2 (1,3)
1119 { false0, true1, true1, false0, false0, false0, false0}, // SE 3 (1,3)
1120 { false0, true1, true1, true1, false0, false0, false0}, // SE 4 (1,3,5)
1121 { false0, true1, true1, true1, false0, false0, false0}, // SE 5 (1,3,5)
1122 { false0, true1, true1, true1, false0, true1, true1 }, // SE 6 (1,3,5,10,11)
1123 { true1, false0, false0, false0, false0, false0, false0}, // SE 7 (0)
1124 { false0, false0, false0, true1, false0, false0, false0}, // SE 8 (5)
1125 { true1, true1, true1, true1, true1, true1, true1 }, // SE 9 (all)
1126 { false0, true1, true1, true1, false0, false0, false0}, // SE 10 (1,3,5)
1127 { false0, true1, true1, false0, false0, false0, false0}, // SE 11 (1,3)
1128 { false0, true1, true1, true1, false0, true1, true1 }, // SE 12 (1,3,5,10,11)
1129 { false0, true1, true1, true1, false0, false0, false0}, // SE 13 (1,3,5)
1130 { false0, false0, false0, true1, false0, false0, false0}, // SE 14 (5)
1131 { false0, false0, false0, true1, true1, false0, false0}, // SE 15 (5,6)
1132 { false0, false0, false0, true1, false0, false0, false0}, // SE 16 (5)
1133 { false0, false0, false0, true1, false0, false0, false0}, // SE 17 (5)
1134 { false0, true1, true1, true1, false0, false0, false0}, // SE 18 (1,3,5)
1135 { false0, true1, true1, false0, false0, false0, false0}, // SE 19 (1,3)
1136 { true1, true1, true1, true1, true1, true1, true1 }, // SE 20 (0,1,3,5,10,11)
1137 { false0, false0, false0, true1, true1, false0, false0}, // SE 21 (5,6)
1138 { true1, true1, true1, true1, true1, true1, true1 }, // SE 22 (all)
1139 { false0, true1, true1, true1, false0, false0, false0}, // SE 23 (1,3,5)
1140 { false0, false0, false0, true1, false0, false0, false0}, // SE 24 (5)
1141 { false0, false0, false0, true1, false0, false0, false0}, // SE 25 (5)
1142 { false0, false0, false0, true1, false0, false0, false0}, // SE 26 (5)
1143 { false0, false0, false0, true1, false0, false0, false0}, // SE 27 (5)
1144 { false0, false0, false0, true1, false0, false0, false0}, // SE 28 (5)
1145 { false0, true1, true1, true1, false0, false0, false0}, // SE 29 (1,3,5)
1146 { false0, false0, false0, true1, false0, false0, false0}, // SE 30 (5)
1147 { false0, true1, true1, true1, false0, false0, false0}, // SE 31 (1,3,5)
1148 { false0, false0, false0, true1, false0, false0, false0}, // SE 32 (5)
1149};
1150
1151static bool_Bool se_allowed_in_st(unsigned se, unsigned st)
1152{
1153 if (se==0 || se>HIGHEST_EXTTYPE32) {
1154 /* Don't know about new SE, so don't complain.. */
1155 return true1;
1156 }
1157
1158 switch (st) {
1159 case 0:
1160 return ext_cts[se-1].ST0;
1161 case 1:
1162 return ext_cts[se-1].ST1;
1163 case 3:
1164 return ext_cts[se-1].ST3;
1165 case 5:
1166 return ext_cts[se-1].ST5;
1167 case 6:
1168 return ext_cts[se-1].ST6;
1169 case 10:
1170 return ext_cts[se-1].ST10;
1171 case 11:
1172 return ext_cts[se-1].ST11;
1173 default:
1174 /* New/unknown section type that includes 'ef'.. assume ok */
1175 return true1;
1176 }
1177}
1178
1179/************************************************************************************/
1180
1181/* Table 7.7.1.2-2 */
1182static const value_string bfw_comp_headers_iq_width[] = {
1183 {0, "I and Q are 16 bits wide"},
1184 {1, "I and Q are 1 bit wide"},
1185 {2, "I and Q are 2 bits wide"},
1186 {3, "I and Q are 3 bits wide"},
1187 {4, "I and Q are 4 bits wide"},
1188 {5, "I and Q are 5 bits wide"},
1189 {6, "I and Q are 6 bits wide"},
1190 {7, "I and Q are 7 bits wide"},
1191 {8, "I and Q are 8 bits wide"},
1192 {9, "I and Q are 9 bits wide"},
1193 {10, "I and Q are 10 bits wide"},
1194 {11, "I and Q are 11 bits wide"},
1195 {12, "I and Q are 12 bits wide"},
1196 {13, "I and Q are 13 bits wide"},
1197 {14, "I and Q are 14 bits wide"},
1198 {15, "I and Q are 15 bits wide"},
1199 {0, NULL((void*)0)}
1200};
1201
1202/* Table 7.7.1.2-3 */
1203static const value_string bfw_comp_headers_comp_meth[] = {
1204 {COMP_NONE0, "no compression"},
1205 {COMP_BLOCK_FP1, "block floating point"},
1206 {COMP_BLOCK_SCALE2, "block scaling"},
1207 {COMP_U_LAW3, "u-law"},
1208 {4, "beamspace compression type I"},
1209 {5, "beamspace compression type II"},
1210 {0, NULL((void*)0)}
1211};
1212
1213/* 7.7.6.2 rbgSize (resource block group size) */
1214static const value_string rbg_size_vals[] = {
1215 {0, "reserved"},
1216 {1, "1"},
1217 {2, "2"},
1218 {3, "3"},
1219 {4, "4"},
1220 {5, "6"},
1221 {6, "8"},
1222 {7, "16"},
1223 {0, NULL((void*)0)}
1224};
1225
1226/* 7.7.6.5 */
1227static const value_string priority_vals[] = {
1228 {0, "0"},
1229 {1, "+1"},
1230 {2, "-2 (reserved, should not be used)"},
1231 {3, "-1"},
1232 {0, NULL((void*)0)}
1233};
1234
1235/* 7.7.10.2 beamGroupType */
1236static const value_string beam_group_type_vals[] = {
1237 {0x0, "common beam"},
1238 {0x1, "beam matrix indication"},
1239 {0x2, "beam vector listing"},
1240 {0x3, "beamId/ueId listing with associated port-list index"},
1241 {0, NULL((void*)0)}
1242};
1243
1244/* 7.7.9.2 technology (interface name) */
1245static const value_string interface_name_vals[] = {
1246 {0x0, "LTE"},
1247 {0x1, "NR"},
1248 {0, NULL((void*)0)}
1249};
1250
1251/* 7.7.18.4 toT (type of transmission) */
1252static const value_string type_of_transmission_vals[] = {
1253 {0x0, "normal transmission mode, data can be distributed in any way the O-RU is implemented to transmit data"},
1254 {0x1, "uniformly distributed over the transmission window"},
1255 {0x2, "Reserved"},
1256 {0x3, "Reserved"},
1257 {0, NULL((void*)0)}
1258};
1259
1260/* 7.7.2.2 (width of bfa parameters) */
1261static const value_string bfa_bw_vals[] = {
1262 {0, "no bits, the field is not applicable (e.g., O-RU does not support it) or the default value shall be used"},
1263 {1, "2-bit bitwidth"},
1264 {2, "3-bit bitwidth"},
1265 {3, "4-bit bitwidth"},
1266 {4, "5-bit bitwidth"},
1267 {5, "6-bit bitwidth"},
1268 {6, "7-bit bitwidth"},
1269 {7, "8-bit bitwidth"},
1270 {0, NULL((void*)0)}
1271};
1272
1273/* 7.7.2.7 & 7.7.2.8 */
1274static const value_string sidelobe_suppression_vals[] = {
1275 {0, "10 dB"},
1276 {1, "15 dB"},
1277 {2, "20 dB"},
1278 {3, "25 dB"},
1279 {4, "30 dB"},
1280 {5, "35 dB"},
1281 {6, "40 dB"},
1282 {7, ">= 45 dB"},
1283 {0, NULL((void*)0)}
1284};
1285
1286static const value_string lbtTrafficClass_vals[] = {
1287 {1, "Priority 1"},
1288 {2, "Priority 2"},
1289 {3, "Priority 3"},
1290 {4, "Priority 4"},
1291 {0, NULL((void*)0)}
1292};
1293
1294/* 7.5.3.22 */
1295static const value_string lbtPdschRes_vals[] = {
1296 {0, "not sensing – indicates that the O-RU is transmitting data"},
1297 {1, "currently sensing – indicates the O-RU has not yet acquired the channel"},
1298 {2, "success – indicates that the channel was successfully acquired"},
1299 {3, "Failure – indicates expiration of the LBT timer. The LBT process should be reset"},
1300 {0, NULL((void*)0)}
1301};
1302
1303/* Table 7.5.2.15-3 */
1304static const value_string ci_comp_opt_vals[] = {
1305 {0, "compression per UE, one ciCompParam exists before the I/Q value of each UE"},
1306 {1, "compression per PRB, one ciCompParam exists before the I/Q value of each PRB"},
1307 {0, NULL((void*)0)}
1308};
1309
1310/* 7.5.2.17 */
1311static const range_string cmd_scope_vals[] = {
1312 {0, 0, "ARRAY-COMMAND"},
1313 {1, 1, "CARRIER-COMMAND"},
1314 {2, 2, "O-RU-COMMAND"},
1315 {3, 15, "reserved"},
1316 {0, 0, NULL((void*)0)}
1317};
1318
1319/* N.B., table in 7.5.3.38 is truncated.. */
1320static const range_string st4_cmd_type_vals[] = {
1321 {0, 0, "reserved for future command types"},
1322 {1, 1, "TIME_DOMAIN_BEAM_CONFIG"},
1323 {2, 2, "TDD_CONFIG_PATTERN"},
1324 {3, 3, "TRX_CONTROL"},
1325 {4, 4, "ASM"},
1326 {5, 5, "TRX_CONTROL_BIDIR"},
1327 {6, 255, "reserved for future command types"},
1328 {0, 0, NULL((void*)0)}
1329};
1330
1331/* Table 7.5.3.51-1 */
1332static const value_string log2maskbits_vals[] = {
1333 {0, "reserved"},
1334 {1, "min antMask size is 16 bits.."},
1335 {2, "min antMask size is 16 bits.."},
1336 {3, "min antMask size is 16 bits.."},
1337 {4, "16 bits"},
1338 {5, "32 bits"},
1339 {6, "64 bits"},
1340 {7, "128 bits"},
1341 {8, "256 bits"},
1342 {9, "512 bits"},
1343 {10, "1024 bits"},
1344 {11, "2048 bits"},
1345 {12, "4096 bits"},
1346 {13, "8192 bits"},
1347 {14, "16384 bits"},
1348 {15, "reserved"},
1349 {0, NULL((void*)0)}
1350};
1351
1352/* Table 16.1-1 Sleep modes */
1353static const value_string sleep_mode_trx_vals[] = {
1354 { 0, "TRXC-mode0-wake-up-duration (symbol)"},
1355 { 1, "TRXC-mode1-wake-up-duration (L)"},
1356 { 2, "TRXC-mode2-wake-up-duration (M)"},
1357 { 3, "TRXC-mode3-wake-up-duration (N)"},
1358 { 0, NULL((void*)0)}
1359};
1360
1361static const value_string sleep_mode_asm_vals[] = {
1362 { 0, "ASM-mode0-wake-up-duration (symbol)"},
1363 { 1, "ASM-mode1-wake-up-duration (L)"},
1364 { 2, "ASM-mode2-wake-up-duration (M)"},
1365 { 3, "ASM-mode3-wake-up-duration (N)"},
1366 { 0, NULL((void*)0)}
1367};
1368
1369/* 7.7.21.3.1 */
1370static const value_string prg_size_st5_vals[] = {
1371 { 0, "reserved"},
1372 { 1, "Precoding resource block group size as WIDEBAND"},
1373 { 2, "Precoding resource block group size 2"},
1374 { 3, "Precoding resource block group size 4"},
1375 { 0, NULL((void*)0)}
1376};
1377
1378/* 7.7.21.3.2 */
1379static const value_string prg_size_st6_vals[] = {
1380 { 0, "if ciPrbGroupSize is 2 or 4, then ciPrbGroupSize, else WIDEBAND"},
1381 { 1, "Precoding resource block group size as WIDEBAND"},
1382 { 2, "Precoding resource block group size 2"},
1383 { 3, "Precoding resource block group size 4"},
1384 { 0, NULL((void*)0)}
1385};
1386
1387/* 7.7.24.4 */
1388static const value_string alpn_per_sym_vals[] = {
1389 { 0, "report one allocated IPN value per all allocated symbols with DMRS"},
1390 { 1, "report one allocated IPN value per group of consecutive DMRS symbols"},
1391 { 0, NULL((void*)0)}
1392};
1393
1394/* 7.7.24.5 */
1395static const value_string ant_dmrs_snr_vals[] = {
1396 { 0, "O-RU shall not report the MEAS_ANT_DMRS_SNR"},
1397 { 1, "O-RU shall report the MEAS_ANT_DMRS_SNR"},
1398 { 0, NULL((void*)0)}
1399};
1400
1401/* 7.7.24.14 */
1402static const value_string dtype_vals[] = {
1403 { 0, "assume DMRS configuration type 1"},
1404 { 1, "assume DMRS configuration type 2"},
1405 { 0, NULL((void*)0)}
1406};
1407
1408/* 7.7.24.17 */
1409static const value_string papr_type_vals[] = {
1410 { 0, "sequence generator type 1 for short sequence lengths"},
1411 { 1, "sequence generator type 1 for long sequence lengths"},
1412 { 2, "sequence generator type 2 for short sequence lengths"},
1413 { 3, "sequence generator type 2 for long sequence lengths"},
1414 { 0, NULL((void*)0)}
1415};
1416
1417/* 7.7.24.18 */
1418static const value_string hopping_mode_vals[] = {
1419 { 0, "neither group, nor sequence hopping is enabled"},
1420 { 1, "group hopping is enabled and sequence hopping is disabled"},
1421 { 2, "sequence hopping is enabled and group hopping is disabled"},
1422 { 3, "reserved"},
1423 { 0, NULL((void*)0)}
1424};
1425
1426/* Table 7.7.31.2-1 */
1427static const value_string mcs_table_vals[] = {
1428 { 0, "MCS index table 1 for PDSCH and PUSCH without transform precoding" },
1429 { 1, "MCS index table 2 for PDSCH and PUSCH without transform precoding" },
1430 { 2, "MCS index table 3 for PDSCH and PUSCH without transform precoding" },
1431 { 3, "MCS index table 4 for PDSCH" },
1432 { 4, "MCS index table for PUSCH with transform precoding and 64QAM" },
1433 { 5, "MCS index table 2 for PUSCH with transform precoding and 64QAM" },
1434 { 0, NULL((void*)0)}
1435};
1436
1437/* 7.7.32.9 */
1438static const value_string full_pwr_mode_vals[] = {
1439 { 0, "not configured"},
1440 { 1, "full power mode 0"},
1441 { 2, "full power mode 1"},
1442 { 3, "full power mode 2"},
1443 { 0, NULL((void*)0)}
1444};
1445
1446
1447static const true_false_string tfs_sfStatus =
1448{
1449 "subframe was transmitted",
1450 "subframe was dropped"
1451};
1452
1453static const true_false_string tfs_lbtBufErr =
1454{
1455 "buffer overflow – data received at O-RU is larger than the available buffer size",
1456 "reserved"
1457};
1458
1459static const true_false_string tfs_partial_full_sf = {
1460 "partial SF",
1461 "full SF"
1462};
1463
1464static const true_false_string disable_tdbfns_tfs = {
1465 "beam numbers excluded",
1466 "beam numbers included"
1467};
1468
1469static const true_false_string continuity_indication_tfs = {
1470 "continuity between current and next bundle",
1471 "discontinuity between current and next bundle"
1472};
1473
1474static const true_false_string prb_mode_tfs = {
1475 "PRB-BLOCK mode",
1476 "PRB-MASK mode"
1477};
1478
1479static const true_false_string symbol_direction_tfs = {
1480 "DL symbol",
1481 "UL symbol"
1482};
1483
1484static const true_false_string symbol_guard_tfs = {
1485 "guard symbol",
1486 "non-guard symbol"
1487};
1488
1489static const true_false_string beam_numbers_included_tfs = {
1490 "time-domain beam numbers excluded in this command",
1491 "time-domain beam numbers included in this command"
1492};
1493
1494static const true_false_string measurement_flag_tfs = {
1495 "at least one additional measurement report or command after the current one",
1496 "no additional measurement report or command"
1497};
1498
1499static const true_false_string repetition_se6_tfs = {
1500 "repeated highest priority data section in the C-Plane message",
1501 "no repetition"
1502};
1503
1504static const true_false_string repetition_se19_tfs = {
1505 "per port information not present in the extension",
1506 "per port info present in the extension"
1507};
1508
1509static const true_false_string tfs_report_no_report_pos_meas =
1510{
1511 "Report MEAS_UE_POS for UE",
1512 "Do not report UE_POS for UE"
1513};
1514
1515
1516/* Forward declaration */
1517static int dissect_udcompparam(tvbuff_t *tvb, packet_info *pinfo _U___attribute__((unused)), proto_tree *tree, unsigned offset,
1518 unsigned comp_meth,
1519 uint32_t *exponent, uint16_t *sReSMask, bool_Bool for_sinr);
1520
1521
1522static const true_false_string ready_tfs = {
1523 "message is a \"ready\" message",
1524 "message is a ACK message"
1525};
1526
1527static const true_false_string multi_sd_scope_tfs = {
1528 "Puncturing pattern applies to current and following sections",
1529 "Puncturing pattern applies to current section"
1530};
1531
1532static const true_false_string tfs_ueid_reset = {
1533 "cannot assume same UE as in preceding slot",
1534 "can assume same UE as in preceding slot"
1535};
1536
1537
1538/* Config for (and later, worked-out allocations) bundles for ext11 (dynamic BFW) */
1539typedef struct {
1540 /* Ext 6 config */
1541 bool_Bool ext6_set;
1542 uint8_t ext6_rbg_size; /* number of PRBs allocated by bitmask */
1543
1544 uint8_t ext6_num_bits_set;
1545 uint8_t ext6_bits_set[28]; /* Which bit position this entry has */
1546 /* TODO: store an f value for each bit position? */
1547
1548 /* Ext 12 config */
1549 bool_Bool ext12_set;
1550 unsigned ext12_num_pairs;
1551#define MAX_BFW_EXT12_PAIRS128 128
1552 struct {
1553 uint8_t off_start_prb;
1554 uint8_t num_prb;
1555 } ext12_pairs[MAX_BFW_EXT12_PAIRS128];
1556
1557 /* Ext 13 config */
1558 bool_Bool ext13_set;
1559 unsigned ext13_num_start_prbs;
1560#define MAX_BFW_EXT13_ALLOCATIONS128 128
1561 unsigned ext13_start_prbs[MAX_BFW_EXT13_ALLOCATIONS128];
1562 /* TODO: store nextSymbolId here too? */
1563
1564 /* Ext 21 config */
1565 bool_Bool ext21_set;
1566 uint8_t ext21_ci_prb_group_size;
1567
1568 /* Results/settings (after calling ext11_work_out_bundles()) */
1569 uint32_t num_bundles;
1570#define MAX_BFW_BUNDLES512 512
1571 struct {
1572 uint32_t start; /* first prb of bundle */
1573 uint32_t end; /* last prb of bundle*/
1574 bool_Bool is_orphan; /* true if not complete (i.e., end-start < numBundPrb) */
1575 } bundles[MAX_BFW_BUNDLES512];
1576} ext11_settings_t;
1577
1578
1579/* Work out bundle allocation for ext 11. Take into account ext6/ext21, ext12 or ext13 in this section before ext 11. */
1580/* Won't be called with numBundPrb=0 */
1581static void ext11_work_out_bundles(unsigned startPrbc,
1582 unsigned numPrbc,
1583 unsigned numBundPrb, /* number of PRBs per (full) bundle */
1584 ext11_settings_t *settings)
1585{
1586 /* Allocation configured by ext 6 */
1587 if (settings->ext6_set) {
1588 unsigned bundles_per_entry = (settings->ext6_rbg_size / numBundPrb);
1589
1590 /* Need to cope with these not dividing exactly, or even having more PRbs in a bundle that
1591 rbg size. i.e. each bundle gets the correct number of PRBs until
1592 all rbg entries are consumed... */
1593
1594 /* TODO: need to check 7.9.4.2. Different cases depending upon value of RAD */
1595
1596 if (bundles_per_entry == 0) {
1597 bundles_per_entry = 1;
1598 }
1599
1600 /* Ext6 behaviour may also be affected by ext 21 */
1601 if (settings->ext21_set) {
1602 /* N.B., have already checked that numPrbc is not 0 */
1603
1604 /* ciPrbGroupSize overrides number of contiguous PRBs in group */
1605 bundles_per_entry = (settings->ext6_rbg_size / settings->ext21_ci_prb_group_size);
1606
1607 /* numPrbc is the number of PRB groups per antenna - handled in call to dissect_bfw_bundle() */
1608 }
1609
1610 unsigned bundles_set = 0;
1611 bool_Bool reached_orphan = false0;
1612 /* For each bit set in ext6 rbg mask.. */
1613 for (unsigned n=0;
1614 !reached_orphan && n < (settings->ext6_num_bits_set * settings->ext6_rbg_size) / numBundPrb;
1615 n++) {
1616
1617 /* Watch out for array bound */
1618 if (n >= 28) {
1619 break;
1620 }
1621
1622 /* For each bundle... */
1623
1624 /* TODO: Work out where first PRB is */
1625 /* May not be the start of an rbg block... */
1626 uint32_t prb_start = (settings->ext6_bits_set[n] * settings->ext6_rbg_size);
1627
1628 /* For each bundle within identified rbgSize block */
1629 for (unsigned m=0; !reached_orphan && m < bundles_per_entry; m++) {
1630
1631 settings->bundles[bundles_set].start = startPrbc+prb_start+(m*numBundPrb);
1632
1633 /* Start already beyond end, so doesn't count. */
1634 if (settings->bundles[bundles_set].start > (startPrbc+numPrbc-1)) {
1635 settings->num_bundles = bundles_set;
1636 return;
1637 }
1638
1639 /* Bundle consists of numBundPrb bundles */
1640 /* TODO: may involve PRBs from >1 rbg blocks.. */
1641 settings->bundles[bundles_set].end = startPrbc+prb_start+((m+1)*numBundPrb)-1;
1642 if (settings->bundles[bundles_set].end > (startPrbc+numPrbc-1)) {
1643 /* Extends beyond end, so counts but is an orphan bundle */
1644 settings->bundles[bundles_set].end = startPrbc+numPrbc-1;
1645 settings->bundles[bundles_set].is_orphan = true1;
1646 reached_orphan = true1;
1647 }
1648
1649 /* Get out if have reached array bound */
1650 if (++bundles_set == MAX_BFW_BUNDLES512) {
1651 return;
1652 }
1653 }
1654 }
1655 settings->num_bundles = bundles_set;
1656 }
1657
1658 /* Allocation configured by ext 12 */
1659 else if (settings->ext12_set) {
1660 /* First, allocate normally from startPrbc, numPrbc */
1661 settings->num_bundles = (numPrbc+numBundPrb-1) / numBundPrb;
1662
1663 /* Don't overflow settings->bundles[] ! */
1664 settings->num_bundles = MIN(MAX_BFW_BUNDLES, settings->num_bundles)(((512) < (settings->num_bundles)) ? (512) : (settings->
num_bundles))
;
1665
1666 for (uint32_t n=0; n < settings->num_bundles; n++) {
1667 settings->bundles[n].start = startPrbc + n*numBundPrb;
1668 settings->bundles[n].end = settings->bundles[n].start + numBundPrb-1;
1669 /* Does it go beyond the end? */
1670 if (settings->bundles[n].end > startPrbc+numPrbc) {
1671 settings->bundles[n].end = startPrbc+numPrbc;
1672 settings->bundles[n].is_orphan = true1;
1673 }
1674 }
1675 if (settings->num_bundles == MAX_BFW_BUNDLES512) {
1676 return;
1677 }
1678
1679 unsigned prb_offset = startPrbc + numPrbc;
1680
1681 /* Loop over pairs, adding bundles for each */
1682 for (unsigned p=0; p < settings->ext12_num_pairs; p++) {
1683 prb_offset += settings->ext12_pairs[p].off_start_prb;
1684 unsigned pair_bundles = (settings->ext12_pairs[p].num_prb+numBundPrb-1) / numBundPrb;
1685
1686 for (uint32_t n=0; n < pair_bundles; n++) {
1687 unsigned idx = settings->num_bundles;
1688
1689 settings->bundles[idx].start = prb_offset + n*numBundPrb;
1690 settings->bundles[idx].end = settings->bundles[idx].start + numBundPrb-1;
1691 /* Does it go beyond the end? */
1692 if (settings->bundles[idx].end > prb_offset + settings->ext12_pairs[p].num_prb) {
1693 settings->bundles[idx].end = prb_offset + settings->ext12_pairs[p].num_prb;
1694 settings->bundles[idx].is_orphan = true1;
1695 }
1696 /* Range check / return */
1697 settings->num_bundles++;
1698 if (settings->num_bundles == MAX_BFW_BUNDLES512) {
1699 return;
1700 }
1701 }
1702
1703 prb_offset += settings->ext12_pairs[p].num_prb;
1704 }
1705 }
1706
1707 /* Allocation configured by ext 13 */
1708 else if (settings->ext13_set) {
1709 unsigned alloc_size = (numPrbc+numBundPrb-1) / numBundPrb;
1710 settings->num_bundles = alloc_size * settings->ext13_num_start_prbs;
1711
1712 /* Don't overflow settings->bundles[] ! */
1713 settings->num_bundles = MIN(MAX_BFW_BUNDLES, settings->num_bundles)(((512) < (settings->num_bundles)) ? (512) : (settings->
num_bundles))
;
1714
1715 for (unsigned alloc=0; alloc < settings->ext13_num_start_prbs; alloc++) {
1716 unsigned alloc_start = alloc * alloc_size;
1717 for (uint32_t n=0; n < alloc_size; n++) {
1718 if ((alloc_start+n) >= MAX_BFW_BUNDLES512) {
1719 /* ERROR */
1720 return;
1721 }
1722 settings->bundles[alloc_start+n].start = settings->ext13_start_prbs[alloc] + startPrbc + n*numBundPrb;
1723 settings->bundles[alloc_start+n].end = settings->bundles[alloc_start+n].start + numBundPrb-1;
1724 if (settings->bundles[alloc_start+n].end > settings->ext13_start_prbs[alloc] + numPrbc) {
1725 settings->bundles[alloc_start+n].end = settings->ext13_start_prbs[alloc] + numPrbc;
1726 settings->bundles[alloc_start+n].is_orphan = true1;
1727 }
1728 }
1729 }
1730 }
1731
1732 /* Case where bundles are not controlled by other extensions - just divide up range into bundles we have */
1733 else {
1734 settings->num_bundles = (numPrbc+numBundPrb-1) / numBundPrb; /* rounded up */
1735
1736 /* Don't overflow settings->bundles[] */
1737 settings->num_bundles = MIN(MAX_BFW_BUNDLES, settings->num_bundles)(((512) < (settings->num_bundles)) ? (512) : (settings->
num_bundles))
;
1738
1739 /* For each bundle.. */
1740 for (uint32_t n=0; n < settings->num_bundles; n++) {
1741 /* Allocate start and end */
1742 settings->bundles[n].start = startPrbc + n*numBundPrb;
1743 settings->bundles[n].end = settings->bundles[n].start + numBundPrb - 1;
1744 /* If would go beyond end of PRBs, limit and identify as orphan */
1745 if (settings->bundles[n].end > startPrbc+numPrbc) {
1746 settings->bundles[n].end = startPrbc+numPrbc;
1747 settings->bundles[n].is_orphan = true1;
1748 }
1749 }
1750 }
1751}
1752
1753
1754/* Modulation Compression configuration */
1755typedef struct {
1756 /* Application of each entry is filtered by RE.
1757 * TODO: should also be filtered by PRB + symbol... */
1758 uint16_t mod_compr_re_mask;
1759
1760 /* Settings to apply */
1761 bool_Bool mod_compr_csf;
1762 float mod_compr_scaler;
1763} mod_compr_config_t;
1764
1765/* Multiple configs with a section */
1766typedef struct {
1767 uint16_t section_id;
1768 uint32_t num_configs;
1769
1770 #define MAX_MOD_COMPR_CONFIGS12 12
1771 mod_compr_config_t configs[MAX_MOD_COMPR_CONFIGS12];
1772} section_mod_compr_config_t;
1773
1774/* Flow has separate configs for each section */
1775typedef struct {
1776 uint16_t num_sections;
1777
1778 /* Separate config for each section */
1779 section_mod_compr_config_t sections[MAX_SECTION_IDs32];
1780} mod_compr_params_t;
1781
1782
1783typedef struct {
1784 uint32_t frame_number;
1785 nstime_t frame_time;
1786
1787 /* Timing to match */
1788 uint8_t frame;
1789 uint8_t subframe;
1790 uint8_t slot;
1791 uint8_t startSymbol;
1792
1793 bool_Bool in_use;
1794 uint16_t startPrb;
1795 uint16_t numPrb;
1796 uint16_t numSymbols;
1797 uint16_t beamIds[273];
1798} section_details_t;
1799
1800typedef struct {
1801 uint16_t sectionId;
1802 /* For the same sectionId, can have 2 currently active entries.. */
1803 section_details_t details[2];
1804} expected_section_data_t;
1805
1806
1807/*******************************************************/
1808/* Overall state of a flow (eAxC/plane) */
1809typedef struct {
1810 /* State for sequence analysis [each direction] */
1811 bool_Bool last_frame_seen[2];
1812 uint32_t last_frame[2];
1813 uint8_t next_expected_sequence_number[2];
1814
1815 /* expected frames. sectionId -> expected_section_data_t* */
1816 wmem_tree_t *expected_sections[2]; /* [direction] */
1817
1818 /* Table recording ackNack requests (ackNackId -> ack_nack_request_t*)
1819 Note that this assumes that the same ackNackId will not be reused within a state,
1820 which may well not be valid */
1821 wmem_tree_t *ack_nack_requests;
1822
1823 /* Store udCompHdr seen in C-Plane for UL - can be looked up and used by U-PLane.
1824 Note that this appears in the common section header parts of ST1, ST3, ST5,
1825 so can still be over-written per sectionId in the U-Plane */
1826 unsigned ul_ud_comp_hdr_frame;
1827 bool_Bool ul_ud_comp_hdr_set;
1828 unsigned ul_ud_comp_hdr_bit_width;
1829 int ul_ud_comp_hdr_compression;
1830
1831 bool_Bool udcomphdrDownlink_heuristic_result_set;
1832 bool_Bool udcomphdrDownlink_heuristic_result;
1833 bool_Bool udcomphdrUplink_heuristic_result_set;
1834 bool_Bool udcomphdrUplink_heuristic_result;
1835
1836 /* Modulation compression params */
1837 mod_compr_params_t mod_comp_params;
1838} flow_state_t;
1839
1840static section_mod_compr_config_t* get_mod_compr_section_to_write(flow_state_t *flow,
1841 unsigned sectionId)
1842{
1843 if (flow == NULL((void*)0)) {
1844 return NULL((void*)0);
1845 }
1846
1847 /* Look for this section among existing entries */
1848 for (unsigned s=0; s < flow->mod_comp_params.num_sections; s++) {
1849 if (flow->mod_comp_params.sections[s].section_id == sectionId) {
1850 return &flow->mod_comp_params.sections[s];
1851 }
1852 }
1853
1854 /* Not found, so try to add a new one */
1855 if (flow->mod_comp_params.num_sections >= MAX_SECTION_IDs32) {
1856 /* Can't allocate one! */
1857 return NULL((void*)0);
1858 }
1859 else {
1860 flow->mod_comp_params.sections[flow->mod_comp_params.num_sections].section_id = sectionId;
1861 return &flow->mod_comp_params.sections[flow->mod_comp_params.num_sections++];
1862 }
1863}
1864
1865static section_mod_compr_config_t* get_mod_compr_section_to_read(flow_state_t *flow,
1866 unsigned sectionId)
1867{
1868 if (flow == NULL((void*)0)) {
1869 return NULL((void*)0);
1870 }
1871
1872 /* Look for this section among existing entries */
1873 for (unsigned s=0; s < flow->mod_comp_params.num_sections; s++) {
1874 if (flow->mod_comp_params.sections[s].section_id == sectionId) {
1875 return &flow->mod_comp_params.sections[s];
1876 }
1877 }
1878
1879 /* Not found */
1880 return NULL((void*)0);
1881}
1882
1883
1884
1885typedef struct {
1886 uint32_t request_frame_number;
1887 nstime_t request_frame_time;
1888 enum {
1889 SE22,
1890 ST4Cmd1,
1891 ST4Cmd2,
1892 ST4Cmd3,
1893 ST4Cmd4
1894 } requestType;
1895
1896 uint32_t response_frame_number;
1897 nstime_t response_frame_time;
1898} ack_nack_request_t;
1899
1900static const value_string acknack_type_vals[] = {
1901 { SE22, "SE 22" },
1902 { ST4Cmd1, "ST4 (TIME_DOMAIN_BEAM_CONFIG)" },
1903 { ST4Cmd2, "ST4 (TDD_CONFIG_PATTERN)" },
1904 { ST4Cmd3, "ST4 (TRX_CONTROL)" },
1905 { ST4Cmd4, "ST4 (ASM)" },
1906 { 0, NULL((void*)0)}
1907};
1908
1909#define ORAN_C_PLANE0 0
1910#define ORAN_U_PLANE1 1
1911
1912/* Using parts of src/dst MAC address, so don't confuse UL messages with DL messages configuring UL.. */
1913static uint32_t make_flow_key(packet_info *pinfo, uint16_t eaxc_id, uint8_t plane, bool_Bool opposite_dir)
1914{
1915 uint16_t eth_bits = 0;
1916 if (pinfo->dl_src.len == 6 && pinfo->dl_dst.len == 6) {
1917 /* Only using (most of) 2 bytes from addresses for now, but reluctant to make key longer.. */
1918 const uint8_t *src_eth = (uint8_t*)pinfo->dl_src.data;
1919 const uint8_t *dst_eth = (uint8_t*)pinfo->dl_dst.data;
1920 if (!opposite_dir) {
1921 eth_bits = (src_eth[0]<<8) | dst_eth[5];
1922 }
1923 else {
1924 eth_bits = (dst_eth[0]<<8) | src_eth[5];
1925 }
1926 }
1927 return eaxc_id | (plane << 16) | (eth_bits << 17);
1928}
1929
1930
1931/* Table maintained on first pass from flow_key(uint32_t) -> flow_state_t* */
1932static wmem_tree_t *flow_states_table;
1933
1934typedef struct {
1935 uint32_t frame_number;
1936 uint16_t sectionId;
1937 uint32_t gap_in_usecs;
1938 uint8_t symbol;
1939 uint16_t startPrbu;
1940 uint16_t numPrbu;
1941} corresponding_uplane_frame;
1942
1943/* Table consulted on subsequent passes: frame_num -> flow_result_t* */
1944static wmem_tree_t *flow_results_table;
1945
1946typedef struct {
1947 /* Sequence analysis */
1948 bool_Bool unexpected_seq_number;
1949 uint8_t expected_sequence_number;
1950 uint32_t previous_frame;
1951
1952 /* sectionId -> expected_section_data_t* */
1953 /* Frame only covers one direction */
1954 wmem_tree_t *expected_sections;
1955
1956 /* List of u-plane frames (corresponding_uplane_frame*) corresponding to a c-plane frame */
1957 wmem_list_t *u_plane_frames;
1958} flow_result_t;
1959
1960
1961/* Uplink timing */
1962/* For a given symbol, track first to last UL frame to find out first-last time */
1963/* frameId (8) + subframeId (4) + slotId (6) + symbolId (6) = 24 bits */
1964/* N.B. if a capture lasts > 2.5s, may see same timing come around again... */
1965static uint32_t get_timing_key(uint8_t frameId, uint8_t subframeId, uint8_t slotId, uint8_t symbolId)
1966{
1967 return symbolId + (slotId<<8) + (subframeId<<14) + (frameId<<18);
1968}
1969
1970typedef struct {
1971 uint32_t first_frame;
1972 nstime_t first_frame_time;
1973 uint32_t frames_seen_in_symbol;
1974 uint32_t last_frame_in_symbol;
1975} ul_timing_for_slot;
1976
1977/* Set during first pass. timing_key -> ul_timing_for_slot* */
1978static wmem_tree_t *ul_symbol_timing;
1979
1980
1981/* Tracking lifetimes of DL beamIds */
1982typedef struct {
1983 uint32_t frame_defined;
1984 uint32_t symbol_when_defined;
1985} bfw_definition;
1986
1987/* Maintained during first pass: beamId (from ext11) -> bfw_definition */
1988static wmem_tree_t *dl_beam_ids_defined;
1989/* Lookup where/when beamIds were defined (frameid:beamid) -> bfw_definition */
1990static wmem_tree_t *dl_beam_ids_results;
1991
1992
1993static void show_link_to_acknack_response(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo,
1994 ack_nack_request_t *response);
1995
1996
1997
1998
1999static void write_pdu_label_and_info(proto_item *ti1, proto_item *ti2,
2000 packet_info *pinfo, const char *format, ...) G_GNUC_PRINTF(4, 5)__attribute__((__format__ (__printf__, 4, 5)));
2001
2002 /* Write the given formatted text to:
2003 - the info column (if pinfo != NULL)
2004 - 1 or 2 other labels (optional)
2005 */
2006static void write_pdu_label_and_info(proto_item *ti1, proto_item *ti2,
2007 packet_info *pinfo, const char *format, ...)
2008{
2009#define MAX_INFO_BUFFER256 256
2010 char info_buffer[MAX_INFO_BUFFER256];
2011 va_list ap;
2012
2013 if ((ti1 == NULL((void*)0)) && (ti2 == NULL((void*)0)) && (pinfo == NULL((void*)0))) {
2014 return;
2015 }
2016
2017 va_start(ap, format)__builtin_va_start(ap, format);
2018 vsnprintf(info_buffer, MAX_INFO_BUFFER256, format, ap);
2019 va_end(ap)__builtin_va_end(ap);
2020
2021 /* Add to indicated places */
2022 if (pinfo != NULL((void*)0)) {
2023 col_append_str(pinfo->cinfo, COL_INFO, info_buffer);
2024 }
2025 if (ti1 != NULL((void*)0)) {
2026 proto_item_append_text(ti1, "%s", info_buffer);
2027 }
2028 if (ti2 != NULL((void*)0)) {
2029 proto_item_append_text(ti2, "%s", info_buffer);
2030 }
2031}
2032
2033/* Add section labels (type + PRB range) for C-Plane, U-Plane */
2034static void
2035write_section_info(proto_item *section_heading, packet_info *pinfo, proto_item *protocol_item,
2036 uint32_t section_id, uint32_t start_prbx, uint32_t num_prbx, uint32_t rb)
2037{
2038 switch (num_prbx) {
2039 case 0:
2040 /* None -> all */
2041 write_pdu_label_and_info(section_heading, protocol_item, pinfo, ", Id: %4d (all PRBs)", section_id);
2042 break;
2043 case 1:
2044 /* Single PRB */
2045 write_pdu_label_and_info(section_heading, protocol_item, pinfo, ", Id: %4d (PRB: %7u)", section_id, start_prbx);
2046 break;
2047 default:
2048 /* Range */
2049 write_pdu_label_and_info(section_heading, protocol_item, pinfo, ", Id: %4d (PRB: %3u-%3u%s)", section_id, start_prbx,
2050 start_prbx + (num_prbx-1)*(1+rb), rb ? " (every-other)" : "");
2051 }
2052}
2053
2054static void
2055write_channel_section_info(proto_item *section_heading, packet_info *pinfo,
2056 uint32_t section_id, uint32_t ueId, uint32_t start_prbx, uint32_t num_prbx,
2057 uint32_t num_trx)
2058{
2059 switch (num_prbx) {
2060 case 0:
2061 /* TODO: ?? */
2062 break;
2063 case 1:
2064 /* Single PRB */
2065 write_pdu_label_and_info(section_heading, NULL((void*)0), pinfo,
2066 ", Id: %4d (UEId=%5u PRB %7u, %2u antennas)",
2067 section_id, ueId, start_prbx, num_trx);
2068 break;
2069 default:
2070 /* Range */
2071 write_pdu_label_and_info(section_heading, NULL((void*)0), pinfo,
2072 ", Id: %4d (UEId=%5u PRBs %3u-%3u, %2u antennas)",
2073 section_id, ueId, start_prbx, start_prbx+num_prbx-1, num_trx);
2074 }
2075}
2076
2077/* Add a reserved field, and warn if value isn't 0 */
2078/* TODO: maybe add a pref not to output expert warning if becomes too annoying? */
2079static void add_reserved_field(proto_tree *tree, int hf, tvbuff_t *tvb, int offset, int len)
2080{
2081 uint32_t reserved;
2082 proto_item *res_ti = proto_tree_add_item_ret_uint(tree, hf, tvb, offset, len, ENC_NA0x00000000, &reserved);
2083 if (reserved != 0) {
2084 expert_add_info_format(NULL((void*)0), res_ti, &ei_oran_reserved_not_zero,
2085 "reserved field saw value of 0x%x", reserved);
2086 }
2087}
2088
2089/* 5.1.3.2.7 (real time control data / IQ data transfer message series identifier) */
2090static void
2091addPcOrRtcid(tvbuff_t *tvb, proto_tree *tree, unsigned *offset, int hf, uint16_t *eAxC, oran_tap_info *tap_info)
2092{
2093 /* Subtree */
2094 proto_item *oran_pcid_ti = proto_tree_add_item(tree, hf,
2095 tvb, *offset, 2, ENC_NA0x00000000);
2096 proto_tree *oran_pcid_tree = proto_item_add_subtree(oran_pcid_ti, ett_oran_ecpri_pcid);
2097
2098 uint64_t duPortId, bandSectorId, ccId, ruPortId = 0;
2099 int id_offset = *offset;
2100
2101 /* All parts of eAxC should be above 0, and should total 16 bits (breakdown controlled by preferences) */
2102 if (!((pref_du_port_id_bits > 0) && (pref_bandsector_id_bits > 0) && (pref_cc_id_bits > 0) && (pref_ru_port_id_bits > 0) &&
2103 ((pref_du_port_id_bits + pref_bandsector_id_bits + pref_cc_id_bits + pref_ru_port_id_bits) == 16))) {
2104 expert_add_info(NULL((void*)0), tree, &ei_oran_invalid_eaxc_bit_width);
2105 *eAxC = 0;
2106 *offset += 2;
2107 return;
2108 }
2109
2110 unsigned bit_offset = *offset * 8;
2111
2112 /* N.B. For sequence analysis / tapping, just interpret these 2 bytes as eAxC ID... */
2113 *eAxC = tvb_get_uint16(tvb, *offset, ENC_BIG_ENDIAN0x00000000);
2114
2115 /* DU Port ID */
2116 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);
2117 bit_offset += pref_du_port_id_bits;
2118 /* BandSector ID */
2119 proto_tree_add_bits_ret_val(oran_pcid_tree, hf_oran_bandsector_id, tvb, bit_offset, pref_bandsector_id_bits, &bandSectorId, ENC_BIG_ENDIAN0x00000000);
2120 bit_offset += pref_bandsector_id_bits;
2121 /* CC ID */
2122 proto_tree_add_bits_ret_val(oran_pcid_tree, hf_oran_cc_id, tvb, bit_offset, pref_cc_id_bits, &ccId, ENC_BIG_ENDIAN0x00000000);
2123 bit_offset += pref_cc_id_bits;
2124 /* RU Port ID */
2125 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);
2126 *offset += 2;
2127
2128 proto_item_append_text(oran_pcid_ti, " (DU_Port_ID: %d, BandSector_ID: %d, CC_ID: %d, RU_Port_ID: %d)",
2129 (int)duPortId, (int)bandSectorId, (int)ccId, (int)ruPortId);
2130 char id[16];
2131 snprintf(id, 16, "%x:%x:%x:%x", (int)duPortId, (int)bandSectorId, (int)ccId, (int)ruPortId);
2132 proto_item *pi = proto_tree_add_string(oran_pcid_tree, hf_oran_c_eAxC_ID, tvb, id_offset, 2, id);
2133 proto_item_set_generated(pi);
2134
2135 tap_info->eaxc = *eAxC;
2136 tap_info->eaxc_du_port_id = (uint16_t)duPortId;
2137 tap_info->eaxc_bandsector_id = (uint16_t)bandSectorId;
2138 tap_info->eaxc_cc_id = (uint16_t)ccId;
2139 tap_info->eaxc_ru_port_id = (uint16_t)ruPortId;
2140}
2141
2142/* Uniquely identify the U-plane stream that may need to be reassembled */
2143static uint32_t make_reassembly_id(uint32_t seqid, uint32_t direction, uint16_t eAxC,
2144 uint8_t frameid, uint8_t subframeid,
2145 uint8_t slotid, uint8_t symbolid)
2146{
2147 /* N.B., no room in 32-bits for all of this info, so cut down some of the fields
2148 and hope for no collisions */
2149 return (seqid << 24) | (direction << 23) | (slotid << 22) | (subframeid << 18) |
2150 (frameid << 9) | (symbolid << 6) | (eAxC & 0x3f);
2151}
2152
2153/* 5.1.3.2.8 ecpriSeqid (message identifier) */
2154/* Return out info that may be used for sequence number analysis and reassembly */
2155static int
2156addSeqid(tvbuff_t *tvb, proto_tree *oran_tree, int offset, int plane, uint32_t *seq_id, proto_item **seq_id_ti, packet_info *pinfo,
2157 uint32_t *subseqid, uint32_t *e)
2158{
2159 /* Subtree */
2160 proto_item *seqIdItem = proto_tree_add_item(oran_tree, hf_oran_ecpri_seqid, tvb, offset, 2, ENC_NA0x00000000);
2161 proto_tree *oran_seqid_tree = proto_item_add_subtree(seqIdItem, ett_oran_ecpri_seqid);
2162
2163 /* Sequence ID (8 bits) */
2164 *seq_id_ti = proto_tree_add_item_ret_uint(oran_seqid_tree, hf_oran_sequence_id, tvb, offset, 1, ENC_NA0x00000000, seq_id);
2165 offset += 1;
2166
2167 /* Show link back to previous sequence ID, if set */
2168 flow_result_t *result = wmem_tree_lookup32(flow_results_table, pinfo->num);
2169 if (result) {
2170 proto_item *prev_ti = proto_tree_add_uint(oran_seqid_tree, hf_oran_previous_frame, tvb, 0, 0, result->previous_frame);
2171 proto_item_set_generated(prev_ti);
2172 }
2173
2174 /* E bit */
2175 proto_tree_add_item_ret_uint(oran_seqid_tree, hf_oran_e_bit, tvb, offset, 1, ENC_NA0x00000000, e);
2176 /* Subsequence ID (7 bits) */
2177 proto_tree_add_item_ret_uint(oran_seqid_tree, hf_oran_subsequence_id, tvb, offset, 1, ENC_NA0x00000000, subseqid);
2178 offset += 1;
2179
2180 /* radio-transport fragmentation not allowed for C-Plane messages */
2181 if (plane == ORAN_C_PLANE0) {
2182 if (*e !=1 || *subseqid != 0) {
2183 expert_add_info(NULL((void*)0), seqIdItem, &ei_oran_radio_fragmentation_c_plane);
2184 }
2185 }
2186
2187 /* Summary */
2188 proto_item_append_text(seqIdItem, " (SeqId: %3d, E: %d, SubSeqId: %d)", *seq_id, *e, *subseqid);
2189 return offset;
2190}
2191
2192static int dissect_symbolmask(tvbuff_t *tvb, proto_tree *tree, int offset, uint32_t *symbol_mask, proto_item **ti)
2193{
2194 uint64_t temp_val;
2195
2196 static int * const symbol_mask_flags[] = {
2197 &hf_oran_symbol_mask_s13,
2198 &hf_oran_symbol_mask_s12,
2199 &hf_oran_symbol_mask_s11,
2200 &hf_oran_symbol_mask_s10,
2201 &hf_oran_symbol_mask_s9,
2202 &hf_oran_symbol_mask_s8,
2203 &hf_oran_symbol_mask_s7,
2204 &hf_oran_symbol_mask_s6,
2205 &hf_oran_symbol_mask_s5,
2206 &hf_oran_symbol_mask_s4,
2207 &hf_oran_symbol_mask_s3,
2208 &hf_oran_symbol_mask_s2,
2209 &hf_oran_symbol_mask_s1,
2210 &hf_oran_symbol_mask_s0,
2211 NULL((void*)0)
2212 };
2213
2214 proto_item *temp_ti = proto_tree_add_bitmask_ret_uint64(tree, tvb, offset,
2215 hf_oran_symbol_mask,
2216 ett_oran_symbol_mask, symbol_mask_flags,
2217 ENC_BIG_ENDIAN0x00000000, &temp_val);
2218 /* Set out parameters */
2219 if (symbol_mask) {
2220 *symbol_mask = (uint32_t)temp_val;
2221 }
2222 if (ti) {
2223 *ti = temp_ti;
2224 }
2225 return offset+2;
2226}
2227
2228/* 7.7.1.2 bfwCompHdr (beamforming weight compression header) */
2229static int dissect_bfwCompHdr(tvbuff_t *tvb, proto_tree *tree, int offset,
2230 uint32_t *iq_width, uint32_t *comp_meth, proto_item **comp_meth_ti)
2231{
2232 /* Subtree */
2233 proto_item *bfwcomphdr_ti = proto_tree_add_string_format(tree, hf_oran_bfwCompHdr,
2234 tvb, offset, 1, "",
2235 "bfwCompHdr");
2236 proto_tree *bfwcomphdr_tree = proto_item_add_subtree(bfwcomphdr_ti, ett_oran_bfwcomphdr);
2237
2238 /* Width and method */
2239 proto_tree_add_item_ret_uint(bfwcomphdr_tree, hf_oran_bfwCompHdr_iqWidth,
2240 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, iq_width);
2241 /* Special case: 0 -> 16 */
2242 *iq_width = (*iq_width==0) ? 16 : *iq_width;
2243 *comp_meth_ti = proto_tree_add_item_ret_uint(bfwcomphdr_tree, hf_oran_bfwCompHdr_compMeth,
2244 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, comp_meth);
2245 offset++;
2246
2247 /* Summary */
2248 proto_item_append_text(bfwcomphdr_ti, " (IqWidth=%u, compMeth=%s)",
2249 *iq_width,
2250 val_to_str_const(*comp_meth, bfw_comp_headers_comp_meth, "reserved"));
2251
2252 return offset;
2253}
2254
2255/* Return offset */
2256/* Returning number of entries set - would be good to also return an array of set TRX# so could show which array element
2257 each BFW is actually for.. */
2258static int dissect_active_beamspace_coefficient_mask(tvbuff_t *tvb, proto_tree *tree, int offset, unsigned *num_trx_entries, uint16_t **trx_entries)
2259{
2260 /* activeBeamspaceCoefficientMask - ceil(K/8) octets */
2261 /* K is the number of elements in uncompressed beamforming weight vector.
2262 * Calculated from parameters describing tx-array or tx-array */
2263 unsigned k_octets = (pref_num_bf_antennas + 7) / 8;
2264
2265 static uint16_t trx_enabled[1024];
2266
2267 /* TODO: could use a bigger bitmask array, but for now just uses this bytes-worth for each byte */
2268 static int * const mask_bits[] = {
2269 &hf_oran_active_beamspace_coefficient_n1,
2270 &hf_oran_active_beamspace_coefficient_n2,
2271 &hf_oran_active_beamspace_coefficient_n3,
2272 &hf_oran_active_beamspace_coefficient_n4,
2273 &hf_oran_active_beamspace_coefficient_n5,
2274 &hf_oran_active_beamspace_coefficient_n6,
2275 &hf_oran_active_beamspace_coefficient_n7,
2276 &hf_oran_active_beamspace_coefficient_n8,
2277 NULL((void*)0)
2278 };
2279
2280 *num_trx_entries = 0;
2281 uint64_t val;
2282 for (unsigned n=0; n < k_octets; n++) {
2283 proto_tree_add_bitmask_ret_uint64(tree, tvb, offset,
2284 hf_oran_activeBeamspaceCoefficientMask,
2285 ett_oran_active_beamspace_coefficient_mask, mask_bits,
2286 ENC_BIG_ENDIAN0x00000000, &val);
2287 offset++;
2288 /* Add up the set bits for this byte (but be careful not to count beyond last real K bit..) */
2289 for (unsigned b=0; b < 8; b++) {
2290 if ((1 << b) & (unsigned)val) {
2291 if (((n*8)+b) < pref_num_bf_antennas) {
2292 if (*num_trx_entries < 1024-1) { /* Don't write beyond array (which should be plenty big) */
2293 trx_enabled[(*num_trx_entries)++] = (n*8) + b + 1;
2294 }
2295 }
2296 }
2297 }
2298 }
2299 /* Set pointer to static array */
2300 *trx_entries = trx_enabled;
2301
2302 /* Show how many bits set */
2303 proto_item *ti = proto_tree_add_uint(tree, hf_oran_activeBeamspaceCoefficientMask_bits_set, tvb,
2304 offset-k_octets, k_octets, *num_trx_entries);
2305 proto_item_set_generated(ti);
2306
2307 return offset;
2308}
2309
2310static void add_beam_id_to_tap(oran_tap_info *tap_info, uint16_t beam_id)
2311{
2312 if (tap_info->num_beams < MAX_BEAMS_IN_FRAME32) {
2313 tap_info->beams[tap_info->num_beams++] = beam_id;
2314 }
2315}
2316
2317
2318/* 7.7.1.3 bfwCompParam (beamforming weight compression parameter).
2319 * Depends upon passed-in bfwCompMeth (field may be empty) */
2320static int dissect_bfwCompParam(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, int offset,
2321 proto_item *meth_ti, uint32_t *bfw_comp_method,
2322 uint32_t *exponent, bool_Bool *supported, unsigned *num_trx_entries, uint16_t **trx_entries)
2323{
2324 if (*bfw_comp_method == COMP_NONE0) {
2325 /* Absent! */
2326 *num_trx_entries = 0;
2327 *supported = true1;
2328 return offset;
2329 }
2330
2331 /* Subtree */
2332 proto_item *bfwcompparam_ti = proto_tree_add_string_format(tree, hf_oran_bfwCompParam,
2333 tvb, offset, 1, "",
2334 "bfwCompParam");
2335 proto_tree *bfwcompparam_tree = proto_item_add_subtree(bfwcompparam_ti, ett_oran_bfwcompparam);
2336
2337 proto_item_append_text(bfwcompparam_ti,
2338 " (meth=%s)", val_to_str_const(*bfw_comp_method, bfw_comp_headers_comp_meth, "reserved"));
2339
2340 *num_trx_entries = 0;
2341 *supported = false0;
2342 switch (*bfw_comp_method) {
2343 case COMP_BLOCK_FP1: /* block floating point */
2344 /* 4 reserved bits + exponent */
2345 add_reserved_field(bfwcompparam_tree, hf_oran_reserved_4bits, tvb, offset, 1);
2346 proto_tree_add_item_ret_uint(bfwcompparam_tree, hf_oran_exponent,
2347 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, exponent);
2348 proto_item_append_text(bfwcompparam_ti, " exponent=%u", *exponent);
2349 *supported = true1;
2350 offset++;
2351 break;
2352 case COMP_BLOCK_SCALE2: /* block scaling */
2353 /* Separate into integer and fractional bits? */
2354 proto_tree_add_item(bfwcompparam_tree, hf_oran_blockScaler,
2355 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
2356 offset++;
2357 break;
2358 case COMP_U_LAW3: /* u-law */
2359 /* compBitWidth, compShift */
2360 proto_tree_add_item(bfwcompparam_tree, hf_oran_compBitWidth,
2361 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
2362 proto_tree_add_item(bfwcompparam_tree, hf_oran_compShift,
2363 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
2364 offset++;
2365 break;
2366 case 4: /* beamspace I (BLOCK SCALING) */
2367 /* activeBeamspaceCoefficientMask */
2368 offset = dissect_active_beamspace_coefficient_mask(tvb, bfwcompparam_tree, offset, num_trx_entries, trx_entries);
2369 *bfw_comp_method = COMP_BLOCK_SCALE2;
2370 *supported = false0; /* TODO: true once BLOCK SCALE is supported */
2371 proto_tree_add_item(bfwcompparam_tree, hf_oran_blockScaler,
2372 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
2373 offset++;
2374 break;
2375 case 5: /* beamspace II (BLOCK FLOATING POINT) */
2376 /* activeBeamspaceCoefficientMask */
2377 offset = dissect_active_beamspace_coefficient_mask(tvb, bfwcompparam_tree, offset, num_trx_entries, trx_entries);
2378 /* reserved (4 bits) + exponent (4 bits) */
2379 add_reserved_field(bfwcompparam_tree, hf_oran_reserved_4bits, tvb, offset, 1);
2380 proto_tree_add_item_ret_uint(bfwcompparam_tree, hf_oran_exponent, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, exponent);
2381 offset += 1;
2382 *bfw_comp_method = COMP_BLOCK_FP1;
2383 *supported = true1;
2384 break;
2385
2386 default:
2387 /* Not handled */
2388 break;
2389 }
2390
2391 proto_item_set_end(bfwcompparam_ti, tvb, offset);
2392
2393 /* Can't go on if compression scheme not supported */
2394 if (!(*supported) && meth_ti) {
2395 expert_add_info_format(pinfo, meth_ti, &ei_oran_unsupported_bfw_compression_method,
2396 "BFW Compression method %u (%s) not decompressed by dissector",
2397 *bfw_comp_method,
2398 val_to_str_const(*bfw_comp_method, bfw_comp_headers_comp_meth, "reserved"));
2399 }
2400 return offset;
2401}
2402
2403
2404/* Special case for uncompressed/16-bit value */
2405static float uncompressed_to_float(uint32_t h)
2406{
2407 int16_t i16 = h & 0x0000ffff;
2408 if (show_unscaled_values) {
2409 return (float)i16;
2410 }
2411 return ((float)i16) / 0x7fff;
2412}
2413
2414/* Decompress I/Q value, taking into account method, width, exponent, other input-specific methods */
2415static float decompress_value(uint32_t bits, uint32_t comp_method, uint8_t iq_width,
2416 uint32_t exponent,
2417 /* Modulation compression settings. N.B. should also pass in PRB + symbol? */
2418 section_mod_compr_config_t *m_c_p, uint8_t re)
2419{
2420 switch (comp_method) {
2421 case COMP_NONE0: /* no compression */
2422 return uncompressed_to_float(bits);
2423
2424 case COMP_BLOCK_FP1: /* block floating point */
2425 case BFP_AND_SELECTIVE_RE5:
2426 {
2427 /* A.1.3 Block Floating Point Decompression Algorithm */
2428 int32_t cPRB = bits;
2429 uint32_t scaler = 1 << exponent; /* i.e. 2^exponent */
2430
2431 /* Check last bit, in case we need to flip to -ve */
2432 if (cPRB >= (1<<(iq_width-1))) {
2433 cPRB -= (1<<iq_width);
2434 }
2435
2436 /* Unscale (8.1.3.1) */
2437 cPRB *= scaler;
2438 if (show_unscaled_values) {
2439 return (float)cPRB;
2440 }
2441
2442 uint32_t mantissa_scale_factor = 1 << (iq_width-1); /* 2^(mantissabits-1) */
2443 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 */
2444
2445 float ret = cPRB / ((float)(mantissa_scale_factor*exp_scale_factor));
2446 return ret;
2447 }
2448
2449 case COMP_BLOCK_SCALE2:
2450 case COMP_U_LAW3:
2451 /* Not supported! But will be reported as expert info outside of this function! */
2452 return 0.0;
2453
2454 case COMP_MODULATION4:
2455 case MOD_COMPR_AND_SELECTIVE_RE6:
2456 {
2457 /* Described in A.5 (with pseudo code) */
2458 /* N.B., Applies to downlink data only - is not used for BFW */
2459
2460 /* Defaults if not overridden. TODO: what should these be? */
2461 bool_Bool csf = false0;
2462 float mcScaler = (float)(1 << 11);
2463
2464 /* Find csf + mcScaler to use. Non-default configs gleaned from SE 4,5,23 */
2465 /* TODO: should ideally be filtering by symbol and PRB too (as configured from SE23) */
2466 if (re > 0 && m_c_p && m_c_p->num_configs > 0) {
2467 for (unsigned c=0; c<m_c_p->num_configs; c++) {
2468 if (m_c_p->configs[c].mod_compr_re_mask & (1 << (12-re))) {
2469 /* Return first (should be only) found */
2470 csf = m_c_p->configs[c].mod_compr_csf;
2471 mcScaler = m_c_p->configs[c].mod_compr_scaler;
2472 break;
2473 }
2474 }
2475 }
2476
2477 int32_t cPRB = bits;
2478
2479 /* 2) Map iqSample to iqSampleFx */
2480 /* Check last bit, in case we need to flip to -ve */
2481 if (cPRB >= (1<<(iq_width-1))) {
2482 cPRB -= (1<<iq_width);
2483 }
2484 float iqSampleFx = (float)cPRB / (1 << (iq_width-1));
2485
2486
2487 /* 3) or 4) (b) - add unshifted value if csf set */
2488 float csf_to_add = 0.0;
2489 if (csf) {
2490 /* Unshift the constellation point */
2491 csf_to_add = (float)1.0 / (1 << (iq_width));
2492 }
2493 iqSampleFx += csf_to_add;
2494
2495 /* 3) or 4) (c) - unscaling */
2496 float iqSampleScaled = mcScaler * iqSampleFx * (float)sqrt(2);
2497 return iqSampleScaled;
2498 }
2499
2500 default:
2501 /* Not supported! But will be reported as expert info outside of this function! */
2502 return 0.0;
2503 }
2504}
2505
2506/* Out-of-range value used for special case */
2507#define ORPHAN_BUNDLE_NUMBER999 999
2508
2509/* Bundle of PRBs/TRX I/Q samples (ext 11) */
2510static uint32_t dissect_bfw_bundle(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, unsigned offset,
2511 proto_item *comp_meth_ti, uint32_t bfwcomphdr_comp_meth,
2512 section_mod_compr_config_t *mod_compr_params,
2513 uint32_t num_weights_per_bundle,
2514 uint8_t iq_width,
2515 unsigned bundle_number,
2516 unsigned first_prb, unsigned last_prb, bool_Bool is_orphan,
2517 uint32_t symbol_count,
2518 section_details_t *section_details,
2519 oran_tap_info *tap_info)
2520{
2521 /* Set bundle name */
2522 char bundle_name[32];
2523 if (!is_orphan) {
2524 snprintf(bundle_name, 32, "Bundle %3u", bundle_number);
2525 }
2526 else {
2527 (void) g_strlcpy(bundle_name, "Orphaned ", 32);
2528 }
2529
2530 /* Create Bundle root */
2531 proto_item *bundle_ti;
2532 if (first_prb != last_prb) {
2533 bundle_ti = proto_tree_add_string_format(tree, hf_oran_bfw_bundle,
2534 tvb, offset, 0, "",
2535 "%s: (PRBs %3u-%3u)",
2536 bundle_name,
2537 first_prb, last_prb);
2538 }
2539 else {
2540 bundle_ti = proto_tree_add_string_format(tree, hf_oran_bfw_bundle,
2541 tvb, offset, 0, "",
2542 "%s: (PRB %3u)",
2543 bundle_name,
2544 first_prb);
2545 }
2546 proto_tree *bundle_tree = proto_item_add_subtree(bundle_ti, ett_oran_bfw_bundle);
2547
2548 /* Generated bundle id */
2549 proto_item *bundleid_ti = proto_tree_add_uint(bundle_tree, hf_oran_bfw_bundle_id, tvb, 0, 0,
2550 bundle_number);
2551 proto_item_set_generated(bundleid_ti);
2552 proto_item_set_hidden(bundleid_ti);
2553
2554 /* bfwCompParam */
2555 bool_Bool compression_method_supported = false0;
2556 unsigned exponent = 0;
2557 unsigned num_trx_entries = 0;
2558 uint16_t *trx_entries;
2559 offset = dissect_bfwCompParam(tvb, bundle_tree, pinfo, offset, comp_meth_ti,
2560 &bfwcomphdr_comp_meth, &exponent, &compression_method_supported,
2561 &num_trx_entries, &trx_entries);
2562
2563 /* Create Bundle subtree */
2564 int bit_offset = offset*8;
2565 int bfw_offset;
2566
2567 /* contInd */
2568 proto_tree_add_item(bundle_tree, hf_oran_cont_ind,
2569 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
2570 /* beamId */
2571 uint32_t beam_id;
2572 proto_tree_add_item_ret_uint(bundle_tree, hf_oran_beam_id, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &beam_id);
2573 proto_item_append_text(bundle_ti, " (beamId:%u) ", beam_id);
2574 bit_offset += 16;
2575 add_beam_id_to_tap(tap_info, beam_id);
2576
2577 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
2578 if (section_details) {
2579 for (unsigned prb = first_prb; prb <= last_prb; prb++) {
2580 if (prb < 273) {
2581 section_details->beamIds[prb] = beam_id;
2582 }
2583 }
2584 }
2585 }
2586
2587 /* On first pass, record that beamId was defined here */
2588 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
2589 bfw_definition *definition = wmem_new0(wmem_file_scope(), bfw_definition)((bfw_definition*)wmem_alloc0((wmem_file_scope()), sizeof(bfw_definition
)))
;
2590 definition->frame_defined = pinfo->num;
2591 definition->symbol_when_defined = symbol_count;
2592 wmem_tree_insert32(dl_beam_ids_defined, beam_id, definition);
2593 }
2594
2595
2596 /* Number of weights per bundle (from preference) */
2597 proto_item *wpb_ti = proto_tree_add_uint(bundle_tree, hf_oran_num_weights_per_bundle, tvb, 0, 0,
2598 num_weights_per_bundle);
2599 proto_item_set_generated(wpb_ti);
2600
2601 /* Add the weights for this bundle. Overwrite with what was seen in bfwCompParam if beamspace */
2602 if (num_trx_entries != 0) {
2603 num_weights_per_bundle = num_trx_entries;
2604 }
2605
2606 bool_Bool non_zero_weights_seen = false0;
2607 int bit_offset_before_weights = bit_offset;
2608 for (unsigned w=0; w < num_weights_per_bundle; w++) {
2609
2610 uint16_t trx_index = (num_trx_entries) ? trx_entries[w] : w+1;
2611
2612 /* Create subtree */
2613 bfw_offset = bit_offset / 8;
2614 uint8_t bfw_extent = ((bit_offset + (iq_width*2)) / 8) - bfw_offset;
2615 proto_item *bfw_ti = proto_tree_add_string_format(bundle_tree, hf_oran_bfw,
2616 tvb, bfw_offset, bfw_extent,
2617 "", "TRX %3u: (", trx_index);
2618 proto_tree *bfw_tree = proto_item_add_subtree(bfw_ti, ett_oran_bfw);
2619
2620 /* I */
2621 /* Get bits, and convert to float. */
2622 uint32_t bits = tvb_get_bits32(tvb, bit_offset, iq_width, ENC_BIG_ENDIAN0x00000000);
2623 if (bits) {
2624 non_zero_weights_seen = true1;
2625 }
2626 float value = decompress_value(bits, bfwcomphdr_comp_meth, iq_width,
2627 exponent, mod_compr_params, 0 /* RE */);
2628 /* Add to tree. */
2629 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);
2630 bit_offset += iq_width;
2631 proto_item_append_text(bfw_ti, "I%u=%f ", w, value);
2632
2633 /* Q */
2634 /* Get bits, and convert to float. */
2635 bits = tvb_get_bits32(tvb, bit_offset, iq_width, ENC_BIG_ENDIAN0x00000000);
2636 if (bits) {
2637 non_zero_weights_seen = true1;
2638 }
2639
2640 value = decompress_value(bits, bfwcomphdr_comp_meth, iq_width,
2641 exponent, mod_compr_params, 0 /* RE */);
2642 /* Add to tree. */
2643 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);
2644 bit_offset += iq_width;
2645 proto_item_append_text(bfw_ti, "Q%u=%f)", w, value);
2646 }
2647
2648 if (!non_zero_weights_seen) {
2649 proto_tree_add_item(bundle_tree, hf_oran_bundle_weights_all_zero, tvb,
2650 bit_offset_before_weights, (bit_offset+7)/8 - (bit_offset_before_weights/8), ENC_NA0x00000000);
2651 }
2652
2653 /* Set extent of bundle */
2654 proto_item_set_end(bundle_ti, tvb, (bit_offset+7)/8);
2655
2656 return (bit_offset+7)/8;
2657}
2658
2659/* Return new bit offset. in/out will always be byte-aligned.. */
2660static int dissect_ciCompParam(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U___attribute__((unused)), unsigned bit_offset,
2661 unsigned comp_meth, uint8_t *exponent)
2662{
2663 if (comp_meth == COMP_NONE0) {
2664 /* Nothing in frame so don't even create subtree */
2665 return bit_offset;
2666 }
2667
2668 /* Subtree */
2669 proto_item *cicompparam_ti = proto_tree_add_string_format(tree, hf_oran_ciCompParam,
2670 tvb, bit_offset/8, 1, "",
2671 "ciCompParam");
2672 proto_tree *cicompparam_tree = proto_item_add_subtree(cicompparam_ti, ett_oran_cicompparam);
2673 uint32_t ci_exponent;
2674
2675 /* Contents differ by compression method */
2676 switch (comp_meth) {
2677 case COMP_BLOCK_FP1:
2678 add_reserved_field(cicompparam_tree, hf_oran_reserved_4bits, tvb, bit_offset/8, 1);
2679 proto_tree_add_item_ret_uint(cicompparam_tree, hf_oran_exponent,
2680 tvb, bit_offset/8, 1, ENC_BIG_ENDIAN0x00000000, &ci_exponent);
2681 *exponent = ci_exponent;
2682 proto_item_append_text(cicompparam_ti, " (Exponent=%u)", ci_exponent);
2683 bit_offset += 8; /* one byte */
2684 break;
2685 case COMP_BLOCK_SCALE2:
2686 /* Separate into integer (1) and fractional (7) bits? */
2687 proto_tree_add_item(cicompparam_tree, hf_oran_blockScaler,
2688 tvb, bit_offset/8, 1, ENC_BIG_ENDIAN0x00000000);
2689 bit_offset += 8;
2690 break;
2691 case COMP_U_LAW3:
2692 /* compBitWidth, compShift (4 bits each) */
2693 proto_tree_add_item(cicompparam_tree, hf_oran_compBitWidth,
2694 tvb, bit_offset/8, 1, ENC_BIG_ENDIAN0x00000000);
2695 proto_tree_add_item(cicompparam_tree, hf_oran_compShift,
2696 tvb, bit_offset/8, 1, ENC_BIG_ENDIAN0x00000000);
2697 bit_offset += 8;
2698 break;
2699
2700 default:
2701 /* reserved, ? bytes of zeros.. */
2702 break;
2703 }
2704
2705 return bit_offset;
2706}
2707
2708/* frameStructure (7.5.2.13) */
2709static unsigned dissect_frame_structure(proto_item *tree, tvbuff_t *tvb, unsigned offset,
2710 uint32_t subframeId, uint32_t slotId)
2711{
2712 uint32_t scs;
2713 /* FFT Size (4 bits) */
2714 proto_tree_add_item(tree, hf_oran_frameStructure_fft, tvb, offset, 1, ENC_NA0x00000000);
2715 /* Subcarrier spacing (SCS) */
2716 proto_tree_add_item_ret_uint(tree, hf_oran_frameStructure_subcarrier_spacing, tvb, offset, 1, ENC_NA0x00000000, &scs);
2717
2718 /* Show slot within frame as a generated field. See table 7.5.13-3 */
2719 uint32_t slots_per_subframe = 1;
2720 if (scs <= 4) {
2721 slots_per_subframe = 1 << scs;
2722 }
2723 if (scs <= 4 || scs >= 12) {
2724 proto_item *ti = proto_tree_add_uint(tree, hf_oran_slot_within_frame, tvb, 0, 0,
2725 (slots_per_subframe*subframeId) + slotId);
2726 proto_item_set_generated(ti);
2727 }
2728 return offset + 1;
2729}
2730
2731static unsigned dissect_csf(proto_item *tree, tvbuff_t *tvb, unsigned bit_offset,
2732 unsigned iq_width, bool_Bool *p_csf)
2733{
2734 proto_item *csf_ti;
2735 uint64_t csf;
2736 csf_ti = proto_tree_add_bits_ret_val(tree, hf_oran_csf, tvb, bit_offset, 1, &csf, ENC_BIG_ENDIAN0x00000000);
2737 if (csf) {
2738 /* Table 7.7.4.2-1 Constellation shift definition (index is udIqWidth) */
2739 const char* shift_value[] = { "n/a", "1/2", "1/4", "1/8", "1/16", "1/32" };
2740 if (iq_width >=1 && iq_width <= 5) {
2741 proto_item_append_text(csf_ti, " (Shift Value is %s)", shift_value[iq_width]);
2742 }
2743 }
2744
2745 /* Set out parameter */
2746 if (p_csf != NULL((void*)0)) {
2747 *p_csf = (csf!=0);
2748 }
2749 return bit_offset+1;
2750}
2751
2752
2753/* Section 7.
2754 * N.B. these are the green parts of the tables showing Section Types, differing by section Type */
2755static int dissect_oran_c_section(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo,
2756 flow_state_t* state,
2757 uint32_t sectionType, oran_tap_info *tap_info, proto_item *protocol_item,
2758 uint32_t subframeId, uint32_t frameId, uint32_t slotId, uint32_t startSymbolId,
2759 uint8_t ci_iq_width, uint8_t ci_comp_meth, unsigned ci_comp_opt,
2760 unsigned num_sinr_per_prb)
2761{
2762 unsigned offset = 0;
2763 proto_tree *c_section_tree = NULL((void*)0);
2764 proto_item *sectionHeading = NULL((void*)0);
2765
2766 /* Section subtree */
2767 sectionHeading = proto_tree_add_string_format(tree, hf_oran_c_section,
2768 tvb, offset, 0, "", "Section");
2769 c_section_tree = proto_item_add_subtree(sectionHeading, ett_oran_c_section);
2770
2771 uint32_t sectionId = 0;
2772
2773 uint32_t startPrbc=0, startPrbu=0;
2774 uint32_t numPrbc=0, numPrbu=0;
2775 uint32_t ueId = 0;
2776 proto_item *ueId_ti = NULL((void*)0);
2777 uint32_t section_beamId = 0;
2778 proto_item *section_beamId_ti = NULL((void*)0);
2779 bool_Bool section_beamId_ignored = false0;
2780
2781 proto_item *numsymbol_ti = NULL((void*)0);
2782 bool_Bool numsymbol_ignored = false0;
2783
2784 proto_item *numprbc_ti = NULL((void*)0);
2785
2786 /* Config affecting ext11 bundles (initially unset) */
2787 ext11_settings_t ext11_settings;
2788 memset(&ext11_settings, 0, sizeof(ext11_settings));
2789
2790 /* Section Type 10 needs to keep track of PRB range that should be reported
2791 for msgTypeId=5 (Interference plus Noise for unallocated PRBs) */
2792 /* All PRBs start as false */
2793#define MAX_PRBS273 273
2794 bool_Bool prbs_for_st10_type5[MAX_PRBS273];
2795 memset(&prbs_for_st10_type5, 0, sizeof(prbs_for_st10_type5));
2796
2797 /* These UEIds are set by ST5, ST10 (single value), and extended by SE10 */
2798#define MAX_UEIDS16 16
2799 uint32_t ueids[MAX_UEIDS16];
2800 uint32_t number_of_ueids = 0;
2801
2802
2803 bool_Bool extension_flag = false0;
2804
2805 /* These sections (ST0, ST1, ST2, ST3, ST5, ST9, ST10, ST11) are similar, so handle as common with per-type differences */
2806 if (((sectionType <= SEC_C_UE_SCHED) || (sectionType >= SEC_C_SINR_REPORTING)) &&
2807 (sectionType != SEC_C_SLOT_CONTROL)) {
2808
2809 /* sectionID */
2810 proto_item *ti = proto_tree_add_item_ret_uint(c_section_tree, hf_oran_section_id, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &sectionId);
2811 if (sectionId == 4095) {
2812 proto_item_append_text(ti, " (not default coupling C/U planes using sectionId)");
2813 }
2814 offset++;
2815
2816 if (tap_info->num_section_ids < MAX_SECTION_IDs32) {
2817 tap_info->section_ids[tap_info->num_section_ids++] = sectionId;
2818 }
2819
2820 /* rb */
2821 uint32_t rb;
2822 proto_tree_add_item_ret_uint(c_section_tree, hf_oran_rb, tvb, offset, 1, ENC_NA0x00000000, &rb);
2823 /* symInc (1 bit) */
2824 /* TODO: mark as ignored if SE6, SE12 or SE19 present */
2825 if (sectionType != SEC_C_RRM_MEAS_REPORTS && /* Section Type 10 */
2826 sectionType != SEC_C_REQUEST_RRM_MEAS) { /* Section Type 11 */
2827 unsigned int sym_inc;
2828 proto_item *sym_inc_ti = proto_tree_add_item_ret_uint(c_section_tree, hf_oran_symInc, tvb, offset, 1, ENC_NA0x00000000, &sym_inc);
2829 if (sym_inc !=0 && (sectionType == SEC_C_SINR_REPORTING)) { /* Section Type 9 */
2830 /* "0 shall be used" */
2831 proto_item_append_text(sym_inc_ti, " (should be 0)");
2832 }
2833 }
2834 else {
2835 /* reserved (1 bit) */
2836 add_reserved_field(c_section_tree, hf_oran_reserved_bit5, tvb, offset, 1);
2837 }
2838
2839 /* startPrbx and numPrbx */
2840 if (sectionType == SEC_C_SINR_REPORTING) {
2841 /* startPrbu (10 bits) */
2842 proto_tree_add_item_ret_uint(c_section_tree, hf_oran_startPrbu, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &startPrbu);
2843 offset += 2;
2844
2845 /* numPrbu */
2846 numprbc_ti = proto_tree_add_item_ret_uint(c_section_tree, hf_oran_numPrbu, tvb, offset, 1, ENC_NA0x00000000, &numPrbu);
2847 if (numPrbu == 0) {
2848 proto_item_append_text(numprbc_ti, " (all PRBs - configured as %u)", pref_data_plane_section_total_rbs);
2849 numPrbu = pref_data_plane_section_total_rbs;
2850 }
2851 offset += 1;
2852 }
2853 else {
2854 /* startPrbc (10 bits) */
2855 proto_tree_add_item_ret_uint(c_section_tree, hf_oran_startPrbc, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &startPrbc);
2856 offset += 2;
2857
2858 /* numPrbc */
2859 numprbc_ti = proto_tree_add_item_ret_uint(c_section_tree, hf_oran_numPrbc, tvb, offset, 1, ENC_NA0x00000000, &numPrbc);
2860 if (numPrbc == 0) {
2861 proto_item_append_text(numprbc_ti, " (all PRBs - configured as %u)", pref_data_plane_section_total_rbs);
2862 /* TODO: should probably set to pref_data_plane_section_total_rbs, and define MAX_PRBS to > 273 ? */
2863 numPrbc = MAX_PRBS273;
2864 }
2865 offset += 1;
2866 }
2867
2868 /* Start with range from section. May get changed by SE6, SE12, SE20 */
2869 for (unsigned n=startPrbc; n < startPrbc+numPrbc; n++) {
2870 if (n < MAX_PRBS273) {
2871 prbs_for_st10_type5[n] = true1;
2872 }
2873 }
2874
2875 if (sectionType != SEC_C_SINR_REPORTING) { /* *NOT* Section Type 9 */
2876 static int * const remask_flags[] = {
2877 &hf_oran_reMask_re1,
2878 &hf_oran_reMask_re2,
2879 &hf_oran_reMask_re3,
2880 &hf_oran_reMask_re4,
2881 &hf_oran_reMask_re5,
2882 &hf_oran_reMask_re6,
2883 &hf_oran_reMask_re7,
2884 &hf_oran_reMask_re8,
2885 &hf_oran_reMask_re9,
2886 &hf_oran_reMask_re10,
2887 &hf_oran_reMask_re11,
2888 &hf_oran_reMask_re12,
2889 NULL((void*)0)
2890 };
2891
2892 /* reMask */
2893 uint64_t remask;
2894 proto_tree_add_bitmask_ret_uint64(c_section_tree, tvb, offset,
2895 hf_oran_reMask, ett_oran_remask, remask_flags, ENC_BIG_ENDIAN0x00000000, &remask);
2896 offset++;
2897 /* numSymbol */
2898 uint32_t numSymbol;
2899 numsymbol_ti = proto_tree_add_item_ret_uint(c_section_tree, hf_oran_numSymbol, tvb, offset, 1, ENC_NA0x00000000, &numSymbol);
2900 if ((sectionType == SEC_C_RRM_MEAS_REPORTS) && (numSymbol != 14)) { /* Section type 10 must have 14 symbols */
2901 proto_item_append_text(numsymbol_ti, " (for ST10, should be 14!)");
2902 expert_add_info_format(pinfo, numsymbol_ti, &ei_oran_st10_numsymbol_not_14,
2903 "numSymbol should be 14 for ST10 - found %u", numSymbol);
2904 }
2905 if ((startSymbolId + numSymbol) > 14) {
2906 /* Warn if startSymbol + numSymbol would be > 14 */
2907 expert_add_info_format(pinfo, numsymbol_ti, &ei_oran_too_many_symbols,
2908 "startSymbolId (%u) + numSymbol (%u) exceeds max of 14",
2909 startSymbolId, numSymbol);
2910 }
2911 offset++;
2912
2913 /* [ef] (extension flag) */
2914 switch (sectionType) {
2915 case SEC_C_UNUSED_RB: /* Section Type 0 */
2916 case SEC_C_NORMAL: /* Section Type 1 */
2917 case SEC_C_PRACH: /* Section Type 3 */
2918 case SEC_C_UE_SCHED: /* Section Type 5 */
2919 case SEC_C_RRM_MEAS_REPORTS: /* Section Type 10 */
2920 case SEC_C_REQUEST_RRM_MEAS: /* Section Type 11 */
2921 proto_tree_add_item_ret_boolean(c_section_tree, hf_oran_ef, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &extension_flag);
2922 break;
2923 default:
2924 /* Other section types don't support extensions */
2925 break;
2926 }
2927
2928 write_section_info(sectionHeading, pinfo, protocol_item, sectionId, startPrbc, numPrbc, rb);
2929 proto_item_append_text(sectionHeading, ", Symbols: %2u", numSymbol);
2930
2931 if (numPrbc == 0) {
2932 /* Special case for all PRBs */
2933 numPrbc = pref_data_plane_section_total_rbs;
2934 startPrbc = 0; /* may already be 0... */
2935 }
2936 }
2937 else {
2938 /* Section Type 9 */
2939 write_section_info(sectionHeading, pinfo, protocol_item, sectionId, startPrbu, numPrbu, rb);
2940 proto_item_append_text(sectionHeading, ", numSinrPerPrb: %2u", num_sinr_per_prb);
2941 }
2942
2943 /* Section type specific fields (after 'numSymbol') */
2944 switch (sectionType) {
2945 case SEC_C_UNUSED_RB: /* Section Type 0 - Table 7.4.2-1 */
2946 /* reserved (15 bits) */
2947 add_reserved_field(c_section_tree, hf_oran_reserved_15bits, tvb, offset, 2);
2948 offset += 2;
2949 break;
2950
2951 case SEC_C_NORMAL: /* Section Type 1 - Table 7.4.3-1 */
2952 /* beamId */
2953 section_beamId_ti = proto_tree_add_item_ret_uint(c_section_tree, hf_oran_beamId, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &section_beamId);
2954 offset += 2;
2955
2956 /* beamId might get invalidated by e.g., ext-6, ext-11, so unused value will still be shown here.. */
2957 proto_item_append_text(sectionHeading, ", BeamId: %d", section_beamId);
2958 break;
2959
2960 case SEC_C_PRACH: /* Section Type 3 - Table 7.4.5-1 */
2961 {
2962 /* beamId */
2963 section_beamId_ti = proto_tree_add_item_ret_uint(c_section_tree, hf_oran_beamId, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &section_beamId);
2964 offset += 2;
2965
2966 /* freqOffset */
2967 int32_t freqOffset; /* Yes, this is signed, so the cast is intentional. */
2968 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);
2969 freqOffset |= 0xff000000; /* Must sign-extend */
2970 proto_item_set_text(freq_offset_item, "Frequency offset: %d \u0394f", freqOffset);
2971 offset += 3;
2972
2973 /* reserved (8 bits) */
2974 add_reserved_field(c_section_tree, hf_oran_reserved_8bits, tvb, offset, 1);
2975 offset += 1;
2976
2977 /* beamId might get invalidated by e.g., ext-6, ext-11, so unused value will still be shown here.. */
2978 proto_item_append_text(sectionHeading, ", BeamId: %d, FreqOffset: %d \u0394f", section_beamId, freqOffset);
2979 break;
2980 }
2981
2982 case SEC_C_UE_SCHED: /* Section Type 5 - Table 7.4.7-1 */
2983 case SEC_C_RRM_MEAS_REPORTS: /* Section Type 10 - Table 7.4.12-1 */
2984 /* ueId */
2985 ueId_ti = proto_tree_add_item_ret_uint(c_section_tree, hf_oran_ueId, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &ueId);
2986 offset += 2;
2987 if (ueId == 0x7fff) {
2988 proto_item_append_text(ueId_ti, " (PRBs not scheduled for eAxC ID in transport header)");
2989 }
2990 else {
2991 ueids[number_of_ueids++] = ueId;
2992 }
2993
2994 proto_item_append_text(sectionHeading, ", UEId: %d", ueId);
2995 break;
2996
2997 case SEC_C_SINR_REPORTING: /* Section Type 9 - SINR Reporting */
2998 {
2999 /* Hidden filter for bf (DMFS-BF) */
3000 proto_item *bf_ti = proto_tree_add_item(tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
3001 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
3002
3003 unsigned bit_offset = offset*8;
3004
3005 /* sinr iqWidth */
3006 proto_item *iq_width_item = proto_tree_add_uint(c_section_tree, hf_oran_sinrCompHdrIqWidth_pref, tvb, 0, 0, pref_sample_bit_width_sinr);
3007 proto_item_append_text(iq_width_item, " (from preferences)");
3008 proto_item_set_generated(iq_width_item);
3009
3010 /* sinr compMethod */
3011 proto_item *sinr_comp_meth_item = proto_tree_add_uint(c_section_tree, hf_oran_sinrCompHdrMeth_pref, tvb, 0, 0, pref_iqCompressionSINR);
3012 proto_item_append_text(sinr_comp_meth_item, " (from preferences)");
3013 proto_item_set_generated(sinr_comp_meth_item);
3014
3015 /* Add SINR entries for each PRB */
3016 for (unsigned prb=startPrbu; prb < startPrbu+numPrbu; prb++) {
3017 /* Create a subtree for each PRB */
3018 proto_item *prb_ti = proto_tree_add_string_format(c_section_tree, hf_oran_sinr_prb,
3019 tvb, offset, 0, "", "PRB %3u (", prb);
3020 proto_tree *prb_tree = proto_item_add_subtree(prb_ti, ett_oran_sinr_prb);
3021
3022 /* Each prb starts byte-aligned */
3023 bit_offset = ((bit_offset+7)/8) * 8;
3024
3025 /* N.B., using width/method from UL U-plane preferences, not certain that this is correct.. */
3026
3027 /* sinrCompParam (udCompParam format, may be empty) */
3028 uint32_t exponent = 0; /* N.B. init to silence warnings, but will always be set if read in COMP_BLOCK_FP case */
3029 uint16_t sReSMask;
3030 bit_offset = dissect_udcompparam(tvb, pinfo, prb_tree, bit_offset/8,
3031 pref_iqCompressionSINR, &exponent, &sReSMask,
3032 true1) * 8; /* last param is for_sinr */
3033
3034 /* sinrValues for this PRB. */
3035 /* TODO: not sure how numSinrPerPrb interacts with rb==1... */
3036 for (unsigned n=0; n < num_sinr_per_prb; n++) {
3037 unsigned sinr_bits = tvb_get_bits32(tvb, bit_offset, pref_sample_bit_width_sinr, ENC_BIG_ENDIAN0x00000000);
3038
3039 /* Using SINR compression settings from preferences */
3040 float value = decompress_value(sinr_bits,
3041 pref_iqCompressionSINR, pref_sample_bit_width_sinr,
3042 exponent,
3043 NULL((void*)0) /* no ModCompr for SINR */, 0 /* RE */);
3044 unsigned sample_len_in_bytes = ((bit_offset%8)+pref_sample_bit_width_sinr+7)/8;
3045 proto_item *val_ti = proto_tree_add_float(prb_tree, hf_oran_sinr_value, tvb,
3046 bit_offset/8, sample_len_in_bytes, value);
3047 proto_item_append_text(prb_ti, " %8f", value);
3048
3049 /* Show here which subcarriers share which values (they all divide 12..) */
3050 if (num_sinr_per_prb == 12) {
3051 proto_item_append_text(val_ti, " (PRB=%u, subcarrier %u)",
3052 startPrbu+((prb-startPrbu)*(rb+1)), n*(12/num_sinr_per_prb));
3053 }
3054 else {
3055 proto_item_append_text(val_ti, " (PRB=%u, subcarriers %u-%u)",
3056 startPrbu+((prb-startPrbu)*(rb+1)),
3057 n*(12/num_sinr_per_prb), (n+1)*(12/num_sinr_per_prb)-1);
3058 }
3059 bit_offset += pref_sample_bit_width_sinr;
3060 }
3061
3062 /* 1-byte alignment per PRB (7.2.11) */
3063 offset = (bit_offset+7)/8;
3064 bit_offset = offset*8;
3065
3066 proto_item_append_text(prb_ti, ")");
3067 proto_item_set_end(prb_ti, tvb, offset);
3068 }
3069 break;
3070 }
3071 case SEC_C_REQUEST_RRM_MEAS: /* Section Type 11 - Request RRM Measurements */
3072 /* Reserved (15 bits) */
3073 add_reserved_field(c_section_tree, hf_oran_reserved_15bits, tvb, offset, 2);
3074 offset += 2;
3075 break;
3076
3077 default:
3078 break;
3079 }
3080 }
3081 else if (sectionType == SEC_C_CH_INFO) { /* Section Type 6 */
3082 /* ef */
3083 proto_tree_add_item_ret_boolean(c_section_tree, hf_oran_ef, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &extension_flag);
3084 /* ueId */
3085 proto_tree_add_item_ret_uint(c_section_tree, hf_oran_ueId, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &ueId);
3086 offset += 2;
3087 /* regularizationFactor */
3088 proto_tree_add_item(c_section_tree, hf_oran_regularizationFactor, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
3089 offset += 2;
3090 /* reserved (4 bits) */
3091 add_reserved_field(c_section_tree, hf_oran_reserved_4bits, tvb, offset, 1);
3092 /* rb ("Value=0 shall be set") */
3093 uint32_t rb;
3094 proto_item *rb_ti = proto_tree_add_item_ret_uint(c_section_tree, hf_oran_rb, tvb, offset, 1, ENC_NA0x00000000, &rb);
3095 if (rb != 0) {
3096 proto_item_append_text(rb_ti, " (should be set to 0)");
3097 expert_add_info(pinfo, rb_ti, &ei_oran_st6_rb_shall_be_0);
3098 }
3099 /* symInc */
3100 proto_tree_add_item(c_section_tree, hf_oran_symInc, tvb, offset, 1, ENC_NA0x00000000);
3101 /* startPrbc */
3102 proto_tree_add_item_ret_uint(c_section_tree, hf_oran_startPrbc, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &startPrbc);
3103 offset += 2;
3104 /* numPrbc */
3105 proto_tree_add_item_ret_uint(c_section_tree, hf_oran_numPrbc, tvb, offset, 1, ENC_NA0x00000000, &numPrbc);
3106 offset += 1;
3107
3108 /* Hidden filter for bf */
3109 proto_item *bf_ti = proto_tree_add_item(tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
3110 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
3111
3112 /* ciIsample,ciQsample pairs */
3113 unsigned m;
3114 unsigned prb;
3115 uint32_t bit_offset = offset*8;
3116
3117 /* Antenna count from preference */
3118 unsigned num_trx = pref_num_bf_antennas;
3119
3120 write_channel_section_info(sectionHeading, pinfo,
3121 sectionId, ueId, startPrbc, numPrbc, num_trx);
3122
3123 bool_Bool first_prb = true1;
3124 uint8_t exponent = 0;
3125 for (prb=startPrbc; prb < startPrbc+numPrbc; prb++) {
3126
3127 /* PRB subtree */
3128 unsigned prb_start_offset = bit_offset;
3129 proto_item *prb_ti = proto_tree_add_string_format(c_section_tree, hf_oran_samples_prb,
3130 tvb, bit_offset/8, 0,
3131 "", "PRB=%u", prb);
3132 proto_tree *prb_tree = proto_item_add_subtree(prb_ti, ett_oran_prb_cisamples);
3133
3134 /* There may be a ciCompParam here.. */
3135 if (first_prb || ci_comp_opt==1) {
3136 bit_offset = dissect_ciCompParam(tvb, prb_tree, pinfo, bit_offset, ci_comp_meth, &exponent);
3137 }
3138 first_prb = false0;
3139
3140 /* Antennas */
3141 for (m=0; m < num_trx; m++) {
3142
3143 unsigned sample_offset = bit_offset / 8;
3144 uint8_t sample_extent = ((bit_offset + (ci_iq_width*2)) / 8) - sample_offset;
3145
3146 /* Create subtree for antenna */
3147 proto_item *sample_ti = proto_tree_add_string_format(prb_tree, hf_oran_ciSample,
3148 tvb, sample_offset, sample_extent,
3149 "", "TRX=%2u: ", m);
3150 proto_tree *sample_tree = proto_item_add_subtree(sample_ti, ett_oran_cisample);
3151
3152 /* I */
3153 /* Get bits, and convert to float. */
3154 uint32_t bits = tvb_get_bits32(tvb, bit_offset, ci_iq_width, ENC_BIG_ENDIAN0x00000000);
3155 float value = decompress_value(bits, ci_comp_meth, ci_iq_width, exponent, NULL((void*)0) /* no ModCompr for ST6 */, 0 /* RE */);
3156
3157 /* Add to tree. */
3158 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);
3159 bit_offset += ci_iq_width;
3160 proto_item_append_text(sample_ti, "I%u=%f ", m, value);
3161
3162 /* Q */
3163 /* Get bits, and convert to float. */
3164 bits = tvb_get_bits32(tvb, bit_offset, ci_iq_width, ENC_BIG_ENDIAN0x00000000);
3165 value = decompress_value(bits, ci_comp_meth, ci_iq_width, exponent, NULL((void*)0) /* no ModCompr for ST6 */, 0 /* RE */);
3166
3167 /* Add to tree. */
3168 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);
3169 bit_offset += ci_iq_width;
3170 proto_item_append_text(sample_ti, "Q%u=%f ", m, value);
3171 }
3172 proto_item_set_len(prb_ti, (bit_offset-prb_start_offset+7)/8);
3173 }
3174
3175 /* Pad out by 1 or 4 bytes, according to preference */
3176 if (!st6_4byte_alignment) {
3177 offset = (bit_offset + 7) / 8;
3178 }
3179 else {
3180 int mode = bit_offset % 32;
3181 if (mode != 0) {
3182 offset = (bit_offset + (32-mode))/8;
3183 }
3184 else {
3185 offset = bit_offset/8;
3186 }
3187 }
3188 proto_item_set_end(c_section_tree, tvb, offset);
3189 }
3190
3191
3192 expected_section_data_t *data_section = NULL((void*)0);
3193 unsigned index_to_use = 0;
3194
3195 /* On first pass, allocate a section entry to use */
3196 if (link_planes_together && !PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
3197
3198 /* Look for existing entry for sectionId to overwrite first. */
3199 uint8_t direction = !tap_info->uplink;
3200 data_section = wmem_tree_lookup32(state->expected_sections[direction],
3201 sectionId);
3202 if (data_section == NULL((void*)0)) {
3203 /* None, so create */
3204 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)))
;
3205 wmem_tree_insert32(state->expected_sections[direction],
3206 sectionId,
3207 data_section);
3208 }
3209
3210 /* If 2nd entry not in use, use that one */
3211 if (!data_section->details[1].in_use) {
3212 index_to_use = 1;
3213 }
3214 else {
3215 /* Both in use, so replace the older of the 2 entries */
3216 if (data_section->details[1].frame_number < data_section->details[0].frame_number) {
3217 index_to_use = 1;
3218 }
3219 }
3220
3221 if (data_section) {
3222 section_details_t *details = &data_section->details[index_to_use];
3223
3224 details->in_use = true1;
3225 details->frame = frameId;
3226 details->subframe = subframeId;
3227 details->slot = slotId;
3228 details->startSymbol = startSymbolId;
3229
3230 details->frame_number = pinfo->num;
3231 details->frame_time = pinfo->abs_ts;
3232 data_section->sectionId = sectionId;
3233 details->startPrb = startPrbc;
3234 details->numPrb = numPrbc;
3235 for (unsigned prb = startPrbc; prb <= startPrbc+numPrbc; prb++) {
3236 if (prb < 273) {
3237 details->beamIds[prb] = section_beamId;
3238 }
3239 }
3240 }
3241 }
3242
3243 bool_Bool seen_se10 = false0;
3244 uint32_t numPortc = 0;
3245 proto_item *bf_ti = NULL((void*)0);
3246
3247 /* Section extension commands */
3248 while (extension_flag) {
3249 int extension_start_offset = offset;
3250
3251 /* Prefetch extType so can use specific extension type ett */
3252 uint32_t exttype = tvb_get_uint8(tvb, offset) & 0x7f;
3253 uint32_t exttype_ett_index = exttype;
3254 if (exttype == 0 || exttype > HIGHEST_EXTTYPE32) {
3255 /* Just use first one if out of range */
3256 exttype_ett_index = 1;
3257 }
3258
3259 /* Create subtree for each extension (with summary) */
3260 proto_item *extension_ti = proto_tree_add_string_format(c_section_tree, hf_oran_extension,
3261 tvb, offset, 0, "", "Extension");
3262 proto_tree *extension_tree = proto_item_add_subtree(extension_ti, ett_oran_c_section_extension[exttype_ett_index-1]);
3263
3264 /* ef (i.e. another extension after this one?) */
3265 proto_tree_add_item_ret_boolean(extension_tree, hf_oran_ef, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &extension_flag);
3266
3267 /* extType */
3268 proto_item *exttype_ti;
3269 exttype_ti = proto_tree_add_item(extension_tree, hf_oran_exttype, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3270 offset++;
3271 proto_item_append_text(sectionHeading, " (ext-%u)", exttype);
3272
3273 proto_item_append_text(extension_ti, " (ext-%u: %s)", exttype, val_to_str_ext_const(exttype, &exttype_vals_ext, "Reserved"));
3274
3275 /* Don't tap if out of range. */
3276 if (exttype > 0 && exttype <= HIGHEST_EXTTYPE32) {
3277 tap_info->extensions[exttype] = true1;
3278 }
3279
3280 /* Is this SE allowed for this section type? */
3281 if (!se_allowed_in_st(exttype, sectionType)) {
3282 expert_add_info_format(pinfo, extension_tree, &ei_oran_se_on_unsupported_st,
3283 "SE %u (%s) should not appear in ST %u (%s)!",
3284 exttype, val_to_str_ext_const(exttype, &exttype_vals_ext, "Reserved"),
3285 sectionType, rval_to_str_const(sectionType, section_types, "Unknown"));
3286 }
3287
3288
3289 /* extLen (number of 32-bit words) */
3290 uint32_t extlen_len = ((exttype==11)||(exttype==19)||(exttype==20)) ? 2 : 1; /* Extensions 11/19/20 are special */
3291 uint32_t extlen;
3292 proto_item *extlen_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_extlen, tvb,
3293 offset, extlen_len, ENC_BIG_ENDIAN0x00000000, &extlen);
3294 proto_item_append_text(extlen_ti, " (%u bytes)", extlen*4);
3295 offset += extlen_len;
3296 if (extlen == 0) {
3297 expert_add_info(pinfo, extlen_ti, &ei_oran_extlen_zero);
3298 /* Break out to avoid infinitely looping! */
3299 break;
3300 }
3301
3302 bool_Bool ext_unhandled = false0;
3303
3304 switch (exttype) {
3305
3306 case 1: /* SE 1: Beamforming Weights */
3307 {
3308 uint32_t bfwcomphdr_iq_width, bfwcomphdr_comp_meth;
3309 proto_item *comp_meth_ti = NULL((void*)0);
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 /* bfwCompHdr (2 subheaders - bfwIqWidth and bfwCompMeth)*/
3316 offset = dissect_bfwCompHdr(tvb, extension_tree, offset,
3317 &bfwcomphdr_iq_width, &bfwcomphdr_comp_meth, &comp_meth_ti);
3318
3319 /* bfwCompParam */
3320 uint32_t exponent = 0;
3321 bool_Bool compression_method_supported = false0;
3322 unsigned num_trx = 0;
3323 uint16_t *trx; /* ptr to array */
3324 offset = dissect_bfwCompParam(tvb, extension_tree, pinfo, offset, comp_meth_ti,
3325 &bfwcomphdr_comp_meth, &exponent, &compression_method_supported,
3326 &num_trx, &trx);
3327
3328 /* Can't show details of unsupported compression method */
3329 if (!compression_method_supported) {
3330 break;
3331 }
3332
3333 /* We know:
3334 - iq_width (above)
3335 - numBfWeights (taken from preference)
3336 - remaining bytes in extension
3337 We can therefore derive TRX (number of antennas).
3338 */
3339
3340 bool_Bool using_array = false0;
3341
3342 /* I & Q samples
3343 May know how many entries from activeBeamspaceCoefficientMask. */
3344 if (num_trx == 0) {
3345 /* Don't know how many there will be, so just fill available bytes... */
3346 unsigned weights_bytes = (extlen*4)-3;
3347 unsigned num_weights_pairs = (weights_bytes*8) / (bfwcomphdr_iq_width*2);
3348 num_trx = num_weights_pairs;
3349 }
3350 else {
3351 using_array = true1;
3352 num_trx = pref_num_bf_antennas;
3353 }
3354
3355 int bit_offset = offset*8;
3356
3357 for (unsigned n=0; n < num_trx; n++) {
3358 /* Create antenna subtree */
3359 int bfw_offset = bit_offset / 8;
3360
3361 uint16_t trx_index = (using_array) ? trx[n] : n+1;
3362
3363 proto_item *bfw_ti = proto_tree_add_string_format(extension_tree, hf_oran_bfw,
3364 tvb, bfw_offset, 0, "", "TRX %3u: (", trx_index);
3365 proto_tree *bfw_tree = proto_item_add_subtree(bfw_ti, ett_oran_bfw);
3366
3367 /* I value */
3368 /* Get bits, and convert to float. */
3369 uint32_t bits = tvb_get_bits32(tvb, bit_offset, bfwcomphdr_iq_width, ENC_BIG_ENDIAN0x00000000);
3370 float value = decompress_value(bits, bfwcomphdr_comp_meth, bfwcomphdr_iq_width, exponent,
3371 NULL((void*)0) /* no ModCompr */, 0 /* RE */);
3372 /* Add to tree. */
3373 proto_tree_add_float(bfw_tree, hf_oran_bfw_i, tvb, bit_offset/8,
3374 (bfwcomphdr_iq_width+7)/8, value);
3375 bit_offset += bfwcomphdr_iq_width;
3376 proto_item_append_text(bfw_ti, "I=%f ", value);
3377
3378 /* Leave a gap between I and Q values */
3379 proto_item_append_text(bfw_ti, " ");
3380
3381 /* Q value */
3382 /* Get bits, and convert to float. */
3383 bits = tvb_get_bits32(tvb, bit_offset, bfwcomphdr_iq_width, ENC_BIG_ENDIAN0x00000000);
3384 value = decompress_value(bits, bfwcomphdr_comp_meth, bfwcomphdr_iq_width, exponent,
3385 NULL((void*)0) /* no ModCompr */, 0 /* RE */);
3386 /* Add to tree. */
3387 proto_tree_add_float(bfw_tree, hf_oran_bfw_q, tvb, bit_offset/8,
3388 (bfwcomphdr_iq_width+7)/8, value);
3389 bit_offset += bfwcomphdr_iq_width;
3390 proto_item_append_text(bfw_ti, "Q=%f", value);
3391
3392 proto_item_append_text(bfw_ti, ")");
3393 proto_item_set_len(bfw_ti, (bit_offset+7)/8 - bfw_offset);
3394 }
3395 /* Need to round to next byte */
3396 offset = (bit_offset+7)/8;
3397
3398 break;
3399 }
3400
3401 case 2: /* SE 2: Beamforming attributes */
3402 {
3403 /* Hidden filter for bf */
3404 bf_ti = proto_tree_add_item(tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
3405 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
3406
3407 /* bfaCompHdr (get widths of fields to follow) */
3408 uint32_t bfAzPtWidth, bfZePtWidth, bfAz3ddWidth, bfZe3ddWidth;
3409 /* subtree */
3410 proto_item *bfa_ti = proto_tree_add_string_format(extension_tree, hf_oran_bfaCompHdr,
3411 tvb, offset, 2, "", "bfaCompHdr");
3412 proto_tree *bfa_tree = proto_item_add_subtree(bfa_ti, ett_oran_bfacomphdr);
3413
3414 /* reserved (2 bits) */
3415 add_reserved_field(bfa_tree, hf_oran_reserved_2bits, tvb, offset, 1);
3416 /* bfAzPtWidth (3 bits) */
3417 proto_tree_add_item_ret_uint(bfa_tree, hf_oran_bfAzPtWidth, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &bfAzPtWidth);
3418 /* bfZePtWidth (3 bits) */
3419 proto_tree_add_item_ret_uint(bfa_tree, hf_oran_bfZePtWidth, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &bfZePtWidth);
3420 offset += 1;
3421
3422 /* reserved (2 bits) */
3423 add_reserved_field(bfa_tree, hf_oran_reserved_2bits, tvb, offset, 1);
3424 /* bfAz3ddWidth (3 bits) */
3425 proto_tree_add_item_ret_uint(bfa_tree, hf_oran_bfAz3ddWidth, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &bfAz3ddWidth);
3426 /* bfZe3ddWidth (3 bits) */
3427 proto_tree_add_item_ret_uint(bfa_tree, hf_oran_bfZe3ddWidth, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &bfZe3ddWidth);
3428 offset += 1;
3429
3430 unsigned bit_offset = offset*8;
3431
3432 /* bfAzPt */
3433 if (bfAzPtWidth > 0) {
3434 proto_tree_add_bits_item(extension_tree, hf_oran_bfAzPt, tvb, bit_offset, bfAzPtWidth+1, ENC_BIG_ENDIAN0x00000000);
3435 bit_offset += (bfAzPtWidth+1);
3436 }
3437 /* bfZePt */
3438 if (bfZePtWidth > 0) {
3439 proto_tree_add_bits_item(extension_tree, hf_oran_bfZePt, tvb, bit_offset, bfZePtWidth+1, ENC_BIG_ENDIAN0x00000000);
3440 bit_offset += (bfZePtWidth+1);
3441 }
3442 /* bfAz3dd */
3443 if (bfAz3ddWidth > 0) {
3444 proto_tree_add_bits_item(extension_tree, hf_oran_bfAz3dd, tvb, bit_offset, bfAz3ddWidth+1, ENC_BIG_ENDIAN0x00000000);
3445 bit_offset += (bfAz3ddWidth+1);
3446 }
3447 /* bfZe3dd */
3448 if (bfZe3ddWidth > 0) {
3449 proto_tree_add_bits_item(extension_tree, hf_oran_bfZe3dd, tvb, bit_offset, bfZe3ddWidth+1, ENC_BIG_ENDIAN0x00000000);
3450 bit_offset += (bfZe3ddWidth+1);
3451 }
3452
3453 /* Pad to next byte (unless last 2 fields already fit in this one) */
3454 if ((bit_offset % 8) > 2) {
3455 offset = (bit_offset+7) / 8;
3456 }
3457 else {
3458 offset = bit_offset / 8;
3459 }
3460
3461 /* bfAzSl (3 bits) */
3462 proto_tree_add_item(extension_tree, hf_oran_bfAzSl, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3463 /* bfZeSl (3 bits) */
3464 proto_tree_add_item(extension_tree, hf_oran_bfZeSl, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3465 offset += 1;
3466 break;
3467 }
3468
3469 case 3: /* SE 3: DL precoding parameters */
3470 {
3471 /* codebookindex (8 bits) */
3472 /* "This parameter is not used and shall be set to zero." */
3473 proto_tree_add_item(extension_tree, hf_oran_codebook_index, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3474 offset += 1;
3475 /* layerid */
3476 uint32_t layerid;
3477 proto_tree_add_item_ret_uint(extension_tree, hf_oran_layerid, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &layerid);
3478 /* numLayers */
3479 proto_tree_add_item(extension_tree, hf_oran_numlayers, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3480 offset += 1;
3481
3482 /* Stop here for non-first data layer */
3483 if (layerid != 0 && layerid != 0xf) {
3484 break;
3485 }
3486
3487 /* First data layer case */
3488 /* txScheme */
3489 proto_tree_add_item(extension_tree, hf_oran_txscheme, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3490 /* crsReMask */
3491 proto_tree_add_item(extension_tree, hf_oran_crs_remask, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
3492 offset += 2;
3493
3494 /* crsShift (1 bit) */
3495 proto_tree_add_item(extension_tree, hf_oran_crs_shift, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3496 /* reserved (3 bits) */
3497 add_reserved_field(extension_tree, hf_oran_reserved_bits123, tvb, offset, 1);
3498 /* crsSymNum (4 bits) */
3499 proto_tree_add_item(extension_tree, hf_oran_crs_symnum, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3500 offset += 1;
3501 /* reserved (8 bits) */
3502 add_reserved_field(extension_tree, hf_oran_reserved_8bits, tvb, offset, 1);
3503 offset += 1;
3504
3505 /* reserved (1 bit) */
3506 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
3507 /* beamIdAP1 (15 bits) */
3508 proto_tree_add_item(extension_tree, hf_oran_beamid_ap1, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
3509 offset += 2;
3510 /* reserved (1 bit) */
3511 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
3512 /* beamIdAP2 (15 bits) */
3513 proto_tree_add_item(extension_tree, hf_oran_beamid_ap2, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
3514 offset += 2;
3515 /* reserved (1 bit) */
3516 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
3517 /* beamIdAP3 (15 bits) */
3518 proto_tree_add_item(extension_tree, hf_oran_beamid_ap3, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
3519 offset += 2;
3520 break;
3521 }
3522
3523 case 4: /* SE 4: Modulation compression params (5.4.7.4) (single sets) */
3524 {
3525 /* csf */
3526 bool_Bool csf;
3527 dissect_csf(extension_tree, tvb, offset*8, ci_iq_width, &csf);
3528
3529 /* modCompScaler */
3530 uint32_t modCompScaler;
3531 proto_item *ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_modcompscaler,
3532 tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &modCompScaler);
3533 offset += 2;
3534
3535 /* Work out and show floating point value too. exponent and mantissa are both unsigned */
3536 uint16_t exponent = (modCompScaler >> 11) & 0x000f; /* m.s. 4 bits */
3537 uint16_t mantissa = modCompScaler & 0x07ff; /* l.s. 11 bits */
3538 float value = ((float)mantissa/(1<<11)) * ((float)1.0 / (1 << exponent));
3539 proto_item_append_text(ti, " (%f)", value);
3540
3541 section_mod_compr_config_t* sect_config = get_mod_compr_section_to_write(state, sectionId);
3542
3543 /* Store these params in this flow's state */
3544 if (sect_config && sect_config->num_configs < MAX_MOD_COMPR_CONFIGS12) {
3545 unsigned i = sect_config->num_configs;
3546 sect_config->configs[i].mod_compr_re_mask = 0xfff; /* Covers all REs */
3547 sect_config->configs[i].mod_compr_csf = csf;
3548 sect_config->configs[i].mod_compr_scaler = value;
3549 sect_config->num_configs++;
3550 }
3551 break;
3552 }
3553
3554 case 5: /* SE 5: Modulation Compression Additional Parameters (7.7.5) (multiple sets) */
3555 {
3556 /* Applies only to section types 1,3 and 5 */
3557 /* N.B. there may be multiple instances of this SE in the same frame */
3558
3559 /* There may be one or 2 entries, depending upon extlen */
3560 int sets = 1, reserved_bits = 0;
3561 switch (extlen) {
3562 case 2:
3563 sets = 1;
3564 reserved_bits = 20;
3565 break;
3566 case 3:
3567 sets = 2;
3568 reserved_bits = 24;
3569 break;
3570 case 4:
3571 /* sets can be 3 or 4, depending upon whether last 28 bits are 0.. */
3572 if ((tvb_get_ntohl(tvb, offset+10) & 0x0fffffff) == 0) {
3573 sets = 3;
3574 reserved_bits = 28;
3575 }
3576 else {
3577 sets = 4;
3578 reserved_bits = 0;
3579 }
3580 break;
3581
3582 default:
3583 /* Malformed error!!! */
3584 expert_add_info_format(pinfo, extlen_ti, &ei_oran_extlen_wrong,
3585 "For section 5, extlen must be 2, 3 or 4, but %u was dissected",
3586 extlen);
3587 break;
3588 }
3589
3590 unsigned bit_offset = offset*8;
3591 /* Dissect each set */
3592 for (int n=0; n < sets; n++) {
3593 /* Subtree for each set */
3594 unsigned set_start_offset = bit_offset/8;
3595 proto_item *set_ti = proto_tree_add_string(extension_tree, hf_oran_modcomp_param_set,
3596 tvb, set_start_offset, 0, "");
3597 proto_tree *set_tree = proto_item_add_subtree(set_ti, ett_oran_modcomp_param_set);
3598
3599 uint64_t mcScaleReMask, mcScaleOffset;
3600 bool_Bool csf;
3601
3602 /* mcScaleReMask (12 bits). Defines which REs the following csf and mcScaleOffset apply to */
3603 static int * const remask_flags[] = {
3604 &hf_oran_mc_scale_re_mask_re1,
3605 &hf_oran_mc_scale_re_mask_re2,
3606 &hf_oran_mc_scale_re_mask_re3,
3607 &hf_oran_mc_scale_re_mask_re4,
3608 &hf_oran_mc_scale_re_mask_re5,
3609 &hf_oran_mc_scale_re_mask_re6,
3610 &hf_oran_mc_scale_re_mask_re7,
3611 &hf_oran_mc_scale_re_mask_re8,
3612 &hf_oran_mc_scale_re_mask_re9,
3613 &hf_oran_mc_scale_re_mask_re10,
3614 &hf_oran_mc_scale_re_mask_re11,
3615 &hf_oran_mc_scale_re_mask_re12,
3616 NULL((void*)0)
3617 };
3618 /* Same as above, but offset by 4 bits */
3619 static int * const remask_flags_even[] = {
3620 &hf_oran_mc_scale_re_mask_re1_even,
3621 &hf_oran_mc_scale_re_mask_re2_even,
3622 &hf_oran_mc_scale_re_mask_re3_even,
3623 &hf_oran_mc_scale_re_mask_re4_even,
3624 &hf_oran_mc_scale_re_mask_re5_even,
3625 &hf_oran_mc_scale_re_mask_re6_even,
3626 &hf_oran_mc_scale_re_mask_re7_even,
3627 &hf_oran_mc_scale_re_mask_re8_even,
3628 &hf_oran_mc_scale_re_mask_re9_even,
3629 &hf_oran_mc_scale_re_mask_re10_even,
3630 &hf_oran_mc_scale_re_mask_re11_even,
3631 &hf_oran_mc_scale_re_mask_re12_even,
3632 NULL((void*)0)
3633 };
3634
3635 /* RE Mask (12 bits) */
3636 proto_tree_add_bitmask_ret_uint64(set_tree, tvb, bit_offset / 8,
3637 (n % 2) ? hf_oran_mc_scale_re_mask_even : hf_oran_mc_scale_re_mask,
3638 ett_oran_mc_scale_remask,
3639 (n % 2) ? remask_flags_even : remask_flags, ENC_BIG_ENDIAN0x00000000, &mcScaleReMask);
3640 bit_offset += 12;
3641
3642 /* csf (1 bit) */
3643 bit_offset = dissect_csf(set_tree, tvb, bit_offset, ci_iq_width, &csf);
3644 /* mcScaleOffset (15 bits) */
3645 proto_item *ti = proto_tree_add_bits_ret_val(set_tree, hf_oran_mc_scale_offset, tvb, bit_offset, 15, &mcScaleOffset, ENC_BIG_ENDIAN0x00000000);
3646 uint16_t exponent = (mcScaleOffset >> 11) & 0x000f; /* m.s. 4 bits */
3647 uint16_t mantissa = mcScaleOffset & 0x07ff; /* l.s. 11 bits */
3648 float mcScaleOffset_value = ((float)mantissa/(1<<11)) * ((float)1.0 / (1 << exponent));
3649 proto_item_append_text(ti, " (%f)", mcScaleOffset_value);
3650 bit_offset += 15;
3651
3652 section_mod_compr_config_t* sect_config = get_mod_compr_section_to_write(state, sectionId);
3653
3654 /* Record this config */
3655 if (sect_config && sect_config->num_configs < MAX_MOD_COMPR_CONFIGS12) {
3656 unsigned i = sect_config->num_configs;
3657 sect_config->configs[i].mod_compr_re_mask = (uint16_t)mcScaleReMask;
3658 sect_config->configs[i].mod_compr_csf = csf;
3659 sect_config->configs[i].mod_compr_scaler = mcScaleOffset_value;
3660 sect_config->num_configs++;
3661 }
3662
3663 /* Summary */
3664 proto_item_set_len(set_ti, (bit_offset+7)/8 - set_start_offset);
3665 proto_item_append_text(set_ti, " (mcScaleReMask=0x%03x csf=%5s mcScaleOffset=%f)",
3666 (unsigned)mcScaleReMask, tfs_get_true_false(csf)tfs_get_string(csf, ((void*)0)), mcScaleOffset_value);
3667 }
3668
3669 proto_item_append_text(extension_ti, " (%u sets)", sets);
3670
3671 /* Reserved (variable-length) */
3672 if (reserved_bits) {
3673 proto_tree_add_bits_item(extension_tree, hf_oran_reserved, tvb, bit_offset, reserved_bits, ENC_BIG_ENDIAN0x00000000);
3674 bit_offset += reserved_bits;
3675 }
3676
3677 offset = bit_offset/8;
3678 break;
3679 }
3680
3681 case 6: /* SE 6: Non-contiguous PRB allocation in time and frequency domain */
3682 {
3683 /* numSymbol not used in this case */
3684 if (numsymbol_ti && !numsymbol_ignored) {
3685 proto_item_append_text(numsymbol_ti, " (ignored)");
3686 numsymbol_ignored = true1;
3687 }
3688
3689 /* Will update ext6 recorded info */
3690 ext11_settings.ext6_set = true1;
3691
3692 /* repetition */
3693 proto_tree_add_bits_item(extension_tree, hf_oran_se6_repetition, tvb, offset*8, 1, ENC_BIG_ENDIAN0x00000000);
3694 /* rbgSize (PRBs per bit set in rbgMask) */
3695 uint32_t rbgSize;
3696 proto_item *rbg_size_ti;
3697 rbg_size_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_rbgSize, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &rbgSize);
3698 if (rbgSize == 0) {
3699 /* N.B. this is only true if "se6-rb-bit-supported" is set... */
3700 expert_add_info(pinfo, rbg_size_ti, &ei_oran_rbg_size_reserved);
3701 }
3702 /* rbgMask (28 bits) */
3703 uint32_t rbgMask;
3704 proto_item *rbgmask_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_rbgMask, tvb, offset, 4, ENC_BIG_ENDIAN0x00000000, &rbgMask);
3705 if (rbgSize == 0) {
3706 proto_item_append_text(rbgmask_ti, " (value ignored since rbgSize is 0)");
3707 }
3708
3709 /* TODO: if receiver detects non-zero bits outside the valid range, those shall be ignored. */
3710 offset += 4;
3711 /* priority */
3712 proto_tree_add_item(extension_tree, hf_oran_noncontig_priority, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3713 /* symbolMask */
3714 offset = dissect_symbolmask(tvb, extension_tree, offset, NULL((void*)0), NULL((void*)0));
3715
3716 /* Look up rbg_size enum -> value */
3717 switch (rbgSize) {
3718 case 0:
3719 /* N.B. reserved, but covered above with expert info (would remain 0) */
3720 break;
3721 case 1:
3722 ext11_settings.ext6_rbg_size = 1; break;
3723 case 2:
3724 ext11_settings.ext6_rbg_size = 2; break;
3725 case 3:
3726 ext11_settings.ext6_rbg_size = 3; break;
3727 case 4:
3728 ext11_settings.ext6_rbg_size = 4; break;
3729 case 5:
3730 ext11_settings.ext6_rbg_size = 6; break;
3731 case 6:
3732 ext11_settings.ext6_rbg_size = 8; break;
3733 case 7:
3734 ext11_settings.ext6_rbg_size = 16; break;
3735 /* N.B., encoded in 3 bits, so no other values are possible */
3736 }
3737
3738 /* Set to looked-up value */
3739 rbgSize = ext11_settings.ext6_rbg_size;
3740
3741 uint32_t lastRbgid = 0;
3742 if (rbgSize != 0) {
3743 /* The O-DU shall not use combinations of startPrbc, numPrbc and rbgSize leading to a value of lastRbgid larger than 27 */
3744 /* i.e., leftmost bit used should not need to go off left end of rbgMask! */
3745 lastRbgid = (uint32_t)ceil((numPrbc + (startPrbc % rbgSize)) / (float)rbgSize) - 1;
3746 if (lastRbgid > 27) {
3747 expert_add_info_format(pinfo, rbg_size_ti, &ei_oran_lastRbdid_out_of_range,
3748 "SE6: rbgSize (%u) not compatible with startPrbc(%u) and numPrbc(%u)",
3749 rbgSize, startPrbc, numPrbc);
3750 break;
3751 }
3752 }
3753
3754 /* Record (and count) which bits are set in rbgMask */
3755 bool_Bool first_seen = false0;
3756 unsigned first_seen_pos=0, last_seen_pos=0;
3757 for (unsigned n=0; n < 28 && ext11_settings.ext6_num_bits_set < 28; n++) {
3758 if ((rbgMask >> n) & 0x01) {
3759 ext11_settings.ext6_bits_set[ext11_settings.ext6_num_bits_set++] = n;
3760 if (!first_seen) {
3761 first_seen = true1;
3762 first_seen_pos = n;
3763 }
3764 last_seen_pos = n;
3765 }
3766 }
3767
3768 /* Show how many bits were set in rbgMask */
3769 proto_item_append_text(rbgmask_ti, " (%u bits set)", ext11_settings.ext6_num_bits_set);
3770 /* Also, that is the range of bits */
3771 if (first_seen) {
3772 proto_item_append_text(rbgmask_ti, " (%u bits spread)", last_seen_pos-first_seen_pos+1);
3773
3774 /* Complain if last set bit is beyond lastRbgid */
3775 if (last_seen_pos > lastRbgid) {
3776 expert_add_info_format(pinfo, rbgmask_ti, &ei_oran_rbgMask_beyond_last_rbdid,
3777 "SE6: rbgMask (0x%07x) has bit %u set, but lastRbgId is %u",
3778 rbgMask, last_seen_pos, lastRbgid);
3779 }
3780 }
3781
3782 /* Also update prbs_for_st10_type5[] */
3783 if (sectionType == 10 && rbgSize != 0) {
3784 /* Unset all entries */
3785 memset(&prbs_for_st10_type5, 0, sizeof(prbs_for_st10_type5));
3786
3787 /* Work out which PRB first bit corresponds to */
3788 unsigned firstPrbStart = (startPrbc/rbgSize) * rbgSize;
3789
3790 /* Add PRBs corresponding to each bit set */
3791 for (unsigned n=0; n < 28 ; n++) {
3792 if ((rbgMask >> n) & 0x01) {
3793 /* Lazy way to clip any values that lie outside of range for section */
3794 for (unsigned p=0; p < rbgSize; p++) {
3795 unsigned start = firstPrbStart + (n*rbgSize);
3796 if ((start+p < MAX_PRBS273) && (start+p >= startPrbc) && (start+p <= startPrbc+numPrbc-1)) {
3797 prbs_for_st10_type5[start+p] = true1;
3798 }
3799 }
3800 }
3801 }
3802 }
3803
3804 break;
3805 }
3806
3807 case 7: /* SE 7: eAxC mask */
3808 /* Allow ST0 to address multiple eAxC_ID values for transmission blanking */
3809 proto_tree_add_item(extension_tree, hf_oran_eAxC_mask, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
3810 offset += 2;
3811 break;
3812
3813 case 8: /* SE 8: Regularization factor */
3814 proto_tree_add_item(extension_tree, hf_oran_regularizationFactor, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
3815 offset += 2;
3816 break;
3817
3818 case 9: /* SE 9: Dynamic Spectrum Sharing parameters */
3819 proto_tree_add_item(extension_tree, hf_oran_technology, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3820 offset += 1;
3821 add_reserved_field(extension_tree, hf_oran_reserved_8bits, tvb, offset, 1);
3822 offset += 1;
3823 break;
3824
3825 case 10: /* SE 10: Group configuration of multiple ports */
3826 {
3827 seen_se10 = true1;
3828
3829 /* beamGroupType */
3830 uint32_t beam_group_type = 0;
3831 proto_item *bgt_ti;
3832 bgt_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_beamGroupType,
3833 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &beam_group_type);
3834 proto_item_append_text(extension_ti, " (%s)", val_to_str_const(beam_group_type, beam_group_type_vals, "Unknown"));
3835
3836 /* numPortc */
3837 proto_tree_add_item_ret_uint(extension_tree, hf_oran_numPortc,
3838 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &numPortc);
3839 offset++;
3840
3841 /* Will append all beamId values to extension_ti, regardless of beamGroupType */
3842 unsigned n;
3843
3844 switch (beam_group_type) {
3845 case 0x0: /* common beam */
3846 case 0x1: /* beam matrix indication */
3847 /* Reserved byte */
3848 add_reserved_field(extension_tree, hf_oran_reserved_8bits, tvb, offset, 1);
3849 offset++;
3850
3851 /* Explain how entries are allocated */
3852 if (beam_group_type == 0x0) {
3853 proto_item_append_text(extension_ti, " (all %u ueid/Beam entries are %u)", numPortc, ueId);
3854 }
3855 else {
3856 /* 'numPortc' consecutive BeamIds from section header */
3857 proto_item_append_text(extension_ti, " (ueId/beam entries are %u -> %u)", ueId, ueId+numPortc);
3858 }
3859
3860 if (sectionType == 5) {
3861 /* These types are not allowed */
3862 expert_add_info_format(pinfo, bgt_ti, &ei_oran_se10_not_allowed,
3863 "SE10: beamGroupType %u is not allowed for section type 5", beam_group_type);
3864 }
3865 break;
3866
3867 case 0x2: /* beam vector listing */
3868 {
3869 proto_item_append_text(extension_ti, " [ ");
3870
3871 /* Beam listing vector case */
3872 /* Work out how many port beam entries there is room for */
3873 /* Using numPortC as visible in issue 18116 */
3874 for (n=0; n < numPortc; n++) {
3875 /* 1 reserved bit */
3876 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
3877
3878 /* port beam ID (or UEID) (15 bits) */
3879 uint32_t id;
3880 proto_item *beamid_or_ueid_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_beamId,
3881 tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &id);
3882 proto_item_append_text(beamid_or_ueid_ti, " port #%u beam ID (or UEId) %u", n, id);
3883 offset += 2;
3884
3885 if (id != 0x7fff) {
3886 if (number_of_ueids < MAX_UEIDS16) {
3887 ueids[number_of_ueids++] = id;
3888 }
3889 }
3890
3891 proto_item_append_text(extension_ti, "%u ", id);
3892 }
3893
3894 proto_item_append_text(extension_ti, "]");
3895 break;
3896 }
3897 case 0x3: /* beamId/ueId listing with associated port-list index */
3898 {
3899 proto_item_append_text(extension_ti, " [ ");
3900
3901 if (numPortc > 0) {
3902 /* first portListIndex is outside loop */
3903 uint32_t port_list_index;
3904 proto_item *pli_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_port_list_index, tvb,
3905 offset, 1, ENC_BIG_ENDIAN0x00000000, &port_list_index);
3906 if (port_list_index == 0) {
3907 /* Value 0 is reserved */
3908 expert_add_info(pinfo, pli_ti, &ei_oran_port_list_index_zero);
3909 }
3910 offset += 1;
3911
3912 for (n=0; n < numPortc-1; n++) {
3913 /* 1 reserved bit */
3914 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
3915
3916 /* port beam ID (or UEID) */
3917 uint32_t id;
3918 proto_item *beamid_or_ueid_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_beamId,
3919 tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &id);
3920 proto_item_append_text(beamid_or_ueid_ti, " port #%u beam ID (or UEId) %u", n, id);
3921 offset += 2;
3922
3923 if (id != 0x7fff) {
3924 if (number_of_ueids < MAX_UEIDS16) {
3925 ueids[number_of_ueids++] = id;
3926 }
3927 }
3928
3929 /* subsequent portListIndex */
3930 pli_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_port_list_index, tvb,
3931 offset, 1, ENC_BIG_ENDIAN0x00000000, &port_list_index);
3932 if (port_list_index == 0) {
3933 /* Value 0 is reserved */
3934 expert_add_info(pinfo, pli_ti, &ei_oran_port_list_index_zero);
3935 }
3936 offset += 1;
3937
3938 proto_item_append_text(extension_ti, "%u:%u ", port_list_index, id);
3939 }
3940 }
3941
3942 proto_item_append_text(extension_ti, "]");
3943 break;
3944 }
3945
3946
3947 default:
3948 /* Warning for unsupported/reserved value */
3949 expert_add_info(NULL((void*)0), bgt_ti, &ei_oran_se10_unknown_beamgrouptype);
3950 break;
3951 }
3952 break;
3953 }
3954
3955 case 11: /* SE 11: Flexible Weights Extension Type */
3956 {
3957 /* Hidden filter for bf */
3958 bf_ti = proto_tree_add_item(tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
3959 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
3960
3961 /* beamId in section header should be ignored. Guard against appending multiple times.. */
3962 if (section_beamId_ti && !section_beamId_ignored) {
3963 proto_item_append_text(section_beamId_ti, " (ignored)");
3964 section_beamId_ignored = true1;
3965 }
3966
3967 bool_Bool disableBFWs;
3968 uint32_t numBundPrb;
3969 bool_Bool rad;
3970
3971 /* disableBFWs */
3972 proto_tree_add_item_ret_boolean(extension_tree, hf_oran_disable_bfws,
3973 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &disableBFWs);
3974 if (disableBFWs) {
3975 proto_item_append_text(extension_ti, " (disableBFWs)");
3976 }
3977
3978 /* RAD */
3979 proto_tree_add_item_ret_boolean(extension_tree, hf_oran_rad,
3980 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &rad);
3981 /* bundleOffset (6 bits) */
3982 proto_tree_add_item(extension_tree, hf_oran_bundle_offset, tvb,
3983 offset, 1, ENC_BIG_ENDIAN0x00000000);
3984 offset++;
3985
3986 /* numBundPrb (number of prbs in each bundle) */
3987 proto_item *num_bund_prb_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_num_bund_prbs,
3988 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &numBundPrb);
3989 offset++;
3990 /* value zero is reserved.. */
3991 if (numBundPrb == 0) {
3992 expert_add_info(pinfo, num_bund_prb_ti, &ei_oran_reserved_numBundPrb);
3993 }
3994
3995 uint32_t num_bundles;
3996 bool_Bool orphaned_prbs = false0;
3997
3998 /* N.B. glibly assuming that Mu=1 */
3999 uint32_t symbol_count = (frameId*20 + slotId) * 14 + startSymbolId;
4000
4001 if (!disableBFWs) {
4002 /********************************************/
4003 /* Table 7.7.1.1-1 */
4004 /********************************************/
4005
4006 uint32_t bfwcomphdr_iq_width, bfwcomphdr_comp_meth;
4007 proto_item *comp_meth_ti = NULL((void*)0);
4008
4009 /* bfwCompHdr (2 subheaders - bfwIqWidth and bfwCompMeth)*/
4010 offset = dissect_bfwCompHdr(tvb, extension_tree, offset,
4011 &bfwcomphdr_iq_width, &bfwcomphdr_comp_meth, &comp_meth_ti);
4012
4013 /* Work out number of bundles, but take care not to divide by zero. */
4014 if (numBundPrb == 0) {
4015 break;
4016 }
4017
4018 /* Work out bundles! */
4019 ext11_work_out_bundles(startPrbc, numPrbc, numBundPrb, &ext11_settings);
4020 num_bundles = ext11_settings.num_bundles;
4021
4022 /* Add (complete) bundles */
4023 for (unsigned b=0; b < num_bundles; b++) {
4024 offset = dissect_bfw_bundle(tvb, extension_tree, pinfo, offset,
4025 comp_meth_ti, bfwcomphdr_comp_meth,
4026 NULL((void*)0) /* no ModCompr */,
4027 (ext11_settings.ext21_set) ?
4028 numPrbc :
4029 pref_num_bf_antennas,
4030 bfwcomphdr_iq_width,
4031 b, /* bundle number */
4032 ext11_settings.bundles[b].start,
4033 ext11_settings.bundles[b].end,
4034 ext11_settings.bundles[b].is_orphan,
4035 symbol_count,
4036 (link_planes_together && data_section) ? &data_section->details[index_to_use] : NULL((void*)0),
4037 tap_info);
4038 if (!offset) {
4039 break;
4040 }
4041 }
4042 if (num_bundles > 0) {
4043 /* Set flag from last bundle entry */
4044 orphaned_prbs = ext11_settings.bundles[num_bundles-1].is_orphan;
4045 }
4046 }
4047 else {
4048 /********************************************/
4049 /* Table 7.7.1.1-2 */
4050 /* No weights in this case */
4051 /********************************************/
4052
4053 /* Work out number of bundles, but take care not to divide by zero. */
4054 if (numBundPrb == 0) {
4055 break;
4056 }
4057
4058 ext11_work_out_bundles(startPrbc, numPrbc, numBundPrb, &ext11_settings);
4059 num_bundles = ext11_settings.num_bundles;
4060
4061 for (unsigned n=0; n < num_bundles; n++) {
4062 /* contInd */
4063 proto_tree_add_item(extension_tree, hf_oran_cont_ind,
4064 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4065 /* beamId */
4066 /* N.B., only added to tap_info if not 0 or ignored (after SEs seen) */
4067 uint32_t beam_id;
4068 proto_item *beamid_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_beam_id,
4069 tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &beam_id);
4070 if (!ext11_settings.bundles[n].is_orphan) {
4071 proto_item_append_text(beamid_ti, " (PRBs %3u-%3u) (Bundle %2u)",
4072 ext11_settings.bundles[n].start,
4073 ext11_settings.bundles[n].end,
4074 n);
4075 }
4076 else {
4077 orphaned_prbs = true1;
4078 proto_item_append_text(beamid_ti, " (PRBs %3u-%3u) (Orphaned PRBs)",
4079 ext11_settings.bundles[n].start,
4080 ext11_settings.bundles[n].end);
4081 }
4082 offset += 2;
4083
4084 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
4085 if (data_section) {
4086 /* Set beamId only for range of PRBs */
4087 for (unsigned prb = ext11_settings.bundles[n].start; prb <= ext11_settings.bundles[n].end; prb++) {
4088 if (prb < 273) {
4089 data_section->details[index_to_use].beamIds[prb] = beam_id;
4090 }
4091 }
4092 }
4093 }
4094
4095 /* Look for where BFWs were sent for this beamId */
4096 bfw_definition *definition;
4097
4098 wmem_tree_key_t key[3];
4099 key[0].length = 1;
4100 key[0].key = &pinfo->num;
4101 key[1].length = 1;
4102 key[1].key = &beam_id;
4103 key[2].length = 0;
4104 key[2].key = NULL((void*)0);
4105
4106 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
4107 /* Look up current result */
4108 definition = wmem_tree_lookup32(dl_beam_ids_defined, beam_id);
4109 if (definition != NULL((void*)0)) {
4110 /* Add to results table for this frame */
4111 wmem_tree_insert32_array(dl_beam_ids_results, key, definition);
4112 }
4113 }
4114 else {
4115 /* Look up from result table */
4116 definition = wmem_tree_lookup32_array(dl_beam_ids_results, key);
4117 }
4118
4119 /* Show link back to frame where/when beamId was defined */
4120 if (definition && definition->frame_defined != 0 && definition->frame_defined != pinfo->num) {
4121 proto_item *defined_ti = proto_tree_add_uint(extension_tree, hf_oran_bfws_frame_defined, tvb, offset, 0, definition->frame_defined);
4122 proto_item_set_generated(defined_ti);
4123 proto_item *since_ti = proto_tree_add_uint(extension_tree, hf_oran_bfws_symbols_since_defined, tvb, offset, 0,
4124 symbol_count - definition->symbol_when_defined);
4125 proto_item_set_generated(since_ti);
4126 }
4127 else {
4128 expert_add_info_format(NULL((void*)0), beamid_ti, &ei_oran_beamid_bfws_not_found,
4129 "ext11 for beamId %u and disableBFWs set, but can't find definition", beam_id);
4130 }
4131 }
4132
4133 }
4134
4135 /* Add summary to extension root */
4136 if (orphaned_prbs) {
4137 proto_item_append_text(extension_ti, " (%u full bundles + orphaned)", num_bundles-1);
4138 }
4139 else {
4140 proto_item_append_text(extension_ti, " (%u bundles)", num_bundles);
4141 }
4142 }
4143
4144 break;
4145
4146 case 12: /* SE 12: Non-Contiguous PRB Allocation with Frequency Ranges */
4147 {
4148 /* numSymbol not used in this case */
4149 if (numsymbol_ti && !numsymbol_ignored) {
4150 proto_item_append_text(numsymbol_ti, " (ignored)");
4151 numsymbol_ignored = true1;
4152 }
4153
4154 ext11_settings.ext12_set = true1;
4155
4156 /* priority */
4157 proto_tree_add_item(extension_tree, hf_oran_noncontig_priority, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4158
4159 /* symbolMask */
4160 offset = dissect_symbolmask(tvb, extension_tree, offset, NULL((void*)0), NULL((void*)0));
4161
4162 /* There are now 'R' pairs of (offStartPrb, numPrb) values. Fill extlen bytes with values. If last one is not set,
4163 should be populated with 0s. */
4164 uint32_t extlen_remaining_bytes = (extlen*4) - 4;
4165 uint8_t prb_index;
4166
4167 /* This is for ST10/ST11. First pair starts after frames signalled there */
4168 uint16_t st10_st11_offset = startPrbc + numPrbc;
4169
4170 for (prb_index = 1; extlen_remaining_bytes > 0; prb_index++)
4171 {
4172 /* Create a subtree for each pair */
4173 proto_item *pair_ti = proto_tree_add_string(extension_tree, hf_oran_frequency_range,
4174 tvb, offset, 2, "");
4175 proto_tree *pair_tree = proto_item_add_subtree(pair_ti, ett_oran_frequency_range);
4176
4177 /* offStartPrb */
4178 uint32_t off_start_prb;
4179 proto_tree_add_item_ret_uint(pair_tree, hf_oran_off_start_prb, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &off_start_prb);
4180 offset++;
4181
4182 /* numPrb */
4183 uint32_t num_prb;
4184 proto_tree_add_item_ret_uint(pair_tree, hf_oran_num_prb, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &num_prb);
4185 offset++;
4186
4187 extlen_remaining_bytes -= 2;
4188
4189 /* Last pair may be 0,0 if not used. Check for this */
4190 if ((extlen_remaining_bytes == 0) && (off_start_prb == 0) && (num_prb == 0)) {
4191 proto_item_append_text(pair_ti, " (not used)");
4192 }
4193 /* Add summary to pair root item, and configure details in ext11_settings */
4194 else {
4195 proto_item_append_text(pair_ti, "(%u) [%u : %u]",
4196 prb_index, off_start_prb, num_prb);
4197 proto_item_append_text(extension_ti, "[%u : %u]",
4198 off_start_prb, num_prb);
4199 if (ext11_settings.ext12_num_pairs < MAX_BFW_EXT12_PAIRS128) {
4200 ext11_settings.ext12_pairs[ext11_settings.ext12_num_pairs].off_start_prb = off_start_prb;
4201 ext11_settings.ext12_pairs[ext11_settings.ext12_num_pairs++].num_prb = num_prb;
4202 }
4203
4204 /* Also update PRBs to be covered for ST10 type 5 */
4205 /* Original range from section is added to.. */
4206 /* TODO: I don't think this is quite right.. */
4207 for (unsigned prb=st10_st11_offset+off_start_prb; prb < st10_st11_offset+off_start_prb+num_prb; prb++) {
4208 if (prb < MAX_PRBS273) {
4209 prbs_for_st10_type5[prb] = true1;
4210 }
4211 }
4212
4213 /* Any next pair will begin after this one */
4214 st10_st11_offset += (off_start_prb + num_prb);
4215 }
4216 }
4217 break;
4218 }
4219
4220 case 13: /* SE 13: PRB Allocation with Frequency Hopping */
4221 {
4222 /* Will update settings for ext11 */
4223 ext11_settings.ext13_set = true1;
4224
4225 uint32_t extlen_remaining_bytes = (extlen*4) - 2;
4226 uint8_t allocation_index;
4227
4228 unsigned prev_next_symbol_id = 0, prev_next_start_prbc = 0;
4229
4230 for (allocation_index = 1; extlen_remaining_bytes > 0; allocation_index++)
4231 {
4232 /* Subtree for allocation */
4233 proto_item *allocation_ti = proto_tree_add_string(extension_tree, hf_oran_prb_allocation,
4234 tvb, offset, 2, "");
4235 proto_tree *allocation_tree = proto_item_add_subtree(allocation_ti, ett_oran_prb_allocation);
4236
4237 /* Reserved (2 bits) */
4238 add_reserved_field(allocation_tree, hf_oran_reserved_2bits, tvb, offset, 1);
4239
4240 /* nextSymbolId (4 bits) */
4241 uint32_t next_symbol_id;
4242 proto_tree_add_item_ret_uint(allocation_tree, hf_oran_nextSymbolId, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &next_symbol_id);
4243
4244 /* nextStartPrbc (10 bits) */
4245 uint32_t next_start_prbc;
4246 proto_tree_add_item_ret_uint(allocation_tree, hf_oran_nextStartPrbc, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &next_start_prbc);
4247 offset += 2;
4248
4249 /* Add summary to allocation root item */
4250 proto_item_append_text(allocation_ti, "(%u) nextSymbolId=%3u, nextStartPrbc=%u",
4251 allocation_index, next_symbol_id, next_start_prbc);
4252
4253 /* Checking for duplicates (expected if e.g. had only 2 entries but extlen bytes still to fill */
4254 if ((allocation_index > 1) && (next_symbol_id == prev_next_symbol_id) && (next_start_prbc == prev_next_start_prbc)) {
4255 proto_item_append_text(allocation_ti, " (repeated - to fill up extlen)");
4256 }
4257 else {
4258 /* Add entry for configuring ext11. don't store out of range */
4259 if (ext11_settings.ext13_num_start_prbs < MAX_BFW_EXT13_ALLOCATIONS128) {
4260 ext11_settings.ext13_start_prbs[ext11_settings.ext13_num_start_prbs++] = next_start_prbc;
4261 }
4262 }
4263 prev_next_symbol_id = next_symbol_id;
4264 prev_next_start_prbc = next_start_prbc;
4265
4266 extlen_remaining_bytes -= 2;
4267 }
4268 break;
4269 }
4270
4271 case 14: /* SE 14: Nulling-layer Info. for ueId-based beamforming */
4272 /* Hidden filter for bf (DMRS BF) */
4273 bf_ti = proto_tree_add_item(tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
4274 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
4275
4276 if (!seen_se10) {
4277 proto_tree_add_item(extension_tree, hf_oran_nullLayerInd, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4278 offset += 1;
4279 add_reserved_field(extension_tree, hf_oran_reserved_8bits, tvb, offset, 1);
4280 offset += 1;
4281 }
4282 else {
4283 /* Loop over numPortc++1 (from SE 10) nullLayerInd fields */
4284 for (unsigned port=0; port < numPortc+1; port++) {
4285 proto_tree_add_item(extension_tree, hf_oran_nullLayerInd, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4286 offset += 1;
4287 }
4288 }
4289 break;
4290
4291 case 15: /* SE 15: Mixed-numerology Info. for ueId-based beamforming */
4292 {
4293 /* frameStructure */
4294 offset = dissect_frame_structure(extension_tree, tvb, offset,
4295 subframeId, slotId);
4296 /* freqOffset */
4297 proto_tree_add_item(extension_tree, hf_oran_freqOffset, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
4298 offset += 3;
4299 /* cpLength */
4300 proto_item *cplength_ti = proto_tree_add_item(extension_tree, hf_oran_cpLength, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4301 if (sectionType != 0 && sectionType != 3) {
4302 proto_item_append_text(cplength_ti, " (ignored - used only with ST0 and ST3)");
4303 }
4304 offset += 2;
4305 break;
4306 }
4307
4308 case 16: /* SE 16: Antenna mapping in UE channel information based UL beamforming */
4309 {
4310 /* Just filling available bytes with antMask entries.
4311 N.B., if SE 10 also used, could associate each antMask with (beamId or UEId) RX eAxC */
4312 uint32_t extlen_remaining_bytes = (extlen*4) - 2;
4313 unsigned num_ant_masks = extlen_remaining_bytes / 8;
4314 for (unsigned n=0; n < num_ant_masks; n++) {
4315 proto_item *ti = proto_tree_add_item(extension_tree, hf_oran_antMask, tvb, offset, 8, ENC_BIG_ENDIAN0x00000000);
4316 proto_item_append_text(ti, " (RX eAxC #%u)", n+1);
4317 offset += 8;
4318 }
4319 break;
4320 }
4321
4322 case 17: /* SE 17: Indication of user port group. Applies to ST5 + SE10 with group type 1 (beam matrix indication) */
4323 {
4324 uint32_t extlen_remaining_bytes = (extlen*4) - 2;
4325 uint32_t end_bit = (offset+extlen_remaining_bytes) * 8;
4326 uint32_t ueid_index = 1;
4327
4328 /* "the preceding Section Type and extension messages implicitly provide the number of scheduled users" */
4329 for (uint32_t bit_offset=offset*8; (bit_offset < end_bit) && (ueid_index <= number_of_ueids); bit_offset+=4, ueid_index++) {
4330 /* numUeId (Number of UE Ids per user) */
4331 proto_item *ti = proto_tree_add_bits_item(extension_tree, hf_oran_num_ueid, tvb, bit_offset, 4, ENC_BIG_ENDIAN0x00000000);
4332 /* TODO: show ueids[ueid_index] here too? */
4333 proto_item_append_text(ti, " (user #%u)", ueid_index);
4334 }
4335 break;
4336 }
4337
4338 case 18: /* SE 18: Uplink transmission management */
4339 /* transmissionWindowOffset */
4340 proto_tree_add_item(extension_tree, hf_oran_transmissionWindowOffset, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4341 offset += 2;
4342 /* reserved (2 bits) */
4343 add_reserved_field(extension_tree, hf_oran_reserved_2bits, tvb, offset, 1);
4344 /* transmissionWindowSize (14 bits) */
4345 proto_tree_add_item(extension_tree, hf_oran_transmissionWindowSize, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4346 offset += 2;
4347
4348 /* reserved (6 bits) */
4349 add_reserved_field(extension_tree, hf_oran_reserved_6bits, tvb, offset, 1);
4350 /* toT (2 bits) */
4351 proto_tree_add_item(extension_tree, hf_oran_toT, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4352 offset += 1;
4353 break;
4354
4355 case 19: /* SE 19: Compact beamforming information for multiple port */
4356 {
4357 /* beamId in section header should be ignored. Guard against appending multiple times.. */
4358 if (section_beamId_ti && !section_beamId_ignored) {
4359 proto_item_append_text(section_beamId_ti, " (ignored)");
4360 section_beamId_ignored = true1;
4361 }
4362
4363 /* numSymbol not used in this case */
4364 if (numsymbol_ti && !numsymbol_ignored) {
4365 proto_item_append_text(numsymbol_ti, " (ignored)");
4366 numsymbol_ignored = true1;
4367 }
4368
4369 /* disableBFWs */
4370 bool_Bool disableBFWs;
4371 proto_tree_add_item_ret_boolean(extension_tree, hf_oran_disable_bfws,
4372 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &disableBFWs);
4373 if (disableBFWs) {
4374 proto_item_append_text(extension_ti, " (disableBFWs)");
4375 }
4376 /* repetition (1 bit) */
4377 uint64_t repetition;
4378 proto_tree_add_bits_ret_val(extension_tree, hf_oran_se19_repetition, tvb, (offset*8)+1, 1, &repetition, ENC_BIG_ENDIAN0x00000000);
4379 /* numPortc (6 bits) */
4380 proto_tree_add_item_ret_uint(extension_tree, hf_oran_numPortc,
4381 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &numPortc);
4382 offset++;
4383
4384 /* priority (2 bits) */
4385 proto_tree_add_item(extension_tree, hf_oran_noncontig_priority, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4386 /* symbolMask (14 bits) */
4387 offset = dissect_symbolmask(tvb, extension_tree, offset, NULL((void*)0), NULL((void*)0));
4388
4389 uint32_t bfwcomphdr_iq_width, bfwcomphdr_comp_meth;
4390 proto_item *comp_meth_ti = NULL((void*)0);
4391
4392 if (!repetition) {
4393
4394 if (!disableBFWs) {
4395 /* bfwCompHdr */
4396 offset = dissect_bfwCompHdr(tvb, extension_tree, offset,
4397 &bfwcomphdr_iq_width, &bfwcomphdr_comp_meth, &comp_meth_ti);
4398 }
4399
4400 /* Add entries for each port */
4401 for (unsigned port=0; port < numPortc; port++) {
4402
4403 /* Create subtree for port entry*/
4404 int port_start_offset = offset;
4405 proto_item *port_ti = proto_tree_add_string_format(extension_tree, hf_oran_ext19_port,
4406 tvb, offset, 0,
4407 "", "Port %u: ", port);
4408 proto_tree *port_tree = proto_item_add_subtree(port_ti, ett_oran_ext19_port);
4409
4410 /* Reserved (4 bits) */
4411 add_reserved_field(port_tree, hf_oran_reserved_4bits, tvb, offset, 1);
4412 /* portReMask (12 bits) */
4413 proto_tree_add_item(port_tree, hf_oran_portReMask, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4414 offset += 2;
4415
4416 /* Reserved (2 bits) */
4417 add_reserved_field(port_tree, hf_oran_reserved_2bits, tvb, offset, 1);
4418 /* portSymbolMask (14 bits) */
4419 proto_tree_add_item(port_tree, hf_oran_portSymbolMask, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4420 offset += 2;
4421
4422 /* Reserved (1 bit) */
4423 add_reserved_field(port_tree, hf_oran_reserved_1bit, tvb, offset, 1);
4424 /* beamID (15 bits) */
4425 uint16_t beamId;
4426 proto_tree_add_item_ret_uint16(port_tree, hf_oran_beamId, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &beamId);
4427 proto_item_append_text(port_ti, " (beamId=%u)", beamId);
4428 offset += 2;
4429
4430 /* No weights present */
4431 if (!disableBFWs) {
4432 /*******************************************************************/
4433 /* Table 7.7.19.1-1 (there is no part -2 for disableBFWs case...), */
4434 /* but for SE 11, bfwCompParam was only present for !disableBFWs */
4435 /*******************************************************************/
4436
4437 /* bfwCompParam */
4438 bool_Bool compression_method_supported = false0;
4439 uint32_t exponent = 0;
4440 unsigned num_trx_entries = 0;
4441 uint16_t *trx;
4442 offset = dissect_bfwCompParam(tvb, port_tree, pinfo, offset, comp_meth_ti,
4443 &bfwcomphdr_comp_meth, &exponent, &compression_method_supported,
4444 &num_trx_entries, &trx);
4445
4446 int bit_offset = offset*8;
4447 int bfw_offset;
4448
4449 /* Add weights for each TRX */
4450 unsigned trx_to_add = (num_trx_entries==0) ? pref_num_bf_antennas : num_trx_entries;
4451 for (unsigned b=0; b < trx_to_add; b++) {
4452
4453 uint16_t trx_index = (num_trx_entries) ? trx[b] : b+1;
4454
4455 /* Create BFW subtree */
4456 bfw_offset = bit_offset / 8;
4457 uint8_t bfw_extent = ((bit_offset + (bfwcomphdr_iq_width*2)) / 8) - bfw_offset;
4458 proto_item *bfw_ti = proto_tree_add_string_format(port_tree, hf_oran_bfw,
4459 tvb, bfw_offset, bfw_extent,
4460 "", "TRX %u: (", trx_index);
4461 proto_tree *bfw_tree = proto_item_add_subtree(bfw_ti, ett_oran_bfw);
4462
4463 /* I */
4464 uint32_t bits = tvb_get_bits32(tvb, bit_offset, bfwcomphdr_iq_width, ENC_BIG_ENDIAN0x00000000);
4465 float value = decompress_value(bits, bfwcomphdr_comp_meth, bfwcomphdr_iq_width, exponent, NULL((void*)0) /* no ModCompr */, 0 /* RE */);
4466 /* Add to tree. */
4467 proto_tree_add_float_format_value(bfw_tree, hf_oran_bfw_i, tvb, bit_offset/8,
4468 (bfwcomphdr_iq_width+7)/8, value, "#%u=%f", b, value);
4469 bit_offset += bfwcomphdr_iq_width;
4470 proto_item_append_text(bfw_ti, "I%u=%f ", b, value);
4471
4472 /* Q */
4473 bits = tvb_get_bits32(tvb, bit_offset, bfwcomphdr_iq_width, ENC_BIG_ENDIAN0x00000000);
4474 value = decompress_value(bits, bfwcomphdr_comp_meth, bfwcomphdr_iq_width, exponent, NULL((void*)0) /* no ModCompr */, 0 /* RE */);
4475 /* Add to tree. */
4476 proto_tree_add_float_format_value(bfw_tree, hf_oran_bfw_q, tvb, bit_offset/8,
4477 (bfwcomphdr_iq_width+7)/8, value, "#%u=%f", b, value);
4478 bit_offset += bfwcomphdr_iq_width;
4479 proto_item_append_text(bfw_ti, "Q%u=%f)", b, value);
4480 }
4481
4482 offset = (bit_offset+7)/8;
4483 }
4484 else {
4485 /* No weights... */
4486 }
4487
4488 /* Set length of this port entry */
4489 proto_item_set_len(port_ti, offset-port_start_offset);
4490 }
4491 }
4492 break;
4493 }
4494
4495 case 20: /* SE 20: Puncturing extension */
4496 {
4497 /* numPuncPatterns */
4498 uint32_t numPuncPatterns;
4499 proto_tree_add_item_ret_uint(extension_tree, hf_oran_numPuncPatterns, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &numPuncPatterns);
4500 offset += 1;
4501
4502 /* Add each puncturing pattern */
4503 for (uint32_t n=0; n < numPuncPatterns; n++) {
4504 unsigned pattern_start_offset = offset;
4505
4506 /* Subtree for this puncturing pattern */
4507 proto_item *pattern_ti = proto_tree_add_string_format(extension_tree, hf_oran_puncPattern,
4508 tvb, offset, 0,
4509 "", "Puncturing Pattern: %u/%u", n+1, numPuncPatterns);
4510 proto_tree *pattern_tree = proto_item_add_subtree(pattern_ti, ett_oran_punc_pattern);
4511
4512 /* SymbolMask (14 bits) */
4513 proto_tree_add_item(pattern_tree, hf_oran_symbolMask_ext20, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4514 offset += 1;
4515
4516 uint32_t startPuncPrb, numPuncPrb;
4517
4518 /* startPuncPrb (10 bits) */
4519 proto_tree_add_item_ret_uint(pattern_tree, hf_oran_startPuncPrb, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &startPuncPrb);
4520 offset += 2;
4521 /* numPuncPrb (8 bits) */
4522 proto_tree_add_item_ret_uint(pattern_tree, hf_oran_numPuncPrb, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &numPuncPrb);
4523 offset += 1;
4524
4525 proto_item_append_text(pattern_ti, " [%u->%u]", startPuncPrb, startPuncPrb+numPuncPrb-1);
4526
4527 /* Make a hole in range of PRBs to report */
4528 for (unsigned p=startPuncPrb; p < startPuncPrb+numPuncPrb; p++) {
4529 if (p < MAX_PRBS273) {
4530 prbs_for_st10_type5[p] = false0;
4531 }
4532 }
4533
4534 /* puncReMask (12 bits) */
4535 proto_tree_add_item(pattern_tree, hf_oran_puncReMask, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4536 offset += 1;
4537 /* rb (1 bit) */
4538 proto_item *rb_ti = proto_tree_add_item(pattern_tree, hf_oran_rb, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4539 /* reserved (1 bit) */
4540 add_reserved_field(pattern_tree, hf_oran_reserved_bit5, tvb, offset, 1);
4541 /* multiSDScope (1 bit) */
4542 proto_tree_add_item(pattern_tree, hf_oran_multiSDScope, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4543 /* rbgIncl (1 bit) */
4544 bool_Bool rbgIncl;
4545 proto_tree_add_item_ret_boolean(pattern_tree, hf_oran_RbgIncl, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &rbgIncl);
4546 offset += 1;
4547
4548 if (rbgIncl) {
4549 /* reserved (1 bit) */
4550 add_reserved_field(pattern_tree, hf_oran_reserved_1bit, tvb, offset, 1);
4551 /* rbgSize(3 bits) */
4552 proto_tree_add_item(pattern_tree, hf_oran_rbgSize, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4553 /* rbgMask (28 bits) */
4554 proto_tree_add_item(pattern_tree, hf_oran_rbgMask, tvb, offset, 4, ENC_BIG_ENDIAN0x00000000);
4555 offset += 4;
4556
4557 proto_item_append_text(rb_ti, " (ignored)");
4558 }
4559
4560 proto_item_set_len(pattern_ti, offset-pattern_start_offset);
4561 }
4562
4563 break;
4564 }
4565 case 21: /* SE 21: Variable PRB group size for channel information */
4566 {
4567 /* ciPrbGroupSize */
4568 uint32_t ci_prb_group_size;
4569 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);
4570 offset += 1;
4571
4572 switch (ci_prb_group_size) {
4573 case 0:
4574 case 1:
4575 case 255:
4576 /* Reserved value */
4577 expert_add_info_format(pinfo, prb_group_size_ti, &ei_oran_ci_prb_group_size_reserved,
4578 "SE 11 ciPrbGroupSize is reserved value %u - must be 2-254",
4579 ci_prb_group_size);
4580 break;
4581 default:
4582 /* This value affects how SE 11 is interpreted */
4583 ext11_settings.ext21_set = true1;
4584 ext11_settings.ext21_ci_prb_group_size = ci_prb_group_size;
4585
4586 if (numPrbc == 0) {
4587 expert_add_info(pinfo, numprbc_ti, &ei_oran_numprbc_ext21_zero);
4588 }
4589 break;
4590 }
4591
4592 /* reserved (6 bits) */
4593 add_reserved_field(extension_tree, hf_oran_reserved_6bits, tvb, offset, 1);
4594
4595 /* prgSize (2 bits). Interpretation depends upon section type (5 or 6), but also mplane parameters? */
4596 if (sectionType == SEC_C_UE_SCHED) { /* Section Type 5 */
4597 proto_tree_add_item(extension_tree, hf_oran_prg_size_st5, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4598 }
4599 else if (sectionType == SEC_C_CH_INFO) { /* Section Type 6 */
4600 proto_tree_add_item(extension_tree, hf_oran_prg_size_st6, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4601 }
4602 offset += 1;
4603 break;
4604 }
4605
4606 case 22: /* SE 22: ACK/NACK request */
4607 {
4608 uint32_t ack_nack_req_id;
4609 proto_tree_add_item_ret_uint(extension_tree, hf_oran_ack_nack_req_id, tvb, offset, 2,
4610 ENC_BIG_ENDIAN0x00000000, &ack_nack_req_id);
4611 offset += 2;
4612
4613 if (state) {
4614 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
4615 /* Add this request into conversation state on first pass */
4616 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)))
;
4617 request_details->request_frame_number = pinfo->num;
4618 request_details->request_frame_time = pinfo->abs_ts;
4619 request_details->requestType = SE22;
4620 /* Insert into flow's tree */
4621 wmem_tree_insert32(state->ack_nack_requests, ack_nack_req_id, request_details);
4622 }
4623 else {
4624 /* Try to link forward to ST8 response */
4625 ack_nack_request_t *response = wmem_tree_lookup32(state->ack_nack_requests,
4626 ack_nack_req_id);
4627 if (response) {
4628 show_link_to_acknack_response(extension_tree, tvb, pinfo, response);
4629 }
4630 }
4631 }
4632 break;
4633 }
4634
4635 case 23: /* SE 23: Arbitrary symbol pattern modulation compression parameters */
4636 {
4637 /* Green common header */
4638
4639 /* numSymPrbPattern (4 bits) */
4640 uint32_t num_sym_prb_pattern;
4641 proto_tree_add_item_ret_uint(extension_tree, hf_oran_num_sym_prb_pattern, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &num_sym_prb_pattern);
4642 /* reserved (3 bits) */
4643 add_reserved_field(extension_tree, hf_oran_reserved_bits456, tvb, offset, 1);
4644 /* prbMode (1 bit) */
4645 bool_Bool prb_mode;
4646 proto_tree_add_item_ret_boolean(extension_tree, hf_oran_prb_mode, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &prb_mode);
4647 offset += 1;
4648
4649 /* reserved (8 bits) */
4650 add_reserved_field(extension_tree, hf_oran_reserved_8bits, tvb, offset, 1);
4651 offset += 1;
4652
4653 /* Dissect each SymPrbPattern */
4654 for (uint32_t n=0; n < num_sym_prb_pattern; n++) {
4655
4656 /* Subtree */
4657 proto_item *pattern_ti = proto_tree_add_string_format(extension_tree, hf_oran_sym_prb_pattern,
4658 tvb, offset, 1, "",
4659 prb_mode ? "PRB-BLOCK" : "PRB-MASK");
4660 proto_tree *pattern_tree = proto_item_add_subtree(pattern_ti, ett_oran_sym_prb_pattern);
4661
4662
4663 /* Orange part */
4664
4665 /* Reserved (2 bits) */
4666 add_reserved_field(pattern_tree, hf_oran_reserved_2bits, tvb, offset, 1);
4667 /* symMask (14 bits) */
4668 proto_tree_add_item(pattern_tree, hf_oran_sym_mask, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4669 offset += 2;
4670 /* numMcScaleOffset (4 bits) */
4671 uint32_t numMcScaleOffset;
4672 proto_tree_add_item_ret_uint(pattern_tree, hf_oran_num_mc_scale_offset, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &numMcScaleOffset);
4673
4674 if (!prb_mode) { /* PRB-MASK */
4675 /* prbPattern (4 bits) */
4676 proto_tree_add_item(pattern_tree, hf_oran_prb_pattern, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4677 offset += 1;
4678 /* reserved (8 bits) */
4679 add_reserved_field(pattern_tree, hf_oran_reserved_8bits, tvb, offset, 1);
4680 offset += 1;
4681 /* reserved (4 bits) */
4682 add_reserved_field(pattern_tree, hf_oran_reserved_4bits, tvb, offset, 1);
4683 }
4684 else { /* PRB-BLOCK */
4685 /* prbBlkOffset (8 bits) */
4686 proto_tree_add_item(pattern_tree, hf_oran_prb_blk_offset, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4687 offset += 1;
4688 /* prbBlkSize (8 bits) */
4689 proto_tree_add_item(pattern_tree, hf_oran_prb_blk_size, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4690 offset += 1;
4691 }
4692
4693 for (unsigned c=0; c < numMcScaleOffset; c++) {
4694 if (c > 0) {
4695 /* reserved (4 bits) */
4696 add_reserved_field(pattern_tree, hf_oran_reserved_4bits, tvb, offset, 1);
4697 }
4698
4699 static int * const remask_flags_even[] = {
4700 &hf_oran_mc_scale_re_mask_re1_even,
4701 &hf_oran_mc_scale_re_mask_re2_even,
4702 &hf_oran_mc_scale_re_mask_re3_even,
4703 &hf_oran_mc_scale_re_mask_re4_even,
4704 &hf_oran_mc_scale_re_mask_re5_even,
4705 &hf_oran_mc_scale_re_mask_re6_even,
4706 &hf_oran_mc_scale_re_mask_re7_even,
4707 &hf_oran_mc_scale_re_mask_re8_even,
4708 &hf_oran_mc_scale_re_mask_re9_even,
4709 &hf_oran_mc_scale_re_mask_re10_even,
4710 &hf_oran_mc_scale_re_mask_re11_even,
4711 &hf_oran_mc_scale_re_mask_re12_even,
4712 NULL((void*)0)
4713 };
4714
4715 /* mcScaleReMask (12 bits). Defines which REs the following csf and mcScaleOffset apply to */
4716 uint64_t mcScaleReMask, mcScaleOffset;
4717 proto_tree_add_bitmask_ret_uint64(pattern_tree, tvb, offset,
4718 hf_oran_mc_scale_re_mask_even,
4719 ett_oran_mc_scale_remask,
4720 remask_flags_even, ENC_BIG_ENDIAN0x00000000, &mcScaleReMask);
4721 offset += 2;
4722
4723 /* csf (1 bit) */
4724 bool_Bool csf;
4725 dissect_csf(pattern_tree, tvb, offset*8, ci_iq_width, &csf);
4726 /* mcScaleOffset (15 bits) */
4727 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);
4728 uint16_t exponent = (mcScaleOffset >> 11) & 0x000f; /* m.s. 4 bits */
4729 uint16_t mantissa = mcScaleOffset & 0x07ff; /* l.s. 11 bits */
4730 float mcScaleOffset_value = ((float)mantissa/(1<<11)) * ((float)1.0 / (1 << exponent));
4731 proto_item_append_text(ti, " (%f)", mcScaleOffset_value);
4732
4733 offset += 2;
4734
4735 /* Record this config. */
4736 /* TODO: at some point, will also want to store/use PRB + symbol filters */
4737 section_mod_compr_config_t* sect_config = get_mod_compr_section_to_write(state, sectionId);
4738
4739 if (sect_config && sect_config->num_configs < MAX_MOD_COMPR_CONFIGS12) {
4740 unsigned i = sect_config->num_configs;
4741 sect_config->configs[i].mod_compr_re_mask = (uint16_t)mcScaleReMask;
4742 sect_config->configs[i].mod_compr_csf = csf;
4743 sect_config->configs[i].mod_compr_scaler = mcScaleOffset_value;
4744 sect_config->num_configs++;
4745 }
4746 }
4747
4748 proto_item_set_end(pattern_ti, tvb, offset);
4749 }
4750 break;
4751 }
4752
4753 case 24: /* SE 24: PUSCH DMRS configuration */
4754 {
4755 /* Hidden filter for bf (DMRS BF) */
4756 bf_ti = proto_tree_add_item(tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
4757 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
4758
4759 /* alpnPerSym (1 bit) */
4760 proto_tree_add_item(extension_tree, hf_oran_alpn_per_sym, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4761 /* antDmrsSnr (1 bit) */
4762 proto_tree_add_item(extension_tree, hf_oran_ant_dmrs_snr, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4763 /* reserved (1 bit) */
4764 add_reserved_field(extension_tree, hf_oran_reserved_bit2, tvb, offset, 1);
4765 /* userGroupSize (5 bits) */
4766 uint32_t user_group_size;
4767 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);
4768 if (user_group_size == 0) {
4769 proto_item_append_text(ugs_ti, " (not used)");
4770 }
4771 else if (user_group_size > 12) {
4772 proto_item_append_text(ugs_ti, " (reserved)");
4773 }
4774 offset += 1;
4775 /* userGroupId (8 bits)*/
4776 uint32_t user_group_id;
4777 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);
4778 if (user_group_id == 0) {
4779 /* TODO: Value 0 can happen in several cases, described in 7.7.24.7.. */
4780 }
4781 if (user_group_id == 255) {
4782 /* Value 255 is reserved */
4783 expert_add_info(pinfo, ugi_ti, &ei_oran_user_group_id_reserved_value);
4784 }
4785 offset += 1;
4786
4787 bool_Bool seen_value_to_inherit = false0;
4788 bool_Bool inherited_config_has_transform_precoding = false0;
4789 int dmrs_configs_seen = 0;
4790
4791 /* Dissect each entry until reach number of configured ueIds (or run out of extlen bytes..) */
4792 uint32_t ueid_index = 0;
4793 while ((offset < (extension_start_offset + extlen*4)) && (ueid_index < number_of_ueids)) {
4794 dmrs_configs_seen++;
4795
4796 /* Subtree */
4797 proto_item *entry_ti = proto_tree_add_string_format(extension_tree, hf_oran_dmrs_entry,
4798 tvb, offset, 0, "",
4799 "Entry");
4800 proto_tree *entry_tree = proto_item_add_subtree(entry_ti, ett_oran_dmrs_entry);
4801
4802 /* entryType (3 bits) */
4803 uint32_t entry_type;
4804 proto_item *entry_type_ti;
4805 entry_type_ti = proto_tree_add_item_ret_uint(entry_tree, hf_oran_entry_type, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &entry_type);
4806 if (entry_type > 3) {
4807 proto_item_append_text(entry_type_ti, " (reserved)");
4808 }
4809
4810 /* dmrsPortNumber (5 bits). Values 0-11 allowed */
4811 unsigned int dmrs_port_number;
4812 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);
4813 if (dmrs_port_number > 11) {
4814 proto_item_append_text(dpn_ti, " (12-31 are reserved)");
4815 }
4816 offset += 1;
4817
4818 /* What follows depends upon entryType */
4819 switch (entry_type) {
4820 case 0: /* dmrsPortNumber config same as previous, ueId ueIdReset=0 */
4821 case 1: /* dmrsPortNumber config same as previous, ueId ueIdReset=1 */
4822 /* No further fields for these */
4823 /* Error here if no previous values to inherit!! */
4824 if (!seen_value_to_inherit) {
4825 expert_add_info_format(pinfo, entry_type_ti, &ei_oran_se24_nothing_to_inherit,
4826 "SE24: have seen entry type %u, but no previous config (type 2 or 3) to inherit config from", entry_type);
4827
4828 }
4829 /* TODO: would be useful to repeat whole inherited config here? */
4830 break;
4831
4832 case 2: /* transform precoding disabled */
4833 case 3: /* transform precoding enabled */
4834 {
4835 /* Type 2/3 are very similar.. */
4836
4837 /* ueIdReset (1 bit) */
4838 proto_tree_add_item(entry_tree, hf_oran_ueid_reset, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4839 /* posMeas (1 bit) */
4840 proto_tree_add_item(entry_tree, hf_oran_pos_meas, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4841
4842 /* dmrsSymbolMask (14 bits) */
4843 static int * const dmrs_symbol_mask_flags[] = {
4844 &hf_oran_dmrs_symbol_mask_s13,
4845 &hf_oran_dmrs_symbol_mask_s12,
4846 &hf_oran_dmrs_symbol_mask_s11,
4847 &hf_oran_dmrs_symbol_mask_s10,
4848 &hf_oran_dmrs_symbol_mask_s9,
4849 &hf_oran_dmrs_symbol_mask_s8,
4850 &hf_oran_dmrs_symbol_mask_s7,
4851 &hf_oran_dmrs_symbol_mask_s6,
4852 &hf_oran_dmrs_symbol_mask_s5,
4853 &hf_oran_dmrs_symbol_mask_s4,
4854 &hf_oran_dmrs_symbol_mask_s3,
4855 &hf_oran_dmrs_symbol_mask_s2,
4856 &hf_oran_dmrs_symbol_mask_s1,
4857 &hf_oran_dmrs_symbol_mask_s0,
4858 NULL((void*)0)
4859 };
4860 proto_tree_add_bitmask(entry_tree, tvb, offset,
4861 hf_oran_dmrs_symbol_mask, ett_oran_dmrs_symbol_mask, dmrs_symbol_mask_flags, ENC_BIG_ENDIAN0x00000000);
4862 offset += 2;
4863
4864 /* scrambling */
4865 proto_tree_add_item(entry_tree, hf_oran_scrambling, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4866 offset += 2;
4867
4868 /* nscid (1 bit) */
4869 proto_tree_add_item(entry_tree, hf_oran_nscid, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4870
4871 /* These 5 bits differ depending upon entry type */
4872 if (entry_type == 2) { /* type 2 */
4873 /* dType (1 bit) */
4874 proto_tree_add_item(entry_tree, hf_oran_dtype, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4875 /* cdmWithoutData (2 bits) */
4876 proto_tree_add_item(entry_tree, hf_oran_cmd_without_data, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4877 /* lambda (2 bits) */
4878 proto_tree_add_item(entry_tree, hf_oran_lambda, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4879 }
4880 else { /* type 3 */
4881 /* reserved (1 bit) */
4882 add_reserved_field(entry_tree, hf_oran_reserved_bit1, tvb, offset, 1);
4883 /* lowPaprType (2 bits) */
4884 proto_tree_add_item(entry_tree, hf_oran_low_papr_type, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4885 /* hoppingMode (2 bits) */
4886 proto_tree_add_item(entry_tree, hf_oran_hopping_mode, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4887 }
4888
4889 /* firstPrb (9 bits) */
4890 proto_tree_add_item(entry_tree, hf_oran_first_prb, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4891 offset += 1;
4892 /* lastPrb (9 bits) */
4893 proto_tree_add_item(entry_tree, hf_oran_last_prb, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4894 offset += 2;
4895 /* Reserved (16 bits) */
4896 add_reserved_field(entry_tree, hf_oran_reserved_16bits, tvb, offset, 2);
4897 offset += 2;
4898
4899 /* Could now see entry types 0 or 1 - they have these values to inherit */
4900 seen_value_to_inherit = true1;
4901 inherited_config_has_transform_precoding = (entry_type == 3);
4902 break;
4903 }
4904
4905 default:
4906 /* reserved - expert info */
4907 break;
4908 }
4909
4910 proto_item_append_text(entry_ti, " [UEId=%u] (dmrsPortNumber=%2u) (type %u - %s) ",
4911 ueids[ueid_index++], dmrs_port_number, entry_type, val_to_str_const(entry_type, entry_type_vals, "Unknown"));
4912 proto_item_set_end(entry_ti, tvb, offset);
4913
4914 if (entry_type <= 1) {
4915 proto_item_append_text(entry_ti, " [transform-precoding %s]",
4916 inherited_config_has_transform_precoding ? "enabled" : "disabled");
4917 }
4918 }
4919
4920 proto_item_append_text(extension_ti, " (%d DMRS configs seen)", dmrs_configs_seen);
4921 break;
4922 }
4923
4924 case 25: /* SE 25: Symbol reordering for DMRS-BF */
4925 /* Just dissect each available block of 7 bytes as the 14 symbols for a layer,
4926 where each layer could be one or apply to all layers. */
4927 {
4928 /* TODO: should only appear in one section of a message - check? */
4929 unsigned layer = 0;
4930 proto_item *layer_ti;
4931 while (offset+7 <= (extension_start_offset + extlen*4)) {
4932 /* Layer subtree */
4933 layer_ti = proto_tree_add_string_format(extension_tree, hf_oran_symbol_reordering_layer,
4934 tvb, offset, 7, "",
4935 "Layer");
4936 proto_tree *layer_tree = proto_item_add_subtree(layer_ti, ett_oran_symbol_reordering_layer);
4937
4938 /* All 14 symbols for a layer (or all layers) */
4939 for (unsigned s=0; s < 14; s++) {
4940 proto_item *sym_ti;
4941 /* txWinForOnAirSymbol */
4942 unsigned int tx_win_for_on_air_symbol;
4943 sym_ti = proto_tree_add_item_ret_uint(layer_tree,
4944 (s % 2) ? hf_oran_tx_win_for_on_air_symbol_r : hf_oran_tx_win_for_on_air_symbol_l,
4945 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &tx_win_for_on_air_symbol);
4946 if (tx_win_for_on_air_symbol == 0x0F) {
4947 /* Ordering not affected */
4948 proto_item_append_text(sym_ti, " (sym %u - no info)", s);
4949 }
4950 else {
4951 proto_item_append_text(sym_ti, " (sym %u)", s);
4952 }
4953 if (s % 2) {
4954 offset += 1;
4955 }
4956 }
4957
4958 proto_item_append_text(layer_ti, " (layer %u)", ++layer);
4959 proto_item_append_text(extension_ti, " (layer %u)", layer);
4960 }
4961 /* Set layer subtree label */
4962 if (layer == 1) {
4963 proto_item_append_text(layer_ti, " (all)");
4964 proto_item_append_text(extension_ti, " (all)");
4965 }
4966 if (layer == 0) {
4967 /* TODO: are no layers valid? What does it mean? */
4968 proto_item_append_text(extension_ti, " (none)");
4969 }
4970 break;
4971 }
4972
4973 case 26: /* SE 26: Frequency offset feedback */
4974 /* Reserved (8 bits) */
4975 add_reserved_field(extension_tree, hf_oran_reserved_8bits, tvb, offset, 1);
4976 offset += 1;
4977 /* Reserved (1 bit) */
4978 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
4979 /* numFoFb (7 bits) */
4980 unsigned num_fo_fb;
4981 proto_tree_add_item_ret_uint(extension_tree, hf_oran_num_fo_fb, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &num_fo_fb);
4982 offset += 1;
4983
4984 /* Add each freqOffsetFb value */
4985 for (unsigned n=0; n < num_fo_fb; n++) {
4986 unsigned freq_offset_fb;
4987 /* freqOffsetFb (16 bits) */
4988 proto_item *offset_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_freq_offset_fb,
4989 tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &freq_offset_fb);
4990 /* Show if maps onto a -ve number */
4991 if ((freq_offset_fb >= 0x8ad0) && (freq_offset_fb <= 0xffff)) {
4992 proto_item_append_text(offset_ti, "(value %d)", -1 - (0xffff-freq_offset_fb));
4993 }
4994 proto_item_append_text(offset_ti, " [#%u]", n+1);
4995 offset += 2;
4996 }
4997 break;
4998
4999 case 27: /* SE 27: O-DU controlled dimensionality reduction */
5000 {
5001 /* Hidden filter for bf (DMRS BF) */
5002 bf_ti = proto_tree_add_item(tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
5003 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
5004
5005 /* beamType (2 bits) */
5006 unsigned beam_type;
5007 proto_tree_add_item_ret_uint(extension_tree, hf_oran_beam_type, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &beam_type);
5008 /* reserved (6 bits) */
5009 add_reserved_field(extension_tree, hf_oran_reserved_last_6bits, tvb, offset, 1);
5010 offset += 1;
5011
5012 /* numElements */
5013 unsigned num_elements;
5014 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);
5015 if (num_elements == 0) {
5016 num_elements = 256;
5017 proto_item_append_text(num_elements_ti, " (256");
5018 }
5019
5020 offset += 1;
5021
5022 /* beamId value(s) */
5023 switch (beam_type) {
5024 case 0:
5025 for (unsigned n=0; n < num_elements; n++) {
5026 /* reserved (1 bit) + beamId */
5027 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
5028 proto_tree_add_item(c_section_tree, hf_oran_beamId, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
5029 offset += 2;
5030 }
5031 break;
5032 case 1:
5033 /* reserved (1 bit) + beamId */
5034 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
5035 proto_tree_add_item(c_section_tree, hf_oran_beamId, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
5036 offset += 2;
5037 break;
5038 default:
5039 /* Unknown type... */
5040 break;
5041 }
5042 break;
5043 }
5044
5045 case 28: /* SE 28: O-DU controlled frequency resolution for SINR reporting */
5046 {
5047 /* reserved (3 bits) */
5048 add_reserved_field(extension_tree, hf_oran_reserved_3bits, tvb, offset, 1);
5049 /* numUeSinrRpt (5 bits) */
5050 uint32_t num_ue_sinr_rpt;
5051 proto_tree_add_item_ret_uint(extension_tree, hf_oran_num_ue_sinr_rpt, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &num_ue_sinr_rpt);
5052 offset += 1;
5053
5054 for (uint32_t n=0; n < num_ue_sinr_rpt; n++) {
5055 /* reserved (1 bit) */
5056 add_reserved_field(extension_tree, (n % 2) ? hf_oran_reserved_bit4 : hf_oran_reserved_1bit,
5057 tvb, offset, 1);
5058
5059 /* numSinrPerPrb (3 bits). Taken from alternate nibbles within byte. */
5060 proto_tree_add_item(extension_tree, (n % 2) ? hf_oran_num_sinr_per_prb_right : hf_oran_num_sinr_per_prb,
5061 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5062 if (n % 2) {
5063 offset += 1;
5064 }
5065 }
5066
5067 /* May need to skip beyond half-used byte */
5068 if (num_ue_sinr_rpt % 2) {
5069 offset += 1;
5070 }
5071 break;
5072 }
5073
5074 case 29: /* SE 29: Cyclic delay adjustment */
5075 /* reserved (4 bits) */
5076 add_reserved_field(extension_tree, hf_oran_reserved_4bits, tvb, offset, 1);
5077 /* cdScgSize (4 bits) */
5078 proto_tree_add_item(extension_tree, hf_oran_cd_scg_size, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5079 offset += 1;
5080
5081 /* cdScgPhaseStep */
5082 proto_tree_add_item(extension_tree, hf_oran_cd_scg_phase_step, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5083 offset += 1;
5084 break;
5085
5086 case 30: /* SE 30: PUSCH repetition indication */
5087 {
5088 /* Only valid for UL */
5089 if (!tap_info->uplink) {
5090 expert_add_info(pinfo, extension_ti, &ei_oran_se30_not_ul);
5091 }
5092
5093 /* ueids[], number_of_ueids may have been rewritten by SE10 */
5094
5095 /* reserved (4 bits) */
5096 add_reserved_field(extension_tree, hf_oran_reserved_4bits, tvb, offset, 1);
5097 /* numRepUe (4 bits) */
5098 uint8_t num_rep_ue;
5099 proto_tree_add_item_ret_uint8(extension_tree, hf_oran_num_rep_ue, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &num_rep_ue);
5100 offset ++;
5101 /* reserved (8 bits) */
5102 add_reserved_field(extension_tree, hf_oran_reserved_8bits, tvb, offset, 1);
5103 offset += 1;
5104
5105 if (num_rep_ue == 1) {
5106 /* SE10 *not* present. N.B. this should tally with number_of_ueids being set to only 1? */
5107 /* reserved (1 bit) */
5108 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
5109 /* isLastRep (1 bit). Value meaningless here? */
5110 proto_tree_add_item(extension_tree, hf_oran_is_last_rep, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5111 /* repIndex (6 bits) */
5112 proto_tree_add_item(extension_tree, hf_oran_rep_index, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5113 offset += 1;
5114
5115 /* reserved (2 bits) */
5116 add_reserved_field(extension_tree, hf_oran_reserved_2bits, tvb, offset, 1);
5117 /* numReps (6 bits) */
5118 uint8_t num_reps;
5119 proto_tree_add_item_ret_uint8(extension_tree, hf_oran_num_reps, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &num_reps);
5120 /* TODO: should numReps be 0 here? */
5121 offset += 1;
5122
5123 /* reserved (2 bits) */
5124 add_reserved_field(extension_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5125 offset += 2;
5126
5127 }
5128 else {
5129 /* SE10 present */
5130 bool_Bool is_last_rep = false0;
5131 /* TODO: should is_last_rep (also) cause loop exit? */
5132 for (uint8_t ue_idx=0; (ue_idx < num_rep_ue) && !is_last_rep; ue_idx++) {
5133 /* reserved (1 bit) */
5134 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
5135 /* isLastRep (1 bit) */
5136 proto_tree_add_item_ret_boolean(extension_tree, hf_oran_is_last_rep, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &is_last_rep);
5137 /* repIndex (6 bits) */
5138 proto_tree_add_item(extension_tree, hf_oran_rep_index, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5139 offset += 1;
5140
5141 /* reserved (2 bits) */
5142 add_reserved_field(extension_tree, hf_oran_reserved_2bits, tvb, offset, 1);
5143 /* numReps (6 bits) */
5144 uint8_t num_reps;
5145 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);
5146 /* TODO: values 33-63 are reserved */
5147 if (num_reps > 32) {
5148 proto_item_append_text(num_reps_ti, " (reserved)");
5149 }
5150 offset += 1;
5151
5152 for (uint8_t rep=0; rep < num_reps; rep++) {
5153 /* reserved (1 bit) */
5154 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
5155 /* repUeId (15 bits) */
5156 /* TODO: should be fetching and comparing with ueids[] from SE10? */
5157 uint16_t ueid;
5158 proto_item *ueid_ti = proto_tree_add_item_ret_uint16(extension_tree, hf_oran_rep_ueid, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &ueid);
5159
5160 /* Check that this ueid is recognised (among ueids[], number_of_ueids) */
5161 bool_Bool matched = false0;
5162 for (unsigned u=0; u < number_of_ueids; u++) {
5163 if (ueid == ueids[u])
5164 matched = true1;
5165 }
5166 if (!matched) {
5167 expert_add_info_format(pinfo, ueid_ti, &ei_oran_se30_unknown_ueid,
5168 "SE 30 mentions UEId %u - not seen in SE10", ueid);
5169 }
5170 offset += 2;
5171 }
5172 }
5173 }
5174 break;
5175 }
5176 case 31: /* SE 31: MCS Information */
5177 {
5178 /* TODO: show ueid (from ST5 or SE10) as generated field? Maybe add a subtree for each entry? */
5179 for (uint32_t u=0; u < number_of_ueids; u++) {
5180 /* reserved (4 bits) */
5181 add_reserved_field(extension_tree, hf_oran_reserved_4bits, tvb, offset, 1);
5182 /* mcsTable (4 bits) */
5183 proto_tree_add_item(extension_tree, hf_oran_mcs_table, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5184 offset += 1;
5185
5186 /* reserved (2 bits) */
5187 add_reserved_field(extension_tree, hf_oran_reserved_4bits, tvb, offset, 1);
5188 /* mcsIndex (6 bits) */
5189 proto_tree_add_item(extension_tree, hf_oran_mcs_index, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5190 }
5191 break;
5192 }
5193
5194 case 32: /* SE 32: Rank and TPMI measurement request */
5195 {
5196 /* reserved (3 bits) */
5197 add_reserved_field(extension_tree, hf_oran_reserved_3bits, tvb, offset, 1);
5198 /* numMeasReq (5 bits) */
5199 uint8_t num_meas_req;
5200 proto_tree_add_item_ret_uint8(extension_tree, hf_oran_num_meas_req, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &num_meas_req);
5201 offset += 1;
5202
5203 /* reserved (8 bits) */
5204 add_reserved_field(extension_tree, hf_oran_reserved_8bits, tvb, offset, 1);
5205 offset += 1;
5206
5207 /* Show each measurement request */
5208 for (unsigned r=0; r < num_meas_req; r++) {
5209 /* Reserved (1 bit) */
5210 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
5211 /* ueId (14 bits) */
5212 proto_tree_add_item(extension_tree, hf_oran_ueId, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
5213 offset += 2;
5214
5215 /* numOfUeAntPorts (4 bits) */
5216 proto_tree_add_item(extension_tree, hf_oran_num_of_ue_ant_ports, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5217 /* ueRank (4 bits) */
5218 proto_tree_add_item(extension_tree, hf_oran_ue_rank, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5219 offset += 1;
5220
5221 /* codebookSubset (2 bits) */
5222 proto_tree_add_item(extension_tree, hf_oran_codebook_subset, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5223 /* TODO: tpmiIndex (6 bits) */
5224 offset += 1;
5225
5226 /* fullPwrMode (2 bits) */
5227 proto_tree_add_item(extension_tree, hf_oran_full_pwr_mode, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5228 /* fullPwrMode2TmpiGroup (14 bits) */
5229 /* TODO: add as a bitset */
5230 proto_tree_add_item(extension_tree, hf_oran_full_pwr_mode_2_tpmi_group, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
5231 offset += 2;
5232
5233 /* reserved (2 bytes) */
5234 add_reserved_field(extension_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5235 offset += 2;
5236 }
5237 break;
5238 }
5239
5240 default:
5241 /* Other/unexpected extension types */
5242 expert_add_info_format(pinfo, exttype_ti, &ei_oran_unhandled_se,
5243 "SE %u (%s) not supported by dissector",
5244 exttype, val_to_str_ext_const(exttype, &exttype_vals_ext, "Reserved"));
5245 ext_unhandled = true1;
5246 break;
5247 }
5248
5249 /* Check offset compared with extlen. There should be 0-3 bytes of padding */
5250 int num_padding_bytes = (extension_start_offset + (extlen*4) - offset);
5251 if (!ext_unhandled && ((num_padding_bytes<0) || (num_padding_bytes>3))) {
5252 expert_add_info_format(pinfo, extlen_ti, &ei_oran_extlen_wrong,
5253 "extlen signalled %u bytes (+ 0-3 bytes padding), but %u were dissected",
5254 extlen*4, offset-extension_start_offset);
5255 }
5256
5257 /* Move offset to beyond signalled length of extension */
5258 offset = extension_start_offset + (extlen*4);
5259
5260 /* Set length of extension header. */
5261 proto_item_set_len(extension_ti, extlen*4);
5262 }
5263 /* End of section extension handling */
5264
5265 /* Tap section beamId if not overwritten by SEs */
5266 if (!section_beamId_ignored && section_beamId != 0) {
5267 add_beam_id_to_tap(tap_info, section_beamId);
5268 }
5269
5270
5271 /* RRM measurement reports have measurement reports *after* extensions */
5272 if (sectionType == SEC_C_RRM_MEAS_REPORTS) /* Section Type 10 */
5273 {
5274 /* Hidden filter for bf (DMFS-BF). No BF weights though.. */
5275 bf_ti = proto_tree_add_item(c_section_tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
5276 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
5277
5278 bool_Bool mf;
5279 do {
5280 /* Measurement report subtree */
5281 proto_item *mr_ti = proto_tree_add_string_format(c_section_tree, hf_oran_measurement_report,
5282 tvb, offset, 1, "", "Measurement Report");
5283 proto_tree *mr_tree = proto_item_add_subtree(mr_ti, ett_oran_measurement_report);
5284 unsigned report_start_offset = offset;
5285
5286 /* measurement flag (i.e., more reports after this one) (1 bit) */
5287 proto_tree_add_item_ret_boolean(mr_tree, hf_oran_mf, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &mf);
5288
5289 /* measTypeId (7 bits) */
5290 uint32_t meas_type_id;
5291 proto_item *meas_type_id_ti;
5292 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);
5293 offset += 1;
5294
5295 /* Common to all measurement types */
5296 unsigned num_elements = 0;
5297 if (meas_type_id == 6) {
5298 /* numElements */
5299 proto_tree_add_item_ret_uint(mr_tree, hf_oran_num_elements, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &num_elements);
5300 }
5301 else {
5302 /* All other meas ids have a reserved byte */
5303 add_reserved_field(mr_tree, hf_oran_reserved_8bits, tvb, offset, 1);
5304 }
5305 offset += 1;
5306
5307 /* measDataSize (16 bits). N.B. begins at mf field, i.e. 2 bytes before this one */
5308 unsigned meas_data_size;
5309 proto_item *meas_data_size_ti;
5310 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);
5311 meas_data_size *= 4;
5312 proto_item_append_text(meas_data_size_ti, " (%u bytes)", meas_data_size);
5313 offset += 2;
5314
5315 /* Summary for measurement report root */
5316 proto_item_append_text(mr_ti, " (measTypeId=%u - %s)",
5317 meas_type_id, val_to_str_const(meas_type_id, meas_type_id_vals, "unknown"));
5318 /* And section header */
5319 proto_item_append_text(tree, " (%s)", val_to_str_const(meas_type_id, meas_type_id_vals, "unknown"));
5320 /* And Info column */
5321 col_append_fstr(pinfo->cinfo, COL_INFO, " (%s)", val_to_str_const(meas_type_id, meas_type_id_vals, "unknown"));
5322
5323 /* Handle specific message type fields */
5324 switch (meas_type_id) {
5325 case 1:
5326 {
5327 /* ueTae */
5328 unsigned ue_tae;
5329 proto_item *ue_tae_ti;
5330 ue_tae_ti = proto_tree_add_item_ret_uint(mr_tree, hf_oran_ue_tae, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &ue_tae);
5331 /* Show if maps onto a -ve number */
5332 if ((ue_tae >= 0x8ad0) && (ue_tae <= 0xffff)) {
5333 proto_item_append_text(ue_tae_ti, "(value %d)", -1 - (0xffff-ue_tae));
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 2:
5343 /* ueLayerPower entries (how many? for now just use up meas_data_size..) */
5344 /* TODO: add number of distinct dmrsPortNumber entries seen in SE24 and save in state? */
5345 /* Or would it make sense to use the preference 'pref_num_bf_antennas' ? */
5346 for (unsigned n=0; n < (meas_data_size-4)/2; n++) {
5347 unsigned ue_layer_power;
5348 proto_item *ue_layer_power_ti;
5349 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);
5350 /* Show if maps onto a -ve number */
5351 if ((ue_layer_power >= 0x8ad0) && (ue_layer_power <= 0xffff)) {
5352 proto_item_append_text(ue_layer_power_ti, "(value %d)", -1 - (0xffff-ue_layer_power));
5353 }
5354 offset += 2;
5355 }
5356 /* padding out to 4 bytes */
5357 break;
5358 case 3:
5359 {
5360 /* ueFreqOffset */
5361 unsigned ue_freq_offset;
5362 proto_item *ue_freq_offset_ti;
5363 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);
5364 /* Show if maps onto a -ve number */
5365 if ((ue_freq_offset >= 0x8ad0) && (ue_freq_offset <= 0xffff)) {
5366 proto_item_append_text(ue_freq_offset_ti, "(value %d)", -1 - (0xffff-ue_freq_offset));
5367 }
5368 offset += 2;
5369
5370 /* Reserved (16 bits) */
5371 add_reserved_field(mr_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5372 offset += 2;
5373 break;
5374 }
5375 case 4:
5376 case 5:
5377 /* reserved (2 bits) */
5378 add_reserved_field(mr_tree, hf_oran_reserved_2bits, tvb, offset, 1);
5379 /* symbolMask (14 bits) */
5380 offset = dissect_symbolmask(tvb, mr_tree, offset, NULL((void*)0), NULL((void*)0));
5381
5382 /* 2 bytes for each PRB ipnPower */
5383 for (unsigned prb=0; prb<MAX_PRBS273; prb++) {
5384 /* Skip if should not be reported */
5385 if (!prbs_for_st10_type5[prb]) {
5386 continue;
5387 }
5388 unsigned ipn_power;
5389 proto_item *ipn_power_ti;
5390 /* ipnPower (2 bytes) */
5391 ipn_power_ti = proto_tree_add_item_ret_uint(mr_tree, hf_oran_ipn_power, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &ipn_power);
5392 proto_item_append_text(ipn_power_ti, " (PRB %3d)", prb);
5393 /* Show if maps onto a -ve number */
5394 if ((ipn_power >= 0x8ad0) && (ipn_power <= 0xffff)) {
5395 proto_item_append_text(ipn_power_ti, " (value %d)", -1 - (0xffff-ipn_power));
5396 }
5397 offset += 2;
5398 }
5399 /* padding out to 4 bytes */
5400 break;
5401 case 6:
5402 /* antDmrsSnrVal entries */
5403 for (unsigned n=0; n < num_elements; n++) {
5404 unsigned snr_value;
5405 proto_item *snr_value_ti;
5406 /* antDmrsSnrVal (2 bytes) */
5407 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);
5408 proto_item_append_text(snr_value_ti, " (elem %2u)", n+1);
5409 /* Show if maps onto a -ve number */
5410 if ((snr_value >= 0x8ad0) && (snr_value <= 0xffff)) {
5411 proto_item_append_text(snr_value_ti, " (value %d)", -1 - (0xffff-snr_value));
5412 }
5413 offset += 2;
5414 }
5415 break;
5416 case 7:
5417 {
5418 /* UE positioning measurement report */
5419 float start_value;
5420
5421 /* ueAzAoa (16 bits) */
5422 uint32_t ue_az_aoa;
5423 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);
5424 if (ue_az_aoa <= 0xE0F) {
5425 if (ue_az_aoa >= 0x0708) {
5426 start_value = (ue_az_aoa-0x0708) * (float)0.1;
5427 proto_item_append_text(ue_az_aoa_ti, " (%.1f <= val < %.1f degrees)", start_value, start_value + (float)0.1);
5428 }
5429 else {
5430 start_value = 180 + (ue_az_aoa * (float)0.1);
5431 proto_item_append_text(ue_az_aoa_ti, " (%.1f <= val < %.1f degrees)", start_value, start_value + (float)0.1);
5432 }
5433 }
5434 else if (ue_az_aoa == 0xffff) {
5435 proto_item_append_text(ue_az_aoa_ti, " (invalid measurement result)");
5436 }
5437 else {
5438 proto_item_append_text(ue_az_aoa_ti, " (reserved)");
5439 }
5440 offset += 2;
5441
5442 /* Reserved (16 bits) */
5443 add_reserved_field(mr_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5444 offset += 2;
5445
5446 /* ueZeAoa (16 bits) */
5447 uint32_t ue_ze_aoa;
5448 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);
5449 if (ue_ze_aoa <= 0x707) {
5450 start_value = ue_ze_aoa * (float)0.1;
5451 proto_item_append_text(ue_ze_aoa_ti, " (%.1f <= val < %.1f degrees)", start_value, start_value + (float)0.1);
5452 }
5453 else if (ue_az_aoa == 0xffff) {
5454 proto_item_append_text(ue_ze_aoa_ti, " (invalid measurement result)");
5455 }
5456 else {
5457 proto_item_append_text(ue_ze_aoa_ti, " (reserved)");
5458 }
5459 offset += 2;
5460
5461 /* Reserved (16 bits) */
5462 add_reserved_field(mr_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5463 offset += 2;
5464
5465 /* uePosToaOffset (16 bits) */
5466 uint32_t ue_pos_toa_offset;
5467 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);
5468 if (ue_pos_toa_offset == 0) {
5469 proto_item_append_text(ue_pos_toa_offset_ti, " (no UE ToA offset, 0 symbols)");
5470 }
5471 else if (ue_pos_toa_offset <= 0x7fff) {
5472 proto_item_append_text(ue_pos_toa_offset_ti, " (+ve UE ToA offset)");
5473 }
5474 else if (ue_pos_toa_offset == 0x8000) {
5475 proto_item_append_text(ue_pos_toa_offset_ti, " (invalid measurement result)");
5476 }
5477 else {
5478 proto_item_append_text(ue_pos_toa_offset_ti, " (-ve UE ToA offset)");
5479 }
5480 offset += 2;
5481
5482 /* Reserved (16 bits) */
5483 add_reserved_field(mr_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5484 offset += 2;
5485 break;
5486 }
5487 case 8:
5488 {
5489 /* UE radial speed measurement report */
5490
5491 /* ueRadialSpeed (16 bits) */
5492 uint32_t radial_speed;
5493 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);
5494 if (radial_speed <= 10000) {
5495 proto_item_append_text(radial_speed_ti, " (%.1f km/h)", radial_speed * (float)0.1);
5496 }
5497 else if (radial_speed == 0x8000) {
5498 proto_item_append_text(radial_speed_ti, " (invalid measurement result)");
5499 }
5500 else {
5501 proto_item_append_text(radial_speed_ti, " (reserved value)");
5502 }
5503 offset += 2;
5504
5505 /* Reserved (16 bits) */
5506 add_reserved_field(mr_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5507 offset += 2;
5508 break;
5509 }
5510 case 9:
5511 {
5512 /* TODO: UE post-equalization MU interference measurement */
5513
5514 /* reserved (16 bits) */
5515 add_reserved_field(mr_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5516 offset += 2;
5517
5518 /* TODO: muInterferenceLevel (all layers * all PRB blocks) */
5519 break;
5520 }
5521 case 10:
5522 {
5523 /* UE TPMI and rank recommendation measurement */
5524
5525 /* numCandRanks (4 bits - only 1-4 valid) */
5526 uint8_t num_cand_ranks;
5527 proto_tree_add_item_ret_uint8(mr_tree, hf_oran_num_cand_ranks, tvb, offset, 1, ENC_NA0x00000000, &num_cand_ranks);
5528 if (num_cand_ranks > 4) {
5529 num_cand_ranks = 4;
5530 }
5531 if (num_cand_ranks < 1) {
5532 num_cand_ranks = 1;
5533 }
5534
5535 /* uePrefRank (4 bits) */
5536 add_reserved_field(mr_tree, hf_oran_ue_pref_rank, tvb, offset, 1);
5537 offset += 1;
5538
5539 for (uint8_t cand_rank=1; cand_rank <= num_cand_ranks; cand_rank++) {
5540 /* ueTpmiRankY (1 byte) */
5541 proto_item *rank_y_ti = proto_tree_add_item(mr_tree, hf_oran_ue_tpmi_rank_y,
5542 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5543 proto_item_append_text(rank_y_ti, " (rank %u)", cand_rank);
5544
5545 offset += 1;
5546
5547 for (uint8_t sinr = 1; sinr <= cand_rank; sinr++) {
5548 /* ueTpmiRankYSinrLX (2 bytes) */
5549 proto_item *rank_y_sinr_x_ti = proto_tree_add_item(mr_tree, hf_oran_ue_tpmi_rank_y_sinr_lx,
5550 tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
5551 proto_item_append_text(rank_y_sinr_x_ti, " (rank %u, sinr %u)", cand_rank, sinr);
5552 offset += 2;
5553 }
5554 }
5555 break;
5556 }
5557 case 11:
5558 {
5559 /* UE layer pre-equalization SINR report */
5560 /* TODO: how to know how many layers? Just fill up available data? */
5561 unsigned num_layers = (meas_data_size-1) * 4;
5562 for (unsigned layer=0; layer < num_layers; layer++) {
5563 /* ueLayerPreEqSinr (2 bytes each) */
5564 proto_item *pre_eq_sinr_ti = proto_tree_add_item(mr_tree, hf_oran_ue_layer_pre_eq_sinr,
5565 tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
5566 proto_item_append_text(pre_eq_sinr_ti, " (layer %u)", layer);
5567 offset += 2;
5568 }
5569 break;
5570 }
5571
5572 default:
5573 /* Anything else is not expected */
5574 expert_add_info_format(pinfo, meas_type_id_ti, &ei_oran_unexpected_measTypeId,
5575 "measTypeId %u (%s) not supported - only 1-6 are expected",
5576 meas_type_id,
5577 val_to_str_const(meas_type_id, meas_type_id_vals, "reserved"));
5578 break;
5579
5580 }
5581
5582 /* Pad out to next 4 bytes */
5583 offset += WS_PADDING_TO_4(offset-report_start_offset)((4U - ((offset-report_start_offset) % 4U)) % 4U);
5584
5585 /* TODO: verify dissected size of report vs meas_data_size? */
5586
5587 /* End of measurement report tree */
5588 proto_item_set_end(mr_ti, tvb, offset);
5589 } while (mf);
5590 }
5591
5592 /* Request for RRM Measurements has measurement commands after extensions */
5593 else if (sectionType == SEC_C_REQUEST_RRM_MEAS) /* Section Type 11 */
5594 {
5595 bool_Bool mf = true1;
5596 do {
5597 /* Measurement command subtree */
5598 proto_item *mc_ti = proto_tree_add_string_format(c_section_tree, hf_oran_measurement_command,
5599 tvb, offset, 8, "", "Measurement Command");
5600 proto_tree *mc_tree = proto_item_add_subtree(mc_ti, ett_oran_measurement_command);
5601
5602 /* mf (1 bit). 1st measurement command is always preset */
5603 proto_tree_add_item_ret_boolean(mc_tree, hf_oran_mf, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &mf);
5604
5605 /* measTypeId (7 bits) */
5606 uint32_t meas_type_id;
5607 proto_item *meas_type_id_ti;
5608 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);
5609 offset += 1;
5610
5611 proto_item *meas_command_ti;
5612 uint32_t meas_command_size;
5613
5614 switch (meas_type_id) {
5615 case 5: /* command for IpN for unallocated PRBs */
5616 /* reserved (1 byte) */
5617 add_reserved_field(mc_tree, hf_oran_reserved_8bits, tvb, offset, 1);
5618 offset += 1;
5619 /* measCmdSize. Presumably number of words so in future could skip unrecognised command types.. */
5620 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);
5621 proto_item_append_text(meas_command_ti, " (%u bytes)", meas_command_size*4);
5622 offset += 2;
5623 /* reserved (2 bits) */
5624 add_reserved_field(mc_tree, hf_oran_reserved_2bits, tvb, offset, 1);
5625 /* symbolMask (14 bits) */
5626 offset = dissect_symbolmask(tvb, mc_tree, offset, NULL((void*)0), NULL((void*)0));
5627 /* reserved (16 bits) */
5628 add_reserved_field(mc_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5629 offset += 2;
5630 break;
5631
5632 default:
5633 /* Anything else is not expected */
5634 expert_add_info_format(pinfo, meas_type_id_ti, &ei_oran_unexpected_measTypeId,
5635 "measTypeId %u (%s) not supported - only 5 is expected",
5636 meas_type_id,
5637 val_to_str_const(meas_type_id, meas_type_id_vals, "reserved"));
5638 break;
5639 }
5640 proto_item_append_text(mc_ti, " (%s)", val_to_str_const(meas_type_id, meas_type_id_vals, "unknown"));
5641
5642 } while (mf);
5643 }
5644
5645 /* Set extent of overall section */
5646 proto_item_set_len(sectionHeading, offset);
5647
5648 return offset;
5649}
5650
5651/* Dissect udCompHdr (user data compression header, 7.5.2.10) */
5652/* bit_width and comp_meth are out params */
5653static int dissect_udcomphdr(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset,
5654 bool_Bool cplane, bool_Bool ignore,
5655 unsigned *bit_width, unsigned *comp_meth, proto_item **comp_meth_ti,
5656 oran_tap_info *tap_info)
5657{
5658 /* Subtree */
5659 proto_item *udcomphdr_ti = proto_tree_add_string_format(tree, hf_oran_udCompHdr,
5660 tvb, offset, 1, "",
5661 "udCompHdr");
5662 proto_tree *udcomphdr_tree = proto_item_add_subtree(udcomphdr_ti, ett_oran_udcomphdr);
5663
5664 /* udIqWidth */
5665 uint32_t hdr_iq_width;
5666 proto_item *iq_width_item = proto_tree_add_item_ret_uint(udcomphdr_tree, hf_oran_udCompHdrIqWidth , tvb, offset, 1, ENC_NA0x00000000, &hdr_iq_width);
5667 *bit_width = (hdr_iq_width) ? hdr_iq_width : 16;
5668 proto_item_append_text(iq_width_item, " (%u bits)", *bit_width);
5669
5670 /* udCompMeth */
5671 uint32_t ud_comp_meth;
5672 *comp_meth_ti = proto_tree_add_item_ret_uint(udcomphdr_tree, hf_oran_udCompHdrMeth, tvb, offset, 1, ENC_NA0x00000000, &ud_comp_meth);
5673 if (comp_meth) {
5674 *comp_meth = ud_comp_meth;
5675 }
5676
5677 /* Populate tap header with compression settings */
5678 if (!ignore) {
5679 tap_info->compression_methods |= (1 << ud_comp_meth);
5680 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))
;
5681 /* Summary */
5682 proto_item_append_text(udcomphdr_ti, " (IqWidth=%u, udCompMeth=%s)",
5683 *bit_width, rval_to_str_const(ud_comp_meth, ud_comp_header_meth, "Unknown"));
5684 }
5685 else {
5686 proto_item_append_text(udcomphdr_ti, " (ignored)");
5687 if (hdr_iq_width || ud_comp_meth) {
5688 if (cplane) {
5689 /* Only ignore DL for cplane */
5690 expert_add_info_format(pinfo, udcomphdr_ti, &ei_oran_udpcomphdr_should_be_zero,
5691 "udCompHdr in C-Plane for DL should be 0 - found 0x%02x",
5692 tvb_get_uint8(tvb, offset));
5693 }
5694 else {
5695 /* TODO: Ignore UL if using m-plane/preference setting rather than c-plane, but wrong to be set? */
5696 /* expert_add_info_format(pinfo, udcomphdr_ti, &ei_oran_udpcomphdr_should_be_zero,
5697 "udCompHdr in C-Plane for UL should be 0 - found 0x%02x",
5698 tvb_get_uint8(tvb, offset));
5699 */
5700 }
5701
5702 }
5703 }
5704 return offset+1;
5705}
5706
5707/* Dissect udCompParam (user data compression parameter, 8.3.3.15) */
5708/* bit_width and comp_meth are out params */
5709static int dissect_udcompparam(tvbuff_t *tvb, packet_info *pinfo _U___attribute__((unused)), proto_tree *tree, unsigned offset,
5710 unsigned comp_meth,
5711 uint32_t *exponent, uint16_t *sReSMask,
5712 bool_Bool for_sinr)
5713{
5714 if (for_sinr && (comp_meth != COMP_BLOCK_FP1)) {
5715 /* sinrCompParam only present when bfp is used */
5716 return offset;
5717 }
5718
5719 if (comp_meth == COMP_NONE0 ||
5720 comp_meth == COMP_MODULATION4 ||
5721 comp_meth == MOD_COMPR_AND_SELECTIVE_RE_WITH_MASKS8) {
5722
5723 /* Not even creating a subtree for udCompMeth 0, 4, 8 */
5724 return offset;
5725 }
5726
5727 /* Subtree */
5728 unsigned start_offset = offset;
5729 proto_item *udcompparam_ti = proto_tree_add_string_format(tree, hf_oran_udCompParam,
5730 tvb, offset, 1, "",
5731 (for_sinr) ? "sinrCompParam" : "udCompParam");
5732 proto_tree *udcompparam_tree = proto_item_add_subtree(udcompparam_ti, ett_oran_udcompparam);
5733
5734 /* Show comp_meth as a generated field */
5735 proto_item *meth_ti = proto_tree_add_uint(udcompparam_tree, hf_oran_udCompHdrMeth_pref, tvb, 0, 0, comp_meth);
5736 proto_item_set_generated(meth_ti);
5737
5738 uint32_t param_exponent;
5739 uint64_t param_sresmask;
5740
5741 static int * const sres_mask_flags[] = {
5742 &hf_oran_sReSMask_re12,
5743 &hf_oran_sReSMask_re11,
5744 &hf_oran_sReSMask_re10,
5745 &hf_oran_sReSMask_re9,
5746 &hf_oran_sReSMask_re8,
5747 &hf_oran_sReSMask_re7,
5748 &hf_oran_sReSMask_re6,
5749 &hf_oran_sReSMask_re5,
5750 &hf_oran_sReSMask_re4,
5751 &hf_oran_sReSMask_re3,
5752 &hf_oran_sReSMask_re2,
5753 &hf_oran_sReSMask_re1,
5754 NULL((void*)0)
5755 };
5756
5757 switch (comp_meth) {
5758 case COMP_BLOCK_FP1: /* 1 */
5759 case BFP_AND_SELECTIVE_RE_WITH_MASKS7: /* 7 */
5760 /* reserved (4 bits) */
5761 add_reserved_field(udcompparam_tree, hf_oran_reserved_4bits, tvb, offset, 1);
5762 /* exponent (4 bits) */
5763 proto_tree_add_item_ret_uint(udcompparam_tree, hf_oran_exponent,
5764 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &param_exponent);
5765 *exponent = param_exponent;
5766 proto_item_append_text(udcompparam_ti, " (Exponent=%u)", param_exponent);
5767 offset += 1;
5768 break;
5769
5770 case COMP_BLOCK_SCALE2: /* 2 */
5771 /* Separate into integer and fractional bits? */
5772 proto_tree_add_item(udcompparam_tree, hf_oran_blockScaler,
5773 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5774 offset++;
5775 break;
5776
5777 case COMP_U_LAW3: /* 3 */
5778 /* compBitWidth, compShift */
5779 proto_tree_add_item(udcompparam_tree, hf_oran_compBitWidth,
5780 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5781 proto_tree_add_item(udcompparam_tree, hf_oran_compShift,
5782 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5783 offset += 1;
5784 break;
5785
5786 case BFP_AND_SELECTIVE_RE5: /* 5 */
5787 {
5788 /* sReSMask (exponent in middle!) */
5789 proto_item *sresmask_ti;
5790 sresmask_ti = proto_tree_add_bitmask_ret_uint64(udcompparam_tree, tvb, offset,
5791 hf_oran_sReSMask,
5792 ett_oran_sresmask,
5793 sres_mask_flags,
5794 ENC_NA0x00000000,
5795 &param_sresmask);
5796
5797 /* Get rid of exponent-shaped gap */
5798 param_sresmask = ((param_sresmask >> 4) & 0x0f00) | (param_sresmask & 0xff);
5799 unsigned res = 0;
5800 for (unsigned n=0; n < 12; n++) {
5801 if ((param_sresmask >> n) & 0x1) {
5802 res++;
5803 }
5804 }
5805 proto_item_append_text(sresmask_ti, " (%2u REs)", res);
5806
5807 /* exponent */
5808 proto_tree_add_item_ret_uint(udcompparam_tree, hf_oran_exponent,
5809 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &param_exponent);
5810 *sReSMask = (uint16_t)param_sresmask;
5811 *exponent = param_exponent;
5812
5813 proto_item_append_text(udcompparam_ti, " (exponent=%u, %u REs)", *exponent, res);
5814 offset += 2;
5815 break;
5816 }
5817
5818 case MOD_COMPR_AND_SELECTIVE_RE6: /* 6 */
5819 {
5820 /* sReSMask (exponent in middle!) */
5821 proto_item *sresmask_ti;
5822
5823 sresmask_ti = proto_tree_add_bitmask_ret_uint64(udcompparam_tree, tvb, offset,
5824 hf_oran_sReSMask,
5825 ett_oran_sresmask,
5826 sres_mask_flags,
5827 ENC_NA0x00000000,
5828 &param_sresmask);
5829
5830 /* Get rid of reserved-shaped gap */
5831 param_sresmask = ((param_sresmask >> 4) & 0x0f00) | (param_sresmask & 0xff);
5832 unsigned res = 0;
5833 for (unsigned n=0; n < 12; n++) {
5834 if ((param_sresmask >> n) & 0x1) {
5835 res++;
5836 }
5837 }
5838 proto_item_append_text(sresmask_ti, " (%u REs)", res);
5839
5840 /* reserved (4 bits) */
5841 add_reserved_field(udcompparam_tree, hf_oran_reserved_last_4bits, tvb, offset, 1);
5842 *sReSMask = (uint16_t)param_sresmask;
5843
5844 proto_item_append_text(udcompparam_ti, " (%u REs)", res);
5845 offset += 2;
5846 break;
5847 }
5848
5849 default:
5850 /* reserved (set to all zeros), but how many bytes?? */
5851 break;
5852 }
5853
5854 proto_item_set_len(udcompparam_ti, offset-start_offset);
5855 return offset;
5856}
5857
5858
5859/* Dissect ciCompHdr (channel information compression header, 7.5.2.15) */
5860/* bit_width and comp_meth are out params */
5861static int dissect_cicomphdr(tvbuff_t *tvb, packet_info *pinfo _U___attribute__((unused)), proto_tree *tree, unsigned offset,
5862 unsigned *bit_width, unsigned *comp_meth, uint8_t *comp_opt)
5863{
5864 /* Subtree */
5865 proto_item *cicomphdr_ti = proto_tree_add_string_format(tree, hf_oran_ciCompHdr,
5866 tvb, offset, 1, "",
5867 "ciCompHdr");
5868 proto_tree *cicomphdr_tree = proto_item_add_subtree(cicomphdr_ti, ett_oran_cicomphdr);
5869
5870 /* ciIqWidth */
5871 uint32_t hdr_iq_width;
5872 proto_item *iq_width_item = proto_tree_add_item_ret_uint(cicomphdr_tree, hf_oran_ciCompHdrIqWidth , tvb, offset, 1, ENC_NA0x00000000, &hdr_iq_width);
5873 hdr_iq_width = (hdr_iq_width) ? hdr_iq_width : 16;
5874 if (bit_width) {
5875 *bit_width = hdr_iq_width;
5876 }
5877 proto_item_append_text(iq_width_item, " (%u bits)", hdr_iq_width);
5878
5879 /* ciCompMeth */
5880 uint32_t ci_comp_meth;
5881 proto_tree_add_item_ret_uint(cicomphdr_tree, hf_oran_ciCompHdrMeth, tvb, offset, 1, ENC_NA0x00000000, &ci_comp_meth);
5882 if (comp_meth) {
5883 *comp_meth = ci_comp_meth;
5884 }
5885
5886 /* ciCompOpt */
5887 uint32_t opt;
5888 proto_tree_add_item_ret_uint(cicomphdr_tree, hf_oran_ciCompOpt, tvb, offset, 1, ENC_NA0x00000000, &opt);
5889 *comp_opt = opt;
5890 offset += 1;
5891
5892 /* Summary */
5893 proto_item_append_text(cicomphdr_ti, " (IqWidth=%u, ciCompMeth=%s, ciCompOpt=%s)",
5894 hdr_iq_width,
5895 rval_to_str_const(ci_comp_meth, ud_comp_header_meth, "Unknown"),
5896 (*comp_opt) ? "compression per PRB" : "compression per UE");
5897 return offset;
5898}
5899
5900static void dissect_payload_version(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, unsigned offset)
5901{
5902 unsigned version;
5903 proto_item *ti = proto_tree_add_item_ret_uint(tree, hf_oran_payload_version, tvb, offset, 1, ENC_NA0x00000000, &version);
5904 if (version != 1) {
5905 expert_add_info_format(pinfo, ti, &ei_oran_version_unsupported,
5906 "PayloadVersion %u not supported by dissector (only 1 is known)",
5907 version);
5908 /* TODO: should throw an exception? */
5909 }
5910}
5911
5912static void show_link_to_acknack_request(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo,
5913 ack_nack_request_t *request)
5914{
5915 /* Request frame */
5916 proto_item *ti = proto_tree_add_uint(tree, hf_oran_acknack_request_frame,
5917 tvb, 0, 0, request->request_frame_number);
5918 PROTO_ITEM_SET_GENERATED(ti)proto_item_set_generated((ti));
5919
5920 /* Work out gap between frames (in ms) */
5921 int seconds_between_packets = (int)
5922 (pinfo->abs_ts.secs - request->request_frame_time.secs);
5923 int nseconds_between_packets =
5924 pinfo->abs_ts.nsecs - request->request_frame_time.nsecs;
5925
5926 int total_gap = (seconds_between_packets*1000) +
5927 ((nseconds_between_packets+500000) / 1000000);
5928
5929 ti = proto_tree_add_uint(tree, hf_oran_acknack_request_time,
5930 tvb, 0, 0, total_gap);
5931 PROTO_ITEM_SET_GENERATED(ti)proto_item_set_generated((ti));
5932
5933 /* Type of request */
5934 ti = proto_tree_add_uint(tree, hf_oran_acknack_request_type,
5935 tvb, 0, 0, request->requestType);
5936 PROTO_ITEM_SET_GENERATED(ti)proto_item_set_generated((ti));
5937}
5938
5939static void show_link_to_acknack_response(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo,
5940 ack_nack_request_t *response)
5941{
5942 if (response->response_frame_number == 0) {
5943 /* Requests may not get a response, and can't always tell when to expect one */
5944 return;
5945 }
5946
5947 /* Response frame */
5948 proto_item *ti = proto_tree_add_uint(tree, hf_oran_acknack_response_frame,
5949 tvb, 0, 0, response->response_frame_number);
5950 PROTO_ITEM_SET_GENERATED(ti)proto_item_set_generated((ti));
5951
5952 /* Work out gap between frames (in ms) */
5953 int seconds_between_packets = (int)
5954 (response->response_frame_time.secs - pinfo->abs_ts.secs);
5955 int nseconds_between_packets =
5956 response->response_frame_time.nsecs - pinfo->abs_ts.nsecs;
5957
5958 int total_gap = (seconds_between_packets*1000) +
5959 ((nseconds_between_packets+500000) / 1000000);
5960
5961 ti = proto_tree_add_uint(tree, hf_oran_acknack_response_time,
5962 tvb, 0, 0, total_gap);
5963 PROTO_ITEM_SET_GENERATED(ti)proto_item_set_generated((ti));
5964}
5965
5966
5967
5968/* Control plane dissector (section 7). */
5969static int dissect_oran_c(tvbuff_t *tvb, packet_info *pinfo,
5970 proto_tree *tree, oran_tap_info *tap_info, void *data _U___attribute__((unused)))
5971{
5972 /* Hidden filter for plane */
5973 proto_item *plane_ti = proto_tree_add_item(tree, hf_oran_cplane, tvb, 0, 0, ENC_NA0x00000000);
5974 PROTO_ITEM_SET_HIDDEN(plane_ti)proto_item_set_hidden((plane_ti));
5975
5976 /* Set up structures needed to add the protocol subtree and manage it */
5977 unsigned offset = 0;
5978
5979 col_set_str(pinfo->cinfo, COL_PROTOCOL, "O-RAN-FH-C");
5980 col_set_str(pinfo->cinfo, COL_INFO, "C-Plane");
5981
5982 tap_info->userplane = false0;
5983
5984 /* Create display subtree for the protocol */
5985 proto_item *protocol_item = proto_tree_add_item(tree, proto_oran, tvb, 0, -1, ENC_NA0x00000000);
5986 proto_item_append_text(protocol_item, "-C");
5987 proto_tree *oran_tree = proto_item_add_subtree(protocol_item, ett_oran);
5988
5989 /* ecpriRtcid (eAxC ID) */
5990 uint16_t eAxC;
5991 addPcOrRtcid(tvb, oran_tree, &offset, hf_oran_ecpri_rtcid, &eAxC, tap_info);
5992 tap_info->eaxc = eAxC;
5993
5994 /* Look up any existing conversation state for eAxC+plane */
5995 uint32_t key = make_flow_key(pinfo, eAxC, ORAN_C_PLANE0, false0);
5996 flow_state_t* state = (flow_state_t*)wmem_tree_lookup32(flow_states_table, key);
5997
5998 /* Message identifier */
5999 uint32_t seq_id, sub_seq_id, e;
6000 proto_item *seq_id_ti;
6001 offset = addSeqid(tvb, oran_tree, offset, ORAN_C_PLANE0, &seq_id, &seq_id_ti, pinfo, &sub_seq_id, &e);
6002
6003 /* Section common subtree */
6004 int section_tree_offset = offset;
6005 proto_item *sectionHeading = proto_tree_add_string_format(oran_tree, hf_oran_c_section_common,
6006 tvb, offset, 0, "", "C-Plane Section Type ");
6007 proto_tree *section_tree = proto_item_add_subtree(sectionHeading, ett_oran_c_section_common);
6008
6009 /* Peek ahead at the section type */
6010 uint32_t sectionType = 0;
6011 sectionType = tvb_get_uint8(tvb, offset+5);
6012
6013 uint32_t scs = 0;
6014 proto_item *scs_ti = NULL((void*)0);
6015
6016 /* dataDirection */
6017 uint32_t direction = 0;
6018 proto_item *datadir_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_data_direction, tvb, offset, 1, ENC_NA0x00000000, &direction);
6019 tap_info->uplink = (direction==0);
6020
6021 /* Update/report status of conversation */
6022 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
6023
6024 if (state == NULL((void*)0)) {
6025 /* Allocate new state */
6026 state = wmem_new0(wmem_file_scope(), flow_state_t)((flow_state_t*)wmem_alloc0((wmem_file_scope()), sizeof(flow_state_t
)))
;
6027 state->ack_nack_requests = wmem_tree_new(wmem_file_scope());
6028 wmem_tree_insert32(flow_states_table, key, state);
6029 /* Tables for each direction */
6030 state->expected_sections[0] = wmem_tree_new(wmem_file_scope());
6031 state->expected_sections[1] = wmem_tree_new(wmem_file_scope());
6032 }
6033
6034 /* Check sequence analysis status */
6035 if (state->last_frame_seen[direction] && (seq_id != state->next_expected_sequence_number[direction])) {
6036 /* Store this result */
6037 flow_result_t *result = wmem_new0(wmem_file_scope(), flow_result_t)((flow_result_t*)wmem_alloc0((wmem_file_scope()), sizeof(flow_result_t
)))
;
6038 result->unexpected_seq_number = true1;
6039 result->expected_sequence_number = state->next_expected_sequence_number[direction];
6040 result->previous_frame = state->last_frame[direction];
6041 result->u_plane_frames = wmem_list_new(wmem_file_scope());
6042 wmem_tree_insert32(flow_results_table, pinfo->num, result);
6043 }
6044 /* Update conversation info */
6045 state->last_frame[direction] = pinfo->num;
6046 state->last_frame_seen[direction] = true1;
6047 state->next_expected_sequence_number[direction] = (seq_id+1) % 256;
6048 }
6049
6050 /* Show any issues associated with this frame number */
6051 flow_result_t *result = wmem_tree_lookup32(flow_results_table, pinfo->num);
6052 if (result!=NULL((void*)0) && result->unexpected_seq_number) {
6053 expert_add_info_format(pinfo, seq_id_ti,
6054 (direction == DIR_UPLINK0) ?
6055 &ei_oran_cplane_unexpected_sequence_number_ul :
6056 &ei_oran_cplane_unexpected_sequence_number_dl,
6057 "Sequence number %u expected, but got %u",
6058 result->expected_sequence_number, seq_id);
6059
6060 /* Update tap info */
6061 uint32_t missing_sns = (256 + seq_id - result->expected_sequence_number) % 256;
6062 /* Don't get confused by being slightly out of order.. */
6063 if (missing_sns < 128) {
6064 tap_info->missing_sns = missing_sns;
6065 }
6066 else {
6067 tap_info->missing_sns = 0;
6068 }
6069
6070 /* TODO: could add previous/next frames (in seqId tree?) ? */
6071 }
6072
6073 /* payloadVersion */
6074 dissect_payload_version(section_tree, tvb, pinfo, offset);
6075
6076 /* filterIndex */
6077 if (sectionType == SEC_C_SLOT_CONTROL || sectionType == SEC_C_ACK_NACK_FEEDBACK) {
6078 /* scs (for ST4 and ST8) */
6079 scs_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_frameStructure_subcarrier_spacing, tvb, offset, 1, ENC_NA0x00000000, &scs);
6080 }
6081 else if (sectionType == SEC_C_RRM_MEAS_REPORTS || sectionType == SEC_C_REQUEST_RRM_MEAS) {
6082 /* reserved (4 bits) */
6083 add_reserved_field(section_tree, hf_oran_reserved_last_4bits, tvb, offset, 1);
6084 }
6085 else if (sectionType != SEC_C_LAA) {
6086 /* filterIndex (most common case) */
6087 proto_tree_add_item(section_tree, hf_oran_filter_index, tvb, offset, 1, ENC_NA0x00000000);
6088 }
6089 offset += 1;
6090
6091 unsigned ref_a_offset = offset;
6092 /* frameId */
6093 uint32_t frameId = 0;
6094 proto_tree_add_item_ret_uint(section_tree, hf_oran_frame_id, tvb, offset, 1, ENC_NA0x00000000, &frameId);
6095 tap_info->frame = frameId;
6096 offset += 1;
6097
6098 /* subframeId */
6099 uint32_t subframeId = 0;
6100 proto_tree_add_item_ret_uint(section_tree, hf_oran_subframe_id, tvb, offset, 1, ENC_NA0x00000000, &subframeId);
6101 /* slotId */
6102 uint32_t slotId = 0;
6103 proto_tree_add_item_ret_uint(section_tree, hf_oran_slot_id, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &slotId);
6104 tap_info->slot = slotId;
6105 offset++;
6106
6107 /* startSymbolId */
6108 uint32_t startSymbolId = 0;
6109 proto_item *ssid_ti = NULL((void*)0);
6110 if ((sectionType == SEC_C_ACK_NACK_FEEDBACK) || /* Section Type 8 */
6111 (sectionType == SEC_C_SINR_REPORTING)) { /* Section Type 9 */
6112 /* symbolId */
6113 proto_tree_add_item_ret_uint(section_tree, hf_oran_symbolId, tvb, offset, 1, ENC_NA0x00000000, &startSymbolId);
6114 }
6115 else if (sectionType != SEC_C_LAA) {
6116 /* startSymbolId is in most section types */
6117 ssid_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_start_symbol_id, tvb, offset, 1, ENC_NA0x00000000, &startSymbolId);
6118 if (startSymbolId && (sectionType == SEC_C_RRM_MEAS_REPORTS)) { /* Section Type 10 */
6119 proto_item_append_text(ssid_ti, " (should be 0 for ST10!)");
6120 expert_add_info_format(pinfo, ssid_ti, &ei_oran_st10_startsymbolid_not_0,
6121 "startSymbolId should be 0 for ST10 - found %u", startSymbolId);
6122 }
6123 }
6124 else {
6125 /* reserved (6 bits) */
6126 add_reserved_field(section_tree, hf_oran_reserved_last_6bits, tvb, offset, 1);
6127 }
6128 offset++;
6129
6130
6131 char id[16];
6132 snprintf(id, 16, "%u-%u-%u-%u", frameId, subframeId, slotId, startSymbolId);
6133 proto_item *pi = proto_tree_add_string(section_tree, hf_oran_refa, tvb, ref_a_offset, 3, id);
6134 proto_item_set_generated(pi);
6135
6136 uint32_t cmd_scope = 0;
6137 bool_Bool st8_ready = false0;
6138
6139 /* numberOfSections (or whatever section has instead) */
6140 uint32_t nSections = 0;
6141 if (sectionType == SEC_C_SLOT_CONTROL) { /* Section Type 4 */
6142 /* Slot Control has these fields instead */
6143 /* reserved (4 bits) */
6144 add_reserved_field(section_tree, hf_oran_reserved_4bits, tvb, offset, 1);
6145 /* cmdScope (4 bits) */
6146 proto_tree_add_item_ret_uint(section_tree, hf_oran_cmd_scope, tvb, offset, 1, ENC_NA0x00000000, &cmd_scope);
6147 }
6148 else if (sectionType == SEC_C_ACK_NACK_FEEDBACK) { /* Section Type 8 */
6149 /* reserved (7 bits) */
6150 add_reserved_field(section_tree, hf_oran_reserved_7bits, tvb, offset, 1);
6151 /* ready (1 bit) */
6152 /* TODO: when set, ready in slotId+1.. */
6153 proto_tree_add_item_ret_boolean(section_tree, hf_oran_ready, tvb, offset, 1, ENC_NA0x00000000, &st8_ready);
6154 if (!st8_ready) {
6155 /* SCS value is ignored, and may be set to any value by O-RU */
6156 proto_item_append_text(scs_ti, " (ignored)");
6157 }
6158 }
6159 else if (sectionType != SEC_C_LAA) {
6160 /* numberOfSections */
6161 proto_tree_add_item_ret_uint(section_tree, hf_oran_numberOfSections, tvb, offset, 1, ENC_NA0x00000000, &nSections);
6162 }
6163 else {
6164 add_reserved_field(section_tree, hf_oran_reserved_8bits, tvb, offset, 1);
6165 }
6166 offset++;
6167
6168 /* sectionType */
6169 proto_tree_add_item_ret_uint(section_tree, hf_oran_sectionType, tvb, offset, 1, ENC_NA0x00000000, &sectionType);
6170 offset += 1;
6171
6172 /* Check that dataDirection is consistent with section type */
6173 if (sectionType == SEC_C_SINR_REPORTING && direction != 0) { /* Section Type 9 */
6174 expert_add_info(pinfo, datadir_ti, &ei_oran_st9_not_ul);
6175 }
6176 if (sectionType == SEC_C_RRM_MEAS_REPORTS && direction != 0) { /* Section Type 10 */
6177 expert_add_info(pinfo, datadir_ti, &ei_oran_st10_not_ul);
6178 }
6179
6180 /* Note this section type in stats */
6181 if (sectionType < SEC_C_MAX_INDEX) {
6182 tap_info->section_types[sectionType] = true1;
6183 }
6184
6185 /* Section-type-specific fields following common header (white entries in Section Type diagrams) */
6186 unsigned bit_width = 0;
6187 unsigned comp_meth = 0;
6188 proto_item *comp_meth_ti;
6189 unsigned ci_comp_method = 0;
6190 uint8_t ci_comp_opt = 0;
6191
6192 uint32_t num_ues = 0;
6193 uint32_t number_of_acks = 0, number_of_nacks = 0;
6194
6195 uint32_t num_sinr_per_prb = 0;
6196
6197 switch (sectionType) {
6198 case SEC_C_UNUSED_RB: /* Section Type 0 */
6199 /* timeOffset */
6200 proto_tree_add_item(section_tree, hf_oran_timeOffset, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6201 offset += 2;
6202 /* frameStructure */
6203 offset = dissect_frame_structure(section_tree, tvb, offset,
6204 subframeId, slotId);
6205
6206 /* cpLength */
6207 proto_tree_add_item(section_tree, hf_oran_cpLength, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6208 offset += 2;
6209 /* reserved (8 bits) */
6210 add_reserved_field(section_tree, hf_oran_reserved_8bits, tvb, offset, 1);
6211 offset += 1;
6212 break;
6213
6214 case SEC_C_NORMAL: /* Section Type 1 */
6215 case SEC_C_UE_SCHED: /* Section Type 5 */
6216 /* udCompHdr */
6217 offset = dissect_udcomphdr(tvb, pinfo, section_tree, offset,
6218 true1, direction==0 && pref_override_ul_compression, /* ignore for DL or if using mplane for UL settings */
6219 &bit_width, &comp_meth, &comp_meth_ti, tap_info);
6220 /* reserved (8 bits) */
6221 add_reserved_field(section_tree, hf_oran_reserved_8bits, tvb, offset, 1);
6222 offset += 1;
6223 break;
6224
6225 case SEC_C_SLOT_CONTROL: /* Section Type 4 */
6226 break;
6227
6228 case SEC_C_PRACH: /* Section Type 3 */
6229 /* timeOffset */
6230 proto_tree_add_item(section_tree, hf_oran_timeOffset, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6231 offset += 2;
6232 /* frameStructure */
6233 offset = dissect_frame_structure(section_tree, tvb, offset,
6234 subframeId, slotId);
6235 /* cpLength */
6236 proto_tree_add_item(section_tree, hf_oran_cpLength, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6237 offset += 2;
6238 /* udCompHdr */
6239 offset = dissect_udcomphdr(tvb, pinfo, section_tree, offset,
6240 true1, direction==0 && pref_override_ul_compression, /* ignore for DL or if using mplane for UL settings */
6241 &bit_width, &comp_meth, &comp_meth_ti, tap_info);
6242 break;
6243
6244 case SEC_C_CH_INFO: /* Section Type 6 */
6245 /* numberOfUEs */
6246 proto_tree_add_item_ret_uint(section_tree, hf_oran_numberOfUEs, tvb, offset, 1, ENC_NA0x00000000, &num_ues);
6247 offset += 1;
6248 /* ciCompHdr (was reserved) */
6249 offset = dissect_cicomphdr(tvb, pinfo, section_tree, offset, &bit_width, &ci_comp_method, &ci_comp_opt);
6250
6251 /* Number of sections may not be filled in (at all, or correctly), so set to the number of UEs.
6252 The data entries are per-UE... they don't have a sectionID, but they could have section extensions... */
6253 if (nSections == 0 || num_ues > nSections) {
6254 nSections = num_ues;
6255 }
6256 break;
6257
6258 case SEC_C_RSVD2:
6259 break;
6260
6261 case SEC_C_LAA: /* Section Type 7 */
6262 add_reserved_field(section_tree, hf_oran_reserved_16bits, tvb, offset, 2);
6263 offset += 2;
6264 break;
6265
6266 case SEC_C_ACK_NACK_FEEDBACK: /* Section Type 8 */
6267 /* numberOfAcks (1 byte) */
6268 proto_tree_add_item_ret_uint(section_tree, hf_oran_number_of_acks, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &number_of_acks);
6269 offset += 1;
6270 /* numberOfNacks (1 byte) */
6271 proto_tree_add_item_ret_uint(section_tree, hf_oran_number_of_nacks, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &number_of_nacks);
6272 offset += 1;
6273
6274 /* Show ACKs and NACKs. For both, try to link back to request. */
6275 for (unsigned int n=1; n <= number_of_acks; n++) {
6276 uint32_t ackid;
6277 proto_item *ack_ti;
6278 ack_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_ackid, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &ackid);
6279 offset += 2;
6280
6281 /* Look up request table in state (which really should be set by now, but test anyway). */
6282 if (state && state->ack_nack_requests) {
6283 ack_nack_request_t *request = wmem_tree_lookup32(state->ack_nack_requests, ackid);
6284 if (request != NULL((void*)0)) {
6285 /* On first pass, update with this response */
6286 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
6287 request->response_frame_number = pinfo->num;
6288 request->response_frame_time = pinfo->abs_ts;
6289 }
6290
6291 /* Show request details */
6292 show_link_to_acknack_request(section_tree, tvb, pinfo, request);
6293 }
6294 else {
6295 /* Request not found */
6296 expert_add_info_format(pinfo, ack_ti, &ei_oran_acknack_no_request,
6297 "Response for ackId=%u received, but no request found",
6298 ackid);
6299 }
6300 }
6301 }
6302 for (unsigned int m=1; m <= number_of_nacks; m++) {
6303 uint32_t nackid;
6304 proto_item *nack_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_nackid, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &nackid);
6305 offset += 2;
6306
6307 expert_add_info_format(pinfo, nack_ti, &ei_oran_st8_nackid,
6308 "Received Nack for ackNackId=%u",
6309 nackid);
6310
6311 /* Look up request table in state. */
6312 if (state && state->ack_nack_requests) {
6313 ack_nack_request_t *request = wmem_tree_lookup32(state->ack_nack_requests, nackid);
6314 if (request) {
6315 /* On first pass, update with this response */
6316 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
6317 request->response_frame_number = pinfo->num;
6318 request->response_frame_time = pinfo->abs_ts;
6319 }
6320
6321 /* Show request details */
6322 show_link_to_acknack_request(section_tree, tvb, pinfo, request);
6323 }
6324 else {
6325 /* Request not found */
6326 expert_add_info_format(pinfo, nack_ti, &ei_oran_acknack_no_request,
6327 "Response for nackId=%u received, but no request found",
6328 nackid);
6329 }
6330 }
6331 }
6332 break;
6333
6334 case SEC_C_SINR_REPORTING: /* Section Type 9 */
6335 {
6336 /* numSinrPerPrb (3 bits) */
6337 proto_item *nspp_ti;
6338 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);
6339 switch (num_sinr_per_prb) {
6340 case 0:
6341 num_sinr_per_prb = 1; break;
6342 case 1:
6343 num_sinr_per_prb = 2; break;
6344 case 2:
6345 num_sinr_per_prb = 3; break;
6346 case 3:
6347 num_sinr_per_prb = 4; break;
6348 case 4:
6349 num_sinr_per_prb = 6; break;
6350 case 5:
6351 num_sinr_per_prb = 12; break;
6352
6353 default:
6354 proto_item_append_text(nspp_ti, " (invalid)");
6355 num_sinr_per_prb = 1;
6356 expert_add_info_format(pinfo, nspp_ti, &ei_oran_num_sinr_per_prb_unknown,
6357 "Invalid numSinrPerPrb value (%u)",
6358 num_sinr_per_prb);
6359 }
6360
6361 /* oruControlSinrSlotMaskId (5 bits) */
6362 proto_tree_add_item(section_tree, hf_oran_oru_control_sinr_slot_mask_id, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6363 offset += 1;
6364 /* reserved (8 bits) */
6365 add_reserved_field(section_tree, hf_oran_reserved_8bits, tvb, offset, 1);
6366 offset += 1;
6367 break;
6368 }
6369
6370 case SEC_C_RRM_MEAS_REPORTS: /* Section Type 10 */
6371 case SEC_C_REQUEST_RRM_MEAS: /* Section Type 11 */
6372 /* reserved (16 bits) */
6373 add_reserved_field(section_tree, hf_oran_reserved_16bits, tvb, offset, 2);
6374 offset += 2;
6375 break;
6376 };
6377
6378 /* Update udCompHdr details in state for UL U-Plane */
6379 if (state && direction==0) {
6380 switch (sectionType) {
6381 case SEC_C_NORMAL: /* Section Type 1 */
6382 case SEC_C_PRACH: /* Section Type 3 */
6383 case SEC_C_UE_SCHED: /* Section Type 5 */
6384 state->ul_ud_comp_hdr_set = true1;
6385 state->ul_ud_comp_hdr_bit_width = bit_width;
6386 state->ul_ud_comp_hdr_compression = comp_meth;
6387 state->ul_ud_comp_hdr_frame = pinfo->num;
6388 break;
6389 default:
6390 break;
6391 }
6392 }
6393
6394
6395 proto_item_append_text(sectionHeading, "%d, %s, frameId: %d, subframeId: %d, slotId: %d, startSymbolId: %d",
6396 sectionType, val_to_str_const(direction, data_direction_vals, "Unknown"),
6397 frameId, subframeId, slotId, startSymbolId);
6398 if (nSections) {
6399 proto_item_append_text(sectionHeading, ", numberOfSections=%u", nSections);
6400 }
6401
6402 write_pdu_label_and_info(protocol_item, NULL((void*)0), pinfo, ", Type: %2d %s", sectionType,
6403 rval_to_str_const(sectionType, section_types_short, "Unknown"));
6404
6405 /* Set actual length of C-Plane section header */
6406 proto_item_set_len(section_tree, offset - section_tree_offset);
6407
6408 if (sectionType == SEC_C_ACK_NACK_FEEDBACK) {
6409 write_pdu_label_and_info(oran_tree, section_tree, pinfo,
6410 (st8_ready) ? " (Ready)" : " (ACK)");
6411 }
6412
6413
6414 /* Section type 4 doesn't have normal sections, so deal with here before normal sections */
6415 if (sectionType == SEC_C_SLOT_CONTROL) {
6416 /* numberOfST4Cmds */
6417 uint32_t no_st4_cmds, st4_cmd_len, num_slots, ack_nack_req_id, st4_cmd_type;
6418 proto_item *no_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_number_of_st4_cmds,
6419 tvb, offset, 1, ENC_NA0x00000000, &no_st4_cmds);
6420 if (no_st4_cmds == 0) {
6421 expert_add_info(pinfo, no_ti, &ei_oran_st4_no_cmds);
6422 }
6423 offset += 1;
6424
6425 /* reserved (1 byte) */
6426 add_reserved_field(section_tree, hf_oran_reserved_8bits, tvb, offset, 1);
6427 offset += 1;
6428
6429 /* Loop over commands. Each has 8-byte common header, followed by cmd-specific payload */
6430 proto_item *len_ti;
6431 for (uint32_t n=0; n < no_st4_cmds; n++) {
6432 /* Table 7.4.6-2: Section Type 4 Command common header format */
6433 proto_item *hdr_ti = proto_tree_add_string_format(section_tree, hf_oran_st4_cmd_header,
6434 tvb, offset, 8, "",
6435 "Type 4 Command common header");
6436 proto_tree *hdr_tree = proto_item_add_subtree(hdr_ti, ett_oran_st4_cmd_header);
6437
6438 /* st4CmdType */
6439 proto_tree_add_item_ret_uint(hdr_tree, hf_oran_st4_cmd_type, tvb, offset, 1, ENC_NA0x00000000, &st4_cmd_type);
6440 offset += 1;
6441
6442 /* st4CmdLen */
6443 len_ti = proto_tree_add_item_ret_uint(hdr_tree, hf_oran_st4_cmd_len, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &st4_cmd_len);
6444 if (st4_cmd_len == 0) {
6445 /* Meaning of 0 not yet defined (v15.00) */
6446 proto_item_append_text(len_ti, " (reserved)");
6447 expert_add_info(pinfo, len_ti, &ei_oran_st4_zero_len_cmd);
6448 }
6449 else {
6450 proto_item_append_text(len_ti, " (%u bytes)", st4_cmd_len*4);
6451 }
6452 offset += 2;
6453
6454 /* numSlots */
6455 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);
6456 if (num_slots == 0) {
6457 proto_item_append_text(slots_ti, " (until changed)");
6458 }
6459 offset += 1;
6460
6461 /* ackNackReqId */
6462 proto_item *ack_nack_req_id_ti;
6463 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);
6464 offset += 2;
6465 if (ack_nack_req_id == 0) {
6466 proto_item_append_text(ack_nack_req_id_ti, " (no Section type 8 response expected)");
6467 }
6468
6469 /* reserved (16 bits) */
6470 add_reserved_field(hdr_tree, hf_oran_reserved_16bits, tvb, offset, 2);
6471 offset += 2;
6472
6473 /* Set common header summary */
6474 proto_item_append_text(hdr_ti, " (cmd=%s, len=%u, slots=%u, ackNackReqId=%u)",
6475 rval_to_str_const(st4_cmd_type, st4_cmd_type_vals, "Unknown"),
6476 st4_cmd_len, num_slots, ack_nack_req_id);
6477
6478 col_append_fstr(pinfo->cinfo, COL_INFO, " (%s)",
6479 rval_to_str_const(st4_cmd_type, st4_cmd_type_vals, "Unknown"));
6480
6481
6482 /* Subtree for this command body */
6483 proto_item *command_ti = proto_tree_add_string_format(section_tree, hf_oran_st4_cmd,
6484 tvb, offset, 0, "",
6485 "Type 4 Command (%s)", rval_to_str_const(st4_cmd_type, st4_cmd_type_vals, "Unknown"));
6486 proto_tree *command_tree = proto_item_add_subtree(command_ti, ett_oran_st4_cmd);
6487
6488 unsigned command_start_offset = offset;
6489
6490 /* Check fields compatible with chosen command. */
6491 if (st4_cmd_type==1) {
6492 if (num_slots != 0) {
6493 /* "the value of numSlots should be set to zero for this command type" */
6494 expert_add_info_format(pinfo, slots_ti, &ei_oran_numslots_not_zero,
6495 "numSlots should be zero for ST4 command 1 - found %u",
6496 num_slots);
6497 }
6498 }
6499
6500 if (st4_cmd_type==3 || st4_cmd_type==4) {
6501 if (startSymbolId != 0) {
6502 /* "expected reception window for the commands is the symbol zero reception window" */
6503 expert_add_info_format(pinfo, ssid_ti, &ei_oran_start_symbol_id_not_zero,
6504 "startSymbolId should be zero for ST4 commands 3&4 - found %u",
6505 startSymbolId);
6506 }
6507 }
6508
6509 /* Add format for this command */
6510 switch (st4_cmd_type) {
6511 case 1: /* TIME_DOMAIN_BEAM_CONFIG */
6512 {
6513 bool_Bool disable_tdbfns;
6514 uint32_t bfwcomphdr_iq_width, bfwcomphdr_comp_meth;
6515
6516 /* Hidden filter for bf */
6517 proto_item *bf_ti = proto_tree_add_item(command_tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
6518 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
6519
6520 /* reserved (2 bits) */
6521 add_reserved_field(command_tree, hf_oran_reserved_2bits, tvb, offset, 1);
6522 /* symbolMask (14 bits) */
6523 uint32_t symbol_mask;
6524 proto_item *symbol_mask_ti;
6525 offset = dissect_symbolmask(tvb, command_tree, offset, &symbol_mask, &symbol_mask_ti);
6526 /* 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 */
6527 /* lsb is symbol 0 */
6528 for (unsigned s=0; s < 14; s++) {
6529 if ((startSymbolId & (1 << s)) && (startSymbolId > s)) {
6530 proto_item_append_text(symbol_mask_ti, " (startSymbolId is %u, so some lower symbol bits ignored!)", startSymbolId);
6531 expert_add_info(pinfo, symbol_mask_ti, &ei_oran_start_symbol_id_bits_ignored);
6532 break;
6533 }
6534 }
6535
6536 /* disableTDBFNs (1 bit) */
6537 proto_tree_add_item_ret_boolean(command_tree, hf_oran_disable_tdbfns, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &disable_tdbfns);
6538
6539 /* tdBeamNum (15 bits) */
6540 proto_tree_add_item(command_tree, hf_oran_td_beam_num, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6541 offset += 2;
6542
6543 /* bfwCompHdr (2 subheaders - bfwIqWidth and bfwCompMeth)*/
6544 offset = dissect_bfwCompHdr(tvb, command_tree, offset,
6545 &bfwcomphdr_iq_width, &bfwcomphdr_comp_meth, &comp_meth_ti);
6546 /* reserved (3 bytes) */
6547 proto_tree_add_bits_item(command_tree, hf_oran_reserved, tvb, offset*8, 24, ENC_BIG_ENDIAN0x00000000);
6548 offset += 3;
6549
6550 if (disable_tdbfns) {
6551 /* No beamnum information to show so get out. */
6552 break;
6553 }
6554
6555 /* Read beam entries until reach end of command length */
6556 while ((offset - command_start_offset) < (st4_cmd_len * 4)) {
6557
6558 /* disableTDBFWs (1 bit) */
6559 bool_Bool disable_tdbfws;
6560 proto_tree_add_item_ret_boolean(command_tree, hf_oran_disable_tdbfws, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &disable_tdbfws);
6561
6562 /* tdBeamNum (15 bits) */
6563 proto_tree_add_item(command_tree, hf_oran_td_beam_num, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6564 offset += 2;
6565
6566 /* Showing BFWs? */
6567 if (!disable_tdbfws) {
6568
6569 /* bfwCompParam */
6570 unsigned exponent = 0;
6571 bool_Bool supported = false0;
6572 unsigned num_trx_entries;
6573 uint16_t *trx_entries;
6574 offset = dissect_bfwCompParam(tvb, command_tree, pinfo, offset, comp_meth_ti,
6575 &bfwcomphdr_comp_meth, &exponent, &supported,
6576 &num_trx_entries, &trx_entries);
6577
6578 /* Antenna count from preference */
6579 unsigned num_trx = pref_num_bf_antennas;
6580 int bit_offset = offset*8;
6581
6582 for (unsigned trx=0; trx < num_trx; trx++) {
6583 /* Create antenna subtree */
6584 int bfw_offset = bit_offset / 8;
6585 proto_item *bfw_ti = proto_tree_add_string_format(command_tree, hf_oran_bfw,
6586 tvb, bfw_offset, 0, "", "TRX %3u: (", trx);
6587 proto_tree *bfw_tree = proto_item_add_subtree(bfw_ti, ett_oran_bfw);
6588
6589 /* I value */
6590 /* Get bits, and convert to float. */
6591 uint32_t bits = tvb_get_bits32(tvb, bit_offset, bfwcomphdr_iq_width, ENC_BIG_ENDIAN0x00000000);
6592 float value = decompress_value(bits, bfwcomphdr_comp_meth, bfwcomphdr_iq_width, exponent, NULL((void*)0) /* no ModCompr*/, 0 /* RE */);
6593 /* Add to tree. */
6594 proto_tree_add_float(bfw_tree, hf_oran_bfw_i, tvb, bit_offset/8,
6595 (bfwcomphdr_iq_width+7)/8, value);
6596 bit_offset += bfwcomphdr_iq_width;
6597 proto_item_append_text(bfw_ti, "I=%f ", value);
6598
6599 /* Leave a gap between I and Q values */
6600 proto_item_append_text(bfw_ti, " ");
6601
6602 /* Q value */
6603 /* Get bits, and convert to float. */
6604 bits = tvb_get_bits32(tvb, bit_offset, bfwcomphdr_iq_width, ENC_BIG_ENDIAN0x00000000);
6605 value = decompress_value(bits, bfwcomphdr_comp_meth, bfwcomphdr_iq_width, exponent, NULL((void*)0) /* no ModCompr*/, 0 /* RE */);
6606 /* Add to tree. */
6607 proto_tree_add_float(bfw_tree, hf_oran_bfw_q, tvb, bit_offset/8,
6608 (bfwcomphdr_iq_width+7)/8, value);
6609 bit_offset += bfwcomphdr_iq_width;
6610 proto_item_append_text(bfw_ti, "Q=%f", value);
6611
6612 proto_item_append_text(bfw_ti, ")");
6613 proto_item_set_len(bfw_ti, (bit_offset+7)/8 - bfw_offset);
6614 }
6615 /* Need to round to next byte */
6616 offset = (bit_offset+7)/8;
6617 }
6618 }
6619 break;
6620 }
6621 case 2: /* TDD_CONFIG_PATTERN */
6622 /* reserved (2 bits) */
6623 add_reserved_field(command_tree, hf_oran_reserved_2bits, tvb, offset, 1);
6624 /* dirPattern (14 bits) */
6625 proto_tree_add_item(command_tree, hf_oran_dir_pattern, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6626 offset += 2;
6627
6628 /* reserved (2 bits) */
6629 add_reserved_field(command_tree, hf_oran_reserved_2bits, tvb, offset, 1);
6630 /* guardPattern (14 bits) */
6631 proto_tree_add_item(command_tree, hf_oran_guard_pattern, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6632 offset += 2;
6633 break;
6634
6635 case 3: /* TRX_CONTROL */
6636 case 5: /* TRX_CONTROL_BIDIR */
6637 {
6638 /* Only allowed cmdScope is ARRAY-COMMAND */
6639 if (cmd_scope != 0) {
6640 expert_add_info(pinfo, command_tree, &ei_oran_trx_control_cmd_scope);
6641 }
6642
6643 /* reserved (2 bits) */
6644 add_reserved_field(command_tree, hf_oran_reserved_2bits, tvb, offset, 1);
6645 /* log2MaskBits (4 bits) */
6646 unsigned log2maskbits;
6647 proto_tree_add_item_ret_uint(command_tree, hf_oran_log2maskbits, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &log2maskbits);
6648 /* sleepMode (2 bits) */
6649 uint32_t sleep_mode;
6650 proto_tree_add_item_ret_uint(command_tree, hf_oran_sleepmode_trx, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &sleep_mode);
6651 offset += 1;
6652
6653 /* reserved (4 bits) */
6654 add_reserved_field(command_tree, hf_oran_reserved_4bits, tvb, offset, 1);
6655 /* numSlotsExt (20 bits) */
6656 uint32_t num_slots_ext;
6657 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);
6658 if (num_slots==0 && num_slots_ext==0) {
6659 proto_item_append_text(num_slots_ext_ti, " (undefined sleep period)");
6660 }
6661 else {
6662 /* Time should be rounded up according to SCS */
6663 float total = (float)(num_slots + num_slots_ext);
6664 /* From table 7.5.2.13-3 */
6665 const float slot_length_by_scs[16] = { 1000, 500, 250, 125, 62.5, 31.25,
6666 0, 0, 0, 0, 0, 0, /* reserved */
6667 1000, 1000, 1000, 1000 };
6668 float slot_length = slot_length_by_scs[scs];
6669 /* Only using valid SCS. TODO: is this test ok? */
6670 if (slot_length != 0) {
6671 /* Round up to next slot */
6672 total = ((int)(total / slot_length) + 1) * slot_length;
6673 proto_item_append_text(num_slots_ext_ti, " (defined sleep period of %f us)", total);
6674 }
6675 }
6676 offset += 3;
6677
6678 /* reserved (2 bits) */
6679 add_reserved_field(command_tree, hf_oran_reserved_2bits, tvb, offset, 1);
6680
6681 /* symbolMask (14 bits) */
6682 uint32_t symbol_mask;
6683 proto_item *sm_ti;
6684 offset = dissect_symbolmask(tvb, command_tree, offset, &symbol_mask, &sm_ti);
6685 if (symbol_mask == 0x0) {
6686 proto_item_append_text(sm_ti, " (wake)");
6687 col_append_str(pinfo->cinfo, COL_INFO, " (wake)");
6688 }
6689 else if (symbol_mask == 0x3fff) {
6690 proto_item_append_text(sm_ti, " (sleep)");
6691 col_append_str(pinfo->cinfo, COL_INFO, " (sleep)");
6692 }
6693 else {
6694 expert_add_info_format(pinfo, sm_ti, &ei_oran_bad_symbolmask,
6695 "For non-zero sleepMode (%u), symbolMask should be 0x0 or 0x3fff - found 0x%05x",
6696 sleep_mode, symbol_mask);
6697 }
6698 offset += 2;
6699
6700 /* antMask (16-2048 bits). Size is lookup from log2MaskBits enum.. */
6701 unsigned antmask_length = 2;
6702 if (log2maskbits >= 4) {
6703 antmask_length = (1 << log2maskbits) / 8;
6704 }
6705 proto_item *ant_mask_ti = proto_tree_add_item(command_tree, hf_oran_antMask_trx_control, tvb, offset, antmask_length, ENC_NA0x00000000);
6706 /* show count */
6707 unsigned antenna_count = 0;
6708 for (unsigned b=0; b < antmask_length; b++) {
6709 uint8_t byte = tvb_get_uint8(tvb, offset+b);
6710 for (unsigned bit=0; bit < 8; bit++) {
6711 if ((1 << bit) & byte) {
6712 antenna_count++;
6713 }
6714 }
6715 }
6716 proto_item_append_text(ant_mask_ti, " (%u antennas)", antenna_count);
6717 offset += antmask_length;
6718
6719 /* Pad to next 4-byte boundary */
6720 offset = WS_ROUNDUP_4(offset)(((offset) + ((unsigned)(4U-1U))) & (~((unsigned)(4U-1U))
))
;
6721 break;
6722 }
6723
6724 case 4: /* ASM (advanced sleep mode) */
6725 /* reserved (2+4=6 bits) */
6726 add_reserved_field(command_tree, hf_oran_reserved_6bits, tvb, offset, 1);
6727 /* sleepMode (2 bits) */
6728 uint32_t sleep_mode;
6729 proto_tree_add_item_ret_uint(command_tree, hf_oran_sleepmode_asm, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &sleep_mode);
6730 offset += 1;
6731
6732 /* reserved (4 bits) */
6733 add_reserved_field(command_tree, hf_oran_reserved_4bits, tvb, offset, 1);
6734 /* numSlotsExt (20 bits) */
6735 proto_tree_add_item(command_tree, hf_oran_num_slots_ext, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6736 offset += 3;
6737
6738 /* reserved (2 bits) */
6739 add_reserved_field(command_tree, hf_oran_reserved_2bits, tvb, offset, 1);
6740 /* symbolMask (14 bits) */
6741 uint32_t symbol_mask;
6742 proto_item *sm_ti;
6743 offset = dissect_symbolmask(tvb, command_tree, offset, &symbol_mask, &sm_ti);
6744 if (symbol_mask == 0x0) {
6745 proto_item_append_text(sm_ti, " (wake)");
6746 col_append_str(pinfo->cinfo, COL_INFO, " (wake)");
6747 }
6748 else if (symbol_mask == 0x3fff) {
6749 proto_item_append_text(sm_ti, " (sleep)");
6750 col_append_str(pinfo->cinfo, COL_INFO, " (sleep)");
6751 }
6752 else {
6753 expert_add_info_format(pinfo, sm_ti, &ei_oran_bad_symbolmask,
6754 "For non-zero sleepMode (%u), symbolMask should be 0x0 or 0x3fff - found 0x%05x",
6755 sleep_mode, symbol_mask);
6756 }
6757 offset += 2;
6758
6759 /* reserved (2 bytes) */
6760 add_reserved_field(command_tree, hf_oran_reserved_16bits, tvb, offset, 2);
6761 offset += 2;
6762 break;
6763
6764 default:
6765 /* Error! */
6766 expert_add_info_format(pinfo, len_ti, &ei_oran_st4_unknown_cmd,
6767 "Dissected ST4 command (%u) not recognised",
6768 st4_cmd_type);
6769 break;
6770 }
6771
6772 /* Check apparent size of padding (0-3 bytes ok) */
6773 long padding_remaining = command_start_offset + (st4_cmd_len * 4) - offset;
6774 if (padding_remaining > 3) {
6775 expert_add_info_format(pinfo, len_ti, &ei_oran_st4_wrong_len_cmd,
6776 "Dissected ST4 command does not match signalled st4CmdLen - set to %u (%u bytes) but dissected %u bytes",
6777 st4_cmd_len, st4_cmd_len*4, offset-command_start_offset);
6778 }
6779
6780 /* Advance by signalled length (needs to be aligned on 4-byte boundary) */
6781 offset = command_start_offset + (st4_cmd_len * 4);
6782
6783 /* Set end of command tree */
6784 proto_item_set_end(command_ti, tvb, offset);
6785
6786 if (ack_nack_req_id != 0 && state && state->ack_nack_requests) {
6787 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
6788 /* Add this request into conversation state on first pass */
6789 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)))
;
6790 request_details->request_frame_number = pinfo->num;
6791 request_details->request_frame_time = pinfo->abs_ts;
6792 request_details->requestType = ST4Cmd1+st4_cmd_type-1;
6793
6794 wmem_tree_insert32(state->ack_nack_requests,
6795 ack_nack_req_id,
6796 request_details);
6797 }
6798 else {
6799 /* On later passes, try to link forward to ST8 response */
6800 ack_nack_request_t *response = wmem_tree_lookup32(state->ack_nack_requests,
6801 ack_nack_req_id);
6802 if (response) {
6803 show_link_to_acknack_response(section_tree, tvb, pinfo, response);
6804 }
6805 }
6806 }
6807 }
6808 }
6809 /* LAA doesn't have sections either.. */
6810 else if (sectionType == SEC_C_LAA) { /* Section Type 7 */
6811 /* 7.2.5 Table 6.4-6 */
6812 unsigned mcot;
6813 proto_item *mcot_ti;
6814
6815 /* laaMsgType */
6816 uint32_t laa_msg_type;
6817 proto_item *laa_msg_type_ti;
6818 laa_msg_type_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_laaMsgType, tvb, offset, 1, ENC_NA0x00000000, &laa_msg_type);
6819 /* laaMsgLen */
6820 uint32_t laa_msg_len;
6821 proto_item *len_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_laaMsgLen, tvb, offset, 1, ENC_NA0x00000000, &laa_msg_len);
6822 proto_item_append_text(len_ti, " (%u bytes)", 4*laa_msg_len);
6823 if (laa_msg_len == 0) {
6824 proto_item_append_text(len_ti, " (reserved)");
6825 }
6826 offset += 1;
6827
6828 int payload_offset = offset;
6829
6830 /* Payload */
6831 switch (laa_msg_type) {
6832 case 0:
6833 /* LBT_PDSCH_REQ */
6834 /* lbtHandle (16 bits) */
6835 proto_tree_add_item(section_tree, hf_oran_lbtHandle, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6836 offset += 2;
6837 /* lbtOffset (10 bits) */
6838 proto_tree_add_item(section_tree, hf_oran_lbtOffset, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6839 offset += 1;
6840 /* lbtMode (2 bits) */
6841 proto_tree_add_bits_item(section_tree, hf_oran_lbtMode, tvb, offset*8+2, 2, ENC_BIG_ENDIAN0x00000000);
6842 /* reserved (1 bit) */
6843 add_reserved_field(section_tree, hf_oran_reserved_bit4, tvb, offset, 1);
6844 /* lbtDeferFactor (3 bits) */
6845 proto_tree_add_item(section_tree, hf_oran_lbtDeferFactor, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6846 offset += 1;
6847 /* lbtBackoffCounter (10 bits) */
6848 proto_tree_add_item(section_tree, hf_oran_lbtBackoffCounter, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6849 offset += 1;
6850 /* MCOT (4 bits) */
6851 mcot_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_MCOT, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &mcot);
6852 if (mcot<1 || mcot>10) {
6853 proto_item_append_text(mcot_ti, " (should be in range 1-10!)");
6854 expert_add_info_format(pinfo, mcot_ti, &ei_oran_mcot_out_of_range,
6855 "MCOT seen with value %u (must be 1-10)", mcot);
6856
6857 }
6858 /* reserved (10 bits) */
6859 proto_tree_add_bits_item(section_tree, hf_oran_reserved, tvb, (offset*8)+6, 10, ENC_BIG_ENDIAN0x00000000);
6860 break;
6861 case 1:
6862 /* LBT_DRS_REQ */
6863 /* lbtHandle (16 bits) */
6864 proto_tree_add_item(section_tree, hf_oran_lbtHandle, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6865 offset += 2;
6866 /* lbtOffset (10 bits) */
6867 proto_tree_add_item(section_tree, hf_oran_lbtOffset, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6868 offset += 1;
6869 /* lbtMode (2 bits) */
6870 proto_tree_add_bits_item(section_tree, hf_oran_lbtMode, tvb, offset*8+2, 2, ENC_BIG_ENDIAN0x00000000);
6871 /* reserved (28 bits) */
6872 proto_tree_add_bits_item(section_tree, hf_oran_reserved, tvb, (offset*8)+4, 28, ENC_BIG_ENDIAN0x00000000);
6873 break;
6874 case 2:
6875 /* LBT_PDSCH_RSP */
6876 /* lbtHandle (16 bits) */
6877 proto_tree_add_item(section_tree, hf_oran_lbtHandle, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6878 offset += 2;
6879 /* lbtPdschRes (2 bits) */
6880 proto_tree_add_item(section_tree, hf_oran_lbtPdschRes, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6881 /* inParSF (1 bit) */
6882 proto_tree_add_item(section_tree, hf_oran_initialPartialSF, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6883 /* sfStatus (1 bit) */
6884 proto_tree_add_item(section_tree, hf_oran_sfStatus, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6885 /* sfnSf (12 bits) */
6886 proto_tree_add_item(section_tree, hf_oran_sfnSfEnd, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6887 offset += 2;
6888 /* reserved (24 bits) */
6889 proto_tree_add_bits_item(section_tree, hf_oran_reserved, tvb, (offset*8), 24, ENC_BIG_ENDIAN0x00000000);
6890 break;
6891 case 3:
6892 /* LBT_DRS_RSP */
6893 /* lbtHandle (16 bits) */
6894 proto_tree_add_item(section_tree, hf_oran_lbtHandle, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6895 offset += 2;
6896 /* lbtDrsRes (1 bit) */
6897 proto_tree_add_item(section_tree, hf_oran_lbtDrsRes, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6898 /* reserved (7 bits) */
6899 add_reserved_field(section_tree, hf_oran_reserved_last_7bits, tvb, offset, 1);
6900 break;
6901 case 4:
6902 /* LBT_Buffer_Error */
6903 /* lbtHandle (16 bits) */
6904 proto_tree_add_item(section_tree, hf_oran_lbtHandle, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6905 offset += 2;
6906 /* lbtBufErr (1 bit) */
6907 proto_tree_add_item(section_tree, hf_oran_lbtBufErr, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6908 /* reserved (7 bits) */
6909 add_reserved_field(section_tree, hf_oran_reserved_last_7bits, tvb, offset, 1);
6910 break;
6911 case 5:
6912 /* LBT_CWCONFIG_REQ */
6913 /* lbtHandle (16 bits) */
6914 proto_tree_add_item(section_tree, hf_oran_lbtHandle, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6915 offset += 2;
6916 /* lbtCWConfig_H (8 bits) */
6917 proto_tree_add_item(section_tree, hf_oran_lbtCWConfig_H, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6918 offset += 1;
6919 /* lbtCWConfig_T (8 bits) */
6920 proto_tree_add_item(section_tree, hf_oran_lbtCWConfig_T, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6921 offset += 1;
6922 /* lbtMode (2 bits) */
6923 proto_tree_add_bits_item(section_tree, hf_oran_lbtMode, tvb, offset*8, 2, ENC_BIG_ENDIAN0x00000000);
6924 /* lbtTrafficClass (3 bits) */
6925 proto_tree_add_item(section_tree, hf_oran_lbtTrafficClass, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6926 /* reserved (19 bits) */
6927 proto_tree_add_bits_item(section_tree, hf_oran_reserved, tvb, (offset*8)+5, 19, ENC_BIG_ENDIAN0x00000000);
6928 break;
6929 case 6:
6930 /* LBT_CWCONFIG_RSP */
6931 /* lbtHandle (16 bits) */
6932 proto_tree_add_item(section_tree, hf_oran_lbtHandle, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6933 offset += 2;
6934 /* lbtCWR_Rst (1 bit) */
6935 proto_tree_add_item(section_tree, hf_oran_lbtCWR_Rst, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6936 /* reserved (7 bits) */
6937 add_reserved_field(section_tree, hf_oran_reserved_last_7bits, tvb, offset, 1);
6938 break;
6939
6940 default:
6941 /* Unhandled! */
6942 expert_add_info_format(pinfo, laa_msg_type_ti, &ei_oran_laa_msg_type_unsupported,
6943 "laaMsgType %u not supported by dissector",
6944 laa_msg_type);
6945
6946 break;
6947 }
6948 /* For now just skip indicated length of bytes */
6949 offset = payload_offset + 4*(laa_msg_len+1);
6950 }
6951
6952
6953 /* Dissect each C section */
6954 for (uint32_t i = 0; i < nSections; ++i) {
6955 tvbuff_t *section_tvb = tvb_new_subset_remaining(tvb, offset);
6956 offset += dissect_oran_c_section(section_tvb, oran_tree, pinfo, state, sectionType, tap_info,
6957 protocol_item,
6958 subframeId, frameId, slotId, startSymbolId,
6959 bit_width, ci_comp_method, ci_comp_opt,
6960 num_sinr_per_prb);
6961 }
6962
6963 /* Expert error if we are short of tvb by > 3 bytes */
6964 if (tvb_reported_length_remaining(tvb, offset) > 3) {
6965 expert_add_info_format(pinfo, protocol_item, &ei_oran_frame_length,
6966 "%u bytes remain at end of frame - should be 0-3",
6967 tvb_reported_length_remaining(tvb, offset));
6968 }
6969
6970 if (PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited) && result) {
6971 /* Show list of frames that have corresponding U-plane data */
6972 wmem_list_frame_t *list_frame;
6973 for (list_frame = wmem_list_head(result->u_plane_frames); list_frame != NULL((void*)0); list_frame = wmem_list_frame_next(list_frame)) {
6974 corresponding_uplane_frame *frame = wmem_list_frame_data(list_frame);
6975 proto_item *uplane_frame_ti = proto_tree_add_uint(oran_tree, hf_oran_corresponding_uplane_frame, tvb, 0, 0,
6976 frame->frame_number);
6977 proto_item_append_text(uplane_frame_ti, " sectionId:%2u symbol:%2u PRBs %3u->%3u (in %uus)",
6978 frame->sectionId, frame->symbol, frame->startPrbu, frame->startPrbu+frame->numPrbu-1, frame->gap_in_usecs);
6979 proto_item_set_generated(uplane_frame_ti);
6980 }
6981 /* Also show total number of corresponding u-plane frames */
6982 proto_item *uplane_frame_count_ti = proto_tree_add_uint(oran_tree, hf_oran_corresponding_uplane_frames_total, tvb, 0, 0,
6983 wmem_list_count(result->u_plane_frames));
6984 proto_item_set_generated(uplane_frame_count_ti);
6985 }
6986
6987 return tvb_captured_length(tvb);
6988}
6989
6990static int dissect_oran_u_re(tvbuff_t *tvb, proto_tree *tree,
6991 unsigned sample_number, int samples_offset,
6992 oran_tap_info *tap_info,
6993 unsigned sample_bit_width,
6994 int comp_meth,
6995 uint32_t exponent,
6996 section_mod_compr_config_t *mod_compr_params,
6997 uint8_t re)
6998{
6999 /* I */
7000 unsigned i_bits = tvb_get_bits32(tvb, samples_offset, sample_bit_width, ENC_BIG_ENDIAN0x00000000);
7001 float i_value = decompress_value(i_bits, comp_meth, sample_bit_width, exponent, mod_compr_params, re);
7002 unsigned sample_len_in_bytes = ((samples_offset%8)+sample_bit_width+7)/8;
7003 proto_item *i_ti = proto_tree_add_float(tree, hf_oran_iSample, tvb, samples_offset/8, sample_len_in_bytes, i_value);
7004 proto_item_set_text(i_ti, "iSample: % 0.7f 0x%04x (RE-%2u in the PRB)", i_value, i_bits, sample_number);
7005 samples_offset += sample_bit_width;
7006 /* Q */
7007 unsigned q_bits = tvb_get_bits32(tvb, samples_offset, sample_bit_width, ENC_BIG_ENDIAN0x00000000);
7008 float q_value = decompress_value(q_bits, comp_meth, sample_bit_width, exponent, mod_compr_params, re);
7009 sample_len_in_bytes = ((samples_offset%8)+sample_bit_width+7)/8;
7010 proto_item *q_ti = proto_tree_add_float(tree, hf_oran_qSample, tvb, samples_offset/8, sample_len_in_bytes, q_value);
7011 proto_item_set_text(q_ti, "qSample: % 0.7f 0x%04x (RE-%2u in the PRB)", q_value, q_bits, sample_number);
7012 samples_offset += sample_bit_width;
7013
7014 /* Update RE stats */
7015 tap_info->num_res++;
7016 /* if (i_value == 0.0 && q_value == 0.0) { */
7017 /* TODO: is just checking bits from frame good enough - assuming this always corresponds to a zero value? */
7018 if (i_bits == 0 && q_bits == 0) {
7019 tap_info->num_res_zero++;
7020 }
7021 else {
7022 tap_info->non_zero_re_in_current_prb = true1;
7023 }
7024 return samples_offset;
7025}
7026
7027
7028static bool_Bool udcomplen_appears_present(bool_Bool udcomphdr_present, tvbuff_t *tvb, int offset)
7029{
7030 if (!udcomplen_heuristic_result_set) {
7031 /* All sections will start the same way */
7032 unsigned int section_bytes_before_field = (udcomphdr_present) ? 6 : 4;
7033
7034 /* Move offset back to the start of the section */
7035 offset -= section_bytes_before_field;
7036
7037 do {
7038 /* This field appears several bytes into the U-plane section */
7039 uint32_t length_remaining = tvb_reported_length_remaining(tvb, offset);
7040 /* Are there enough bytes to still read the length field? */
7041 if (section_bytes_before_field+2 > length_remaining) {
7042 udcomplen_heuristic_result = false0;
7043 udcomplen_heuristic_result_set = true1;
7044 break;
7045 }
7046
7047 /* Read the length field */
7048 uint16_t udcomplen = tvb_get_ntohs(tvb, offset+section_bytes_before_field);
7049
7050 /* Is this less than a valid section? Realistic minimal section will be bigger than this..
7051 * Could take into account numPrbU, etc */
7052 if (udcomplen < section_bytes_before_field+2) {
7053 udcomplen_heuristic_result = false0;
7054 udcomplen_heuristic_result_set = true1;
7055 break;
7056 }
7057
7058 /* Does this section fit into the frame? */
7059 if (udcomplen > length_remaining) {
7060 udcomplen_heuristic_result = false0;
7061 udcomplen_heuristic_result_set = true1;
7062 break;
7063 }
7064
7065 /* Move past this section */
7066 offset += udcomplen;
7067
7068 /* Are we at the end of the frame? */
7069 /* TODO: if frame is less than 60 bytes, there may be > 4 bytes, likely zeros.. */
7070 if (tvb_reported_length_remaining(tvb, offset) < 4) {
7071 udcomplen_heuristic_result = true1;
7072 udcomplen_heuristic_result_set = true1;
7073 }
7074 } while (!udcomplen_heuristic_result_set);
7075 }
7076 return udcomplen_heuristic_result;
7077}
7078
7079static bool_Bool at_udcomphdr(tvbuff_t *tvb, int offset)
7080{
7081 if (tvb_captured_length_remaining(tvb, offset) < 2) {
7082 return false0;
7083 }
7084 uint8_t first_byte = tvb_get_uint8(tvb, offset);
7085 uint8_t reserved_byte = tvb_get_uint8(tvb, offset+1);
7086
7087 /* - iq width could be anything, though unlikely to be signalled as (say) < 1-3? */
7088 /* - meth should be 0-8 */
7089 /* - reserved byte should be 0 */
7090 return (((first_byte & 0x0f) <= MOD_COMPR_AND_SELECTIVE_RE_WITH_MASKS8) && (reserved_byte == 0));
7091}
7092
7093static bool_Bool udcomphdr_appears_present(flow_state_t *flow, uint32_t direction, tvbuff_t *tvb, int offset)
7094{
7095 /* Should really not happen, but guard against this anyway. */
7096 if (flow == NULL((void*)0)) {
7097 /* No state to update. */
7098 return false0;
7099 }
7100
7101 if (direction == DIR_UPLINK0) {
7102 if (flow->udcomphdrUplink_heuristic_result_set) {
7103 /* Return cached value */
7104 return flow->udcomphdrUplink_heuristic_result;
7105 }
7106 else {
7107 /* Work it out, and save answer for next time */
7108 flow->udcomphdrUplink_heuristic_result_set = true1;
7109 flow->udcomphdrUplink_heuristic_result = at_udcomphdr(tvb, offset);
7110 return flow->udcomphdrUplink_heuristic_result;
7111 }
7112 }
7113 else {
7114 /* Downlink */
7115 if (flow->udcomphdrDownlink_heuristic_result_set) {
7116 /* Return cached value */
7117 return flow->udcomphdrDownlink_heuristic_result;
7118 }
7119 else {
7120 /* Work it out, and save answer for next time */
7121 flow->udcomphdrDownlink_heuristic_result_set = true1;
7122 flow->udcomphdrDownlink_heuristic_result = at_udcomphdr(tvb, offset);
7123 return flow->udcomphdrDownlink_heuristic_result;
7124 }
7125 }
7126}
7127
7128static bool_Bool copy_section_entry(const void *key, void* value, void *userdata)
7129{
7130 /* Cast parameters to their types */
7131 uint32_t sectionId = GPOINTER_TO_UINT(key)((guint) (gulong) (key));
7132 expected_section_data_t *result_value = (expected_section_data_t *)value;
7133 wmem_tree_t *result_tree = (wmem_tree_t*)userdata;
7134
7135 /* Deep copy of section data */
7136 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)))
;
7137 *copy = *result_value;
7138
7139 /* Add into result tree */
7140 wmem_tree_insert32(result_tree, sectionId, copy);
7141
7142 return false0;
7143}
7144
7145/* User plane dissector (section 8) */
7146static int
7147dissect_oran_u(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
7148 oran_tap_info *tap_info, void *data _U___attribute__((unused)))
7149{
7150 /* Hidden filter for plane */
7151 proto_item *plane_ti = proto_tree_add_item(tree, hf_oran_uplane, tvb, 0, 0, ENC_NA0x00000000);
7152 PROTO_ITEM_SET_HIDDEN(plane_ti)proto_item_set_hidden((plane_ti));
7153
7154 /* Set up structures needed to add the protocol subtree and manage it */
7155 unsigned offset = 0;
7156
7157 col_set_str(pinfo->cinfo, COL_PROTOCOL, "O-RAN-FH-U");
7158 col_set_str(pinfo->cinfo, COL_INFO, "U-Plane");
7159
7160 tap_info->userplane = true1;
7161
7162 /* Create display subtree for the protocol */
7163 proto_item *protocol_item = proto_tree_add_item(tree, proto_oran, tvb, 0, -1, ENC_NA0x00000000);
7164 proto_item_append_text(protocol_item, "-U");
7165 proto_tree *oran_tree = proto_item_add_subtree(protocol_item, ett_oran);
7166
7167 /* Transport header */
7168 /* Real-time control data / IQ data transfer message series identifier */
7169 uint16_t eAxC;
7170 addPcOrRtcid(tvb, oran_tree, &offset, hf_oran_ecpri_pcid, &eAxC, tap_info);
7171 tap_info->eaxc = eAxC;
7172
7173 /* Update/report status of conversation */
7174 uint32_t key = make_flow_key(pinfo, eAxC, ORAN_U_PLANE1, false0);
7175 flow_state_t* state = (flow_state_t*)wmem_tree_lookup32(flow_states_table, key);
7176
7177 flow_result_t *result = NULL((void*)0);
7178
7179 /* Message identifier */
7180 proto_item *seqIdItem;
7181 uint32_t seqId, subSeqId, e;
7182 offset = addSeqid(tvb, oran_tree, offset, ORAN_U_PLANE1, &seqId, &seqIdItem, pinfo, &subSeqId, &e);
7183
7184 /* Common header for time reference */
7185 proto_item *timingHeader = proto_tree_add_string_format(oran_tree, hf_oran_timing_header,
7186 tvb, offset, 4, "", "Timing Header (");
7187 proto_tree *timing_header_tree = proto_item_add_subtree(timingHeader, ett_oran_u_timing);
7188
7189 /* dataDirection */
7190 uint32_t direction;
7191 proto_tree_add_item_ret_uint(timing_header_tree, hf_oran_data_direction, tvb, offset, 1, ENC_NA0x00000000, &direction);
7192 tap_info->uplink = (direction==0);
1
Assuming 'direction' is not equal to 0
7193 /* payloadVersion */
7194 dissect_payload_version(timing_header_tree, tvb, pinfo, offset);
7195 /* filterIndex */
7196 proto_tree_add_item(timing_header_tree, hf_oran_filter_index, tvb, offset, 1, ENC_NA0x00000000);
7197 offset += 1;
7198
7199 int ref_a_offset = offset;
7200
7201 /* frameId */
7202 uint32_t frameId = 0;
7203 proto_tree_add_item_ret_uint(timing_header_tree, hf_oran_frame_id, tvb, offset, 1, ENC_NA0x00000000, &frameId);
7204 tap_info->frame = frameId;
7205 offset += 1;
7206
7207 /* subframeId */
7208 uint32_t subframeId = 0;
7209 proto_tree_add_item_ret_uint(timing_header_tree, hf_oran_subframe_id, tvb, offset, 1, ENC_NA0x00000000, &subframeId);
7210 /* slotId */
7211 uint32_t slotId = 0;
7212 proto_tree_add_item_ret_uint(timing_header_tree, hf_oran_slot_id, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &slotId);
7213 tap_info->slot = slotId;
7214 offset++;
7215 /* symbolId */
7216 uint32_t symbolId = 0;
7217 proto_tree_add_item_ret_uint(timing_header_tree, hf_oran_symbolId, tvb, offset, 1, ENC_NA0x00000000, &symbolId);
7218 offset++;
7219
7220 char id[16];
7221 snprintf(id, 16, "%u-%u-%u-%u", frameId, subframeId, slotId, symbolId);
7222 proto_item *pi = proto_tree_add_string(timing_header_tree, hf_oran_refa, tvb, ref_a_offset, 3, id);
7223 proto_item_set_generated(pi);
7224
7225 proto_item_append_text(timingHeader, "%s, frameId: %d, subframeId: %d, slotId: %d, symbolId: %d)",
7226 val_to_str_const(direction, data_direction_vals, "Unknown"), frameId, subframeId, slotId, symbolId);
7227
7228 unsigned sample_bit_width;
7229 unsigned compression;
7230 int includeUdCompHeader;
7231
7232 /* Also lookup C-PLANE state (sent in opposite direction for UL) so may check current compression settings */
7233 uint32_t cplane_key = make_flow_key(pinfo, eAxC, ORAN_C_PLANE0, direction
1.1
'direction' is not equal to 0
== 0);
7234 flow_state_t* cplane_state = (flow_state_t*)wmem_tree_lookup32(flow_states_table, cplane_key);
7235
7236 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
2
Assuming field 'visited' is 0
3
Taking true branch
7237 /* Create state/conversation if doesn't exist yet */
7238 if (!state) {
4
Assuming 'state' is non-null
5
Taking false branch
7239 /* Allocate new state */
7240 state = wmem_new0(wmem_file_scope(), flow_state_t)((flow_state_t*)wmem_alloc0((wmem_file_scope()), sizeof(flow_state_t
)))
;
7241 state->ack_nack_requests = wmem_tree_new(wmem_file_scope());
7242 state->expected_sections[0] = wmem_tree_new(wmem_file_scope());
7243 state->expected_sections[1] = wmem_tree_new(wmem_file_scope());
7244 wmem_tree_insert32(flow_states_table, key, state);
7245 }
7246
7247 result = wmem_new0(wmem_file_scope(), flow_result_t)((flow_result_t*)wmem_alloc0((wmem_file_scope()), sizeof(flow_result_t
)))
;
7248 result->expected_sections = wmem_tree_new(wmem_file_scope());
7249 result->u_plane_frames = wmem_list_new(wmem_file_scope());
7250
7251 wmem_tree_insert32(flow_results_table, pinfo->num, result);
7252
7253 /* Check sequence analysis status (but not if later part of radio layer fragmentation) */
7254 if (state->last_frame_seen[direction] && (subSeqId==0) && (seqId != state->next_expected_sequence_number[direction])) {
6
Assuming the condition is true
7
Assuming 'subSeqId' is not equal to 0
7255 /* Store this result */
7256 result->unexpected_seq_number = true1;
7257 result->expected_sequence_number = state->next_expected_sequence_number[direction];
7258 result->previous_frame = state->last_frame[direction];
7259 }
7260 /* Update sequence analysis state */
7261 state->last_frame[direction] = pinfo->num;
7262 state->last_frame_seen[direction] = true1;
7263 state->next_expected_sequence_number[direction] = (seqId+1) % 256;
7264 }
7265
7266 /* Show any issues associated with this frame number */
7267 result = wmem_tree_lookup32(flow_results_table, pinfo->num);
8
Value assigned to 'result'
7268 if (result) {
9
Assuming 'result' is null
7269 if (result->unexpected_seq_number) {
7270 expert_add_info_format(pinfo, seqIdItem,
7271 (direction == DIR_UPLINK0) ?
7272 &ei_oran_uplane_unexpected_sequence_number_ul :
7273 &ei_oran_uplane_unexpected_sequence_number_dl,
7274 "Sequence number %u expected, but got %u",
7275 result->expected_sequence_number, seqId);
7276 tap_info->missing_sns = (256 + seqId - result->expected_sequence_number) % 256;
7277 /* TODO: could add previous/next frame (in seqId tree?) ? */
7278 }
7279 }
7280
7281 /* Checking UL timing within current slot. Disabled if limit set to 0. */
7282 /* N.B., timing is relative to first seen frame,
7283 not some notion of the beginning of the slot from sync, offset by some timing.. */
7284 if (direction
9.1
'direction' is not equal to DIR_UPLINK
== DIR_UPLINK0 && us_allowed_for_ul_in_symbol > 0) {
7285 uint32_t timing_key = get_timing_key(frameId, subframeId, slotId, symbolId);
7286 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
7287 /* Set state on first pass */
7288 ul_timing_for_slot* timing = (ul_timing_for_slot*)wmem_tree_lookup32(ul_symbol_timing, timing_key);
7289 if (!timing) {
7290 /* Allocate new state */
7291 timing = wmem_new0(wmem_file_scope(), ul_timing_for_slot)((ul_timing_for_slot*)wmem_alloc0((wmem_file_scope()), sizeof
(ul_timing_for_slot)))
;
7292 timing->first_frame = pinfo->num;
7293 timing->first_frame_time = pinfo->abs_ts;
7294 timing->frames_seen_in_symbol = 1;
7295 timing->last_frame_in_symbol = pinfo->num;
7296 wmem_tree_insert32(ul_symbol_timing, timing_key, timing);
7297 }
7298 else {
7299 /* Update existing state */
7300 timing->frames_seen_in_symbol++;
7301 timing->last_frame_in_symbol = pinfo->num;
7302 }
7303 }
7304 else {
7305 /* Subsequent passes - look up result */
7306 ul_timing_for_slot* timing = (ul_timing_for_slot*)wmem_tree_lookup32(ul_symbol_timing, timing_key);
7307 if (timing) { /* Really shouldn't fail! */
7308 if (timing->frames_seen_in_symbol > 1) {
7309 /* Work out gap between frames (in microseconds) back to frame carrying first seen symbol */
7310 int seconds_between_packets = (int)
7311 (pinfo->abs_ts.secs - timing->first_frame_time.secs);
7312 int nseconds_between_packets =
7313 pinfo->abs_ts.nsecs - timing->first_frame_time.nsecs;
7314
7315 /* Round to nearest microsecond. */
7316 uint32_t total_gap = (seconds_between_packets*1000000) +
7317 ((nseconds_between_packets+500) / 1000);
7318
7319 /* Show how long it has been */
7320 proto_item *ti = NULL((void*)0);
7321 if (pinfo->num != timing->first_frame) {
7322 ti = proto_tree_add_uint(timingHeader, hf_oran_u_section_ul_symbol_time, tvb, 0, 0, total_gap);
7323 proto_item_set_generated(ti);
7324 }
7325
7326 if (total_gap > us_allowed_for_ul_in_symbol) {
7327 expert_add_info_format(pinfo, ti, &ei_oran_ul_uplane_symbol_too_long,
7328 "UL U-Plane Tx took longer (%u us) than limit set in preferences (%u us)",
7329 total_gap, us_allowed_for_ul_in_symbol);
7330 proto_item_append_text(timingHeader, " (%uus since first frame seen for symbol)", total_gap);
7331 }
7332
7333 /* Show how many frames were received */
7334 ti = proto_tree_add_uint(timingHeader, hf_oran_u_section_ul_symbol_frames, tvb, 0, 0, timing->frames_seen_in_symbol);
7335 proto_item_set_generated(ti);
7336
7337 /* Link to first frame for this symbol */
7338 if (pinfo->num != timing->first_frame) {
7339 ti = proto_tree_add_uint(timingHeader, hf_oran_u_section_ul_symbol_first_frame, tvb, 0, 0, timing->first_frame);
7340 proto_item_set_generated(ti);
7341 }
7342
7343 /* And also last frame */
7344 if (pinfo->num != timing->last_frame_in_symbol) {
7345 ti = proto_tree_add_uint(timingHeader, hf_oran_u_section_ul_symbol_last_frame, tvb, 0, 0, timing->last_frame_in_symbol);
7346 proto_item_set_generated(ti);
7347 }
7348
7349 tap_info->ul_delay_in_us = total_gap;
7350 }
7351 }
7352 }
7353 }
7354
7355
7356 /* Look up preferences for samples */
7357 if (direction
9.2
'direction' is not equal to DIR_UPLINK
== DIR_UPLINK0) {
10
Taking false branch
7358 sample_bit_width = pref_sample_bit_width_uplink;
7359 compression = pref_iqCompressionUplink;
7360 includeUdCompHeader = pref_includeUdCompHeaderUplink;
7361 } else {
7362 sample_bit_width = pref_sample_bit_width_downlink;
7363 compression = pref_iqCompressionDownlink;
7364 includeUdCompHeader = pref_includeUdCompHeaderDownlink;
7365 }
7366
7367 /* If uplink, load any udCompHdr settings written by C-Plane */
7368 bool_Bool ud_cmp_hdr_cplane = false0;
7369 if (cplane_state && direction
11.1
'direction' is not equal to 0
== 0) {
11
Assuming 'cplane_state' is non-null
12
Taking false branch
7370 /* Initialise settings from udpCompHdr from C-Plane */
7371 if (cplane_state->ul_ud_comp_hdr_set && !pref_override_ul_compression) {
7372 sample_bit_width = cplane_state->ul_ud_comp_hdr_bit_width;
7373 compression = cplane_state->ul_ud_comp_hdr_compression;
7374 ud_cmp_hdr_cplane = true1;
7375 }
7376 }
7377
7378 /* Need a valid value (e.g. 9, 14). 0 definitely won't work, as won't progress around loop! */
7379 /* N.B. may yet be overwritten by udCompHdr settings in sections below! */
7380 if (sample_bit_width == 0) {
13
Assuming 'sample_bit_width' is not equal to 0
14
Taking false branch
7381 expert_add_info_format(pinfo, protocol_item, &ei_oran_invalid_sample_bit_width,
7382 "%cL Sample bit width from %s (%u) not valid, so can't decode sections",
7383 (direction == DIR_UPLINK0) ? 'U' : 'D',
7384 !ud_cmp_hdr_cplane ? "preference" : "C-Plane",
7385 sample_bit_width);
7386 return offset;
7387 }
7388
7389 unsigned bytesLeft;
7390 unsigned number_of_sections = 0;
7391 unsigned nBytesPerPrb =0;
7392
7393 if (link_planes_together && !PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited) && cplane_state
15.2
'cplane_state' is non-null
) {
15
Assuming 'link_planes_together' is true
16
Taking true branch
7394 /* Take a deep-copy of this state on first pass */
7395 wmem_tree_foreach(cplane_state->expected_sections[direction], copy_section_entry, result->expected_sections);
17
Access to field 'expected_sections' results in a dereference of a null pointer (loaded from variable 'result')
7396 }
7397
7398 /* Add each section (not from count, just keep parsing until payload used) */
7399 do {
7400 /* Section subtree */
7401 unsigned section_start_offset = offset;
7402 proto_item *sectionHeading = proto_tree_add_string_format(oran_tree, hf_oran_u_section,
7403 tvb, offset, 0, "", "Section");
7404 proto_tree *section_tree = proto_item_add_subtree(sectionHeading, ett_oran_u_section);
7405
7406 /* Section Header fields (darker green part) */
7407
7408 /* sectionId */
7409 uint32_t sectionId = 0;
7410 proto_item *ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_section_id, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &sectionId);
7411 if (sectionId == 4095) {
7412 proto_item_append_text(ti, " (not default coupling C/U planes using sectionId)");
7413 }
7414 offset++;
7415
7416 if (tap_info->num_section_ids < MAX_SECTION_IDs32) {
7417 tap_info->section_ids[tap_info->num_section_ids++] = sectionId;
7418 }
7419
7420 section_details_t *section_details = NULL((void*)0);
7421 corresponding_uplane_frame *details = NULL((void*)0);
7422
7423 /* Lookup corresponding C-plane frame/info */
7424 if (link_planes_together) {
7425 if (cplane_state != NULL((void*)0)) {
7426
7427 expected_section_data_t *section_data = NULL((void*)0);
7428 section_data = wmem_tree_lookup32(result->expected_sections, sectionId);
7429
7430 if (section_data) {
7431 /* Need to work out which of 2 entries is in use for this data frame */
7432 unsigned index_to_use = 0;
7433
7434 /* Does the first entry match the timing for this frame? */
7435 if (section_data->details[0].frame == frameId &&
7436 section_data->details[0].subframe == subframeId &&
7437 section_data->details[0].slot == slotId &&
7438 /* Check that symbolId is in range */
7439 section_data->details[0].startSymbol <= symbolId &&
7440 (unsigned)(section_data->details[0].startSymbol + section_data->details[0].numSymbols) <= (unsigned)symbolId) {
7441
7442 index_to_use = 0;
7443 }
7444 else if (section_data->details[1].frame == frameId &&
7445 section_data->details[1].subframe == subframeId &&
7446 section_data->details[1].slot == slotId &&
7447 /* Check that symbolId is in range */
7448 section_data->details[1].startSymbol <= symbolId &&
7449 (unsigned)(section_data->details[1].startSymbol + section_data->details[1].numSymbols) <= (unsigned)symbolId) {
7450
7451 index_to_use = 1;
7452 }
7453 else {
7454 /* Just choose the latest one. Don't know numerology, so just use up to subframe */
7455 unsigned total_first = section_data->details[0].frame * 10 + section_data->details[0].subframe;
7456 unsigned total_second = section_data->details[1].frame * 10 + section_data->details[1].subframe;
7457 index_to_use = total_second > total_first;
7458 }
7459
7460 section_details = &section_data->details[index_to_use];
7461
7462 /* Cplane frame number */
7463 proto_item *cplane_frame_ti = proto_tree_add_uint(section_tree, hf_oran_corresponding_cplane_frame, tvb, 0, 0,
7464 section_details->frame_number);
7465 proto_item_set_generated(cplane_frame_ti);
7466
7467 /* usecs since cplane frame */
7468 time_t total_gap = 0;
7469
7470 if ((pinfo->abs_ts.secs == section_details->frame_time.secs) || (pinfo->abs_ts.secs == section_details->frame_time.secs+1)) {
7471 total_gap = ((pinfo->abs_ts.secs - section_details->frame_time.secs) * 1000000) +
7472 ((pinfo->abs_ts.nsecs - section_details->frame_time.nsecs)/1000);
7473 }
7474
7475 if (total_gap > 0) {
7476 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);
7477 proto_item_set_generated(cplane_delta_ti);
7478 }
7479
7480 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
7481 /* Look up 'result' for c-plane frame, and tell it about this frame.. */
7482 flow_result_t *cplane_result = wmem_tree_lookup32(flow_results_table, section_details->frame_number);
7483 if (!cplane_result) {
7484 cplane_result = wmem_new0(wmem_file_scope(), flow_result_t)((flow_result_t*)wmem_alloc0((wmem_file_scope()), sizeof(flow_result_t
)))
;
7485 cplane_result->u_plane_frames = wmem_list_new(wmem_file_scope());
7486 wmem_tree_insert32(flow_results_table, section_details->frame_number, cplane_result);
7487 }
7488 /* PRB range filled in below.. */
7489
7490 details = wmem_new(wmem_file_scope(), corresponding_uplane_frame)((corresponding_uplane_frame*)wmem_alloc((wmem_file_scope()),
sizeof(corresponding_uplane_frame)))
;
7491 details->frame_number = pinfo->num;
7492 details->gap_in_usecs = (uint32_t)total_gap;
7493 details->sectionId = sectionId;
7494 details->symbol = symbolId;
7495
7496 wmem_list_append(cplane_result->u_plane_frames, details);
7497 }
7498 }
7499 }
7500 }
7501
7502 /* rb */
7503 uint32_t rb;
7504 proto_tree_add_item_ret_uint(section_tree, hf_oran_rb, tvb, offset, 1, ENC_NA0x00000000, &rb);
7505 /* symInc. "use of symInc=1 shall be prohibited in the U-plane" */
7506 uint8_t syminc;
7507 proto_item *syminc_ti = proto_tree_add_item_ret_uint8(section_tree, hf_oran_symInc, tvb, offset, 1, ENC_NA0x00000000, &syminc);
7508 if (syminc) {
7509 expert_add_info(NULL((void*)0), syminc_ti, &ei_oran_syminc_set_for_uplane);
7510 }
7511 /* startPrbu */
7512 uint32_t startPrbu = 0;
7513 proto_tree_add_item_ret_uint(section_tree, hf_oran_startPrbu, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &startPrbu);
7514 offset += 2;
7515
7516 /* numPrbu */
7517 uint32_t numPrbu = 0;
7518 proto_tree_add_item_ret_uint(section_tree, hf_oran_numPrbu, tvb, offset, 1, ENC_NA0x00000000, &numPrbu);
7519 offset += 1;
7520
7521 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited) && details) {
7522 details->startPrbu = startPrbu;
7523 details->numPrbu = (numPrbu) ? numPrbu : 273;
7524 }
7525
7526 proto_item *ud_comp_meth_item, *ud_comp_len_ti=NULL((void*)0);
7527 uint32_t ud_comp_len = 0;
7528
7529 /* udCompHdr (if preferences indicate will be present) */
7530 bool_Bool included = (includeUdCompHeader==1) || /* 1 means present.. */
7531 (includeUdCompHeader==2 && udcomphdr_appears_present(state, direction, tvb, offset));
7532 if (included) {
7533 /* 7.5.2.10 */
7534 /* Extract these values to inform how wide IQ samples in each PRB will be. */
7535 offset = dissect_udcomphdr(tvb, pinfo, section_tree, offset, false0, direction == 0, &sample_bit_width,
7536 &compression, &ud_comp_meth_item, tap_info);
7537
7538 /* Not part of udCompHdr */
7539 uint32_t reserved;
7540 proto_item *res_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_reserved_8bits, tvb, offset, 1, ENC_NA0x00000000, &reserved);
7541 offset += 1;
7542 if (reserved != 0) {
7543 expert_add_info_format(pinfo, res_ti, &ei_oran_reserved_not_zero,
7544 "reserved field (0x%x) not zero - perhaps udCompHdr is not really present?",
7545 reserved);
7546 }
7547 }
7548 else {
7549 /* No fields to dissect - just showing comp values from prefs */
7550 /* iqWidth */
7551 proto_item *iq_width_item = proto_tree_add_uint(section_tree, hf_oran_udCompHdrIqWidth_pref, tvb, 0, 0, sample_bit_width);
7552 proto_item_append_text(iq_width_item, (ud_cmp_hdr_cplane) ? " (from c-plane)" : " (from preferences)");
7553 proto_item_set_generated(iq_width_item);
7554
7555 /* udCompMethod */
7556 ud_comp_meth_item = proto_tree_add_uint(section_tree, hf_oran_udCompHdrMeth_pref, tvb, 0, 0, compression);
7557 proto_item_append_text(ud_comp_meth_item, (ud_cmp_hdr_cplane) ? " (from c-plane)" : " (from preferences)");
7558 proto_item_set_generated(ud_comp_meth_item);
7559
7560 /* Point back to C-Plane, if used */
7561 /* TODO: doesn't work with multiple port mappings using SE10.. */
7562 if (ud_cmp_hdr_cplane) {
7563 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);
7564 proto_item_set_generated(cplane_ti);
7565 }
7566
7567 tap_info->compression_methods |= (1 << compression);
7568 tap_info->compression_width = sample_bit_width;
7569 }
7570
7571 /* Consider fragmentation after first section header */
7572 if (do_radio_transport_layer_reassembly && (number_of_sections == 0) && (e !=1 || subSeqId!= 0)) {
7573
7574 /* Set fragmented flag. */
7575 bool_Bool save_fragmented = pinfo->fragmented;
7576 pinfo->fragmented = true1;
7577 fragment_head *fh;
7578 unsigned frag_data_len = tvb_reported_length_remaining(tvb, offset);
7579
7580 /* Add this fragment into reassembly table */
7581 uint32_t reassembly_id = make_reassembly_id(seqId, direction, eAxC,
7582 frameId, subframeId, slotId, symbolId);
7583 fh = fragment_add_seq(&oran_reassembly_table, tvb, offset, pinfo,
7584 reassembly_id, /* id */
7585 GUINT_TO_POINTER(reassembly_id)((gpointer) (gulong) (reassembly_id)), /* data */
7586 subSeqId, /* frag_number */
7587 frag_data_len, /* frag_data_len */
7588 !e, /* more_frags */
7589 0);
7590
7591 bool_Bool update_col_info = true1;
7592
7593 /* See if this completes an SDU */
7594 tvbuff_t *original_tvb = tvb;
7595 tvbuff_t *next_tvb = process_reassembled_data(tvb, offset, pinfo, "Reassembled O-RAN FH CUS Payload",
7596 fh, &oran_frag_items,
7597 &update_col_info, oran_tree);
7598 if (next_tvb) {
7599 /* Have reassembled data */
7600 proto_tree_add_item(oran_tree, hf_oran_payload, next_tvb, 0, -1, ENC_NA0x00000000);
7601 col_append_fstr(pinfo->cinfo, COL_INFO, " Reassembled Data (%u bytes)", tvb_reported_length(next_tvb));
7602 /* Dissection should resume at start of reassembled tvb */
7603 offset = 0;
7604 }
7605 /* Will continue with either reassembled tvb or NULL */
7606 tvb = next_tvb;
7607
7608 /* Restore fragmented flag */
7609 pinfo->fragmented = save_fragmented;
7610
7611 /* Don't dissect any more if not complete yet.. */
7612 if (tvb == NULL((void*)0)) {
7613 return tvb_captured_length(original_tvb);
7614 }
7615 }
7616
7617
7618 /* Not supported! TODO: other places where comp method is looked up (e.g., bfw?) */
7619 switch (compression) {
7620 case COMP_NONE0:
7621 case COMP_BLOCK_FP1:
7622 case BFP_AND_SELECTIVE_RE5:
7623 case COMP_MODULATION4:
7624 case MOD_COMPR_AND_SELECTIVE_RE6:
7625 break;
7626 default:
7627 expert_add_info_format(pinfo, ud_comp_meth_item, &ei_oran_unsupported_compression_method,
7628 "Compression method %u (%s) not supported by dissector",
7629 compression,
7630 rval_to_str_const(compression, ud_comp_header_meth, "reserved"));
7631 }
7632
7633 /* udCompLen (when supported, methods 5,6,7,8) */
7634 if (compression >= BFP_AND_SELECTIVE_RE5) {
7635 bool_Bool supported = (pref_support_udcompLen==1) || /* supported */
7636 (pref_support_udcompLen==2 && udcomplen_appears_present(includeUdCompHeader, tvb, offset));
7637
7638 if (supported) {
7639 ud_comp_len_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_udCompLen, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &ud_comp_len);
7640 if (ud_comp_len <= 1) {
7641 proto_item_append_text(ud_comp_len_ti, " (reserved)");
7642 }
7643 /* TODO: report if less than a viable section in frame? */
7644 /* Check that there is this much length left in the frame */
7645 if (ud_comp_len > tvb_reported_length_remaining(tvb, section_start_offset)) {
7646 expert_add_info_format(pinfo, ud_comp_len_ti, &ei_oran_ud_comp_len_wrong_size,
7647 "udCompLen indicates %u bytes in section, but only %u are left in frame",
7648 ud_comp_len, tvb_reported_length_remaining(tvb, section_start_offset));
7649 }
7650 /* Actual length of section will be checked below, at the end of the section */
7651 offset += 2;
7652 }
7653 }
7654
7655 /* sReSMask1 + sReSMask2 (depends upon compression method) */
7656 uint64_t sresmask1=0, sresmask2=0;
7657 if (compression == BFP_AND_SELECTIVE_RE_WITH_MASKS7 ||
7658 compression == MOD_COMPR_AND_SELECTIVE_RE_WITH_MASKS8)
7659 {
7660 static int * const sres_mask1_2_flags[] = {
7661 &hf_oran_sReSMask1_2_re12,
7662 &hf_oran_sReSMask1_2_re11,
7663 &hf_oran_sReSMask1_2_re10,
7664 &hf_oran_sReSMask1_2_re9,
7665 &hf_oran_sReSMask_re8,
7666 &hf_oran_sReSMask_re7,
7667 &hf_oran_sReSMask_re6,
7668 &hf_oran_sReSMask_re5,
7669 &hf_oran_sReSMask_re4,
7670 &hf_oran_sReSMask_re3,
7671 &hf_oran_sReSMask_re2,
7672 &hf_oran_sReSMask_re1,
7673 NULL((void*)0)
7674 };
7675
7676 /* reserved (4 bits) */
7677 add_reserved_field(section_tree, hf_oran_reserved_4bits, tvb, offset, 1);
7678 /* sReSMask1 (12 bits) */
7679 proto_item *sresmask_ti;
7680 sresmask_ti = proto_tree_add_bitmask_ret_uint64(section_tree, tvb, offset,
7681 hf_oran_sReSMask1,
7682 ett_oran_sresmask,
7683 sres_mask1_2_flags,
7684 ENC_NA0x00000000,
7685 &sresmask1);
7686 offset += 2;
7687 /* Count REs present */
7688 unsigned res = 0;
7689 for (unsigned n=0; n < 12; n++) {
7690 if ((sresmask1 >> n) & 0x1) {
7691 res++;
7692 }
7693 }
7694 proto_item_append_text(sresmask_ti, " (%u REs)", res);
7695
7696
7697 /* reserved (4 bits) */
7698 add_reserved_field(section_tree, hf_oran_reserved_4bits, tvb, offset, 1);
7699 /* sReSMask2 (12 bits) */
7700 sresmask_ti = proto_tree_add_bitmask_ret_uint64(section_tree, tvb, offset,
7701 hf_oran_sReSMask2,
7702 ett_oran_sresmask,
7703 sres_mask1_2_flags,
7704 ENC_NA0x00000000,
7705 &sresmask2);
7706 offset += 2;
7707
7708 if (rb == 1) {
7709 proto_item_append_text(sresmask_ti, " (ignored)");
7710 if (sresmask2 != 0) {
7711 expert_add_info(pinfo, ud_comp_len_ti, &ei_oran_sresmask2_not_zero_with_rb);
7712 }
7713 }
7714 else {
7715 /* Count REs present */
7716 res = 0;
7717 for (unsigned n=0; n < 12; n++) {
7718 if ((sresmask2 >> n) & 0x1) {
7719 res++;
7720 }
7721 }
7722 proto_item_append_text(sresmask_ti, " (%u REs)", res);
7723 }
7724 }
7725
7726 write_section_info(sectionHeading, pinfo, protocol_item, sectionId, startPrbu, numPrbu, rb);
7727
7728 /* TODO: should this use the same pref as c-plane? */
7729 if (numPrbu == 0) {
7730 /* Special case for all PRBs (NR: the total number of PRBs may be > 255) */
7731 numPrbu = pref_data_plane_section_total_rbs;
7732 startPrbu = 0; /* may already be 0... */
7733 }
7734
7735 section_mod_compr_config_t* mod_compr_config = get_mod_compr_section_to_read(cplane_state, sectionId);
7736
7737 /* Add each PRB */
7738 for (unsigned i = 0; i < numPrbu; i++) {
7739 /* Create subtree */
7740 proto_item *prbHeading = proto_tree_add_string_format(section_tree, hf_oran_samples_prb,
7741 tvb, offset, 0,
7742 "", "PRB");
7743 proto_tree *rb_tree = proto_item_add_subtree(prbHeading, ett_oran_u_prb);
7744 uint32_t exponent = 0;
7745 uint16_t sresmask = 0;
7746
7747 /* udCompParam (depends upon compression method) */
7748 int before = offset;
7749 offset = dissect_udcompparam(tvb, pinfo, rb_tree, offset, compression, &exponent, &sresmask, false0);
7750 int udcompparam_len = offset-before;
7751
7752 /* Show PRB number in root */
7753 proto_item_append_text(prbHeading, " %3u", startPrbu + i*(1+rb));
7754
7755 /* Work out how many REs / PRB */
7756 unsigned res_per_prb = 12;
7757 uint16_t sresmask_to_use = 0x0fff;
7758
7759 if (compression >= BFP_AND_SELECTIVE_RE5) {
7760 /* Work out which mask should be used */
7761 if (compression==BFP_AND_SELECTIVE_RE5 || compression==MOD_COMPR_AND_SELECTIVE_RE6) {
7762 /* Selective RE cases, use value from compModParam */
7763 sresmask_to_use = (uint16_t)sresmask;
7764 }
7765 else {
7766 /* With masks (in section). Choose between sresmask1 and sresmask2 */
7767 if (rb==1 || (i%2)==0) {
7768 /* Even values */
7769 sresmask_to_use = (uint16_t)sresmask1;
7770 }
7771 else {
7772 /* Odd values */
7773 sresmask_to_use = (uint16_t)sresmask2;
7774 }
7775 }
7776
7777 /* Count REs present using sresmask */
7778 res_per_prb = 0;
7779 /* Use sresmask to pick out which REs are present */
7780 for (unsigned n=0; n<12; n++) {
7781 if (sresmask_to_use & (1<<n)) {
7782 res_per_prb++;
7783 }
7784 }
7785 }
7786
7787 /* N.B. bytes for samples need to be padded out to next byte
7788 (certainly where there aren't 12 REs in PRB..) */
7789 unsigned nBytesForSamples = (sample_bit_width * res_per_prb * 2 + 7) / 8;
7790 nBytesPerPrb = nBytesForSamples + udcompparam_len;
7791
7792 proto_tree_add_item(rb_tree, hf_oran_iq_user_data, tvb, offset, nBytesForSamples, ENC_NA0x00000000);
7793
7794 if (section_details) {
7795 if ((startPrbu + i*(1+rb)) < 273) {
7796 proto_item *beamid_ti = proto_tree_add_uint(rb_tree, hf_oran_beamId, tvb, 0, 0,
7797 section_details->beamIds[startPrbu + i*(1+rb)]);
7798 proto_item_set_generated(beamid_ti);
7799 }
7800 }
7801
7802
7803 tap_info->non_zero_re_in_current_prb = false0;
7804
7805 /* Optionally trying to show I/Q RE values */
7806 if (pref_showIQSampleValues) {
7807 /* Individual values */
7808 unsigned samples_offset = offset*8;
7809 unsigned samples_start = offset;
7810 unsigned samples = 0;
7811
7812 if (compression >= BFP_AND_SELECTIVE_RE5) {
7813 /* Use sresmask to pick out which REs are present */
7814 for (unsigned n=1; n<=12; n++) {
7815 if (sresmask_to_use & (1<<(n-1))) {
7816 samples_offset = dissect_oran_u_re(tvb, rb_tree,
7817 n, samples_offset, tap_info, sample_bit_width, compression, exponent, mod_compr_config, n);
7818 samples++;
7819 }
7820 }
7821 }
7822 else {
7823 /* All 12 REs are present */
7824 for (unsigned n=1; n<=12; n++) {
7825 samples_offset = dissect_oran_u_re(tvb, rb_tree,
7826 n, samples_offset, tap_info, sample_bit_width, compression, exponent, mod_compr_config, n);
7827 samples++;
7828 }
7829 }
7830 proto_item_append_text(prbHeading, " (%u REs)", samples);
7831 if (section_details) {
7832 if ((startPrbu + i*(1+rb)) < 273) {
7833 proto_item_append_text(prbHeading, " [BeamId:%u]", section_details->beamIds[startPrbu + i*(1+rb)]);
7834 }
7835 }
7836
7837 /* Was this PRB all zeros? */
7838 if (!tap_info->non_zero_re_in_current_prb) {
7839 tap_info->num_prbs_zero++;
7840 /* Add a filter to make zero-valued PRBs more findable */
7841 proto_item *zero_ti = proto_tree_add_item(rb_tree, hf_oran_zero_prb, tvb,
7842 samples_start, nBytesForSamples, ENC_NA0x00000000);
7843 proto_item_set_hidden(zero_ti);
7844 proto_item_append_text(prbHeading, " (all zeros)");
7845 }
7846 else {
7847 proto_item *nonzero_ti = proto_tree_add_item(rb_tree, hf_oran_nonzero_prb, tvb, samples_start, nBytesForSamples, ENC_NA0x00000000);
7848 proto_item_set_hidden(nonzero_ti);
7849 }
7850 }
7851
7852 tap_info->num_prbs++;
7853
7854
7855 /* Advance past samples */
7856 offset += nBytesForSamples;
7857
7858 /* Set end of prb subtree */
7859 proto_item_set_end(prbHeading, tvb, offset);
7860 }
7861
7862 /* Set extent of section */
7863 proto_item_set_len(sectionHeading, offset-section_start_offset);
7864 if (ud_comp_len_ti != NULL((void*)0) && ((offset-section_start_offset != ud_comp_len))) {
7865 expert_add_info_format(pinfo, ud_comp_len_ti, &ei_oran_ud_comp_len_wrong_size,
7866 "udCompLen indicates %u bytes in section, but dissected %u instead",
7867 ud_comp_len, offset-section_start_offset);
7868 }
7869
7870 bytesLeft = tvb_captured_length(tvb) - offset;
7871 number_of_sections++;
7872 } while (bytesLeft >= (4 + nBytesPerPrb)); /* FIXME: bad heuristic */
7873
7874 /* Show number of sections found */
7875 proto_item *ti = proto_tree_add_uint(oran_tree, hf_oran_numberOfSections, tvb, 0, 0, number_of_sections);
7876 proto_item_set_generated(ti);
7877
7878 /* Expert error if we are short of tvb by > 3 bytes */
7879 if (tvb_reported_length_remaining(tvb, offset) > 3) {
7880 expert_add_info_format(pinfo, protocol_item, &ei_oran_frame_length,
7881 "%u bytes remain at end of frame - should be 0-3",
7882 tvb_reported_length_remaining(tvb, offset));
7883 }
7884
7885 return tvb_captured_length(tvb);
7886}
7887
7888
7889/**********************************************************************/
7890/* Main dissection function. */
7891/* N.B. ecpri message type passed in as 'data' arg by eCPRI dissector */
7892static int
7893dissect_oran(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
7894{
7895 uint32_t ecpri_message_type = *(uint32_t *)data;
7896 unsigned offset = 0;
7897
7898 /* Allocate and zero tap struct */
7899 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
)))
;
7900 tap_info->pdu_size = pinfo->fd->pkt_len;
7901 tap_info->ul_delay_configured_max = us_allowed_for_ul_in_symbol;
7902
7903 switch (ecpri_message_type) {
7904 case ECPRI_MT_IQ_DATA0:
7905 offset = dissect_oran_u(tvb, pinfo, tree, tap_info, data);
7906 break;
7907 case ECPRI_MT_RT_CTRL_DATA2:
7908 offset = dissect_oran_c(tvb, pinfo, tree, tap_info, data);
7909 break;
7910 default:
7911 /* Not dissecting other types - assume these are handled by eCPRI dissector */
7912 return 0;
7913 }
7914
7915 tap_queue_packet(oran_tap, pinfo, tap_info);
7916
7917 return offset;
7918}
7919
7920static void oran_init_protocol(void)
7921{
7922 udcomplen_heuristic_result_set = false0;
7923 udcomplen_heuristic_result = false0;
7924}
7925
7926
7927/* Register the protocol with Wireshark. */
7928void
7929proto_register_oran(void)
7930{
7931 static hf_register_info hf[] = {
7932
7933 /* Section 5.1.3.2.7 */
7934 { &hf_oran_du_port_id,
7935 { "DU Port ID", "oran_fh_cus.du_port_id",
7936 FT_UINT16, BASE_DEC,
7937 NULL((void*)0), 0x0,
7938 "Processing unit at O-RU - width set in dissector preference", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
7939 },
7940
7941 /* Section 5.1.3.2.7 */
7942 { &hf_oran_bandsector_id,
7943 { "BandSector ID", "oran_fh_cus.bandsector_id",
7944 FT_UINT16, BASE_DEC,
7945 NULL((void*)0), 0x0,
7946 "Aggregated cell identified - width set in dissector preference", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
7947 },
7948
7949 /* Section 5.1.3.2.7 */
7950 { &hf_oran_cc_id,
7951 { "CC ID", "oran_fh_cus.cc_id",
7952 FT_UINT16, BASE_DEC,
7953 NULL((void*)0), 0x0,
7954 "Component Carrier - width set in dissector preference", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
7955 },
7956
7957 /* Section 5.1.3.2.7 */
7958 { &hf_oran_ru_port_id,
7959 { "RU Port ID", "oran_fh_cus.ru_port_id",
7960 FT_UINT16, BASE_DEC,
7961 NULL((void*)0), 0x0,
7962 "Logical flow - width set in dissector preference", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
7963 },
7964
7965 /* Section 5.1.3.2.8 */
7966 { &hf_oran_sequence_id,
7967 { "Sequence ID", "oran_fh_cus.sequence_id",
7968 FT_UINT8, BASE_DEC,
7969 NULL((void*)0), 0x0,
7970 "The Sequence ID wraps around individually per eAxC", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
7971 },
7972
7973 /* Section 5.1.3.2.8 */
7974 { &hf_oran_e_bit,
7975 { "E Bit", "oran_fh_cus.e_bit",
7976 FT_UINT8, BASE_DEC,
7977 VALS(e_bit)((0 ? (const struct _value_string*)0 : ((e_bit)))), 0x80,
7978 "Indicate the last message of a subsequence (U-Plane only)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
7979 },
7980
7981 /* Section 5.1.3.2.8 */
7982 { &hf_oran_subsequence_id,
7983 { "Subsequence ID", "oran_fh_cus.subsequence_id",
7984 FT_UINT8, BASE_DEC,
7985 NULL((void*)0), 0x7f,
7986 "The subsequence ID (for eCPRI layer fragmentation)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
7987 },
7988
7989 { &hf_oran_previous_frame,
7990 { "Previous frame in stream", "oran_fh_cus.previous-frame",
7991 FT_FRAMENUM, BASE_NONE,
7992 FRAMENUM_TYPE(FT_FRAMENUM_NONE)((gpointer) (glong) (FT_FRAMENUM_NONE)), 0x0,
7993 "Previous frame in sequence", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
7994 },
7995
7996 /* Section 7.5.2.1 */
7997 { &hf_oran_data_direction,
7998 { "Data Direction", "oran_fh_cus.data_direction",
7999 FT_UINT8, BASE_DEC,
8000 VALS(data_direction_vals)((0 ? (const struct _value_string*)0 : ((data_direction_vals)
)))
, 0x80,
8001 "gNB data direction", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
8002 },
8003
8004 /* Section 7.5.2.2 */
8005 { &hf_oran_payload_version,
8006 { "Payload Version", "oran_fh_cus.payloadVersion",
8007 FT_UINT8, BASE_DEC,
8008 NULL((void*)0), 0x70,
8009 "Payload protocol version the following IEs", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8010 },
8011
8012 /* Section 7.5.2.3 */
8013 { &hf_oran_filter_index,
8014 { "Filter Index", "oran_fh_cus.filterIndex",
8015 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
8016 RVALS(filter_indices)((0 ? (const struct _range_string*)0 : ((filter_indices)))), 0x0f,
8017 "used between IQ data and air interface, both in DL and UL", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8018 },
8019
8020 /* Section 7.5.2.4 */
8021 { &hf_oran_frame_id,
8022 { "Frame ID", "oran_fh_cus.frameId",
8023 FT_UINT8, BASE_DEC,
8024 NULL((void*)0), 0x0,
8025 "A counter for 10 ms frames (wrapping period 2.56 seconds)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8026 },
8027
8028 /* Section 7.5.2.5 */
8029 { &hf_oran_subframe_id,
8030 { "Subframe ID", "oran_fh_cus.subframe_id",
8031 FT_UINT8, BASE_DEC,
8032 NULL((void*)0), 0xf0,
8033 "A counter for 1 ms sub-frames within 10ms frame", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8034 },
8035
8036 /* Section 7.5.2.6 */
8037 { &hf_oran_slot_id,
8038 { "Slot ID", "oran_fh_cus.slotId",
8039 FT_UINT16, BASE_DEC,
8040 NULL((void*)0), 0x0fc0,
8041 "Slot number within a 1ms sub-frame", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8042 },
8043
8044 /* Generated for convenience */
8045 { &hf_oran_slot_within_frame,
8046 { "Slot within frame", "oran_fh_cus.slot-within-frame",
8047 FT_UINT16, BASE_DEC,
8048 NULL((void*)0), 0x0,
8049 "Slot within frame, to match DCT logs", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8050 },
8051
8052 /* Section 7.5.2.7 */
8053 { &hf_oran_start_symbol_id,
8054 { "Start Symbol ID", "oran_fh_cus.startSymbolId",
8055 FT_UINT8, BASE_DEC,
8056 NULL((void*)0), 0x3f,
8057 "The first symbol number within slot affected", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8058 },
8059
8060 /* Section 7.5.2.8 */
8061 { &hf_oran_numberOfSections,
8062 { "Number of Sections", "oran_fh_cus.numberOfSections",
8063 FT_UINT8, BASE_DEC,
8064 NULL((void*)0), 0x0,
8065 "The number of section IDs included in this message", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8066 },
8067
8068 /* Section 7.5.2.9 */
8069 { &hf_oran_sectionType,
8070 { "Section Type", "oran_fh_cus.sectionType",
8071 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
8072 RVALS(section_types)((0 ? (const struct _range_string*)0 : ((section_types)))), 0x0,
8073 "Determines the characteristics of U-plane data", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8074 },
8075
8076 /* Section 7.5.2.10 */
8077 { &hf_oran_udCompHdr,
8078 { "udCompHdr", "oran_fh_cus.udCompHdr",
8079 FT_STRING, BASE_NONE,
8080 NULL((void*)0), 0x0,
8081 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8082 },
8083
8084 /* Section 7.5.2.11 */
8085 { &hf_oran_numberOfUEs,
8086 { "Number Of UEs", "oran_fh_cus.numberOfUEs",
8087 FT_UINT8, BASE_DEC,
8088 NULL((void*)0), 0x0,
8089 "Indicates number of UEs for which channel info is provided", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8090 },
8091
8092 /* Section 7.5.2.12 */
8093 { &hf_oran_timeOffset,
8094 { "Time Offset", "oran_fh_cus.timeOffset",
8095 FT_UINT16, BASE_DEC,
8096 NULL((void*)0), 0x0,
8097 "from start of the slot to start of CP in samples", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8098 },
8099
8100 /* Section 7.5.2.13 */
8101 { &hf_oran_frameStructure_fft,
8102 { "FFT Size", "oran_fh_cus.frameStructure.fft",
8103 FT_UINT8, BASE_HEX | BASE_RANGE_STRING0x00000100,
8104 RVALS(frame_structure_fft)((0 ? (const struct _range_string*)0 : ((frame_structure_fft)
)))
, 0xf0,
8105 "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) }
8106 },
8107
8108 /* Section 7.5.2.13 */
8109 { &hf_oran_frameStructure_subcarrier_spacing,
8110 { "Subcarrier Spacing", "oran_fh_cus.frameStructure.spacing",
8111 FT_UINT8, BASE_HEX | BASE_RANGE_STRING0x00000100,
8112 RVALS(subcarrier_spacings)((0 ? (const struct _range_string*)0 : ((subcarrier_spacings)
)))
, 0x0f,
8113 "The sub carrier spacing as well as the number of slots per 1ms sub-frame",
8114 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
8115 },
8116
8117 /* Section 7.5.2.14 */
8118 { &hf_oran_cpLength,
8119 { "cpLength", "oran_fh_cus.cpLength",
8120 FT_UINT16, BASE_DEC,
8121 NULL((void*)0), 0x0,
8122 "cyclic prefix length", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8123 },
8124
8125 { &hf_oran_timing_header,
8126 { "Timing Header", "oran_fh_cus.timingHeader",
8127 FT_STRING, BASE_NONE,
8128 NULL((void*)0), 0x0,
8129 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8130 },
8131
8132 /* Section 7.5.3.1 */
8133 { &hf_oran_section_id,
8134 { "sectionId", "oran_fh_cus.sectionId",
8135 FT_UINT16, BASE_DEC,
8136 NULL((void*)0), 0xfff0,
8137 "section identifier of data", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8138 },
8139
8140 /* Section 7.5.3.2 */
8141 { &hf_oran_rb,
8142 { "rb", "oran_fh_cus.rb",
8143 FT_UINT8, BASE_DEC,
8144 VALS(rb_vals)((0 ? (const struct _value_string*)0 : ((rb_vals)))), 0x08,
8145 "resource block indicator", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8146 },
8147
8148 /* Section 7.5.5.3 */
8149 { &hf_oran_symInc,
8150 { "symInc", "oran_fh_cus.symInc",
8151 FT_UINT8, BASE_DEC,
8152 VALS(sym_inc_vals)((0 ? (const struct _value_string*)0 : ((sym_inc_vals)))), 0x04,
8153 "Symbol Number Increment Command", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8154 },
8155
8156 /* Section 7.5.3.4 */
8157 { &hf_oran_startPrbc,
8158 { "startPrbc", "oran_fh_cus.startPrbc",
8159 FT_UINT16, BASE_DEC,
8160 NULL((void*)0), 0x03ff,
8161 "Starting PRB of Control Plane Section", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8162 },
8163
8164 /* Section 7.5.3.5 */
8165 { &hf_oran_reMask_re1,
8166 { "RE 1", "oran_fh_cus.reMask-RE1",
8167 FT_BOOLEAN, 16,
8168 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x8000,
8169 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8170 },
8171 { &hf_oran_reMask_re2,
8172 { "RE 2", "oran_fh_cus.reMask-RE2",
8173 FT_BOOLEAN, 16,
8174 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x4000,
8175 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8176 },
8177 { &hf_oran_reMask_re3,
8178 { "RE 3", "oran_fh_cus.reMask-RE3",
8179 FT_BOOLEAN, 16,
8180 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x2000,
8181 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8182 },
8183 { &hf_oran_reMask_re4,
8184 { "RE 4", "oran_fh_cus.reMask-RE4",
8185 FT_BOOLEAN, 16,
8186 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x1000,
8187 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8188 },
8189 { &hf_oran_reMask_re5,
8190 { "RE 5", "oran_fh_cus.reMask-RE5",
8191 FT_BOOLEAN, 16,
8192 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0800,
8193 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8194 },
8195 { &hf_oran_reMask_re6,
8196 { "RE 6", "oran_fh_cus.reMask-RE6",
8197 FT_BOOLEAN, 16,
8198 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0400,
8199 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8200 },
8201 { &hf_oran_reMask_re7,
8202 { "RE 7", "oran_fh_cus.reMask-RE7",
8203 FT_BOOLEAN, 16,
8204 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0200,
8205 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8206 },
8207 { &hf_oran_reMask_re8,
8208 { "RE 8", "oran_fh_cus.reMask-RE8",
8209 FT_BOOLEAN, 16,
8210 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0100,
8211 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8212 },
8213 { &hf_oran_reMask_re9,
8214 { "RE 9", "oran_fh_cus.reMask-RE9",
8215 FT_BOOLEAN, 16,
8216 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0080,
8217 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8218 },
8219 { &hf_oran_reMask_re10,
8220 { "RE 10", "oran_fh_cus.reMask-RE10",
8221 FT_BOOLEAN, 16,
8222 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0040,
8223 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8224 },
8225 { &hf_oran_reMask_re11,
8226 { "RE 11", "oran_fh_cus.reMask-RE11",
8227 FT_BOOLEAN, 16,
8228 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0020,
8229 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8230 },
8231 { &hf_oran_reMask_re12,
8232 { "RE 12", "oran_fh_cus.reMask-RE12",
8233 FT_BOOLEAN, 16,
8234 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0010,
8235 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8236 },
8237 { &hf_oran_reMask,
8238 { "RE Mask", "oran_fh_cus.reMask",
8239 FT_UINT16, BASE_HEX,
8240 NULL((void*)0), 0xfff0,
8241 "The Resource Element (RE) mask within a PRB", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8242 },
8243
8244 /* Section 7.5.3.6 */
8245 { &hf_oran_numPrbc,
8246 { "numPrbc", "oran_fh_cus.numPrbc",
8247 FT_UINT8, BASE_DEC,
8248 NULL((void*)0), 0x0,
8249 "Number of contiguous PRBs per data section description", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8250 },
8251 /* Section 7.5.3.7 */
8252 { &hf_oran_numSymbol,
8253 { "Number of Symbols", "oran_fh_cus.numSymbol",
8254 FT_UINT8, BASE_DEC,
8255 NULL((void*)0), 0x0f,
8256 "Defines number of symbols to which the section control is applicable", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8257 },
8258 /* Section 7.5.3.8 */
8259 { &hf_oran_ef,
8260 { "Extension Flag", "oran_fh_cus.ef",
8261 FT_BOOLEAN, 8,
8262 NULL((void*)0), 0x80,
8263 "Indicates if more section extensions follow", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8264 },
8265 /* Section 7.5.3.9 */
8266 { &hf_oran_beamId,
8267 { "Beam ID", "oran_fh_cus.beamId",
8268 FT_UINT16, BASE_DEC,
8269 NULL((void*)0), 0x7fff,
8270 "Defines the beam pattern to be applied to the U-Plane data", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8271 },
8272
8273 { &hf_oran_extension,
8274 { "Extension", "oran_fh_cus.extension",
8275 FT_STRING, BASE_NONE,
8276 NULL((void*)0), 0x0,
8277 "Section extension", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8278 },
8279
8280 /* Section 7.6.2.1 */
8281 { &hf_oran_exttype,
8282 { "extType", "oran_fh_cus.extType",
8283 FT_UINT8, BASE_DEC|BASE_EXT_STRING0x00000200,
8284 &exttype_vals_ext, 0x7f,
8285 "The extension type, which provides additional parameters specific to subject data extension", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8286 },
8287
8288 /* Section 7.6.2.3 */
8289 { &hf_oran_extlen,
8290 { "extLen", "oran_fh_cus.extLen",
8291 FT_UINT16, BASE_DEC,
8292 NULL((void*)0), 0x0,
8293 "Extension length in 32-bit words", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8294 },
8295
8296 /* Section 7.7.1 */
8297 { &hf_oran_bfw,
8298 { "bfw", "oran_fh_cus.bfw",
8299 FT_STRING, BASE_NONE,
8300 NULL((void*)0), 0x0,
8301 "Set of weights for a particular antenna", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8302 },
8303 { &hf_oran_bfw_bundle,
8304 { "Bundle", "oran_fh_cus.bfw.bundle",
8305 FT_STRING, BASE_NONE,
8306 NULL((void*)0), 0x0,
8307 "Bundle of BFWs", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8308 },
8309 { &hf_oran_bfw_bundle_id,
8310 { "Bundle Id", "oran_fh_cus.bfw.bundleId",
8311 FT_UINT32, BASE_DEC,
8312 NULL((void*)0), 0x0,
8313 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8314 },
8315 /* Section 7.7.1.4 */
8316 { &hf_oran_bfw_i,
8317 { "bfwI", "oran_fh_cus.bfwI",
8318 FT_FLOAT, BASE_NONE,
8319 NULL((void*)0), 0x0,
8320 "In-phase", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8321 },
8322 /* Section 7.7.1.5 */
8323 { &hf_oran_bfw_q,
8324 { "bfwQ", "oran_fh_cus.bfwQ",
8325 FT_FLOAT, BASE_NONE,
8326 NULL((void*)0), 0x0,
8327 "Quadrature", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8328 },
8329
8330 /* Section 7.5.3.10 */
8331 { &hf_oran_ueId,
8332 { "UE ID", "oran_fh_cus.ueId",
8333 FT_UINT16, BASE_DEC,
8334 NULL((void*)0), 0x7fff,
8335 "logical identifier for set of channel info", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8336 },
8337 /* Section 7.5.3.11 */
8338 { &hf_oran_freqOffset,
8339 { "Frequency Offset", "oran_fh_cus.freqOffset",
8340 FT_UINT24, BASE_DEC,
8341 NULL((void*)0), 0x0,
8342 "with respect to the carrier center frequency before additional filtering", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8343 },
8344
8345 /* Section 7.5.3.12 */
8346 { &hf_oran_regularizationFactor,
8347 { "Regularization Factor", "oran_fh_cus.regularizationFactor",
8348 FT_INT16, BASE_DEC,
8349 NULL((void*)0), 0x0,
8350 "Signed value to support MMSE operation within O-RU", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8351 },
8352 /* Section 7.5.3.14 */
8353 { &hf_oran_laaMsgType,
8354 { "LAA Message Type", "oran_fh_cus.laaMsgType",
8355 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
8356 RVALS(laaMsgTypes)((0 ? (const struct _range_string*)0 : ((laaMsgTypes)))), 0xf0,
8357 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8358 },
8359 /* Section 7.5.3.15 */
8360 { &hf_oran_laaMsgLen,
8361 { "LAA Message Length", "oran_fh_cus.laaMsgLen",
8362 FT_UINT8, BASE_DEC,
8363 NULL((void*)0), 0x0f,
8364 "number of 32-bit words in the LAA section", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8365 },
8366 /* Section 7.5.3.16 */
8367 { &hf_oran_lbtHandle,
8368 { "LBT Handle", "oran_fh_cus.lbtHandle",
8369 FT_UINT16, BASE_HEX,
8370 NULL((void*)0), 0x0,
8371 "label to identify transaction", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8372 },
8373 /* Section 7.5.3.17 */
8374 { &hf_oran_lbtDeferFactor,
8375 { "Defer Factor", "oran_fh_cus.lbtDeferFactor",
8376 FT_UINT8, BASE_DEC,
8377 NULL((void*)0), 0x07,
8378 "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)}
8379 },
8380 /* Section 7.5.3.18 */
8381 { &hf_oran_lbtBackoffCounter,
8382 { "Backoff Counter", "oran_fh_cus.lbtBackoffCounter",
8383 FT_UINT16, BASE_DEC,
8384 NULL((void*)0), 0xffc0,
8385 "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)}
8386 },
8387 /* Section 7.5.3.19 */
8388 { &hf_oran_lbtOffset,
8389 { "LBT Offset", "oran_fh_cus.lbtOffset",
8390 FT_UINT16, BASE_DEC,
8391 NULL((void*)0), 0xffc0,
8392 "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)}
8393 },
8394 /* Section 7.5.3.20 */
8395 { &hf_oran_MCOT,
8396 { "Maximum Channel Occupancy Time", "oran_fh_cus.MCOT",
8397 FT_UINT8, BASE_DEC,
8398 NULL((void*)0), 0x3c,
8399 "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)}
8400 },
8401 /* Section 7.5.3.21 */
8402 { &hf_oran_lbtMode,
8403 { "LBT Mode", "oran_fh_cus.lbtMode",
8404 FT_UINT8, BASE_DEC,
8405 VALS(lbtMode_vals)((0 ? (const struct _value_string*)0 : ((lbtMode_vals)))), 0x0,
8406 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8407 },
8408 /* Section 7.5.3.22 */
8409 { &hf_oran_lbtPdschRes,
8410 { "lbtPdschRes", "oran_fh_cus.lbtPdschRes",
8411 FT_UINT8, BASE_DEC,
8412 VALS(lbtPdschRes_vals)((0 ? (const struct _value_string*)0 : ((lbtPdschRes_vals)))), 0xc0,
8413 "LBT result of SFN/SF", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8414 },
8415 /* Section 7.5.3.23 */
8416 { &hf_oran_sfStatus,
8417 { "sfStatus", "oran_fh_cus.sfStatus",
8418 FT_BOOLEAN, 8,
8419 TFS(&tfs_sfStatus)((0 ? (const struct true_false_string*)0 : ((&tfs_sfStatus
))))
, 0x10,
8420 "Indicates whether the subframe was dropped or transmitted", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8421 },
8422 /* Section 7.5.3.24 */
8423 { &hf_oran_lbtDrsRes,
8424 { "lbtDrsRes", "oran_fh_cus.lbtDrsRes",
8425 FT_BOOLEAN, 8,
8426 TFS(&tfs_fail_success)((0 ? (const struct true_false_string*)0 : ((&tfs_fail_success
))))
, 0x80,
8427 "Indicates whether the subframe was dropped or transmitted", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8428 },
8429 /* Section 7.5.3.25 */
8430 { &hf_oran_initialPartialSF,
8431 { "Initial partial SF", "oran_fh_cus.initialPartialSF",
8432 FT_BOOLEAN, 8,
8433 TFS(&tfs_partial_full_sf)((0 ? (const struct true_false_string*)0 : ((&tfs_partial_full_sf
))))
, 0x40,
8434 "Indicates whether the initial SF in the LBT process is full or partial", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8435 },
8436 /* Section 7.5.3.26. */
8437 { &hf_oran_lbtBufErr,
8438 { "lbtBufErr", "oran_fh_cus.lbtBufErr",
8439 FT_BOOLEAN, 8,
8440 TFS(&tfs_lbtBufErr)((0 ? (const struct true_false_string*)0 : ((&tfs_lbtBufErr
))))
, 0x80,
8441 "LBT buffer error", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8442 },
8443 /* Section 7.5.3.27 */
8444 { &hf_oran_sfnSfEnd,
8445 { "SFN/SF End", "oran_fh_cus.sfnSfEnd",
8446 FT_UINT16, BASE_DEC,
8447 NULL((void*)0), 0x0fff,
8448 "SFN/SF by which the DRS window must end", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8449 },
8450 /* Section 7.5.3.28 */
8451 { &hf_oran_lbtCWConfig_H,
8452 { "lbtCWConfig_H", "oran_fh_cus.lbtCWConfig_H",
8453 FT_UINT8, BASE_DEC,
8454 NULL((void*)0), 0x0,
8455 "HARQ parameters for congestion window management", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8456 },
8457 /* Section 7.5.3.29 */
8458 { &hf_oran_lbtCWConfig_T,
8459 { "lbtCWConfig_T", "oran_fh_cus.lbtCWConfig_T",
8460 FT_UINT8, BASE_DEC,
8461 NULL((void*)0), 0x0,
8462 "TB parameters for congestion window management", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8463 },
8464 /* Section 7.5.3.30 */
8465 { &hf_oran_lbtTrafficClass,
8466 { "lbtTrafficClass", "oran_fh_cus.lbtTrafficClass",
8467 FT_UINT8, BASE_DEC,
8468 VALS(lbtTrafficClass_vals)((0 ? (const struct _value_string*)0 : ((lbtTrafficClass_vals
))))
, 0x38,
8469 "Traffic class priority for congestion window management", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8470 },
8471 /* Section 7.5.3.31 */
8472 { &hf_oran_lbtCWR_Rst,
8473 { "lbtCWR_Rst", "oran_fh_cus.lbtCWR_Rst",
8474 FT_BOOLEAN, 8,
8475 TFS(&tfs_fail_success)((0 ? (const struct true_false_string*)0 : ((&tfs_fail_success
))))
, 0x80,
8476 "notification about packet reception successful or not", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8477 },
8478
8479 /* Reserved fields */
8480 { &hf_oran_reserved,
8481 { "reserved", "oran_fh_cus.reserved",
8482 FT_UINT64, BASE_HEX,
8483 NULL((void*)0), 0x0,
8484 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8485 },
8486 { &hf_oran_reserved_1bit,
8487 { "reserved", "oran_fh_cus.reserved",
8488 FT_UINT8, BASE_HEX,
8489 NULL((void*)0), 0x80,
8490 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8491 },
8492 { &hf_oran_reserved_2bits,
8493 { "reserved", "oran_fh_cus.reserved",
8494 FT_UINT8, BASE_HEX,
8495 NULL((void*)0), 0xc0,
8496 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8497 },
8498 { &hf_oran_reserved_3bits,
8499 { "reserved", "oran_fh_cus.reserved",
8500 FT_UINT8, BASE_HEX,
8501 NULL((void*)0), 0xe0,
8502 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8503 },
8504 { &hf_oran_reserved_4bits,
8505 { "reserved", "oran_fh_cus.reserved",
8506 FT_UINT8, BASE_HEX,
8507 NULL((void*)0), 0xf0,
8508 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8509 },
8510 { &hf_oran_reserved_last_4bits,
8511 { "reserved", "oran_fh_cus.reserved",
8512 FT_UINT8, BASE_HEX,
8513 NULL((void*)0), 0x0f,
8514 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8515 },
8516 { &hf_oran_reserved_last_5bits,
8517 { "reserved", "oran_fh_cus.reserved",
8518 FT_UINT8, BASE_HEX,
8519 NULL((void*)0), 0x1f,
8520 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8521 },
8522 { &hf_oran_reserved_6bits,
8523 { "reserved", "oran_fh_cus.reserved",
8524 FT_UINT8, BASE_HEX,
8525 NULL((void*)0), 0xfc,
8526 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8527 },
8528 { &hf_oran_reserved_last_6bits,
8529 { "reserved", "oran_fh_cus.reserved",
8530 FT_UINT8, BASE_HEX,
8531 NULL((void*)0), 0x3f,
8532 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8533 },
8534 { &hf_oran_reserved_7bits,
8535 { "reserved", "oran_fh_cus.reserved",
8536 FT_UINT8, BASE_HEX,
8537 NULL((void*)0), 0xfe,
8538 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8539 },
8540 { &hf_oran_reserved_last_7bits,
8541 { "reserved", "oran_fh_cus.reserved",
8542 FT_UINT8, BASE_HEX,
8543 NULL((void*)0), 0x7f,
8544 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8545 },
8546 { &hf_oran_reserved_8bits,
8547 { "reserved", "oran_fh_cus.reserved",
8548 FT_UINT8, BASE_HEX,
8549 NULL((void*)0), 0x0,
8550 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8551 },
8552 { &hf_oran_reserved_16bits,
8553 { "reserved", "oran_fh_cus.reserved",
8554 FT_UINT16, BASE_HEX,
8555 NULL((void*)0), 0x0,
8556 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8557 },
8558 { &hf_oran_reserved_15bits,
8559 { "reserved", "oran_fh_cus.reserved",
8560 FT_UINT16, BASE_HEX,
8561 NULL((void*)0), 0x7fff,
8562 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8563 },
8564 { &hf_oran_reserved_bit1,
8565 { "reserved", "oran_fh_cus.reserved",
8566 FT_UINT8, BASE_HEX,
8567 NULL((void*)0), 0x40,
8568 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8569 },
8570 { &hf_oran_reserved_bit2,
8571 { "reserved", "oran_fh_cus.reserved",
8572 FT_UINT8, BASE_HEX,
8573 NULL((void*)0), 0x20,
8574 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8575 },
8576 { &hf_oran_reserved_bit4,
8577 { "reserved", "oran_fh_cus.reserved",
8578 FT_UINT8, BASE_HEX,
8579 NULL((void*)0), 0x08,
8580 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8581 },
8582 { &hf_oran_reserved_bit5,
8583 { "reserved", "oran_fh_cus.reserved",
8584 FT_UINT8, BASE_HEX,
8585 NULL((void*)0), 0x04,
8586 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8587 },
8588 { &hf_oran_reserved_bits123,
8589 { "reserved", "oran_fh_cus.reserved",
8590 FT_UINT8, BASE_HEX,
8591 NULL((void*)0), 0x70,
8592 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8593 },
8594 { &hf_oran_reserved_bits456,
8595 { "reserved", "oran_fh_cus.reserved",
8596 FT_UINT8, BASE_HEX,
8597 NULL((void*)0), 0x0e,
8598 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8599 },
8600
8601 /* 7.7.11.9 */
8602 { &hf_oran_cont_ind,
8603 { "contInd", "oran_fh_cus.contInd",
8604 FT_BOOLEAN, 8,
8605 TFS(&continuity_indication_tfs)((0 ? (const struct true_false_string*)0 : ((&continuity_indication_tfs
))))
, 0x80,
8606 "PRB region continuity flag", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8607 },
8608 /* 7.7.11.10 */
8609 { &hf_oran_bundle_offset,
8610 { "BundleOffset", "oran_fh_cus.bundleOffset",
8611 FT_UINT8, BASE_DEC,
8612 NULL((void*)0), 0x3f,
8613 "offset between start of first PRB bundle and startPrbc", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8614 },
8615
8616 /* 7.7.1.2 bfwCompHdr (beamforming weight compression header) */
8617 { &hf_oran_bfwCompHdr,
8618 { "bfwCompHdr", "oran_fh_cus.bfwCompHdr",
8619 FT_STRING, BASE_NONE,
8620 NULL((void*)0), 0x0,
8621 "Compression method and IQ bit width for beamforming weights", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8622 },
8623 { &hf_oran_bfwCompHdr_iqWidth,
8624 { "IQ Bit Width", "oran_fh_cus.bfwCompHdr_iqWidth",
8625 FT_UINT8, BASE_HEX,
8626 VALS(bfw_comp_headers_iq_width)((0 ? (const struct _value_string*)0 : ((bfw_comp_headers_iq_width
))))
, 0xf0,
8627 "IQ bit width for the beamforming weights", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8628 },
8629 { &hf_oran_bfwCompHdr_compMeth,
8630 { "Compression Method", "oran_fh_cus.bfwCompHdr_compMeth",
8631 FT_UINT8, BASE_HEX,
8632 VALS(bfw_comp_headers_comp_meth)((0 ? (const struct _value_string*)0 : ((bfw_comp_headers_comp_meth
))))
, 0x0f,
8633 "compression method for the beamforming weights", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8634 },
8635
8636 /* 7.5.3.32 */
8637 { &hf_oran_ciCompParam,
8638 { "ciCompParam", "oran_fh_cus.ciCompParam",
8639 FT_STRING, BASE_NONE,
8640 NULL((void*)0), 0x0,
8641 "channel information compression parameter", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8642 },
8643
8644 /* Table 7.5.3.32-1 */
8645 { &hf_oran_blockScaler,
8646 { "blockScaler", "oran_fh_cus.blockScaler",
8647 FT_UINT8, BASE_HEX,
8648 NULL((void*)0), 0x0,
8649 "unsigned, 1 integer bit, 7 fractional bits", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8650 },
8651 { &hf_oran_compBitWidth,
8652 { "compBitWidth", "oran_fh_cus.compBitWidth",
8653 FT_UINT8, BASE_DEC,
8654 NULL((void*)0), 0xf0,
8655 "Length of I bits and length of Q bits after compression over entire PRB", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8656 },
8657 { &hf_oran_compShift,
8658 { "compShift", "oran_fh_cus.compShift",
8659 FT_UINT8, BASE_DEC,
8660 NULL((void*)0), 0x0f,
8661 "The shift applied to the entire PRB", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8662 },
8663
8664 { &hf_oran_active_beamspace_coefficient_n1,
8665 { "N1", "oran_fh_cus.activeBeamspace_Coefficient_n1",
8666 FT_BOOLEAN, 8,
8667 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x80,
8668 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8669 },
8670 { &hf_oran_active_beamspace_coefficient_n2,
8671 { "N2", "oran_fh_cus.activeBeamspace_Coefficient_n2",
8672 FT_BOOLEAN, 8,
8673 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x40,
8674 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8675 },
8676 { &hf_oran_active_beamspace_coefficient_n3,
8677 { "N3", "oran_fh_cus.activeBeamspace_Coefficient_n3",
8678 FT_BOOLEAN, 8,
8679 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x20,
8680 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8681 },
8682 { &hf_oran_active_beamspace_coefficient_n4,
8683 { "N4", "oran_fh_cus.activeBeamspace_Coefficient_n4",
8684 FT_BOOLEAN, 8,
8685 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x10,
8686 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8687 },
8688 { &hf_oran_active_beamspace_coefficient_n5,
8689 { "N5", "oran_fh_cus.activeBeamspace_Coefficient_n5",
8690 FT_BOOLEAN, 8,
8691 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x08,
8692 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8693 },
8694 { &hf_oran_active_beamspace_coefficient_n6,
8695 { "N6", "oran_fh_cus.activeBeamspace_Coefficient_n6",
8696 FT_BOOLEAN, 8,
8697 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x04,
8698 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8699 },
8700 { &hf_oran_active_beamspace_coefficient_n7,
8701 { "N7", "oran_fh_cus.activeBeamspace_Coefficient_n7",
8702 FT_BOOLEAN, 8,
8703 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x02,
8704 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8705 },
8706 { &hf_oran_active_beamspace_coefficient_n8,
8707 { "N8", "oran_fh_cus.activeBeamspace_Coefficient_n8",
8708 FT_BOOLEAN, 8,
8709 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x01,
8710 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8711 },
8712
8713 { &hf_oran_activeBeamspaceCoefficientMask,
8714 { "activeBeamspaceCoefficientMask", "oran_fh_cus.activeBeamspaceCoefficientMask",
8715 FT_UINT8, BASE_HEX,
8716 NULL((void*)0), 0xff,
8717 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8718 },
8719 { &hf_oran_activeBeamspaceCoefficientMask_bits_set,
8720 { "Array elements set", "oran_fh_cus.activeBeamspaceCoefficientMask.bits-set",
8721 FT_UINT32, BASE_DEC,
8722 NULL((void*)0), 0x0,
8723 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8724 },
8725
8726 /* Section 7.7.6.6 */
8727 { &hf_oran_se6_repetition,
8728 { "repetition", "oran_fh_cus.repetition",
8729 FT_BOOLEAN, BASE_NONE,
8730 TFS(&repetition_se6_tfs)((0 ? (const struct true_false_string*)0 : ((&repetition_se6_tfs
))))
, 0x0,
8731 "Repetition of a highest priority data section for C-Plane", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8732 },
8733 /* 7.7.20.9 */
8734 { &hf_oran_rbgSize,
8735 { "rbgSize", "oran_fh_cus.rbgSize",
8736 FT_UINT8, BASE_HEX,
8737 VALS(rbg_size_vals)((0 ? (const struct _value_string*)0 : ((rbg_size_vals)))), 0x70,
8738 "Number of PRBs of the resource block groups allocated by the bit mask", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8739 },
8740 /* 7.7.20.10 */
8741 { &hf_oran_rbgMask,
8742 { "rbgMask", "oran_fh_cus.rbgMask",
8743 FT_UINT32, BASE_HEX,
8744 NULL((void*)0), 0x0fffffff,
8745 "Each bit indicates whether a corresponding resource block group is present", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8746 },
8747 /* 7.7.6.5. Also 7.7.12.3 and 7.7.19.5 */
8748 { &hf_oran_noncontig_priority,
8749 { "priority", "oran_fh_cus.priority",
8750 FT_UINT8, BASE_HEX,
8751 VALS(priority_vals)((0 ? (const struct _value_string*)0 : ((priority_vals)))), 0xc0,
8752 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8753 },
8754
8755 /* 7.7.6.4 */
8756 { &hf_oran_symbol_mask,
8757 { "symbolMask", "oran_fh_cus.symbolMask",
8758 FT_UINT16, BASE_HEX,
8759 NULL((void*)0), 0x3fff,
8760 "Each bit indicates whether the rbgMask applies to a given symbol in the slot", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8761 },
8762 { &hf_oran_symbol_mask_s13,
8763 { "symbol 13", "oran_fh_cus.symbolMask.symbol-13",
8764 FT_BOOLEAN, 16,
8765 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x2000,
8766 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8767 },
8768 { &hf_oran_symbol_mask_s12,
8769 { "symbol 12", "oran_fh_cus.symbolMask.symbol-12",
8770 FT_BOOLEAN, 16,
8771 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x1000,
8772 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8773 },
8774 { &hf_oran_symbol_mask_s11,
8775 { "symbol 11", "oran_fh_cus.symbolMask.symbol-11",
8776 FT_BOOLEAN, 16,
8777 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0800,
8778 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8779 },
8780 { &hf_oran_symbol_mask_s10,
8781 { "symbol 10", "oran_fh_cus.symbolMask.symbol-10",
8782 FT_BOOLEAN, 16,
8783 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0400,
8784 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8785 },
8786 { &hf_oran_symbol_mask_s9,
8787 { "symbol 9", "oran_fh_cus.symbolMask.symbol-9",
8788 FT_BOOLEAN, 16,
8789 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0200,
8790 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8791 },
8792 { &hf_oran_symbol_mask_s8,
8793 { "symbol 8", "oran_fh_cus.symbolMask.symbol-8",
8794 FT_BOOLEAN, 16,
8795 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0100,
8796 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8797 },
8798 { &hf_oran_symbol_mask_s7,
8799 { "symbol 7", "oran_fh_cus.symbolMask.symbol-7",
8800 FT_BOOLEAN, 16,
8801 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0080,
8802 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8803 },
8804 { &hf_oran_symbol_mask_s6,
8805 { "symbol 6", "oran_fh_cus.symbolMask.symbol-6",
8806 FT_BOOLEAN, 16,
8807 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0040,
8808 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8809 },
8810 { &hf_oran_symbol_mask_s5,
8811 { "symbol 5", "oran_fh_cus.symbolMask.symbol-5",
8812 FT_BOOLEAN, 16,
8813 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0020,
8814 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8815 },
8816 { &hf_oran_symbol_mask_s4,
8817 { "symbol 4", "oran_fh_cus.symbolMask.symbol-4",
8818 FT_BOOLEAN, 16,
8819 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0010,
8820 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8821 },
8822 { &hf_oran_symbol_mask_s3,
8823 { "symbol 3", "oran_fh_cus.symbolMask.symbol-3",
8824 FT_BOOLEAN, 16,
8825 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0008,
8826 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8827 },
8828 { &hf_oran_symbol_mask_s2,
8829 { "symbol 2", "oran_fh_cus.symbolMask.symbol-2",
8830 FT_BOOLEAN, 16,
8831 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0004,
8832 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8833 },
8834 { &hf_oran_symbol_mask_s1,
8835 { "symbol 1", "oran_fh_cus.symbolMask.symbol-1",
8836 FT_BOOLEAN, 16,
8837 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0002,
8838 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8839 },
8840 { &hf_oran_symbol_mask_s0,
8841 { "symbol 0", "oran_fh_cus.symbolMask.symbol-0",
8842 FT_BOOLEAN, 16,
8843 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0001,
8844 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8845 },
8846
8847
8848 /* 7.7.22.2 */
8849 { &hf_oran_ack_nack_req_id,
8850 { "ackNackReqId", "oran_fh_cus.ackNackReqId",
8851 FT_UINT16, BASE_HEX,
8852 NULL((void*)0), 0x0,
8853 "Indicates the ACK/NACK request ID of a section description", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8854 },
8855
8856 /* Subtree for next 2 items */
8857 { &hf_oran_frequency_range,
8858 { "Frequency Range", "oran_fh_cus.frequencyRange",
8859 FT_STRING, BASE_NONE,
8860 NULL((void*)0), 0x0,
8861 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8862 },
8863
8864 /* 7.7.12.4 */
8865 { &hf_oran_off_start_prb,
8866 { "offStartPrb", "oran_fh_cus.offStartPrb",
8867 FT_UINT8, BASE_DEC,
8868 NULL((void*)0), 0x0,
8869 "Offset of PRB range start", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8870 },
8871 /* 7.7.12.5 */
8872 { &hf_oran_num_prb,
8873 { "numPrb", "oran_fh_cus.numPrb",
8874 FT_UINT8, BASE_DEC,
8875 NULL((void*)0), 0x0,
8876 "Number of PRBs in PRB range", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8877 },
8878
8879 /* symbolId 8.3.3.7 */
8880 { &hf_oran_symbolId,
8881 { "Symbol Identifier", "oran_fh_cus.symbolId",
8882 FT_UINT8, BASE_DEC,
8883 NULL((void*)0), 0x3f,
8884 "Identifies a symbol number within a slot", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8885 },
8886
8887 /* startPrbu 8.3.3.11 */
8888 { &hf_oran_startPrbu,
8889 { "startPrbu", "oran_fh_cus.startPrbu",
8890 FT_UINT16, BASE_DEC,
8891 NULL((void*)0), 0x03ff,
8892 "starting PRB of user plane section", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8893 },
8894
8895 /* numPrbu 8.3.3.12 */
8896 { &hf_oran_numPrbu,
8897 { "numPrbu", "oran_fh_cus.numPrbu",
8898 FT_UINT8, BASE_DEC,
8899 NULL((void*)0), 0x0,
8900 "number of PRBs per user plane section", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8901 },
8902
8903 /* 7.7.1.3 */
8904 { &hf_oran_bfwCompParam,
8905 { "bfwCompParam", "oran_fh_cus.bfwCompParam",
8906 FT_STRING, BASE_NONE,
8907 NULL((void*)0), 0x0,
8908 "Beamforming weight compression parameter", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8909 },
8910
8911 /* 6.3.3.13 */
8912 { &hf_oran_udCompHdrMeth,
8913 { "User Data Compression Method", "oran_fh_cus.udCompHdrMeth",
8914 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
8915 RVALS(ud_comp_header_meth)((0 ? (const struct _range_string*)0 : ((ud_comp_header_meth)
)))
, 0x0f,
8916 "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)}
8917 },
8918 { &hf_oran_udCompHdrMeth_pref,
8919 { "User Data Compression Method", "oran_fh_cus.udCompHdrMeth",
8920 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
8921 RVALS(ud_comp_header_meth)((0 ? (const struct _range_string*)0 : ((ud_comp_header_meth)
)))
, 0x0,
8922 "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)}
8923 },
8924 /* 8.3.3.18 */
8925 { &hf_oran_udCompLen,
8926 { "udCompLen", "oran_fh_cus.udCompLen",
8927 FT_UINT16, BASE_DEC,
8928 NULL((void*)0), 0x0,
8929 "PRB field length in octets", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8930 },
8931
8932 /* 7.5.2.10 */
8933 { &hf_oran_udCompHdrIqWidth,
8934 { "User Data IQ width", "oran_fh_cus.udCompHdrWidth",
8935 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
8936 RVALS(ud_comp_header_width)((0 ? (const struct _range_string*)0 : ((ud_comp_header_width
))))
, 0xf0,
8937 "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)}
8938 },
8939 { &hf_oran_udCompHdrIqWidth_pref,
8940 { "User Data IQ width", "oran_fh_cus.udCompHdrWidth.pref",
8941 FT_UINT8, BASE_DEC,
8942 NULL((void*)0), 0x0,
8943 "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)}
8944 },
8945
8946 { &hf_oran_sinrCompHdrIqWidth_pref,
8947 { "SINR IQ width", "oran_fh_cus.sinrCompHdrWidth",
8948 FT_UINT8, BASE_DEC,
8949 NULL((void*)0), 0x0,
8950 "Defines the IQ bit width for SINR data in section type 9", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8951 },
8952 { &hf_oran_sinrCompHdrMeth_pref,
8953 { "SINR Compression Method", "oran_fh_cus.sinrCompHdrMeth",
8954 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
8955 RVALS(ud_comp_header_meth)((0 ? (const struct _range_string*)0 : ((ud_comp_header_meth)
)))
, 0x0,
8956 "Defines the compression method for SINR data in section type 9", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8957 },
8958
8959 /* Section 8.3.3.15 (not always present - depends upon meth) */
8960 { &hf_oran_udCompParam,
8961 { "User Data Compression Parameter", "oran_fh_cus.udCompParam",
8962 FT_STRING, BASE_NONE,
8963 NULL((void*)0), 0x0,
8964 "Applies to whatever compression method is specified by the associated sectionID's compMeth value", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8965 },
8966 /* 8.3.3.18 */
8967 { &hf_oran_sReSMask,
8968 { "sReSMask", "oran_fh_cus.sReSMask",
8969 FT_UINT16, BASE_HEX,
8970 NULL((void*)0), 0xf0ff,
8971 "selective RE sending mask", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8972 },
8973
8974 { &hf_oran_sReSMask_re12,
8975 { "RE-12", "oran_fh_cus.sReSMask-re12",
8976 FT_BOOLEAN, 16,
8977 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x8000,
8978 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8979 },
8980 { &hf_oran_sReSMask_re11,
8981 { "RE-11", "oran_fh_cus.sReSMask-re11",
8982 FT_BOOLEAN, 16,
8983 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x4000,
8984 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8985 },
8986 { &hf_oran_sReSMask_re10,
8987 { "RE-10", "oran_fh_cus.sReSMask-re10",
8988 FT_BOOLEAN, 16,
8989 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x2000,
8990 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8991 },
8992 { &hf_oran_sReSMask_re9,
8993 { "RE-9", "oran_fh_cus.sReSMask-re9",
8994 FT_BOOLEAN, 16,
8995 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x1000,
8996 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8997 },
8998 { &hf_oran_sReSMask_re8,
8999 { "RE-8", "oran_fh_cus.sReSMask-re8",
9000 FT_BOOLEAN, 16,
9001 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0080,
9002 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9003 },
9004 { &hf_oran_sReSMask_re7,
9005 { "RE-7", "oran_fh_cus.sReSMask-re7",
9006 FT_BOOLEAN, 16,
9007 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0040,
9008 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9009 },
9010 { &hf_oran_sReSMask_re6,
9011 { "RE-6", "oran_fh_cus.sReSMask-re6",
9012 FT_BOOLEAN, 16,
9013 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0020,
9014 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9015 },
9016 { &hf_oran_sReSMask_re5,
9017 { "RE-5", "oran_fh_cus.sReSMask-re5",
9018 FT_BOOLEAN, 16,
9019 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0010,
9020 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9021 },
9022 { &hf_oran_sReSMask_re4,
9023 { "RE-4", "oran_fh_cus.sReSMask-re4",
9024 FT_BOOLEAN, 16,
9025 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0008,
9026 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9027 },
9028 { &hf_oran_sReSMask_re3,
9029 { "RE-3", "oran_fh_cus.sReSMask-re3",
9030 FT_BOOLEAN, 16,
9031 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0004,
9032 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9033 },
9034 { &hf_oran_sReSMask_re2,
9035 { "RE-2", "oran_fh_cus.sReSMask-re2",
9036 FT_BOOLEAN, 16,
9037 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0002,
9038 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9039 },
9040 { &hf_oran_sReSMask_re1,
9041 { "RE-1", "oran_fh_cus.sReSMask-re1",
9042 FT_BOOLEAN, 16,
9043 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0001,
9044 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9045 },
9046
9047 /* 8.3.3.20 */
9048 { &hf_oran_sReSMask1,
9049 { "sReSMask1", "oran_fh_cus.sReSMask1",
9050 FT_UINT16, BASE_HEX,
9051 NULL((void*)0), 0x0fff,
9052 "selective RE sending mask 1", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9053 },
9054 /* 8.3.3.21 */
9055 { &hf_oran_sReSMask2,
9056 { "sReSMask2", "oran_fh_cus.sReSMask2",
9057 FT_UINT16, BASE_HEX,
9058 NULL((void*)0), 0x0fff,
9059 "selective RE sending mask 2", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9060 },
9061
9062 { &hf_oran_sReSMask1_2_re12,
9063 { "RE-12", "oran_fh_cus.sReSMask-re12",
9064 FT_BOOLEAN, 16,
9065 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0800,
9066 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9067 },
9068 { &hf_oran_sReSMask1_2_re11,
9069 { "RE-11", "oran_fh_cus.sReSMask-re11",
9070 FT_BOOLEAN, 16,
9071 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0400,
9072 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9073 },
9074 { &hf_oran_sReSMask1_2_re10,
9075 { "RE-10", "oran_fh_cus.sReSMask-re10",
9076 FT_BOOLEAN, 16,
9077 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0200,
9078 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9079 },
9080 { &hf_oran_sReSMask1_2_re9,
9081 { "RE-9", "oran_fh_cus.sReSMask-re9",
9082 FT_BOOLEAN, 16,
9083 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0100,
9084 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9085 },
9086
9087 /* Section 6.3.3.15 */
9088 { &hf_oran_iSample,
9089 { "iSample", "oran_fh_cus.iSample",
9090 FT_FLOAT, BASE_NONE,
9091 NULL((void*)0), 0x0,
9092 "In-phase Sample value", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9093 },
9094
9095 /* Section 6.3.3.16 */
9096 { &hf_oran_qSample,
9097 { "qSample", "oran_fh_cus.qSample",
9098 FT_FLOAT, BASE_NONE,
9099 NULL((void*)0), 0x0,
9100 "Quadrature Sample value", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9101 },
9102
9103 { &hf_oran_exponent,
9104 { "Exponent", "oran_fh_cus.exponent",
9105 FT_UINT8, BASE_DEC,
9106 NULL((void*)0), 0x0f,
9107 "Exponent applicable to the I & Q mantissas", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9108 },
9109
9110 { &hf_oran_iq_user_data,
9111 { "IQ User Data", "oran_fh_cus.iq_user_data",
9112 FT_BYTES, BASE_NONE,
9113 NULL((void*)0), 0x0,
9114 "Used for the In-phase and Quadrature sample mantissa", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9115 },
9116
9117
9118 { &hf_oran_u_section_ul_symbol_time,
9119 { "Microseconds since first UL U-plane frame for this symbol", "oran_fh_cus.us-since-first-ul-frame",
9120 FT_UINT32, BASE_DEC,
9121 NULL((void*)0), 0x0,
9122 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9123 },
9124 { &hf_oran_u_section_ul_symbol_frames,
9125 { "Number of UL frames sent for this symbol", "oran_fh_cus.number-ul-frames-in-symbol",
9126 FT_UINT32, BASE_DEC,
9127 NULL((void*)0), 0x0,
9128 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9129 },
9130 { &hf_oran_u_section_ul_symbol_first_frame,
9131 { "First UL frame for this symbol", "oran_fh_cus.first-ul-frame-in-symbol",
9132 FT_FRAMENUM, BASE_NONE,
9133 FRAMENUM_TYPE(FT_FRAMENUM_NONE)((gpointer) (glong) (FT_FRAMENUM_NONE)), 0x0,
9134 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9135 },
9136 { &hf_oran_u_section_ul_symbol_last_frame,
9137 { "Last UL frame for this symbol", "oran_fh_cus.last-ul-frame-in-symbol",
9138 FT_FRAMENUM, BASE_NONE,
9139 FRAMENUM_TYPE(FT_FRAMENUM_NONE)((gpointer) (glong) (FT_FRAMENUM_NONE)), 0x0,
9140 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9141 },
9142
9143 { &hf_oran_c_eAxC_ID,
9144 { "c_eAxC_ID", "oran_fh_cus.c_eaxc_id",
9145 FT_STRING, BASE_NONE,
9146 NULL((void*)0), 0x0,
9147 "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) }
9148 },
9149
9150 { &hf_oran_refa,
9151 { "RefA", "oran_fh_cus.refa",
9152 FT_STRING, BASE_NONE,
9153 NULL((void*)0), 0x0,
9154 "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) }
9155 },
9156
9157
9158 /* Section 7.5.2.15 */
9159 { &hf_oran_ciCompHdr,
9160 { "ciCompHdr", "oran_fh_cus.ciCompHdr",
9161 FT_STRING, BASE_NONE,
9162 NULL((void*)0), 0x0,
9163 "Channel Information Compression Header", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9164 },
9165 { &hf_oran_ciCompHdrMeth,
9166 { "User Data Compression Method", "oran_fh_cus.ciCompHdrMeth",
9167 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
9168 RVALS(ud_comp_header_meth)((0 ? (const struct _range_string*)0 : ((ud_comp_header_meth)
)))
, 0x0e,
9169 "Compression method for Channel Information", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9170 },
9171 { &hf_oran_ciCompHdrIqWidth,
9172 { "User Data IQ width", "oran_fh_cus.ciCompHdrWidth",
9173 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
9174 RVALS(ud_comp_header_width)((0 ? (const struct _range_string*)0 : ((ud_comp_header_width
))))
, 0xf0,
9175 "IQ bit width for Channel Information", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9176 },
9177 { &hf_oran_ciCompOpt,
9178 { "ciCompOpt", "oran_fh_cus.ciCompOpt",
9179 FT_UINT8, BASE_DEC,
9180 VALS(ci_comp_opt_vals)((0 ? (const struct _value_string*)0 : ((ci_comp_opt_vals)))), 0x01,
9181 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9182 },
9183
9184 /* 7.7.11.7 */
9185 { &hf_oran_disable_bfws,
9186 { "disableBFWs", "oran_fh_cus.disableBFWs",
9187 FT_BOOLEAN, 8,
9188 NULL((void*)0), 0x80,
9189 "Indicate if BFWs under section extension are disabled", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9190 },
9191 /* 7.7.11.8 */
9192 { &hf_oran_rad,
9193 { "RAD", "oran_fh_cus.rad",
9194 FT_BOOLEAN, 8,
9195 NULL((void*)0), 0x40,
9196 "Reset After PRB Discontinuity", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9197 },
9198 /* 7.7.11.4 */
9199 { &hf_oran_num_bund_prbs,
9200 { "numBundPrb", "oran_fh_cus.numBundPrb",
9201 FT_UINT8, BASE_DEC,
9202 NULL((void*)0), 0x0,
9203 "Number of bundled PRBs per BFWs", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9204 },
9205 { &hf_oran_beam_id,
9206 { "beamId", "oran_fh_cus.beamId",
9207 FT_UINT16, BASE_DEC,
9208 NULL((void*)0), 0x7fff,
9209 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9210 },
9211 { &hf_oran_num_weights_per_bundle,
9212 { "Num weights per bundle", "oran_fh_cus.num_weights_per_bundle",
9213 FT_UINT16, BASE_DEC,
9214 NULL((void*)0), 0x0,
9215 "From dissector preference", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9216 },
9217
9218 { &hf_oran_samples_prb,
9219 {"PRB", "oran_fh_cus.prb",
9220 FT_STRING, BASE_NONE,
9221 NULL((void*)0), 0x0,
9222 "Grouping of samples for a particular Physical Resource Block", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9223 },
9224
9225 /* 7.5.3.13 */
9226 { &hf_oran_ciSample,
9227 { "ciSample", "oran_fh_cus.ciSample",
9228 FT_STRING, BASE_NONE,
9229 NULL((void*)0), 0x0,
9230 "Sample (I and Q values)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9231 },
9232 { &hf_oran_ciIsample,
9233 { "ciIsample", "oran_fh_cus.ciISample",
9234 FT_FLOAT, BASE_NONE,
9235 NULL((void*)0), 0x0,
9236 "Channel information complex value - I part", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9237 },
9238 { &hf_oran_ciQsample,
9239 { "ciQsample", "oran_fh_cus.ciQSample",
9240 FT_FLOAT, BASE_NONE,
9241 NULL((void*)0), 0x0,
9242 "Channel information complex value - Q part", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9243 },
9244
9245 /* 7.7.10.2 */
9246 { &hf_oran_beamGroupType,
9247 { "beamGroupType", "oran_fh_cus.beamGroupType",
9248 FT_UINT8, BASE_DEC,
9249 VALS(beam_group_type_vals)((0 ? (const struct _value_string*)0 : ((beam_group_type_vals
))))
, 0xc0,
9250 "The type of beam grouping", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9251 },
9252 /* 7.7.10.3 */
9253 { &hf_oran_numPortc,
9254 { "numPortc", "oran_fh_cus.numPortc",
9255 FT_UINT8, BASE_DEC,
9256 NULL((void*)0), 0x3f,
9257 "The number of eAxC ports", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9258 },
9259
9260 /* 7.7.4.2 (1 bit) */
9261 { &hf_oran_csf,
9262 { "csf", "oran_fh_cus.csf",
9263 FT_BOOLEAN, BASE_NONE,
9264 NULL((void*)0), 0x0,
9265 "constellation shift flag", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9266 },
9267 /* 7.7.4.3 */
9268 { &hf_oran_modcompscaler,
9269 { "modCompScaler", "oran_fh_cus.modcompscaler",
9270 FT_UINT16, BASE_DEC,
9271 NULL((void*)0), 0x7fff,
9272 "modulation compression scaler value", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9273 },
9274
9275 /* 7.7.5.1 */
9276 { &hf_oran_modcomp_param_set,
9277 { "Set", "oran_fh_cus.modcomp-param-set",
9278 FT_STRING, BASE_NONE,
9279 NULL((void*)0), 0x0,
9280 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9281 },
9282
9283
9284
9285 /* mcScaleReMask 7.7.5.2 (12 bits) */
9286
9287 /* First entry (starts with msb within byte) */
9288 { &hf_oran_mc_scale_re_mask_re1,
9289 { "RE 1", "oran_fh_cus.mcscalermask-RE1",
9290 FT_BOOLEAN, 16,
9291 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x8000,
9292 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9293 },
9294 { &hf_oran_mc_scale_re_mask_re2,
9295 { "RE 2", "oran_fh_cus.mcscalermask-RE2",
9296 FT_BOOLEAN, 16,
9297 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x4000,
9298 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9299 },
9300 { &hf_oran_mc_scale_re_mask_re3,
9301 { "RE 3", "oran_fh_cus.mcscalermask-RE3",
9302 FT_BOOLEAN, 16,
9303 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x2000,
9304 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9305 },
9306 { &hf_oran_mc_scale_re_mask_re4,
9307 { "RE 4", "oran_fh_cus.mcscalermask-RE4",
9308 FT_BOOLEAN, 16,
9309 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x1000,
9310 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9311 },
9312 { &hf_oran_mc_scale_re_mask_re5,
9313 { "RE 5", "oran_fh_cus.mcscalermask-RE5",
9314 FT_BOOLEAN, 16,
9315 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0800,
9316 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9317 },
9318 { &hf_oran_mc_scale_re_mask_re6,
9319 { "RE 6", "oran_fh_cus.mcscalermask-RE6",
9320 FT_BOOLEAN, 16,
9321 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0400,
9322 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9323 },
9324 { &hf_oran_mc_scale_re_mask_re7,
9325 { "RE 7", "oran_fh_cus.mcscalermask-RE7",
9326 FT_BOOLEAN, 16,
9327 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0200,
9328 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9329 },
9330 { &hf_oran_mc_scale_re_mask_re8,
9331 { "RE 8", "oran_fh_cus.mcscalermask-RE8",
9332 FT_BOOLEAN, 16,
9333 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0100,
9334 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9335 },
9336 { &hf_oran_mc_scale_re_mask_re9,
9337 { "RE 9", "oran_fh_cus.mcscalermask-RE9",
9338 FT_BOOLEAN, 16,
9339 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0080,
9340 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9341 },
9342 { &hf_oran_mc_scale_re_mask_re10,
9343 { "RE 10", "oran_fh_cus.mcscalermask-RE10",
9344 FT_BOOLEAN, 16,
9345 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0040,
9346 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9347 },
9348 { &hf_oran_mc_scale_re_mask_re11,
9349 { "RE 11", "oran_fh_cus.mcscalermask-RE11",
9350 FT_BOOLEAN, 16,
9351 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0020,
9352 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9353 },
9354 { &hf_oran_mc_scale_re_mask_re12,
9355 { "RE 12", "oran_fh_cus.mcscalermask-RE12",
9356 FT_BOOLEAN, 16,
9357 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0010,
9358 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9359 },
9360
9361 /* Even tries entry (starts with 5th bit within byte) */
9362 { &hf_oran_mc_scale_re_mask_re1_even,
9363 { "RE 1", "oran_fh_cus.mcscalermask-RE1",
9364 FT_BOOLEAN, 16,
9365 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0800,
9366 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9367 },
9368 { &hf_oran_mc_scale_re_mask_re2_even,
9369 { "RE 2", "oran_fh_cus.mcscalermask-RE2",
9370 FT_BOOLEAN, 16,
9371 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0400,
9372 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9373 },
9374 { &hf_oran_mc_scale_re_mask_re3_even,
9375 { "RE 3", "oran_fh_cus.mcscalermask-RE3",
9376 FT_BOOLEAN, 16,
9377 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0200,
9378 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9379 },
9380 { &hf_oran_mc_scale_re_mask_re4_even,
9381 { "RE 4", "oran_fh_cus.mcscalermask-RE4",
9382 FT_BOOLEAN, 16,
9383 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0100,
9384 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9385 },
9386 { &hf_oran_mc_scale_re_mask_re5_even,
9387 { "RE 5", "oran_fh_cus.mcscalermask-RE5",
9388 FT_BOOLEAN, 16,
9389 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0080,
9390 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9391 },
9392 { &hf_oran_mc_scale_re_mask_re6_even,
9393 { "RE 6", "oran_fh_cus.mcscalermask-RE6",
9394 FT_BOOLEAN, 16,
9395 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0040,
9396 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9397 },
9398 { &hf_oran_mc_scale_re_mask_re7_even,
9399 { "RE 7", "oran_fh_cus.mcscalermask-RE7",
9400 FT_BOOLEAN, 16,
9401 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0020,
9402 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9403 },
9404 { &hf_oran_mc_scale_re_mask_re8_even,
9405 { "RE 8", "oran_fh_cus.mcscalermask-RE8",
9406 FT_BOOLEAN, 16,
9407 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0010,
9408 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9409 },
9410 { &hf_oran_mc_scale_re_mask_re9_even,
9411 { "RE 9", "oran_fh_cus.mcscalermask-RE9",
9412 FT_BOOLEAN, 16,
9413 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0008,
9414 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9415 },
9416 { &hf_oran_mc_scale_re_mask_re10_even,
9417 { "RE 10", "oran_fh_cus.mcscalermask-RE10",
9418 FT_BOOLEAN, 16,
9419 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0004,
9420 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9421 },
9422 { &hf_oran_mc_scale_re_mask_re11_even,
9423 { "RE 11", "oran_fh_cus.mcscalermask-RE11",
9424 FT_BOOLEAN, 16,
9425 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0002,
9426 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9427 },
9428 { &hf_oran_mc_scale_re_mask_re12_even,
9429 { "RE 12", "oran_fh_cus.mcscalermask-RE12",
9430 FT_BOOLEAN, 16,
9431 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0001,
9432 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9433 },
9434
9435 { &hf_oran_mc_scale_re_mask,
9436 { "mcScaleReMask", "oran_fh_cus.mcscaleremask",
9437 FT_UINT16, BASE_HEX,
9438 NULL((void*)0), 0xfff0,
9439 "modulation compression power scale RE mask", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9440 },
9441 { &hf_oran_mc_scale_re_mask_even,
9442 { "mcScaleReMask", "oran_fh_cus.mcscaleremask",
9443 FT_UINT16, BASE_HEX,
9444 NULL((void*)0), 0x0fff,
9445 "modulation compression power scale RE mask", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9446 },
9447
9448 /* mcScaleOffset 7.7.5.4 (15 bits) */
9449 { &hf_oran_mc_scale_offset,
9450 { "mcScaleOffset", "oran_fh_cus.mcscaleoffset",
9451 FT_UINT24, BASE_DEC,
9452 NULL((void*)0), 0x0,
9453 "scaling value for modulation compression", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9454 },
9455 /* eAxCmask (7.7.7.2) */
9456 { &hf_oran_eAxC_mask,
9457 { "eAxC Mask", "oran_fh_cus.eaxcmask",
9458 FT_UINT16, BASE_HEX,
9459 NULL((void*)0), 0xffff,
9460 "Which eAxC_ID values the C-Plane message applies to", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9461 },
9462 /* technology (interface name) 7.7.9.2 */
9463 { &hf_oran_technology,
9464 { "Technology", "oran_fh_cus.technology",
9465 FT_UINT8, BASE_DEC,
9466 VALS(interface_name_vals)((0 ? (const struct _value_string*)0 : ((interface_name_vals)
)))
, 0x0,
9467 "Interface name (that C-PLane section applies to)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9468 },
9469 /* Exttype 14 (7.7.14.2) */
9470 { &hf_oran_nullLayerInd,
9471 { "nullLayerInd", "oran_fh_cus.nulllayerind",
9472 FT_BOOLEAN, BASE_NONE,
9473 NULL((void*)0), 0x0,
9474 "Whether corresponding layer is nulling-layer or not", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9475 },
9476
9477 /* Exttype 19 */
9478 /* 7.7.19.3 */
9479 { &hf_oran_se19_repetition,
9480 { "repetition", "oran_fh_cus.repetition",
9481 FT_BOOLEAN, BASE_NONE,
9482 TFS(&repetition_se19_tfs)((0 ? (const struct true_false_string*)0 : ((&repetition_se19_tfs
))))
, 0x0,
9483 "repeat port info flag", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9484 },
9485 /* 7.7.19.8 */
9486 /* TODO: break down into each RE as done for 7.5.3.5 ? */
9487 { &hf_oran_portReMask,
9488 { "portReMask", "oran_fh_cus.portReMask",
9489 FT_BOOLEAN, 16,
9490 TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, 0x0fff,
9491 "RE bitmask per port", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9492 },
9493 /* 7.7.19.9 */
9494 { &hf_oran_portSymbolMask,
9495 { "portSymbolMask", "oran_fh_cus.portSymbolMask",
9496 FT_BOOLEAN, 16,
9497 TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, 0x3fff,
9498 "Symbol bitmask port port", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9499 },
9500
9501 { &hf_oran_ext19_port,
9502 {"Port", "oran_fh_cus.ext19.port",
9503 FT_STRING, BASE_NONE,
9504 NULL((void*)0), 0x0,
9505 "Entry for a given port in ext19", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9506 },
9507
9508 /* Ext 13 */
9509 { &hf_oran_prb_allocation,
9510 {"PRB allocation", "oran_fh_cus.prb-allocation",
9511 FT_STRING, BASE_NONE,
9512 NULL((void*)0), 0x0,
9513 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9514 },
9515 /* 7.7.13.2 */
9516 { &hf_oran_nextSymbolId,
9517 { "nextSymbolId", "oran_fh_cus.nextSymbolId",
9518 FT_UINT8, BASE_DEC,
9519 NULL((void*)0), 0x3c,
9520 "offset of PRB range start", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9521 },
9522 /* 7.7.13.3 */
9523 { &hf_oran_nextStartPrbc,
9524 { "nextStartPrbc", "oran_fh_cus.nextStartPrbc",
9525 FT_UINT16, BASE_DEC,
9526 NULL((void*)0), 0x03ff,
9527 "number of PRBs in PRB range", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9528 },
9529
9530 /* Puncturing patters as appears in SE 20 */
9531 { &hf_oran_puncPattern,
9532 { "puncPattern", "oran_fh_cus.puncPattern",
9533 FT_STRING, BASE_NONE,
9534 NULL((void*)0), 0x0,
9535 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9536 },
9537
9538 /* 7.7.20.2 numPuncPatterns */
9539 { &hf_oran_numPuncPatterns,
9540 { "numPuncPatterns", "oran_fh_cus.numPuncPatterns",
9541 FT_UINT8, BASE_DEC,
9542 NULL((void*)0), 0x0,
9543 "number of puncturing patterns", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9544 },
9545 /* 7.7.20.3 symbolMask */
9546 { &hf_oran_symbolMask_ext20,
9547 { "symbolMask", "oran_fh_cus.symbolMask",
9548 FT_UINT16, BASE_HEX,
9549 NULL((void*)0), 0xfffc,
9550 "Bitmask where each bit indicates the symbols associated with the puncturing pattern", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9551 },
9552 /* 7.7.20.4 startPuncPrb */
9553 { &hf_oran_startPuncPrb,
9554 { "startPuncPrb", "oran_fh_cus.startPuncPrb",
9555 FT_UINT16, BASE_DEC,
9556 NULL((void*)0), 0x03ff,
9557 "starting PRB to which one puncturing pattern applies", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9558 },
9559 /* 7.7.20.5 numPuncPrb */
9560 { &hf_oran_numPuncPrb,
9561 { "numPuncPrb", "oran_fh_cus.numPuncPrb",
9562 FT_UINT8, BASE_DEC,
9563 NULL((void*)0), 0x0,
9564 "the number of PRBs of the puncturing pattern", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9565 },
9566 /* 7.7.20.6 puncReMask */
9567 { &hf_oran_puncReMask,
9568 { "puncReMask", "oran_fh_cus.puncReMask",
9569 FT_UINT16, BASE_DEC,
9570 NULL((void*)0), 0xffc0,
9571 "puncturing pattern RE mask", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9572 },
9573 /* 7.7.20.12 multiSDScope */
9574 { &hf_oran_multiSDScope,
9575 { "multiSDScope", "oran_fh_cus.multiSDScope",
9576 FT_BOOLEAN, 8,
9577 TFS(&multi_sd_scope_tfs)((0 ? (const struct true_false_string*)0 : ((&multi_sd_scope_tfs
))))
, 0x02,
9578 "multiple section description scope flag", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9579 },
9580 /* 7.7.20.4 rbgIncl */
9581 { &hf_oran_RbgIncl,
9582 { "rbgIncl", "oran_fh_cus.rbgIncl",
9583 FT_BOOLEAN, 8,
9584 NULL((void*)0), 0x01,
9585 "rbg included flag", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9586 },
9587
9588 /* 7.7.21.2 ciPrbGroupSize */
9589 { &hf_oran_ci_prb_group_size,
9590 { "ciPrbGroupSize", "oran_fh_cus.ciPrbGroupSize",
9591 FT_UINT8, BASE_DEC,
9592 NULL((void*)0), 0x0,
9593 "channel information PRB group size", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9594 },
9595 /* 7.21.3 */
9596 { &hf_oran_prg_size_st5,
9597 { "prgSize", "oran_fh_cus.prgSize",
9598 FT_UINT8, BASE_DEC,
9599 VALS(prg_size_st5_vals)((0 ? (const struct _value_string*)0 : ((prg_size_st5_vals)))
)
, 0x03,
9600 "precoding resource block group size", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9601 },
9602 { &hf_oran_prg_size_st6,
9603 { "prgSize", "oran_fh_cus.prgSize",
9604 FT_UINT8, BASE_DEC,
9605 VALS(prg_size_st6_vals)((0 ? (const struct _value_string*)0 : ((prg_size_st6_vals)))
)
, 0x03,
9606 "precoding resource block group size", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9607 },
9608
9609 /* 7.7.17.2 numUeID */
9610 { &hf_oran_num_ueid,
9611 { "numUeID", "oran_fh_cus.numUeID",
9612 FT_UINT8, BASE_DEC,
9613 NULL((void*)0), 0x0,
9614 "number of ueIDs per user", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9615 },
9616
9617 /* 7.7.16.2 antMask */
9618 { &hf_oran_antMask,
9619 { "antMask", "oran_fh_cus.antMask",
9620 FT_UINT64, BASE_HEX,
9621 NULL((void*)0), 0xffffffffffffffff,
9622 "indices of antennas to be pre-combined per RX endpoint", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9623 },
9624
9625 /* 7.7.18.2 transmissionWindowOffset */
9626 { &hf_oran_transmissionWindowOffset,
9627 { "transmissionWindowOffset", "oran_fh_cus.transmissionWindowOffset",
9628 FT_UINT16, BASE_DEC,
9629 NULL((void*)0), 0x0,
9630 "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)}
9631 },
9632 /* 7.7.18.3 transmissionWindowSize */
9633 { &hf_oran_transmissionWindowSize,
9634 { "transmissionWindowSize", "oran_fh_cus.transmissionWindowSize",
9635 FT_UINT16, BASE_DEC,
9636 NULL((void*)0), 0x3fff,
9637 "size of the transmission window in resolution µs", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9638 },
9639 /* 7.7.18.4 toT */
9640 { &hf_oran_toT,
9641 { "toT", "oran_fh_cus.toT",
9642 FT_UINT8, BASE_DEC,
9643 VALS(type_of_transmission_vals)((0 ? (const struct _value_string*)0 : ((type_of_transmission_vals
))))
, 0x03,
9644 "type of transmission", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9645 },
9646
9647 /* 7.7.2.2 bfaCompHdr */
9648 { &hf_oran_bfaCompHdr,
9649 { "bfaCompHdr", "oran_fh_cus.bfaCompHdr",
9650 FT_STRING, BASE_NONE,
9651 NULL((void*)0), 0x0,
9652 "beamforming attributes compression header", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9653 },
9654 /* 7.7.2.2-2: bfAzPtWidth */
9655 { &hf_oran_bfAzPtWidth,
9656 { "bfAzPtWidth", "oran_fh_cus.bfAzPtWidth",
9657 FT_UINT8, BASE_DEC,
9658 VALS(bfa_bw_vals)((0 ? (const struct _value_string*)0 : ((bfa_bw_vals)))), 0x38,
9659 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9660 },
9661 /* 7.7.2.2-3: bfZePtWidth */
9662 { &hf_oran_bfZePtWidth,
9663 { "bfZePtWidth", "oran_fh_cus.bfZePtWidth",
9664 FT_UINT8, BASE_DEC,
9665 VALS(bfa_bw_vals)((0 ? (const struct _value_string*)0 : ((bfa_bw_vals)))), 0x07,
9666 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9667 },
9668 /* 7.7.2.2-4: bfAz3ddWidth */
9669 { &hf_oran_bfAz3ddWidth,
9670 { "bfAz3ddWidth", "oran_fh_cus.bfAz3ddWidth",
9671 FT_UINT8, BASE_DEC,
9672 VALS(bfa_bw_vals)((0 ? (const struct _value_string*)0 : ((bfa_bw_vals)))), 0x38,
9673 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9674 },
9675 /* 7.7.2.2-5: bfZe3ddWidth */
9676 { &hf_oran_bfZe3ddWidth,
9677 { "bfZe3ddWidth", "oran_fh_cus.bfZe3ddWidth",
9678 FT_UINT8, BASE_DEC,
9679 VALS(bfa_bw_vals)((0 ? (const struct _value_string*)0 : ((bfa_bw_vals)))), 0x07,
9680 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9681 },
9682
9683 /* 7.7.2.3 bfAzPt */
9684 { &hf_oran_bfAzPt,
9685 { "bfAzPt", "oran_fh_cus.bfAzPt",
9686 FT_UINT8, BASE_DEC,
9687 NULL((void*)0), 0x0,
9688 "beamforming azimuth pointing parameter", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9689 },
9690 /* 7.7.2.4 bfZePt */
9691 { &hf_oran_bfZePt,
9692 { "bfZePt", "oran_fh_cus.bfZePt",
9693 FT_UINT8, BASE_DEC,
9694 NULL((void*)0), 0x0,
9695 "beamforming zenith pointing parameter", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9696 },
9697 /* 7.7.2.5 bfAz3dd */
9698 { &hf_oran_bfAz3dd,
9699 { "bfAz3dd", "oran_fh_cus.bfAz3dd",
9700 FT_UINT8, BASE_DEC,
9701 NULL((void*)0), 0x0,
9702 "beamforming azimuth beamwidth parameter", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9703 },
9704 /* 7.7.2.6 bfZe3dd */
9705 { &hf_oran_bfZe3dd,
9706 { "bfZe3dd", "oran_fh_cus.bfZe3dd",
9707 FT_UINT8, BASE_DEC,
9708 NULL((void*)0), 0x0,
9709 "beamforming zenith beamwidth parameter", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9710 },
9711
9712 /* 7.7.2.7 bfAzSl */
9713 { &hf_oran_bfAzSl,
9714 { "bfAzSl", "oran_fh_cus.bfAzSl",
9715 FT_UINT8, BASE_DEC,
9716 VALS(sidelobe_suppression_vals)((0 ? (const struct _value_string*)0 : ((sidelobe_suppression_vals
))))
, 0x38,
9717 "beamforming azimuth sidelobe parameter", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9718 },
9719 /* 7.7.2.8 bfZeSl */
9720 { &hf_oran_bfZeSl,
9721 { "bfZeSl", "oran_fh_cus.bfZeSl",
9722 FT_UINT8, BASE_DEC,
9723 VALS(sidelobe_suppression_vals)((0 ? (const struct _value_string*)0 : ((sidelobe_suppression_vals
))))
, 0x07,
9724 "beamforming zenith sidelobe parameter", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9725 },
9726
9727 /* 7.5.2.17 */
9728 { &hf_oran_cmd_scope,
9729 { "cmdScope", "oran_fh_cus.cmdScope",
9730 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
9731 RVALS(cmd_scope_vals)((0 ? (const struct _range_string*)0 : ((cmd_scope_vals)))), 0x0f,
9732 "command scope", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9733 },
9734 /* 7.5.2.18 */
9735 { &hf_oran_number_of_st4_cmds,
9736 { "numberOfST4Cmds", "oran_fh_cus.numberOfST4Cmds",
9737 FT_UINT8, BASE_DEC,
9738 NULL((void*)0), 0x0,
9739 "Number of Section Type 4 commands", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9740 },
9741
9742 { &hf_oran_st4_cmd_header,
9743 { "Command common header", "oran_fh_cus.st4CmdCommonHeader",
9744 FT_STRING, BASE_NONE,
9745 NULL((void*)0), 0x0,
9746 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9747 },
9748
9749 /* 7.5.3.38 */
9750 { &hf_oran_st4_cmd_type,
9751 { "st4CmdType", "oran_fh_cus.st4CmdType",
9752 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
9753 RVALS(st4_cmd_type_vals)((0 ? (const struct _range_string*)0 : ((st4_cmd_type_vals)))
)
, 0x0,
9754 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9755 },
9756 /* 7.5.3.39 */
9757 { &hf_oran_st4_cmd_len,
9758 { "st4CmdLen", "oran_fh_cus.st4CmdLen",
9759 FT_UINT16, BASE_DEC,
9760 NULL((void*)0), 0x0,
9761 "Length of command in 32-bit words", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9762 },
9763 /* 7.5.3.40 */
9764 { &hf_oran_st4_cmd_num_slots,
9765 { "numSlots", "oran_fh_cus.st4NumSlots",
9766 FT_UINT8, BASE_DEC,
9767 NULL((void*)0), 0x0,
9768 "Contiguous slots for which command is applicable", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9769 },
9770 /* 7.5.3.41 */
9771 { &hf_oran_st4_cmd_ack_nack_req_id,
9772 { "ackNackReqId", "oran_fh_cus.ackNackReqId",
9773 FT_UINT16, BASE_DEC,
9774 NULL((void*)0), 0x0,
9775 "ACK/NACK Request Id", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9776 },
9777
9778 { &hf_oran_st4_cmd,
9779 { "Command", "oran_fh_cus.st4Cmd",
9780 FT_STRING, BASE_NONE,
9781 NULL((void*)0), 0x0,
9782 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9783 },
9784
9785 /* 7.5.3.52 */
9786 { &hf_oran_sleepmode_trx,
9787 { "sleepMode", "oran_fh_cus.sleepMode",
9788 FT_UINT8, BASE_HEX,
9789 VALS(sleep_mode_trx_vals)((0 ? (const struct _value_string*)0 : ((sleep_mode_trx_vals)
)))
, 0x03,
9790 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9791 },
9792 { &hf_oran_sleepmode_asm,
9793 { "sleepMode", "oran_fh_cus.sleepMode",
9794 FT_UINT8, BASE_HEX,
9795 VALS(sleep_mode_asm_vals)((0 ? (const struct _value_string*)0 : ((sleep_mode_asm_vals)
)))
, 0x03,
9796 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9797 },
9798
9799 /* 7.5.3.51 */
9800 { &hf_oran_log2maskbits,
9801 { "log2MaskBits", "oran_fh_cus.log2MaskBits",
9802 FT_UINT8, BASE_HEX,
9803 VALS(log2maskbits_vals)((0 ? (const struct _value_string*)0 : ((log2maskbits_vals)))
)
, 0x3c,
9804 "Number of bits to appear in antMask", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9805 },
9806 /* 7.5.3.53 */
9807 { &hf_oran_num_slots_ext,
9808 { "numSlotsExt", "oran_fh_cus.numSlotsExt",
9809 FT_UINT24, BASE_HEX,
9810 NULL((void*)0), 0x0fffff,
9811 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9812 },
9813 /* 7.5.3.54 */
9814 { &hf_oran_antMask_trx_control,
9815 { "antMask", "oran_fh_cus.trxControl.antMask",
9816 FT_BYTES, BASE_NONE,
9817 NULL((void*)0), 0x0,
9818 "which antennas should sleep or wake-up", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9819 },
9820 /* 7.5.3.55 */
9821 { &hf_oran_ready,
9822 { "ready", "oran_fh_cus.ready",
9823 FT_BOOLEAN, 8,
9824 TFS(&ready_tfs)((0 ? (const struct true_false_string*)0 : ((&ready_tfs))
))
, 0x01,
9825 "wake-up ready indicator", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9826 },
9827 /* 7.5.3.34 */
9828 { &hf_oran_number_of_acks,
9829 { "numberOfAcks", "oran_fh_cus.numberOfAcks",
9830 FT_UINT8, BASE_DEC,
9831 NULL((void*)0), 0x0,
9832 "number of ACKs for one eAxC_ID", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9833 },
9834 /* 7.5.3.35 */
9835 { &hf_oran_number_of_nacks,
9836 { "numberOfNacks", "oran_fh_cus.numberOfNacks",
9837 FT_UINT8, BASE_DEC,
9838 NULL((void*)0), 0x0,
9839 "number of NACKs for one eAxC_ID", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9840 },
9841 /* 7.5.3.36 */
9842 { &hf_oran_ackid,
9843 { "ackId", "oran_fh_cus.ackId",
9844 FT_UINT16, BASE_DEC,
9845 NULL((void*)0), 0x0,
9846 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9847 },
9848 /* 7.5.3.37 */
9849 { &hf_oran_nackid,
9850 { "nackId", "oran_fh_cus.nackId",
9851 FT_UINT16, BASE_DEC,
9852 NULL((void*)0), 0x0,
9853 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9854 },
9855
9856 /* Links between acknack requests & responses */
9857 { &hf_oran_acknack_request_frame,
9858 { "Request Frame", "oran_fh_cus.ackNackId.request-frame",
9859 FT_FRAMENUM, BASE_NONE,
9860 FRAMENUM_TYPE(FT_FRAMENUM_REQUEST)((gpointer) (glong) (FT_FRAMENUM_REQUEST)), 0x0,
9861 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9862 },
9863 { &hf_oran_acknack_request_time,
9864 { "Time since request in ms", "oran_fh_cus.ackNackId.time-since-request",
9865 FT_UINT32, BASE_DEC,
9866 NULL((void*)0), 0x0,
9867 "Time between request and response", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9868 },
9869 { &hf_oran_acknack_request_type,
9870 { "Request Type", "oran_fh_cus.ackNackId.request-type",
9871 FT_UINT32, BASE_DEC,
9872 VALS(acknack_type_vals)((0 ? (const struct _value_string*)0 : ((acknack_type_vals)))
)
, 0x0,
9873 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9874 },
9875 { &hf_oran_acknack_response_frame,
9876 { "Response Frame", "oran_fh_cus.ackNackId.response-frame",
9877 FT_FRAMENUM, BASE_NONE,
9878 FRAMENUM_TYPE(FT_FRAMENUM_RESPONSE)((gpointer) (glong) (FT_FRAMENUM_RESPONSE)), 0x0,
9879 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9880 },
9881 { &hf_oran_acknack_response_time,
9882 { "Time to response in ms", "oran_fh_cus.ackNackId.time-to-response",
9883 FT_UINT32, BASE_DEC,
9884 NULL((void*)0), 0x0,
9885 "Time between request and response", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9886 },
9887
9888 /* 7.5.3.43 */
9889 { &hf_oran_disable_tdbfns,
9890 { "disableTDBFNs", "oran_fh_cus.disableTDBFNs",
9891 FT_BOOLEAN, 8,
9892 TFS(&disable_tdbfns_tfs)((0 ? (const struct true_false_string*)0 : ((&disable_tdbfns_tfs
))))
, 0x80,
9893 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9894 },
9895
9896 /* 7.5.3.44 */
9897 { &hf_oran_td_beam_group,
9898 { "tdBeamGrp", "oran_fh_cus.tdBeamGrp",
9899 FT_UINT16, BASE_HEX,
9900 NULL((void*)0), 0x7fff,
9901 "Applies to symbolMask in command header", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9902 },
9903 /* 7.5.3.43 */
9904 { &hf_oran_disable_tdbfws,
9905 { "disableTDBFWs", "oran_fh_cus.disableTDBFWs",
9906 FT_BOOLEAN, 8,
9907 TFS(&beam_numbers_included_tfs)((0 ? (const struct true_false_string*)0 : ((&beam_numbers_included_tfs
))))
, 0x80,
9908 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9909 },
9910
9911 /* 7.5.3.56 */
9912 { &hf_oran_td_beam_num,
9913 { "tdBeamNum", "oran_fh_cus.tdBeamNum",
9914 FT_UINT16, BASE_HEX,
9915 NULL((void*)0), 0x7fff,
9916 "time-domain beam number", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9917 },
9918
9919 /* 7.5.3.49 */
9920 { &hf_oran_dir_pattern,
9921 { "dirPattern", "oran_fh_cus.dirPattern",
9922 FT_BOOLEAN, 16,
9923 TFS(&symbol_direction_tfs)((0 ? (const struct true_false_string*)0 : ((&symbol_direction_tfs
))))
, 0x3fff,
9924 "symbol data direction (gNB Tx/Rx) pattern", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9925 },
9926 /* 7.5.3.50 */
9927 { &hf_oran_guard_pattern,
9928 { "guardPattern", "oran_fh_cus.guardPattern",
9929 FT_BOOLEAN, 16,
9930 TFS(&symbol_guard_tfs)((0 ? (const struct true_false_string*)0 : ((&symbol_guard_tfs
))))
, 0x3fff,
9931 "guard pattern bitmask", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9932 },
9933
9934 /* For convenient filtering */
9935 { &hf_oran_cplane,
9936 { "C-Plane", "oran_fh_cus.c-plane",
9937 FT_NONE, BASE_NONE,
9938 NULL((void*)0), 0x0,
9939 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9940 },
9941 { &hf_oran_uplane,
9942 { "U-Plane", "oran_fh_cus.u-plane",
9943 FT_NONE, BASE_NONE,
9944 NULL((void*)0), 0x0,
9945 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9946 },
9947 { &hf_oran_bf,
9948 { "BeamForming", "oran_fh_cus.bf",
9949 FT_NONE, BASE_NONE,
9950 NULL((void*)0), 0x0,
9951 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9952 },
9953 { &hf_oran_zero_prb,
9954 { "Zero PRB", "oran_fh_cus.zero-prb",
9955 FT_NONE, BASE_NONE,
9956 NULL((void*)0), 0x0,
9957 "All of the REs in this PRB are zero", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9958 },
9959 { &hf_oran_nonzero_prb,
9960 { "Non-Zero PRB", "oran_fh_cus.nonzero-prb",
9961 FT_NONE, BASE_NONE,
9962 NULL((void*)0), 0x0,
9963 "Not all of the REs in this PRB are zero", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9964 },
9965 { &hf_oran_bundle_weights_all_zero,
9966 { "Bundle Weights all zero", "oran_fh_cus.zero-bundle",
9967 FT_NONE, BASE_NONE,
9968 NULL((void*)0), 0x0,
9969 "All of the weights in a bundle are zero", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9970 },
9971
9972
9973 /* 5.1.3.2.7 */
9974 { &hf_oran_ecpri_pcid,
9975 { "ecpriPcid", "oran_fh_cus.ecpriPcid",
9976 FT_NONE, BASE_NONE,
9977 NULL((void*)0), 0x0,
9978 "IQ data transfer message series identifier", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9979 },
9980 { &hf_oran_ecpri_rtcid,
9981 { "ecpriRtcid", "oran_fh_cus.ecpriRtcid",
9982 FT_NONE, BASE_NONE,
9983 NULL((void*)0), 0x0,
9984 "Real time control data identifier", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9985 },
9986 /* 5.1.3.2.8 */
9987 { &hf_oran_ecpri_seqid,
9988 { "ecpriSeqid", "oran_fh_cus.ecpriSeqid",
9989 FT_NONE, BASE_NONE,
9990 NULL((void*)0), 0x0,
9991 "message identifier", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9992 },
9993
9994 /* 7.7.23.2 */
9995 { &hf_oran_num_sym_prb_pattern,
9996 { "numSymPrbPattern", "oran_fh_cus.numSymPrbPattern",
9997 FT_UINT8, BASE_DEC,
9998 NULL((void*)0), 0xf0,
9999 "number of symbol and resource block patterns", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10000 },
10001 /* 7.7.23.9 */
10002 { &hf_oran_prb_mode,
10003 { "prbMode", "oran_fh_cus.prbMode",
10004 FT_BOOLEAN, 8,
10005 TFS(&prb_mode_tfs)((0 ? (const struct true_false_string*)0 : ((&prb_mode_tfs
))))
, 0x01,
10006 "PRB Mode", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10007 },
10008 /* 7.7.23.4 */
10009 { &hf_oran_sym_prb_pattern,
10010 { "symPrbPattern", "oran_fh_cus.symPrbPattern",
10011 FT_STRING, BASE_NONE,
10012 NULL((void*)0), 0x0,
10013 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10014 },
10015 /* 7.7.23.3 */
10016 { &hf_oran_sym_mask,
10017 { "symMask", "oran_fh_cus.symMask",
10018 FT_UINT16, BASE_HEX,
10019 NULL((void*)0), 0x3fff,
10020 "symbol mask part of symPrbPattern", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10021 },
10022 /* 7.7.23.5 */
10023 {&hf_oran_num_mc_scale_offset,
10024 {"numMcScaleOffset", "oran_fh_cus.numMcScaleOffset",
10025 FT_UINT8, BASE_DEC,
10026 NULL((void*)0), 0xf0,
10027 "number of modulation compression scaling value per symPrbPattern",
10028 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10029 },
10030 /* 7.7.23.4 */
10031 { &hf_oran_prb_pattern,
10032 { "prbPattern", "oran_fh_cus.prbPattern",
10033 FT_UINT8, BASE_DEC,
10034 NULL((void*)0), 0x0f,
10035 "size of one PRB block of one SymPrbPattern", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10036 },
10037 /* 7.7.23.10 */
10038 { &hf_oran_prb_blk_offset,
10039 { "prbBlkOffset", "oran_fh_cus.prbBlkOffset",
10040 FT_UINT16, BASE_DEC,
10041 NULL((void*)0), 0x0ff0,
10042 "offset to start of PRB block", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10043 },
10044
10045 /* 7.7.23.11 */
10046 { &hf_oran_prb_blk_size,
10047 { "prbBlkSize", "oran_fh_cus.prbBlkSize",
10048 FT_UINT16, BASE_DEC,
10049 NULL((void*)0), 0x0ff0,
10050 "size of one PRB block of one SymPrbPattern", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10051 },
10052
10053 /* 7.7.3.2 */
10054 { &hf_oran_codebook_index,
10055 { "codebookIndex", "oran_fh_cus.codebookIndex",
10056 FT_UINT8, BASE_DEC,
10057 NULL((void*)0), 0x0,
10058 "precoder codebook used for transmission", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10059 },
10060 /* 7.7.3.3 */
10061 { &hf_oran_layerid,
10062 { "layerID", "oran_fh_cus.layerID",
10063 FT_UINT8, BASE_DEC,
10064 NULL((void*)0), 0xf0,
10065 "Layer ID for DL transmission", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10066 },
10067 /* 7.7.3.5 */
10068 { &hf_oran_numlayers,
10069 { "numLayers", "oran_fh_cus.numLayers",
10070 FT_UINT8, BASE_DEC,
10071 NULL((void*)0), 0x0f,
10072 "number of layers for DL transmission", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10073 },
10074 /* 7.7.3.4 */
10075 { &hf_oran_txscheme,
10076 { "txScheme", "oran_fh_cus.txScheme",
10077 FT_UINT8, BASE_DEC,
10078 NULL((void*)0), 0xf0,
10079 "transmission scheme", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10080 },
10081 /* 7.7.3.6 */
10082 { &hf_oran_crs_remask,
10083 { "crsReMask", "oran_fh_cus.crsReMask",
10084 FT_UINT16, BASE_HEX,
10085 NULL((void*)0), 0x0fff,
10086 "CRS resource element mask", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10087 },
10088 /* 7.7.3.8 */
10089 { &hf_oran_crs_shift,
10090 { "crsShift", "oran_fh_cus.crsShift",
10091 FT_UINT8, BASE_HEX,
10092 NULL((void*)0), 0x80,
10093 "CRS resource element mask", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10094 },
10095 /* 7.7.3.7 */
10096 { &hf_oran_crs_symnum,
10097 { "crsSymNum", "oran_fh_cus.crsSymNum",
10098 FT_UINT8, BASE_DEC,
10099 NULL((void*)0), 0x0f,
10100 "CRS symbol number indication", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10101 },
10102 /* 7.7.3.9 */
10103 { &hf_oran_beamid_ap1,
10104 { "beamIdAP1", "oran_fh_cus.beamIdAP1",
10105 FT_UINT16, BASE_DEC,
10106 NULL((void*)0), 0x7f,
10107 "beam id to be used for antenna port 1", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10108 },
10109 /* 7.7.3.10 */
10110 { &hf_oran_beamid_ap2,
10111 { "beamIdAP2", "oran_fh_cus.beamIdAP2",
10112 FT_UINT16, BASE_DEC,
10113 NULL((void*)0), 0x7f,
10114 "beam id to be used for antenna port 2", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10115 },
10116 /* 7.7.3.11 */
10117 { &hf_oran_beamid_ap3,
10118 { "beamIdAP3", "oran_fh_cus.beamIdAP3",
10119 FT_UINT16, BASE_DEC,
10120 NULL((void*)0), 0x7f,
10121 "beam id to be used for antenna port 3", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10122 },
10123
10124 /* 7.7.10.3a */
10125 { &hf_oran_port_list_index,
10126 { "portListIndex", "oran_fh_cus.portListIndex",
10127 FT_UINT8, BASE_DEC,
10128 NULL((void*)0), 0x0,
10129 "the index of an eAxC_ID in the port-list", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10130 },
10131
10132 { &hf_oran_alpn_per_sym,
10133 { "alpnPerSym", "oran_fh_cus.alpnPerSym",
10134 FT_UINT8, BASE_HEX,
10135 VALS(alpn_per_sym_vals)((0 ? (const struct _value_string*)0 : ((alpn_per_sym_vals)))
)
, 0x80,
10136 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10137 },
10138 { &hf_oran_ant_dmrs_snr,
10139 { "antDmrsSnr", "oran_fh_cus.antDmrsSnr",
10140 FT_UINT8, BASE_HEX,
10141 VALS(ant_dmrs_snr_vals)((0 ? (const struct _value_string*)0 : ((ant_dmrs_snr_vals)))
)
, 0x40,
10142 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10143 },
10144
10145 /* 7.7.24.6 */
10146 { &hf_oran_user_group_size,
10147 { "userGroupSize", "oran_fh_cus.userGroupSize",
10148 FT_UINT8, BASE_DEC,
10149 NULL((void*)0), 0x1f,
10150 "number of UE data layers in the user group identified by userGroupId", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10151 },
10152 /* 7.7.24.7 */
10153 { &hf_oran_user_group_id,
10154 { "userGroupId", "oran_fh_cus.userGroupId",
10155 FT_UINT8, BASE_DEC,
10156 NULL((void*)0), 0x0,
10157 "indicates user group described by the section", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10158 },
10159 /* 7.7.24.8 */
10160 { &hf_oran_entry_type,
10161 { "entryType", "oran_fh_cus.entryType",
10162 FT_UINT8, BASE_DEC,
10163 VALS(entry_type_vals)((0 ? (const struct _value_string*)0 : ((entry_type_vals)))), 0xe0,
10164 "indicates format of the entry", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10165 },
10166 /* 7.7.24.9 */
10167 { &hf_oran_dmrs_port_number,
10168 { "dmrsPortNumber", "oran_fh_cus.dmrsPortNumber",
10169 FT_UINT8, BASE_DEC,
10170 NULL((void*)0), 0x1f,
10171 "DMRS antenna port number for the associated ueId", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10172 },
10173 /* 7.7.24.10 */
10174 { &hf_oran_ueid_reset,
10175 { "ueidReset", "oran_fh_cus.ueidReset",
10176 FT_BOOLEAN, 8,
10177 TFS(&tfs_ueid_reset)((0 ? (const struct true_false_string*)0 : ((&tfs_ueid_reset
))))
, 0x80,
10178 "same UEID as the previous slot", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10179 },
10180 /* 7.7.24.11 */
10181 { &hf_oran_dmrs_symbol_mask,
10182 { "dmrsSymbolMask", "oran_fh_cus.dmrsSymbolMask",
10183 FT_UINT16, BASE_HEX,
10184 NULL((void*)0), 0x3fff,
10185 "symbols within the slot containing DMRS", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10186 },
10187 { &hf_oran_dmrs_symbol_mask_s13,
10188 { "symbol 13", "oran_fh_cus.dmrsSymbolMask.symbol-13",
10189 FT_BOOLEAN, 16,
10190 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x2000,
10191 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10192 },
10193 { &hf_oran_dmrs_symbol_mask_s12,
10194 { "symbol 12", "oran_fh_cus.dmrsSymbolMask.symbol-12",
10195 FT_BOOLEAN, 16,
10196 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x1000,
10197 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10198 },
10199 { &hf_oran_dmrs_symbol_mask_s11,
10200 { "symbol 11", "oran_fh_cus.dmrsSymbolMask.symbol-11",
10201 FT_BOOLEAN, 16,
10202 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0800,
10203 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10204 },
10205 { &hf_oran_dmrs_symbol_mask_s10,
10206 { "symbol 10", "oran_fh_cus.dmrsSymbolMask.symbol-10",
10207 FT_BOOLEAN, 16,
10208 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0400,
10209 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10210 },
10211 { &hf_oran_dmrs_symbol_mask_s9,
10212 { "symbol 9", "oran_fh_cus.dmrsSymbolMask.symbol-9",
10213 FT_BOOLEAN, 16,
10214 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0200,
10215 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10216 },
10217 { &hf_oran_dmrs_symbol_mask_s8,
10218 { "symbol 8", "oran_fh_cus.dmrsSymbolMask.symbol-8",
10219 FT_BOOLEAN, 16,
10220 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0100,
10221 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10222 },
10223 { &hf_oran_dmrs_symbol_mask_s7,
10224 { "symbol 7", "oran_fh_cus.dmrsSymbolMask.symbol-7",
10225 FT_BOOLEAN, 16,
10226 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0080,
10227 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10228 },
10229 { &hf_oran_dmrs_symbol_mask_s6,
10230 { "symbol 6", "oran_fh_cus.dmrsSymbolMask.symbol-6",
10231 FT_BOOLEAN, 16,
10232 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0040,
10233 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10234 },
10235 { &hf_oran_dmrs_symbol_mask_s5,
10236 { "symbol 5", "oran_fh_cus.dmrsSymbolMask.symbol-5",
10237 FT_BOOLEAN, 16,
10238 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0020,
10239 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10240 },
10241 { &hf_oran_dmrs_symbol_mask_s4,
10242 { "symbol 4", "oran_fh_cus.dmrsSymbolMask.symbol-4",
10243 FT_BOOLEAN, 16,
10244 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0010,
10245 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10246 },
10247 { &hf_oran_dmrs_symbol_mask_s3,
10248 { "symbol 3", "oran_fh_cus.dmrsSymbolMask.symbol-3",
10249 FT_BOOLEAN, 16,
10250 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0008,
10251 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10252 },
10253 { &hf_oran_dmrs_symbol_mask_s2,
10254 { "symbol 2", "oran_fh_cus.dmrsSymbolMask.symbol-2",
10255 FT_BOOLEAN, 16,
10256 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0004,
10257 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10258 },
10259 { &hf_oran_dmrs_symbol_mask_s1,
10260 { "symbol 1", "oran_fh_cus.dmrsSymbolMask.symbol-1",
10261 FT_BOOLEAN, 16,
10262 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0002,
10263 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10264 },
10265 { &hf_oran_dmrs_symbol_mask_s0,
10266 { "symbol 0", "oran_fh_cus.dmrsSymbolMask.symbol-0",
10267 FT_BOOLEAN, 16,
10268 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0001,
10269 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10270 },
10271
10272 /* 7.7.24.12 */
10273 { &hf_oran_scrambling,
10274 { "scrambling", "oran_fh_cus.scrambling",
10275 FT_UINT16, BASE_HEX,
10276 NULL((void*)0), 0x0,
10277 "used to calculate the seed value required to initialize pseudo-random generator", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10278 },
10279 /* 7.7.24.13 */
10280 { &hf_oran_nscid,
10281 { "nscid", "oran_fh_cus.nscid",
10282 FT_UINT8, BASE_HEX,
10283 NULL((void*)0), 0x80,
10284 "used to calculate the seed value for pseudo-random generator", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10285 },
10286 /* 7.7.24.14 */
10287 { &hf_oran_dtype,
10288 { "dType", "oran_fh_cus.dType",
10289 FT_UINT8, BASE_HEX,
10290 VALS(dtype_vals)((0 ? (const struct _value_string*)0 : ((dtype_vals)))), 0x40,
10291 "PUSCH DMRS configuration type", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10292 },
10293 /* 7.7.24.15 */
10294 { &hf_oran_cmd_without_data,
10295 { "cmdWithoutData", "oran_fh_cus.cmdWithoutData",
10296 FT_UINT8, BASE_HEX,
10297 NULL((void*)0), 0x30,
10298 "number of DMRS CDM groups without data", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10299 },
10300 /* 7.7.24.16 */
10301 { &hf_oran_lambda,
10302 { "lambda", "oran_fh_cus.lambda",
10303 FT_UINT8, BASE_HEX,
10304 NULL((void*)0), 0x0c,
10305 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10306 },
10307 /* 7.7.24.19 */
10308 { &hf_oran_first_prb,
10309 { "firstPrb", "oran_fh_cus.firstPrb",
10310 FT_UINT16, BASE_DEC,
10311 NULL((void*)0), 0x03fe,
10312 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10313 },
10314 /* 7.7.24.20 */
10315 { &hf_oran_last_prb,
10316 { "lastPrb", "oran_fh_cus.lastPrb",
10317 FT_UINT16, BASE_DEC,
10318 NULL((void*)0), 0x01ff,
10319 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10320 },
10321
10322 /* 7.7.24.17 */
10323 /* TODO: add value_string */
10324 { &hf_oran_low_papr_type,
10325 { "lowPaprType", "oran_fh_cus.lowPaprType",
10326 FT_UINT8, BASE_HEX,
10327 VALS(papr_type_vals)((0 ? (const struct _value_string*)0 : ((papr_type_vals)))), 0x30,
10328 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10329 },
10330 /* 7.7.24.18 */
10331 { &hf_oran_hopping_mode,
10332 { "hoppingMode", "oran_fh_cus.hoppingMode",
10333 FT_UINT8, BASE_HEX,
10334 VALS(hopping_mode_vals)((0 ? (const struct _value_string*)0 : ((hopping_mode_vals)))
)
, 0x0c,
10335 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10336 },
10337
10338 { &hf_oran_tx_win_for_on_air_symbol_l,
10339 { "txWinForOnAirSymbol", "oran_fh_cus.txWinForOnAirSymbol",
10340 FT_UINT8, BASE_DEC,
10341 NULL((void*)0), 0xf0,
10342 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10343 },
10344 { &hf_oran_tx_win_for_on_air_symbol_r,
10345 { "txWinForOnAirSymbol", "oran_fh_cus.txWinForOnAirSymbol",
10346 FT_UINT8, BASE_DEC,
10347 NULL((void*)0), 0x0f,
10348 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10349 },
10350 /* 7.7.26.2 */
10351 { &hf_oran_num_fo_fb,
10352 { "numFoFb", "oran_fh_cus.numFoFb",
10353 FT_UINT8, BASE_DEC,
10354 NULL((void*)0), 0x7f,
10355 "number of frequency offset feedback", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10356 },
10357 /* 7.7.26.3 */
10358 { &hf_oran_freq_offset_fb,
10359 { "freqOffsetFb", "oran_fh_cus.freqOffsetFb",
10360 FT_UINT16, BASE_HEX_DEC | BASE_RANGE_STRING0x00000100,
10361 RVALS(freq_offset_fb_values)((0 ? (const struct _range_string*)0 : ((freq_offset_fb_values
))))
, 0x0,
10362 "UE frequency offset feedback", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10363 },
10364
10365 /* 7.7.28.2 */
10366 { &hf_oran_num_ue_sinr_rpt,
10367 { "numUeSinrRpt", "oran_fh_cus.numUeSinrRpt",
10368 FT_UINT8, BASE_DEC,
10369 NULL((void*)0), 0x1f,
10370 "number of sinr reported UEs {1 - 12}", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10371 },
10372
10373 /* 7.5.2.19 */
10374 { &hf_oran_num_sinr_per_prb,
10375 { "numSinrPerPrb", "oran_fh_cus.numSinrPerPrb",
10376 FT_UINT8, BASE_DEC,
10377 VALS(num_sinr_per_prb_vals)((0 ? (const struct _value_string*)0 : ((num_sinr_per_prb_vals
))))
, 0x70,
10378 "number of SINR values per PRB", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10379 },
10380 { &hf_oran_num_sinr_per_prb_right,
10381 { "numSinrPerPrb", "oran_fh_cus.numSinrPerPrb",
10382 FT_UINT8, BASE_DEC,
10383 VALS(num_sinr_per_prb_vals)((0 ? (const struct _value_string*)0 : ((num_sinr_per_prb_vals
))))
, 0x07,
10384 "number of SINR values per PRB", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10385 },
10386
10387 /* 7.5.3.68 */
10388 { &hf_oran_sinr_value,
10389 { "sinrValue", "oran_fh_cus.sinrValue",
10390 FT_FLOAT, BASE_NONE,
10391 NULL((void*)0), 0x0,
10392 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10393 },
10394
10395 { &hf_oran_measurement_report,
10396 { "Measurement Report", "oran_fh_cus.measurement-report",
10397 FT_STRING, BASE_NONE,
10398 NULL((void*)0), 0x0,
10399 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10400 },
10401 /* 7.5.3.57 */
10402 { &hf_oran_mf,
10403 { "mf", "oran_fh_cus.mf",
10404 FT_BOOLEAN, 8,
10405 TFS(&measurement_flag_tfs)((0 ? (const struct true_false_string*)0 : ((&measurement_flag_tfs
))))
, 0x80,
10406 "measurement flag", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10407 },
10408 /* 7.5.3.59 */
10409 { &hf_oran_meas_data_size,
10410 { "measDataSize", "oran_fh_cus.measDataSize",
10411 FT_UINT16, BASE_DEC,
10412 NULL((void*)0), 0x0,
10413 "measurement data size (in words)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10414 },
10415
10416 /* 7.5.3.58 */
10417 { &hf_oran_meas_type_id,
10418 { "measTypeId", "oran_fh_cus.measTypeId",
10419 FT_UINT8, BASE_DEC,
10420 VALS(meas_type_id_vals)((0 ? (const struct _value_string*)0 : ((meas_type_id_vals)))
)
, 0x7F,
10421 "measurement report type identifier", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10422 },
10423 /* 7.5.3.66 */
10424 { &hf_oran_num_elements,
10425 { "numElements", "oran_fh_cus.numElements",
10426 FT_UINT8, BASE_DEC,
10427 NULL((void*)0), 0x0,
10428 "measurement report type identifier", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10429 },
10430 /* 7.5.3.60 */
10431 { &hf_oran_ue_tae,
10432 { "ueTae", "oran_fh_cus.ueTae",
10433 FT_UINT16, BASE_DEC | BASE_RANGE_STRING0x00000100,
10434 RVALS(freq_offset_fb_values)((0 ? (const struct _range_string*)0 : ((freq_offset_fb_values
))))
, 0x0,
10435 "UE Timing Advance Error", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10436 },
10437 /* 7.5.3.61 */
10438 { &hf_oran_ue_layer_power,
10439 { "ueLayerPower", "oran_fh_cus.ueLayerPower",
10440 FT_UINT16, BASE_DEC | BASE_RANGE_STRING0x00000100,
10441 RVALS(freq_offset_fb_values)((0 ? (const struct _range_string*)0 : ((freq_offset_fb_values
))))
, 0x0,
10442 "UE Layer Power", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10443 },
10444
10445 /* 7.5.3.62 */
10446 { &hf_oran_ue_freq_offset,
10447 { "ueFreqOffset", "oran_fh_cus.ueFreqOffset",
10448 FT_UINT16, BASE_DEC | BASE_RANGE_STRING0x00000100,
10449 RVALS(freq_offset_fb_values)((0 ? (const struct _range_string*)0 : ((freq_offset_fb_values
))))
, 0x0,
10450 "UE frequency offset", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10451 },
10452 /* 7.5.3.63 */
10453 { &hf_oran_ipn_power,
10454 { "ipnPower", "oran_fh_cus.ipnPower",
10455 FT_UINT16, BASE_DEC | BASE_RANGE_STRING0x00000100,
10456 RVALS(freq_offset_fb_values)((0 ? (const struct _range_string*)0 : ((freq_offset_fb_values
))))
, 0x0,
10457 "Interference plus Noise power", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10458 },
10459 /* 7.5.3.64 */
10460 { &hf_oran_ant_dmrs_snr_val,
10461 { "antDmrsSnrVal", "oran_fh_cus.antDmrsSnrVal",
10462 FT_UINT16, BASE_DEC | BASE_RANGE_STRING0x00000100,
10463 RVALS(freq_offset_fb_values)((0 ? (const struct _range_string*)0 : ((freq_offset_fb_values
))))
, 0x0,
10464 "antenna DMRS-SNR", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10465 },
10466
10467 { &hf_oran_measurement_command,
10468 { "Measurement Command", "oran_fh_cus.measurement-command",
10469 FT_STRING, BASE_NONE,
10470 NULL((void*)0), 0x0,
10471 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10472 },
10473
10474 /* 7.5.27.2 */
10475 { &hf_oran_beam_type,
10476 {"beamType", "oran_fh_cus.beamType",
10477 FT_UINT16, BASE_DEC,
10478 VALS(beam_type_vals)((0 ? (const struct _value_string*)0 : ((beam_type_vals)))), 0xc0,
10479 NULL((void*)0),
10480 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10481 },
10482 /* 7.5.3.65 */
10483 { &hf_oran_meas_cmd_size,
10484 {"measCmdSize", "oran_fh_cus.measCmdSize",
10485 FT_UINT16, BASE_DEC,
10486 NULL((void*)0), 0x0,
10487 "measurement command size in words",
10488 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10489 },
10490
10491 { &hf_oran_symbol_reordering_layer,
10492 { "Layer", "oran_fh_cus.layer",
10493 FT_STRING, BASE_NONE,
10494 NULL((void*)0), 0x0,
10495 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10496 },
10497 { &hf_oran_dmrs_entry,
10498 { "Entry", "oran_fh_cus.dmrs-entry",
10499 FT_STRING, BASE_NONE,
10500 NULL((void*)0), 0x0,
10501 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10502 },
10503
10504 /* 7.7.29.3 */
10505 { &hf_oran_cd_scg_size,
10506 {"cdScgSize", "oran_fh_cus.cdScgSize",
10507 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
10508 RVALS(cd_scg_size_vals)((0 ? (const struct _range_string*)0 : ((cd_scg_size_vals)))), 0x0f,
10509 "Cyclic delay subcarrier group size",
10510 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10511 },
10512 /* 7.7.29.4 */
10513 { &hf_oran_cd_scg_phase_step,
10514 {"cdScgPhaseStep", "oran_fh_cus.cdScgPhaseStep",
10515 FT_INT8, BASE_DEC,
10516 NULL((void*)0), 0x0,
10517 "Cyclic delay subcarrier group phase step",
10518 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10519 },
10520
10521 { &hf_oran_sinr_prb,
10522 { "PRB", "oran_fh_cus.sinr.prb",
10523 FT_STRING, BASE_NONE,
10524 NULL((void*)0), 0x0,
10525 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10526 },
10527 /* 7.5.2.20 */
10528 { &hf_oran_oru_control_sinr_slot_mask_id,
10529 {"oruControlSinrSlotMaskId", "oran_fh_cus.oruControlSinrSlotMaskId",
10530 FT_UINT8, BASE_DEC,
10531 NULL((void*)0), 0x1f,
10532 "SINR time resolution",
10533 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10534 },
10535 /* 7.7.24.21 */
10536 { &hf_oran_pos_meas,
10537 {"posMeas", "oran_fh_cus.posMeas",
10538 FT_BOOLEAN, 8,
10539 TFS(&tfs_report_no_report_pos_meas)((0 ? (const struct true_false_string*)0 : ((&tfs_report_no_report_pos_meas
))))
, 0x40,
10540 "Positioning measurement report request",
10541 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10542 },
10543
10544 /* 7.5.3.69 */
10545 { &hf_oran_ue_radial_speed,
10546 {"ueRadialSpeed", "oran_fh_cus.ueRadialSpeed",
10547 FT_UINT16, BASE_DEC,
10548 NULL((void*)0), 0x0,
10549 "UE radial speed",
10550 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10551 },
10552 /* 7.5.3.70 */
10553 { &hf_oran_ue_az_aoa,
10554 {"ueAzAoa", "oran_fh_cus.ueAzAoa",
10555 FT_UINT16, BASE_DEC,
10556 NULL((void*)0), 0x0,
10557 "UE azimuth angle of arrival",
10558 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10559 },
10560 /* 7.5.3.71 */
10561 { &hf_oran_ue_ze_aoa,
10562 {"ueZeAoa", "oran_fh_cus.ueZeAoa",
10563 FT_UINT16, BASE_DEC,
10564 NULL((void*)0), 0x0,
10565 "UE zenith angle of arrival",
10566 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10567 },
10568 /* 7.5.3.72 */
10569 { &hf_oran_ue_pos_toa_offset,
10570 {"uePosToaOffset", "oran_fh_cus.uePosToaOffset",
10571 FT_UINT16, BASE_DEC,
10572 NULL((void*)0), 0x0,
10573 "UE positioning time of arrival offset",
10574 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10575 },
10576
10577 /* 7.7.30.2 */
10578 { &hf_oran_num_rep_ue,
10579 {"numRepUe", "oran_fh_cus.numRepUe",
10580 FT_UINT8, BASE_DEC,
10581 NULL((void*)0), 0x0f,
10582 "Number of UEs with PUSCH repetition",
10583 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10584 },
10585 /* 7.7.30.3 */
10586 { &hf_oran_rep_ueid,
10587 {"repUeId", "oran_fh_cus.repUeId",
10588 FT_UINT16, BASE_DEC,
10589 NULL((void*)0), 0x7fff,
10590 "UEId the PUSCH is part of",
10591 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10592 },
10593 /* 7.7.30.4 */
10594 { &hf_oran_is_last_rep,
10595 {"isLastRep", "oran_fh_cus.isLastRep",
10596 FT_BOOLEAN, 8,
10597 NULL((void*)0), 0x40,
10598 "Last transmission in the repetition",
10599 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10600 },
10601 /* 7.7.30.5 */
10602 { &hf_oran_rep_index,
10603 {"repIndex", "oran_fh_cus.repIndex",
10604 FT_UINT8, BASE_DEC,
10605 NULL((void*)0), 0x3f,
10606 "Repetition index of the PUSCH transmission",
10607 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10608 },
10609 /* 7.7.30.6 */
10610 { &hf_oran_num_reps,
10611 {"numReps", "oran_fh_cus.numReps",
10612 FT_UINT8, BASE_DEC,
10613 NULL((void*)0), 0x3f,
10614 "The number of total PUSCH repetitions",
10615 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10616 },
10617
10618 /* 7.7.31.2 */
10619 { &hf_oran_mcs_table,
10620 {"mcsTable", "oran_fh_cus.mcsTable",
10621 FT_UINT8, BASE_DEC,
10622 VALS(mcs_table_vals)((0 ? (const struct _value_string*)0 : ((mcs_table_vals)))), 0x0f,
10623 "MCS index table",
10624 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10625 },
10626 /* 7.7.31.3 */
10627 { &hf_oran_mcs_index,
10628 {"mcsIndex", "oran_fh_cus.mcsIndex",
10629 FT_UINT8, BASE_DEC,
10630 NULL((void*)0), 0x3f,
10631 "MCS index value",
10632 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10633 },
10634
10635 /* 7.7.33.3 */
10636 { &hf_oran_num_meas_req,
10637 {"numMeasReq", "oran_fh_cus.numMeasReq",
10638 FT_UINT8, BASE_DEC,
10639 NULL((void*)0), 0x1f,
10640 "Number of UEs for which meas is requested",
10641 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10642 },
10643 /* 7.7.32.5 */
10644 { &hf_oran_ue_rank,
10645 {"ueRank", "oran_fh_cus.ueRank",
10646 FT_UINT8, BASE_DEC,
10647 VALS(ue_rank_vals)((0 ? (const struct _value_string*)0 : ((ue_rank_vals)))), 0x0f,
10648 "Number of UE layers under evaluation",
10649 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10650 },
10651 /* 7.7.32.6 */
10652 { &hf_oran_num_of_ue_ant_ports,
10653 {"numOfUeAntPorts", "oran_fh_cus.numofUeAntPorts",
10654 FT_UINT8, BASE_DEC,
10655 VALS(num_of_ue_ant_ports_vals)((0 ? (const struct _value_string*)0 : ((num_of_ue_ant_ports_vals
))))
, 0xf0,
10656 "Used for the PUSCH tx under evaluation",
10657 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10658 },
10659 /* 7.7.32.8 */
10660 { &hf_oran_codebook_subset,
10661 {"codebookSubset", "oran_fh_cus.codebookSubset",
10662 FT_UINT8, BASE_DEC,
10663 VALS(codebook_subset_vals)((0 ? (const struct _value_string*)0 : ((codebook_subset_vals
))))
, 0xc0,
10664 "UE capability wrt ULTPMI sets",
10665 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10666 },
10667 /* 7.7.32.9 */
10668 { &hf_oran_full_pwr_mode,
10669 {"fullPwrMode", "oran_fh_cus.fullPwrMode",
10670 FT_UINT8, BASE_DEC,
10671 VALS(full_pwr_mode_vals)((0 ? (const struct _value_string*)0 : ((full_pwr_mode_vals))
))
, 0xc0,
10672 "Transmission mode",
10673 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10674 },
10675 /* 7.7.32.10 */
10676 { &hf_oran_full_pwr_mode_2_tpmi_group,
10677 {"fullPwrMode2TpmiGroup", "oran_fh_cus.fullPwrMode2TpmiGroup",
10678 FT_UINT16, BASE_HEX,
10679 NULL((void*)0), 0x3fff,
10680 "Capabilities",
10681 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10682 },
10683
10684 /* 7.5.3.75 */
10685 { &hf_oran_num_cand_ranks,
10686 {"numCandRanks", "oran_fh_cus.numCandRanks",
10687 FT_UINT8, BASE_DEC,
10688 NULL((void*)0), 0xf0,
10689 NULL((void*)0),
10690 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10691 },
10692 /* 7.5.3.76 */
10693 { &hf_oran_ue_pref_rank,
10694 {"uePrefRank", "oran_fh_cus.uePrefRank",
10695 FT_UINT8, BASE_DEC,
10696 NULL((void*)0), 0x0f,
10697 "Most optimal UL Tx rank for UE",
10698 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10699 },
10700 /* 7.5.3.77 */
10701 { &hf_oran_ue_tpmi_rank_y,
10702 {"ueTpmiRankY", "oran_fh_cus.ueTpmiRankY",
10703 FT_UINT8, BASE_DEC,
10704 NULL((void*)0), 0x0,
10705 "TPMI index for codebook-based PUSCH tx",
10706 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10707 },
10708 /* 7.5.3.78 */
10709 { &hf_oran_ue_tpmi_rank_y_sinr_lx,
10710 {"ueTpmiRankYSinrLX", "oran_fh_cus.ueTpmiRankYSinrLX",
10711 FT_UINT16, BASE_HEX | BASE_RANGE_STRING0x00000100,
10712 RVALS(ue_tmpi_rank_sinr_vals)((0 ? (const struct _range_string*)0 : ((ue_tmpi_rank_sinr_vals
))))
, 0x0,
10713 "Estimation of post-equalization SINR",
10714 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10715 },
10716 /* 7.5.3.79 */
10717 { &hf_oran_ue_layer_pre_eq_sinr,
10718 {"ueLayerPreEqSinr", "oran_fh_cus.ueLayerPreEqSinr",
10719 FT_UINT16, BASE_HEX,
10720 NULL((void*)0), 0x0,
10721 "Pre-equalization SINR of a UE layer",
10722 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10723 },
10724
10725 { &hf_oran_c_section_common,
10726 { "Common Section", "oran_fh_cus.c-plane.section.common",
10727 FT_STRING, BASE_NONE,
10728 NULL((void*)0), 0x0,
10729 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10730 },
10731 { &hf_oran_c_section,
10732 { "Section", "oran_fh_cus.c-plane.section",
10733 FT_STRING, BASE_NONE,
10734 NULL((void*)0), 0x0,
10735 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10736 },
10737 { &hf_oran_u_section,
10738 { "Section", "oran_fh_cus.u-plane.section",
10739 FT_STRING, BASE_NONE,
10740 NULL((void*)0), 0x0,
10741 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10742 },
10743
10744 /* Link back to UL C-plane where udCompHdr was recorded */
10745 { &hf_oran_ul_cplane_ud_comp_hdr_frame,
10746 { "C-Plane UL udCompHdr frame", "oran_fh_cus.ul-cplane.udCompHdr",
10747 FT_FRAMENUM, BASE_NONE,
10748 FRAMENUM_TYPE(FT_FRAMENUM_REQUEST)((gpointer) (glong) (FT_FRAMENUM_REQUEST)), 0x0,
10749 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10750 },
10751
10752 /* For ext11, where was a beamId (last) defined? */
10753 { &hf_oran_bfws_frame_defined,
10754 { "Beam defined in frame", "oran_fh_cus.bfw-defined",
10755 FT_FRAMENUM, BASE_NONE,
10756 FRAMENUM_TYPE(FT_FRAMENUM_RETRANS_PREV)((gpointer) (glong) (FT_FRAMENUM_RETRANS_PREV)), 0x0,
10757 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10758 },
10759 { &hf_oran_bfws_symbols_since_defined,
10760 { "Symbols since BFWs defined", "oran_fh_cus.symbols-since-bfw-defined",
10761 FT_UINT32, BASE_DEC,
10762 NULL((void*)0), 0x0,
10763 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10764 },
10765
10766 /* Corresponding C-plane frame for DL U-plane */
10767 { &hf_oran_corresponding_cplane_frame,
10768 { "C-plane frame", "oran_fh_cus.cplane-frame",
10769 FT_FRAMENUM, BASE_NONE,
10770 FRAMENUM_TYPE(FT_FRAMENUM_REQUEST)((gpointer) (glong) (FT_FRAMENUM_REQUEST)), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10771 },
10772 /* Time since corresponding C-plane frame for U-plane */
10773 { &hf_oran_corresponding_cplane_frame_time_delta,
10774 { "Time since C-plane frame", "oran_fh_cus.cplane-frame-time-delta",
10775 FT_UINT32, BASE_DEC, NULL((void*)0), 0x0,
10776 "Microseconds since C-plane frame", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10777 },
10778 /* Corresponding U-plane frame for C-plane */
10779 { &hf_oran_corresponding_uplane_frame,
10780 { "U-plane frame", "oran_fh_cus.uplane-frame",
10781 FT_FRAMENUM, BASE_NONE,
10782 FRAMENUM_TYPE(FT_FRAMENUM_RESPONSE)((gpointer) (glong) (FT_FRAMENUM_RESPONSE)), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10783 },
10784 { &hf_oran_corresponding_uplane_frames_total,
10785 { "U-plane frames total", "oran_fh_cus.u-plane-frames-total",
10786 FT_UINT32, BASE_DEC, NULL((void*)0), 0x0,
10787 "Number of corresponding U-plane frames", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10788 },
10789
10790 /* Reassembly */
10791 { &hf_oran_fragment,
10792 { "Fragment", "oran_fh_cus.fragment", FT_FRAMENUM, BASE_NONE,
10793 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10794 { &hf_oran_fragments,
10795 { "Fragments", "oran_fh_cus.fragments", FT_BYTES, BASE_NONE,
10796 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10797 { &hf_oran_fragment_overlap,
10798 { "Fragment overlap", "oran_fh_cus.fragment.overlap", FT_BOOLEAN, BASE_NONE,
10799 NULL((void*)0), 0x0, "Fragment overlaps with other fragments", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10800 { &hf_oran_fragment_overlap_conflict,
10801 { "Conflicting data in fragment overlap", "oran_fh_cus.fragment.overlap.conflict",
10802 FT_BOOLEAN, BASE_NONE, NULL((void*)0), 0x0,
10803 "Overlapping fragments contained conflicting data", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10804 { &hf_oran_fragment_multiple_tails,
10805 { "Multiple tail fragments found", "oran_fh_cus.fragment.multipletails",
10806 FT_BOOLEAN, BASE_NONE, NULL((void*)0), 0x0,
10807 "Several tails were found when defragmenting the packet", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10808 { &hf_oran_fragment_too_long_fragment,
10809 { "Fragment too long", "oran_fh_cus.fragment.toolongfragment",
10810 FT_BOOLEAN, BASE_NONE, NULL((void*)0), 0x0,
10811 "Fragment contained data past end of packet", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10812 { &hf_oran_fragment_error,
10813 { "Defragmentation error", "oran_fh_cus.fragment.error", FT_FRAMENUM, BASE_NONE,
10814 NULL((void*)0), 0x0, "Defragmentation error due to illegal fragments", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10815 { &hf_oran_fragment_count,
10816 { "Fragment count", "oran_fh_cus.fragment.count", FT_UINT32, BASE_DEC,
10817 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10818 { &hf_oran_reassembled_in,
10819 { "Reassembled payload in frame", "oran_fh_cus.reassembled_in", FT_FRAMENUM, BASE_NONE,
10820 NULL((void*)0), 0x0, "This payload packet is reassembled in this frame", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10821 { &hf_oran_reassembled_length,
10822 { "Reassembled payload length", "oran_fh_cus.reassembled.length", FT_UINT32, BASE_DEC,
10823 NULL((void*)0), 0x0, "The total length of the reassembled payload", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10824 { &hf_oran_reassembled_data,
10825 { "Reassembled data", "oran_fh_cus.reassembled.data", FT_BYTES, BASE_NONE,
10826 NULL((void*)0), 0x0, "The reassembled payload", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10827
10828 { &hf_oran_payload,
10829 { "Payload", "oran_fh_cus.payload", FT_BYTES, BASE_SHOW_ASCII_PRINTABLE0x00010000,
10830 NULL((void*)0), 0x0, "Complete or reassembled payload", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10831 };
10832
10833 /* Setup protocol subtree array */
10834 static int *ett[] = {
10835 &ett_oran,
10836 &ett_oran_ecpri_pcid,
10837 &ett_oran_ecpri_rtcid,
10838 &ett_oran_ecpri_seqid,
10839 &ett_oran_section_type,
10840 &ett_oran_u_timing,
10841 &ett_oran_u_section,
10842 &ett_oran_u_prb,
10843 &ett_oran_section,
10844 &ett_oran_iq,
10845 &ett_oran_bfw_bundle,
10846 &ett_oran_bfw,
10847 &ett_oran_frequency_range,
10848 &ett_oran_prb_cisamples,
10849 &ett_oran_cisample,
10850 &ett_oran_udcomphdr,
10851 &ett_oran_udcompparam,
10852 &ett_oran_cicomphdr,
10853 &ett_oran_cicompparam,
10854 &ett_oran_bfwcomphdr,
10855 &ett_oran_bfwcompparam,
10856 &ett_oran_ext19_port,
10857 &ett_oran_prb_allocation,
10858 &ett_oran_punc_pattern,
10859 &ett_oran_bfacomphdr,
10860 &ett_oran_modcomp_param_set,
10861 &ett_oran_st4_cmd_header,
10862 &ett_oran_st4_cmd,
10863 &ett_oran_sym_prb_pattern,
10864 &ett_oran_measurement_report,
10865 &ett_oran_measurement_command,
10866 &ett_oran_sresmask,
10867 &ett_oran_c_section_common,
10868 &ett_oran_c_section,
10869 &ett_oran_remask,
10870 &ett_oran_mc_scale_remask,
10871 &ett_oran_symbol_reordering_layer,
10872 &ett_oran_dmrs_entry,
10873 &ett_oran_dmrs_symbol_mask,
10874 &ett_oran_symbol_mask,
10875 &ett_oran_active_beamspace_coefficient_mask,
10876 &ett_oran_sinr_prb,
10877
10878 &ett_oran_fragment,
10879 &ett_oran_fragments
10880 };
10881
10882 /* Separate subtree array for extensions. Used with [ext-1] */
10883 static int *ext_ett[HIGHEST_EXTTYPE32];
10884 for (unsigned extno=0; extno<HIGHEST_EXTTYPE32; extno++) {
10885 ext_ett[extno] = &ett_oran_c_section_extension[extno];
10886 }
10887
10888 expert_module_t* expert_oran;
10889
10890 static ei_register_info ei[] = {
10891 { &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)}}
}},
10892 { &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)}}
}},
10893 { &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)}}
}},
10894 { &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)}}
}},
10895 { &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)}}
}},
10896 { &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)}}
}},
10897 { &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)}}
}},
10898 { &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)}}
}},
10899 { &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)}}
}},
10900 { &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)}}
}},
10901 { &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)}}
}},
10902 { &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)}}
}},
10903 { &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)}}
}},
10904 { &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)}}
}},
10905 { &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)}}
}},
10906 { &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)}}
}},
10907 { &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)}}
}},
10908 { &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)}}
}},
10909 { &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)}}
}},
10910 { &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)}}
}},
10911 { &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)}}
}},
10912 { &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)}}
}},
10913 { &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)}}
}},
10914 { &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)}}
}},
10915 { &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)}}
}},
10916 { &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)}}
}},
10917 { &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)}}
}},
10918 { &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)}}
}},
10919 { &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)}}
}},
10920 { &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)}}
}},
10921 { &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)}}
}},
10922 { &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)}}
}},
10923 { &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)}}
}},
10924 { &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)}}
}},
10925 { &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)}}
}},
10926 { &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)}}
}},
10927 { &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)}}
}},
10928 { &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)}}
}},
10929 { &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)}}
}},
10930 { &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)}}
}},
10931 { &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)}}
}},
10932 { &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)}}
}},
10933 { &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)}}
}},
10934 { &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)}}
}},
10935 { &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)}}
}},
10936 { &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)}}
}},
10937 { &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)}}
}},
10938 { &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)}}
}},
10939 { &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)}}
}},
10940 { &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)}}
}},
10941 { &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)}}
}},
10942 { &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)}}
}},
10943 { &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)}}
}},
10944 { &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)}}
}},
10945 { &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)}}
}},
10946 { &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)}}
}}
10947 };
10948
10949 /* Register the protocol name and description */
10950 proto_oran = proto_register_protocol("O-RAN Fronthaul CUS", "O-RAN FH CUS", "oran_fh_cus");
10951
10952 /* Allow dissector to find be found by name. */
10953 register_dissector("oran_fh_cus", dissect_oran, proto_oran);
10954
10955 /* Register the tap name. */
10956 oran_tap = register_tap("oran-fh-cus");
10957
10958 /* Required function calls to register the header fields and subtrees */
10959 proto_register_field_array(proto_oran, hf, array_length(hf)(sizeof (hf) / sizeof (hf)[0]));
10960 proto_register_subtree_array(ett, array_length(ett)(sizeof (ett) / sizeof (ett)[0]));
10961 proto_register_subtree_array(ext_ett, array_length(ext_ett)(sizeof (ext_ett) / sizeof (ext_ett)[0]));
10962
10963 expert_oran = expert_register_protocol(proto_oran);
10964 expert_register_field_array(expert_oran, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
10965
10966
10967 /* Preferences */
10968 module_t * oran_module = prefs_register_protocol(proto_oran, NULL((void*)0));
10969
10970 /* Register bit width/compression preferences separately by direction. */
10971 prefs_register_uint_preference(oran_module, "oran.du_port_id_bits", "DU Port ID bits [a]",
10972 "The bit width of DU Port ID - sum of a,b,c&d (eAxC) must be 16", 10, &pref_du_port_id_bits);
10973 prefs_register_uint_preference(oran_module, "oran.bandsector_id_bits", "BandSector ID bits [b]",
10974 "The bit width of BandSector ID - sum of a,b,c&d (eAxC) must be 16", 10, &pref_bandsector_id_bits);
10975 prefs_register_uint_preference(oran_module, "oran.cc_id_bits", "CC ID bits [c]",
10976 "The bit width of CC ID - sum of a,b,c&d (eAxC) must be 16", 10, &pref_cc_id_bits);
10977 prefs_register_uint_preference(oran_module, "oran.ru_port_id_bits", "RU Port ID bits [d]",
10978 "The bit width of RU Port ID - sum of a,b,c&d (eAxC) must be 16", 10, &pref_ru_port_id_bits);
10979
10980 /* Uplink userplane */
10981 prefs_register_static_text_preference(oran_module, "oran.ul", "", "");
10982 prefs_register_uint_preference(oran_module, "oran.iq_bitwidth_up", "IQ Bitwidth Uplink",
10983 "The bit width of a sample in the Uplink (if no udcompHdr and no C-Plane)", 10, &pref_sample_bit_width_uplink);
10984 prefs_register_enum_preference(oran_module, "oran.ud_comp_up", "Uplink User Data Compression",
10985 "Uplink User Data Compression (if no udcompHdr and no C-Plane)", &pref_iqCompressionUplink, ul_compression_options, false0);
10986 prefs_register_enum_preference(oran_module, "oran.ud_comp_hdr_up", "udCompHdr field is present for uplink",
10987 "The udCompHdr field in U-Plane messages may or may not be present, depending on the "
10988 "configuration of the O-RU. This preference instructs the dissector to expect "
10989 "this field to be present in uplink messages",
10990 &pref_includeUdCompHeaderUplink, udcomphdr_present_options, false0);
10991 prefs_register_bool_preference(oran_module, "oran.ignore_cplane_ul_udcomphdr", "Ignore UL compression settings from C-plane",
10992 "When set, override udCompHdr from UL C-Plane with compression method and width configured here", &pref_override_ul_compression);
10993 prefs_register_uint_preference(oran_module, "oran.ul_slot_us_limit", "Microseconds allowed for UL tx in symbol",
10994 "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",
10995 10, &us_allowed_for_ul_in_symbol);
10996
10997 /* Downlink userplane */
10998 prefs_register_static_text_preference(oran_module, "oran.dl", "", "");
10999 prefs_register_uint_preference(oran_module, "oran.iq_bitwidth_down", "IQ Bitwidth Downlink",
11000 "The bit width of a sample in the Downlink (if no udcompHdr)", 10, &pref_sample_bit_width_downlink);
11001 prefs_register_enum_preference(oran_module, "oran.ud_comp_down", "Downlink User Data Compression",
11002 "Downlink User Data Compression", &pref_iqCompressionDownlink, dl_compression_options, false0);
11003 prefs_register_enum_preference(oran_module, "oran.ud_comp_hdr_down", "udCompHdr field is present for downlink",
11004 "The udCompHdr field in U-Plane messages may or may not be present, depending on the "
11005 "configuration of the O-RU. This preference instructs the dissector to expect "
11006 "this field to be present in downlink messages",
11007 &pref_includeUdCompHeaderDownlink, udcomphdr_present_options, false0);
11008
11009 /* SINR */
11010 prefs_register_static_text_preference(oran_module, "oran.sinr", "", "");
11011 prefs_register_uint_preference(oran_module, "oran.iq_bitwidth_sinr", "IQ Bitwidth SINR",
11012 "The bit width of a sample in SINR", 10, &pref_sample_bit_width_sinr);
11013 prefs_register_enum_preference(oran_module, "oran.ud_comp_sinr", "SINR Compression",
11014 "SINR Compression", &pref_iqCompressionSINR, ul_compression_options, false0);
11015
11016 /* BF-related */
11017 prefs_register_static_text_preference(oran_module, "oran.bf", "", "");
11018 prefs_register_uint_preference(oran_module, "oran.num_bf_antennas", "Number of beam weights",
11019 "Number of array elements that BF weights will be provided for", 10, &pref_num_bf_antennas);
11020 prefs_register_obsolete_preference(oran_module, "oran.num_weights_per_bundle");
11021 prefs_register_obsolete_preference(oran_module, "oran.num_bf_weights");
11022 prefs_register_bool_preference(oran_module, "oran.st6_4byte_alignment_required", "Use 4-byte alignment for ST6 sections",
11023 "Default is 1-byte alignment", &st6_4byte_alignment);
11024
11025 /* Misc (and will seldom need to be accessed) */
11026 prefs_register_static_text_preference(oran_module, "oran.misc", "", "");
11027 prefs_register_bool_preference(oran_module, "oran.show_iq_samples", "Show IQ Sample values",
11028 "When enabled, for U-Plane frames show each I and Q value in PRB", &pref_showIQSampleValues);
11029 prefs_register_enum_preference(oran_module, "oran.support_udcomplen", "udCompLen supported",
11030 "When enabled, U-Plane messages with relevant compression schemes will include udCompLen",
11031 &pref_support_udcompLen, udcomplen_support_options, false0);
11032 prefs_register_uint_preference(oran_module, "oran.rbs_in_uplane_section", "Total RBs in User-Plane data section",
11033 "This is used if numPrbu is signalled as 0", 10, &pref_data_plane_section_total_rbs);
11034 prefs_register_bool_preference(oran_module, "oran.unscaled_iq", "Show unscaled I/Q values",
11035 "", &show_unscaled_values);
11036 prefs_register_bool_preference(oran_module, "oran.attempt_reassembly",
11037 "Attempt Radio Transport layer reassembly", "",
11038 &do_radio_transport_layer_reassembly);
11039 prefs_register_obsolete_preference(oran_module, "oran.k_antenna_ports");
11040
11041 prefs_register_bool_preference(oran_module, "oran.link_planes",
11042 "Link C-plane and U-plane using sectionId", "",
11043 &link_planes_together);
11044
11045
11046 flow_states_table = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
11047 flow_results_table = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
11048 ul_symbol_timing = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
11049
11050 dl_beam_ids_defined = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
11051 dl_beam_ids_results = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
11052
11053 register_init_routine(&oran_init_protocol);
11054
11055 /* Register reassembly table. */
11056 reassembly_table_register(&oran_reassembly_table,
11057 &oran_reassembly_table_functions);
11058}
11059
11060/*
11061* Editor modelines - http://www.wireshark.org/tools/modelines.html
11062*
11063* Local Variables:
11064* c-basic-offset: 4
11065* tab-width: 8
11066* indent-tabs-mode: nil
11067* End:
11068*
11069* ex: set shiftwidth=4 tabstop=8 expandtab:
11070* :indentSize=4:tabSize=8:noTabs=true:
11071*/