Bug Summary

File:builds/wireshark/wireshark/epan/dissectors/packet-oran.c
Warning:line 7437, column 51
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-07-100348-3595-1 -x c /builds/wireshark/wireshark/epan/dissectors/packet-oran.c
1/* packet-oran.c
2 * Routines for O-RAN fronthaul UC-plane dissection
3 * Copyright 2020, Jan Schiefer, Keysight Technologies, Inc.
4 * Copyright 2020- Martin Mathieson
5 *
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
9 *
10 * SPDX-License-Identifier: GPL-2.0-or-later
11 */
12
13 /*
14 * Dissector for the O-RAN Fronthaul CUS protocol specification.
15 * See https://specifications.o-ran.org/specifications, WG4, Fronthaul Interfaces Workgroup
16 * The current implementation is based on the ORAN-WG4.CUS.0-v20.00 specification.
17 * Note that other eCPRI message types are handled in packet-ecpri.c
18 */
19
20#include <config.h>
21
22#include <math.h>
23
24#include <epan/packet.h>
25#include <epan/expert.h>
26#include <epan/prefs.h>
27#include <epan/tap.h>
28#include <epan/tfs.h>
29#include <epan/reassemble.h>
30
31#include <wsutil/ws_roundup.h>
32#include <wsutil/ws_padding_to.h>
33
34#include "epan/dissectors/packet-oran.h"
35
36/* N.B. dissector preferences are taking the place of (some) M-plane parameters,
37 * so unfortunately it can be fiddly to get the preferences into a good state to
38 * decode a given capture..
39 * TODO:
40 * - for U-Plane, track back to last C-Plane frame for that eAxC
41 * doing, but this matching can be tricky see 7.8.1 Coupling of C-Plane and U-Plane
42 * - Detect/indicate signs of application layer fragmentation?
43 * same eAxC in same symbol (same/different section ID?)
44 * - Not handling M-plane setting for "little endian byte order" as applied to
45 * IQ samples and beam weights does anyone use this?
46 * - for section extensions, check more constraints (which other extension types
47 * appear with them, order, repeated)
48 * - re-order items (decl and hf definitions) to match spec order?
49 * - track energy-saving status, and identify TRX or ASM commands as 'Sleep extension'
50 */
51
52/* Prototypes */
53void proto_register_oran(void);
54
55/* Initialize the protocol and registered fields */
56static int proto_oran;
57
58static int oran_tap = -1;
59
60static int hf_oran_du_port_id;
61static int hf_oran_bandsector_id;
62static int hf_oran_cc_id;
63static int hf_oran_ru_port_id;
64static int hf_oran_sequence_id;
65static int hf_oran_e_bit;
66static int hf_oran_subsequence_id;
67static int hf_oran_previous_frame;
68
69static int hf_oran_data_direction;
70static int hf_oran_payload_version;
71static int hf_oran_filter_index;
72static int hf_oran_frame_id;
73static int hf_oran_subframe_id;
74static int hf_oran_slot_id;
75static int hf_oran_slot_within_frame;
76static int hf_oran_start_symbol_id;
77static int hf_oran_numberOfSections;
78static int hf_oran_sectionType;
79
80static int hf_oran_udCompHdr;
81static int hf_oran_udCompHdrIqWidth;
82static int hf_oran_udCompHdrIqWidth_pref;
83static int hf_oran_udCompHdrMeth;
84static int hf_oran_udCompHdrMeth_pref;
85static int hf_oran_udCompLen;
86static int hf_oran_numberOfUEs;
87static int hf_oran_timeOffset;
88static int hf_oran_frameStructure_fft;
89static int hf_oran_frameStructure_subcarrier_spacing;
90static int hf_oran_cpLength;
91static int hf_oran_timing_header;
92static int hf_oran_section_id;
93static int hf_oran_rb;
94static int hf_oran_symInc;
95static int hf_oran_startPrbc;
96static int hf_oran_reMask_re1;
97static int hf_oran_reMask_re2;
98static int hf_oran_reMask_re3;
99static int hf_oran_reMask_re4;
100static int hf_oran_reMask_re5;
101static int hf_oran_reMask_re6;
102static int hf_oran_reMask_re7;
103static int hf_oran_reMask_re8;
104static int hf_oran_reMask_re9;
105static int hf_oran_reMask_re10;
106static int hf_oran_reMask_re11;
107static int hf_oran_reMask_re12;
108static int hf_oran_reMask;
109static int hf_oran_numPrbc;
110static int hf_oran_numSymbol;
111static int hf_oran_ef;
112static int hf_oran_beamId;
113
114static int hf_oran_sinrCompHdrIqWidth_pref;
115static int hf_oran_sinrCompHdrMeth_pref;
116
117static int hf_oran_ciCompHdr;
118static int hf_oran_ciCompHdrIqWidth;
119static int hf_oran_ciCompHdrMeth;
120static int hf_oran_ciCompOpt;
121
122static int hf_oran_extension;
123static int hf_oran_exttype;
124static int hf_oran_extlen;
125
126static int hf_oran_bfw_bundle;
127static int hf_oran_bfw_bundle_id;
128static int hf_oran_bfw;
129static int hf_oran_bfw_i;
130static int hf_oran_bfw_q;
131
132static int hf_oran_ueId;
133static int hf_oran_freqOffset;
134static int hf_oran_regularizationFactor;
135static int hf_oran_laaMsgType;
136static int hf_oran_laaMsgLen;
137static int hf_oran_lbtHandle;
138static int hf_oran_lbtDeferFactor;
139static int hf_oran_lbtBackoffCounter;
140static int hf_oran_lbtOffset;
141static int hf_oran_MCOT;
142static int hf_oran_lbtMode;
143static int hf_oran_sfnSfEnd;
144static int hf_oran_lbtPdschRes;
145static int hf_oran_sfStatus;
146static int hf_oran_initialPartialSF;
147static int hf_oran_lbtDrsRes;
148static int hf_oran_lbtBufErr;
149static int hf_oran_lbtTrafficClass;
150static int hf_oran_lbtCWConfig_H;
151static int hf_oran_lbtCWConfig_T;
152static int hf_oran_lbtCWR_Rst;
153
154static int hf_oran_reserved;
155static int hf_oran_reserved_1bit;
156static int hf_oran_reserved_2bits;
157static int hf_oran_reserved_3bits;
158static int hf_oran_reserved_4bits;
159static int hf_oran_reserved_last_4bits;
160static int hf_oran_reserved_last_5bits;
161static int hf_oran_reserved_6bits;
162static int hf_oran_reserved_last_6bits;
163static int hf_oran_reserved_7bits;
164static int hf_oran_reserved_last_7bits;
165static int hf_oran_reserved_8bits;
166static int hf_oran_reserved_16bits;
167static int hf_oran_reserved_15bits;
168static int hf_oran_reserved_bit1;
169static int hf_oran_reserved_bit2;
170static int hf_oran_reserved_bit4;
171static int hf_oran_reserved_bit5;
172static int hf_oran_reserved_bits123;
173static int hf_oran_reserved_bits456;
174
175static int hf_oran_bundle_offset;
176static int hf_oran_cont_ind;
177
178static int hf_oran_bfwCompHdr;
179static int hf_oran_bfwCompHdr_iqWidth;
180static int hf_oran_bfwCompHdr_compMeth;
181static int hf_oran_symbolId;
182static int hf_oran_startPrbu;
183static int hf_oran_numPrbu;
184
185static int hf_oran_udCompParam;
186static int hf_oran_sReSMask;
187static int hf_oran_sReSMask_re12;
188static int hf_oran_sReSMask_re11;
189static int hf_oran_sReSMask_re10;
190static int hf_oran_sReSMask_re9;
191static int hf_oran_sReSMask_re8;
192static int hf_oran_sReSMask_re7;
193static int hf_oran_sReSMask_re6;
194static int hf_oran_sReSMask_re5;
195static int hf_oran_sReSMask_re4;
196static int hf_oran_sReSMask_re3;
197static int hf_oran_sReSMask_re2;
198static int hf_oran_sReSMask_re1;
199
200static int hf_oran_sReSMask1;
201static int hf_oran_sReSMask2;
202static int hf_oran_sReSMask1_2_re12;
203static int hf_oran_sReSMask1_2_re11;
204static int hf_oran_sReSMask1_2_re10;
205static int hf_oran_sReSMask1_2_re9;
206
207static int hf_oran_bfwCompParam;
208
209static int hf_oran_iSample;
210static int hf_oran_qSample;
211
212static int hf_oran_ciCompParam;
213
214static int hf_oran_blockScaler;
215static int hf_oran_compBitWidth;
216static int hf_oran_compShift;
217
218static int hf_oran_active_beamspace_coefficient_n1;
219static int hf_oran_active_beamspace_coefficient_n2;
220static int hf_oran_active_beamspace_coefficient_n3;
221static int hf_oran_active_beamspace_coefficient_n4;
222static int hf_oran_active_beamspace_coefficient_n5;
223static int hf_oran_active_beamspace_coefficient_n6;
224static int hf_oran_active_beamspace_coefficient_n7;
225static int hf_oran_active_beamspace_coefficient_n8;
226static int hf_oran_activeBeamspaceCoefficientMask;
227static int hf_oran_activeBeamspaceCoefficientMask_bits_set;
228
229static int hf_oran_se6_repetition;
230
231static int hf_oran_rbgSize;
232static int hf_oran_rbgMask;
233static int hf_oran_noncontig_priority;
234
235static int hf_oran_symbol_mask;
236static int hf_oran_symbol_mask_s13;
237static int hf_oran_symbol_mask_s12;
238static int hf_oran_symbol_mask_s11;
239static int hf_oran_symbol_mask_s10;
240static int hf_oran_symbol_mask_s9;
241static int hf_oran_symbol_mask_s8;
242static int hf_oran_symbol_mask_s7;
243static int hf_oran_symbol_mask_s6;
244static int hf_oran_symbol_mask_s5;
245static int hf_oran_symbol_mask_s4;
246static int hf_oran_symbol_mask_s3;
247static int hf_oran_symbol_mask_s2;
248static int hf_oran_symbol_mask_s1;
249static int hf_oran_symbol_mask_s0;
250
251static int hf_oran_exponent;
252static int hf_oran_iq_user_data;
253
254static int hf_oran_disable_bfws;
255static int hf_oran_rad;
256static int hf_oran_num_bund_prbs;
257static int hf_oran_beam_id;
258static int hf_oran_num_weights_per_bundle;
259
260static int hf_oran_ack_nack_req_id;
261
262static int hf_oran_frequency_range;
263static int hf_oran_off_start_prb;
264static int hf_oran_num_prb;
265
266static int hf_oran_samples_prb;
267static int hf_oran_ciSample;
268static int hf_oran_ciIsample;
269static int hf_oran_ciQsample;
270
271static int hf_oran_beamGroupType;
272static int hf_oran_numPortc;
273
274static int hf_oran_csf;
275static int hf_oran_modcompscaler;
276
277static int hf_oran_modcomp_param_set;
278static int hf_oran_mc_scale_re_mask_re1;
279static int hf_oran_mc_scale_re_mask_re2;
280static int hf_oran_mc_scale_re_mask_re3;
281static int hf_oran_mc_scale_re_mask_re4;
282static int hf_oran_mc_scale_re_mask_re5;
283static int hf_oran_mc_scale_re_mask_re6;
284static int hf_oran_mc_scale_re_mask_re7;
285static int hf_oran_mc_scale_re_mask_re8;
286static int hf_oran_mc_scale_re_mask_re9;
287static int hf_oran_mc_scale_re_mask_re10;
288static int hf_oran_mc_scale_re_mask_re11;
289static int hf_oran_mc_scale_re_mask_re12;
290static int hf_oran_mc_scale_re_mask_re1_even;
291static int hf_oran_mc_scale_re_mask_re2_even;
292static int hf_oran_mc_scale_re_mask_re3_even;
293static int hf_oran_mc_scale_re_mask_re4_even;
294static int hf_oran_mc_scale_re_mask_re5_even;
295static int hf_oran_mc_scale_re_mask_re6_even;
296static int hf_oran_mc_scale_re_mask_re7_even;
297static int hf_oran_mc_scale_re_mask_re8_even;
298static int hf_oran_mc_scale_re_mask_re9_even;
299static int hf_oran_mc_scale_re_mask_re10_even;
300static int hf_oran_mc_scale_re_mask_re11_even;
301static int hf_oran_mc_scale_re_mask_re12_even;
302
303static int hf_oran_mc_scale_re_mask;
304static int hf_oran_mc_scale_re_mask_even;
305
306static int hf_oran_mc_scale_offset;
307
308static int hf_oran_eAxC_mask;
309static int hf_oran_technology;
310static int hf_oran_nullLayerInd;
311
312static int hf_oran_se19_repetition;
313static int hf_oran_portReMask;
314static int hf_oran_portSymbolMask;
315
316static int hf_oran_ext19_port;
317
318static int hf_oran_prb_allocation;
319static int hf_oran_nextSymbolId;
320static int hf_oran_nextStartPrbc;
321
322static int hf_oran_puncPattern;
323static int hf_oran_numPuncPatterns;
324static int hf_oran_symbolMask_ext20;
325static int hf_oran_startPuncPrb;
326static int hf_oran_numPuncPrb;
327static int hf_oran_puncReMask;
328static int hf_oran_multiSDScope;
329static int hf_oran_RbgIncl;
330
331static int hf_oran_ci_prb_group_size;
332static int hf_oran_prg_size_st5;
333static int hf_oran_prg_size_st6;
334
335static int hf_oran_num_ueid;
336
337static int hf_oran_antMask;
338
339static int hf_oran_transmissionWindowOffset;
340static int hf_oran_transmissionWindowSize;
341static int hf_oran_toT;
342
343static int hf_oran_bfaCompHdr;
344static int hf_oran_bfAzPtWidth;
345static int hf_oran_bfZePtWidth;
346static int hf_oran_bfAz3ddWidth;
347static int hf_oran_bfZe3ddWidth;
348static int hf_oran_bfAzPt;
349static int hf_oran_bfZePt;
350static int hf_oran_bfAz3dd;
351static int hf_oran_bfZe3dd;
352static int hf_oran_bfAzSl;
353static int hf_oran_bfZeSl;
354
355static int hf_oran_cmd_scope;
356static int hf_oran_number_of_st4_cmds;
357
358static int hf_oran_st4_cmd_header;
359static int hf_oran_st4_cmd_type;
360static int hf_oran_st4_cmd_len;
361static int hf_oran_st4_cmd_num_slots;
362static int hf_oran_st4_cmd_ack_nack_req_id;
363
364static int hf_oran_st4_cmd;
365
366static int hf_oran_sleepmode_trx;
367static int hf_oran_sleepmode_asm;
368static int hf_oran_log2maskbits;
369static int hf_oran_num_slots_ext;
370static int hf_oran_antMask_trx_control;
371
372static int hf_oran_ready;
373static int hf_oran_number_of_acks;
374static int hf_oran_number_of_nacks;
375static int hf_oran_ackid;
376static int hf_oran_nackid;
377
378static int hf_oran_acknack_request_frame;
379static int hf_oran_acknack_request_time;
380static int hf_oran_acknack_request_type;
381static int hf_oran_acknack_response_frame;
382static int hf_oran_acknack_response_time;
383
384static int hf_oran_disable_tdbfns;
385static int hf_oran_td_beam_group;
386static int hf_oran_disable_tdbfws;
387static int hf_oran_td_beam_num;
388
389static int hf_oran_dir_pattern;
390static int hf_oran_guard_pattern;
391
392static int hf_oran_ecpri_pcid;
393static int hf_oran_ecpri_rtcid;
394static int hf_oran_ecpri_seqid;
395
396static int hf_oran_num_sym_prb_pattern;
397static int hf_oran_prb_mode;
398static int hf_oran_sym_prb_pattern;
399static int hf_oran_sym_mask;
400static int hf_oran_num_mc_scale_offset;
401static int hf_oran_prb_pattern;
402static int hf_oran_prb_block_offset;
403static int hf_oran_prb_block_size;
404
405static int hf_oran_codebook_index;
406static int hf_oran_layerid;
407static int hf_oran_numlayers;
408static int hf_oran_txscheme;
409static int hf_oran_crs_remask;
410static int hf_oran_crs_shift;
411static int hf_oran_crs_symnum;
412static int hf_oran_beamid_ap1;
413static int hf_oran_beamid_ap2;
414static int hf_oran_beamid_ap3;
415
416static int hf_oran_port_list_index;
417static int hf_oran_alpn_per_sym;
418static int hf_oran_ant_dmrs_snr;
419static int hf_oran_user_group_size;
420static int hf_oran_user_group_id;
421static int hf_oran_entry_type;
422static int hf_oran_dmrs_port_number;
423static int hf_oran_ueid_reset;
424
425static int hf_oran_dmrs_symbol_mask;
426static int hf_oran_dmrs_symbol_mask_s13;
427static int hf_oran_dmrs_symbol_mask_s12;
428static int hf_oran_dmrs_symbol_mask_s11;
429static int hf_oran_dmrs_symbol_mask_s10;
430static int hf_oran_dmrs_symbol_mask_s9;
431static int hf_oran_dmrs_symbol_mask_s8;
432static int hf_oran_dmrs_symbol_mask_s7;
433static int hf_oran_dmrs_symbol_mask_s6;
434static int hf_oran_dmrs_symbol_mask_s5;
435static int hf_oran_dmrs_symbol_mask_s4;
436static int hf_oran_dmrs_symbol_mask_s3;
437static int hf_oran_dmrs_symbol_mask_s2;
438static int hf_oran_dmrs_symbol_mask_s1;
439static int hf_oran_dmrs_symbol_mask_s0;
440
441static int hf_oran_scrambling;
442static int hf_oran_nscid;
443static int hf_oran_dtype;
444static int hf_oran_cmd_without_data;
445static int hf_oran_lambda;
446static int hf_oran_first_prb;
447static int hf_oran_last_prb;
448static int hf_oran_low_papr_type;
449static int hf_oran_hopping_mode;
450
451static int hf_oran_tx_win_for_on_air_symbol_l;
452static int hf_oran_tx_win_for_on_air_symbol_r;
453
454static int hf_oran_num_fo_fb;
455static int hf_oran_freq_offset_fb;
456
457static int hf_oran_num_ue_sinr_rpt;
458static int hf_oran_num_sinr_per_prb;
459static int hf_oran_num_sinr_per_prb_right;
460
461static int hf_oran_sinr_value;
462
463static int hf_oran_measurement_report;
464static int hf_oran_mf;
465static int hf_oran_meas_data_size;
466static int hf_oran_meas_type_id;
467static int hf_oran_ipn_power;
468static int hf_oran_ue_tae;
469static int hf_oran_ue_layer_power;
470static int hf_oran_num_elements;
471static int hf_oran_ant_dmrs_snr_val;
472static int hf_oran_ue_freq_offset;
473
474static int hf_oran_measurement_command;
475
476static int hf_oran_beam_type;
477static int hf_oran_meas_cmd_size;
478
479static int hf_oran_symbol_reordering_layer;
480static int hf_oran_dmrs_entry;
481
482static int hf_oran_c_section_common;
483static int hf_oran_c_section;
484static int hf_oran_u_section;
485
486static int hf_oran_u_section_ul_symbol_time;
487static int hf_oran_u_section_ul_symbol_frames;
488static int hf_oran_u_section_ul_symbol_first_frame;
489static int hf_oran_u_section_ul_symbol_last_frame;
490
491static int hf_oran_cd_scg_size;
492static int hf_oran_cd_scg_phase_step;
493
494static int hf_oran_sinr_prb;
495static int hf_oran_oru_control_sinr_slot_mask_id;
496static int hf_oran_pos_meas;
497
498static int hf_oran_ue_radial_speed;
499static int hf_oran_ue_az_aoa;
500static int hf_oran_ue_ze_aoa;
501static int hf_oran_ue_pos_toa_offset;
502
503static int hf_oran_num_rep_ue;
504static int hf_oran_rep_ueid;
505static int hf_oran_is_last_rep;
506static int hf_oran_rep_index;
507static int hf_oran_num_reps;
508
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 }
4682 else { /* PRB-BLOCK */
4683 /* prbBlkOffset (8 bits) */
4684 proto_tree_add_item(pattern_tree, hf_oran_prb_block_offset, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4685 offset += 1;
4686 /* prbBlkSize (4 bits) */
4687 proto_tree_add_item(pattern_tree, hf_oran_prb_block_size, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4688 offset += 1;
4689 }
4690
4691 /* Yellowish part */
4692 if (prb_mode) { /* PRB-BLOCK */
4693 /* prbBlkSize (4 bits) */
4694 proto_tree_add_item(pattern_tree, hf_oran_prb_block_size, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4695 }
4696 else {
4697 /* reserved (4 bits) */
4698 add_reserved_field(pattern_tree, hf_oran_reserved_4bits, tvb, offset, 1);
4699 }
4700
4701 for (unsigned c=0; c < numMcScaleOffset; c++) {
4702
4703 if (c > 0) {
4704 /* reserved (4 bits) */
4705 add_reserved_field(pattern_tree, hf_oran_reserved_4bits, tvb, offset, 1);
4706 }
4707
4708 static int * const remask_flags_even[] = {
4709 &hf_oran_mc_scale_re_mask_re1_even,
4710 &hf_oran_mc_scale_re_mask_re2_even,
4711 &hf_oran_mc_scale_re_mask_re3_even,
4712 &hf_oran_mc_scale_re_mask_re4_even,
4713 &hf_oran_mc_scale_re_mask_re5_even,
4714 &hf_oran_mc_scale_re_mask_re6_even,
4715 &hf_oran_mc_scale_re_mask_re7_even,
4716 &hf_oran_mc_scale_re_mask_re8_even,
4717 &hf_oran_mc_scale_re_mask_re9_even,
4718 &hf_oran_mc_scale_re_mask_re10_even,
4719 &hf_oran_mc_scale_re_mask_re11_even,
4720 &hf_oran_mc_scale_re_mask_re12_even,
4721 NULL((void*)0)
4722 };
4723
4724 /* mcScaleReMask (12 bits). Defines which REs the following csf and mcScaleOffset apply to */
4725 uint64_t mcScaleReMask, mcScaleOffset;
4726 proto_tree_add_bitmask_ret_uint64(pattern_tree, tvb, offset,
4727 hf_oran_mc_scale_re_mask_even,
4728 ett_oran_mc_scale_remask,
4729 remask_flags_even, ENC_BIG_ENDIAN0x00000000, &mcScaleReMask);
4730
4731 offset += 2;
4732 /* csf (1 bit) */
4733 bool_Bool csf;
4734 dissect_csf(pattern_tree, tvb, offset*8, ci_iq_width, &csf);
4735 /* mcScaleOffset (15 bits) */
4736 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);
4737 uint16_t exponent = (mcScaleOffset >> 11) & 0x000f; /* m.s. 4 bits */
4738 uint16_t mantissa = mcScaleOffset & 0x07ff; /* l.s. 11 bits */
4739 float mcScaleOffset_value = ((float)mantissa/(1<<11)) * ((float)1.0 / (1 << exponent));
4740 proto_item_append_text(ti, " (%f)", mcScaleOffset_value);
4741
4742 offset += 2;
4743
4744 /* Record this config. */
4745 /* TODO: at some point, will also want to store/use PRB + symbol filters */
4746 section_mod_compr_config_t* sect_config = get_mod_compr_section_to_write(state, sectionId);
4747
4748 if (sect_config && sect_config->num_configs < MAX_MOD_COMPR_CONFIGS12) {
4749 unsigned i = sect_config->num_configs;
4750 sect_config->configs[i].mod_compr_re_mask = (uint16_t)mcScaleReMask;
4751 sect_config->configs[i].mod_compr_csf = csf;
4752 sect_config->configs[i].mod_compr_scaler = mcScaleOffset_value;
4753 sect_config->num_configs++;
4754 }
4755 }
4756
4757 proto_item_set_end(pattern_ti, tvb, offset);
4758 }
4759 break;
4760 }
4761
4762 case 24: /* SE 24: PUSCH DMRS configuration */
4763 {
4764 /* Hidden filter for bf (DMRS BF) */
4765 bf_ti = proto_tree_add_item(tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
4766 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
4767
4768 /* alpnPerSym (1 bit) */
4769 proto_tree_add_item(extension_tree, hf_oran_alpn_per_sym, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4770 /* antDmrsSnr (1 bit) */
4771 proto_tree_add_item(extension_tree, hf_oran_ant_dmrs_snr, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4772 /* reserved (1 bit) */
4773 add_reserved_field(extension_tree, hf_oran_reserved_bit2, tvb, offset, 1);
4774 /* userGroupSize (5 bits) */
4775 uint32_t user_group_size;
4776 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);
4777 if (user_group_size == 0) {
4778 proto_item_append_text(ugs_ti, " (not used)");
4779 }
4780 else if (user_group_size > 12) {
4781 proto_item_append_text(ugs_ti, " (reserved)");
4782 }
4783 offset += 1;
4784 /* userGroupId (8 bits)*/
4785 uint32_t user_group_id;
4786 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);
4787 if (user_group_id == 0) {
4788 /* TODO: Value 0 can happen in several cases, described in 7.7.24.7.. */
4789 }
4790 if (user_group_id == 255) {
4791 /* Value 255 is reserved */
4792 expert_add_info(pinfo, ugi_ti, &ei_oran_user_group_id_reserved_value);
4793 }
4794 offset += 1;
4795
4796 bool_Bool seen_value_to_inherit = false0;
4797 bool_Bool inherited_config_has_transform_precoding = false0;
4798 int dmrs_configs_seen = 0;
4799
4800 /* Dissect each entry until reach number of configured ueIds (or run out of extlen bytes..) */
4801 uint32_t ueid_index = 0;
4802 while ((offset < (extension_start_offset + extlen*4)) && (ueid_index < number_of_ueids)) {
4803 dmrs_configs_seen++;
4804
4805 /* Subtree */
4806 proto_item *entry_ti = proto_tree_add_string_format(extension_tree, hf_oran_dmrs_entry,
4807 tvb, offset, 0, "",
4808 "Entry");
4809 proto_tree *entry_tree = proto_item_add_subtree(entry_ti, ett_oran_dmrs_entry);
4810
4811 /* entryType (3 bits) */
4812 uint32_t entry_type;
4813 proto_item *entry_type_ti;
4814 entry_type_ti = proto_tree_add_item_ret_uint(entry_tree, hf_oran_entry_type, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &entry_type);
4815 if (entry_type > 3) {
4816 proto_item_append_text(entry_type_ti, " (reserved)");
4817 }
4818
4819 /* dmrsPortNumber (5 bits). Values 0-11 allowed */
4820 unsigned int dmrs_port_number;
4821 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);
4822 if (dmrs_port_number > 11) {
4823 proto_item_append_text(dpn_ti, " (12-31 are reserved)");
4824 }
4825 offset += 1;
4826
4827 /* What follows depends upon entryType */
4828 switch (entry_type) {
4829 case 0: /* dmrsPortNumber config same as previous, ueId ueIdReset=0 */
4830 case 1: /* dmrsPortNumber config same as previous, ueId ueIdReset=1 */
4831 /* No further fields for these */
4832 /* Error here if no previous values to inherit!! */
4833 if (!seen_value_to_inherit) {
4834 expert_add_info_format(pinfo, entry_type_ti, &ei_oran_se24_nothing_to_inherit,
4835 "SE24: have seen entry type %u, but no previous config (type 2 or 3) to inherit config from", entry_type);
4836
4837 }
4838 /* TODO: would be useful to repeat whole inherited config here? */
4839 break;
4840
4841 case 2: /* transform precoding disabled */
4842 case 3: /* transform precoding enabled */
4843 {
4844 /* Type 2/3 are very similar.. */
4845
4846 /* ueIdReset (1 bit) */
4847 proto_tree_add_item(entry_tree, hf_oran_ueid_reset, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4848 /* posMeas (1 bit) */
4849 proto_tree_add_item(entry_tree, hf_oran_pos_meas, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4850
4851 /* dmrsSymbolMask (14 bits) */
4852 static int * const dmrs_symbol_mask_flags[] = {
4853 &hf_oran_dmrs_symbol_mask_s13,
4854 &hf_oran_dmrs_symbol_mask_s12,
4855 &hf_oran_dmrs_symbol_mask_s11,
4856 &hf_oran_dmrs_symbol_mask_s10,
4857 &hf_oran_dmrs_symbol_mask_s9,
4858 &hf_oran_dmrs_symbol_mask_s8,
4859 &hf_oran_dmrs_symbol_mask_s7,
4860 &hf_oran_dmrs_symbol_mask_s6,
4861 &hf_oran_dmrs_symbol_mask_s5,
4862 &hf_oran_dmrs_symbol_mask_s4,
4863 &hf_oran_dmrs_symbol_mask_s3,
4864 &hf_oran_dmrs_symbol_mask_s2,
4865 &hf_oran_dmrs_symbol_mask_s1,
4866 &hf_oran_dmrs_symbol_mask_s0,
4867 NULL((void*)0)
4868 };
4869 proto_tree_add_bitmask(entry_tree, tvb, offset,
4870 hf_oran_dmrs_symbol_mask, ett_oran_dmrs_symbol_mask, dmrs_symbol_mask_flags, ENC_BIG_ENDIAN0x00000000);
4871 offset += 2;
4872
4873 /* scrambling */
4874 proto_tree_add_item(entry_tree, hf_oran_scrambling, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4875 offset += 2;
4876
4877 /* nscid (1 bit) */
4878 proto_tree_add_item(entry_tree, hf_oran_nscid, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4879
4880 /* These 5 bits differ depending upon entry type */
4881 if (entry_type == 2) { /* type 2 */
4882 /* dType (1 bit) */
4883 proto_tree_add_item(entry_tree, hf_oran_dtype, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4884 /* cdmWithoutData (2 bits) */
4885 proto_tree_add_item(entry_tree, hf_oran_cmd_without_data, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4886 /* lambda (2 bits) */
4887 proto_tree_add_item(entry_tree, hf_oran_lambda, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4888 }
4889 else { /* type 3 */
4890 /* reserved (1 bit) */
4891 add_reserved_field(entry_tree, hf_oran_reserved_bit1, tvb, offset, 1);
4892 /* lowPaprType (2 bits) */
4893 proto_tree_add_item(entry_tree, hf_oran_low_papr_type, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4894 /* hoppingMode (2 bits) */
4895 proto_tree_add_item(entry_tree, hf_oran_hopping_mode, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4896 }
4897
4898 /* firstPrb (9 bits) */
4899 proto_tree_add_item(entry_tree, hf_oran_first_prb, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4900 offset += 1;
4901 /* lastPrb (9 bits) */
4902 proto_tree_add_item(entry_tree, hf_oran_last_prb, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4903 offset += 2;
4904 /* Reserved (16 bits) */
4905 add_reserved_field(entry_tree, hf_oran_reserved_16bits, tvb, offset, 2);
4906 offset += 2;
4907
4908 /* Could now see entry types 0 or 1 - they have these values to inherit */
4909 seen_value_to_inherit = true1;
4910 inherited_config_has_transform_precoding = (entry_type == 3);
4911 break;
4912 }
4913
4914 default:
4915 /* reserved - expert info */
4916 break;
4917 }
4918
4919 proto_item_append_text(entry_ti, " [UEId=%u] (dmrsPortNumber=%2u) (type %u - %s) ",
4920 ueids[ueid_index++], dmrs_port_number, entry_type, val_to_str_const(entry_type, entry_type_vals, "Unknown"));
4921 proto_item_set_end(entry_ti, tvb, offset);
4922
4923 if (entry_type <= 1) {
4924 proto_item_append_text(entry_ti, " [transform-precoding %s]",
4925 inherited_config_has_transform_precoding ? "enabled" : "disabled");
4926 }
4927 }
4928
4929 proto_item_append_text(extension_ti, " (%d DMRS configs seen)", dmrs_configs_seen);
4930 break;
4931 }
4932
4933 case 25: /* SE 25: Symbol reordering for DMRS-BF */
4934 /* Just dissect each available block of 7 bytes as the 14 symbols for a layer,
4935 where each layer could be one or apply to all layers. */
4936 {
4937 /* TODO: should only appear in one section of a message - check? */
4938 unsigned layer = 0;
4939 proto_item *layer_ti;
4940 while (offset+7 <= (extension_start_offset + extlen*4)) {
4941 /* Layer subtree */
4942 layer_ti = proto_tree_add_string_format(extension_tree, hf_oran_symbol_reordering_layer,
4943 tvb, offset, 7, "",
4944 "Layer");
4945 proto_tree *layer_tree = proto_item_add_subtree(layer_ti, ett_oran_symbol_reordering_layer);
4946
4947 /* All 14 symbols for a layer (or all layers) */
4948 for (unsigned s=0; s < 14; s++) {
4949 proto_item *sym_ti;
4950 /* txWinForOnAirSymbol */
4951 unsigned int tx_win_for_on_air_symbol;
4952 sym_ti = proto_tree_add_item_ret_uint(layer_tree,
4953 (s % 2) ? hf_oran_tx_win_for_on_air_symbol_r : hf_oran_tx_win_for_on_air_symbol_l,
4954 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &tx_win_for_on_air_symbol);
4955 if (tx_win_for_on_air_symbol == 0x0F) {
4956 /* Ordering not affected */
4957 proto_item_append_text(sym_ti, " (sym %u - no info)", s);
4958 }
4959 else {
4960 proto_item_append_text(sym_ti, " (sym %u)", s);
4961 }
4962 if (s % 2) {
4963 offset += 1;
4964 }
4965 }
4966
4967 proto_item_append_text(layer_ti, " (layer %u)", ++layer);
4968 proto_item_append_text(extension_ti, " (layer %u)", layer);
4969 }
4970 /* Set layer subtree label */
4971 if (layer == 1) {
4972 proto_item_append_text(layer_ti, " (all)");
4973 proto_item_append_text(extension_ti, " (all)");
4974 }
4975 if (layer == 0) {
4976 /* TODO: are no layers valid? What does it mean? */
4977 proto_item_append_text(extension_ti, " (none)");
4978 }
4979 break;
4980 }
4981
4982 case 26: /* SE 26: Frequency offset feedback */
4983 /* Reserved (8 bits) */
4984 add_reserved_field(extension_tree, hf_oran_reserved_8bits, tvb, offset, 1);
4985 offset += 1;
4986 /* Reserved (1 bit) */
4987 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
4988 /* numFoFb (7 bits) */
4989 unsigned num_fo_fb;
4990 proto_tree_add_item_ret_uint(extension_tree, hf_oran_num_fo_fb, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &num_fo_fb);
4991 offset += 1;
4992
4993 /* Add each freqOffsetFb value */
4994 for (unsigned n=0; n < num_fo_fb; n++) {
4995 unsigned freq_offset_fb;
4996 /* freqOffsetFb (16 bits) */
4997 proto_item *offset_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_freq_offset_fb,
4998 tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &freq_offset_fb);
4999 /* Show if maps onto a -ve number */
5000 if ((freq_offset_fb >= 0x8ad0) && (freq_offset_fb <= 0xffff)) {
5001 proto_item_append_text(offset_ti, "(value %d)", -1 - (0xffff-freq_offset_fb));
5002 }
5003 proto_item_append_text(offset_ti, " [#%u]", n+1);
5004 offset += 2;
5005 }
5006 break;
5007
5008 case 27: /* SE 27: O-DU controlled dimensionality reduction */
5009 {
5010 /* Hidden filter for bf (DMRS BF) */
5011 bf_ti = proto_tree_add_item(tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
5012 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
5013
5014 /* beamType (2 bits) */
5015 unsigned beam_type;
5016 proto_tree_add_item_ret_uint(extension_tree, hf_oran_beam_type, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &beam_type);
5017 /* reserved (6 bits) */
5018 add_reserved_field(extension_tree, hf_oran_reserved_last_6bits, tvb, offset, 1);
5019 offset += 1;
5020
5021 /* numElements */
5022 unsigned num_elements;
5023 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);
5024 if (num_elements == 0) {
5025 num_elements = 256;
5026 proto_item_append_text(num_elements_ti, " (256");
5027 }
5028
5029 offset += 1;
5030
5031 /* beamId value(s) */
5032 switch (beam_type) {
5033 case 0:
5034 for (unsigned n=0; n < num_elements; n++) {
5035 /* reserved (1 bit) + beamId */
5036 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
5037 proto_tree_add_item(c_section_tree, hf_oran_beamId, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
5038 offset += 2;
5039 }
5040 break;
5041 case 1:
5042 /* reserved (1 bit) + beamId */
5043 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
5044 proto_tree_add_item(c_section_tree, hf_oran_beamId, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
5045 offset += 2;
5046 break;
5047 default:
5048 /* Unknown type... */
5049 break;
5050 }
5051 break;
5052 }
5053
5054 case 28: /* SE 28: O-DU controlled frequency resolution for SINR reporting */
5055 {
5056 /* reserved (3 bits) */
5057 add_reserved_field(extension_tree, hf_oran_reserved_3bits, tvb, offset, 1);
5058 /* numUeSinrRpt (5 bits) */
5059 uint32_t num_ue_sinr_rpt;
5060 proto_tree_add_item_ret_uint(extension_tree, hf_oran_num_ue_sinr_rpt, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &num_ue_sinr_rpt);
5061 offset += 1;
5062
5063 for (uint32_t n=0; n < num_ue_sinr_rpt; n++) {
5064 /* reserved (1 bit) */
5065 add_reserved_field(extension_tree, (n % 2) ? hf_oran_reserved_bit4 : hf_oran_reserved_1bit,
5066 tvb, offset, 1);
5067
5068 /* numSinrPerPrb (3 bits). Taken from alternate nibbles within byte. */
5069 proto_tree_add_item(extension_tree, (n % 2) ? hf_oran_num_sinr_per_prb_right : hf_oran_num_sinr_per_prb,
5070 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5071 if (n % 2) {
5072 offset += 1;
5073 }
5074 }
5075
5076 /* May need to skip beyond half-used byte */
5077 if (num_ue_sinr_rpt % 2) {
5078 offset += 1;
5079 }
5080 break;
5081 }
5082
5083 case 29: /* SE 29: Cyclic delay adjustment */
5084 /* reserved (4 bits) */
5085 add_reserved_field(extension_tree, hf_oran_reserved_4bits, tvb, offset, 1);
5086 /* cdScgSize (4 bits) */
5087 proto_tree_add_item(extension_tree, hf_oran_cd_scg_size, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5088 offset += 1;
5089
5090 /* cdScgPhaseStep */
5091 proto_tree_add_item(extension_tree, hf_oran_cd_scg_phase_step, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5092 offset += 1;
5093 break;
5094
5095 case 30: /* SE 30: PUSCH repetition indication */
5096 {
5097 /* Only valid for UL */
5098 if (!tap_info->uplink) {
5099 expert_add_info(pinfo, extension_ti, &ei_oran_se30_not_ul);
5100 }
5101
5102 /* ueids[], number_of_ueids may have been rewritten by SE10 */
5103
5104 /* reserved (4 bits) */
5105 add_reserved_field(extension_tree, hf_oran_reserved_4bits, tvb, offset, 1);
5106 /* numRepUe (4 bits) */
5107 uint8_t num_rep_ue;
5108 proto_tree_add_item_ret_uint8(extension_tree, hf_oran_num_rep_ue, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &num_rep_ue);
5109 offset ++;
5110 /* reserved (8 bits) */
5111 add_reserved_field(extension_tree, hf_oran_reserved_8bits, tvb, offset, 1);
5112 offset += 1;
5113
5114 if (num_rep_ue == 1) {
5115 /* SE10 *not* present. N.B. this should tally with number_of_ueids being set to only 1? */
5116 /* reserved (1 bit) */
5117 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
5118 /* isLastRep (1 bit). Value meaningless here? */
5119 proto_tree_add_item(extension_tree, hf_oran_is_last_rep, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5120 /* repIndex (6 bits) */
5121 proto_tree_add_item(extension_tree, hf_oran_rep_index, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5122 offset += 1;
5123
5124 /* reserved (2 bits) */
5125 add_reserved_field(extension_tree, hf_oran_reserved_2bits, tvb, offset, 1);
5126 /* numReps (6 bits) */
5127 uint8_t num_reps;
5128 proto_tree_add_item_ret_uint8(extension_tree, hf_oran_num_reps, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &num_reps);
5129 /* TODO: should numReps be 0 here? */
5130 offset += 1;
5131
5132 /* reserved (2 bits) */
5133 add_reserved_field(extension_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5134 offset += 2;
5135
5136 }
5137 else {
5138 /* SE10 present */
5139 bool_Bool is_last_rep = false0;
5140 /* TODO: should is_last_rep (also) cause loop exit? */
5141 for (uint8_t ue_idx=0; (ue_idx < num_rep_ue) && !is_last_rep; ue_idx++) {
5142 /* reserved (1 bit) */
5143 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
5144 /* isLastRep (1 bit) */
5145 proto_tree_add_item_ret_boolean(extension_tree, hf_oran_is_last_rep, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &is_last_rep);
5146 /* repIndex (6 bits) */
5147 proto_tree_add_item(extension_tree, hf_oran_rep_index, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5148 offset += 1;
5149
5150 /* reserved (2 bits) */
5151 add_reserved_field(extension_tree, hf_oran_reserved_2bits, tvb, offset, 1);
5152 /* numReps (6 bits) */
5153 uint8_t num_reps;
5154 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);
5155 /* TODO: values 33-63 are reserved */
5156 if (num_reps > 32) {
5157 proto_item_append_text(num_reps_ti, " (reserved)");
5158 }
5159 offset += 1;
5160
5161 for (uint8_t rep=0; rep < num_reps; rep++) {
5162 /* reserved (1 bit) */
5163 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
5164 /* repUeId (15 bits) */
5165 /* TODO: should be fetching and comparing with ueids[] from SE10? */
5166 uint16_t ueid;
5167 proto_item *ueid_ti = proto_tree_add_item_ret_uint16(extension_tree, hf_oran_rep_ueid, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &ueid);
5168
5169 /* Check that this ueid is recognised (among ueids[], number_of_ueids) */
5170 bool_Bool matched = false0;
5171 for (unsigned u=0; u < number_of_ueids; u++) {
5172 if (ueid == ueids[u])
5173 matched = true1;
5174 }
5175 if (!matched) {
5176 expert_add_info_format(pinfo, ueid_ti, &ei_oran_se30_unknown_ueid,
5177 "SE 30 mentions UEId %u - not seen in SE10", ueid);
5178 }
5179 offset += 2;
5180 }
5181 }
5182 }
5183 break;
5184 }
5185 case 31: /* SE 31: MCS Information */
5186 {
5187 /* TODO: show ueid (from ST5 or SE10) as generated field? Maybe add a subtree for each entry? */
5188 for (uint32_t u=0; u < number_of_ueids; u++) {
5189 /* reserved (4 bits) */
5190 add_reserved_field(extension_tree, hf_oran_reserved_4bits, tvb, offset, 1);
5191 /* mcsTable (4 bits) */
5192 proto_tree_add_item(extension_tree, hf_oran_mcs_table, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5193 offset += 1;
5194
5195 /* reserved (2 bits) */
5196 add_reserved_field(extension_tree, hf_oran_reserved_4bits, tvb, offset, 1);
5197 /* mcsIndex (6 bits) */
5198 proto_tree_add_item(extension_tree, hf_oran_mcs_index, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5199 }
5200 break;
5201 }
5202
5203 case 32: /* SE 32: Rank and TPMI measurement request */
5204 {
5205 /* reserved (3 bits) */
5206 add_reserved_field(extension_tree, hf_oran_reserved_3bits, tvb, offset, 1);
5207 /* numMeasReq (5 bits) */
5208 uint8_t num_meas_req;
5209 proto_tree_add_item_ret_uint8(extension_tree, hf_oran_num_meas_req, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &num_meas_req);
5210 offset += 1;
5211
5212 /* reserved (8 bits) */
5213 add_reserved_field(extension_tree, hf_oran_reserved_8bits, tvb, offset, 1);
5214 offset += 1;
5215
5216 /* Show each measurement request */
5217 for (unsigned r=0; r < num_meas_req; r++) {
5218 /* Reserved (1 bit) */
5219 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
5220 /* ueId (14 bits) */
5221 proto_tree_add_item(extension_tree, hf_oran_ueId, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
5222 offset += 2;
5223
5224 /* numOfUeAntPorts (4 bits) */
5225 proto_tree_add_item(extension_tree, hf_oran_num_of_ue_ant_ports, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5226 /* ueRank (4 bits) */
5227 proto_tree_add_item(extension_tree, hf_oran_ue_rank, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5228 offset += 1;
5229
5230 /* codebookSubset (2 bits) */
5231 proto_tree_add_item(extension_tree, hf_oran_codebook_subset, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5232 /* TODO: tpmiIndex (6 bits) */
5233 offset += 1;
5234
5235 /* fullPwrMode (2 bits) */
5236 proto_tree_add_item(extension_tree, hf_oran_full_pwr_mode, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5237 /* fullPwrMode2TmpiGroup (14 bits) */
5238 /* TODO: add as a bitset */
5239 proto_tree_add_item(extension_tree, hf_oran_full_pwr_mode_2_tpmi_group, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
5240 offset += 2;
5241
5242 /* reserved (2 bytes) */
5243 add_reserved_field(extension_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5244 offset += 2;
5245 }
5246 break;
5247 }
5248
5249 default:
5250 /* Other/unexpected extension types */
5251 expert_add_info_format(pinfo, exttype_ti, &ei_oran_unhandled_se,
5252 "SE %u (%s) not supported by dissector",
5253 exttype, val_to_str_ext_const(exttype, &exttype_vals_ext, "Reserved"));
5254 ext_unhandled = true1;
5255 break;
5256 }
5257
5258 /* Check offset compared with extlen. There should be 0-3 bytes of padding */
5259 int num_padding_bytes = (extension_start_offset + (extlen*4) - offset);
5260 if (!ext_unhandled && ((num_padding_bytes<0) || (num_padding_bytes>3))) {
5261 expert_add_info_format(pinfo, extlen_ti, &ei_oran_extlen_wrong,
5262 "extlen signalled %u bytes (+ 0-3 bytes padding), but %u were dissected",
5263 extlen*4, offset-extension_start_offset);
5264 }
5265
5266 /* Move offset to beyond signalled length of extension */
5267 offset = extension_start_offset + (extlen*4);
5268
5269 /* Set length of extension header. */
5270 proto_item_set_len(extension_ti, extlen*4);
5271 }
5272 /* End of section extension handling */
5273
5274 /* Tap section beamId if not overwritten by SEs */
5275 if (!section_beamId_ignored && section_beamId != 0) {
5276 add_beam_id_to_tap(tap_info, section_beamId);
5277 }
5278
5279
5280 /* RRM measurement reports have measurement reports *after* extensions */
5281 if (sectionType == SEC_C_RRM_MEAS_REPORTS) /* Section Type 10 */
5282 {
5283 /* Hidden filter for bf (DMFS-BF). No BF weights though.. */
5284 bf_ti = proto_tree_add_item(c_section_tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
5285 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
5286
5287 bool_Bool mf;
5288 do {
5289 /* Measurement report subtree */
5290 proto_item *mr_ti = proto_tree_add_string_format(c_section_tree, hf_oran_measurement_report,
5291 tvb, offset, 1, "", "Measurement Report");
5292 proto_tree *mr_tree = proto_item_add_subtree(mr_ti, ett_oran_measurement_report);
5293 unsigned report_start_offset = offset;
5294
5295 /* measurement flag (i.e., more reports after this one) (1 bit) */
5296 proto_tree_add_item_ret_boolean(mr_tree, hf_oran_mf, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &mf);
5297
5298 /* measTypeId (7 bits) */
5299 uint32_t meas_type_id;
5300 proto_item *meas_type_id_ti;
5301 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);
5302 offset += 1;
5303
5304 /* Common to all measurement types */
5305 unsigned num_elements = 0;
5306 if (meas_type_id == 6) {
5307 /* numElements */
5308 proto_tree_add_item_ret_uint(mr_tree, hf_oran_num_elements, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &num_elements);
5309 }
5310 else {
5311 /* All other meas ids have a reserved byte */
5312 add_reserved_field(mr_tree, hf_oran_reserved_8bits, tvb, offset, 1);
5313 }
5314 offset += 1;
5315
5316 /* measDataSize (16 bits). N.B. begins at mf field, i.e. 2 bytes before this one */
5317 unsigned meas_data_size;
5318 proto_item *meas_data_size_ti;
5319 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);
5320 meas_data_size *= 4;
5321 proto_item_append_text(meas_data_size_ti, " (%u bytes)", meas_data_size);
5322 offset += 2;
5323
5324 /* Summary for measurement report root */
5325 proto_item_append_text(mr_ti, " (measTypeId=%u - %s)",
5326 meas_type_id, val_to_str_const(meas_type_id, meas_type_id_vals, "unknown"));
5327 /* And section header */
5328 proto_item_append_text(tree, " (%s)", val_to_str_const(meas_type_id, meas_type_id_vals, "unknown"));
5329 /* And Info column */
5330 col_append_fstr(pinfo->cinfo, COL_INFO, " (%s)", val_to_str_const(meas_type_id, meas_type_id_vals, "unknown"));
5331
5332 /* Handle specific message type fields */
5333 switch (meas_type_id) {
5334 case 1:
5335 {
5336 /* ueTae */
5337 unsigned ue_tae;
5338 proto_item *ue_tae_ti;
5339 ue_tae_ti = proto_tree_add_item_ret_uint(mr_tree, hf_oran_ue_tae, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &ue_tae);
5340 /* Show if maps onto a -ve number */
5341 if ((ue_tae >= 0x8ad0) && (ue_tae <= 0xffff)) {
5342 proto_item_append_text(ue_tae_ti, "(value %d)", -1 - (0xffff-ue_tae));
5343 }
5344 offset += 2;
5345
5346 /* Reserved (16 bits) */
5347 add_reserved_field(mr_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5348 offset += 2;
5349 break;
5350 }
5351 case 2:
5352 /* ueLayerPower entries (how many? for now just use up meas_data_size..) */
5353 /* TODO: add number of distinct dmrsPortNumber entries seen in SE24 and save in state? */
5354 /* Or would it make sense to use the preference 'pref_num_bf_antennas' ? */
5355 for (unsigned n=0; n < (meas_data_size-4)/2; n++) {
5356 unsigned ue_layer_power;
5357 proto_item *ue_layer_power_ti;
5358 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);
5359 /* Show if maps onto a -ve number */
5360 if ((ue_layer_power >= 0x8ad0) && (ue_layer_power <= 0xffff)) {
5361 proto_item_append_text(ue_layer_power_ti, "(value %d)", -1 - (0xffff-ue_layer_power));
5362 }
5363 offset += 2;
5364 }
5365 /* padding out to 4 bytes */
5366 break;
5367 case 3:
5368 {
5369 /* ueFreqOffset */
5370 unsigned ue_freq_offset;
5371 proto_item *ue_freq_offset_ti;
5372 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);
5373 /* Show if maps onto a -ve number */
5374 if ((ue_freq_offset >= 0x8ad0) && (ue_freq_offset <= 0xffff)) {
5375 proto_item_append_text(ue_freq_offset_ti, "(value %d)", -1 - (0xffff-ue_freq_offset));
5376 }
5377 offset += 2;
5378
5379 /* Reserved (16 bits) */
5380 add_reserved_field(mr_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5381 offset += 2;
5382 break;
5383 }
5384 case 4:
5385 case 5:
5386 /* reserved (2 bits) */
5387 add_reserved_field(mr_tree, hf_oran_reserved_2bits, tvb, offset, 1);
5388 /* symbolMask (14 bits) */
5389 offset = dissect_symbolmask(tvb, mr_tree, offset, NULL((void*)0), NULL((void*)0));
5390
5391 /* 2 bytes for each PRB ipnPower */
5392 for (unsigned prb=0; prb<MAX_PRBS273; prb++) {
5393 /* Skip if should not be reported */
5394 if (!prbs_for_st10_type5[prb]) {
5395 continue;
5396 }
5397 unsigned ipn_power;
5398 proto_item *ipn_power_ti;
5399 /* ipnPower (2 bytes) */
5400 ipn_power_ti = proto_tree_add_item_ret_uint(mr_tree, hf_oran_ipn_power, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &ipn_power);
5401 proto_item_append_text(ipn_power_ti, " (PRB %3d)", prb);
5402 /* Show if maps onto a -ve number */
5403 if ((ipn_power >= 0x8ad0) && (ipn_power <= 0xffff)) {
5404 proto_item_append_text(ipn_power_ti, " (value %d)", -1 - (0xffff-ipn_power));
5405 }
5406 offset += 2;
5407 }
5408 /* padding out to 4 bytes */
5409 break;
5410 case 6:
5411 /* antDmrsSnrVal entries */
5412 for (unsigned n=0; n < num_elements; n++) {
5413 unsigned snr_value;
5414 proto_item *snr_value_ti;
5415 /* antDmrsSnrVal (2 bytes) */
5416 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);
5417 proto_item_append_text(snr_value_ti, " (elem %2u)", n+1);
5418 /* Show if maps onto a -ve number */
5419 if ((snr_value >= 0x8ad0) && (snr_value <= 0xffff)) {
5420 proto_item_append_text(snr_value_ti, " (value %d)", -1 - (0xffff-snr_value));
5421 }
5422 offset += 2;
5423 }
5424 break;
5425 case 7:
5426 {
5427 /* UE positioning measurement report */
5428 float start_value;
5429
5430 /* ueAzAoa (16 bits) */
5431 uint32_t ue_az_aoa;
5432 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);
5433 if (ue_az_aoa <= 0xE0F) {
5434 if (ue_az_aoa >= 0x0708) {
5435 start_value = (ue_az_aoa-0x0708) * (float)0.1;
5436 proto_item_append_text(ue_az_aoa_ti, " (%.1f <= val < %.1f degrees)", start_value, start_value + (float)0.1);
5437 }
5438 else {
5439 start_value = 180 + (ue_az_aoa * (float)0.1);
5440 proto_item_append_text(ue_az_aoa_ti, " (%.1f <= val < %.1f degrees)", start_value, start_value + (float)0.1);
5441 }
5442 }
5443 else if (ue_az_aoa == 0xffff) {
5444 proto_item_append_text(ue_az_aoa_ti, " (invalid measurement result)");
5445 }
5446 else {
5447 proto_item_append_text(ue_az_aoa_ti, " (reserved)");
5448 }
5449 offset += 2;
5450
5451 /* Reserved (16 bits) */
5452 add_reserved_field(mr_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5453 offset += 2;
5454
5455 /* ueZeAoa (16 bits) */
5456 uint32_t ue_ze_aoa;
5457 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);
5458 if (ue_ze_aoa <= 0x707) {
5459 start_value = ue_ze_aoa * (float)0.1;
5460 proto_item_append_text(ue_ze_aoa_ti, " (%.1f <= val < %.1f degrees)", start_value, start_value + (float)0.1);
5461 }
5462 else if (ue_az_aoa == 0xffff) {
5463 proto_item_append_text(ue_ze_aoa_ti, " (invalid measurement result)");
5464 }
5465 else {
5466 proto_item_append_text(ue_ze_aoa_ti, " (reserved)");
5467 }
5468 offset += 2;
5469
5470 /* Reserved (16 bits) */
5471 add_reserved_field(mr_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5472 offset += 2;
5473
5474 /* uePosToaOffset (16 bits) */
5475 uint32_t ue_pos_toa_offset;
5476 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);
5477 if (ue_pos_toa_offset == 0) {
5478 proto_item_append_text(ue_pos_toa_offset_ti, " (no UE ToA offset, 0 symbols)");
5479 }
5480 else if (ue_pos_toa_offset <= 0x7fff) {
5481 proto_item_append_text(ue_pos_toa_offset_ti, " (+ve UE ToA offset)");
5482 }
5483 else if (ue_pos_toa_offset == 0x8000) {
5484 proto_item_append_text(ue_pos_toa_offset_ti, " (invalid measurement result)");
5485 }
5486 else {
5487 proto_item_append_text(ue_pos_toa_offset_ti, " (-ve UE ToA offset)");
5488 }
5489 offset += 2;
5490
5491 /* Reserved (16 bits) */
5492 add_reserved_field(mr_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5493 offset += 2;
5494 break;
5495 }
5496 case 8:
5497 {
5498 /* UE radial speed measurement report */
5499
5500 /* ueRadialSpeed (16 bits) */
5501 uint32_t radial_speed;
5502 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);
5503 if (radial_speed <= 10000) {
5504 proto_item_append_text(radial_speed_ti, " (%.1f km/h)", radial_speed * (float)0.1);
5505 }
5506 else if (radial_speed == 0x8000) {
5507 proto_item_append_text(radial_speed_ti, " (invalid measurement result)");
5508 }
5509 else {
5510 proto_item_append_text(radial_speed_ti, " (reserved value)");
5511 }
5512 offset += 2;
5513
5514 /* Reserved (16 bits) */
5515 add_reserved_field(mr_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5516 offset += 2;
5517 break;
5518 }
5519 case 9:
5520 {
5521 /* TODO: UE post-equalization MU interference measurement */
5522
5523 /* reserved (16 bits) */
5524 add_reserved_field(mr_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5525 offset += 2;
5526
5527 /* TODO: muInterferenceLevel (all layers * all PRB blocks) */
5528 break;
5529 }
5530 case 10:
5531 {
5532 /* UE TPMI and rank recommendation measurement */
5533
5534 /* numCandRanks (4 bits - only 1-4 valid) */
5535 uint8_t num_cand_ranks;
5536 proto_tree_add_item_ret_uint8(mr_tree, hf_oran_num_cand_ranks, tvb, offset, 1, ENC_NA0x00000000, &num_cand_ranks);
5537 if (num_cand_ranks > 4) {
5538 num_cand_ranks = 4;
5539 }
5540 if (num_cand_ranks < 1) {
5541 num_cand_ranks = 1;
5542 }
5543
5544 /* uePrefRank (4 bits) */
5545 add_reserved_field(mr_tree, hf_oran_ue_pref_rank, tvb, offset, 1);
5546 offset += 1;
5547
5548 for (uint8_t cand_rank=1; cand_rank <= num_cand_ranks; cand_rank++) {
5549 /* ueTpmiRankY (1 byte) */
5550 proto_item *rank_y_ti = proto_tree_add_item(mr_tree, hf_oran_ue_tpmi_rank_y,
5551 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5552 proto_item_append_text(rank_y_ti, " (rank %u)", cand_rank);
5553
5554 offset += 1;
5555
5556 for (uint8_t sinr = 1; sinr <= cand_rank; sinr++) {
5557 /* ueTpmiRankYSinrLX (2 bytes) */
5558 proto_item *rank_y_sinr_x_ti = proto_tree_add_item(mr_tree, hf_oran_ue_tpmi_rank_y_sinr_lx,
5559 tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
5560 proto_item_append_text(rank_y_sinr_x_ti, " (rank %u, sinr %u)", cand_rank, sinr);
5561 offset += 2;
5562 }
5563 }
5564 break;
5565 }
5566 case 11:
5567 {
5568 /* UE layer pre-equalization SINR report */
5569 /* TODO: how to know how many layers? Just fill up available data? */
5570 unsigned num_layers = (meas_data_size-1) * 4;
5571 for (unsigned layer=0; layer < num_layers; layer++) {
5572 /* ueLayerPreEqSinr (2 bytes each) */
5573 proto_item *pre_eq_sinr_ti = proto_tree_add_item(mr_tree, hf_oran_ue_layer_pre_eq_sinr,
5574 tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
5575 proto_item_append_text(pre_eq_sinr_ti, " (layer %u)", layer);
5576 offset += 2;
5577 }
5578 break;
5579 }
5580
5581 default:
5582 /* Anything else is not expected */
5583 expert_add_info_format(pinfo, meas_type_id_ti, &ei_oran_unexpected_measTypeId,
5584 "measTypeId %u (%s) not supported - only 1-6 are expected",
5585 meas_type_id,
5586 val_to_str_const(meas_type_id, meas_type_id_vals, "reserved"));
5587 break;
5588
5589 }
5590
5591 /* Pad out to next 4 bytes */
5592 offset += WS_PADDING_TO_4(offset-report_start_offset)((4U - ((offset-report_start_offset) % 4U)) % 4U);
5593
5594 /* TODO: verify dissected size of report vs meas_data_size? */
5595
5596 /* End of measurement report tree */
5597 proto_item_set_end(mr_ti, tvb, offset);
5598 } while (mf);
5599 }
5600
5601 /* Request for RRM Measurements has measurement commands after extensions */
5602 else if (sectionType == SEC_C_REQUEST_RRM_MEAS) /* Section Type 11 */
5603 {
5604 bool_Bool mf = true1;
5605 do {
5606 /* Measurement command subtree */
5607 proto_item *mc_ti = proto_tree_add_string_format(c_section_tree, hf_oran_measurement_command,
5608 tvb, offset, 8, "", "Measurement Command");
5609 proto_tree *mc_tree = proto_item_add_subtree(mc_ti, ett_oran_measurement_command);
5610
5611 /* mf (1 bit). 1st measurement command is always preset */
5612 proto_tree_add_item_ret_boolean(mc_tree, hf_oran_mf, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &mf);
5613
5614 /* measTypeId (7 bits) */
5615 uint32_t meas_type_id;
5616 proto_item *meas_type_id_ti;
5617 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);
5618 offset += 1;
5619
5620 proto_item *meas_command_ti;
5621 uint32_t meas_command_size;
5622
5623 switch (meas_type_id) {
5624 case 5: /* command for IpN for unallocated PRBs */
5625 /* reserved (1 byte) */
5626 add_reserved_field(mc_tree, hf_oran_reserved_8bits, tvb, offset, 1);
5627 offset += 1;
5628 /* measCmdSize. Presumably number of words so in future could skip unrecognised command types.. */
5629 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);
5630 proto_item_append_text(meas_command_ti, " (%u bytes)", meas_command_size*4);
5631 offset += 2;
5632 /* reserved (2 bits) */
5633 add_reserved_field(mc_tree, hf_oran_reserved_2bits, tvb, offset, 1);
5634 /* symbolMask (14 bits) */
5635 offset = dissect_symbolmask(tvb, mc_tree, offset, NULL((void*)0), NULL((void*)0));
5636 /* reserved (16 bits) */
5637 add_reserved_field(mc_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5638 offset += 2;
5639 break;
5640
5641 default:
5642 /* Anything else is not expected */
5643 expert_add_info_format(pinfo, meas_type_id_ti, &ei_oran_unexpected_measTypeId,
5644 "measTypeId %u (%s) not supported - only 5 is expected",
5645 meas_type_id,
5646 val_to_str_const(meas_type_id, meas_type_id_vals, "reserved"));
5647 break;
5648 }
5649 proto_item_append_text(mc_ti, " (%s)", val_to_str_const(meas_type_id, meas_type_id_vals, "unknown"));
5650
5651 } while (mf);
5652 }
5653
5654 /* Set extent of overall section */
5655 proto_item_set_len(sectionHeading, offset);
5656
5657 return offset;
5658}
5659
5660/* Dissect udCompHdr (user data compression header, 7.5.2.10) */
5661/* bit_width and comp_meth are out params */
5662static int dissect_udcomphdr(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset,
5663 bool_Bool cplane, bool_Bool ignore,
5664 unsigned *bit_width, unsigned *comp_meth, proto_item **comp_meth_ti,
5665 oran_tap_info *tap_info)
5666{
5667 /* Subtree */
5668 proto_item *udcomphdr_ti = proto_tree_add_string_format(tree, hf_oran_udCompHdr,
5669 tvb, offset, 1, "",
5670 "udCompHdr");
5671 proto_tree *udcomphdr_tree = proto_item_add_subtree(udcomphdr_ti, ett_oran_udcomphdr);
5672
5673 /* udIqWidth */
5674 uint32_t hdr_iq_width;
5675 proto_item *iq_width_item = proto_tree_add_item_ret_uint(udcomphdr_tree, hf_oran_udCompHdrIqWidth , tvb, offset, 1, ENC_NA0x00000000, &hdr_iq_width);
5676 *bit_width = (hdr_iq_width) ? hdr_iq_width : 16;
5677 proto_item_append_text(iq_width_item, " (%u bits)", *bit_width);
5678
5679 /* udCompMeth */
5680 uint32_t ud_comp_meth;
5681 *comp_meth_ti = proto_tree_add_item_ret_uint(udcomphdr_tree, hf_oran_udCompHdrMeth, tvb, offset, 1, ENC_NA0x00000000, &ud_comp_meth);
5682 if (comp_meth) {
5683 *comp_meth = ud_comp_meth;
5684 }
5685
5686 /* Populate tap header with compression settings */
5687 if (!ignore) {
5688 tap_info->compression_methods |= (1 << ud_comp_meth);
5689 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))
;
5690 /* Summary */
5691 proto_item_append_text(udcomphdr_ti, " (IqWidth=%u, udCompMeth=%s)",
5692 *bit_width, rval_to_str_const(ud_comp_meth, ud_comp_header_meth, "Unknown"));
5693 }
5694 else {
5695 proto_item_append_text(udcomphdr_ti, " (ignored)");
5696 if (hdr_iq_width || ud_comp_meth) {
5697 if (cplane) {
5698 /* Only ignore DL for cplane */
5699 expert_add_info_format(pinfo, udcomphdr_ti, &ei_oran_udpcomphdr_should_be_zero,
5700 "udCompHdr in C-Plane for DL should be 0 - found 0x%02x",
5701 tvb_get_uint8(tvb, offset));
5702 }
5703 else {
5704 /* TODO: Ignore UL if using m-plane/preference setting rather than c-plane, but wrong to be set? */
5705 /* expert_add_info_format(pinfo, udcomphdr_ti, &ei_oran_udpcomphdr_should_be_zero,
5706 "udCompHdr in C-Plane for UL should be 0 - found 0x%02x",
5707 tvb_get_uint8(tvb, offset));
5708 */
5709 }
5710
5711 }
5712 }
5713 return offset+1;
5714}
5715
5716/* Dissect udCompParam (user data compression parameter, 8.3.3.15) */
5717/* bit_width and comp_meth are out params */
5718static int dissect_udcompparam(tvbuff_t *tvb, packet_info *pinfo _U___attribute__((unused)), proto_tree *tree, unsigned offset,
5719 unsigned comp_meth,
5720 uint32_t *exponent, uint16_t *sReSMask,
5721 bool_Bool for_sinr)
5722{
5723 if (for_sinr && (comp_meth != COMP_BLOCK_FP1)) {
5724 /* sinrCompParam only present when bfp is used */
5725 return offset;
5726 }
5727
5728 if (comp_meth == COMP_NONE0 ||
5729 comp_meth == COMP_MODULATION4 ||
5730 comp_meth == MOD_COMPR_AND_SELECTIVE_RE_WITH_MASKS8) {
5731
5732 /* Not even creating a subtree for udCompMeth 0, 4, 8 */
5733 return offset;
5734 }
5735
5736 /* Subtree */
5737 unsigned start_offset = offset;
5738 proto_item *udcompparam_ti = proto_tree_add_string_format(tree, hf_oran_udCompParam,
5739 tvb, offset, 1, "",
5740 (for_sinr) ? "sinrCompParam" : "udCompParam");
5741 proto_tree *udcompparam_tree = proto_item_add_subtree(udcompparam_ti, ett_oran_udcompparam);
5742
5743 /* Show comp_meth as a generated field */
5744 proto_item *meth_ti = proto_tree_add_uint(udcompparam_tree, hf_oran_udCompHdrMeth_pref, tvb, 0, 0, comp_meth);
5745 proto_item_set_generated(meth_ti);
5746
5747 uint32_t param_exponent;
5748 uint64_t param_sresmask;
5749
5750 static int * const sres_mask_flags[] = {
5751 &hf_oran_sReSMask_re12,
5752 &hf_oran_sReSMask_re11,
5753 &hf_oran_sReSMask_re10,
5754 &hf_oran_sReSMask_re9,
5755 &hf_oran_sReSMask_re8,
5756 &hf_oran_sReSMask_re7,
5757 &hf_oran_sReSMask_re6,
5758 &hf_oran_sReSMask_re5,
5759 &hf_oran_sReSMask_re4,
5760 &hf_oran_sReSMask_re3,
5761 &hf_oran_sReSMask_re2,
5762 &hf_oran_sReSMask_re1,
5763 NULL((void*)0)
5764 };
5765
5766 switch (comp_meth) {
5767 case COMP_BLOCK_FP1: /* 1 */
5768 case BFP_AND_SELECTIVE_RE_WITH_MASKS7: /* 7 */
5769 /* reserved (4 bits) */
5770 add_reserved_field(udcompparam_tree, hf_oran_reserved_4bits, tvb, offset, 1);
5771 /* exponent (4 bits) */
5772 proto_tree_add_item_ret_uint(udcompparam_tree, hf_oran_exponent,
5773 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &param_exponent);
5774 *exponent = param_exponent;
5775 proto_item_append_text(udcompparam_ti, " (Exponent=%u)", param_exponent);
5776 offset += 1;
5777 break;
5778
5779 case COMP_BLOCK_SCALE2: /* 2 */
5780 /* Separate into integer and fractional bits? */
5781 proto_tree_add_item(udcompparam_tree, hf_oran_blockScaler,
5782 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5783 offset++;
5784 break;
5785
5786 case COMP_U_LAW3: /* 3 */
5787 /* compBitWidth, compShift */
5788 proto_tree_add_item(udcompparam_tree, hf_oran_compBitWidth,
5789 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5790 proto_tree_add_item(udcompparam_tree, hf_oran_compShift,
5791 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5792 offset += 1;
5793 break;
5794
5795 case BFP_AND_SELECTIVE_RE5: /* 5 */
5796 {
5797 /* sReSMask (exponent in middle!) */
5798 proto_item *sresmask_ti;
5799 sresmask_ti = proto_tree_add_bitmask_ret_uint64(udcompparam_tree, tvb, offset,
5800 hf_oran_sReSMask,
5801 ett_oran_sresmask,
5802 sres_mask_flags,
5803 ENC_NA0x00000000,
5804 &param_sresmask);
5805
5806 /* Get rid of exponent-shaped gap */
5807 param_sresmask = ((param_sresmask >> 4) & 0x0f00) | (param_sresmask & 0xff);
5808 unsigned res = 0;
5809 for (unsigned n=0; n < 12; n++) {
5810 if ((param_sresmask >> n) & 0x1) {
5811 res++;
5812 }
5813 }
5814 proto_item_append_text(sresmask_ti, " (%2u REs)", res);
5815
5816 /* exponent */
5817 proto_tree_add_item_ret_uint(udcompparam_tree, hf_oran_exponent,
5818 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &param_exponent);
5819 *sReSMask = (uint16_t)param_sresmask;
5820 *exponent = param_exponent;
5821
5822 proto_item_append_text(udcompparam_ti, " (exponent=%u, %u REs)", *exponent, res);
5823 offset += 2;
5824 break;
5825 }
5826
5827 case MOD_COMPR_AND_SELECTIVE_RE6: /* 6 */
5828 {
5829 /* sReSMask (exponent in middle!) */
5830 proto_item *sresmask_ti;
5831
5832 sresmask_ti = proto_tree_add_bitmask_ret_uint64(udcompparam_tree, tvb, offset,
5833 hf_oran_sReSMask,
5834 ett_oran_sresmask,
5835 sres_mask_flags,
5836 ENC_NA0x00000000,
5837 &param_sresmask);
5838
5839 /* Get rid of reserved-shaped gap */
5840 param_sresmask = ((param_sresmask >> 4) & 0x0f00) | (param_sresmask & 0xff);
5841 unsigned res = 0;
5842 for (unsigned n=0; n < 12; n++) {
5843 if ((param_sresmask >> n) & 0x1) {
5844 res++;
5845 }
5846 }
5847 proto_item_append_text(sresmask_ti, " (%u REs)", res);
5848
5849 /* reserved (4 bits) */
5850 add_reserved_field(udcompparam_tree, hf_oran_reserved_last_4bits, tvb, offset, 1);
5851 *sReSMask = (uint16_t)param_sresmask;
5852
5853 proto_item_append_text(udcompparam_ti, " (%u REs)", res);
5854 offset += 2;
5855 break;
5856 }
5857
5858 default:
5859 /* reserved (set to all zeros), but how many bytes?? */
5860 break;
5861 }
5862
5863 proto_item_set_len(udcompparam_ti, offset-start_offset);
5864 return offset;
5865}
5866
5867
5868/* Dissect ciCompHdr (channel information compression header, 7.5.2.15) */
5869/* bit_width and comp_meth are out params */
5870static int dissect_cicomphdr(tvbuff_t *tvb, packet_info *pinfo _U___attribute__((unused)), proto_tree *tree, unsigned offset,
5871 unsigned *bit_width, unsigned *comp_meth, uint8_t *comp_opt)
5872{
5873 /* Subtree */
5874 proto_item *cicomphdr_ti = proto_tree_add_string_format(tree, hf_oran_ciCompHdr,
5875 tvb, offset, 1, "",
5876 "ciCompHdr");
5877 proto_tree *cicomphdr_tree = proto_item_add_subtree(cicomphdr_ti, ett_oran_cicomphdr);
5878
5879 /* ciIqWidth */
5880 uint32_t hdr_iq_width;
5881 proto_item *iq_width_item = proto_tree_add_item_ret_uint(cicomphdr_tree, hf_oran_ciCompHdrIqWidth , tvb, offset, 1, ENC_NA0x00000000, &hdr_iq_width);
5882 hdr_iq_width = (hdr_iq_width) ? hdr_iq_width : 16;
5883 if (bit_width) {
5884 *bit_width = hdr_iq_width;
5885 }
5886 proto_item_append_text(iq_width_item, " (%u bits)", hdr_iq_width);
5887
5888 /* ciCompMeth */
5889 uint32_t ci_comp_meth;
5890 proto_tree_add_item_ret_uint(cicomphdr_tree, hf_oran_ciCompHdrMeth, tvb, offset, 1, ENC_NA0x00000000, &ci_comp_meth);
5891 if (comp_meth) {
5892 *comp_meth = ci_comp_meth;
5893 }
5894
5895 /* ciCompOpt */
5896 uint32_t opt;
5897 proto_tree_add_item_ret_uint(cicomphdr_tree, hf_oran_ciCompOpt, tvb, offset, 1, ENC_NA0x00000000, &opt);
5898 *comp_opt = opt;
5899 offset += 1;
5900
5901 /* Summary */
5902 proto_item_append_text(cicomphdr_ti, " (IqWidth=%u, ciCompMeth=%s, ciCompOpt=%s)",
5903 hdr_iq_width,
5904 rval_to_str_const(ci_comp_meth, ud_comp_header_meth, "Unknown"),
5905 (*comp_opt) ? "compression per PRB" : "compression per UE");
5906 return offset;
5907}
5908
5909static void dissect_payload_version(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, unsigned offset)
5910{
5911 unsigned version;
5912 proto_item *ti = proto_tree_add_item_ret_uint(tree, hf_oran_payload_version, tvb, offset, 1, ENC_NA0x00000000, &version);
5913 if (version != 1) {
5914 expert_add_info_format(pinfo, ti, &ei_oran_version_unsupported,
5915 "PayloadVersion %u not supported by dissector (only 1 is known)",
5916 version);
5917 /* TODO: should throw an exception? */
5918 }
5919}
5920
5921static void show_link_to_acknack_request(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo,
5922 ack_nack_request_t *request)
5923{
5924 /* Request frame */
5925 proto_item *ti = proto_tree_add_uint(tree, hf_oran_acknack_request_frame,
5926 tvb, 0, 0, request->request_frame_number);
5927 PROTO_ITEM_SET_GENERATED(ti)proto_item_set_generated((ti));
5928
5929 /* Work out gap between frames (in ms) */
5930 int seconds_between_packets = (int)
5931 (pinfo->abs_ts.secs - request->request_frame_time.secs);
5932 int nseconds_between_packets =
5933 pinfo->abs_ts.nsecs - request->request_frame_time.nsecs;
5934
5935 int total_gap = (seconds_between_packets*1000) +
5936 ((nseconds_between_packets+500000) / 1000000);
5937
5938 ti = proto_tree_add_uint(tree, hf_oran_acknack_request_time,
5939 tvb, 0, 0, total_gap);
5940 PROTO_ITEM_SET_GENERATED(ti)proto_item_set_generated((ti));
5941
5942 /* Type of request */
5943 ti = proto_tree_add_uint(tree, hf_oran_acknack_request_type,
5944 tvb, 0, 0, request->requestType);
5945 PROTO_ITEM_SET_GENERATED(ti)proto_item_set_generated((ti));
5946}
5947
5948static void show_link_to_acknack_response(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo,
5949 ack_nack_request_t *response)
5950{
5951 if (response->response_frame_number == 0) {
5952 /* Requests may not get a response, and can't always tell when to expect one */
5953 return;
5954 }
5955
5956 /* Response frame */
5957 proto_item *ti = proto_tree_add_uint(tree, hf_oran_acknack_response_frame,
5958 tvb, 0, 0, response->response_frame_number);
5959 PROTO_ITEM_SET_GENERATED(ti)proto_item_set_generated((ti));
5960
5961 /* Work out gap between frames (in ms) */
5962 int seconds_between_packets = (int)
5963 (response->response_frame_time.secs - pinfo->abs_ts.secs);
5964 int nseconds_between_packets =
5965 response->response_frame_time.nsecs - pinfo->abs_ts.nsecs;
5966
5967 int total_gap = (seconds_between_packets*1000) +
5968 ((nseconds_between_packets+500000) / 1000000);
5969
5970 ti = proto_tree_add_uint(tree, hf_oran_acknack_response_time,
5971 tvb, 0, 0, total_gap);
5972 PROTO_ITEM_SET_GENERATED(ti)proto_item_set_generated((ti));
5973}
5974
5975
5976
5977/* Control plane dissector (section 7). */
5978static int dissect_oran_c(tvbuff_t *tvb, packet_info *pinfo,
5979 proto_tree *tree, oran_tap_info *tap_info, void *data _U___attribute__((unused)))
5980{
5981 /* Hidden filter for plane */
5982 proto_item *plane_ti = proto_tree_add_item(tree, hf_oran_cplane, tvb, 0, 0, ENC_NA0x00000000);
5983 PROTO_ITEM_SET_HIDDEN(plane_ti)proto_item_set_hidden((plane_ti));
5984
5985 /* Set up structures needed to add the protocol subtree and manage it */
5986 unsigned offset = 0;
5987
5988 col_set_str(pinfo->cinfo, COL_PROTOCOL, "O-RAN-FH-C");
5989 col_set_str(pinfo->cinfo, COL_INFO, "C-Plane");
5990
5991 tap_info->userplane = false0;
5992
5993 /* Create display subtree for the protocol */
5994 proto_item *protocol_item = proto_tree_add_item(tree, proto_oran, tvb, 0, -1, ENC_NA0x00000000);
5995 proto_item_append_text(protocol_item, "-C");
5996 proto_tree *oran_tree = proto_item_add_subtree(protocol_item, ett_oran);
5997
5998 /* ecpriRtcid (eAxC ID) */
5999 uint16_t eAxC;
6000 addPcOrRtcid(tvb, oran_tree, &offset, hf_oran_ecpri_rtcid, &eAxC, tap_info);
6001 tap_info->eaxc = eAxC;
6002
6003 /* Look up any existing conversation state for eAxC+plane */
6004 uint32_t key = make_flow_key(pinfo, eAxC, ORAN_C_PLANE0, false0);
6005 flow_state_t* state = (flow_state_t*)wmem_tree_lookup32(flow_states_table, key);
6006
6007 /* Message identifier */
6008 uint32_t seq_id, sub_seq_id, e;
6009 proto_item *seq_id_ti;
6010 offset = addSeqid(tvb, oran_tree, offset, ORAN_C_PLANE0, &seq_id, &seq_id_ti, pinfo, &sub_seq_id, &e);
6011
6012 /* Section common subtree */
6013 int section_tree_offset = offset;
6014 proto_item *sectionHeading = proto_tree_add_string_format(oran_tree, hf_oran_c_section_common,
6015 tvb, offset, 0, "", "C-Plane Section Type ");
6016 proto_tree *section_tree = proto_item_add_subtree(sectionHeading, ett_oran_c_section_common);
6017
6018 /* Peek ahead at the section type */
6019 uint32_t sectionType = 0;
6020 sectionType = tvb_get_uint8(tvb, offset+5);
6021
6022 uint32_t scs = 0;
6023 proto_item *scs_ti = NULL((void*)0);
6024
6025 /* dataDirection */
6026 uint32_t direction = 0;
6027 proto_item *datadir_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_data_direction, tvb, offset, 1, ENC_NA0x00000000, &direction);
6028 tap_info->uplink = (direction==0);
6029
6030 /* Update/report status of conversation */
6031 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
6032
6033 if (state == NULL((void*)0)) {
6034 /* Allocate new state */
6035 state = wmem_new0(wmem_file_scope(), flow_state_t)((flow_state_t*)wmem_alloc0((wmem_file_scope()), sizeof(flow_state_t
)))
;
6036 state->ack_nack_requests = wmem_tree_new(wmem_file_scope());
6037 wmem_tree_insert32(flow_states_table, key, state);
6038 /* Tables for each direction */
6039 state->expected_sections[0] = wmem_tree_new(wmem_file_scope());
6040 state->expected_sections[1] = wmem_tree_new(wmem_file_scope());
6041 }
6042
6043 /* Check sequence analysis status */
6044 if (state->last_frame_seen[direction] && (seq_id != state->next_expected_sequence_number[direction])) {
6045 /* Store this result */
6046 flow_result_t *result = wmem_new0(wmem_file_scope(), flow_result_t)((flow_result_t*)wmem_alloc0((wmem_file_scope()), sizeof(flow_result_t
)))
;
6047 result->unexpected_seq_number = true1;
6048 result->expected_sequence_number = state->next_expected_sequence_number[direction];
6049 result->previous_frame = state->last_frame[direction];
6050 result->u_plane_frames = wmem_list_new(wmem_file_scope());
6051 wmem_tree_insert32(flow_results_table, pinfo->num, result);
6052 }
6053 /* Update conversation info */
6054 state->last_frame[direction] = pinfo->num;
6055 state->last_frame_seen[direction] = true1;
6056 state->next_expected_sequence_number[direction] = (seq_id+1) % 256;
6057 }
6058
6059 /* Show any issues associated with this frame number */
6060 flow_result_t *result = wmem_tree_lookup32(flow_results_table, pinfo->num);
6061 if (result!=NULL((void*)0) && result->unexpected_seq_number) {
6062 expert_add_info_format(pinfo, seq_id_ti,
6063 (direction == DIR_UPLINK0) ?
6064 &ei_oran_cplane_unexpected_sequence_number_ul :
6065 &ei_oran_cplane_unexpected_sequence_number_dl,
6066 "Sequence number %u expected, but got %u",
6067 result->expected_sequence_number, seq_id);
6068
6069 /* Update tap info */
6070 uint32_t missing_sns = (256 + seq_id - result->expected_sequence_number) % 256;
6071 /* Don't get confused by being slightly out of order.. */
6072 if (missing_sns < 128) {
6073 tap_info->missing_sns = missing_sns;
6074 }
6075 else {
6076 tap_info->missing_sns = 0;
6077 }
6078
6079 /* TODO: could add previous/next frames (in seqId tree?) ? */
6080 }
6081
6082 /* payloadVersion */
6083 dissect_payload_version(section_tree, tvb, pinfo, offset);
6084
6085 /* filterIndex */
6086 if (sectionType == SEC_C_SLOT_CONTROL || sectionType == SEC_C_ACK_NACK_FEEDBACK) {
6087 /* scs (for ST4 and ST8) */
6088 scs_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_frameStructure_subcarrier_spacing, tvb, offset, 1, ENC_NA0x00000000, &scs);
6089 }
6090 else if (sectionType == SEC_C_RRM_MEAS_REPORTS || sectionType == SEC_C_REQUEST_RRM_MEAS) {
6091 /* reserved (4 bits) */
6092 add_reserved_field(section_tree, hf_oran_reserved_last_4bits, tvb, offset, 1);
6093 }
6094 else if (sectionType != SEC_C_LAA) {
6095 /* filterIndex (most common case) */
6096 proto_tree_add_item(section_tree, hf_oran_filter_index, tvb, offset, 1, ENC_NA0x00000000);
6097 }
6098 offset += 1;
6099
6100 unsigned ref_a_offset = offset;
6101 /* frameId */
6102 uint32_t frameId = 0;
6103 proto_tree_add_item_ret_uint(section_tree, hf_oran_frame_id, tvb, offset, 1, ENC_NA0x00000000, &frameId);
6104 tap_info->frame = frameId;
6105 offset += 1;
6106
6107 /* subframeId */
6108 uint32_t subframeId = 0;
6109 proto_tree_add_item_ret_uint(section_tree, hf_oran_subframe_id, tvb, offset, 1, ENC_NA0x00000000, &subframeId);
6110 /* slotId */
6111 uint32_t slotId = 0;
6112 proto_tree_add_item_ret_uint(section_tree, hf_oran_slot_id, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &slotId);
6113 tap_info->slot = slotId;
6114 offset++;
6115
6116 /* startSymbolId */
6117 uint32_t startSymbolId = 0;
6118 proto_item *ssid_ti = NULL((void*)0);
6119 if ((sectionType == SEC_C_ACK_NACK_FEEDBACK) || /* Section Type 8 */
6120 (sectionType == SEC_C_SINR_REPORTING)) { /* Section Type 9 */
6121 /* symbolId */
6122 proto_tree_add_item_ret_uint(section_tree, hf_oran_symbolId, tvb, offset, 1, ENC_NA0x00000000, &startSymbolId);
6123 }
6124 else if (sectionType != SEC_C_LAA) {
6125 /* startSymbolId is in most section types */
6126 ssid_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_start_symbol_id, tvb, offset, 1, ENC_NA0x00000000, &startSymbolId);
6127 if (startSymbolId && (sectionType == SEC_C_RRM_MEAS_REPORTS)) { /* Section Type 10 */
6128 proto_item_append_text(ssid_ti, " (should be 0 for ST10!)");
6129 expert_add_info_format(pinfo, ssid_ti, &ei_oran_st10_startsymbolid_not_0,
6130 "startSymbolId should be 0 for ST10 - found %u", startSymbolId);
6131 }
6132 }
6133 else {
6134 /* reserved (6 bits) */
6135 add_reserved_field(section_tree, hf_oran_reserved_last_6bits, tvb, offset, 1);
6136 }
6137 offset++;
6138
6139
6140 char id[16];
6141 snprintf(id, 16, "%u-%u-%u-%u", frameId, subframeId, slotId, startSymbolId);
6142 proto_item *pi = proto_tree_add_string(section_tree, hf_oran_refa, tvb, ref_a_offset, 3, id);
6143 proto_item_set_generated(pi);
6144
6145 uint32_t cmd_scope = 0;
6146 bool_Bool st8_ready = false0;
6147
6148 /* numberOfSections (or whatever section has instead) */
6149 uint32_t nSections = 0;
6150 if (sectionType == SEC_C_SLOT_CONTROL) { /* Section Type 4 */
6151 /* Slot Control has these fields instead */
6152 /* reserved (4 bits) */
6153 add_reserved_field(section_tree, hf_oran_reserved_4bits, tvb, offset, 1);
6154 /* cmdScope (4 bits) */
6155 proto_tree_add_item_ret_uint(section_tree, hf_oran_cmd_scope, tvb, offset, 1, ENC_NA0x00000000, &cmd_scope);
6156 }
6157 else if (sectionType == SEC_C_ACK_NACK_FEEDBACK) { /* Section Type 8 */
6158 /* reserved (7 bits) */
6159 add_reserved_field(section_tree, hf_oran_reserved_7bits, tvb, offset, 1);
6160 /* ready (1 bit) */
6161 /* TODO: when set, ready in slotId+1.. */
6162 proto_tree_add_item_ret_boolean(section_tree, hf_oran_ready, tvb, offset, 1, ENC_NA0x00000000, &st8_ready);
6163 if (!st8_ready) {
6164 /* SCS value is ignored, and may be set to any value by O-RU */
6165 proto_item_append_text(scs_ti, " (ignored)");
6166 }
6167 }
6168 else if (sectionType != SEC_C_LAA) {
6169 /* numberOfSections */
6170 proto_tree_add_item_ret_uint(section_tree, hf_oran_numberOfSections, tvb, offset, 1, ENC_NA0x00000000, &nSections);
6171 }
6172 else {
6173 add_reserved_field(section_tree, hf_oran_reserved_8bits, tvb, offset, 1);
6174 }
6175 offset++;
6176
6177 /* sectionType */
6178 proto_tree_add_item_ret_uint(section_tree, hf_oran_sectionType, tvb, offset, 1, ENC_NA0x00000000, &sectionType);
6179 offset += 1;
6180
6181 /* Check that dataDirection is consistent with section type */
6182 if (sectionType == SEC_C_SINR_REPORTING && direction != 0) { /* Section Type 9 */
6183 expert_add_info(pinfo, datadir_ti, &ei_oran_st9_not_ul);
6184 }
6185 if (sectionType == SEC_C_RRM_MEAS_REPORTS && direction != 0) { /* Section Type 10 */
6186 expert_add_info(pinfo, datadir_ti, &ei_oran_st10_not_ul);
6187 }
6188
6189 /* Note this section type in stats */
6190 if (sectionType < SEC_C_MAX_INDEX) {
6191 tap_info->section_types[sectionType] = true1;
6192 }
6193
6194 /* Section-type-specific fields following common header (white entries in Section Type diagrams) */
6195 unsigned bit_width = 0;
6196 unsigned comp_meth = 0;
6197 proto_item *comp_meth_ti;
6198 unsigned ci_comp_method = 0;
6199 uint8_t ci_comp_opt = 0;
6200
6201 uint32_t num_ues = 0;
6202 uint32_t number_of_acks = 0, number_of_nacks = 0;
6203
6204 uint32_t num_sinr_per_prb = 0;
6205
6206 switch (sectionType) {
6207 case SEC_C_UNUSED_RB: /* Section Type 0 */
6208 /* timeOffset */
6209 proto_tree_add_item(section_tree, hf_oran_timeOffset, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6210 offset += 2;
6211 /* frameStructure */
6212 offset = dissect_frame_structure(section_tree, tvb, offset,
6213 subframeId, slotId);
6214
6215 /* cpLength */
6216 proto_tree_add_item(section_tree, hf_oran_cpLength, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6217 offset += 2;
6218 /* reserved (8 bits) */
6219 add_reserved_field(section_tree, hf_oran_reserved_8bits, tvb, offset, 1);
6220 offset += 1;
6221 break;
6222
6223 case SEC_C_NORMAL: /* Section Type 1 */
6224 case SEC_C_UE_SCHED: /* Section Type 5 */
6225 /* udCompHdr */
6226 offset = dissect_udcomphdr(tvb, pinfo, section_tree, offset,
6227 true1, direction==0 && pref_override_ul_compression, /* ignore for DL or if using mplane for UL settings */
6228 &bit_width, &comp_meth, &comp_meth_ti, tap_info);
6229 /* reserved (8 bits) */
6230 add_reserved_field(section_tree, hf_oran_reserved_8bits, tvb, offset, 1);
6231 offset += 1;
6232 break;
6233
6234 case SEC_C_SLOT_CONTROL: /* Section Type 4 */
6235 break;
6236
6237 case SEC_C_PRACH: /* Section Type 3 */
6238 /* timeOffset */
6239 proto_tree_add_item(section_tree, hf_oran_timeOffset, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6240 offset += 2;
6241 /* frameStructure */
6242 offset = dissect_frame_structure(section_tree, tvb, offset,
6243 subframeId, slotId);
6244 /* cpLength */
6245 proto_tree_add_item(section_tree, hf_oran_cpLength, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6246 offset += 2;
6247 /* udCompHdr */
6248 offset = dissect_udcomphdr(tvb, pinfo, section_tree, offset,
6249 true1, direction==0 && pref_override_ul_compression, /* ignore for DL or if using mplane for UL settings */
6250 &bit_width, &comp_meth, &comp_meth_ti, tap_info);
6251 break;
6252
6253 case SEC_C_CH_INFO: /* Section Type 6 */
6254 /* numberOfUEs */
6255 proto_tree_add_item_ret_uint(section_tree, hf_oran_numberOfUEs, tvb, offset, 1, ENC_NA0x00000000, &num_ues);
6256 offset += 1;
6257 /* ciCompHdr (was reserved) */
6258 offset = dissect_cicomphdr(tvb, pinfo, section_tree, offset, &bit_width, &ci_comp_method, &ci_comp_opt);
6259
6260 /* Number of sections may not be filled in (at all, or correctly), so set to the number of UEs.
6261 The data entries are per-UE... they don't have a sectionID, but they could have section extensions... */
6262 if (nSections == 0 || num_ues > nSections) {
6263 nSections = num_ues;
6264 }
6265 break;
6266
6267 case SEC_C_RSVD2:
6268 break;
6269
6270 case SEC_C_LAA: /* Section Type 7 */
6271 add_reserved_field(section_tree, hf_oran_reserved_16bits, tvb, offset, 2);
6272 offset += 2;
6273 break;
6274
6275 case SEC_C_ACK_NACK_FEEDBACK: /* Section Type 8 */
6276 /* numberOfAcks (1 byte) */
6277 proto_tree_add_item_ret_uint(section_tree, hf_oran_number_of_acks, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &number_of_acks);
6278 offset += 1;
6279 /* numberOfNacks (1 byte) */
6280 proto_tree_add_item_ret_uint(section_tree, hf_oran_number_of_nacks, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &number_of_nacks);
6281 offset += 1;
6282
6283 /* Show ACKs and NACKs. For both, try to link back to request. */
6284 for (unsigned int n=1; n <= number_of_acks; n++) {
6285 uint32_t ackid;
6286 proto_item *ack_ti;
6287 ack_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_ackid, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &ackid);
6288 offset += 2;
6289
6290 /* Look up request table in state (which really should be set by now, but test anyway). */
6291 if (state && state->ack_nack_requests) {
6292 ack_nack_request_t *request = wmem_tree_lookup32(state->ack_nack_requests, ackid);
6293 if (request != NULL((void*)0)) {
6294 /* On first pass, update with this response */
6295 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
6296 request->response_frame_number = pinfo->num;
6297 request->response_frame_time = pinfo->abs_ts;
6298 }
6299
6300 /* Show request details */
6301 show_link_to_acknack_request(section_tree, tvb, pinfo, request);
6302 }
6303 else {
6304 /* Request not found */
6305 expert_add_info_format(pinfo, ack_ti, &ei_oran_acknack_no_request,
6306 "Response for ackId=%u received, but no request found",
6307 ackid);
6308 }
6309 }
6310 }
6311 for (unsigned int m=1; m <= number_of_nacks; m++) {
6312 uint32_t nackid;
6313 proto_item *nack_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_nackid, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &nackid);
6314 offset += 2;
6315
6316 expert_add_info_format(pinfo, nack_ti, &ei_oran_st8_nackid,
6317 "Received Nack for ackNackId=%u",
6318 nackid);
6319
6320 /* Look up request table in state. */
6321 if (state && state->ack_nack_requests) {
6322 ack_nack_request_t *request = wmem_tree_lookup32(state->ack_nack_requests, nackid);
6323 if (request) {
6324 /* On first pass, update with this response */
6325 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
6326 request->response_frame_number = pinfo->num;
6327 request->response_frame_time = pinfo->abs_ts;
6328 }
6329
6330 /* Show request details */
6331 show_link_to_acknack_request(section_tree, tvb, pinfo, request);
6332 }
6333 else {
6334 /* Request not found */
6335 expert_add_info_format(pinfo, nack_ti, &ei_oran_acknack_no_request,
6336 "Response for nackId=%u received, but no request found",
6337 nackid);
6338 }
6339 }
6340 }
6341 break;
6342
6343 case SEC_C_SINR_REPORTING: /* Section Type 9 */
6344 {
6345 /* numSinrPerPrb (3 bits) */
6346 proto_item *nspp_ti;
6347 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);
6348 switch (num_sinr_per_prb) {
6349 case 0:
6350 num_sinr_per_prb = 1; break;
6351 case 1:
6352 num_sinr_per_prb = 2; break;
6353 case 2:
6354 num_sinr_per_prb = 3; break;
6355 case 3:
6356 num_sinr_per_prb = 4; break;
6357 case 4:
6358 num_sinr_per_prb = 6; break;
6359 case 5:
6360 num_sinr_per_prb = 12; break;
6361
6362 default:
6363 proto_item_append_text(nspp_ti, " (invalid)");
6364 num_sinr_per_prb = 1;
6365 expert_add_info_format(pinfo, nspp_ti, &ei_oran_num_sinr_per_prb_unknown,
6366 "Invalid numSinrPerPrb value (%u)",
6367 num_sinr_per_prb);
6368 }
6369
6370 /* oruControlSinrSlotMaskId (5 bits) */
6371 proto_tree_add_item(section_tree, hf_oran_oru_control_sinr_slot_mask_id, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6372 offset += 1;
6373 /* reserved (8 bits) */
6374 add_reserved_field(section_tree, hf_oran_reserved_8bits, tvb, offset, 1);
6375 offset += 1;
6376 break;
6377 }
6378
6379 case SEC_C_RRM_MEAS_REPORTS: /* Section Type 10 */
6380 case SEC_C_REQUEST_RRM_MEAS: /* Section Type 11 */
6381 /* reserved (16 bits) */
6382 add_reserved_field(section_tree, hf_oran_reserved_16bits, tvb, offset, 2);
6383 offset += 2;
6384 break;
6385 };
6386
6387 /* Update udCompHdr details in state for UL U-Plane */
6388 if (state && direction==0) {
6389 switch (sectionType) {
6390 case SEC_C_NORMAL: /* Section Type 1 */
6391 case SEC_C_PRACH: /* Section Type 3 */
6392 case SEC_C_UE_SCHED: /* Section Type 5 */
6393 state->ul_ud_comp_hdr_set = true1;
6394 state->ul_ud_comp_hdr_bit_width = bit_width;
6395 state->ul_ud_comp_hdr_compression = comp_meth;
6396 state->ul_ud_comp_hdr_frame = pinfo->num;
6397 break;
6398 default:
6399 break;
6400 }
6401 }
6402
6403
6404 proto_item_append_text(sectionHeading, "%d, %s, frameId: %d, subframeId: %d, slotId: %d, startSymbolId: %d",
6405 sectionType, val_to_str_const(direction, data_direction_vals, "Unknown"),
6406 frameId, subframeId, slotId, startSymbolId);
6407 if (nSections) {
6408 proto_item_append_text(sectionHeading, ", numberOfSections=%u", nSections);
6409 }
6410
6411 write_pdu_label_and_info(protocol_item, NULL((void*)0), pinfo, ", Type: %2d %s", sectionType,
6412 rval_to_str_const(sectionType, section_types_short, "Unknown"));
6413
6414 /* Set actual length of C-Plane section header */
6415 proto_item_set_len(section_tree, offset - section_tree_offset);
6416
6417 if (sectionType == SEC_C_ACK_NACK_FEEDBACK) {
6418 write_pdu_label_and_info(oran_tree, section_tree, pinfo,
6419 (st8_ready) ? " (Ready)" : " (ACK)");
6420 }
6421
6422
6423 /* Section type 4 doesn't have normal sections, so deal with here before normal sections */
6424 if (sectionType == SEC_C_SLOT_CONTROL) {
6425 /* numberOfST4Cmds */
6426 uint32_t no_st4_cmds, st4_cmd_len, num_slots, ack_nack_req_id, st4_cmd_type;
6427 proto_item *no_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_number_of_st4_cmds,
6428 tvb, offset, 1, ENC_NA0x00000000, &no_st4_cmds);
6429 if (no_st4_cmds == 0) {
6430 expert_add_info(pinfo, no_ti, &ei_oran_st4_no_cmds);
6431 }
6432 offset += 1;
6433
6434 /* reserved (1 byte) */
6435 add_reserved_field(section_tree, hf_oran_reserved_8bits, tvb, offset, 1);
6436 offset += 1;
6437
6438 /* Loop over commands. Each has 8-byte common header, followed by cmd-specific payload */
6439 proto_item *len_ti;
6440 for (uint32_t n=0; n < no_st4_cmds; n++) {
6441 /* Table 7.4.6-2: Section Type 4 Command common header format */
6442 proto_item *hdr_ti = proto_tree_add_string_format(section_tree, hf_oran_st4_cmd_header,
6443 tvb, offset, 8, "",
6444 "Type 4 Command common header");
6445 proto_tree *hdr_tree = proto_item_add_subtree(hdr_ti, ett_oran_st4_cmd_header);
6446
6447 /* st4CmdType */
6448 proto_tree_add_item_ret_uint(hdr_tree, hf_oran_st4_cmd_type, tvb, offset, 1, ENC_NA0x00000000, &st4_cmd_type);
6449 offset += 1;
6450
6451 /* st4CmdLen */
6452 len_ti = proto_tree_add_item_ret_uint(hdr_tree, hf_oran_st4_cmd_len, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &st4_cmd_len);
6453 if (st4_cmd_len == 0) {
6454 /* Meaning of 0 not yet defined (v15.00) */
6455 proto_item_append_text(len_ti, " (reserved)");
6456 expert_add_info(pinfo, len_ti, &ei_oran_st4_zero_len_cmd);
6457 }
6458 else {
6459 proto_item_append_text(len_ti, " (%u bytes)", st4_cmd_len*4);
6460 }
6461 offset += 2;
6462
6463 /* numSlots */
6464 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);
6465 if (num_slots == 0) {
6466 proto_item_append_text(slots_ti, " (until changed)");
6467 }
6468 offset += 1;
6469
6470 /* ackNackReqId */
6471 proto_item *ack_nack_req_id_ti;
6472 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);
6473 offset += 2;
6474 if (ack_nack_req_id == 0) {
6475 proto_item_append_text(ack_nack_req_id_ti, " (no Section type 8 response expected)");
6476 }
6477
6478 /* reserved (16 bits) */
6479 add_reserved_field(hdr_tree, hf_oran_reserved_16bits, tvb, offset, 2);
6480 offset += 2;
6481
6482 /* Set common header summary */
6483 proto_item_append_text(hdr_ti, " (cmd=%s, len=%u, slots=%u, ackNackReqId=%u)",
6484 rval_to_str_const(st4_cmd_type, st4_cmd_type_vals, "Unknown"),
6485 st4_cmd_len, num_slots, ack_nack_req_id);
6486
6487 col_append_fstr(pinfo->cinfo, COL_INFO, " (%s)",
6488 rval_to_str_const(st4_cmd_type, st4_cmd_type_vals, "Unknown"));
6489
6490
6491 /* Subtree for this command body */
6492 proto_item *command_ti = proto_tree_add_string_format(section_tree, hf_oran_st4_cmd,
6493 tvb, offset, 0, "",
6494 "Type 4 Command (%s)", rval_to_str_const(st4_cmd_type, st4_cmd_type_vals, "Unknown"));
6495 proto_tree *command_tree = proto_item_add_subtree(command_ti, ett_oran_st4_cmd);
6496
6497 unsigned command_start_offset = offset;
6498
6499 /* Check fields compatible with chosen command. */
6500 if (st4_cmd_type==1) {
6501 if (num_slots != 0) {
6502 /* "the value of numSlots should be set to zero for this command type" */
6503 expert_add_info_format(pinfo, slots_ti, &ei_oran_numslots_not_zero,
6504 "numSlots should be zero for ST4 command 1 - found %u",
6505 num_slots);
6506 }
6507 }
6508
6509 if (st4_cmd_type==3 || st4_cmd_type==4) {
6510 if (startSymbolId != 0) {
6511 /* "expected reception window for the commands is the symbol zero reception window" */
6512 expert_add_info_format(pinfo, ssid_ti, &ei_oran_start_symbol_id_not_zero,
6513 "startSymbolId should be zero for ST4 commands 3&4 - found %u",
6514 startSymbolId);
6515 }
6516 }
6517
6518 /* Add format for this command */
6519 switch (st4_cmd_type) {
6520 case 1: /* TIME_DOMAIN_BEAM_CONFIG */
6521 {
6522 bool_Bool disable_tdbfns;
6523 uint32_t bfwcomphdr_iq_width, bfwcomphdr_comp_meth;
6524
6525 /* Hidden filter for bf */
6526 proto_item *bf_ti = proto_tree_add_item(command_tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
6527 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
6528
6529 /* reserved (2 bits) */
6530 add_reserved_field(command_tree, hf_oran_reserved_2bits, tvb, offset, 1);
6531 /* symbolMask (14 bits) */
6532 uint32_t symbol_mask;
6533 proto_item *symbol_mask_ti;
6534 offset = dissect_symbolmask(tvb, command_tree, offset, &symbol_mask, &symbol_mask_ti);
6535 /* 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 */
6536 /* lsb is symbol 0 */
6537 for (unsigned s=0; s < 14; s++) {
6538 if ((startSymbolId & (1 << s)) && (startSymbolId > s)) {
6539 proto_item_append_text(symbol_mask_ti, " (startSymbolId is %u, so some lower symbol bits ignored!)", startSymbolId);
6540 expert_add_info(pinfo, symbol_mask_ti, &ei_oran_start_symbol_id_bits_ignored);
6541 break;
6542 }
6543 }
6544
6545 /* disableTDBFNs (1 bit) */
6546 proto_tree_add_item_ret_boolean(command_tree, hf_oran_disable_tdbfns, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &disable_tdbfns);
6547
6548 /* tdBeamNum (15 bits) */
6549 proto_tree_add_item(command_tree, hf_oran_td_beam_num, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6550 offset += 2;
6551
6552 /* bfwCompHdr (2 subheaders - bfwIqWidth and bfwCompMeth)*/
6553 offset = dissect_bfwCompHdr(tvb, command_tree, offset,
6554 &bfwcomphdr_iq_width, &bfwcomphdr_comp_meth, &comp_meth_ti);
6555 /* reserved (3 bytes) */
6556 proto_tree_add_bits_item(command_tree, hf_oran_reserved, tvb, offset*8, 24, ENC_BIG_ENDIAN0x00000000);
6557 offset += 3;
6558
6559 if (disable_tdbfns) {
6560 /* No beamnum information to show so get out. */
6561 break;
6562 }
6563
6564 /* Read beam entries until reach end of command length */
6565 while ((offset - command_start_offset) < (st4_cmd_len * 4)) {
6566
6567 /* disableTDBFWs (1 bit) */
6568 bool_Bool disable_tdbfws;
6569 proto_tree_add_item_ret_boolean(command_tree, hf_oran_disable_tdbfws, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &disable_tdbfws);
6570
6571 /* tdBeamNum (15 bits) */
6572 proto_tree_add_item(command_tree, hf_oran_td_beam_num, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6573 offset += 2;
6574
6575 /* Showing BFWs? */
6576 if (!disable_tdbfws) {
6577
6578 /* bfwCompParam */
6579 unsigned exponent = 0;
6580 bool_Bool supported = false0;
6581 unsigned num_trx_entries;
6582 uint16_t *trx_entries;
6583 offset = dissect_bfwCompParam(tvb, command_tree, pinfo, offset, comp_meth_ti,
6584 &bfwcomphdr_comp_meth, &exponent, &supported,
6585 &num_trx_entries, &trx_entries);
6586
6587 /* Antenna count from preference */
6588 unsigned num_trx = pref_num_bf_antennas;
6589 int bit_offset = offset*8;
6590
6591 for (unsigned trx=0; trx < num_trx; trx++) {
6592 /* Create antenna subtree */
6593 int bfw_offset = bit_offset / 8;
6594 proto_item *bfw_ti = proto_tree_add_string_format(command_tree, hf_oran_bfw,
6595 tvb, bfw_offset, 0, "", "TRX %3u: (", trx);
6596 proto_tree *bfw_tree = proto_item_add_subtree(bfw_ti, ett_oran_bfw);
6597
6598 /* I value */
6599 /* Get bits, and convert to float. */
6600 uint32_t bits = tvb_get_bits32(tvb, bit_offset, bfwcomphdr_iq_width, ENC_BIG_ENDIAN0x00000000);
6601 float value = decompress_value(bits, bfwcomphdr_comp_meth, bfwcomphdr_iq_width, exponent, NULL((void*)0) /* no ModCompr*/, 0 /* RE */);
6602 /* Add to tree. */
6603 proto_tree_add_float(bfw_tree, hf_oran_bfw_i, tvb, bit_offset/8,
6604 (bfwcomphdr_iq_width+7)/8, value);
6605 bit_offset += bfwcomphdr_iq_width;
6606 proto_item_append_text(bfw_ti, "I=%f ", value);
6607
6608 /* Leave a gap between I and Q values */
6609 proto_item_append_text(bfw_ti, " ");
6610
6611 /* Q value */
6612 /* Get bits, and convert to float. */
6613 bits = tvb_get_bits32(tvb, bit_offset, bfwcomphdr_iq_width, ENC_BIG_ENDIAN0x00000000);
6614 value = decompress_value(bits, bfwcomphdr_comp_meth, bfwcomphdr_iq_width, exponent, NULL((void*)0) /* no ModCompr*/, 0 /* RE */);
6615 /* Add to tree. */
6616 proto_tree_add_float(bfw_tree, hf_oran_bfw_q, tvb, bit_offset/8,
6617 (bfwcomphdr_iq_width+7)/8, value);
6618 bit_offset += bfwcomphdr_iq_width;
6619 proto_item_append_text(bfw_ti, "Q=%f", value);
6620
6621 proto_item_append_text(bfw_ti, ")");
6622 proto_item_set_len(bfw_ti, (bit_offset+7)/8 - bfw_offset);
6623 }
6624 /* Need to round to next byte */
6625 offset = (bit_offset+7)/8;
6626 }
6627 }
6628 break;
6629 }
6630 case 2: /* TDD_CONFIG_PATTERN */
6631 /* reserved (2 bits) */
6632 add_reserved_field(command_tree, hf_oran_reserved_2bits, tvb, offset, 1);
6633 /* dirPattern (14 bits) */
6634 proto_tree_add_item(command_tree, hf_oran_dir_pattern, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6635 offset += 2;
6636
6637 /* reserved (2 bits) */
6638 add_reserved_field(command_tree, hf_oran_reserved_2bits, tvb, offset, 1);
6639 /* guardPattern (14 bits) */
6640 proto_tree_add_item(command_tree, hf_oran_guard_pattern, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6641 offset += 2;
6642 break;
6643
6644 case 3: /* TRX_CONTROL */
6645 case 5: /* TRX_CONTROL_BIDIR */
6646 {
6647 /* Only allowed cmdScope is ARRAY-COMMAND */
6648 if (cmd_scope != 0) {
6649 expert_add_info(pinfo, command_tree, &ei_oran_trx_control_cmd_scope);
6650 }
6651
6652 /* reserved (2 bits) */
6653 add_reserved_field(command_tree, hf_oran_reserved_2bits, tvb, offset, 1);
6654 /* log2MaskBits (4 bits) */
6655 unsigned log2maskbits;
6656 proto_tree_add_item_ret_uint(command_tree, hf_oran_log2maskbits, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &log2maskbits);
6657 /* sleepMode (2 bits) */
6658 uint32_t sleep_mode;
6659 proto_tree_add_item_ret_uint(command_tree, hf_oran_sleepmode_trx, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &sleep_mode);
6660 offset += 1;
6661
6662 /* reserved (4 bits) */
6663 add_reserved_field(command_tree, hf_oran_reserved_4bits, tvb, offset, 1);
6664 /* numSlotsExt (20 bits) */
6665 uint32_t num_slots_ext;
6666 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);
6667 if (num_slots==0 && num_slots_ext==0) {
6668 proto_item_append_text(num_slots_ext_ti, " (undefined sleep period)");
6669 }
6670 else {
6671 /* Time should be rounded up according to SCS */
6672 float total = (float)(num_slots + num_slots_ext);
6673 /* From table 7.5.2.13-3 */
6674 const float slot_length_by_scs[16] = { 1000, 500, 250, 125, 62.5, 31.25,
6675 0, 0, 0, 0, 0, 0, /* reserved */
6676 1000, 1000, 1000, 1000 };
6677 float slot_length = slot_length_by_scs[scs];
6678 /* Only using valid SCS. TODO: is this test ok? */
6679 if (slot_length != 0) {
6680 /* Round up to next slot */
6681 total = ((int)(total / slot_length) + 1) * slot_length;
6682 proto_item_append_text(num_slots_ext_ti, " (defined sleep period of %f us)", total);
6683 }
6684 }
6685 offset += 3;
6686
6687 /* reserved (2 bits) */
6688 add_reserved_field(command_tree, hf_oran_reserved_2bits, tvb, offset, 1);
6689
6690 /* symbolMask (14 bits) */
6691 uint32_t symbol_mask;
6692 proto_item *sm_ti;
6693 offset = dissect_symbolmask(tvb, command_tree, offset, &symbol_mask, &sm_ti);
6694 if (symbol_mask == 0x0) {
6695 proto_item_append_text(sm_ti, " (wake)");
6696 col_append_str(pinfo->cinfo, COL_INFO, " (wake)");
6697 }
6698 else if (symbol_mask == 0x3fff) {
6699 proto_item_append_text(sm_ti, " (sleep)");
6700 col_append_str(pinfo->cinfo, COL_INFO, " (sleep)");
6701 }
6702 else {
6703 expert_add_info_format(pinfo, sm_ti, &ei_oran_bad_symbolmask,
6704 "For non-zero sleepMode (%u), symbolMask should be 0x0 or 0x3fff - found 0x%05x",
6705 sleep_mode, symbol_mask);
6706 }
6707 offset += 2;
6708
6709 /* antMask (16-2048 bits). Size is lookup from log2MaskBits enum.. */
6710 unsigned antmask_length = 2;
6711 if (log2maskbits >= 4) {
6712 antmask_length = (1 << log2maskbits) / 8;
6713 }
6714 proto_item *ant_mask_ti = proto_tree_add_item(command_tree, hf_oran_antMask_trx_control, tvb, offset, antmask_length, ENC_NA0x00000000);
6715 /* show count */
6716 unsigned antenna_count = 0;
6717 for (unsigned b=0; b < antmask_length; b++) {
6718 uint8_t byte = tvb_get_uint8(tvb, offset+b);
6719 for (unsigned bit=0; bit < 8; bit++) {
6720 if ((1 << bit) & byte) {
6721 antenna_count++;
6722 }
6723 }
6724 }
6725 proto_item_append_text(ant_mask_ti, " (%u antennas)", antenna_count);
6726 offset += antmask_length;
6727
6728 /* Pad to next 4-byte boundary */
6729 offset = WS_ROUNDUP_4(offset)(((offset) + ((unsigned)(4U-1U))) & (~((unsigned)(4U-1U))
))
;
6730 break;
6731 }
6732
6733 case 4: /* ASM (advanced sleep mode) */
6734 /* reserved (2+4=6 bits) */
6735 add_reserved_field(command_tree, hf_oran_reserved_6bits, tvb, offset, 1);
6736 /* sleepMode (2 bits) */
6737 uint32_t sleep_mode;
6738 proto_tree_add_item_ret_uint(command_tree, hf_oran_sleepmode_asm, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &sleep_mode);
6739 offset += 1;
6740
6741 /* reserved (4 bits) */
6742 add_reserved_field(command_tree, hf_oran_reserved_4bits, tvb, offset, 1);
6743 /* numSlotsExt (20 bits) */
6744 proto_tree_add_item(command_tree, hf_oran_num_slots_ext, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6745 offset += 3;
6746
6747 /* reserved (2 bits) */
6748 add_reserved_field(command_tree, hf_oran_reserved_2bits, tvb, offset, 1);
6749 /* symbolMask (14 bits) */
6750 uint32_t symbol_mask;
6751 proto_item *sm_ti;
6752 offset = dissect_symbolmask(tvb, command_tree, offset, &symbol_mask, &sm_ti);
6753 if (symbol_mask == 0x0) {
6754 proto_item_append_text(sm_ti, " (wake)");
6755 col_append_str(pinfo->cinfo, COL_INFO, " (wake)");
6756 }
6757 else if (symbol_mask == 0x3fff) {
6758 proto_item_append_text(sm_ti, " (sleep)");
6759 col_append_str(pinfo->cinfo, COL_INFO, " (sleep)");
6760 }
6761 else {
6762 expert_add_info_format(pinfo, sm_ti, &ei_oran_bad_symbolmask,
6763 "For non-zero sleepMode (%u), symbolMask should be 0x0 or 0x3fff - found 0x%05x",
6764 sleep_mode, symbol_mask);
6765 }
6766 offset += 2;
6767
6768 /* reserved (2 bytes) */
6769 add_reserved_field(command_tree, hf_oran_reserved_16bits, tvb, offset, 2);
6770 offset += 2;
6771 break;
6772
6773 default:
6774 /* Error! */
6775 expert_add_info_format(pinfo, len_ti, &ei_oran_st4_unknown_cmd,
6776 "Dissected ST4 command (%u) not recognised",
6777 st4_cmd_type);
6778 break;
6779 }
6780
6781 /* Check apparent size of padding (0-3 bytes ok) */
6782 long padding_remaining = command_start_offset + (st4_cmd_len * 4) - offset;
6783 if (padding_remaining > 3) {
6784 expert_add_info_format(pinfo, len_ti, &ei_oran_st4_wrong_len_cmd,
6785 "Dissected ST4 command does not match signalled st4CmdLen - set to %u (%u bytes) but dissected %u bytes",
6786 st4_cmd_len, st4_cmd_len*4, offset-command_start_offset);
6787 }
6788
6789 /* Advance by signalled length (needs to be aligned on 4-byte boundary) */
6790 offset = command_start_offset + (st4_cmd_len * 4);
6791
6792 /* Set end of command tree */
6793 proto_item_set_end(command_ti, tvb, offset);
6794
6795 if (ack_nack_req_id != 0 && state && state->ack_nack_requests) {
6796 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
6797 /* Add this request into conversation state on first pass */
6798 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)))
;
6799 request_details->request_frame_number = pinfo->num;
6800 request_details->request_frame_time = pinfo->abs_ts;
6801 request_details->requestType = ST4Cmd1+st4_cmd_type-1;
6802
6803 wmem_tree_insert32(state->ack_nack_requests,
6804 ack_nack_req_id,
6805 request_details);
6806 }
6807 else {
6808 /* On later passes, try to link forward to ST8 response */
6809 ack_nack_request_t *response = wmem_tree_lookup32(state->ack_nack_requests,
6810 ack_nack_req_id);
6811 if (response) {
6812 show_link_to_acknack_response(section_tree, tvb, pinfo, response);
6813 }
6814 }
6815 }
6816 }
6817 }
6818 /* LAA doesn't have sections either.. */
6819 else if (sectionType == SEC_C_LAA) { /* Section Type 7 */
6820 /* 7.2.5 Table 6.4-6 */
6821 unsigned mcot;
6822 proto_item *mcot_ti;
6823
6824 /* laaMsgType */
6825 uint32_t laa_msg_type;
6826 proto_item *laa_msg_type_ti;
6827 laa_msg_type_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_laaMsgType, tvb, offset, 1, ENC_NA0x00000000, &laa_msg_type);
6828 /* laaMsgLen */
6829 uint32_t laa_msg_len;
6830 proto_item *len_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_laaMsgLen, tvb, offset, 1, ENC_NA0x00000000, &laa_msg_len);
6831 proto_item_append_text(len_ti, " (%u bytes)", 4*laa_msg_len);
6832 if (laa_msg_len == 0) {
6833 proto_item_append_text(len_ti, " (reserved)");
6834 }
6835 offset += 1;
6836
6837 int payload_offset = offset;
6838
6839 /* Payload */
6840 switch (laa_msg_type) {
6841 case 0:
6842 /* LBT_PDSCH_REQ */
6843 /* lbtHandle (16 bits) */
6844 proto_tree_add_item(section_tree, hf_oran_lbtHandle, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6845 offset += 2;
6846 /* lbtOffset (10 bits) */
6847 proto_tree_add_item(section_tree, hf_oran_lbtOffset, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6848 offset += 1;
6849 /* lbtMode (2 bits) */
6850 proto_tree_add_bits_item(section_tree, hf_oran_lbtMode, tvb, offset*8+2, 2, ENC_BIG_ENDIAN0x00000000);
6851 /* reserved (1 bit) */
6852 add_reserved_field(section_tree, hf_oran_reserved_bit4, tvb, offset, 1);
6853 /* lbtDeferFactor (3 bits) */
6854 proto_tree_add_item(section_tree, hf_oran_lbtDeferFactor, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6855 offset += 1;
6856 /* lbtBackoffCounter (10 bits) */
6857 proto_tree_add_item(section_tree, hf_oran_lbtBackoffCounter, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6858 offset += 1;
6859 /* MCOT (4 bits) */
6860 mcot_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_MCOT, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &mcot);
6861 if (mcot<1 || mcot>10) {
6862 proto_item_append_text(mcot_ti, " (should be in range 1-10!)");
6863 expert_add_info_format(pinfo, mcot_ti, &ei_oran_mcot_out_of_range,
6864 "MCOT seen with value %u (must be 1-10)", mcot);
6865
6866 }
6867 /* reserved (10 bits) */
6868 proto_tree_add_bits_item(section_tree, hf_oran_reserved, tvb, (offset*8)+6, 10, ENC_BIG_ENDIAN0x00000000);
6869 break;
6870 case 1:
6871 /* LBT_DRS_REQ */
6872 /* lbtHandle (16 bits) */
6873 proto_tree_add_item(section_tree, hf_oran_lbtHandle, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6874 offset += 2;
6875 /* lbtOffset (10 bits) */
6876 proto_tree_add_item(section_tree, hf_oran_lbtOffset, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6877 offset += 1;
6878 /* lbtMode (2 bits) */
6879 proto_tree_add_bits_item(section_tree, hf_oran_lbtMode, tvb, offset*8+2, 2, ENC_BIG_ENDIAN0x00000000);
6880 /* reserved (28 bits) */
6881 proto_tree_add_bits_item(section_tree, hf_oran_reserved, tvb, (offset*8)+4, 28, ENC_BIG_ENDIAN0x00000000);
6882 break;
6883 case 2:
6884 /* LBT_PDSCH_RSP */
6885 /* lbtHandle (16 bits) */
6886 proto_tree_add_item(section_tree, hf_oran_lbtHandle, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6887 offset += 2;
6888 /* lbtPdschRes (2 bits) */
6889 proto_tree_add_item(section_tree, hf_oran_lbtPdschRes, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6890 /* inParSF (1 bit) */
6891 proto_tree_add_item(section_tree, hf_oran_initialPartialSF, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6892 /* sfStatus (1 bit) */
6893 proto_tree_add_item(section_tree, hf_oran_sfStatus, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6894 /* sfnSf (12 bits) */
6895 proto_tree_add_item(section_tree, hf_oran_sfnSfEnd, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6896 offset += 2;
6897 /* reserved (24 bits) */
6898 proto_tree_add_bits_item(section_tree, hf_oran_reserved, tvb, (offset*8), 24, ENC_BIG_ENDIAN0x00000000);
6899 break;
6900 case 3:
6901 /* LBT_DRS_RSP */
6902 /* lbtHandle (16 bits) */
6903 proto_tree_add_item(section_tree, hf_oran_lbtHandle, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6904 offset += 2;
6905 /* lbtDrsRes (1 bit) */
6906 proto_tree_add_item(section_tree, hf_oran_lbtDrsRes, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6907 /* reserved (7 bits) */
6908 add_reserved_field(section_tree, hf_oran_reserved_last_7bits, tvb, offset, 1);
6909 break;
6910 case 4:
6911 /* LBT_Buffer_Error */
6912 /* lbtHandle (16 bits) */
6913 proto_tree_add_item(section_tree, hf_oran_lbtHandle, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6914 offset += 2;
6915 /* lbtBufErr (1 bit) */
6916 proto_tree_add_item(section_tree, hf_oran_lbtBufErr, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6917 /* reserved (7 bits) */
6918 add_reserved_field(section_tree, hf_oran_reserved_last_7bits, tvb, offset, 1);
6919 break;
6920 case 5:
6921 /* LBT_CWCONFIG_REQ */
6922 /* lbtHandle (16 bits) */
6923 proto_tree_add_item(section_tree, hf_oran_lbtHandle, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6924 offset += 2;
6925 /* lbtCWConfig_H (8 bits) */
6926 proto_tree_add_item(section_tree, hf_oran_lbtCWConfig_H, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6927 offset += 1;
6928 /* lbtCWConfig_T (8 bits) */
6929 proto_tree_add_item(section_tree, hf_oran_lbtCWConfig_T, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6930 offset += 1;
6931 /* lbtMode (2 bits) */
6932 proto_tree_add_bits_item(section_tree, hf_oran_lbtMode, tvb, offset*8, 2, ENC_BIG_ENDIAN0x00000000);
6933 /* lbtTrafficClass (3 bits) */
6934 proto_tree_add_item(section_tree, hf_oran_lbtTrafficClass, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6935 /* reserved (19 bits) */
6936 proto_tree_add_bits_item(section_tree, hf_oran_reserved, tvb, (offset*8)+5, 19, ENC_BIG_ENDIAN0x00000000);
6937 break;
6938 case 6:
6939 /* LBT_CWCONFIG_RSP */
6940 /* lbtHandle (16 bits) */
6941 proto_tree_add_item(section_tree, hf_oran_lbtHandle, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6942 offset += 2;
6943 /* lbtCWR_Rst (1 bit) */
6944 proto_tree_add_item(section_tree, hf_oran_lbtCWR_Rst, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6945 /* reserved (7 bits) */
6946 add_reserved_field(section_tree, hf_oran_reserved_last_7bits, tvb, offset, 1);
6947 break;
6948
6949 default:
6950 /* Unhandled! */
6951 expert_add_info_format(pinfo, laa_msg_type_ti, &ei_oran_laa_msg_type_unsupported,
6952 "laaMsgType %u not supported by dissector",
6953 laa_msg_type);
6954
6955 break;
6956 }
6957 /* For now just skip indicated length of bytes */
6958 offset = payload_offset + 4*(laa_msg_len+1);
6959 }
6960
6961
6962 /* Dissect each C section */
6963 for (uint32_t i = 0; i < nSections; ++i) {
6964 tvbuff_t *section_tvb = tvb_new_subset_remaining(tvb, offset);
6965 offset += dissect_oran_c_section(section_tvb, oran_tree, pinfo, state, sectionType, tap_info,
6966 protocol_item,
6967 subframeId, frameId, slotId, startSymbolId,
6968 bit_width, ci_comp_method, ci_comp_opt,
6969 num_sinr_per_prb);
6970 }
6971
6972 /* Expert error if we are short of tvb by > 3 bytes */
6973 if (tvb_reported_length_remaining(tvb, offset) > 3) {
6974 expert_add_info_format(pinfo, protocol_item, &ei_oran_frame_length,
6975 "%u bytes remain at end of frame - should be 0-3",
6976 tvb_reported_length_remaining(tvb, offset));
6977 }
6978
6979 if (PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited) && result) {
6980 /* Show list of frames that have corresponding U-plane data */
6981 wmem_list_frame_t *list_frame;
6982 for (list_frame = wmem_list_head(result->u_plane_frames); list_frame != NULL((void*)0); list_frame = wmem_list_frame_next(list_frame)) {
6983 corresponding_uplane_frame *frame = wmem_list_frame_data(list_frame);
6984 proto_item *uplane_frame_ti = proto_tree_add_uint(oran_tree, hf_oran_corresponding_uplane_frame, tvb, 0, 0,
6985 frame->frame_number);
6986 proto_item_append_text(uplane_frame_ti, " sectionId:%2u symbol:%2u PRBs %3u->%3u (in %uus)",
6987 frame->sectionId, frame->symbol, frame->startPrbu, frame->startPrbu+frame->numPrbu-1, frame->gap_in_usecs);
6988 proto_item_set_generated(uplane_frame_ti);
6989 }
6990 /* Also show total number of corresponding u-plane frames */
6991 proto_item *uplane_frame_count_ti = proto_tree_add_uint(oran_tree, hf_oran_corresponding_uplane_frames_total, tvb, 0, 0,
6992 wmem_list_count(result->u_plane_frames));
6993 proto_item_set_generated(uplane_frame_count_ti);
6994 }
6995
6996 return tvb_captured_length(tvb);
6997}
6998
6999static int dissect_oran_u_re(tvbuff_t *tvb, proto_tree *tree,
7000 unsigned sample_number, int samples_offset,
7001 oran_tap_info *tap_info,
7002 unsigned sample_bit_width,
7003 int comp_meth,
7004 uint32_t exponent,
7005 section_mod_compr_config_t *mod_compr_params,
7006 uint8_t re)
7007{
7008 /* I */
7009 unsigned i_bits = tvb_get_bits32(tvb, samples_offset, sample_bit_width, ENC_BIG_ENDIAN0x00000000);
7010 float i_value = decompress_value(i_bits, comp_meth, sample_bit_width, exponent, mod_compr_params, re);
7011 unsigned sample_len_in_bytes = ((samples_offset%8)+sample_bit_width+7)/8;
7012 proto_item *i_ti = proto_tree_add_float(tree, hf_oran_iSample, tvb, samples_offset/8, sample_len_in_bytes, i_value);
7013 proto_item_set_text(i_ti, "iSample: % 0.7f 0x%04x (RE-%2u in the PRB)", i_value, i_bits, sample_number);
7014 samples_offset += sample_bit_width;
7015 /* Q */
7016 unsigned q_bits = tvb_get_bits32(tvb, samples_offset, sample_bit_width, ENC_BIG_ENDIAN0x00000000);
7017 float q_value = decompress_value(q_bits, comp_meth, sample_bit_width, exponent, mod_compr_params, re);
7018 sample_len_in_bytes = ((samples_offset%8)+sample_bit_width+7)/8;
7019 proto_item *q_ti = proto_tree_add_float(tree, hf_oran_qSample, tvb, samples_offset/8, sample_len_in_bytes, q_value);
7020 proto_item_set_text(q_ti, "qSample: % 0.7f 0x%04x (RE-%2u in the PRB)", q_value, q_bits, sample_number);
7021 samples_offset += sample_bit_width;
7022
7023 /* Update RE stats */
7024 tap_info->num_res++;
7025 /* if (i_value == 0.0 && q_value == 0.0) { */
7026 /* TODO: is just checking bits from frame good enough - assuming this always corresponds to a zero value? */
7027 if (i_bits == 0 && q_bits == 0) {
7028 tap_info->num_res_zero++;
7029 }
7030 else {
7031 tap_info->non_zero_re_in_current_prb = true1;
7032 }
7033 return samples_offset;
7034}
7035
7036
7037static bool_Bool udcomplen_appears_present(bool_Bool udcomphdr_present, tvbuff_t *tvb, int offset)
7038{
7039 if (!udcomplen_heuristic_result_set) {
7040 /* All sections will start the same way */
7041 unsigned int section_bytes_before_field = (udcomphdr_present) ? 6 : 4;
7042
7043 /* Move offset back to the start of the section */
7044 offset -= section_bytes_before_field;
7045
7046 do {
7047 /* This field appears several bytes into the U-plane section */
7048 uint32_t length_remaining = tvb_reported_length_remaining(tvb, offset);
7049 /* Are there enough bytes to still read the length field? */
7050 if (section_bytes_before_field+2 > length_remaining) {
7051 udcomplen_heuristic_result = false0;
7052 udcomplen_heuristic_result_set = true1;
7053 break;
7054 }
7055
7056 /* Read the length field */
7057 uint16_t udcomplen = tvb_get_ntohs(tvb, offset+section_bytes_before_field);
7058
7059 /* Is this less than a valid section? Realistic minimal section will be bigger than this..
7060 * Could take into account numPrbU, etc */
7061 if (udcomplen < section_bytes_before_field+2) {
7062 udcomplen_heuristic_result = false0;
7063 udcomplen_heuristic_result_set = true1;
7064 break;
7065 }
7066
7067 /* Does this section fit into the frame? */
7068 if (udcomplen > length_remaining) {
7069 udcomplen_heuristic_result = false0;
7070 udcomplen_heuristic_result_set = true1;
7071 break;
7072 }
7073
7074 /* Move past this section */
7075 offset += udcomplen;
7076
7077 /* Are we at the end of the frame? */
7078 /* TODO: if frame is less than 60 bytes, there may be > 4 bytes, likely zeros.. */
7079 if (tvb_reported_length_remaining(tvb, offset) < 4) {
7080 udcomplen_heuristic_result = true1;
7081 udcomplen_heuristic_result_set = true1;
7082 }
7083 } while (!udcomplen_heuristic_result_set);
7084 }
7085 return udcomplen_heuristic_result;
7086}
7087
7088static bool_Bool at_udcomphdr(tvbuff_t *tvb, int offset)
7089{
7090 if (tvb_captured_length_remaining(tvb, offset) < 2) {
7091 return false0;
7092 }
7093 uint8_t first_byte = tvb_get_uint8(tvb, offset);
7094 uint8_t reserved_byte = tvb_get_uint8(tvb, offset+1);
7095
7096 /* - iq width could be anything, though unlikely to be signalled as (say) < 1-3? */
7097 /* - meth should be 0-8 */
7098 /* - reserved byte should be 0 */
7099 return (((first_byte & 0x0f) <= MOD_COMPR_AND_SELECTIVE_RE_WITH_MASKS8) && (reserved_byte == 0));
7100}
7101
7102static bool_Bool udcomphdr_appears_present(flow_state_t *flow, uint32_t direction, tvbuff_t *tvb, int offset)
7103{
7104 /* Should really not happen, but guard against this anyway. */
7105 if (flow == NULL((void*)0)) {
7106 /* No state to update. */
7107 return false0;
7108 }
7109
7110 if (direction == DIR_UPLINK0) {
7111 if (flow->udcomphdrUplink_heuristic_result_set) {
7112 /* Return cached value */
7113 return flow->udcomphdrUplink_heuristic_result;
7114 }
7115 else {
7116 /* Work it out, and save answer for next time */
7117 flow->udcomphdrUplink_heuristic_result_set = true1;
7118 flow->udcomphdrUplink_heuristic_result = at_udcomphdr(tvb, offset);
7119 return flow->udcomphdrUplink_heuristic_result;
7120 }
7121 }
7122 else {
7123 /* Downlink */
7124 if (flow->udcomphdrDownlink_heuristic_result_set) {
7125 /* Return cached value */
7126 return flow->udcomphdrDownlink_heuristic_result;
7127 }
7128 else {
7129 /* Work it out, and save answer for next time */
7130 flow->udcomphdrDownlink_heuristic_result_set = true1;
7131 flow->udcomphdrDownlink_heuristic_result = at_udcomphdr(tvb, offset);
7132 return flow->udcomphdrDownlink_heuristic_result;
7133 }
7134 }
7135}
7136
7137static bool_Bool copy_section_entry(const void *key, void* value, void *userdata)
7138{
7139 /* Cast parameters to their types */
7140 uint32_t sectionId = GPOINTER_TO_UINT(key)((guint) (gulong) (key));
7141 expected_section_data_t *result_value = (expected_section_data_t *)value;
7142 wmem_tree_t *result_tree = (wmem_tree_t*)userdata;
7143
7144 /* Deep copy of section data */
7145 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)))
;
7146 *copy = *result_value;
7147
7148 /* Add into result tree */
7149 wmem_tree_insert32(result_tree, sectionId, copy);
7150
7151 return false0;
7152}
7153
7154/* User plane dissector (section 8) */
7155static int
7156dissect_oran_u(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
7157 oran_tap_info *tap_info, void *data _U___attribute__((unused)))
7158{
7159 /* Hidden filter for plane */
7160 proto_item *plane_ti = proto_tree_add_item(tree, hf_oran_uplane, tvb, 0, 0, ENC_NA0x00000000);
7161 PROTO_ITEM_SET_HIDDEN(plane_ti)proto_item_set_hidden((plane_ti));
7162
7163 /* Set up structures needed to add the protocol subtree and manage it */
7164 unsigned offset = 0;
7165
7166 col_set_str(pinfo->cinfo, COL_PROTOCOL, "O-RAN-FH-U");
7167 col_set_str(pinfo->cinfo, COL_INFO, "U-Plane");
7168
7169 tap_info->userplane = true1;
7170
7171 /* Create display subtree for the protocol */
7172 proto_item *protocol_item = proto_tree_add_item(tree, proto_oran, tvb, 0, -1, ENC_NA0x00000000);
7173 proto_item_append_text(protocol_item, "-U");
7174 proto_tree *oran_tree = proto_item_add_subtree(protocol_item, ett_oran);
7175
7176 /* Transport header */
7177 /* Real-time control data / IQ data transfer message series identifier */
7178 uint16_t eAxC;
7179 addPcOrRtcid(tvb, oran_tree, &offset, hf_oran_ecpri_pcid, &eAxC, tap_info);
7180 tap_info->eaxc = eAxC;
7181
7182 /* Update/report status of conversation */
7183 uint32_t key = make_flow_key(pinfo, eAxC, ORAN_U_PLANE1, false0);
7184 flow_state_t* state = (flow_state_t*)wmem_tree_lookup32(flow_states_table, key);
7185
7186 flow_result_t *result = NULL((void*)0);
7187
7188 /* Message identifier */
7189 proto_item *seqIdItem;
7190 uint32_t seqId, subSeqId, e;
7191 offset = addSeqid(tvb, oran_tree, offset, ORAN_U_PLANE1, &seqId, &seqIdItem, pinfo, &subSeqId, &e);
7192
7193 /* Common header for time reference */
7194 proto_item *timingHeader = proto_tree_add_string_format(oran_tree, hf_oran_timing_header,
7195 tvb, offset, 4, "", "Timing Header (");
7196 proto_tree *timing_header_tree = proto_item_add_subtree(timingHeader, ett_oran_u_timing);
7197
7198 /* dataDirection */
7199 uint32_t direction;
7200 proto_tree_add_item_ret_uint(timing_header_tree, hf_oran_data_direction, tvb, offset, 1, ENC_NA0x00000000, &direction);
7201 tap_info->uplink = (direction==0);
1
Assuming 'direction' is not equal to 0
7202 /* payloadVersion */
7203 dissect_payload_version(timing_header_tree, tvb, pinfo, offset);
7204 /* filterIndex */
7205 proto_tree_add_item(timing_header_tree, hf_oran_filter_index, tvb, offset, 1, ENC_NA0x00000000);
7206 offset += 1;
7207
7208 int ref_a_offset = offset;
7209
7210 /* frameId */
7211 uint32_t frameId = 0;
7212 proto_tree_add_item_ret_uint(timing_header_tree, hf_oran_frame_id, tvb, offset, 1, ENC_NA0x00000000, &frameId);
7213 tap_info->frame = frameId;
7214 offset += 1;
7215
7216 /* subframeId */
7217 uint32_t subframeId = 0;
7218 proto_tree_add_item_ret_uint(timing_header_tree, hf_oran_subframe_id, tvb, offset, 1, ENC_NA0x00000000, &subframeId);
7219 /* slotId */
7220 uint32_t slotId = 0;
7221 proto_tree_add_item_ret_uint(timing_header_tree, hf_oran_slot_id, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &slotId);
7222 tap_info->slot = slotId;
7223 offset++;
7224 /* symbolId */
7225 uint32_t symbolId = 0;
7226 proto_tree_add_item_ret_uint(timing_header_tree, hf_oran_symbolId, tvb, offset, 1, ENC_NA0x00000000, &symbolId);
7227 offset++;
7228
7229 char id[16];
7230 snprintf(id, 16, "%u-%u-%u-%u", frameId, subframeId, slotId, symbolId);
7231 proto_item *pi = proto_tree_add_string(timing_header_tree, hf_oran_refa, tvb, ref_a_offset, 3, id);
7232 proto_item_set_generated(pi);
7233
7234 proto_item_append_text(timingHeader, "%s, frameId: %d, subframeId: %d, slotId: %d, symbolId: %d)",
7235 val_to_str_const(direction, data_direction_vals, "Unknown"), frameId, subframeId, slotId, symbolId);
7236
7237 unsigned sample_bit_width;
7238 unsigned compression;
7239 int includeUdCompHeader;
7240
7241 /* Also lookup C-PLANE state (sent in opposite direction for UL) so may check current compression settings */
7242 uint32_t cplane_key = make_flow_key(pinfo, eAxC, ORAN_C_PLANE0, direction
1.1
'direction' is not equal to 0
== 0);
7243 flow_state_t* cplane_state = (flow_state_t*)wmem_tree_lookup32(flow_states_table, cplane_key);
7244
7245 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
2
Assuming field 'visited' is not equal to 0
3
Taking false branch
7246 /* Create state/conversation if doesn't exist yet */
7247 if (!state) {
7248 /* Allocate new state */
7249 state = wmem_new0(wmem_file_scope(), flow_state_t)((flow_state_t*)wmem_alloc0((wmem_file_scope()), sizeof(flow_state_t
)))
;
7250 state->ack_nack_requests = wmem_tree_new(wmem_file_scope());
7251 state->expected_sections[0] = wmem_tree_new(wmem_file_scope());
7252 state->expected_sections[1] = wmem_tree_new(wmem_file_scope());
7253 wmem_tree_insert32(flow_states_table, key, state);
7254 }
7255
7256 result = wmem_new0(wmem_file_scope(), flow_result_t)((flow_result_t*)wmem_alloc0((wmem_file_scope()), sizeof(flow_result_t
)))
;
7257 result->expected_sections = wmem_tree_new(wmem_file_scope());
7258 result->u_plane_frames = wmem_list_new(wmem_file_scope());
7259
7260 wmem_tree_insert32(flow_results_table, pinfo->num, result);
7261
7262 /* Check sequence analysis status (but not if later part of radio layer fragmentation) */
7263 if (state->last_frame_seen[direction] && (subSeqId==0) && (seqId != state->next_expected_sequence_number[direction])) {
7264 /* Store this result */
7265 result->unexpected_seq_number = true1;
7266 result->expected_sequence_number = state->next_expected_sequence_number[direction];
7267 result->previous_frame = state->last_frame[direction];
7268 }
7269 /* Update sequence analysis state */
7270 state->last_frame[direction] = pinfo->num;
7271 state->last_frame_seen[direction] = true1;
7272 state->next_expected_sequence_number[direction] = (seqId+1) % 256;
7273 }
7274
7275 /* Show any issues associated with this frame number */
7276 result = wmem_tree_lookup32(flow_results_table, pinfo->num);
4
Value assigned to 'result'
7277 if (result) {
5
Assuming 'result' is null
7278 if (result->unexpected_seq_number) {
7279 expert_add_info_format(pinfo, seqIdItem,
7280 (direction == DIR_UPLINK0) ?
7281 &ei_oran_uplane_unexpected_sequence_number_ul :
7282 &ei_oran_uplane_unexpected_sequence_number_dl,
7283 "Sequence number %u expected, but got %u",
7284 result->expected_sequence_number, seqId);
7285 tap_info->missing_sns = (256 + seqId - result->expected_sequence_number) % 256;
7286 /* TODO: could add previous/next frame (in seqId tree?) ? */
7287 }
7288 }
7289
7290 /* Checking UL timing within current slot. Disabled if limit set to 0. */
7291 /* N.B., timing is relative to first seen frame,
7292 not some notion of the beginning of the slot from sync, offset by some timing.. */
7293 if (direction
5.1
'direction' is not equal to DIR_UPLINK
== DIR_UPLINK0 && us_allowed_for_ul_in_symbol > 0) {
7294 uint32_t timing_key = get_timing_key(frameId, subframeId, slotId, symbolId);
7295 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
7296 /* Set state on first pass */
7297 ul_timing_for_slot* timing = (ul_timing_for_slot*)wmem_tree_lookup32(ul_symbol_timing, timing_key);
7298 if (!timing) {
7299 /* Allocate new state */
7300 timing = wmem_new0(wmem_file_scope(), ul_timing_for_slot)((ul_timing_for_slot*)wmem_alloc0((wmem_file_scope()), sizeof
(ul_timing_for_slot)))
;
7301 timing->first_frame = pinfo->num;
7302 timing->first_frame_time = pinfo->abs_ts;
7303 timing->frames_seen_in_symbol = 1;
7304 timing->last_frame_in_symbol = pinfo->num;
7305 wmem_tree_insert32(ul_symbol_timing, timing_key, timing);
7306 }
7307 else {
7308 /* Update existing state */
7309 timing->frames_seen_in_symbol++;
7310 timing->last_frame_in_symbol = pinfo->num;
7311 }
7312 }
7313 else {
7314 /* Subsequent passes - look up result */
7315 ul_timing_for_slot* timing = (ul_timing_for_slot*)wmem_tree_lookup32(ul_symbol_timing, timing_key);
7316 if (timing) { /* Really shouldn't fail! */
7317 if (timing->frames_seen_in_symbol > 1) {
7318 /* Work out gap between frames (in microseconds) back to frame carrying first seen symbol */
7319 int seconds_between_packets = (int)
7320 (pinfo->abs_ts.secs - timing->first_frame_time.secs);
7321 int nseconds_between_packets =
7322 pinfo->abs_ts.nsecs - timing->first_frame_time.nsecs;
7323
7324 /* Round to nearest microsecond. */
7325 uint32_t total_gap = (seconds_between_packets*1000000) +
7326 ((nseconds_between_packets+500) / 1000);
7327
7328 /* Show how long it has been */
7329 proto_item *ti = NULL((void*)0);
7330 if (pinfo->num != timing->first_frame) {
7331 ti = proto_tree_add_uint(timingHeader, hf_oran_u_section_ul_symbol_time, tvb, 0, 0, total_gap);
7332 proto_item_set_generated(ti);
7333 }
7334
7335 if (total_gap > us_allowed_for_ul_in_symbol) {
7336 expert_add_info_format(pinfo, ti, &ei_oran_ul_uplane_symbol_too_long,
7337 "UL U-Plane Tx took longer (%u us) than limit set in preferences (%u us)",
7338 total_gap, us_allowed_for_ul_in_symbol);
7339 proto_item_append_text(timingHeader, " (%uus since first frame seen for symbol)", total_gap);
7340 }
7341
7342 /* Show how many frames were received */
7343 ti = proto_tree_add_uint(timingHeader, hf_oran_u_section_ul_symbol_frames, tvb, 0, 0, timing->frames_seen_in_symbol);
7344 proto_item_set_generated(ti);
7345
7346 /* Link to first frame for this symbol */
7347 if (pinfo->num != timing->first_frame) {
7348 ti = proto_tree_add_uint(timingHeader, hf_oran_u_section_ul_symbol_first_frame, tvb, 0, 0, timing->first_frame);
7349 proto_item_set_generated(ti);
7350 }
7351
7352 /* And also last frame */
7353 if (pinfo->num != timing->last_frame_in_symbol) {
7354 ti = proto_tree_add_uint(timingHeader, hf_oran_u_section_ul_symbol_last_frame, tvb, 0, 0, timing->last_frame_in_symbol);
7355 proto_item_set_generated(ti);
7356 }
7357
7358 tap_info->ul_delay_in_us = total_gap;
7359 }
7360 }
7361 }
7362 }
7363
7364
7365 /* Look up preferences for samples */
7366 if (direction
5.2
'direction' is not equal to DIR_UPLINK
== DIR_UPLINK0) {
6
Taking false branch
7367 sample_bit_width = pref_sample_bit_width_uplink;
7368 compression = pref_iqCompressionUplink;
7369 includeUdCompHeader = pref_includeUdCompHeaderUplink;
7370 } else {
7371 sample_bit_width = pref_sample_bit_width_downlink;
7372 compression = pref_iqCompressionDownlink;
7373 includeUdCompHeader = pref_includeUdCompHeaderDownlink;
7374 }
7375
7376 /* If uplink, load any udCompHdr settings written by C-Plane */
7377 bool_Bool ud_cmp_hdr_cplane = false0;
7378 if (cplane_state && direction
7.1
'direction' is not equal to 0
== 0) {
7
Assuming 'cplane_state' is non-null
8
Taking false branch
7379 /* Initialise settings from udpCompHdr from C-Plane */
7380 if (cplane_state->ul_ud_comp_hdr_set && !pref_override_ul_compression) {
7381 sample_bit_width = cplane_state->ul_ud_comp_hdr_bit_width;
7382 compression = cplane_state->ul_ud_comp_hdr_compression;
7383 ud_cmp_hdr_cplane = true1;
7384 }
7385 }
7386
7387 /* Need a valid value (e.g. 9, 14). 0 definitely won't work, as won't progress around loop! */
7388 /* N.B. may yet be overwritten by udCompHdr settings in sections below! */
7389 if (sample_bit_width == 0) {
9
Assuming 'sample_bit_width' is not equal to 0
10
Taking false branch
7390 expert_add_info_format(pinfo, protocol_item, &ei_oran_invalid_sample_bit_width,
7391 "%cL Sample bit width from %s (%u) not valid, so can't decode sections",
7392 (direction == DIR_UPLINK0) ? 'U' : 'D',
7393 !ud_cmp_hdr_cplane ? "preference" : "C-Plane",
7394 sample_bit_width);
7395 return offset;
7396 }
7397
7398 unsigned bytesLeft;
7399 unsigned number_of_sections = 0;
7400 unsigned nBytesPerPrb =0;
7401
7402 if (link_planes_together && !PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited) && cplane_state) {
11
Assuming 'link_planes_together' is false
7403 /* Take a deep-copy of this state on first pass */
7404 wmem_tree_foreach(cplane_state->expected_sections[direction], copy_section_entry, result->expected_sections);
7405 }
7406
7407 /* Add each section (not from count, just keep parsing until payload used) */
7408 do {
7409 /* Section subtree */
7410 unsigned section_start_offset = offset;
7411 proto_item *sectionHeading = proto_tree_add_string_format(oran_tree, hf_oran_u_section,
7412 tvb, offset, 0, "", "Section");
7413 proto_tree *section_tree = proto_item_add_subtree(sectionHeading, ett_oran_u_section);
7414
7415 /* Section Header fields (darker green part) */
7416
7417 /* sectionId */
7418 uint32_t sectionId = 0;
7419 proto_item *ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_section_id, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &sectionId);
7420 if (sectionId == 4095) {
12
Assuming 'sectionId' is not equal to 4095
13
Taking false branch
7421 proto_item_append_text(ti, " (not default coupling C/U planes using sectionId)");
7422 }
7423 offset++;
7424
7425 if (tap_info->num_section_ids < MAX_SECTION_IDs32) {
14
Assuming field 'num_section_ids' is >= MAX_SECTION_IDs
15
Taking false branch
7426 tap_info->section_ids[tap_info->num_section_ids++] = sectionId;
7427 }
7428
7429 section_details_t *section_details = NULL((void*)0);
7430 corresponding_uplane_frame *details = NULL((void*)0);
7431
7432 /* Lookup corresponding C-plane frame/info */
7433 if (link_planes_together) {
16
Assuming 'link_planes_together' is true
17
Taking true branch
7434 if (cplane_state
17.1
'cplane_state' is not equal to NULL
!= NULL((void*)0)) {
18
Taking true branch
7435
7436 expected_section_data_t *section_data = NULL((void*)0);
7437 section_data = wmem_tree_lookup32(result->expected_sections, sectionId);
19
Access to field 'expected_sections' results in a dereference of a null pointer (loaded from variable 'result')
7438
7439 if (section_data) {
7440 /* Need to work out which of 2 entries is in use for this data frame */
7441 unsigned index_to_use = 0;
7442
7443 /* Does the first entry match the timing for this frame? */
7444 if (section_data->details[0].frame == frameId &&
7445 section_data->details[0].subframe == subframeId &&
7446 section_data->details[0].slot == slotId &&
7447 /* Check that symbolId is in range */
7448 section_data->details[0].startSymbol <= symbolId &&
7449 (unsigned)(section_data->details[0].startSymbol + section_data->details[0].numSymbols) <= (unsigned)symbolId) {
7450
7451 index_to_use = 0;
7452 }
7453 else if (section_data->details[1].frame == frameId &&
7454 section_data->details[1].subframe == subframeId &&
7455 section_data->details[1].slot == slotId &&
7456 /* Check that symbolId is in range */
7457 section_data->details[1].startSymbol <= symbolId &&
7458 (unsigned)(section_data->details[1].startSymbol + section_data->details[1].numSymbols) <= (unsigned)symbolId) {
7459
7460 index_to_use = 1;
7461 }
7462 else {
7463 /* TODO: expert info warning? */
7464 }
7465
7466 section_details = &section_data->details[index_to_use];
7467
7468 /* Cplane frame number */
7469 proto_item *cplane_frame_ti = proto_tree_add_uint(section_tree, hf_oran_corresponding_cplane_frame, tvb, 0, 0,
7470 section_details->frame_number);
7471 proto_item_set_generated(cplane_frame_ti);
7472
7473 /* usecs since cplane frame */
7474 time_t total_gap = 0;
7475
7476 if ((pinfo->abs_ts.secs == section_details->frame_time.secs) || (pinfo->abs_ts.secs == section_details->frame_time.secs+1)) {
7477 total_gap = ((pinfo->abs_ts.secs - section_details->frame_time.secs) * 1000000) +
7478 ((pinfo->abs_ts.nsecs - section_details->frame_time.nsecs)/1000);
7479 }
7480
7481 if (total_gap > 0) {
7482 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);
7483 proto_item_set_generated(cplane_delta_ti);
7484 }
7485
7486 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
7487 /* Look up 'result' for c-plane frame, and tell it about this frame.. */
7488 flow_result_t *cplane_result = wmem_tree_lookup32(flow_results_table, section_details->frame_number);
7489 if (!cplane_result) {
7490 cplane_result = wmem_new0(wmem_file_scope(), flow_result_t)((flow_result_t*)wmem_alloc0((wmem_file_scope()), sizeof(flow_result_t
)))
;
7491 cplane_result->u_plane_frames = wmem_list_new(wmem_file_scope());
7492 wmem_tree_insert32(flow_results_table, section_details->frame_number, cplane_result);
7493 }
7494 /* PRB range filled in below.. */
7495
7496 details = wmem_new(wmem_file_scope(), corresponding_uplane_frame)((corresponding_uplane_frame*)wmem_alloc((wmem_file_scope()),
sizeof(corresponding_uplane_frame)))
;
7497 details->frame_number = pinfo->num;
7498 details->gap_in_usecs = (uint32_t)total_gap;
7499 details->sectionId = sectionId;
7500 details->symbol = symbolId;
7501
7502 wmem_list_append(cplane_result->u_plane_frames, details);
7503 }
7504 }
7505 }
7506 }
7507
7508 /* rb */
7509 uint32_t rb;
7510 proto_tree_add_item_ret_uint(section_tree, hf_oran_rb, tvb, offset, 1, ENC_NA0x00000000, &rb);
7511 /* symInc. "use of symInc=1 shall be prohibited in the U-plane" */
7512 uint8_t syminc;
7513 proto_item *syminc_ti = proto_tree_add_item_ret_uint8(section_tree, hf_oran_symInc, tvb, offset, 1, ENC_NA0x00000000, &syminc);
7514 if (syminc) {
7515 expert_add_info(NULL((void*)0), syminc_ti, &ei_oran_syminc_set_for_uplane);
7516 }
7517 /* startPrbu */
7518 uint32_t startPrbu = 0;
7519 proto_tree_add_item_ret_uint(section_tree, hf_oran_startPrbu, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &startPrbu);
7520 offset += 2;
7521
7522 /* numPrbu */
7523 uint32_t numPrbu = 0;
7524 proto_tree_add_item_ret_uint(section_tree, hf_oran_numPrbu, tvb, offset, 1, ENC_NA0x00000000, &numPrbu);
7525 offset += 1;
7526
7527 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited) && details) {
7528 details->startPrbu = startPrbu;
7529 details->numPrbu = (numPrbu) ? numPrbu : 273;
7530 }
7531
7532 proto_item *ud_comp_meth_item, *ud_comp_len_ti=NULL((void*)0);
7533 uint32_t ud_comp_len = 0;
7534
7535 /* udCompHdr (if preferences indicate will be present) */
7536 bool_Bool included = (includeUdCompHeader==1) || /* 1 means present.. */
7537 (includeUdCompHeader==2 && udcomphdr_appears_present(state, direction, tvb, offset));
7538 if (included) {
7539 /* 7.5.2.10 */
7540 /* Extract these values to inform how wide IQ samples in each PRB will be. */
7541 offset = dissect_udcomphdr(tvb, pinfo, section_tree, offset, false0, direction == 0, &sample_bit_width,
7542 &compression, &ud_comp_meth_item, tap_info);
7543
7544 /* Not part of udCompHdr */
7545 uint32_t reserved;
7546 proto_item *res_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_reserved_8bits, tvb, offset, 1, ENC_NA0x00000000, &reserved);
7547 offset += 1;
7548 if (reserved != 0) {
7549 expert_add_info_format(pinfo, res_ti, &ei_oran_reserved_not_zero,
7550 "reserved field (0x%x) not zero - perhaps udCompHdr is not really present?",
7551 reserved);
7552 }
7553 }
7554 else {
7555 /* No fields to dissect - just showing comp values from prefs */
7556 /* iqWidth */
7557 proto_item *iq_width_item = proto_tree_add_uint(section_tree, hf_oran_udCompHdrIqWidth_pref, tvb, 0, 0, sample_bit_width);
7558 proto_item_append_text(iq_width_item, (ud_cmp_hdr_cplane) ? " (from c-plane)" : " (from preferences)");
7559 proto_item_set_generated(iq_width_item);
7560
7561 /* udCompMethod */
7562 ud_comp_meth_item = proto_tree_add_uint(section_tree, hf_oran_udCompHdrMeth_pref, tvb, 0, 0, compression);
7563 proto_item_append_text(ud_comp_meth_item, (ud_cmp_hdr_cplane) ? " (from c-plane)" : " (from preferences)");
7564 proto_item_set_generated(ud_comp_meth_item);
7565
7566 /* Point back to C-Plane, if used */
7567 /* TODO: doesn't work with multiple port mappings using SE10.. */
7568 if (ud_cmp_hdr_cplane) {
7569 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);
7570 proto_item_set_generated(cplane_ti);
7571 }
7572
7573 tap_info->compression_methods |= (1 << compression);
7574 tap_info->compression_width = sample_bit_width;
7575 }
7576
7577 /* Consider fragmentation after first section header */
7578 if (do_radio_transport_layer_reassembly && (number_of_sections == 0) && (e !=1 || subSeqId!= 0)) {
7579
7580 /* Set fragmented flag. */
7581 bool_Bool save_fragmented = pinfo->fragmented;
7582 pinfo->fragmented = true1;
7583 fragment_head *fh;
7584 unsigned frag_data_len = tvb_reported_length_remaining(tvb, offset);
7585
7586 /* Add this fragment into reassembly table */
7587 uint32_t reassembly_id = make_reassembly_id(seqId, direction, eAxC,
7588 frameId, subframeId, slotId, symbolId);
7589 fh = fragment_add_seq(&oran_reassembly_table, tvb, offset, pinfo,
7590 reassembly_id, /* id */
7591 GUINT_TO_POINTER(reassembly_id)((gpointer) (gulong) (reassembly_id)), /* data */
7592 subSeqId, /* frag_number */
7593 frag_data_len, /* frag_data_len */
7594 !e, /* more_frags */
7595 0);
7596
7597 bool_Bool update_col_info = true1;
7598
7599 /* See if this completes an SDU */
7600 tvbuff_t *original_tvb = tvb;
7601 tvbuff_t *next_tvb = process_reassembled_data(tvb, offset, pinfo, "Reassembled O-RAN FH CUS Payload",
7602 fh, &oran_frag_items,
7603 &update_col_info, oran_tree);
7604 if (next_tvb) {
7605 /* Have reassembled data */
7606 proto_tree_add_item(oran_tree, hf_oran_payload, next_tvb, 0, -1, ENC_NA0x00000000);
7607 col_append_fstr(pinfo->cinfo, COL_INFO, " Reassembled Data (%u bytes)", tvb_reported_length(next_tvb));
7608 /* Dissection should resume at start of reassembled tvb */
7609 offset = 0;
7610 }
7611 /* Will continue with either reassembled tvb or NULL */
7612 tvb = next_tvb;
7613
7614 /* Restore fragmented flag */
7615 pinfo->fragmented = save_fragmented;
7616
7617 /* Don't dissect any more if not complete yet.. */
7618 if (tvb == NULL((void*)0)) {
7619 return tvb_captured_length(original_tvb);
7620 }
7621 }
7622
7623
7624 /* Not supported! TODO: other places where comp method is looked up (e.g., bfw?) */
7625 switch (compression) {
7626 case COMP_NONE0:
7627 case COMP_BLOCK_FP1:
7628 case BFP_AND_SELECTIVE_RE5:
7629 case COMP_MODULATION4:
7630 case MOD_COMPR_AND_SELECTIVE_RE6:
7631 break;
7632 default:
7633 expert_add_info_format(pinfo, ud_comp_meth_item, &ei_oran_unsupported_compression_method,
7634 "Compression method %u (%s) not supported by dissector",
7635 compression,
7636 rval_to_str_const(compression, ud_comp_header_meth, "reserved"));
7637 }
7638
7639 /* udCompLen (when supported, methods 5,6,7,8) */
7640 if (compression >= BFP_AND_SELECTIVE_RE5) {
7641 bool_Bool supported = (pref_support_udcompLen==1) || /* supported */
7642 (pref_support_udcompLen==2 && udcomplen_appears_present(includeUdCompHeader, tvb, offset));
7643
7644 if (supported) {
7645 ud_comp_len_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_udCompLen, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &ud_comp_len);
7646 if (ud_comp_len <= 1) {
7647 proto_item_append_text(ud_comp_len_ti, " (reserved)");
7648 }
7649 /* TODO: report if less than a viable section in frame? */
7650 /* Check that there is this much length left in the frame */
7651 if (ud_comp_len > tvb_reported_length_remaining(tvb, section_start_offset)) {
7652 expert_add_info_format(pinfo, ud_comp_len_ti, &ei_oran_ud_comp_len_wrong_size,
7653 "udCompLen indicates %u bytes in section, but only %u are left in frame",
7654 ud_comp_len, tvb_reported_length_remaining(tvb, section_start_offset));
7655 }
7656 /* Actual length of section will be checked below, at the end of the section */
7657 offset += 2;
7658 }
7659 }
7660
7661 /* sReSMask1 + sReSMask2 (depends upon compression method) */
7662 uint64_t sresmask1=0, sresmask2=0;
7663 if (compression == BFP_AND_SELECTIVE_RE_WITH_MASKS7 ||
7664 compression == MOD_COMPR_AND_SELECTIVE_RE_WITH_MASKS8)
7665 {
7666 static int * const sres_mask1_2_flags[] = {
7667 &hf_oran_sReSMask1_2_re12,
7668 &hf_oran_sReSMask1_2_re11,
7669 &hf_oran_sReSMask1_2_re10,
7670 &hf_oran_sReSMask1_2_re9,
7671 &hf_oran_sReSMask_re8,
7672 &hf_oran_sReSMask_re7,
7673 &hf_oran_sReSMask_re6,
7674 &hf_oran_sReSMask_re5,
7675 &hf_oran_sReSMask_re4,
7676 &hf_oran_sReSMask_re3,
7677 &hf_oran_sReSMask_re2,
7678 &hf_oran_sReSMask_re1,
7679 NULL((void*)0)
7680 };
7681
7682 /* reserved (4 bits) */
7683 add_reserved_field(section_tree, hf_oran_reserved_4bits, tvb, offset, 1);
7684 /* sReSMask1 (12 bits) */
7685 proto_item *sresmask_ti;
7686 sresmask_ti = proto_tree_add_bitmask_ret_uint64(section_tree, tvb, offset,
7687 hf_oran_sReSMask1,
7688 ett_oran_sresmask,
7689 sres_mask1_2_flags,
7690 ENC_NA0x00000000,
7691 &sresmask1);
7692 offset += 2;
7693 /* Count REs present */
7694 unsigned res = 0;
7695 for (unsigned n=0; n < 12; n++) {
7696 if ((sresmask1 >> n) & 0x1) {
7697 res++;
7698 }
7699 }
7700 proto_item_append_text(sresmask_ti, " (%u REs)", res);
7701
7702
7703 /* reserved (4 bits) */
7704 add_reserved_field(section_tree, hf_oran_reserved_4bits, tvb, offset, 1);
7705 /* sReSMask2 (12 bits) */
7706 sresmask_ti = proto_tree_add_bitmask_ret_uint64(section_tree, tvb, offset,
7707 hf_oran_sReSMask2,
7708 ett_oran_sresmask,
7709 sres_mask1_2_flags,
7710 ENC_NA0x00000000,
7711 &sresmask2);
7712 offset += 2;
7713
7714 if (rb == 1) {
7715 proto_item_append_text(sresmask_ti, " (ignored)");
7716 if (sresmask2 != 0) {
7717 expert_add_info(pinfo, ud_comp_len_ti, &ei_oran_sresmask2_not_zero_with_rb);
7718 }
7719 }
7720 else {
7721 /* Count REs present */
7722 res = 0;
7723 for (unsigned n=0; n < 12; n++) {
7724 if ((sresmask2 >> n) & 0x1) {
7725 res++;
7726 }
7727 }
7728 proto_item_append_text(sresmask_ti, " (%u REs)", res);
7729 }
7730 }
7731
7732 write_section_info(sectionHeading, pinfo, protocol_item, sectionId, startPrbu, numPrbu, rb);
7733
7734 /* TODO: should this use the same pref as c-plane? */
7735 if (numPrbu == 0) {
7736 /* Special case for all PRBs (NR: the total number of PRBs may be > 255) */
7737 numPrbu = pref_data_plane_section_total_rbs;
7738 startPrbu = 0; /* may already be 0... */
7739 }
7740
7741 section_mod_compr_config_t* mod_compr_config = get_mod_compr_section_to_read(cplane_state, sectionId);
7742
7743 /* Add each PRB */
7744 for (unsigned i = 0; i < numPrbu; i++) {
7745 /* Create subtree */
7746 proto_item *prbHeading = proto_tree_add_string_format(section_tree, hf_oran_samples_prb,
7747 tvb, offset, 0,
7748 "", "PRB");
7749 proto_tree *rb_tree = proto_item_add_subtree(prbHeading, ett_oran_u_prb);
7750 uint32_t exponent = 0;
7751 uint16_t sresmask = 0;
7752
7753 /* udCompParam (depends upon compression method) */
7754 int before = offset;
7755 offset = dissect_udcompparam(tvb, pinfo, rb_tree, offset, compression, &exponent, &sresmask, false0);
7756 int udcompparam_len = offset-before;
7757
7758 /* Show PRB number in root */
7759 proto_item_append_text(prbHeading, " %3u", startPrbu + i*(1+rb));
7760
7761 /* Work out how many REs / PRB */
7762 unsigned res_per_prb = 12;
7763 uint16_t sresmask_to_use = 0x0fff;
7764
7765 if (compression >= BFP_AND_SELECTIVE_RE5) {
7766 /* Work out which mask should be used */
7767 if (compression==BFP_AND_SELECTIVE_RE5 || compression==MOD_COMPR_AND_SELECTIVE_RE6) {
7768 /* Selective RE cases, use value from compModParam */
7769 sresmask_to_use = (uint16_t)sresmask;
7770 }
7771 else {
7772 /* With masks (in section). Choose between sresmask1 and sresmask2 */
7773 if (rb==1 || (i%2)==0) {
7774 /* Even values */
7775 sresmask_to_use = (uint16_t)sresmask1;
7776 }
7777 else {
7778 /* Odd values */
7779 sresmask_to_use = (uint16_t)sresmask2;
7780 }
7781 }
7782
7783 /* Count REs present using sresmask */
7784 res_per_prb = 0;
7785 /* Use sresmask to pick out which REs are present */
7786 for (unsigned n=0; n<12; n++) {
7787 if (sresmask_to_use & (1<<n)) {
7788 res_per_prb++;
7789 }
7790 }
7791 }
7792
7793 /* N.B. bytes for samples need to be padded out to next byte
7794 (certainly where there aren't 12 REs in PRB..) */
7795 unsigned nBytesForSamples = (sample_bit_width * res_per_prb * 2 + 7) / 8;
7796 nBytesPerPrb = nBytesForSamples + udcompparam_len;
7797
7798 proto_tree_add_item(rb_tree, hf_oran_iq_user_data, tvb, offset, nBytesForSamples, ENC_NA0x00000000);
7799
7800 if (section_details) {
7801 if ((startPrbu + i*(1+rb)) < 273) {
7802 proto_item *beamid_ti = proto_tree_add_uint(rb_tree, hf_oran_beamId, tvb, 0, 0,
7803 section_details->beamIds[startPrbu + i*(1+rb)]);
7804 proto_item_set_generated(beamid_ti);
7805 }
7806 }
7807
7808
7809 tap_info->non_zero_re_in_current_prb = false0;
7810
7811 /* Optionally trying to show I/Q RE values */
7812 if (pref_showIQSampleValues) {
7813 /* Individual values */
7814 unsigned samples_offset = offset*8;
7815 unsigned samples_start = offset;
7816 unsigned samples = 0;
7817
7818 if (compression >= BFP_AND_SELECTIVE_RE5) {
7819 /* Use sresmask to pick out which REs are present */
7820 for (unsigned n=1; n<=12; n++) {
7821 if (sresmask_to_use & (1<<(n-1))) {
7822 samples_offset = dissect_oran_u_re(tvb, rb_tree,
7823 n, samples_offset, tap_info, sample_bit_width, compression, exponent, mod_compr_config, n);
7824 samples++;
7825 }
7826 }
7827 }
7828 else {
7829 /* All 12 REs are present */
7830 for (unsigned n=1; n<=12; n++) {
7831 samples_offset = dissect_oran_u_re(tvb, rb_tree,
7832 n, samples_offset, tap_info, sample_bit_width, compression, exponent, mod_compr_config, n);
7833 samples++;
7834 }
7835 }
7836 proto_item_append_text(prbHeading, " (%u REs)", samples);
7837 if (section_details) {
7838 if ((startPrbu + i*(1+rb)) < 273) {
7839 proto_item_append_text(prbHeading, " [BeamId:%u]", section_details->beamIds[startPrbu + i*(1+rb)]);
7840 }
7841 }
7842
7843 /* Was this PRB all zeros? */
7844 if (!tap_info->non_zero_re_in_current_prb) {
7845 tap_info->num_prbs_zero++;
7846 /* Add a filter to make zero-valued PRBs more findable */
7847 proto_item *zero_ti = proto_tree_add_item(rb_tree, hf_oran_zero_prb, tvb,
7848 samples_start, nBytesForSamples, ENC_NA0x00000000);
7849 proto_item_set_hidden(zero_ti);
7850 proto_item_append_text(prbHeading, " (all zeros)");
7851 }
7852 else {
7853 proto_item *nonzero_ti = proto_tree_add_item(rb_tree, hf_oran_nonzero_prb, tvb, samples_start, nBytesForSamples, ENC_NA0x00000000);
7854 proto_item_set_hidden(nonzero_ti);
7855 }
7856 }
7857
7858 tap_info->num_prbs++;
7859
7860
7861 /* Advance past samples */
7862 offset += nBytesForSamples;
7863
7864 /* Set end of prb subtree */
7865 proto_item_set_end(prbHeading, tvb, offset);
7866 }
7867
7868 /* Set extent of section */
7869 proto_item_set_len(sectionHeading, offset-section_start_offset);
7870 if (ud_comp_len_ti != NULL((void*)0) && ((offset-section_start_offset != ud_comp_len))) {
7871 expert_add_info_format(pinfo, ud_comp_len_ti, &ei_oran_ud_comp_len_wrong_size,
7872 "udCompLen indicates %u bytes in section, but dissected %u instead",
7873 ud_comp_len, offset-section_start_offset);
7874 }
7875
7876 bytesLeft = tvb_captured_length(tvb) - offset;
7877 number_of_sections++;
7878 } while (bytesLeft >= (4 + nBytesPerPrb)); /* FIXME: bad heuristic */
7879
7880 /* Show number of sections found */
7881 proto_item *ti = proto_tree_add_uint(oran_tree, hf_oran_numberOfSections, tvb, 0, 0, number_of_sections);
7882 proto_item_set_generated(ti);
7883
7884 /* Expert error if we are short of tvb by > 3 bytes */
7885 if (tvb_reported_length_remaining(tvb, offset) > 3) {
7886 expert_add_info_format(pinfo, protocol_item, &ei_oran_frame_length,
7887 "%u bytes remain at end of frame - should be 0-3",
7888 tvb_reported_length_remaining(tvb, offset));
7889 }
7890
7891 return tvb_captured_length(tvb);
7892}
7893
7894
7895/**********************************************************************/
7896/* Main dissection function. */
7897/* N.B. ecpri message type passed in as 'data' arg by eCPRI dissector */
7898static int
7899dissect_oran(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
7900{
7901 uint32_t ecpri_message_type = *(uint32_t *)data;
7902 unsigned offset = 0;
7903
7904 /* Allocate and zero tap struct */
7905 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
)))
;
7906 tap_info->pdu_size = pinfo->fd->pkt_len;
7907 tap_info->ul_delay_configured_max = us_allowed_for_ul_in_symbol;
7908
7909 switch (ecpri_message_type) {
7910 case ECPRI_MT_IQ_DATA0:
7911 offset = dissect_oran_u(tvb, pinfo, tree, tap_info, data);
7912 break;
7913 case ECPRI_MT_RT_CTRL_DATA2:
7914 offset = dissect_oran_c(tvb, pinfo, tree, tap_info, data);
7915 break;
7916 default:
7917 /* Not dissecting other types - assume these are handled by eCPRI dissector */
7918 return 0;
7919 }
7920
7921 tap_queue_packet(oran_tap, pinfo, tap_info);
7922
7923 return offset;
7924}
7925
7926static void oran_init_protocol(void)
7927{
7928 udcomplen_heuristic_result_set = false0;
7929 udcomplen_heuristic_result = false0;
7930}
7931
7932
7933/* Register the protocol with Wireshark. */
7934void
7935proto_register_oran(void)
7936{
7937 static hf_register_info hf[] = {
7938
7939 /* Section 5.1.3.2.7 */
7940 { &hf_oran_du_port_id,
7941 { "DU Port ID", "oran_fh_cus.du_port_id",
7942 FT_UINT16, BASE_DEC,
7943 NULL((void*)0), 0x0,
7944 "Processing unit at O-RU - width set in dissector preference", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
7945 },
7946
7947 /* Section 5.1.3.2.7 */
7948 { &hf_oran_bandsector_id,
7949 { "BandSector ID", "oran_fh_cus.bandsector_id",
7950 FT_UINT16, BASE_DEC,
7951 NULL((void*)0), 0x0,
7952 "Aggregated cell identified - width set in dissector preference", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
7953 },
7954
7955 /* Section 5.1.3.2.7 */
7956 { &hf_oran_cc_id,
7957 { "CC ID", "oran_fh_cus.cc_id",
7958 FT_UINT16, BASE_DEC,
7959 NULL((void*)0), 0x0,
7960 "Component Carrier - width set in dissector preference", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
7961 },
7962
7963 /* Section 5.1.3.2.7 */
7964 { &hf_oran_ru_port_id,
7965 { "RU Port ID", "oran_fh_cus.ru_port_id",
7966 FT_UINT16, BASE_DEC,
7967 NULL((void*)0), 0x0,
7968 "Logical flow - width set in dissector preference", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
7969 },
7970
7971 /* Section 5.1.3.2.8 */
7972 { &hf_oran_sequence_id,
7973 { "Sequence ID", "oran_fh_cus.sequence_id",
7974 FT_UINT8, BASE_DEC,
7975 NULL((void*)0), 0x0,
7976 "The Sequence ID wraps around individually per eAxC", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
7977 },
7978
7979 /* Section 5.1.3.2.8 */
7980 { &hf_oran_e_bit,
7981 { "E Bit", "oran_fh_cus.e_bit",
7982 FT_UINT8, BASE_DEC,
7983 VALS(e_bit)((0 ? (const struct _value_string*)0 : ((e_bit)))), 0x80,
7984 "Indicate the last message of a subsequence (U-Plane only)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
7985 },
7986
7987 /* Section 5.1.3.2.8 */
7988 { &hf_oran_subsequence_id,
7989 { "Subsequence ID", "oran_fh_cus.subsequence_id",
7990 FT_UINT8, BASE_DEC,
7991 NULL((void*)0), 0x7f,
7992 "The subsequence ID (for eCPRI layer fragmentation)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
7993 },
7994
7995 { &hf_oran_previous_frame,
7996 { "Previous frame in stream", "oran_fh_cus.previous-frame",
7997 FT_FRAMENUM, BASE_NONE,
7998 FRAMENUM_TYPE(FT_FRAMENUM_NONE)((gpointer) (glong) (FT_FRAMENUM_NONE)), 0x0,
7999 "Previous frame in sequence", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
8000 },
8001
8002 /* Section 7.5.2.1 */
8003 { &hf_oran_data_direction,
8004 { "Data Direction", "oran_fh_cus.data_direction",
8005 FT_UINT8, BASE_DEC,
8006 VALS(data_direction_vals)((0 ? (const struct _value_string*)0 : ((data_direction_vals)
)))
, 0x80,
8007 "gNB data direction", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
8008 },
8009
8010 /* Section 7.5.2.2 */
8011 { &hf_oran_payload_version,
8012 { "Payload Version", "oran_fh_cus.payloadVersion",
8013 FT_UINT8, BASE_DEC,
8014 NULL((void*)0), 0x70,
8015 "Payload protocol version the following IEs", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8016 },
8017
8018 /* Section 7.5.2.3 */
8019 { &hf_oran_filter_index,
8020 { "Filter Index", "oran_fh_cus.filterIndex",
8021 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
8022 RVALS(filter_indices)((0 ? (const struct _range_string*)0 : ((filter_indices)))), 0x0f,
8023 "used between IQ data and air interface, both in DL and UL", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8024 },
8025
8026 /* Section 7.5.2.4 */
8027 { &hf_oran_frame_id,
8028 { "Frame ID", "oran_fh_cus.frameId",
8029 FT_UINT8, BASE_DEC,
8030 NULL((void*)0), 0x0,
8031 "A counter for 10 ms frames (wrapping period 2.56 seconds)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8032 },
8033
8034 /* Section 7.5.2.5 */
8035 { &hf_oran_subframe_id,
8036 { "Subframe ID", "oran_fh_cus.subframe_id",
8037 FT_UINT8, BASE_DEC,
8038 NULL((void*)0), 0xf0,
8039 "A counter for 1 ms sub-frames within 10ms frame", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8040 },
8041
8042 /* Section 7.5.2.6 */
8043 { &hf_oran_slot_id,
8044 { "Slot ID", "oran_fh_cus.slotId",
8045 FT_UINT16, BASE_DEC,
8046 NULL((void*)0), 0x0fc0,
8047 "Slot number within a 1ms sub-frame", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8048 },
8049
8050 /* Generated for convenience */
8051 { &hf_oran_slot_within_frame,
8052 { "Slot within frame", "oran_fh_cus.slot-within-frame",
8053 FT_UINT16, BASE_DEC,
8054 NULL((void*)0), 0x0,
8055 "Slot within frame, to match DCT logs", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8056 },
8057
8058 /* Section 7.5.2.7 */
8059 { &hf_oran_start_symbol_id,
8060 { "Start Symbol ID", "oran_fh_cus.startSymbolId",
8061 FT_UINT8, BASE_DEC,
8062 NULL((void*)0), 0x3f,
8063 "The first symbol number within slot affected", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8064 },
8065
8066 /* Section 7.5.2.8 */
8067 { &hf_oran_numberOfSections,
8068 { "Number of Sections", "oran_fh_cus.numberOfSections",
8069 FT_UINT8, BASE_DEC,
8070 NULL((void*)0), 0x0,
8071 "The number of section IDs included in this message", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8072 },
8073
8074 /* Section 7.5.2.9 */
8075 { &hf_oran_sectionType,
8076 { "Section Type", "oran_fh_cus.sectionType",
8077 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
8078 RVALS(section_types)((0 ? (const struct _range_string*)0 : ((section_types)))), 0x0,
8079 "Determines the characteristics of U-plane data", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8080 },
8081
8082 /* Section 7.5.2.10 */
8083 { &hf_oran_udCompHdr,
8084 { "udCompHdr", "oran_fh_cus.udCompHdr",
8085 FT_STRING, BASE_NONE,
8086 NULL((void*)0), 0x0,
8087 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8088 },
8089
8090 /* Section 7.5.2.11 */
8091 { &hf_oran_numberOfUEs,
8092 { "Number Of UEs", "oran_fh_cus.numberOfUEs",
8093 FT_UINT8, BASE_DEC,
8094 NULL((void*)0), 0x0,
8095 "Indicates number of UEs for which channel info is provided", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8096 },
8097
8098 /* Section 7.5.2.12 */
8099 { &hf_oran_timeOffset,
8100 { "Time Offset", "oran_fh_cus.timeOffset",
8101 FT_UINT16, BASE_DEC,
8102 NULL((void*)0), 0x0,
8103 "from start of the slot to start of CP in samples", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8104 },
8105
8106 /* Section 7.5.2.13 */
8107 { &hf_oran_frameStructure_fft,
8108 { "FFT Size", "oran_fh_cus.frameStructure.fft",
8109 FT_UINT8, BASE_HEX | BASE_RANGE_STRING0x00000100,
8110 RVALS(frame_structure_fft)((0 ? (const struct _range_string*)0 : ((frame_structure_fft)
)))
, 0xf0,
8111 "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) }
8112 },
8113
8114 /* Section 7.5.2.13 */
8115 { &hf_oran_frameStructure_subcarrier_spacing,
8116 { "Subcarrier Spacing", "oran_fh_cus.frameStructure.spacing",
8117 FT_UINT8, BASE_HEX | BASE_RANGE_STRING0x00000100,
8118 RVALS(subcarrier_spacings)((0 ? (const struct _range_string*)0 : ((subcarrier_spacings)
)))
, 0x0f,
8119 "The sub carrier spacing as well as the number of slots per 1ms sub-frame",
8120 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
8121 },
8122
8123 /* Section 7.5.2.14 */
8124 { &hf_oran_cpLength,
8125 { "cpLength", "oran_fh_cus.cpLength",
8126 FT_UINT16, BASE_DEC,
8127 NULL((void*)0), 0x0,
8128 "cyclic prefix length", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8129 },
8130
8131 { &hf_oran_timing_header,
8132 { "Timing Header", "oran_fh_cus.timingHeader",
8133 FT_STRING, BASE_NONE,
8134 NULL((void*)0), 0x0,
8135 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8136 },
8137
8138 /* Section 7.5.3.1 */
8139 { &hf_oran_section_id,
8140 { "sectionId", "oran_fh_cus.sectionId",
8141 FT_UINT16, BASE_DEC,
8142 NULL((void*)0), 0xfff0,
8143 "section identifier of data", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8144 },
8145
8146 /* Section 7.5.3.2 */
8147 { &hf_oran_rb,
8148 { "rb", "oran_fh_cus.rb",
8149 FT_UINT8, BASE_DEC,
8150 VALS(rb_vals)((0 ? (const struct _value_string*)0 : ((rb_vals)))), 0x08,
8151 "resource block indicator", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8152 },
8153
8154 /* Section 7.5.5.3 */
8155 { &hf_oran_symInc,
8156 { "symInc", "oran_fh_cus.symInc",
8157 FT_UINT8, BASE_DEC,
8158 VALS(sym_inc_vals)((0 ? (const struct _value_string*)0 : ((sym_inc_vals)))), 0x04,
8159 "Symbol Number Increment Command", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8160 },
8161
8162 /* Section 7.5.3.4 */
8163 { &hf_oran_startPrbc,
8164 { "startPrbc", "oran_fh_cus.startPrbc",
8165 FT_UINT16, BASE_DEC,
8166 NULL((void*)0), 0x03ff,
8167 "Starting PRB of Control Plane Section", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8168 },
8169
8170 /* Section 7.5.3.5 */
8171 { &hf_oran_reMask_re1,
8172 { "RE 1", "oran_fh_cus.reMask-RE1",
8173 FT_BOOLEAN, 16,
8174 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x8000,
8175 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8176 },
8177 { &hf_oran_reMask_re2,
8178 { "RE 2", "oran_fh_cus.reMask-RE2",
8179 FT_BOOLEAN, 16,
8180 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x4000,
8181 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8182 },
8183 { &hf_oran_reMask_re3,
8184 { "RE 3", "oran_fh_cus.reMask-RE3",
8185 FT_BOOLEAN, 16,
8186 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x2000,
8187 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8188 },
8189 { &hf_oran_reMask_re4,
8190 { "RE 4", "oran_fh_cus.reMask-RE4",
8191 FT_BOOLEAN, 16,
8192 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x1000,
8193 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8194 },
8195 { &hf_oran_reMask_re5,
8196 { "RE 5", "oran_fh_cus.reMask-RE5",
8197 FT_BOOLEAN, 16,
8198 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0800,
8199 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8200 },
8201 { &hf_oran_reMask_re6,
8202 { "RE 6", "oran_fh_cus.reMask-RE6",
8203 FT_BOOLEAN, 16,
8204 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0400,
8205 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8206 },
8207 { &hf_oran_reMask_re7,
8208 { "RE 7", "oran_fh_cus.reMask-RE7",
8209 FT_BOOLEAN, 16,
8210 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0200,
8211 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8212 },
8213 { &hf_oran_reMask_re8,
8214 { "RE 8", "oran_fh_cus.reMask-RE8",
8215 FT_BOOLEAN, 16,
8216 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0100,
8217 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8218 },
8219 { &hf_oran_reMask_re9,
8220 { "RE 9", "oran_fh_cus.reMask-RE9",
8221 FT_BOOLEAN, 16,
8222 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0080,
8223 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8224 },
8225 { &hf_oran_reMask_re10,
8226 { "RE 10", "oran_fh_cus.reMask-RE10",
8227 FT_BOOLEAN, 16,
8228 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0040,
8229 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8230 },
8231 { &hf_oran_reMask_re11,
8232 { "RE 11", "oran_fh_cus.reMask-RE11",
8233 FT_BOOLEAN, 16,
8234 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0020,
8235 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8236 },
8237 { &hf_oran_reMask_re12,
8238 { "RE 12", "oran_fh_cus.reMask-RE12",
8239 FT_BOOLEAN, 16,
8240 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0010,
8241 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8242 },
8243 { &hf_oran_reMask,
8244 { "RE Mask", "oran_fh_cus.reMask",
8245 FT_UINT16, BASE_HEX,
8246 NULL((void*)0), 0xfff0,
8247 "The Resource Element (RE) mask within a PRB", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8248 },
8249
8250 /* Section 7.5.3.6 */
8251 { &hf_oran_numPrbc,
8252 { "numPrbc", "oran_fh_cus.numPrbc",
8253 FT_UINT8, BASE_DEC,
8254 NULL((void*)0), 0x0,
8255 "Number of contiguous PRBs per data section description", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8256 },
8257 /* Section 7.5.3.7 */
8258 { &hf_oran_numSymbol,
8259 { "Number of Symbols", "oran_fh_cus.numSymbol",
8260 FT_UINT8, BASE_DEC,
8261 NULL((void*)0), 0x0f,
8262 "Defines number of symbols to which the section control is applicable", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8263 },
8264 /* Section 7.5.3.8 */
8265 { &hf_oran_ef,
8266 { "Extension Flag", "oran_fh_cus.ef",
8267 FT_BOOLEAN, 8,
8268 NULL((void*)0), 0x80,
8269 "Indicates if more section extensions follow", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8270 },
8271 /* Section 7.5.3.9 */
8272 { &hf_oran_beamId,
8273 { "Beam ID", "oran_fh_cus.beamId",
8274 FT_UINT16, BASE_DEC,
8275 NULL((void*)0), 0x7fff,
8276 "Defines the beam pattern to be applied to the U-Plane data", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8277 },
8278
8279 { &hf_oran_extension,
8280 { "Extension", "oran_fh_cus.extension",
8281 FT_STRING, BASE_NONE,
8282 NULL((void*)0), 0x0,
8283 "Section extension", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8284 },
8285
8286 /* Section 7.6.2.1 */
8287 { &hf_oran_exttype,
8288 { "extType", "oran_fh_cus.extType",
8289 FT_UINT8, BASE_DEC|BASE_EXT_STRING0x00000200,
8290 &exttype_vals_ext, 0x7f,
8291 "The extension type, which provides additional parameters specific to subject data extension", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8292 },
8293
8294 /* Section 7.6.2.3 */
8295 { &hf_oran_extlen,
8296 { "extLen", "oran_fh_cus.extLen",
8297 FT_UINT16, BASE_DEC,
8298 NULL((void*)0), 0x0,
8299 "Extension length in 32-bit words", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8300 },
8301
8302 /* Section 7.7.1 */
8303 { &hf_oran_bfw,
8304 { "bfw", "oran_fh_cus.bfw",
8305 FT_STRING, BASE_NONE,
8306 NULL((void*)0), 0x0,
8307 "Set of weights for a particular antenna", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8308 },
8309 { &hf_oran_bfw_bundle,
8310 { "Bundle", "oran_fh_cus.bfw.bundle",
8311 FT_STRING, BASE_NONE,
8312 NULL((void*)0), 0x0,
8313 "Bundle of BFWs", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8314 },
8315 { &hf_oran_bfw_bundle_id,
8316 { "Bundle Id", "oran_fh_cus.bfw.bundleId",
8317 FT_UINT32, BASE_DEC,
8318 NULL((void*)0), 0x0,
8319 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8320 },
8321 /* Section 7.7.1.4 */
8322 { &hf_oran_bfw_i,
8323 { "bfwI", "oran_fh_cus.bfwI",
8324 FT_FLOAT, BASE_NONE,
8325 NULL((void*)0), 0x0,
8326 "In-phase", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8327 },
8328 /* Section 7.7.1.5 */
8329 { &hf_oran_bfw_q,
8330 { "bfwQ", "oran_fh_cus.bfwQ",
8331 FT_FLOAT, BASE_NONE,
8332 NULL((void*)0), 0x0,
8333 "Quadrature", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8334 },
8335
8336 /* Section 7.5.3.10 */
8337 { &hf_oran_ueId,
8338 { "UE ID", "oran_fh_cus.ueId",
8339 FT_UINT16, BASE_DEC,
8340 NULL((void*)0), 0x7fff,
8341 "logical identifier for set of channel info", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8342 },
8343 /* Section 7.5.3.11 */
8344 { &hf_oran_freqOffset,
8345 { "Frequency Offset", "oran_fh_cus.freqOffset",
8346 FT_UINT24, BASE_DEC,
8347 NULL((void*)0), 0x0,
8348 "with respect to the carrier center frequency before additional filtering", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8349 },
8350
8351 /* Section 7.5.3.12 */
8352 { &hf_oran_regularizationFactor,
8353 { "Regularization Factor", "oran_fh_cus.regularizationFactor",
8354 FT_INT16, BASE_DEC,
8355 NULL((void*)0), 0x0,
8356 "Signed value to support MMSE operation within O-RU", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8357 },
8358 /* Section 7.5.3.14 */
8359 { &hf_oran_laaMsgType,
8360 { "LAA Message Type", "oran_fh_cus.laaMsgType",
8361 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
8362 RVALS(laaMsgTypes)((0 ? (const struct _range_string*)0 : ((laaMsgTypes)))), 0xf0,
8363 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8364 },
8365 /* Section 7.5.3.15 */
8366 { &hf_oran_laaMsgLen,
8367 { "LAA Message Length", "oran_fh_cus.laaMsgLen",
8368 FT_UINT8, BASE_DEC,
8369 NULL((void*)0), 0x0f,
8370 "number of 32-bit words in the LAA section", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8371 },
8372 /* Section 7.5.3.16 */
8373 { &hf_oran_lbtHandle,
8374 { "LBT Handle", "oran_fh_cus.lbtHandle",
8375 FT_UINT16, BASE_HEX,
8376 NULL((void*)0), 0x0,
8377 "label to identify transaction", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8378 },
8379 /* Section 7.5.3.17 */
8380 { &hf_oran_lbtDeferFactor,
8381 { "Defer Factor", "oran_fh_cus.lbtDeferFactor",
8382 FT_UINT8, BASE_DEC,
8383 NULL((void*)0), 0x07,
8384 "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)}
8385 },
8386 /* Section 7.5.3.18 */
8387 { &hf_oran_lbtBackoffCounter,
8388 { "Backoff Counter", "oran_fh_cus.lbtBackoffCounter",
8389 FT_UINT16, BASE_DEC,
8390 NULL((void*)0), 0xffc0,
8391 "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)}
8392 },
8393 /* Section 7.5.3.19 */
8394 { &hf_oran_lbtOffset,
8395 { "LBT Offset", "oran_fh_cus.lbtOffset",
8396 FT_UINT16, BASE_DEC,
8397 NULL((void*)0), 0xffc0,
8398 "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)}
8399 },
8400 /* Section 7.5.3.20 */
8401 { &hf_oran_MCOT,
8402 { "Maximum Channel Occupancy Time", "oran_fh_cus.MCOT",
8403 FT_UINT8, BASE_DEC,
8404 NULL((void*)0), 0x3c,
8405 "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)}
8406 },
8407 /* Section 7.5.3.21 */
8408 { &hf_oran_lbtMode,
8409 { "LBT Mode", "oran_fh_cus.lbtMode",
8410 FT_UINT8, BASE_DEC,
8411 VALS(lbtMode_vals)((0 ? (const struct _value_string*)0 : ((lbtMode_vals)))), 0x0,
8412 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8413 },
8414 /* Section 7.5.3.22 */
8415 { &hf_oran_lbtPdschRes,
8416 { "lbtPdschRes", "oran_fh_cus.lbtPdschRes",
8417 FT_UINT8, BASE_DEC,
8418 VALS(lbtPdschRes_vals)((0 ? (const struct _value_string*)0 : ((lbtPdschRes_vals)))), 0xc0,
8419 "LBT result of SFN/SF", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8420 },
8421 /* Section 7.5.3.23 */
8422 { &hf_oran_sfStatus,
8423 { "sfStatus", "oran_fh_cus.sfStatus",
8424 FT_BOOLEAN, 8,
8425 TFS(&tfs_sfStatus)((0 ? (const struct true_false_string*)0 : ((&tfs_sfStatus
))))
, 0x10,
8426 "Indicates whether the subframe was dropped or transmitted", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8427 },
8428 /* Section 7.5.3.24 */
8429 { &hf_oran_lbtDrsRes,
8430 { "lbtDrsRes", "oran_fh_cus.lbtDrsRes",
8431 FT_BOOLEAN, 8,
8432 TFS(&tfs_fail_success)((0 ? (const struct true_false_string*)0 : ((&tfs_fail_success
))))
, 0x80,
8433 "Indicates whether the subframe was dropped or transmitted", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8434 },
8435 /* Section 7.5.3.25 */
8436 { &hf_oran_initialPartialSF,
8437 { "Initial partial SF", "oran_fh_cus.initialPartialSF",
8438 FT_BOOLEAN, 8,
8439 TFS(&tfs_partial_full_sf)((0 ? (const struct true_false_string*)0 : ((&tfs_partial_full_sf
))))
, 0x40,
8440 "Indicates whether the initial SF in the LBT process is full or partial", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8441 },
8442 /* Section 7.5.3.26. */
8443 { &hf_oran_lbtBufErr,
8444 { "lbtBufErr", "oran_fh_cus.lbtBufErr",
8445 FT_BOOLEAN, 8,
8446 TFS(&tfs_lbtBufErr)((0 ? (const struct true_false_string*)0 : ((&tfs_lbtBufErr
))))
, 0x80,
8447 "LBT buffer error", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8448 },
8449 /* Section 7.5.3.27 */
8450 { &hf_oran_sfnSfEnd,
8451 { "SFN/SF End", "oran_fh_cus.sfnSfEnd",
8452 FT_UINT16, BASE_DEC,
8453 NULL((void*)0), 0x0fff,
8454 "SFN/SF by which the DRS window must end", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8455 },
8456 /* Section 7.5.3.28 */
8457 { &hf_oran_lbtCWConfig_H,
8458 { "lbtCWConfig_H", "oran_fh_cus.lbtCWConfig_H",
8459 FT_UINT8, BASE_DEC,
8460 NULL((void*)0), 0x0,
8461 "HARQ parameters for congestion window management", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8462 },
8463 /* Section 7.5.3.29 */
8464 { &hf_oran_lbtCWConfig_T,
8465 { "lbtCWConfig_T", "oran_fh_cus.lbtCWConfig_T",
8466 FT_UINT8, BASE_DEC,
8467 NULL((void*)0), 0x0,
8468 "TB parameters for congestion window management", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8469 },
8470 /* Section 7.5.3.30 */
8471 { &hf_oran_lbtTrafficClass,
8472 { "lbtTrafficClass", "oran_fh_cus.lbtTrafficClass",
8473 FT_UINT8, BASE_DEC,
8474 VALS(lbtTrafficClass_vals)((0 ? (const struct _value_string*)0 : ((lbtTrafficClass_vals
))))
, 0x38,
8475 "Traffic class priority for congestion window management", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8476 },
8477 /* Section 7.5.3.31 */
8478 { &hf_oran_lbtCWR_Rst,
8479 { "lbtCWR_Rst", "oran_fh_cus.lbtCWR_Rst",
8480 FT_BOOLEAN, 8,
8481 TFS(&tfs_fail_success)((0 ? (const struct true_false_string*)0 : ((&tfs_fail_success
))))
, 0x80,
8482 "notification about packet reception successful or not", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8483 },
8484
8485 /* Reserved fields */
8486 { &hf_oran_reserved,
8487 { "reserved", "oran_fh_cus.reserved",
8488 FT_UINT64, BASE_HEX,
8489 NULL((void*)0), 0x0,
8490 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8491 },
8492 { &hf_oran_reserved_1bit,
8493 { "reserved", "oran_fh_cus.reserved",
8494 FT_UINT8, BASE_HEX,
8495 NULL((void*)0), 0x80,
8496 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8497 },
8498 { &hf_oran_reserved_2bits,
8499 { "reserved", "oran_fh_cus.reserved",
8500 FT_UINT8, BASE_HEX,
8501 NULL((void*)0), 0xc0,
8502 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8503 },
8504 { &hf_oran_reserved_3bits,
8505 { "reserved", "oran_fh_cus.reserved",
8506 FT_UINT8, BASE_HEX,
8507 NULL((void*)0), 0xe0,
8508 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8509 },
8510 { &hf_oran_reserved_4bits,
8511 { "reserved", "oran_fh_cus.reserved",
8512 FT_UINT8, BASE_HEX,
8513 NULL((void*)0), 0xf0,
8514 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8515 },
8516 { &hf_oran_reserved_last_4bits,
8517 { "reserved", "oran_fh_cus.reserved",
8518 FT_UINT8, BASE_HEX,
8519 NULL((void*)0), 0x0f,
8520 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8521 },
8522 { &hf_oran_reserved_last_5bits,
8523 { "reserved", "oran_fh_cus.reserved",
8524 FT_UINT8, BASE_HEX,
8525 NULL((void*)0), 0x1f,
8526 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8527 },
8528 { &hf_oran_reserved_6bits,
8529 { "reserved", "oran_fh_cus.reserved",
8530 FT_UINT8, BASE_HEX,
8531 NULL((void*)0), 0xfc,
8532 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8533 },
8534 { &hf_oran_reserved_last_6bits,
8535 { "reserved", "oran_fh_cus.reserved",
8536 FT_UINT8, BASE_HEX,
8537 NULL((void*)0), 0x3f,
8538 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8539 },
8540 { &hf_oran_reserved_7bits,
8541 { "reserved", "oran_fh_cus.reserved",
8542 FT_UINT8, BASE_HEX,
8543 NULL((void*)0), 0xfe,
8544 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8545 },
8546 { &hf_oran_reserved_last_7bits,
8547 { "reserved", "oran_fh_cus.reserved",
8548 FT_UINT8, BASE_HEX,
8549 NULL((void*)0), 0x7f,
8550 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8551 },
8552 { &hf_oran_reserved_8bits,
8553 { "reserved", "oran_fh_cus.reserved",
8554 FT_UINT8, 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_16bits,
8559 { "reserved", "oran_fh_cus.reserved",
8560 FT_UINT16, BASE_HEX,
8561 NULL((void*)0), 0x0,
8562 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8563 },
8564 { &hf_oran_reserved_15bits,
8565 { "reserved", "oran_fh_cus.reserved",
8566 FT_UINT16, BASE_HEX,
8567 NULL((void*)0), 0x7fff,
8568 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8569 },
8570 { &hf_oran_reserved_bit1,
8571 { "reserved", "oran_fh_cus.reserved",
8572 FT_UINT8, BASE_HEX,
8573 NULL((void*)0), 0x40,
8574 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8575 },
8576 { &hf_oran_reserved_bit2,
8577 { "reserved", "oran_fh_cus.reserved",
8578 FT_UINT8, BASE_HEX,
8579 NULL((void*)0), 0x20,
8580 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8581 },
8582 { &hf_oran_reserved_bit4,
8583 { "reserved", "oran_fh_cus.reserved",
8584 FT_UINT8, BASE_HEX,
8585 NULL((void*)0), 0x08,
8586 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8587 },
8588 { &hf_oran_reserved_bit5,
8589 { "reserved", "oran_fh_cus.reserved",
8590 FT_UINT8, BASE_HEX,
8591 NULL((void*)0), 0x04,
8592 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8593 },
8594 { &hf_oran_reserved_bits123,
8595 { "reserved", "oran_fh_cus.reserved",
8596 FT_UINT8, BASE_HEX,
8597 NULL((void*)0), 0x70,
8598 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8599 },
8600 { &hf_oran_reserved_bits456,
8601 { "reserved", "oran_fh_cus.reserved",
8602 FT_UINT8, BASE_HEX,
8603 NULL((void*)0), 0x0e,
8604 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8605 },
8606
8607 /* 7.7.11.9 */
8608 { &hf_oran_cont_ind,
8609 { "contInd", "oran_fh_cus.contInd",
8610 FT_BOOLEAN, 8,
8611 TFS(&continuity_indication_tfs)((0 ? (const struct true_false_string*)0 : ((&continuity_indication_tfs
))))
, 0x80,
8612 "PRB region continuity flag", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8613 },
8614 /* 7.7.11.10 */
8615 { &hf_oran_bundle_offset,
8616 { "BundleOffset", "oran_fh_cus.bundleOffset",
8617 FT_UINT8, BASE_DEC,
8618 NULL((void*)0), 0x3f,
8619 "offset between start of first PRB bundle and startPrbc", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8620 },
8621
8622 /* 7.7.1.2 bfwCompHdr (beamforming weight compression header) */
8623 { &hf_oran_bfwCompHdr,
8624 { "bfwCompHdr", "oran_fh_cus.bfwCompHdr",
8625 FT_STRING, BASE_NONE,
8626 NULL((void*)0), 0x0,
8627 "Compression method and IQ bit width for beamforming weights", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8628 },
8629 { &hf_oran_bfwCompHdr_iqWidth,
8630 { "IQ Bit Width", "oran_fh_cus.bfwCompHdr_iqWidth",
8631 FT_UINT8, BASE_HEX,
8632 VALS(bfw_comp_headers_iq_width)((0 ? (const struct _value_string*)0 : ((bfw_comp_headers_iq_width
))))
, 0xf0,
8633 "IQ bit width for the beamforming weights", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8634 },
8635 { &hf_oran_bfwCompHdr_compMeth,
8636 { "Compression Method", "oran_fh_cus.bfwCompHdr_compMeth",
8637 FT_UINT8, BASE_HEX,
8638 VALS(bfw_comp_headers_comp_meth)((0 ? (const struct _value_string*)0 : ((bfw_comp_headers_comp_meth
))))
, 0x0f,
8639 "compression method for the beamforming weights", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8640 },
8641
8642 /* 7.5.3.32 */
8643 { &hf_oran_ciCompParam,
8644 { "ciCompParam", "oran_fh_cus.ciCompParam",
8645 FT_STRING, BASE_NONE,
8646 NULL((void*)0), 0x0,
8647 "channel information compression parameter", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8648 },
8649
8650 /* Table 7.5.3.32-1 */
8651 { &hf_oran_blockScaler,
8652 { "blockScaler", "oran_fh_cus.blockScaler",
8653 FT_UINT8, BASE_HEX,
8654 NULL((void*)0), 0x0,
8655 "unsigned, 1 integer bit, 7 fractional bits", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8656 },
8657 { &hf_oran_compBitWidth,
8658 { "compBitWidth", "oran_fh_cus.compBitWidth",
8659 FT_UINT8, BASE_DEC,
8660 NULL((void*)0), 0xf0,
8661 "Length of I bits and length of Q bits after compression over entire PRB", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8662 },
8663 { &hf_oran_compShift,
8664 { "compShift", "oran_fh_cus.compShift",
8665 FT_UINT8, BASE_DEC,
8666 NULL((void*)0), 0x0f,
8667 "The shift applied to the entire PRB", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8668 },
8669
8670 { &hf_oran_active_beamspace_coefficient_n1,
8671 { "N1", "oran_fh_cus.activeBeamspace_Coefficient_n1",
8672 FT_BOOLEAN, 8,
8673 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x80,
8674 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8675 },
8676 { &hf_oran_active_beamspace_coefficient_n2,
8677 { "N2", "oran_fh_cus.activeBeamspace_Coefficient_n2",
8678 FT_BOOLEAN, 8,
8679 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x40,
8680 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8681 },
8682 { &hf_oran_active_beamspace_coefficient_n3,
8683 { "N3", "oran_fh_cus.activeBeamspace_Coefficient_n3",
8684 FT_BOOLEAN, 8,
8685 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x20,
8686 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8687 },
8688 { &hf_oran_active_beamspace_coefficient_n4,
8689 { "N4", "oran_fh_cus.activeBeamspace_Coefficient_n4",
8690 FT_BOOLEAN, 8,
8691 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x10,
8692 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8693 },
8694 { &hf_oran_active_beamspace_coefficient_n5,
8695 { "N5", "oran_fh_cus.activeBeamspace_Coefficient_n5",
8696 FT_BOOLEAN, 8,
8697 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x08,
8698 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8699 },
8700 { &hf_oran_active_beamspace_coefficient_n6,
8701 { "N6", "oran_fh_cus.activeBeamspace_Coefficient_n6",
8702 FT_BOOLEAN, 8,
8703 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x04,
8704 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8705 },
8706 { &hf_oran_active_beamspace_coefficient_n7,
8707 { "N7", "oran_fh_cus.activeBeamspace_Coefficient_n7",
8708 FT_BOOLEAN, 8,
8709 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x02,
8710 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8711 },
8712 { &hf_oran_active_beamspace_coefficient_n8,
8713 { "N8", "oran_fh_cus.activeBeamspace_Coefficient_n8",
8714 FT_BOOLEAN, 8,
8715 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x01,
8716 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8717 },
8718
8719 { &hf_oran_activeBeamspaceCoefficientMask,
8720 { "activeBeamspaceCoefficientMask", "oran_fh_cus.activeBeamspaceCoefficientMask",
8721 FT_UINT8, BASE_HEX,
8722 NULL((void*)0), 0xff,
8723 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8724 },
8725 { &hf_oran_activeBeamspaceCoefficientMask_bits_set,
8726 { "Array elements set", "oran_fh_cus.activeBeamspaceCoefficientMask.bits-set",
8727 FT_UINT32, BASE_DEC,
8728 NULL((void*)0), 0x0,
8729 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8730 },
8731
8732 /* Section 7.7.6.6 */
8733 { &hf_oran_se6_repetition,
8734 { "repetition", "oran_fh_cus.repetition",
8735 FT_BOOLEAN, BASE_NONE,
8736 TFS(&repetition_se6_tfs)((0 ? (const struct true_false_string*)0 : ((&repetition_se6_tfs
))))
, 0x0,
8737 "Repetition of a highest priority data section for C-Plane", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8738 },
8739 /* 7.7.20.9 */
8740 { &hf_oran_rbgSize,
8741 { "rbgSize", "oran_fh_cus.rbgSize",
8742 FT_UINT8, BASE_HEX,
8743 VALS(rbg_size_vals)((0 ? (const struct _value_string*)0 : ((rbg_size_vals)))), 0x70,
8744 "Number of PRBs of the resource block groups allocated by the bit mask", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8745 },
8746 /* 7.7.20.10 */
8747 { &hf_oran_rbgMask,
8748 { "rbgMask", "oran_fh_cus.rbgMask",
8749 FT_UINT32, BASE_HEX,
8750 NULL((void*)0), 0x0fffffff,
8751 "Each bit indicates whether a corresponding resource block group is present", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8752 },
8753 /* 7.7.6.5. Also 7.7.12.3 and 7.7.19.5 */
8754 { &hf_oran_noncontig_priority,
8755 { "priority", "oran_fh_cus.priority",
8756 FT_UINT8, BASE_HEX,
8757 VALS(priority_vals)((0 ? (const struct _value_string*)0 : ((priority_vals)))), 0xc0,
8758 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8759 },
8760
8761 /* 7.7.6.4 */
8762 { &hf_oran_symbol_mask,
8763 { "symbolMask", "oran_fh_cus.symbolMask",
8764 FT_UINT16, BASE_HEX,
8765 NULL((void*)0), 0x3fff,
8766 "Each bit indicates whether the rbgMask applies to a given symbol in the slot", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8767 },
8768 { &hf_oran_symbol_mask_s13,
8769 { "symbol 13", "oran_fh_cus.symbolMask.symbol-13",
8770 FT_BOOLEAN, 16,
8771 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x2000,
8772 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8773 },
8774 { &hf_oran_symbol_mask_s12,
8775 { "symbol 12", "oran_fh_cus.symbolMask.symbol-12",
8776 FT_BOOLEAN, 16,
8777 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x1000,
8778 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8779 },
8780 { &hf_oran_symbol_mask_s11,
8781 { "symbol 11", "oran_fh_cus.symbolMask.symbol-11",
8782 FT_BOOLEAN, 16,
8783 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0800,
8784 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8785 },
8786 { &hf_oran_symbol_mask_s10,
8787 { "symbol 10", "oran_fh_cus.symbolMask.symbol-10",
8788 FT_BOOLEAN, 16,
8789 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0400,
8790 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8791 },
8792 { &hf_oran_symbol_mask_s9,
8793 { "symbol 9", "oran_fh_cus.symbolMask.symbol-9",
8794 FT_BOOLEAN, 16,
8795 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0200,
8796 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8797 },
8798 { &hf_oran_symbol_mask_s8,
8799 { "symbol 8", "oran_fh_cus.symbolMask.symbol-8",
8800 FT_BOOLEAN, 16,
8801 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0100,
8802 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8803 },
8804 { &hf_oran_symbol_mask_s7,
8805 { "symbol 7", "oran_fh_cus.symbolMask.symbol-7",
8806 FT_BOOLEAN, 16,
8807 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0080,
8808 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8809 },
8810 { &hf_oran_symbol_mask_s6,
8811 { "symbol 6", "oran_fh_cus.symbolMask.symbol-6",
8812 FT_BOOLEAN, 16,
8813 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0040,
8814 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8815 },
8816 { &hf_oran_symbol_mask_s5,
8817 { "symbol 5", "oran_fh_cus.symbolMask.symbol-5",
8818 FT_BOOLEAN, 16,
8819 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0020,
8820 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8821 },
8822 { &hf_oran_symbol_mask_s4,
8823 { "symbol 4", "oran_fh_cus.symbolMask.symbol-4",
8824 FT_BOOLEAN, 16,
8825 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0010,
8826 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8827 },
8828 { &hf_oran_symbol_mask_s3,
8829 { "symbol 3", "oran_fh_cus.symbolMask.symbol-3",
8830 FT_BOOLEAN, 16,
8831 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0008,
8832 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8833 },
8834 { &hf_oran_symbol_mask_s2,
8835 { "symbol 2", "oran_fh_cus.symbolMask.symbol-2",
8836 FT_BOOLEAN, 16,
8837 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0004,
8838 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8839 },
8840 { &hf_oran_symbol_mask_s1,
8841 { "symbol 1", "oran_fh_cus.symbolMask.symbol-1",
8842 FT_BOOLEAN, 16,
8843 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0002,
8844 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8845 },
8846 { &hf_oran_symbol_mask_s0,
8847 { "symbol 0", "oran_fh_cus.symbolMask.symbol-0",
8848 FT_BOOLEAN, 16,
8849 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0001,
8850 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8851 },
8852
8853
8854 /* 7.7.22.2 */
8855 { &hf_oran_ack_nack_req_id,
8856 { "ackNackReqId", "oran_fh_cus.ackNackReqId",
8857 FT_UINT16, BASE_HEX,
8858 NULL((void*)0), 0x0,
8859 "Indicates the ACK/NACK request ID of a section description", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8860 },
8861
8862 /* Subtree for next 2 items */
8863 { &hf_oran_frequency_range,
8864 { "Frequency Range", "oran_fh_cus.frequencyRange",
8865 FT_STRING, BASE_NONE,
8866 NULL((void*)0), 0x0,
8867 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8868 },
8869
8870 /* 7.7.12.4 */
8871 { &hf_oran_off_start_prb,
8872 { "offStartPrb", "oran_fh_cus.offStartPrb",
8873 FT_UINT8, BASE_DEC,
8874 NULL((void*)0), 0x0,
8875 "Offset of PRB range start", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8876 },
8877 /* 7.7.12.5 */
8878 { &hf_oran_num_prb,
8879 { "numPrb", "oran_fh_cus.numPrb",
8880 FT_UINT8, BASE_DEC,
8881 NULL((void*)0), 0x0,
8882 "Number of PRBs in PRB range", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8883 },
8884
8885 /* symbolId 8.3.3.7 */
8886 { &hf_oran_symbolId,
8887 { "Symbol Identifier", "oran_fh_cus.symbolId",
8888 FT_UINT8, BASE_DEC,
8889 NULL((void*)0), 0x3f,
8890 "Identifies a symbol number within a slot", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8891 },
8892
8893 /* startPrbu 8.3.3.11 */
8894 { &hf_oran_startPrbu,
8895 { "startPrbu", "oran_fh_cus.startPrbu",
8896 FT_UINT16, BASE_DEC,
8897 NULL((void*)0), 0x03ff,
8898 "starting PRB of user plane section", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8899 },
8900
8901 /* numPrbu 8.3.3.12 */
8902 { &hf_oran_numPrbu,
8903 { "numPrbu", "oran_fh_cus.numPrbu",
8904 FT_UINT8, BASE_DEC,
8905 NULL((void*)0), 0x0,
8906 "number of PRBs per user plane section", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8907 },
8908
8909 /* 7.7.1.3 */
8910 { &hf_oran_bfwCompParam,
8911 { "bfwCompParam", "oran_fh_cus.bfwCompParam",
8912 FT_STRING, BASE_NONE,
8913 NULL((void*)0), 0x0,
8914 "Beamforming weight compression parameter", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8915 },
8916
8917 /* 6.3.3.13 */
8918 { &hf_oran_udCompHdrMeth,
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)
)))
, 0x0f,
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 { &hf_oran_udCompHdrMeth_pref,
8925 { "User Data Compression Method", "oran_fh_cus.udCompHdrMeth",
8926 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
8927 RVALS(ud_comp_header_meth)((0 ? (const struct _range_string*)0 : ((ud_comp_header_meth)
)))
, 0x0,
8928 "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)}
8929 },
8930 /* 8.3.3.18 */
8931 { &hf_oran_udCompLen,
8932 { "udCompLen", "oran_fh_cus.udCompLen",
8933 FT_UINT16, BASE_DEC,
8934 NULL((void*)0), 0x0,
8935 "PRB field length in octets", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8936 },
8937
8938 /* 7.5.2.10 */
8939 { &hf_oran_udCompHdrIqWidth,
8940 { "User Data IQ width", "oran_fh_cus.udCompHdrWidth",
8941 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
8942 RVALS(ud_comp_header_width)((0 ? (const struct _range_string*)0 : ((ud_comp_header_width
))))
, 0xf0,
8943 "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)}
8944 },
8945 { &hf_oran_udCompHdrIqWidth_pref,
8946 { "User Data IQ width", "oran_fh_cus.udCompHdrWidth.pref",
8947 FT_UINT8, BASE_DEC,
8948 NULL((void*)0), 0x0,
8949 "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)}
8950 },
8951
8952 { &hf_oran_sinrCompHdrIqWidth_pref,
8953 { "SINR IQ width", "oran_fh_cus.sinrCompHdrWidth",
8954 FT_UINT8, BASE_DEC,
8955 NULL((void*)0), 0x0,
8956 "Defines the IQ bit width for SINR data in section type 9", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8957 },
8958 { &hf_oran_sinrCompHdrMeth_pref,
8959 { "SINR Compression Method", "oran_fh_cus.sinrCompHdrMeth",
8960 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
8961 RVALS(ud_comp_header_meth)((0 ? (const struct _range_string*)0 : ((ud_comp_header_meth)
)))
, 0x0,
8962 "Defines the compression method for SINR data in section type 9", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8963 },
8964
8965 /* Section 8.3.3.15 (not always present - depends upon meth) */
8966 { &hf_oran_udCompParam,
8967 { "User Data Compression Parameter", "oran_fh_cus.udCompParam",
8968 FT_STRING, BASE_NONE,
8969 NULL((void*)0), 0x0,
8970 "Applies to whatever compression method is specified by the associated sectionID's compMeth value", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8971 },
8972 /* 8.3.3.18 */
8973 { &hf_oran_sReSMask,
8974 { "sReSMask", "oran_fh_cus.sReSMask",
8975 FT_UINT16, BASE_HEX,
8976 NULL((void*)0), 0xf0ff,
8977 "selective RE sending mask", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8978 },
8979
8980 { &hf_oran_sReSMask_re12,
8981 { "RE-12", "oran_fh_cus.sReSMask-re12",
8982 FT_BOOLEAN, 16,
8983 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x8000,
8984 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8985 },
8986 { &hf_oran_sReSMask_re11,
8987 { "RE-11", "oran_fh_cus.sReSMask-re11",
8988 FT_BOOLEAN, 16,
8989 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x4000,
8990 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8991 },
8992 { &hf_oran_sReSMask_re10,
8993 { "RE-10", "oran_fh_cus.sReSMask-re10",
8994 FT_BOOLEAN, 16,
8995 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x2000,
8996 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8997 },
8998 { &hf_oran_sReSMask_re9,
8999 { "RE-9", "oran_fh_cus.sReSMask-re9",
9000 FT_BOOLEAN, 16,
9001 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x1000,
9002 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9003 },
9004 { &hf_oran_sReSMask_re8,
9005 { "RE-8", "oran_fh_cus.sReSMask-re8",
9006 FT_BOOLEAN, 16,
9007 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0080,
9008 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9009 },
9010 { &hf_oran_sReSMask_re7,
9011 { "RE-7", "oran_fh_cus.sReSMask-re7",
9012 FT_BOOLEAN, 16,
9013 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0040,
9014 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9015 },
9016 { &hf_oran_sReSMask_re6,
9017 { "RE-6", "oran_fh_cus.sReSMask-re6",
9018 FT_BOOLEAN, 16,
9019 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0020,
9020 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9021 },
9022 { &hf_oran_sReSMask_re5,
9023 { "RE-5", "oran_fh_cus.sReSMask-re5",
9024 FT_BOOLEAN, 16,
9025 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0010,
9026 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9027 },
9028 { &hf_oran_sReSMask_re4,
9029 { "RE-4", "oran_fh_cus.sReSMask-re4",
9030 FT_BOOLEAN, 16,
9031 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0008,
9032 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9033 },
9034 { &hf_oran_sReSMask_re3,
9035 { "RE-3", "oran_fh_cus.sReSMask-re3",
9036 FT_BOOLEAN, 16,
9037 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0004,
9038 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9039 },
9040 { &hf_oran_sReSMask_re2,
9041 { "RE-2", "oran_fh_cus.sReSMask-re2",
9042 FT_BOOLEAN, 16,
9043 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0002,
9044 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9045 },
9046 { &hf_oran_sReSMask_re1,
9047 { "RE-1", "oran_fh_cus.sReSMask-re1",
9048 FT_BOOLEAN, 16,
9049 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0001,
9050 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9051 },
9052
9053 /* 8.3.3.20 */
9054 { &hf_oran_sReSMask1,
9055 { "sReSMask1", "oran_fh_cus.sReSMask1",
9056 FT_UINT16, BASE_HEX,
9057 NULL((void*)0), 0x0fff,
9058 "selective RE sending mask 1", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9059 },
9060 /* 8.3.3.21 */
9061 { &hf_oran_sReSMask2,
9062 { "sReSMask2", "oran_fh_cus.sReSMask2",
9063 FT_UINT16, BASE_HEX,
9064 NULL((void*)0), 0x0fff,
9065 "selective RE sending mask 2", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9066 },
9067
9068 { &hf_oran_sReSMask1_2_re12,
9069 { "RE-12", "oran_fh_cus.sReSMask-re12",
9070 FT_BOOLEAN, 16,
9071 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0800,
9072 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9073 },
9074 { &hf_oran_sReSMask1_2_re11,
9075 { "RE-11", "oran_fh_cus.sReSMask-re11",
9076 FT_BOOLEAN, 16,
9077 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0400,
9078 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9079 },
9080 { &hf_oran_sReSMask1_2_re10,
9081 { "RE-10", "oran_fh_cus.sReSMask-re10",
9082 FT_BOOLEAN, 16,
9083 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0200,
9084 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9085 },
9086 { &hf_oran_sReSMask1_2_re9,
9087 { "RE-9", "oran_fh_cus.sReSMask-re9",
9088 FT_BOOLEAN, 16,
9089 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0100,
9090 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9091 },
9092
9093 /* Section 6.3.3.15 */
9094 { &hf_oran_iSample,
9095 { "iSample", "oran_fh_cus.iSample",
9096 FT_FLOAT, BASE_NONE,
9097 NULL((void*)0), 0x0,
9098 "In-phase Sample value", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9099 },
9100
9101 /* Section 6.3.3.16 */
9102 { &hf_oran_qSample,
9103 { "qSample", "oran_fh_cus.qSample",
9104 FT_FLOAT, BASE_NONE,
9105 NULL((void*)0), 0x0,
9106 "Quadrature Sample value", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9107 },
9108
9109 { &hf_oran_exponent,
9110 { "Exponent", "oran_fh_cus.exponent",
9111 FT_UINT8, BASE_DEC,
9112 NULL((void*)0), 0x0f,
9113 "Exponent applicable to the I & Q mantissas", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9114 },
9115
9116 { &hf_oran_iq_user_data,
9117 { "IQ User Data", "oran_fh_cus.iq_user_data",
9118 FT_BYTES, BASE_NONE,
9119 NULL((void*)0), 0x0,
9120 "Used for the In-phase and Quadrature sample mantissa", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9121 },
9122
9123
9124 { &hf_oran_u_section_ul_symbol_time,
9125 { "Microseconds since first UL U-plane frame for this symbol", "oran_fh_cus.us-since-first-ul-frame",
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_frames,
9131 { "Number of UL frames sent for this symbol", "oran_fh_cus.number-ul-frames-in-symbol",
9132 FT_UINT32, BASE_DEC,
9133 NULL((void*)0), 0x0,
9134 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9135 },
9136 { &hf_oran_u_section_ul_symbol_first_frame,
9137 { "First UL frame for this symbol", "oran_fh_cus.first-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 { &hf_oran_u_section_ul_symbol_last_frame,
9143 { "Last UL frame for this symbol", "oran_fh_cus.last-ul-frame-in-symbol",
9144 FT_FRAMENUM, BASE_NONE,
9145 FRAMENUM_TYPE(FT_FRAMENUM_NONE)((gpointer) (glong) (FT_FRAMENUM_NONE)), 0x0,
9146 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9147 },
9148
9149 { &hf_oran_c_eAxC_ID,
9150 { "c_eAxC_ID", "oran_fh_cus.c_eaxc_id",
9151 FT_STRING, BASE_NONE,
9152 NULL((void*)0), 0x0,
9153 "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) }
9154 },
9155
9156 { &hf_oran_refa,
9157 { "RefA", "oran_fh_cus.refa",
9158 FT_STRING, BASE_NONE,
9159 NULL((void*)0), 0x0,
9160 "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) }
9161 },
9162
9163
9164 /* Section 7.5.2.15 */
9165 { &hf_oran_ciCompHdr,
9166 { "ciCompHdr", "oran_fh_cus.ciCompHdr",
9167 FT_STRING, BASE_NONE,
9168 NULL((void*)0), 0x0,
9169 "Channel Information Compression Header", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9170 },
9171 { &hf_oran_ciCompHdrMeth,
9172 { "User Data Compression Method", "oran_fh_cus.ciCompHdrMeth",
9173 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
9174 RVALS(ud_comp_header_meth)((0 ? (const struct _range_string*)0 : ((ud_comp_header_meth)
)))
, 0x0e,
9175 "Compression method for Channel Information", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9176 },
9177 { &hf_oran_ciCompHdrIqWidth,
9178 { "User Data IQ width", "oran_fh_cus.ciCompHdrWidth",
9179 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
9180 RVALS(ud_comp_header_width)((0 ? (const struct _range_string*)0 : ((ud_comp_header_width
))))
, 0xf0,
9181 "IQ bit width for Channel Information", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9182 },
9183 { &hf_oran_ciCompOpt,
9184 { "ciCompOpt", "oran_fh_cus.ciCompOpt",
9185 FT_UINT8, BASE_DEC,
9186 VALS(ci_comp_opt_vals)((0 ? (const struct _value_string*)0 : ((ci_comp_opt_vals)))), 0x01,
9187 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9188 },
9189
9190 /* 7.7.11.7 */
9191 { &hf_oran_disable_bfws,
9192 { "disableBFWs", "oran_fh_cus.disableBFWs",
9193 FT_BOOLEAN, 8,
9194 NULL((void*)0), 0x80,
9195 "Indicate if BFWs under section extension are disabled", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9196 },
9197 /* 7.7.11.8 */
9198 { &hf_oran_rad,
9199 { "RAD", "oran_fh_cus.rad",
9200 FT_BOOLEAN, 8,
9201 NULL((void*)0), 0x40,
9202 "Reset After PRB Discontinuity", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9203 },
9204 /* 7.7.11.4 */
9205 { &hf_oran_num_bund_prbs,
9206 { "numBundPrb", "oran_fh_cus.numBundPrb",
9207 FT_UINT8, BASE_DEC,
9208 NULL((void*)0), 0x0,
9209 "Number of bundled PRBs per BFWs", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9210 },
9211 { &hf_oran_beam_id,
9212 { "beamId", "oran_fh_cus.beamId",
9213 FT_UINT16, BASE_DEC,
9214 NULL((void*)0), 0x7fff,
9215 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9216 },
9217 { &hf_oran_num_weights_per_bundle,
9218 { "Num weights per bundle", "oran_fh_cus.num_weights_per_bundle",
9219 FT_UINT16, BASE_DEC,
9220 NULL((void*)0), 0x0,
9221 "From dissector preference", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9222 },
9223
9224 { &hf_oran_samples_prb,
9225 {"PRB", "oran_fh_cus.prb",
9226 FT_STRING, BASE_NONE,
9227 NULL((void*)0), 0x0,
9228 "Grouping of samples for a particular Physical Resource Block", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9229 },
9230
9231 /* 7.5.3.13 */
9232 { &hf_oran_ciSample,
9233 { "ciSample", "oran_fh_cus.ciSample",
9234 FT_STRING, BASE_NONE,
9235 NULL((void*)0), 0x0,
9236 "Sample (I and Q values)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9237 },
9238 { &hf_oran_ciIsample,
9239 { "ciIsample", "oran_fh_cus.ciISample",
9240 FT_FLOAT, BASE_NONE,
9241 NULL((void*)0), 0x0,
9242 "Channel information complex value - I part", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9243 },
9244 { &hf_oran_ciQsample,
9245 { "ciQsample", "oran_fh_cus.ciQSample",
9246 FT_FLOAT, BASE_NONE,
9247 NULL((void*)0), 0x0,
9248 "Channel information complex value - Q part", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9249 },
9250
9251 /* 7.7.10.2 */
9252 { &hf_oran_beamGroupType,
9253 { "beamGroupType", "oran_fh_cus.beamGroupType",
9254 FT_UINT8, BASE_DEC,
9255 VALS(beam_group_type_vals)((0 ? (const struct _value_string*)0 : ((beam_group_type_vals
))))
, 0xc0,
9256 "The type of beam grouping", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9257 },
9258 /* 7.7.10.3 */
9259 { &hf_oran_numPortc,
9260 { "numPortc", "oran_fh_cus.numPortc",
9261 FT_UINT8, BASE_DEC,
9262 NULL((void*)0), 0x3f,
9263 "The number of eAxC ports", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9264 },
9265
9266 /* 7.7.4.2 (1 bit) */
9267 { &hf_oran_csf,
9268 { "csf", "oran_fh_cus.csf",
9269 FT_BOOLEAN, BASE_NONE,
9270 NULL((void*)0), 0x0,
9271 "constellation shift flag", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9272 },
9273 /* 7.7.4.3 */
9274 { &hf_oran_modcompscaler,
9275 { "modCompScaler", "oran_fh_cus.modcompscaler",
9276 FT_UINT16, BASE_DEC,
9277 NULL((void*)0), 0x7fff,
9278 "modulation compression scaler value", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9279 },
9280
9281 /* 7.7.5.1 */
9282 { &hf_oran_modcomp_param_set,
9283 { "Set", "oran_fh_cus.modcomp-param-set",
9284 FT_STRING, BASE_NONE,
9285 NULL((void*)0), 0x0,
9286 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9287 },
9288
9289
9290
9291 /* mcScaleReMask 7.7.5.2 (12 bits) */
9292
9293 /* First entry (starts with msb within byte) */
9294 { &hf_oran_mc_scale_re_mask_re1,
9295 { "RE 1", "oran_fh_cus.mcscalermask-RE1",
9296 FT_BOOLEAN, 16,
9297 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x8000,
9298 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9299 },
9300 { &hf_oran_mc_scale_re_mask_re2,
9301 { "RE 2", "oran_fh_cus.mcscalermask-RE2",
9302 FT_BOOLEAN, 16,
9303 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x4000,
9304 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9305 },
9306 { &hf_oran_mc_scale_re_mask_re3,
9307 { "RE 3", "oran_fh_cus.mcscalermask-RE3",
9308 FT_BOOLEAN, 16,
9309 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x2000,
9310 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9311 },
9312 { &hf_oran_mc_scale_re_mask_re4,
9313 { "RE 4", "oran_fh_cus.mcscalermask-RE4",
9314 FT_BOOLEAN, 16,
9315 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x1000,
9316 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9317 },
9318 { &hf_oran_mc_scale_re_mask_re5,
9319 { "RE 5", "oran_fh_cus.mcscalermask-RE5",
9320 FT_BOOLEAN, 16,
9321 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0800,
9322 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9323 },
9324 { &hf_oran_mc_scale_re_mask_re6,
9325 { "RE 6", "oran_fh_cus.mcscalermask-RE6",
9326 FT_BOOLEAN, 16,
9327 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0400,
9328 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9329 },
9330 { &hf_oran_mc_scale_re_mask_re7,
9331 { "RE 7", "oran_fh_cus.mcscalermask-RE7",
9332 FT_BOOLEAN, 16,
9333 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0200,
9334 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9335 },
9336 { &hf_oran_mc_scale_re_mask_re8,
9337 { "RE 8", "oran_fh_cus.mcscalermask-RE8",
9338 FT_BOOLEAN, 16,
9339 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0100,
9340 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9341 },
9342 { &hf_oran_mc_scale_re_mask_re9,
9343 { "RE 9", "oran_fh_cus.mcscalermask-RE9",
9344 FT_BOOLEAN, 16,
9345 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0080,
9346 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9347 },
9348 { &hf_oran_mc_scale_re_mask_re10,
9349 { "RE 10", "oran_fh_cus.mcscalermask-RE10",
9350 FT_BOOLEAN, 16,
9351 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0040,
9352 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9353 },
9354 { &hf_oran_mc_scale_re_mask_re11,
9355 { "RE 11", "oran_fh_cus.mcscalermask-RE11",
9356 FT_BOOLEAN, 16,
9357 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0020,
9358 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9359 },
9360 { &hf_oran_mc_scale_re_mask_re12,
9361 { "RE 12", "oran_fh_cus.mcscalermask-RE12",
9362 FT_BOOLEAN, 16,
9363 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0010,
9364 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9365 },
9366
9367 /* Even tries entry (starts with 5th bit within byte) */
9368 { &hf_oran_mc_scale_re_mask_re1_even,
9369 { "RE 1", "oran_fh_cus.mcscalermask-RE1",
9370 FT_BOOLEAN, 16,
9371 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0800,
9372 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9373 },
9374 { &hf_oran_mc_scale_re_mask_re2_even,
9375 { "RE 2", "oran_fh_cus.mcscalermask-RE2",
9376 FT_BOOLEAN, 16,
9377 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0400,
9378 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9379 },
9380 { &hf_oran_mc_scale_re_mask_re3_even,
9381 { "RE 3", "oran_fh_cus.mcscalermask-RE3",
9382 FT_BOOLEAN, 16,
9383 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0200,
9384 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9385 },
9386 { &hf_oran_mc_scale_re_mask_re4_even,
9387 { "RE 4", "oran_fh_cus.mcscalermask-RE4",
9388 FT_BOOLEAN, 16,
9389 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0100,
9390 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9391 },
9392 { &hf_oran_mc_scale_re_mask_re5_even,
9393 { "RE 5", "oran_fh_cus.mcscalermask-RE5",
9394 FT_BOOLEAN, 16,
9395 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0080,
9396 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9397 },
9398 { &hf_oran_mc_scale_re_mask_re6_even,
9399 { "RE 6", "oran_fh_cus.mcscalermask-RE6",
9400 FT_BOOLEAN, 16,
9401 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0040,
9402 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9403 },
9404 { &hf_oran_mc_scale_re_mask_re7_even,
9405 { "RE 7", "oran_fh_cus.mcscalermask-RE7",
9406 FT_BOOLEAN, 16,
9407 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0020,
9408 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9409 },
9410 { &hf_oran_mc_scale_re_mask_re8_even,
9411 { "RE 8", "oran_fh_cus.mcscalermask-RE8",
9412 FT_BOOLEAN, 16,
9413 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0010,
9414 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9415 },
9416 { &hf_oran_mc_scale_re_mask_re9_even,
9417 { "RE 9", "oran_fh_cus.mcscalermask-RE9",
9418 FT_BOOLEAN, 16,
9419 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0008,
9420 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9421 },
9422 { &hf_oran_mc_scale_re_mask_re10_even,
9423 { "RE 10", "oran_fh_cus.mcscalermask-RE10",
9424 FT_BOOLEAN, 16,
9425 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0004,
9426 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9427 },
9428 { &hf_oran_mc_scale_re_mask_re11_even,
9429 { "RE 11", "oran_fh_cus.mcscalermask-RE11",
9430 FT_BOOLEAN, 16,
9431 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0002,
9432 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9433 },
9434 { &hf_oran_mc_scale_re_mask_re12_even,
9435 { "RE 12", "oran_fh_cus.mcscalermask-RE12",
9436 FT_BOOLEAN, 16,
9437 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0001,
9438 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9439 },
9440
9441 { &hf_oran_mc_scale_re_mask,
9442 { "mcScaleReMask", "oran_fh_cus.mcscaleremask",
9443 FT_UINT16, BASE_HEX,
9444 NULL((void*)0), 0xfff0,
9445 "modulation compression power scale RE mask", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9446 },
9447 { &hf_oran_mc_scale_re_mask_even,
9448 { "mcScaleReMask", "oran_fh_cus.mcscaleremask",
9449 FT_UINT16, BASE_HEX,
9450 NULL((void*)0), 0x0fff,
9451 "modulation compression power scale RE mask", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9452 },
9453
9454 /* mcScaleOffset 7.7.5.4 (15 bits) */
9455 { &hf_oran_mc_scale_offset,
9456 { "mcScaleOffset", "oran_fh_cus.mcscaleoffset",
9457 FT_UINT24, BASE_DEC,
9458 NULL((void*)0), 0x0,
9459 "scaling value for modulation compression", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9460 },
9461 /* eAxCmask (7.7.7.2) */
9462 { &hf_oran_eAxC_mask,
9463 { "eAxC Mask", "oran_fh_cus.eaxcmask",
9464 FT_UINT16, BASE_HEX,
9465 NULL((void*)0), 0xffff,
9466 "Which eAxC_ID values the C-Plane message applies to", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9467 },
9468 /* technology (interface name) 7.7.9.2 */
9469 { &hf_oran_technology,
9470 { "Technology", "oran_fh_cus.technology",
9471 FT_UINT8, BASE_DEC,
9472 VALS(interface_name_vals)((0 ? (const struct _value_string*)0 : ((interface_name_vals)
)))
, 0x0,
9473 "Interface name (that C-PLane section applies to)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9474 },
9475 /* Exttype 14 (7.7.14.2) */
9476 { &hf_oran_nullLayerInd,
9477 { "nullLayerInd", "oran_fh_cus.nulllayerind",
9478 FT_BOOLEAN, BASE_NONE,
9479 NULL((void*)0), 0x0,
9480 "Whether corresponding layer is nulling-layer or not", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9481 },
9482
9483 /* Exttype 19 */
9484 /* 7.7.19.3 */
9485 { &hf_oran_se19_repetition,
9486 { "repetition", "oran_fh_cus.repetition",
9487 FT_BOOLEAN, BASE_NONE,
9488 TFS(&repetition_se19_tfs)((0 ? (const struct true_false_string*)0 : ((&repetition_se19_tfs
))))
, 0x0,
9489 "repeat port info flag", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9490 },
9491 /* 7.7.19.8 */
9492 /* TODO: break down into each RE as done for 7.5.3.5 ? */
9493 { &hf_oran_portReMask,
9494 { "portReMask", "oran_fh_cus.portReMask",
9495 FT_BOOLEAN, 16,
9496 TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, 0x0fff,
9497 "RE bitmask per port", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9498 },
9499 /* 7.7.19.9 */
9500 { &hf_oran_portSymbolMask,
9501 { "portSymbolMask", "oran_fh_cus.portSymbolMask",
9502 FT_BOOLEAN, 16,
9503 TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, 0x3fff,
9504 "Symbol bitmask port port", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9505 },
9506
9507 { &hf_oran_ext19_port,
9508 {"Port", "oran_fh_cus.ext19.port",
9509 FT_STRING, BASE_NONE,
9510 NULL((void*)0), 0x0,
9511 "Entry for a given port in ext19", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9512 },
9513
9514 /* Ext 13 */
9515 { &hf_oran_prb_allocation,
9516 {"PRB allocation", "oran_fh_cus.prb-allocation",
9517 FT_STRING, BASE_NONE,
9518 NULL((void*)0), 0x0,
9519 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9520 },
9521 /* 7.7.13.2 */
9522 { &hf_oran_nextSymbolId,
9523 { "nextSymbolId", "oran_fh_cus.nextSymbolId",
9524 FT_UINT8, BASE_DEC,
9525 NULL((void*)0), 0x3c,
9526 "offset of PRB range start", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9527 },
9528 /* 7.7.13.3 */
9529 { &hf_oran_nextStartPrbc,
9530 { "nextStartPrbc", "oran_fh_cus.nextStartPrbc",
9531 FT_UINT16, BASE_DEC,
9532 NULL((void*)0), 0x03ff,
9533 "number of PRBs in PRB range", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9534 },
9535
9536 /* Puncturing patters as appears in SE 20 */
9537 { &hf_oran_puncPattern,
9538 { "puncPattern", "oran_fh_cus.puncPattern",
9539 FT_STRING, BASE_NONE,
9540 NULL((void*)0), 0x0,
9541 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9542 },
9543
9544 /* 7.7.20.2 numPuncPatterns */
9545 { &hf_oran_numPuncPatterns,
9546 { "numPuncPatterns", "oran_fh_cus.numPuncPatterns",
9547 FT_UINT8, BASE_DEC,
9548 NULL((void*)0), 0x0,
9549 "number of puncturing patterns", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9550 },
9551 /* 7.7.20.3 symbolMask */
9552 { &hf_oran_symbolMask_ext20,
9553 { "symbolMask", "oran_fh_cus.symbolMask",
9554 FT_UINT16, BASE_HEX,
9555 NULL((void*)0), 0xfffc,
9556 "Bitmask where each bit indicates the symbols associated with the puncturing pattern", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9557 },
9558 /* 7.7.20.4 startPuncPrb */
9559 { &hf_oran_startPuncPrb,
9560 { "startPuncPrb", "oran_fh_cus.startPuncPrb",
9561 FT_UINT16, BASE_DEC,
9562 NULL((void*)0), 0x03ff,
9563 "starting PRB to which one puncturing pattern applies", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9564 },
9565 /* 7.7.20.5 numPuncPrb */
9566 { &hf_oran_numPuncPrb,
9567 { "numPuncPrb", "oran_fh_cus.numPuncPrb",
9568 FT_UINT8, BASE_DEC,
9569 NULL((void*)0), 0x0,
9570 "the number of PRBs of the puncturing pattern", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9571 },
9572 /* 7.7.20.6 puncReMask */
9573 { &hf_oran_puncReMask,
9574 { "puncReMask", "oran_fh_cus.puncReMask",
9575 FT_UINT16, BASE_DEC,
9576 NULL((void*)0), 0xffc0,
9577 "puncturing pattern RE mask", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9578 },
9579 /* 7.7.20.12 multiSDScope */
9580 { &hf_oran_multiSDScope,
9581 { "multiSDScope", "oran_fh_cus.multiSDScope",
9582 FT_BOOLEAN, 8,
9583 TFS(&multi_sd_scope_tfs)((0 ? (const struct true_false_string*)0 : ((&multi_sd_scope_tfs
))))
, 0x02,
9584 "multiple section description scope flag", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9585 },
9586 /* 7.7.20.4 rbgIncl */
9587 { &hf_oran_RbgIncl,
9588 { "rbgIncl", "oran_fh_cus.rbgIncl",
9589 FT_BOOLEAN, 8,
9590 NULL((void*)0), 0x01,
9591 "rbg included flag", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9592 },
9593
9594 /* 7.7.21.2 ciPrbGroupSize */
9595 { &hf_oran_ci_prb_group_size,
9596 { "ciPrbGroupSize", "oran_fh_cus.ciPrbGroupSize",
9597 FT_UINT8, BASE_DEC,
9598 NULL((void*)0), 0x0,
9599 "channel information PRB group size", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9600 },
9601 /* 7.21.3 */
9602 { &hf_oran_prg_size_st5,
9603 { "prgSize", "oran_fh_cus.prgSize",
9604 FT_UINT8, BASE_DEC,
9605 VALS(prg_size_st5_vals)((0 ? (const struct _value_string*)0 : ((prg_size_st5_vals)))
)
, 0x03,
9606 "precoding resource block group size", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9607 },
9608 { &hf_oran_prg_size_st6,
9609 { "prgSize", "oran_fh_cus.prgSize",
9610 FT_UINT8, BASE_DEC,
9611 VALS(prg_size_st6_vals)((0 ? (const struct _value_string*)0 : ((prg_size_st6_vals)))
)
, 0x03,
9612 "precoding resource block group size", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9613 },
9614
9615 /* 7.7.17.2 numUeID */
9616 { &hf_oran_num_ueid,
9617 { "numUeID", "oran_fh_cus.numUeID",
9618 FT_UINT8, BASE_DEC,
9619 NULL((void*)0), 0x0,
9620 "number of ueIDs per user", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9621 },
9622
9623 /* 7.7.16.2 antMask */
9624 { &hf_oran_antMask,
9625 { "antMask", "oran_fh_cus.antMask",
9626 FT_UINT64, BASE_HEX,
9627 NULL((void*)0), 0xffffffffffffffff,
9628 "indices of antennas to be pre-combined per RX endpoint", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9629 },
9630
9631 /* 7.7.18.2 transmissionWindowOffset */
9632 { &hf_oran_transmissionWindowOffset,
9633 { "transmissionWindowOffset", "oran_fh_cus.transmissionWindowOffset",
9634 FT_UINT16, BASE_DEC,
9635 NULL((void*)0), 0x0,
9636 "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)}
9637 },
9638 /* 7.7.18.3 transmissionWindowSize */
9639 { &hf_oran_transmissionWindowSize,
9640 { "transmissionWindowSize", "oran_fh_cus.transmissionWindowSize",
9641 FT_UINT16, BASE_DEC,
9642 NULL((void*)0), 0x3fff,
9643 "size of the transmission window in resolution µs", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9644 },
9645 /* 7.7.18.4 toT */
9646 { &hf_oran_toT,
9647 { "toT", "oran_fh_cus.toT",
9648 FT_UINT8, BASE_DEC,
9649 VALS(type_of_transmission_vals)((0 ? (const struct _value_string*)0 : ((type_of_transmission_vals
))))
, 0x03,
9650 "type of transmission", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9651 },
9652
9653 /* 7.7.2.2 bfaCompHdr */
9654 { &hf_oran_bfaCompHdr,
9655 { "bfaCompHdr", "oran_fh_cus.bfaCompHdr",
9656 FT_STRING, BASE_NONE,
9657 NULL((void*)0), 0x0,
9658 "beamforming attributes compression header", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9659 },
9660 /* 7.7.2.2-2: bfAzPtWidth */
9661 { &hf_oran_bfAzPtWidth,
9662 { "bfAzPtWidth", "oran_fh_cus.bfAzPtWidth",
9663 FT_UINT8, BASE_DEC,
9664 VALS(bfa_bw_vals)((0 ? (const struct _value_string*)0 : ((bfa_bw_vals)))), 0x38,
9665 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9666 },
9667 /* 7.7.2.2-3: bfZePtWidth */
9668 { &hf_oran_bfZePtWidth,
9669 { "bfZePtWidth", "oran_fh_cus.bfZePtWidth",
9670 FT_UINT8, BASE_DEC,
9671 VALS(bfa_bw_vals)((0 ? (const struct _value_string*)0 : ((bfa_bw_vals)))), 0x07,
9672 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9673 },
9674 /* 7.7.2.2-4: bfAz3ddWidth */
9675 { &hf_oran_bfAz3ddWidth,
9676 { "bfAz3ddWidth", "oran_fh_cus.bfAz3ddWidth",
9677 FT_UINT8, BASE_DEC,
9678 VALS(bfa_bw_vals)((0 ? (const struct _value_string*)0 : ((bfa_bw_vals)))), 0x38,
9679 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9680 },
9681 /* 7.7.2.2-5: bfZe3ddWidth */
9682 { &hf_oran_bfZe3ddWidth,
9683 { "bfZe3ddWidth", "oran_fh_cus.bfZe3ddWidth",
9684 FT_UINT8, BASE_DEC,
9685 VALS(bfa_bw_vals)((0 ? (const struct _value_string*)0 : ((bfa_bw_vals)))), 0x07,
9686 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9687 },
9688
9689 /* 7.7.2.3 bfAzPt */
9690 { &hf_oran_bfAzPt,
9691 { "bfAzPt", "oran_fh_cus.bfAzPt",
9692 FT_UINT8, BASE_DEC,
9693 NULL((void*)0), 0x0,
9694 "beamforming azimuth pointing parameter", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9695 },
9696 /* 7.7.2.4 bfZePt */
9697 { &hf_oran_bfZePt,
9698 { "bfZePt", "oran_fh_cus.bfZePt",
9699 FT_UINT8, BASE_DEC,
9700 NULL((void*)0), 0x0,
9701 "beamforming zenith pointing parameter", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9702 },
9703 /* 7.7.2.5 bfAz3dd */
9704 { &hf_oran_bfAz3dd,
9705 { "bfAz3dd", "oran_fh_cus.bfAz3dd",
9706 FT_UINT8, BASE_DEC,
9707 NULL((void*)0), 0x0,
9708 "beamforming azimuth beamwidth parameter", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9709 },
9710 /* 7.7.2.6 bfZe3dd */
9711 { &hf_oran_bfZe3dd,
9712 { "bfZe3dd", "oran_fh_cus.bfZe3dd",
9713 FT_UINT8, BASE_DEC,
9714 NULL((void*)0), 0x0,
9715 "beamforming zenith beamwidth parameter", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9716 },
9717
9718 /* 7.7.2.7 bfAzSl */
9719 { &hf_oran_bfAzSl,
9720 { "bfAzSl", "oran_fh_cus.bfAzSl",
9721 FT_UINT8, BASE_DEC,
9722 VALS(sidelobe_suppression_vals)((0 ? (const struct _value_string*)0 : ((sidelobe_suppression_vals
))))
, 0x38,
9723 "beamforming azimuth sidelobe parameter", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9724 },
9725 /* 7.7.2.8 bfZeSl */
9726 { &hf_oran_bfZeSl,
9727 { "bfZeSl", "oran_fh_cus.bfZeSl",
9728 FT_UINT8, BASE_DEC,
9729 VALS(sidelobe_suppression_vals)((0 ? (const struct _value_string*)0 : ((sidelobe_suppression_vals
))))
, 0x07,
9730 "beamforming zenith sidelobe parameter", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9731 },
9732
9733 /* 7.5.2.17 */
9734 { &hf_oran_cmd_scope,
9735 { "cmdScope", "oran_fh_cus.cmdScope",
9736 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
9737 RVALS(cmd_scope_vals)((0 ? (const struct _range_string*)0 : ((cmd_scope_vals)))), 0x0f,
9738 "command scope", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9739 },
9740 /* 7.5.2.18 */
9741 { &hf_oran_number_of_st4_cmds,
9742 { "numberOfST4Cmds", "oran_fh_cus.numberOfST4Cmds",
9743 FT_UINT8, BASE_DEC,
9744 NULL((void*)0), 0x0,
9745 "Number of Section Type 4 commands", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9746 },
9747
9748 { &hf_oran_st4_cmd_header,
9749 { "Command common header", "oran_fh_cus.st4CmdCommonHeader",
9750 FT_STRING, BASE_NONE,
9751 NULL((void*)0), 0x0,
9752 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9753 },
9754
9755 /* 7.5.3.38 */
9756 { &hf_oran_st4_cmd_type,
9757 { "st4CmdType", "oran_fh_cus.st4CmdType",
9758 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
9759 RVALS(st4_cmd_type_vals)((0 ? (const struct _range_string*)0 : ((st4_cmd_type_vals)))
)
, 0x0,
9760 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9761 },
9762 /* 7.5.3.39 */
9763 { &hf_oran_st4_cmd_len,
9764 { "st4CmdLen", "oran_fh_cus.st4CmdLen",
9765 FT_UINT16, BASE_DEC,
9766 NULL((void*)0), 0x0,
9767 "Length of command in 32-bit words", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9768 },
9769 /* 7.5.3.40 */
9770 { &hf_oran_st4_cmd_num_slots,
9771 { "numSlots", "oran_fh_cus.st4NumSlots",
9772 FT_UINT8, BASE_DEC,
9773 NULL((void*)0), 0x0,
9774 "Contiguous slots for which command is applicable", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9775 },
9776 /* 7.5.3.41 */
9777 { &hf_oran_st4_cmd_ack_nack_req_id,
9778 { "ackNackReqId", "oran_fh_cus.ackNackReqId",
9779 FT_UINT16, BASE_DEC,
9780 NULL((void*)0), 0x0,
9781 "ACK/NACK Request Id", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9782 },
9783
9784 { &hf_oran_st4_cmd,
9785 { "Command", "oran_fh_cus.st4Cmd",
9786 FT_STRING, BASE_NONE,
9787 NULL((void*)0), 0x0,
9788 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9789 },
9790
9791 /* 7.5.3.52 */
9792 { &hf_oran_sleepmode_trx,
9793 { "sleepMode", "oran_fh_cus.sleepMode",
9794 FT_UINT8, BASE_HEX,
9795 VALS(sleep_mode_trx_vals)((0 ? (const struct _value_string*)0 : ((sleep_mode_trx_vals)
)))
, 0x03,
9796 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9797 },
9798 { &hf_oran_sleepmode_asm,
9799 { "sleepMode", "oran_fh_cus.sleepMode",
9800 FT_UINT8, BASE_HEX,
9801 VALS(sleep_mode_asm_vals)((0 ? (const struct _value_string*)0 : ((sleep_mode_asm_vals)
)))
, 0x03,
9802 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9803 },
9804
9805 /* 7.5.3.51 */
9806 { &hf_oran_log2maskbits,
9807 { "log2MaskBits", "oran_fh_cus.log2MaskBits",
9808 FT_UINT8, BASE_HEX,
9809 VALS(log2maskbits_vals)((0 ? (const struct _value_string*)0 : ((log2maskbits_vals)))
)
, 0x3c,
9810 "Number of bits to appear in antMask", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9811 },
9812 /* 7.5.3.53 */
9813 { &hf_oran_num_slots_ext,
9814 { "numSlotsExt", "oran_fh_cus.numSlotsExt",
9815 FT_UINT24, BASE_HEX,
9816 NULL((void*)0), 0x0fffff,
9817 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9818 },
9819 /* 7.5.3.54 */
9820 { &hf_oran_antMask_trx_control,
9821 { "antMask", "oran_fh_cus.trxControl.antMask",
9822 FT_BYTES, BASE_NONE,
9823 NULL((void*)0), 0x0,
9824 "which antennas should sleep or wake-up", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9825 },
9826 /* 7.5.3.55 */
9827 { &hf_oran_ready,
9828 { "ready", "oran_fh_cus.ready",
9829 FT_BOOLEAN, 8,
9830 TFS(&ready_tfs)((0 ? (const struct true_false_string*)0 : ((&ready_tfs))
))
, 0x01,
9831 "wake-up ready indicator", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9832 },
9833 /* 7.5.3.34 */
9834 { &hf_oran_number_of_acks,
9835 { "numberOfAcks", "oran_fh_cus.numberOfAcks",
9836 FT_UINT8, BASE_DEC,
9837 NULL((void*)0), 0x0,
9838 "number of ACKs for one eAxC_ID", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9839 },
9840 /* 7.5.3.35 */
9841 { &hf_oran_number_of_nacks,
9842 { "numberOfNacks", "oran_fh_cus.numberOfNacks",
9843 FT_UINT8, BASE_DEC,
9844 NULL((void*)0), 0x0,
9845 "number of NACKs for one eAxC_ID", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9846 },
9847 /* 7.5.3.36 */
9848 { &hf_oran_ackid,
9849 { "ackId", "oran_fh_cus.ackId",
9850 FT_UINT16, BASE_DEC,
9851 NULL((void*)0), 0x0,
9852 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9853 },
9854 /* 7.5.3.37 */
9855 { &hf_oran_nackid,
9856 { "nackId", "oran_fh_cus.nackId",
9857 FT_UINT16, BASE_DEC,
9858 NULL((void*)0), 0x0,
9859 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9860 },
9861
9862 /* Links between acknack requests & responses */
9863 { &hf_oran_acknack_request_frame,
9864 { "Request Frame", "oran_fh_cus.ackNackId.request-frame",
9865 FT_FRAMENUM, BASE_NONE,
9866 FRAMENUM_TYPE(FT_FRAMENUM_REQUEST)((gpointer) (glong) (FT_FRAMENUM_REQUEST)), 0x0,
9867 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9868 },
9869 { &hf_oran_acknack_request_time,
9870 { "Time since request in ms", "oran_fh_cus.ackNackId.time-since-request",
9871 FT_UINT32, BASE_DEC,
9872 NULL((void*)0), 0x0,
9873 "Time between request and response", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9874 },
9875 { &hf_oran_acknack_request_type,
9876 { "Request Type", "oran_fh_cus.ackNackId.request-type",
9877 FT_UINT32, BASE_DEC,
9878 VALS(acknack_type_vals)((0 ? (const struct _value_string*)0 : ((acknack_type_vals)))
)
, 0x0,
9879 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9880 },
9881 { &hf_oran_acknack_response_frame,
9882 { "Response Frame", "oran_fh_cus.ackNackId.response-frame",
9883 FT_FRAMENUM, BASE_NONE,
9884 FRAMENUM_TYPE(FT_FRAMENUM_RESPONSE)((gpointer) (glong) (FT_FRAMENUM_RESPONSE)), 0x0,
9885 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9886 },
9887 { &hf_oran_acknack_response_time,
9888 { "Time to response in ms", "oran_fh_cus.ackNackId.time-to-response",
9889 FT_UINT32, BASE_DEC,
9890 NULL((void*)0), 0x0,
9891 "Time between request and response", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9892 },
9893
9894 /* 7.5.3.43 */
9895 { &hf_oran_disable_tdbfns,
9896 { "disableTDBFNs", "oran_fh_cus.disableTDBFNs",
9897 FT_BOOLEAN, 8,
9898 TFS(&disable_tdbfns_tfs)((0 ? (const struct true_false_string*)0 : ((&disable_tdbfns_tfs
))))
, 0x80,
9899 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9900 },
9901
9902 /* 7.5.3.44 */
9903 { &hf_oran_td_beam_group,
9904 { "tdBeamGrp", "oran_fh_cus.tdBeamGrp",
9905 FT_UINT16, BASE_HEX,
9906 NULL((void*)0), 0x7fff,
9907 "Applies to symbolMask in command header", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9908 },
9909 /* 7.5.3.43 */
9910 { &hf_oran_disable_tdbfws,
9911 { "disableTDBFWs", "oran_fh_cus.disableTDBFWs",
9912 FT_BOOLEAN, 8,
9913 TFS(&beam_numbers_included_tfs)((0 ? (const struct true_false_string*)0 : ((&beam_numbers_included_tfs
))))
, 0x80,
9914 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9915 },
9916
9917 /* 7.5.3.56 */
9918 { &hf_oran_td_beam_num,
9919 { "tdBeamNum", "oran_fh_cus.tdBeamNum",
9920 FT_UINT16, BASE_HEX,
9921 NULL((void*)0), 0x7fff,
9922 "time-domain beam number", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9923 },
9924
9925 /* 7.5.3.49 */
9926 { &hf_oran_dir_pattern,
9927 { "dirPattern", "oran_fh_cus.dirPattern",
9928 FT_BOOLEAN, 16,
9929 TFS(&symbol_direction_tfs)((0 ? (const struct true_false_string*)0 : ((&symbol_direction_tfs
))))
, 0x3fff,
9930 "symbol data direction (gNB Tx/Rx) pattern", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9931 },
9932 /* 7.5.3.50 */
9933 { &hf_oran_guard_pattern,
9934 { "guardPattern", "oran_fh_cus.guardPattern",
9935 FT_BOOLEAN, 16,
9936 TFS(&symbol_guard_tfs)((0 ? (const struct true_false_string*)0 : ((&symbol_guard_tfs
))))
, 0x3fff,
9937 "guard pattern bitmask", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9938 },
9939
9940 /* For convenient filtering */
9941 { &hf_oran_cplane,
9942 { "C-Plane", "oran_fh_cus.c-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_uplane,
9948 { "U-Plane", "oran_fh_cus.u-plane",
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_bf,
9954 { "BeamForming", "oran_fh_cus.bf",
9955 FT_NONE, BASE_NONE,
9956 NULL((void*)0), 0x0,
9957 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9958 },
9959 { &hf_oran_zero_prb,
9960 { "Zero PRB", "oran_fh_cus.zero-prb",
9961 FT_NONE, BASE_NONE,
9962 NULL((void*)0), 0x0,
9963 "All of the REs in this PRB are zero", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9964 },
9965 { &hf_oran_nonzero_prb,
9966 { "Non-Zero PRB", "oran_fh_cus.nonzero-prb",
9967 FT_NONE, BASE_NONE,
9968 NULL((void*)0), 0x0,
9969 "Not all of the REs in this PRB are zero", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9970 },
9971 { &hf_oran_bundle_weights_all_zero,
9972 { "Bundle Weights all zero", "oran_fh_cus.zero-bundle",
9973 FT_NONE, BASE_NONE,
9974 NULL((void*)0), 0x0,
9975 "All of the weights in a bundle are zero", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9976 },
9977
9978
9979 /* 5.1.3.2.7 */
9980 { &hf_oran_ecpri_pcid,
9981 { "ecpriPcid", "oran_fh_cus.ecpriPcid",
9982 FT_NONE, BASE_NONE,
9983 NULL((void*)0), 0x0,
9984 "IQ data transfer message series identifier", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9985 },
9986 { &hf_oran_ecpri_rtcid,
9987 { "ecpriRtcid", "oran_fh_cus.ecpriRtcid",
9988 FT_NONE, BASE_NONE,
9989 NULL((void*)0), 0x0,
9990 "Real time control data identifier", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9991 },
9992 /* 5.1.3.2.8 */
9993 { &hf_oran_ecpri_seqid,
9994 { "ecpriSeqid", "oran_fh_cus.ecpriSeqid",
9995 FT_NONE, BASE_NONE,
9996 NULL((void*)0), 0x0,
9997 "message identifier", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9998 },
9999
10000 /* 7.7.23.2 */
10001 { &hf_oran_num_sym_prb_pattern,
10002 { "numSymPrbPattern", "oran_fh_cus.numSymPrbPattern",
10003 FT_UINT8, BASE_DEC,
10004 NULL((void*)0), 0xf0,
10005 "number of symbol and resource block patterns", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10006 },
10007 /* 7.7.23.11 */
10008 { &hf_oran_prb_mode,
10009 { "prbMode", "oran_fh_cus.prbMode",
10010 FT_BOOLEAN, 8,
10011 TFS(&prb_mode_tfs)((0 ? (const struct true_false_string*)0 : ((&prb_mode_tfs
))))
, 0x01,
10012 "PRB Mode", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10013 },
10014
10015 { &hf_oran_sym_prb_pattern,
10016 { "symPrbPattern", "oran_fh_cus.symPrbPattern",
10017 FT_STRING, BASE_NONE,
10018 NULL((void*)0), 0x0,
10019 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10020 },
10021
10022 /* 7.7.23.3 */
10023 { &hf_oran_sym_mask,
10024 { "symMask", "oran_fh_cus.symMask",
10025 FT_UINT16, BASE_HEX,
10026 NULL((void*)0), 0x3fff,
10027 "symbol mask part of symPrbPattern", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10028 },
10029 /* 7.7.23.5 */
10030 {&hf_oran_num_mc_scale_offset,
10031 {"numMcScaleOffset", "oran_fh_cus.numMcScaleOffset",
10032 FT_UINT8, BASE_DEC,
10033 NULL((void*)0), 0xf0,
10034 "number of modulation compression scaling value per symPrbPattern",
10035 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10036 },
10037 /* 7.7.23.4 */
10038 { &hf_oran_prb_pattern,
10039 { "prbPattern", "oran_fh_cus.prbPattern",
10040 FT_UINT8, BASE_DEC,
10041 NULL((void*)0), 0x0f,
10042 "resource block pattern part of symPrbPattern", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10043 },
10044
10045 /* 7.7.3.2 */
10046 { &hf_oran_codebook_index,
10047 { "codebookIndex", "oran_fh_cus.codebookIndex",
10048 FT_UINT8, BASE_DEC,
10049 NULL((void*)0), 0x0,
10050 "precoder codebook used for transmission", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10051 },
10052 /* 7.7.3.3 */
10053 { &hf_oran_layerid,
10054 { "layerID", "oran_fh_cus.layerID",
10055 FT_UINT8, BASE_DEC,
10056 NULL((void*)0), 0xf0,
10057 "Layer ID for DL transmission", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10058 },
10059 /* 7.7.3.5 */
10060 { &hf_oran_numlayers,
10061 { "numLayers", "oran_fh_cus.numLayers",
10062 FT_UINT8, BASE_DEC,
10063 NULL((void*)0), 0x0f,
10064 "number of layers for DL transmission", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10065 },
10066 /* 7.7.3.4 */
10067 { &hf_oran_txscheme,
10068 { "txScheme", "oran_fh_cus.txScheme",
10069 FT_UINT8, BASE_DEC,
10070 NULL((void*)0), 0xf0,
10071 "transmission scheme", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10072 },
10073 /* 7.7.3.6 */
10074 { &hf_oran_crs_remask,
10075 { "crsReMask", "oran_fh_cus.crsReMask",
10076 FT_UINT16, BASE_HEX,
10077 NULL((void*)0), 0x0fff,
10078 "CRS resource element mask", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10079 },
10080 /* 7.7.3.8 */
10081 { &hf_oran_crs_shift,
10082 { "crsShift", "oran_fh_cus.crsShift",
10083 FT_UINT8, BASE_HEX,
10084 NULL((void*)0), 0x80,
10085 "CRS resource element mask", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10086 },
10087 /* 7.7.3.7 */
10088 { &hf_oran_crs_symnum,
10089 { "crsSymNum", "oran_fh_cus.crsSymNum",
10090 FT_UINT8, BASE_DEC,
10091 NULL((void*)0), 0x0f,
10092 "CRS symbol number indication", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10093 },
10094 /* 7.7.3.9 */
10095 { &hf_oran_beamid_ap1,
10096 { "beamIdAP1", "oran_fh_cus.beamIdAP1",
10097 FT_UINT16, BASE_DEC,
10098 NULL((void*)0), 0x7f,
10099 "beam id to be used for antenna port 1", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10100 },
10101 /* 7.7.3.10 */
10102 { &hf_oran_beamid_ap2,
10103 { "beamIdAP2", "oran_fh_cus.beamIdAP2",
10104 FT_UINT16, BASE_DEC,
10105 NULL((void*)0), 0x7f,
10106 "beam id to be used for antenna port 2", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10107 },
10108 /* 7.7.3.11 */
10109 { &hf_oran_beamid_ap3,
10110 { "beamIdAP3", "oran_fh_cus.beamIdAP3",
10111 FT_UINT16, BASE_DEC,
10112 NULL((void*)0), 0x7f,
10113 "beam id to be used for antenna port 3", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10114 },
10115
10116 /* 7.7.10.3a */
10117 { &hf_oran_port_list_index,
10118 { "portListIndex", "oran_fh_cus.portListIndex",
10119 FT_UINT8, BASE_DEC,
10120 NULL((void*)0), 0x0,
10121 "the index of an eAxC_ID in the port-list", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10122 },
10123
10124 { &hf_oran_alpn_per_sym,
10125 { "alpnPerSym", "oran_fh_cus.alpnPerSym",
10126 FT_UINT8, BASE_HEX,
10127 VALS(alpn_per_sym_vals)((0 ? (const struct _value_string*)0 : ((alpn_per_sym_vals)))
)
, 0x80,
10128 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10129 },
10130 { &hf_oran_ant_dmrs_snr,
10131 { "antDmrsSnr", "oran_fh_cus.antDmrsSnr",
10132 FT_UINT8, BASE_HEX,
10133 VALS(ant_dmrs_snr_vals)((0 ? (const struct _value_string*)0 : ((ant_dmrs_snr_vals)))
)
, 0x40,
10134 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10135 },
10136
10137 /* 7.7.24.6 */
10138 { &hf_oran_user_group_size,
10139 { "userGroupSize", "oran_fh_cus.userGroupSize",
10140 FT_UINT8, BASE_DEC,
10141 NULL((void*)0), 0x1f,
10142 "number of UE data layers in the user group identified by userGroupId", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10143 },
10144 /* 7.7.24.7 */
10145 { &hf_oran_user_group_id,
10146 { "userGroupId", "oran_fh_cus.userGroupId",
10147 FT_UINT8, BASE_DEC,
10148 NULL((void*)0), 0x0,
10149 "indicates user group described by the section", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10150 },
10151 /* 7.7.24.8 */
10152 { &hf_oran_entry_type,
10153 { "entryType", "oran_fh_cus.entryType",
10154 FT_UINT8, BASE_DEC,
10155 VALS(entry_type_vals)((0 ? (const struct _value_string*)0 : ((entry_type_vals)))), 0xe0,
10156 "indicates format of the entry", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10157 },
10158 /* 7.7.24.9 */
10159 { &hf_oran_dmrs_port_number,
10160 { "dmrsPortNumber", "oran_fh_cus.dmrsPortNumber",
10161 FT_UINT8, BASE_DEC,
10162 NULL((void*)0), 0x1f,
10163 "DMRS antenna port number for the associated ueId", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10164 },
10165 /* 7.7.24.10 */
10166 { &hf_oran_ueid_reset,
10167 { "ueidReset", "oran_fh_cus.ueidReset",
10168 FT_BOOLEAN, 8,
10169 TFS(&tfs_ueid_reset)((0 ? (const struct true_false_string*)0 : ((&tfs_ueid_reset
))))
, 0x80,
10170 "same UEID as the previous slot", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10171 },
10172 /* 7.7.24.11 */
10173 { &hf_oran_dmrs_symbol_mask,
10174 { "dmrsSymbolMask", "oran_fh_cus.dmrsSymbolMask",
10175 FT_UINT16, BASE_HEX,
10176 NULL((void*)0), 0x3fff,
10177 "symbols within the slot containing DMRS", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10178 },
10179 { &hf_oran_dmrs_symbol_mask_s13,
10180 { "symbol 13", "oran_fh_cus.dmrsSymbolMask.symbol-13",
10181 FT_BOOLEAN, 16,
10182 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x2000,
10183 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10184 },
10185 { &hf_oran_dmrs_symbol_mask_s12,
10186 { "symbol 12", "oran_fh_cus.dmrsSymbolMask.symbol-12",
10187 FT_BOOLEAN, 16,
10188 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x1000,
10189 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10190 },
10191 { &hf_oran_dmrs_symbol_mask_s11,
10192 { "symbol 11", "oran_fh_cus.dmrsSymbolMask.symbol-11",
10193 FT_BOOLEAN, 16,
10194 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0800,
10195 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10196 },
10197 { &hf_oran_dmrs_symbol_mask_s10,
10198 { "symbol 10", "oran_fh_cus.dmrsSymbolMask.symbol-10",
10199 FT_BOOLEAN, 16,
10200 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0400,
10201 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10202 },
10203 { &hf_oran_dmrs_symbol_mask_s9,
10204 { "symbol 9", "oran_fh_cus.dmrsSymbolMask.symbol-9",
10205 FT_BOOLEAN, 16,
10206 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0200,
10207 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10208 },
10209 { &hf_oran_dmrs_symbol_mask_s8,
10210 { "symbol 8", "oran_fh_cus.dmrsSymbolMask.symbol-8",
10211 FT_BOOLEAN, 16,
10212 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0100,
10213 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10214 },
10215 { &hf_oran_dmrs_symbol_mask_s7,
10216 { "symbol 7", "oran_fh_cus.dmrsSymbolMask.symbol-7",
10217 FT_BOOLEAN, 16,
10218 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0080,
10219 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10220 },
10221 { &hf_oran_dmrs_symbol_mask_s6,
10222 { "symbol 6", "oran_fh_cus.dmrsSymbolMask.symbol-6",
10223 FT_BOOLEAN, 16,
10224 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0040,
10225 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10226 },
10227 { &hf_oran_dmrs_symbol_mask_s5,
10228 { "symbol 5", "oran_fh_cus.dmrsSymbolMask.symbol-5",
10229 FT_BOOLEAN, 16,
10230 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0020,
10231 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10232 },
10233 { &hf_oran_dmrs_symbol_mask_s4,
10234 { "symbol 4", "oran_fh_cus.dmrsSymbolMask.symbol-4",
10235 FT_BOOLEAN, 16,
10236 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0010,
10237 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10238 },
10239 { &hf_oran_dmrs_symbol_mask_s3,
10240 { "symbol 3", "oran_fh_cus.dmrsSymbolMask.symbol-3",
10241 FT_BOOLEAN, 16,
10242 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0008,
10243 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10244 },
10245 { &hf_oran_dmrs_symbol_mask_s2,
10246 { "symbol 2", "oran_fh_cus.dmrsSymbolMask.symbol-2",
10247 FT_BOOLEAN, 16,
10248 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0004,
10249 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10250 },
10251 { &hf_oran_dmrs_symbol_mask_s1,
10252 { "symbol 1", "oran_fh_cus.dmrsSymbolMask.symbol-1",
10253 FT_BOOLEAN, 16,
10254 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0002,
10255 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10256 },
10257 { &hf_oran_dmrs_symbol_mask_s0,
10258 { "symbol 0", "oran_fh_cus.dmrsSymbolMask.symbol-0",
10259 FT_BOOLEAN, 16,
10260 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0001,
10261 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10262 },
10263
10264 /* 7.7.24.12 */
10265 { &hf_oran_scrambling,
10266 { "scrambling", "oran_fh_cus.scrambling",
10267 FT_UINT16, BASE_HEX,
10268 NULL((void*)0), 0x0,
10269 "used to calculate the seed value required to initialize pseudo-random generator", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10270 },
10271 /* 7.7.24.13 */
10272 { &hf_oran_nscid,
10273 { "nscid", "oran_fh_cus.nscid",
10274 FT_UINT8, BASE_HEX,
10275 NULL((void*)0), 0x80,
10276 "used to calculate the seed value for pseudo-random generator", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10277 },
10278 /* 7.7.24.14 */
10279 { &hf_oran_dtype,
10280 { "dType", "oran_fh_cus.dType",
10281 FT_UINT8, BASE_HEX,
10282 VALS(dtype_vals)((0 ? (const struct _value_string*)0 : ((dtype_vals)))), 0x40,
10283 "PUSCH DMRS configuration type", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10284 },
10285 /* 7.7.24.15 */
10286 { &hf_oran_cmd_without_data,
10287 { "cmdWithoutData", "oran_fh_cus.cmdWithoutData",
10288 FT_UINT8, BASE_HEX,
10289 NULL((void*)0), 0x30,
10290 "number of DMRS CDM groups without data", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10291 },
10292 /* 7.7.24.16 */
10293 { &hf_oran_lambda,
10294 { "lambda", "oran_fh_cus.lambda",
10295 FT_UINT8, BASE_HEX,
10296 NULL((void*)0), 0x0c,
10297 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10298 },
10299 /* 7.7.24.19 */
10300 { &hf_oran_first_prb,
10301 { "firstPrb", "oran_fh_cus.firstPrb",
10302 FT_UINT16, BASE_DEC,
10303 NULL((void*)0), 0x03fe,
10304 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10305 },
10306 /* 7.7.24.20 */
10307 { &hf_oran_last_prb,
10308 { "lastPrb", "oran_fh_cus.lastPrb",
10309 FT_UINT16, BASE_DEC,
10310 NULL((void*)0), 0x01ff,
10311 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10312 },
10313
10314 /* 7.7.24.17 */
10315 /* TODO: add value_string */
10316 { &hf_oran_low_papr_type,
10317 { "lowPaprType", "oran_fh_cus.lowPaprType",
10318 FT_UINT8, BASE_HEX,
10319 VALS(papr_type_vals)((0 ? (const struct _value_string*)0 : ((papr_type_vals)))), 0x30,
10320 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10321 },
10322 /* 7.7.24.18 */
10323 { &hf_oran_hopping_mode,
10324 { "hoppingMode", "oran_fh_cus.hoppingMode",
10325 FT_UINT8, BASE_HEX,
10326 VALS(hopping_mode_vals)((0 ? (const struct _value_string*)0 : ((hopping_mode_vals)))
)
, 0x0c,
10327 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10328 },
10329
10330 { &hf_oran_tx_win_for_on_air_symbol_l,
10331 { "txWinForOnAirSymbol", "oran_fh_cus.txWinForOnAirSymbol",
10332 FT_UINT8, BASE_DEC,
10333 NULL((void*)0), 0xf0,
10334 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10335 },
10336 { &hf_oran_tx_win_for_on_air_symbol_r,
10337 { "txWinForOnAirSymbol", "oran_fh_cus.txWinForOnAirSymbol",
10338 FT_UINT8, BASE_DEC,
10339 NULL((void*)0), 0x0f,
10340 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10341 },
10342 /* 7.7.26.2 */
10343 { &hf_oran_num_fo_fb,
10344 { "numFoFb", "oran_fh_cus.numFoFb",
10345 FT_UINT8, BASE_DEC,
10346 NULL((void*)0), 0x7f,
10347 "number of frequency offset feedback", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10348 },
10349 /* 7.7.26.3 */
10350 { &hf_oran_freq_offset_fb,
10351 { "freqOffsetFb", "oran_fh_cus.freqOffsetFb",
10352 FT_UINT16, BASE_HEX_DEC | BASE_RANGE_STRING0x00000100,
10353 RVALS(freq_offset_fb_values)((0 ? (const struct _range_string*)0 : ((freq_offset_fb_values
))))
, 0x0,
10354 "UE frequency offset feedback", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10355 },
10356
10357 /* 7.7.28.2 */
10358 { &hf_oran_num_ue_sinr_rpt,
10359 { "numUeSinrRpt", "oran_fh_cus.numUeSinrRpt",
10360 FT_UINT8, BASE_DEC,
10361 NULL((void*)0), 0x1f,
10362 "number of sinr reported UEs {1 - 12}", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10363 },
10364
10365 /* 7.5.2.19 */
10366 { &hf_oran_num_sinr_per_prb,
10367 { "numSinrPerPrb", "oran_fh_cus.numSinrPerPrb",
10368 FT_UINT8, BASE_DEC,
10369 VALS(num_sinr_per_prb_vals)((0 ? (const struct _value_string*)0 : ((num_sinr_per_prb_vals
))))
, 0x70,
10370 "number of SINR values per PRB", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10371 },
10372 { &hf_oran_num_sinr_per_prb_right,
10373 { "numSinrPerPrb", "oran_fh_cus.numSinrPerPrb",
10374 FT_UINT8, BASE_DEC,
10375 VALS(num_sinr_per_prb_vals)((0 ? (const struct _value_string*)0 : ((num_sinr_per_prb_vals
))))
, 0x07,
10376 "number of SINR values per PRB", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10377 },
10378
10379 /* 7.5.3.68 */
10380 { &hf_oran_sinr_value,
10381 { "sinrValue", "oran_fh_cus.sinrValue",
10382 FT_FLOAT, BASE_NONE,
10383 NULL((void*)0), 0x0,
10384 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10385 },
10386
10387 { &hf_oran_measurement_report,
10388 { "Measurement Report", "oran_fh_cus.measurement-report",
10389 FT_STRING, BASE_NONE,
10390 NULL((void*)0), 0x0,
10391 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10392 },
10393 /* 7.5.3.57 */
10394 { &hf_oran_mf,
10395 { "mf", "oran_fh_cus.mf",
10396 FT_BOOLEAN, 8,
10397 TFS(&measurement_flag_tfs)((0 ? (const struct true_false_string*)0 : ((&measurement_flag_tfs
))))
, 0x80,
10398 "measurement flag", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10399 },
10400 /* 7.5.3.59 */
10401 { &hf_oran_meas_data_size,
10402 { "measDataSize", "oran_fh_cus.measDataSize",
10403 FT_UINT16, BASE_DEC,
10404 NULL((void*)0), 0x0,
10405 "measurement data size (in words)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10406 },
10407
10408 /* 7.5.3.58 */
10409 { &hf_oran_meas_type_id,
10410 { "measTypeId", "oran_fh_cus.measTypeId",
10411 FT_UINT8, BASE_DEC,
10412 VALS(meas_type_id_vals)((0 ? (const struct _value_string*)0 : ((meas_type_id_vals)))
)
, 0x7F,
10413 "measurement report type identifier", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10414 },
10415 /* 7.5.3.66 */
10416 { &hf_oran_num_elements,
10417 { "numElements", "oran_fh_cus.numElements",
10418 FT_UINT8, BASE_DEC,
10419 NULL((void*)0), 0x0,
10420 "measurement report type identifier", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10421 },
10422 /* 7.5.3.60 */
10423 { &hf_oran_ue_tae,
10424 { "ueTae", "oran_fh_cus.ueTae",
10425 FT_UINT16, BASE_DEC | BASE_RANGE_STRING0x00000100,
10426 RVALS(freq_offset_fb_values)((0 ? (const struct _range_string*)0 : ((freq_offset_fb_values
))))
, 0x0,
10427 "UE Timing Advance Error", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10428 },
10429 /* 7.5.3.61 */
10430 { &hf_oran_ue_layer_power,
10431 { "ueLayerPower", "oran_fh_cus.ueLayerPower",
10432 FT_UINT16, BASE_DEC | BASE_RANGE_STRING0x00000100,
10433 RVALS(freq_offset_fb_values)((0 ? (const struct _range_string*)0 : ((freq_offset_fb_values
))))
, 0x0,
10434 "UE Layer Power", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10435 },
10436
10437 /* 7.5.3.62 */
10438 { &hf_oran_ue_freq_offset,
10439 { "ueFreqOffset", "oran_fh_cus.ueFreqOffset",
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 frequency offset", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10443 },
10444 /* 7.5.3.63 */
10445 { &hf_oran_ipn_power,
10446 { "ipnPower", "oran_fh_cus.ipnPower",
10447 FT_UINT16, BASE_DEC | BASE_RANGE_STRING0x00000100,
10448 RVALS(freq_offset_fb_values)((0 ? (const struct _range_string*)0 : ((freq_offset_fb_values
))))
, 0x0,
10449 "Interference plus Noise power", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10450 },
10451 /* 7.5.3.64 */
10452 { &hf_oran_ant_dmrs_snr_val,
10453 { "antDmrsSnrVal", "oran_fh_cus.antDmrsSnrVal",
10454 FT_UINT16, BASE_DEC | BASE_RANGE_STRING0x00000100,
10455 RVALS(freq_offset_fb_values)((0 ? (const struct _range_string*)0 : ((freq_offset_fb_values
))))
, 0x0,
10456 "antenna DMRS-SNR", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10457 },
10458
10459 { &hf_oran_measurement_command,
10460 { "Measurement Command", "oran_fh_cus.measurement-command",
10461 FT_STRING, BASE_NONE,
10462 NULL((void*)0), 0x0,
10463 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10464 },
10465
10466 /* 7.5.27.2 */
10467 { &hf_oran_beam_type,
10468 {"beamType", "oran_fh_cus.beamType",
10469 FT_UINT16, BASE_DEC,
10470 VALS(beam_type_vals)((0 ? (const struct _value_string*)0 : ((beam_type_vals)))), 0xc0,
10471 NULL((void*)0),
10472 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10473 },
10474 /* 7.5.3.65 */
10475 { &hf_oran_meas_cmd_size,
10476 {"measCmdSize", "oran_fh_cus.measCmdSize",
10477 FT_UINT16, BASE_DEC,
10478 NULL((void*)0), 0x0,
10479 "measurement command size in words",
10480 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10481 },
10482
10483 { &hf_oran_symbol_reordering_layer,
10484 { "Layer", "oran_fh_cus.layer",
10485 FT_STRING, BASE_NONE,
10486 NULL((void*)0), 0x0,
10487 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10488 },
10489 { &hf_oran_dmrs_entry,
10490 { "Entry", "oran_fh_cus.dmrs-entry",
10491 FT_STRING, BASE_NONE,
10492 NULL((void*)0), 0x0,
10493 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10494 },
10495
10496 /* 7.7.29.3 */
10497 { &hf_oran_cd_scg_size,
10498 {"cdScgSize", "oran_fh_cus.cdScgSize",
10499 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
10500 RVALS(cd_scg_size_vals)((0 ? (const struct _range_string*)0 : ((cd_scg_size_vals)))), 0x0f,
10501 "Cyclic delay subcarrier group size",
10502 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10503 },
10504 /* 7.7.29.4 */
10505 { &hf_oran_cd_scg_phase_step,
10506 {"cdScgPhaseStep", "oran_fh_cus.cdScgPhaseStep",
10507 FT_INT8, BASE_DEC,
10508 NULL((void*)0), 0x0,
10509 "Cyclic delay subcarrier group phase step",
10510 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10511 },
10512
10513 { &hf_oran_sinr_prb,
10514 { "PRB", "oran_fh_cus.sinr.prb",
10515 FT_STRING, BASE_NONE,
10516 NULL((void*)0), 0x0,
10517 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10518 },
10519 /* 7.5.2.20 */
10520 { &hf_oran_oru_control_sinr_slot_mask_id,
10521 {"oruControlSinrSlotMaskId", "oran_fh_cus.oruControlSinrSlotMaskId",
10522 FT_UINT8, BASE_DEC,
10523 NULL((void*)0), 0x1f,
10524 "SINR time resolution",
10525 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10526 },
10527 /* 7.7.24.21 */
10528 { &hf_oran_pos_meas,
10529 {"posMeas", "oran_fh_cus.posMeas",
10530 FT_BOOLEAN, 8,
10531 TFS(&tfs_report_no_report_pos_meas)((0 ? (const struct true_false_string*)0 : ((&tfs_report_no_report_pos_meas
))))
, 0x40,
10532 "Positioning measurement report request",
10533 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10534 },
10535
10536 /* 7.5.3.69 */
10537 { &hf_oran_ue_radial_speed,
10538 {"ueRadialSpeed", "oran_fh_cus.ueRadialSpeed",
10539 FT_UINT16, BASE_DEC,
10540 NULL((void*)0), 0x0,
10541 "UE radial speed",
10542 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10543 },
10544 /* 7.5.3.70 */
10545 { &hf_oran_ue_az_aoa,
10546 {"ueAzAoa", "oran_fh_cus.ueAzAoa",
10547 FT_UINT16, BASE_DEC,
10548 NULL((void*)0), 0x0,
10549 "UE azimuth angle of arrival",
10550 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10551 },
10552 /* 7.5.3.71 */
10553 { &hf_oran_ue_ze_aoa,
10554 {"ueZeAoa", "oran_fh_cus.ueZeAoa",
10555 FT_UINT16, BASE_DEC,
10556 NULL((void*)0), 0x0,
10557 "UE zenith angle of arrival",
10558 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10559 },
10560 /* 7.5.3.72 */
10561 { &hf_oran_ue_pos_toa_offset,
10562 {"uePosToaOffset", "oran_fh_cus.uePosToaOffset",
10563 FT_UINT16, BASE_DEC,
10564 NULL((void*)0), 0x0,
10565 "UE positioning time of arrival offset",
10566 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10567 },
10568
10569 /* 7.7.30.2 */
10570 { &hf_oran_num_rep_ue,
10571 {"numRepUe", "oran_fh_cus.numRepUe",
10572 FT_UINT8, BASE_DEC,
10573 NULL((void*)0), 0x0f,
10574 "Number of UEs with PUSCH repetition",
10575 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10576 },
10577 /* 7.7.30.3 */
10578 { &hf_oran_rep_ueid,
10579 {"repUeId", "oran_fh_cus.repUeId",
10580 FT_UINT16, BASE_DEC,
10581 NULL((void*)0), 0x7fff,
10582 "UEId the PUSCH is part of",
10583 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10584 },
10585 /* 7.7.30.4 */
10586 { &hf_oran_is_last_rep,
10587 {"isLastRep", "oran_fh_cus.isLastRep",
10588 FT_BOOLEAN, 8,
10589 NULL((void*)0), 0x40,
10590 "Last transmission in the repetition",
10591 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10592 },
10593 /* 7.7.30.5 */
10594 { &hf_oran_rep_index,
10595 {"repIndex", "oran_fh_cus.repIndex",
10596 FT_UINT8, BASE_DEC,
10597 NULL((void*)0), 0x3f,
10598 "Repetition index of the PUSCH transmission",
10599 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10600 },
10601 /* 7.7.30.6 */
10602 { &hf_oran_num_reps,
10603 {"numReps", "oran_fh_cus.numReps",
10604 FT_UINT8, BASE_DEC,
10605 NULL((void*)0), 0x3f,
10606 "The number of total PUSCH repetitions",
10607 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10608 },
10609
10610 /* 7.7.31.2 */
10611 { &hf_oran_mcs_table,
10612 {"mcsTable", "oran_fh_cus.mcsTable",
10613 FT_UINT8, BASE_DEC,
10614 VALS(mcs_table_vals)((0 ? (const struct _value_string*)0 : ((mcs_table_vals)))), 0x0f,
10615 "MCS index table",
10616 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10617 },
10618 /* 7.7.31.3 */
10619 { &hf_oran_mcs_index,
10620 {"mcsIndex", "oran_fh_cus.mcsIndex",
10621 FT_UINT8, BASE_DEC,
10622 NULL((void*)0), 0x3f,
10623 "MCS index value",
10624 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10625 },
10626
10627 /* 7.7.33.3 */
10628 { &hf_oran_num_meas_req,
10629 {"numMeasReq", "oran_fh_cus.numMeasReq",
10630 FT_UINT8, BASE_DEC,
10631 NULL((void*)0), 0x1f,
10632 "Number of UEs for which meas is requested",
10633 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10634 },
10635 /* 7.7.32.5 */
10636 { &hf_oran_ue_rank,
10637 {"ueRank", "oran_fh_cus.ueRank",
10638 FT_UINT8, BASE_DEC,
10639 VALS(ue_rank_vals)((0 ? (const struct _value_string*)0 : ((ue_rank_vals)))), 0x0f,
10640 "Number of UE layers under evaluation",
10641 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10642 },
10643 /* 7.7.32.6 */
10644 { &hf_oran_num_of_ue_ant_ports,
10645 {"numOfUeAntPorts", "oran_fh_cus.numofUeAntPorts",
10646 FT_UINT8, BASE_DEC,
10647 VALS(num_of_ue_ant_ports_vals)((0 ? (const struct _value_string*)0 : ((num_of_ue_ant_ports_vals
))))
, 0xf0,
10648 "Used for the PUSCH tx under evaluation",
10649 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10650 },
10651 /* 7.7.32.8 */
10652 { &hf_oran_codebook_subset,
10653 {"codebookSubset", "oran_fh_cus.codebookSubset",
10654 FT_UINT8, BASE_DEC,
10655 VALS(codebook_subset_vals)((0 ? (const struct _value_string*)0 : ((codebook_subset_vals
))))
, 0xc0,
10656 "UE capability wrt ULTPMI sets",
10657 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10658 },
10659 /* 7.7.32.9 */
10660 { &hf_oran_full_pwr_mode,
10661 {"fullPwrMode", "oran_fh_cus.fullPwrMode",
10662 FT_UINT8, BASE_DEC,
10663 VALS(full_pwr_mode_vals)((0 ? (const struct _value_string*)0 : ((full_pwr_mode_vals))
))
, 0xc0,
10664 "Transmission mode",
10665 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10666 },
10667 /* 7.7.32.10 */
10668 { &hf_oran_full_pwr_mode_2_tpmi_group,
10669 {"fullPwrMode2TpmiGroup", "oran_fh_cus.fullPwrMode2TpmiGroup",
10670 FT_UINT16, BASE_HEX,
10671 NULL((void*)0), 0x3fff,
10672 "Capabilities",
10673 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10674 },
10675
10676 /* 7.5.3.75 */
10677 { &hf_oran_num_cand_ranks,
10678 {"numCandRanks", "oran_fh_cus.numCandRanks",
10679 FT_UINT8, BASE_DEC,
10680 NULL((void*)0), 0xf0,
10681 NULL((void*)0),
10682 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10683 },
10684 /* 7.5.3.76 */
10685 { &hf_oran_ue_pref_rank,
10686 {"uePrefRank", "oran_fh_cus.uePrefRank",
10687 FT_UINT8, BASE_DEC,
10688 NULL((void*)0), 0x0f,
10689 "Most optimal UL Tx rank for UE",
10690 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10691 },
10692 /* 7.5.3.77 */
10693 { &hf_oran_ue_tpmi_rank_y,
10694 {"ueTpmiRankY", "oran_fh_cus.ueTpmiRankY",
10695 FT_UINT8, BASE_DEC,
10696 NULL((void*)0), 0x0,
10697 "TPMI index for codebook-based PUSCH tx",
10698 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10699 },
10700 /* 7.5.3.78 */
10701 { &hf_oran_ue_tpmi_rank_y_sinr_lx,
10702 {"ueTpmiRankYSinrLX", "oran_fh_cus.ueTpmiRankYSinrLX",
10703 FT_UINT16, BASE_HEX | BASE_RANGE_STRING0x00000100,
10704 RVALS(ue_tmpi_rank_sinr_vals)((0 ? (const struct _range_string*)0 : ((ue_tmpi_rank_sinr_vals
))))
, 0x0,
10705 "Estimation of post-equalization SINR",
10706 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10707 },
10708 /* 7.5.3.79 */
10709 { &hf_oran_ue_layer_pre_eq_sinr,
10710 {"ueLayerPreEqSinr", "oran_fh_cus.ueLayerPreEqSinr",
10711 FT_UINT16, BASE_HEX,
10712 NULL((void*)0), 0x0,
10713 "Pre-equalization SINR of a UE layer",
10714 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10715 },
10716
10717 { &hf_oran_c_section_common,
10718 { "Common Section", "oran_fh_cus.c-plane.section.common",
10719 FT_STRING, BASE_NONE,
10720 NULL((void*)0), 0x0,
10721 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10722 },
10723 { &hf_oran_c_section,
10724 { "Section", "oran_fh_cus.c-plane.section",
10725 FT_STRING, BASE_NONE,
10726 NULL((void*)0), 0x0,
10727 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10728 },
10729 { &hf_oran_u_section,
10730 { "Section", "oran_fh_cus.u-plane.section",
10731 FT_STRING, BASE_NONE,
10732 NULL((void*)0), 0x0,
10733 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10734 },
10735
10736 /* Link back to UL C-plane where udCompHdr was recorded */
10737 { &hf_oran_ul_cplane_ud_comp_hdr_frame,
10738 { "C-Plane UL udCompHdr frame", "oran_fh_cus.ul-cplane.udCompHdr",
10739 FT_FRAMENUM, BASE_NONE,
10740 FRAMENUM_TYPE(FT_FRAMENUM_REQUEST)((gpointer) (glong) (FT_FRAMENUM_REQUEST)), 0x0,
10741 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10742 },
10743
10744 /* For ext11, where was a beamId (last) defined? */
10745 { &hf_oran_bfws_frame_defined,
10746 { "Beam defined in frame", "oran_fh_cus.bfw-defined",
10747 FT_FRAMENUM, BASE_NONE,
10748 FRAMENUM_TYPE(FT_FRAMENUM_RETRANS_PREV)((gpointer) (glong) (FT_FRAMENUM_RETRANS_PREV)), 0x0,
10749 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10750 },
10751 { &hf_oran_bfws_symbols_since_defined,
10752 { "Symbols since BFWs defined", "oran_fh_cus.symbols-since-bfw-defined",
10753 FT_UINT32, BASE_DEC,
10754 NULL((void*)0), 0x0,
10755 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10756 },
10757
10758 /* Corresponding C-plane frame for DL U-plane */
10759 { &hf_oran_corresponding_cplane_frame,
10760 { "C-plane frame", "oran_fh_cus.cplane-frame",
10761 FT_FRAMENUM, BASE_NONE,
10762 FRAMENUM_TYPE(FT_FRAMENUM_REQUEST)((gpointer) (glong) (FT_FRAMENUM_REQUEST)), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10763 },
10764 /* Time since corresponding C-plane frame for U-plane */
10765 { &hf_oran_corresponding_cplane_frame_time_delta,
10766 { "Time since C-plane frame", "oran_fh_cus.cplane-frame-time-delta",
10767 FT_UINT32, BASE_DEC, NULL((void*)0), 0x0,
10768 "Microseconds since C-plane frame", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10769 },
10770 /* Corresponding U-plane frame for C-plane */
10771 { &hf_oran_corresponding_uplane_frame,
10772 { "U-plane frame", "oran_fh_cus.uplane-frame",
10773 FT_FRAMENUM, BASE_NONE,
10774 FRAMENUM_TYPE(FT_FRAMENUM_RESPONSE)((gpointer) (glong) (FT_FRAMENUM_RESPONSE)), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10775 },
10776 { &hf_oran_corresponding_uplane_frames_total,
10777 { "U-plane frames total", "oran_fh_cus.u-plane-frames-total",
10778 FT_UINT32, BASE_DEC, NULL((void*)0), 0x0,
10779 "Number of corresponding U-plane frames", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10780 },
10781
10782 /* Reassembly */
10783 { &hf_oran_fragment,
10784 { "Fragment", "oran_fh_cus.fragment", FT_FRAMENUM, BASE_NONE,
10785 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10786 { &hf_oran_fragments,
10787 { "Fragments", "oran_fh_cus.fragments", FT_BYTES, BASE_NONE,
10788 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10789 { &hf_oran_fragment_overlap,
10790 { "Fragment overlap", "oran_fh_cus.fragment.overlap", FT_BOOLEAN, BASE_NONE,
10791 NULL((void*)0), 0x0, "Fragment overlaps with other fragments", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10792 { &hf_oran_fragment_overlap_conflict,
10793 { "Conflicting data in fragment overlap", "oran_fh_cus.fragment.overlap.conflict",
10794 FT_BOOLEAN, BASE_NONE, NULL((void*)0), 0x0,
10795 "Overlapping fragments contained conflicting data", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10796 { &hf_oran_fragment_multiple_tails,
10797 { "Multiple tail fragments found", "oran_fh_cus.fragment.multipletails",
10798 FT_BOOLEAN, BASE_NONE, NULL((void*)0), 0x0,
10799 "Several tails were found when defragmenting the packet", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10800 { &hf_oran_fragment_too_long_fragment,
10801 { "Fragment too long", "oran_fh_cus.fragment.toolongfragment",
10802 FT_BOOLEAN, BASE_NONE, NULL((void*)0), 0x0,
10803 "Fragment contained data past end of packet", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10804 { &hf_oran_fragment_error,
10805 { "Defragmentation error", "oran_fh_cus.fragment.error", FT_FRAMENUM, BASE_NONE,
10806 NULL((void*)0), 0x0, "Defragmentation error due to illegal fragments", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10807 { &hf_oran_fragment_count,
10808 { "Fragment count", "oran_fh_cus.fragment.count", FT_UINT32, BASE_DEC,
10809 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10810 { &hf_oran_reassembled_in,
10811 { "Reassembled payload in frame", "oran_fh_cus.reassembled_in", FT_FRAMENUM, BASE_NONE,
10812 NULL((void*)0), 0x0, "This payload packet is reassembled in this frame", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10813 { &hf_oran_reassembled_length,
10814 { "Reassembled payload length", "oran_fh_cus.reassembled.length", FT_UINT32, BASE_DEC,
10815 NULL((void*)0), 0x0, "The total length of the reassembled payload", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10816 { &hf_oran_reassembled_data,
10817 { "Reassembled data", "oran_fh_cus.reassembled.data", FT_BYTES, BASE_NONE,
10818 NULL((void*)0), 0x0, "The reassembled payload", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10819
10820 { &hf_oran_payload,
10821 { "Payload", "oran_fh_cus.payload", FT_BYTES, BASE_SHOW_ASCII_PRINTABLE0x00010000,
10822 NULL((void*)0), 0x0, "Complete or reassembled payload", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10823 };
10824
10825 /* Setup protocol subtree array */
10826 static int *ett[] = {
10827 &ett_oran,
10828 &ett_oran_ecpri_pcid,
10829 &ett_oran_ecpri_rtcid,
10830 &ett_oran_ecpri_seqid,
10831 &ett_oran_section_type,
10832 &ett_oran_u_timing,
10833 &ett_oran_u_section,
10834 &ett_oran_u_prb,
10835 &ett_oran_section,
10836 &ett_oran_iq,
10837 &ett_oran_bfw_bundle,
10838 &ett_oran_bfw,
10839 &ett_oran_frequency_range,
10840 &ett_oran_prb_cisamples,
10841 &ett_oran_cisample,
10842 &ett_oran_udcomphdr,
10843 &ett_oran_udcompparam,
10844 &ett_oran_cicomphdr,
10845 &ett_oran_cicompparam,
10846 &ett_oran_bfwcomphdr,
10847 &ett_oran_bfwcompparam,
10848 &ett_oran_ext19_port,
10849 &ett_oran_prb_allocation,
10850 &ett_oran_punc_pattern,
10851 &ett_oran_bfacomphdr,
10852 &ett_oran_modcomp_param_set,
10853 &ett_oran_st4_cmd_header,
10854 &ett_oran_st4_cmd,
10855 &ett_oran_sym_prb_pattern,
10856 &ett_oran_measurement_report,
10857 &ett_oran_measurement_command,
10858 &ett_oran_sresmask,
10859 &ett_oran_c_section_common,
10860 &ett_oran_c_section,
10861 &ett_oran_remask,
10862 &ett_oran_mc_scale_remask,
10863 &ett_oran_symbol_reordering_layer,
10864 &ett_oran_dmrs_entry,
10865 &ett_oran_dmrs_symbol_mask,
10866 &ett_oran_symbol_mask,
10867 &ett_oran_active_beamspace_coefficient_mask,
10868 &ett_oran_sinr_prb,
10869
10870 &ett_oran_fragment,
10871 &ett_oran_fragments
10872 };
10873
10874 /* Separate subtree array for extensions. Used with [ext-1] */
10875 static int *ext_ett[HIGHEST_EXTTYPE32];
10876 for (unsigned extno=0; extno<HIGHEST_EXTTYPE32; extno++) {
10877 ext_ett[extno] = &ett_oran_c_section_extension[extno];
10878 }
10879
10880 expert_module_t* expert_oran;
10881
10882 static ei_register_info ei[] = {
10883 { &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)}}
}},
10884 { &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)}}
}},
10885 { &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)}}
}},
10886 { &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)}}
}},
10887 { &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)}}
}},
10888 { &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)}}
}},
10889 { &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)}}
}},
10890 { &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)}}
}},
10891 { &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)}}
}},
10892 { &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)}}
}},
10893 { &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)}}
}},
10894 { &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)}}
}},
10895 { &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)}}
}},
10896 { &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)}}
}},
10897 { &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)}}
}},
10898 { &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)}}
}},
10899 { &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)}}
}},
10900 { &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)}}
}},
10901 { &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)}}
}},
10902 { &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)}}
}},
10903 { &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)}}
}},
10904 { &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)}}
}},
10905 { &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)}}
}},
10906 { &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)}}
}},
10907 { &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)}}
}},
10908 { &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)}}
}},
10909 { &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)}}
}},
10910 { &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)}}
}},
10911 { &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)}}
}},
10912 { &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)}}
}},
10913 { &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)}}
}},
10914 { &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)}}
}},
10915 { &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)}}
}},
10916 { &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)}}
}},
10917 { &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)}}
}},
10918 { &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)}}
}},
10919 { &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)}}
}},
10920 { &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)}}
}},
10921 { &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)}}
}},
10922 { &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)}}
}},
10923 { &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)}}
}},
10924 { &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)}}
}},
10925 { &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)}}
}},
10926 { &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)}}
}},
10927 { &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)}}
}},
10928 { &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)}}
}},
10929 { &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)}}
}},
10930 { &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)}}
}},
10931 { &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)}}
}},
10932 { &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)}}
}},
10933 { &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)}}
}},
10934 { &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)}}
}},
10935 { &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)}}
}},
10936 { &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)}}
}},
10937 { &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)}}
}},
10938 { &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)}}
}}
10939 };
10940
10941 /* Register the protocol name and description */
10942 proto_oran = proto_register_protocol("O-RAN Fronthaul CUS", "O-RAN FH CUS", "oran_fh_cus");
10943
10944 /* Allow dissector to find be found by name. */
10945 register_dissector("oran_fh_cus", dissect_oran, proto_oran);
10946
10947 /* Register the tap name. */
10948 oran_tap = register_tap("oran-fh-cus");
10949
10950 /* Required function calls to register the header fields and subtrees */
10951 proto_register_field_array(proto_oran, hf, array_length(hf)(sizeof (hf) / sizeof (hf)[0]));
10952 proto_register_subtree_array(ett, array_length(ett)(sizeof (ett) / sizeof (ett)[0]));
10953 proto_register_subtree_array(ext_ett, array_length(ext_ett)(sizeof (ext_ett) / sizeof (ext_ett)[0]));
10954
10955 expert_oran = expert_register_protocol(proto_oran);
10956 expert_register_field_array(expert_oran, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
10957
10958
10959 /* Preferences */
10960 module_t * oran_module = prefs_register_protocol(proto_oran, NULL((void*)0));
10961
10962 /* Register bit width/compression preferences separately by direction. */
10963 prefs_register_uint_preference(oran_module, "oran.du_port_id_bits", "DU Port ID bits [a]",
10964 "The bit width of DU Port ID - sum of a,b,c&d (eAxC) must be 16", 10, &pref_du_port_id_bits);
10965 prefs_register_uint_preference(oran_module, "oran.bandsector_id_bits", "BandSector ID bits [b]",
10966 "The bit width of BandSector ID - sum of a,b,c&d (eAxC) must be 16", 10, &pref_bandsector_id_bits);
10967 prefs_register_uint_preference(oran_module, "oran.cc_id_bits", "CC ID bits [c]",
10968 "The bit width of CC ID - sum of a,b,c&d (eAxC) must be 16", 10, &pref_cc_id_bits);
10969 prefs_register_uint_preference(oran_module, "oran.ru_port_id_bits", "RU Port ID bits [d]",
10970 "The bit width of RU Port ID - sum of a,b,c&d (eAxC) must be 16", 10, &pref_ru_port_id_bits);
10971
10972 /* Uplink userplane */
10973 prefs_register_static_text_preference(oran_module, "oran.ul", "", "");
10974 prefs_register_uint_preference(oran_module, "oran.iq_bitwidth_up", "IQ Bitwidth Uplink",
10975 "The bit width of a sample in the Uplink (if no udcompHdr and no C-Plane)", 10, &pref_sample_bit_width_uplink);
10976 prefs_register_enum_preference(oran_module, "oran.ud_comp_up", "Uplink User Data Compression",
10977 "Uplink User Data Compression (if no udcompHdr and no C-Plane)", &pref_iqCompressionUplink, ul_compression_options, false0);
10978 prefs_register_enum_preference(oran_module, "oran.ud_comp_hdr_up", "udCompHdr field is present for uplink",
10979 "The udCompHdr field in U-Plane messages may or may not be present, depending on the "
10980 "configuration of the O-RU. This preference instructs the dissector to expect "
10981 "this field to be present in uplink messages",
10982 &pref_includeUdCompHeaderUplink, udcomphdr_present_options, false0);
10983 prefs_register_bool_preference(oran_module, "oran.ignore_cplane_ul_udcomphdr", "Ignore UL compression settings from C-plane",
10984 "When set, override udCompHdr from UL C-Plane with compression method and width configured here", &pref_override_ul_compression);
10985 prefs_register_uint_preference(oran_module, "oran.ul_slot_us_limit", "Microseconds allowed for UL tx in symbol",
10986 "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",
10987 10, &us_allowed_for_ul_in_symbol);
10988
10989 /* Downlink userplane */
10990 prefs_register_static_text_preference(oran_module, "oran.dl", "", "");
10991 prefs_register_uint_preference(oran_module, "oran.iq_bitwidth_down", "IQ Bitwidth Downlink",
10992 "The bit width of a sample in the Downlink (if no udcompHdr)", 10, &pref_sample_bit_width_downlink);
10993 prefs_register_enum_preference(oran_module, "oran.ud_comp_down", "Downlink User Data Compression",
10994 "Downlink User Data Compression", &pref_iqCompressionDownlink, dl_compression_options, false0);
10995 prefs_register_enum_preference(oran_module, "oran.ud_comp_hdr_down", "udCompHdr field is present for downlink",
10996 "The udCompHdr field in U-Plane messages may or may not be present, depending on the "
10997 "configuration of the O-RU. This preference instructs the dissector to expect "
10998 "this field to be present in downlink messages",
10999 &pref_includeUdCompHeaderDownlink, udcomphdr_present_options, false0);
11000
11001 /* SINR */
11002 prefs_register_static_text_preference(oran_module, "oran.sinr", "", "");
11003 prefs_register_uint_preference(oran_module, "oran.iq_bitwidth_sinr", "IQ Bitwidth SINR",
11004 "The bit width of a sample in SINR", 10, &pref_sample_bit_width_sinr);
11005 prefs_register_enum_preference(oran_module, "oran.ud_comp_sinr", "SINR Compression",
11006 "SINR Compression", &pref_iqCompressionSINR, ul_compression_options, false0);
11007
11008 /* BF-related */
11009 prefs_register_static_text_preference(oran_module, "oran.bf", "", "");
11010 prefs_register_uint_preference(oran_module, "oran.num_bf_antennas", "Number of beam weights",
11011 "Number of array elements that BF weights will be provided for", 10, &pref_num_bf_antennas);
11012 prefs_register_obsolete_preference(oran_module, "oran.num_weights_per_bundle");
11013 prefs_register_obsolete_preference(oran_module, "oran.num_bf_weights");
11014 prefs_register_bool_preference(oran_module, "oran.st6_4byte_alignment_required", "Use 4-byte alignment for ST6 sections",
11015 "Default is 1-byte alignment", &st6_4byte_alignment);
11016
11017 /* Misc (and will seldom need to be accessed) */
11018 prefs_register_static_text_preference(oran_module, "oran.misc", "", "");
11019 prefs_register_bool_preference(oran_module, "oran.show_iq_samples", "Show IQ Sample values",
11020 "When enabled, for U-Plane frames show each I and Q value in PRB", &pref_showIQSampleValues);
11021 prefs_register_enum_preference(oran_module, "oran.support_udcomplen", "udCompLen supported",
11022 "When enabled, U-Plane messages with relevant compression schemes will include udCompLen",
11023 &pref_support_udcompLen, udcomplen_support_options, false0);
11024 prefs_register_uint_preference(oran_module, "oran.rbs_in_uplane_section", "Total RBs in User-Plane data section",
11025 "This is used if numPrbu is signalled as 0", 10, &pref_data_plane_section_total_rbs);
11026 prefs_register_bool_preference(oran_module, "oran.unscaled_iq", "Show unscaled I/Q values",
11027 "", &show_unscaled_values);
11028 prefs_register_bool_preference(oran_module, "oran.attempt_reassembly",
11029 "Attempt Radio Transport layer reassembly", "",
11030 &do_radio_transport_layer_reassembly);
11031 prefs_register_obsolete_preference(oran_module, "oran.k_antenna_ports");
11032
11033 prefs_register_bool_preference(oran_module, "oran.link_planes",
11034 "Link C-plane and U-plane using sectionId", "",
11035 &link_planes_together);
11036
11037
11038 flow_states_table = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
11039 flow_results_table = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
11040 ul_symbol_timing = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
11041
11042 dl_beam_ids_defined = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
11043 dl_beam_ids_results = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
11044
11045 register_init_routine(&oran_init_protocol);
11046
11047 /* Register reassembly table. */
11048 reassembly_table_register(&oran_reassembly_table,
11049 &oran_reassembly_table_functions);
11050}
11051
11052/*
11053* Editor modelines - http://www.wireshark.org/tools/modelines.html
11054*
11055* Local Variables:
11056* c-basic-offset: 4
11057* tab-width: 8
11058* indent-tabs-mode: nil
11059* End:
11060*
11061* ex: set shiftwidth=4 tabstop=8 expandtab:
11062* :indentSize=4:tabSize=8:noTabs=true:
11063*/