Bug Summary

File:builds/wireshark/wireshark/epan/dissectors/packet-oran.c
Warning:line 7386, 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-04-100350-3577-1 -x c /builds/wireshark/wireshark/epan/dissectors/packet-oran.c
1/* packet-oran.c
2 * Routines for O-RAN fronthaul UC-plane dissection
3 * Copyright 2020, Jan Schiefer, Keysight Technologies, Inc.
4 * Copyright 2020- Martin Mathieson
5 *
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <[email protected]>
8 * Copyright 1998 Gerald Combs
9 *
10 * SPDX-License-Identifier: GPL-2.0-or-later
11 */
12
13 /*
14 * Dissector for the O-RAN Fronthaul CUS protocol specification.
15 * See https://specifications.o-ran.org/specifications, WG4, Fronthaul Interfaces Workgroup
16 * The current implementation is based on the ORAN-WG4.CUS.0-v20.00 specification.
17 * Note that other eCPRI message types are handled in packet-ecpri.c
18 */
19
20#include <config.h>
21
22#include <math.h>
23
24#include <epan/packet.h>
25#include <epan/expert.h>
26#include <epan/prefs.h>
27#include <epan/tap.h>
28#include <epan/tfs.h>
29#include <epan/reassemble.h>
30
31#include <wsutil/ws_roundup.h>
32#include <wsutil/ws_padding_to.h>
33
34#include "epan/dissectors/packet-oran.h"
35
36/* N.B. dissector preferences are taking the place of (some) M-plane parameters,
37 * so unfortunately it can be fiddly to get the preferences into a good state to
38 * decode a given capture..
39 * TODO:
40 * - for U-Plane, track back to last C-Plane frame for that eAxC
41 * doing, but this matching can be tricky see 7.8.1 Coupling of C-Plane and U-Plane
42 * - Detect/indicate signs of application layer fragmentation?
43 * same eAxC in same symbol (same/different section ID?)
44 * - Not handling M-plane setting for "little endian byte order" as applied to
45 * IQ samples and beam weights does anyone use this?
46 * - for section extensions, check more constraints (which other extension types
47 * appear with them, order, repeated)
48 * - re-order items (decl and hf definitions) to match spec order?
49 * - track energy-saving status, and identify TRX or ASM commands as 'Sleep extension'
50 */
51
52/* Prototypes */
53void proto_register_oran(void);
54
55/* Initialize the protocol and registered fields */
56static int proto_oran;
57
58static int oran_tap = -1;
59
60static int hf_oran_du_port_id;
61static int hf_oran_bandsector_id;
62static int hf_oran_cc_id;
63static int hf_oran_ru_port_id;
64static int hf_oran_sequence_id;
65static int hf_oran_e_bit;
66static int hf_oran_subsequence_id;
67static int hf_oran_previous_frame;
68
69static int hf_oran_data_direction;
70static int hf_oran_payload_version;
71static int hf_oran_filter_index;
72static int hf_oran_frame_id;
73static int hf_oran_subframe_id;
74static int hf_oran_slot_id;
75static int hf_oran_slot_within_frame;
76static int hf_oran_start_symbol_id;
77static int hf_oran_numberOfSections;
78static int hf_oran_sectionType;
79
80static int hf_oran_udCompHdr;
81static int hf_oran_udCompHdrIqWidth;
82static int hf_oran_udCompHdrIqWidth_pref;
83static int hf_oran_udCompHdrMeth;
84static int hf_oran_udCompHdrMeth_pref;
85static int hf_oran_udCompLen;
86static int hf_oran_numberOfUEs;
87static int hf_oran_timeOffset;
88static int hf_oran_frameStructure_fft;
89static int hf_oran_frameStructure_subcarrier_spacing;
90static int hf_oran_cpLength;
91static int hf_oran_timing_header;
92static int hf_oran_section_id;
93static int hf_oran_rb;
94static int hf_oran_symInc;
95static int hf_oran_startPrbc;
96static int hf_oran_reMask_re1;
97static int hf_oran_reMask_re2;
98static int hf_oran_reMask_re3;
99static int hf_oran_reMask_re4;
100static int hf_oran_reMask_re5;
101static int hf_oran_reMask_re6;
102static int hf_oran_reMask_re7;
103static int hf_oran_reMask_re8;
104static int hf_oran_reMask_re9;
105static int hf_oran_reMask_re10;
106static int hf_oran_reMask_re11;
107static int hf_oran_reMask_re12;
108static int hf_oran_reMask;
109static int hf_oran_numPrbc;
110static int hf_oran_numSymbol;
111static int hf_oran_ef;
112static int hf_oran_beamId;
113
114static int hf_oran_sinrCompHdrIqWidth_pref;
115static int hf_oran_sinrCompHdrMeth_pref;
116
117static int hf_oran_ciCompHdr;
118static int hf_oran_ciCompHdrIqWidth;
119static int hf_oran_ciCompHdrMeth;
120static int hf_oran_ciCompOpt;
121
122static int hf_oran_extension;
123static int hf_oran_exttype;
124static int hf_oran_extlen;
125
126static int hf_oran_bfw_bundle;
127static int hf_oran_bfw_bundle_id;
128static int hf_oran_bfw;
129static int hf_oran_bfw_i;
130static int hf_oran_bfw_q;
131
132static int hf_oran_ueId;
133static int hf_oran_freqOffset;
134static int hf_oran_regularizationFactor;
135static int hf_oran_laaMsgType;
136static int hf_oran_laaMsgLen;
137static int hf_oran_lbtHandle;
138static int hf_oran_lbtDeferFactor;
139static int hf_oran_lbtBackoffCounter;
140static int hf_oran_lbtOffset;
141static int hf_oran_MCOT;
142static int hf_oran_lbtMode;
143static int hf_oran_sfnSfEnd;
144static int hf_oran_lbtPdschRes;
145static int hf_oran_sfStatus;
146static int hf_oran_initialPartialSF;
147static int hf_oran_lbtDrsRes;
148static int hf_oran_lbtBufErr;
149static int hf_oran_lbtTrafficClass;
150static int hf_oran_lbtCWConfig_H;
151static int hf_oran_lbtCWConfig_T;
152static int hf_oran_lbtCWR_Rst;
153
154static int hf_oran_reserved;
155static int hf_oran_reserved_1bit;
156static int hf_oran_reserved_2bits;
157static int hf_oran_reserved_3bits;
158static int hf_oran_reserved_4bits;
159static int hf_oran_reserved_last_4bits;
160static int hf_oran_reserved_last_5bits;
161static int hf_oran_reserved_6bits;
162static int hf_oran_reserved_last_6bits;
163static int hf_oran_reserved_7bits;
164static int hf_oran_reserved_last_7bits;
165static int hf_oran_reserved_8bits;
166static int hf_oran_reserved_16bits;
167static int hf_oran_reserved_15bits;
168static int hf_oran_reserved_bit1;
169static int hf_oran_reserved_bit2;
170static int hf_oran_reserved_bit4;
171static int hf_oran_reserved_bit5;
172static int hf_oran_reserved_bits123;
173static int hf_oran_reserved_bits456;
174
175static int hf_oran_bundle_offset;
176static int hf_oran_cont_ind;
177
178static int hf_oran_bfwCompHdr;
179static int hf_oran_bfwCompHdr_iqWidth;
180static int hf_oran_bfwCompHdr_compMeth;
181static int hf_oran_symbolId;
182static int hf_oran_startPrbu;
183static int hf_oran_numPrbu;
184
185static int hf_oran_udCompParam;
186static int hf_oran_sReSMask;
187static int hf_oran_sReSMask_re12;
188static int hf_oran_sReSMask_re11;
189static int hf_oran_sReSMask_re10;
190static int hf_oran_sReSMask_re9;
191static int hf_oran_sReSMask_re8;
192static int hf_oran_sReSMask_re7;
193static int hf_oran_sReSMask_re6;
194static int hf_oran_sReSMask_re5;
195static int hf_oran_sReSMask_re4;
196static int hf_oran_sReSMask_re3;
197static int hf_oran_sReSMask_re2;
198static int hf_oran_sReSMask_re1;
199
200static int hf_oran_sReSMask1;
201static int hf_oran_sReSMask2;
202static int hf_oran_sReSMask1_2_re12;
203static int hf_oran_sReSMask1_2_re11;
204static int hf_oran_sReSMask1_2_re10;
205static int hf_oran_sReSMask1_2_re9;
206
207static int hf_oran_bfwCompParam;
208
209static int hf_oran_iSample;
210static int hf_oran_qSample;
211
212static int hf_oran_ciCompParam;
213
214static int hf_oran_blockScaler;
215static int hf_oran_compBitWidth;
216static int hf_oran_compShift;
217
218static int hf_oran_active_beamspace_coefficient_n1;
219static int hf_oran_active_beamspace_coefficient_n2;
220static int hf_oran_active_beamspace_coefficient_n3;
221static int hf_oran_active_beamspace_coefficient_n4;
222static int hf_oran_active_beamspace_coefficient_n5;
223static int hf_oran_active_beamspace_coefficient_n6;
224static int hf_oran_active_beamspace_coefficient_n7;
225static int hf_oran_active_beamspace_coefficient_n8;
226static int hf_oran_activeBeamspaceCoefficientMask;
227static int hf_oran_activeBeamspaceCoefficientMask_bits_set;
228
229static int hf_oran_se6_repetition;
230
231static int hf_oran_rbgSize;
232static int hf_oran_rbgMask;
233static int hf_oran_noncontig_priority;
234
235static int hf_oran_symbol_mask;
236static int hf_oran_symbol_mask_s13;
237static int hf_oran_symbol_mask_s12;
238static int hf_oran_symbol_mask_s11;
239static int hf_oran_symbol_mask_s10;
240static int hf_oran_symbol_mask_s9;
241static int hf_oran_symbol_mask_s8;
242static int hf_oran_symbol_mask_s7;
243static int hf_oran_symbol_mask_s6;
244static int hf_oran_symbol_mask_s5;
245static int hf_oran_symbol_mask_s4;
246static int hf_oran_symbol_mask_s3;
247static int hf_oran_symbol_mask_s2;
248static int hf_oran_symbol_mask_s1;
249static int hf_oran_symbol_mask_s0;
250
251static int hf_oran_exponent;
252static int hf_oran_iq_user_data;
253
254static int hf_oran_disable_bfws;
255static int hf_oran_rad;
256static int hf_oran_num_bund_prbs;
257static int hf_oran_beam_id;
258static int hf_oran_num_weights_per_bundle;
259
260static int hf_oran_ack_nack_req_id;
261
262static int hf_oran_frequency_range;
263static int hf_oran_off_start_prb;
264static int hf_oran_num_prb;
265
266static int hf_oran_samples_prb;
267static int hf_oran_ciSample;
268static int hf_oran_ciIsample;
269static int hf_oran_ciQsample;
270
271static int hf_oran_beamGroupType;
272static int hf_oran_numPortc;
273
274static int hf_oran_csf;
275static int hf_oran_modcompscaler;
276
277static int hf_oran_modcomp_param_set;
278static int hf_oran_mc_scale_re_mask_re1;
279static int hf_oran_mc_scale_re_mask_re2;
280static int hf_oran_mc_scale_re_mask_re3;
281static int hf_oran_mc_scale_re_mask_re4;
282static int hf_oran_mc_scale_re_mask_re5;
283static int hf_oran_mc_scale_re_mask_re6;
284static int hf_oran_mc_scale_re_mask_re7;
285static int hf_oran_mc_scale_re_mask_re8;
286static int hf_oran_mc_scale_re_mask_re9;
287static int hf_oran_mc_scale_re_mask_re10;
288static int hf_oran_mc_scale_re_mask_re11;
289static int hf_oran_mc_scale_re_mask_re12;
290static int hf_oran_mc_scale_re_mask_re1_even;
291static int hf_oran_mc_scale_re_mask_re2_even;
292static int hf_oran_mc_scale_re_mask_re3_even;
293static int hf_oran_mc_scale_re_mask_re4_even;
294static int hf_oran_mc_scale_re_mask_re5_even;
295static int hf_oran_mc_scale_re_mask_re6_even;
296static int hf_oran_mc_scale_re_mask_re7_even;
297static int hf_oran_mc_scale_re_mask_re8_even;
298static int hf_oran_mc_scale_re_mask_re9_even;
299static int hf_oran_mc_scale_re_mask_re10_even;
300static int hf_oran_mc_scale_re_mask_re11_even;
301static int hf_oran_mc_scale_re_mask_re12_even;
302
303static int hf_oran_mc_scale_re_mask;
304static int hf_oran_mc_scale_re_mask_even;
305
306static int hf_oran_mc_scale_offset;
307
308static int hf_oran_eAxC_mask;
309static int hf_oran_technology;
310static int hf_oran_nullLayerInd;
311
312static int hf_oran_se19_repetition;
313static int hf_oran_portReMask;
314static int hf_oran_portSymbolMask;
315
316static int hf_oran_ext19_port;
317
318static int hf_oran_prb_allocation;
319static int hf_oran_nextSymbolId;
320static int hf_oran_nextStartPrbc;
321
322static int hf_oran_puncPattern;
323static int hf_oran_numPuncPatterns;
324static int hf_oran_symbolMask_ext20;
325static int hf_oran_startPuncPrb;
326static int hf_oran_numPuncPrb;
327static int hf_oran_puncReMask;
328static int hf_oran_multiSDScope;
329static int hf_oran_RbgIncl;
330
331static int hf_oran_ci_prb_group_size;
332static int hf_oran_prg_size_st5;
333static int hf_oran_prg_size_st6;
334
335static int hf_oran_num_ueid;
336
337static int hf_oran_antMask;
338
339static int hf_oran_transmissionWindowOffset;
340static int hf_oran_transmissionWindowSize;
341static int hf_oran_toT;
342
343static int hf_oran_bfaCompHdr;
344static int hf_oran_bfAzPtWidth;
345static int hf_oran_bfZePtWidth;
346static int hf_oran_bfAz3ddWidth;
347static int hf_oran_bfZe3ddWidth;
348static int hf_oran_bfAzPt;
349static int hf_oran_bfZePt;
350static int hf_oran_bfAz3dd;
351static int hf_oran_bfZe3dd;
352static int hf_oran_bfAzSl;
353static int hf_oran_bfZeSl;
354
355static int hf_oran_cmd_scope;
356static int hf_oran_number_of_st4_cmds;
357
358static int hf_oran_st4_cmd_header;
359static int hf_oran_st4_cmd_type;
360static int hf_oran_st4_cmd_len;
361static int hf_oran_st4_cmd_num_slots;
362static int hf_oran_st4_cmd_ack_nack_req_id;
363
364static int hf_oran_st4_cmd;
365
366static int hf_oran_sleepmode_trx;
367static int hf_oran_sleepmode_asm;
368static int hf_oran_log2maskbits;
369static int hf_oran_num_slots_ext;
370static int hf_oran_antMask_trx_control;
371
372static int hf_oran_ready;
373static int hf_oran_number_of_acks;
374static int hf_oran_number_of_nacks;
375static int hf_oran_ackid;
376static int hf_oran_nackid;
377
378static int hf_oran_acknack_request_frame;
379static int hf_oran_acknack_request_time;
380static int hf_oran_acknack_request_type;
381static int hf_oran_acknack_response_frame;
382static int hf_oran_acknack_response_time;
383
384static int hf_oran_disable_tdbfns;
385static int hf_oran_td_beam_group;
386static int hf_oran_disable_tdbfws;
387static int hf_oran_td_beam_num;
388
389static int hf_oran_dir_pattern;
390static int hf_oran_guard_pattern;
391
392static int hf_oran_ecpri_pcid;
393static int hf_oran_ecpri_rtcid;
394static int hf_oran_ecpri_seqid;
395
396static int hf_oran_num_sym_prb_pattern;
397static int hf_oran_prb_mode;
398static int hf_oran_sym_prb_pattern;
399static int hf_oran_sym_mask;
400static int hf_oran_num_mc_scale_offset;
401static int hf_oran_prb_pattern;
402static int hf_oran_prb_block_offset;
403static int hf_oran_prb_block_size;
404
405static int hf_oran_codebook_index;
406static int hf_oran_layerid;
407static int hf_oran_numlayers;
408static int hf_oran_txscheme;
409static int hf_oran_crs_remask;
410static int hf_oran_crs_shift;
411static int hf_oran_crs_symnum;
412static int hf_oran_beamid_ap1;
413static int hf_oran_beamid_ap2;
414static int hf_oran_beamid_ap3;
415
416static int hf_oran_port_list_index;
417static int hf_oran_alpn_per_sym;
418static int hf_oran_ant_dmrs_snr;
419static int hf_oran_user_group_size;
420static int hf_oran_user_group_id;
421static int hf_oran_entry_type;
422static int hf_oran_dmrs_port_number;
423static int hf_oran_ueid_reset;
424
425static int hf_oran_dmrs_symbol_mask;
426static int hf_oran_dmrs_symbol_mask_s13;
427static int hf_oran_dmrs_symbol_mask_s12;
428static int hf_oran_dmrs_symbol_mask_s11;
429static int hf_oran_dmrs_symbol_mask_s10;
430static int hf_oran_dmrs_symbol_mask_s9;
431static int hf_oran_dmrs_symbol_mask_s8;
432static int hf_oran_dmrs_symbol_mask_s7;
433static int hf_oran_dmrs_symbol_mask_s6;
434static int hf_oran_dmrs_symbol_mask_s5;
435static int hf_oran_dmrs_symbol_mask_s4;
436static int hf_oran_dmrs_symbol_mask_s3;
437static int hf_oran_dmrs_symbol_mask_s2;
438static int hf_oran_dmrs_symbol_mask_s1;
439static int hf_oran_dmrs_symbol_mask_s0;
440
441static int hf_oran_scrambling;
442static int hf_oran_nscid;
443static int hf_oran_dtype;
444static int hf_oran_cmd_without_data;
445static int hf_oran_lambda;
446static int hf_oran_first_prb;
447static int hf_oran_last_prb;
448static int hf_oran_low_papr_type;
449static int hf_oran_hopping_mode;
450
451static int hf_oran_tx_win_for_on_air_symbol_l;
452static int hf_oran_tx_win_for_on_air_symbol_r;
453
454static int hf_oran_num_fo_fb;
455static int hf_oran_freq_offset_fb;
456
457static int hf_oran_num_ue_sinr_rpt;
458static int hf_oran_num_sinr_per_prb;
459static int hf_oran_num_sinr_per_prb_right;
460
461static int hf_oran_sinr_value;
462
463static int hf_oran_measurement_report;
464static int hf_oran_mf;
465static int hf_oran_meas_data_size;
466static int hf_oran_meas_type_id;
467static int hf_oran_ipn_power;
468static int hf_oran_ue_tae;
469static int hf_oran_ue_layer_power;
470static int hf_oran_num_elements;
471static int hf_oran_ant_dmrs_snr_val;
472static int hf_oran_ue_freq_offset;
473
474static int hf_oran_measurement_command;
475
476static int hf_oran_beam_type;
477static int hf_oran_meas_cmd_size;
478
479static int hf_oran_symbol_reordering_layer;
480static int hf_oran_dmrs_entry;
481
482static int hf_oran_c_section_common;
483static int hf_oran_c_section;
484static int hf_oran_u_section;
485
486static int hf_oran_u_section_ul_symbol_time;
487static int hf_oran_u_section_ul_symbol_frames;
488static int hf_oran_u_section_ul_symbol_first_frame;
489static int hf_oran_u_section_ul_symbol_last_frame;
490
491static int hf_oran_cd_scg_size;
492static int hf_oran_cd_scg_phase_step;
493
494static int hf_oran_sinr_prb;
495static int hf_oran_oru_control_sinr_slot_mask_id;
496static int hf_oran_pos_meas;
497
498static int hf_oran_ue_radial_speed;
499static int hf_oran_ue_az_aoa;
500static int hf_oran_ue_ze_aoa;
501static int hf_oran_ue_pos_toa_offset;
502
503static int hf_oran_num_rep_ue;
504static int hf_oran_rep_ueid;
505static int hf_oran_is_last_rep;
506static int hf_oran_rep_index;
507static int hf_oran_num_reps;
508
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;
521
522/* Computed fields */
523static int hf_oran_c_eAxC_ID;
524static int hf_oran_refa;
525
526static int hf_oran_bfws_frame_defined;
527static int hf_oran_bfws_symbols_since_defined;
528
529static int hf_oran_corresponding_cplane_frame;
530static int hf_oran_corresponding_cplane_frame_time_delta;
531static int hf_oran_corresponding_uplane_frame;
532
533
534/* Convenient fields for filtering, mostly shown as hidden */
535static int hf_oran_cplane;
536static int hf_oran_uplane;
537static int hf_oran_bf; /* to match frames that configure beamforming in any way */
538static int hf_oran_zero_prb;
539static int hf_oran_nonzero_prb;
540static int hf_oran_bundle_weights_all_zero;
541
542static int hf_oran_ul_cplane_ud_comp_hdr_frame;
543
544/* For reassembly */
545static int hf_oran_fragments;
546static int hf_oran_fragment;
547static int hf_oran_fragment_overlap;
548static int hf_oran_fragment_overlap_conflict;
549static int hf_oran_fragment_multiple_tails;
550static int hf_oran_fragment_too_long_fragment;
551static int hf_oran_fragment_error;
552static int hf_oran_fragment_count;
553static int hf_oran_reassembled_in;
554static int hf_oran_reassembled_length;
555static int hf_oran_reassembled_data;
556
557static int hf_oran_payload;
558
559
560/* Subtrees */
561static int ett_oran;
562static int ett_oran_ecpri_rtcid;
563static int ett_oran_ecpri_pcid;
564static int ett_oran_ecpri_seqid;
565static int ett_oran_section;
566static int ett_oran_section_type;
567static int ett_oran_u_timing;
568static int ett_oran_u_section;
569static int ett_oran_u_prb;
570static int ett_oran_iq;
571static int ett_oran_bfw_bundle;
572static int ett_oran_bfw;
573static int ett_oran_frequency_range;
574static int ett_oran_prb_cisamples;
575static int ett_oran_cisample;
576static int ett_oran_udcomphdr;
577static int ett_oran_udcompparam;
578static int ett_oran_cicomphdr;
579static int ett_oran_cicompparam;
580static int ett_oran_bfwcomphdr;
581static int ett_oran_bfwcompparam;
582static int ett_oran_ext19_port;
583static int ett_oran_prb_allocation;
584static int ett_oran_punc_pattern;
585static int ett_oran_bfacomphdr;
586static int ett_oran_modcomp_param_set;
587static int ett_oran_st4_cmd_header;
588static int ett_oran_st4_cmd;
589static int ett_oran_sym_prb_pattern;
590static int ett_oran_measurement_report;
591static int ett_oran_measurement_command;
592static int ett_oran_sresmask;
593static int ett_oran_c_section_common;
594static int ett_oran_c_section;
595static int ett_oran_remask;
596static int ett_oran_mc_scale_remask;
597static int ett_oran_symbol_reordering_layer;
598static int ett_oran_dmrs_entry;
599static int ett_oran_dmrs_symbol_mask;
600static int ett_oran_symbol_mask;
601static int ett_oran_active_beamspace_coefficient_mask;
602static int ett_oran_sinr_prb;
603
604static int ett_oran_fragment;
605static int ett_oran_fragments;
606
607/* Reassembly table. */
608static reassembly_table oran_reassembly_table;
609
610static void *oran_key(const packet_info *pinfo _U___attribute__((unused)), const uint32_t id _U___attribute__((unused)), const void *data)
611{
612 return (void *)data;
613}
614
615static void oran_free_key(void *ptr _U___attribute__((unused)))
616{
617}
618
619static reassembly_table_functions oran_reassembly_table_functions =
620{
621 g_direct_hash,
622 g_direct_equal,
623 oran_key,
624 oran_key,
625 oran_free_key,
626 oran_free_key
627};
628
629static const fragment_items oran_frag_items = {
630 &ett_oran_fragment,
631 &ett_oran_fragments,
632 &hf_oran_fragments,
633 &hf_oran_fragment,
634 &hf_oran_fragment_overlap,
635 &hf_oran_fragment_overlap_conflict,
636 &hf_oran_fragment_multiple_tails,
637 &hf_oran_fragment_too_long_fragment,
638 &hf_oran_fragment_error,
639 &hf_oran_fragment_count,
640 &hf_oran_reassembled_in,
641 &hf_oran_reassembled_length,
642 &hf_oran_reassembled_data,
643 "O-RAN FH CUS fragments"
644};
645
646
647
648/* Don't want all extensions to open and close together. Use [extType-1] entry */
649static int ett_oran_c_section_extension[HIGHEST_EXTTYPE32];
650
651/* Expert info */
652static expert_field ei_oran_unsupported_bfw_compression_method;
653static expert_field ei_oran_invalid_sample_bit_width;
654static expert_field ei_oran_reserved_numBundPrb;
655static expert_field ei_oran_extlen_wrong;
656static expert_field ei_oran_invalid_eaxc_bit_width;
657static expert_field ei_oran_extlen_zero;
658static expert_field ei_oran_rbg_size_reserved;
659static expert_field ei_oran_frame_length;
660static expert_field ei_oran_numprbc_ext21_zero;
661static expert_field ei_oran_ci_prb_group_size_reserved;
662static expert_field ei_oran_st8_nackid;
663static expert_field ei_oran_st4_no_cmds;
664static expert_field ei_oran_st4_zero_len_cmd;
665static expert_field ei_oran_st4_wrong_len_cmd;
666static expert_field ei_oran_st4_unknown_cmd;
667static expert_field ei_oran_mcot_out_of_range;
668static expert_field ei_oran_se10_unknown_beamgrouptype;
669static expert_field ei_oran_se10_not_allowed;
670static expert_field ei_oran_start_symbol_id_not_zero;
671static expert_field ei_oran_trx_control_cmd_scope;
672static expert_field ei_oran_unhandled_se;
673static expert_field ei_oran_bad_symbolmask;
674static expert_field ei_oran_numslots_not_zero;
675static expert_field ei_oran_version_unsupported;
676static expert_field ei_oran_laa_msg_type_unsupported;
677static expert_field ei_oran_se_on_unsupported_st;
678static expert_field ei_oran_cplane_unexpected_sequence_number_ul;
679static expert_field ei_oran_cplane_unexpected_sequence_number_dl;
680static expert_field ei_oran_uplane_unexpected_sequence_number_ul;
681static expert_field ei_oran_uplane_unexpected_sequence_number_dl;
682static expert_field ei_oran_acknack_no_request;
683static expert_field ei_oran_udpcomphdr_should_be_zero;
684static expert_field ei_oran_radio_fragmentation_c_plane;
685static expert_field ei_oran_lastRbdid_out_of_range;
686static expert_field ei_oran_rbgMask_beyond_last_rbdid;
687static expert_field ei_oran_unexpected_measTypeId;
688static expert_field ei_oran_unsupported_compression_method;
689static expert_field ei_oran_ud_comp_len_wrong_size;
690static expert_field ei_oran_sresmask2_not_zero_with_rb;
691static expert_field ei_oran_st6_rb_shall_be_0;
692static expert_field ei_oran_st9_not_ul;
693static expert_field ei_oran_st10_numsymbol_not_14;
694static expert_field ei_oran_st10_startsymbolid_not_0;
695static expert_field ei_oran_st10_not_ul;
696static expert_field ei_oran_se24_nothing_to_inherit;
697static expert_field ei_oran_num_sinr_per_prb_unknown;
698static expert_field ei_oran_start_symbol_id_bits_ignored;
699static expert_field ei_oran_user_group_id_reserved_value;
700static expert_field ei_oran_port_list_index_zero;
701static expert_field ei_oran_ul_uplane_symbol_too_long;
702static expert_field ei_oran_reserved_not_zero;
703static expert_field ei_oran_too_many_symbols;
704static expert_field ei_oran_se30_not_ul;
705static expert_field ei_oran_se30_unknown_ueid;
706static expert_field ei_oran_beamid_bfws_not_found;
707static expert_field ei_oran_syminc_set_for_uplane;
708
709
710
711/* These are the message types handled by this dissector. Others have handling in packet-ecpri.c */
712#define ECPRI_MT_IQ_DATA0 0
713#define ECPRI_MT_RT_CTRL_DATA2 2
714
715
716/* Preference settings - try to set reasonable defaults */
717static unsigned pref_du_port_id_bits = 4;
718static unsigned pref_bandsector_id_bits = 4;
719static unsigned pref_cc_id_bits = 4;
720static unsigned pref_ru_port_id_bits = 4;
721
722/* TODO: ideally should be per-flow */
723static unsigned pref_sample_bit_width_uplink = 14;
724static unsigned pref_sample_bit_width_downlink = 14;
725static unsigned pref_sample_bit_width_sinr = 14;
726
727/* TODO: these ideally should be per-flow too */
728static int pref_iqCompressionUplink = COMP_BLOCK_FP1;
729static int pref_iqCompressionDownlink = COMP_BLOCK_FP1;
730
731static int pref_iqCompressionSINR = COMP_BLOCK_FP1;
732
733
734/* Is udCompHeader present (both directions) */
735static int pref_includeUdCompHeaderUplink = 2; /* start using heuristic */
736static int pref_includeUdCompHeaderDownlink = 2; /* start using heuristic */
737
738/* Are we ignoring UL C-Plane udCompHdr? */
739static bool_Bool pref_override_ul_compression = false0;
740
741static unsigned pref_data_plane_section_total_rbs = 273;
742static unsigned pref_num_bf_antennas = 32;
743static bool_Bool pref_showIQSampleValues = true1;
744
745/* Based upon m-plane param, so will be system-wide */
746static int pref_support_udcompLen = 2; /* start heuristic, can force other settings if necessary */
747static bool_Bool udcomplen_heuristic_result_set = false0;
748static bool_Bool udcomplen_heuristic_result = false0;
749
750/* st6-4byte-alignment-required */
751static bool_Bool st6_4byte_alignment = false0;
752
753/* Requested, allows I/Q to be stored as integers.. */
754static bool_Bool show_unscaled_values = false0;
755
756/* Initialized off. Timing is in microseconds. */
757static unsigned us_allowed_for_ul_in_symbol = 0;
758
759/* Reassemble U-Plane (at Radio Transport layer) */
760static bool_Bool do_radio_transport_layer_reassembly = true1;
761
762/* Link U-plane back to C-plane using sectionIds */
763static bool_Bool link_planes_together = true1;
764
765static const enum_val_t dl_compression_options[] = {
766 { "COMP_NONE", "No Compression", COMP_NONE0 },
767 { "COMP_BLOCK_FP", "Block Floating Point Compression", COMP_BLOCK_FP1 },
768 { "COMP_BLOCK_SCALE", "Block Scaling Compression", COMP_BLOCK_SCALE2 },
769 { "COMP_U_LAW", "u-Law Compression", COMP_U_LAW3 },
770 { "COMP_MODULATION", "Modulation Compression", COMP_MODULATION4 },
771 { "BFP_AND_SELECTIVE_RE", "Block Floating Point + selective RE sending", BFP_AND_SELECTIVE_RE5 },
772 { "MOD_COMPR_AND_SELECTIVE_RE", "Modulation Compression + selective RE sending", MOD_COMPR_AND_SELECTIVE_RE6 },
773 { "BFP_AND_SELECTIVE_RE_WITH_MASKS", "Block Floating Point + selective RE sending with masks in section header", BFP_AND_SELECTIVE_RE_WITH_MASKS7 },
774 { "MOD_COMPR_AND_SELECTIVE_RE_WITH_MASKS", "Modulation Compression + selective RE sending with masks in section header", MOD_COMPR_AND_SELECTIVE_RE6 },
775 { NULL((void*)0), NULL((void*)0), 0 }
776};
777
778/* No Modulation compression in UL.. */
779static const enum_val_t ul_compression_options[] = {
780 { "COMP_NONE", "No Compression", COMP_NONE0 },
781 { "COMP_BLOCK_FP", "Block Floating Point Compression", COMP_BLOCK_FP1 },
782 { "COMP_BLOCK_SCALE", "Block Scaling Compression", COMP_BLOCK_SCALE2 },
783 { "COMP_U_LAW", "u-Law Compression", COMP_U_LAW3 },
784 { "BFP_AND_SELECTIVE_RE", "Block Floating Point + selective RE sending", BFP_AND_SELECTIVE_RE5 },
785 { "BFP_AND_SELECTIVE_RE_WITH_MASKS", "Block Floating Point + selective RE sending with masks in section header", BFP_AND_SELECTIVE_RE_WITH_MASKS7 },
786 { NULL((void*)0), NULL((void*)0), 0 }
787};
788
789static const enum_val_t udcomplen_support_options[] = {
790 { "NOT_SUPPORTED", "Not Supported", 0 },
791 { "SUPPORTED", "Supported", 1 },
792 { "HEURISTIC", "Attempt Heuristic", 2 },
793 { NULL((void*)0), NULL((void*)0), 0 }
794};
795
796static const enum_val_t udcomphdr_present_options[] = {
797 { "NOT_PRESENT", "Not Present", 0 },
798 { "PRESENT", "Present", 1 },
799 { "HEURISTIC", "Attempt Heuristic", 2 },
800 { NULL((void*)0), NULL((void*)0), 0 }
801};
802
803
804
805static const value_string e_bit[] = {
806 { 0, "More fragments follow" },
807 { 1, "Last fragment" },
808 { 0, NULL((void*)0)}
809};
810
811#define DIR_UPLINK0 0
812#define DIR_DOWNLINK1 1
813
814
815static const value_string data_direction_vals[] = {
816 { DIR_UPLINK0, "Uplink" }, /* gNB Rx */
817 { DIR_DOWNLINK1, "Downlink" }, /* gNB Tx */
818 { 0, NULL((void*)0)}
819};
820
821static const value_string rb_vals[] = {
822 { 0, "Every RB used" },
823 { 1, "Every other RB used" },
824 { 0, NULL((void*)0)}
825};
826
827static const value_string sym_inc_vals[] = {
828 { 0, "Use the current symbol number" },
829 { 1, "Increment the current symbol number" },
830 { 0, NULL((void*)0)}
831};
832
833static const value_string lbtMode_vals[] = {
834 { 0, "Full LBT (regular LBT, sending reservation signal until the beginning of the SF/slot)" },
835 { 1, "Partial LBT (looking back 25 usec prior to transmission" },
836 { 2, "Partial LBT (looking back 34 usec prior to transmission" },
837 { 3, "Full LBT and stop (regular LBT, without sending reservation signal" },
838 { 0, NULL((void*)0)}
839};
840
841static const value_string ue_rank_vals[] = {
842 { 1, "1" },
843 { 2, "2" },
844 { 3, "3" },
845 { 4, "4" },
846 { 0, NULL((void*)0)}
847};
848
849static const value_string num_of_ue_ant_ports_vals[] = {
850 { 2, "2" },
851 { 4, "4" },
852 { 0, NULL((void*)0)}
853};
854
855static const value_string codebook_subset_vals[] = {
856 { 0, "nonCoherent" },
857 { 1, "partialAndNonCoherent" },
858 { 2, "fullyAndPartialAndNonCoherent" },
859 { 3, "reserved" },
860 { 0, NULL((void*)0)}
861};
862
863
864static const range_string filter_indices[] = {
865 {0, 0, "standard channel filter"},
866 {1, 1, "UL filter for PRACH preamble formats 0, 1, 2; min. passband 839 x 1.25kHz = 1048.75 kHz"},
867 {2, 2, "UL filter for PRACH preamble format 3, min. passband 839 x 5 kHz = 4195 kHz"},
868 {3, 3, "UL filter for PRACH preamble formats A1, A2, A3, B1, B2, B3, B4, C0, C2; min. passband 139 x \u0394fRA"},
869 {4, 4, "UL filter for NPRACH 0, 1; min. passband 48 x 3.75KHz = 180 KHz"},
870 {5, 5, "UL filter for PRACH preamble formats"},
871 {8, 8, "UL filter NPUSCH"},
872 {9, 9, "Mixed numerology and other channels except PRACH and NB-IoT"},
873 {9, 15, "Reserved"},
874 {0, 0, NULL((void*)0)}
875};
876
877/* 7.3.1-1 */
878static const range_string section_types[] = {
879 { SEC_C_UNUSED_RB, SEC_C_UNUSED_RB, "Unused Resource Blocks or symbols in Downlink or Uplink" },
880 { SEC_C_NORMAL, SEC_C_NORMAL, "Most DL/UL radio channels" },
881 { SEC_C_RSVD2, SEC_C_RSVD2, "Reserved for future use" },
882 { SEC_C_PRACH, SEC_C_PRACH, "PRACH and mixed-numerology channels" },
883 { SEC_C_SLOT_CONTROL, SEC_C_SLOT_CONTROL, "Slot Configuration Control" },
884 { SEC_C_UE_SCHED, SEC_C_UE_SCHED, "UE scheduling information (UE-ID assignment to section)" },
885 { SEC_C_CH_INFO, SEC_C_CH_INFO, "Channel information" },
886 { SEC_C_LAA, SEC_C_LAA, "LAA (License Assisted Access)" },
887 { SEC_C_ACK_NACK_FEEDBACK, SEC_C_ACK_NACK_FEEDBACK, "ACK/NACK Feedback" },
888 { SEC_C_SINR_REPORTING, SEC_C_SINR_REPORTING, "SINR Reporting" },
889 { SEC_C_RRM_MEAS_REPORTS, SEC_C_RRM_MEAS_REPORTS, "RRM Measurement Reports" },
890 { SEC_C_REQUEST_RRM_MEAS, SEC_C_REQUEST_RRM_MEAS, "Request RRM Measurements" },
891 { 12, 255, "Reserved for future use" },
892 { 0, 0, NULL((void*)0)} };
893
894static const range_string section_types_short[] = {
895 { SEC_C_UNUSED_RB, SEC_C_UNUSED_RB, "(Unused RBs) " },
896 { SEC_C_NORMAL, SEC_C_NORMAL, "(Most channels) " },
897 { SEC_C_RSVD2, SEC_C_RSVD2, "(reserved) " },
898 { SEC_C_PRACH, SEC_C_PRACH, "(PRACH/mixed-\u03bc)" },
899 { SEC_C_SLOT_CONTROL, SEC_C_SLOT_CONTROL, "(Slot info) " },
900 { SEC_C_UE_SCHED, SEC_C_UE_SCHED, "(UE scheduling info)" },
901 { SEC_C_CH_INFO, SEC_C_CH_INFO, "(Channel info) " },
902 { SEC_C_LAA, SEC_C_LAA, "(LAA) " },
903 { SEC_C_ACK_NACK_FEEDBACK, SEC_C_ACK_NACK_FEEDBACK, "(ACK/NACK) " },
904 { SEC_C_SINR_REPORTING, SEC_C_SINR_REPORTING, "(SINR Reporting) " },
905 { SEC_C_RRM_MEAS_REPORTS, SEC_C_RRM_MEAS_REPORTS, "(RRM Meas Reports) " },
906 { SEC_C_REQUEST_RRM_MEAS, SEC_C_REQUEST_RRM_MEAS, "(Req RRM Meas) " },
907 { 12, 255, "Reserved for future use" },
908 { 0, 0, NULL((void*)0) }
909};
910
911static const range_string ud_comp_header_width[] = {
912 {0, 0, "I and Q are each 16 bits wide"},
913 {1, 15, "Bit width of I and Q"},
914 {0, 0, NULL((void*)0)} };
915
916/* Table 8.3.3.13-3 */
917static const range_string ud_comp_header_meth[] = {
918 {COMP_NONE0, COMP_NONE0, "No compression" },
919 {COMP_BLOCK_FP1, COMP_BLOCK_FP1, "Block floating point compression" },
920 {COMP_BLOCK_SCALE2, COMP_BLOCK_SCALE2, "Block scaling" },
921 {COMP_U_LAW3, COMP_U_LAW3, "Mu - law" },
922 {COMP_MODULATION4, COMP_MODULATION4, "Modulation compression" },
923 {BFP_AND_SELECTIVE_RE5, BFP_AND_SELECTIVE_RE5, "BFP + selective RE sending" },
924 {MOD_COMPR_AND_SELECTIVE_RE6, MOD_COMPR_AND_SELECTIVE_RE6, "mod-compr + selective RE sending" },
925 {BFP_AND_SELECTIVE_RE_WITH_MASKS7, BFP_AND_SELECTIVE_RE_WITH_MASKS7, "BFP + selective RE sending with masks in section header" },
926 {MOD_COMPR_AND_SELECTIVE_RE_WITH_MASKS8, MOD_COMPR_AND_SELECTIVE_RE_WITH_MASKS8, "mod-compr + selective RE sending with masks in section header"},
927 {9, 15, "Reserved"},
928 {0, 0, NULL((void*)0)}
929};
930
931/* Table 7.5.2.13-2 */
932static const range_string frame_structure_fft[] = {
933 {0, 0, "Reserved (no FFT/iFFT processing)"},
934 {1, 3, "Reserved"},
935 {4, 4, "FFT size 16"},
936 {5, 5, "FFT size 32"},
937 {6, 6, "FFT size 64"},
938 {7, 7, "FFT size 128"},
939 {8, 8, "FFT size 256"},
940 {9, 9, "FFT size 512"},
941 {10, 10, "FFT size 1024"},
942 {11, 11, "FFT size 2048"},
943 {12, 12, "FFT size 4096"},
944 {13, 13, "FFT size 1536"},
945 {14, 14, "FFT size 3072"},
946 {15, 15, "Reserved"},
947 {0, 0, NULL((void*)0)}
948};
949
950/* Table 7.5.2.13-3 */
951static const range_string subcarrier_spacings[] = {
952 { 0, 0, "SCS 15 kHz, 1 slot/subframe, slot length 1 ms" },
953 { 1, 1, "SCS 30 kHz, 2 slots/subframe, slot length 500 \u03bcs" },
954 { 2, 2, "SCS 60 kHz, 4 slots/subframe, slot length 250 \u03bcs" },
955 { 3, 3, "SCS 120 kHz, 8 slots/subframe, slot length 125 \u03bcs" },
956 { 4, 4, "SCS 240 kHz, 16 slots/subframe, slot length 62.5 \u03bcs" },
957 { 5, 11, "Reserved" }, /* N.B., 5 was 480kHz in early spec versions */
958 { 12, 12, "SCS 1.25 kHz, 1 slot/subframe, slot length 1 ms" },
959 { 13, 13, "SCS 3.75 kHz(LTE - specific), 1 slot/subframe, slot length 1 ms" },
960 { 14, 14, "SCS 5 kHz, 1 slot/subframe, slot length 1 ms" },
961 { 15, 15, "SCS 7.5 kHz(LTE - specific), 1 slot/subframe, slot length 1 ms" },
962 { 0, 0, NULL((void*)0) }
963};
964
965/* Table 7.5.3.14-1 laaMsgType definition */
966static const range_string laaMsgTypes[] = {
967 {0, 0, "LBT_PDSCH_REQ - lls - O-DU to O-RU request to obtain a PDSCH channel"},
968 {1, 1, "LBT_DRS_REQ - lls - O-DU to O-RU request to obtain the channel and send DRS"},
969 {2, 2, "LBT_PDSCH_RSP - O-RU to O-DU response, channel acq success or failure"},
970 {3, 3, "LBT_DRS_RSP - O-RU to O-DU response, DRS sending success or failure"},
971 {4, 4, "LBT_Buffer_Error - O-RU to O-DU response, reporting buffer overflow"},
972 {5, 5, "LBT_CWCONFIG_REQ - O-DU to O-RU request, congestion window configuration"},
973 {6, 6, "LBT_CWCONFIG_RST - O-RU to O-DU request, congestion window config, response"},
974 {7, 15, "reserved for future methods"},
975 {0, 0, NULL((void*)0)}
976};
977
978/* 7.7.26.3 */
979static const range_string freq_offset_fb_values[] = {
980 {0, 0, "no frequency offset"},
981 {8000, 8000, "value not provided"},
982 {1, 30000, "positive frequency offset, (0, +0.5] subcarrier"},
983 {0x8ad0, 0xffff, "negative frequency offset, [-0.5, 0) subcarrier"},
984 {0x0, 0xffff, "reserved"},
985 {0, 0, NULL((void*)0)}
986};
987
988/* Table 7.5.2.19-1 */
989static const value_string num_sinr_per_prb_vals[] = {
990 { 0, "1" },
991 { 1, "2" },
992 { 2, "3" },
993 { 3, "4" },
994 { 4, "6" },
995 { 5, "12" },
996 { 6, "1 SINR value per section for DFT-s-OFDM" },
997 { 7, "reserved" },
998 { 0, NULL((void*)0)}
999};
1000
1001static const value_string meas_type_id_vals[] = {
1002 { 1, "UE Timing Advance Error" },
1003 { 2, "UE Layer power" },
1004 { 3, "UE frequency offset" },
1005 { 4, "Interference plus Noise for allocated PRBs" },
1006 { 5, "Interference plus Noise for unallocated PRBs" },
1007 { 6, "DMRS-SNR per antenna" },
1008 { 7, "UE positioning measurement report" },
1009 { 8, "UE radial speed measurement report" },
1010 { 9, "UE post-equalization MU inteference measurement" },
1011 { 10, "UE TPMI and rank recommendation measurement" },
1012 { 11, "UE layer pre-equalization SINR report" },
1013 { 0, NULL((void*)0)}
1014};
1015
1016static const value_string beam_type_vals[] = {
1017 { 0, "List of beamId values" },
1018 { 1, "Range of beamId values" },
1019 { 0, NULL((void*)0)}
1020};
1021
1022/* 7.7.24.3 */
1023static const value_string entry_type_vals[] = {
1024 { 0, "inherit config from preceding entry (2 or 3) ueIdReset=0" },
1025 { 1, "inherit config from preceding entry (2 or 3) ueIdReset=1" },
1026 { 2, "related parameters if have transform precoding disabled " },
1027 { 3, "related parameters if have transform precoding enabled " },
1028 { 0, NULL((void*)0)}
1029};
1030
1031/* Table 7.7.29.3-1 */
1032static const range_string cd_scg_size_vals[] = {
1033 { 0, 0, "1 subcarrier" },
1034 { 1, 1, "1 RB x N subcarriers" },
1035 { 2, 2, "2 RB x N subcarriers" },
1036 { 3, 3, "4 RB x N subcarriers" },
1037 { 4, 4, "8 RB x N subcarriers" },
1038 { 5, 5, "16 RB x N subcarriers" },
1039 { 6, 6, "32 RB x N subcarriers" },
1040 { 7, 15, "reserved"},
1041 { 0, 0, NULL((void*)0)}
1042};
1043
1044
1045/* Table 7.6.1-1 */
1046static const value_string exttype_vals[] = {
1047 {0, "Reserved"},
1048 {1, "Beamforming weights"},
1049 {2, "Beamforming attributes"},
1050 {3, "DL Precoding configuration parameters and indications"},
1051 {4, "Modulation compr. params"},
1052 {5, "Modulation compression additional scaling parameters"},
1053 {6, "Non-contiguous PRB allocation"},
1054 {7, "Multiple-eAxC designation"},
1055 {8, "Regularization factor"},
1056 {9, "Dynamic Spectrum Sharing parameters"},
1057 {10, "Multiple ports grouping"},
1058 {11, "Flexible BF weights"},
1059 {12, "Non-Contiguous PRB Allocation with Frequency Ranges"},
1060 {13, "PRB Allocation with Frequency Hopping"},
1061 {14, "Nulling-layer Info. for ueId-based beamforming"},
1062 {15, "Mixed-numerology Info. for ueId-based beamforming"},
1063 {16, "Section description for antenna mapping in UE channel information based UL beamforming"},
1064 {17, "Section description for indication of user port group"},
1065 {18, "Section description for Uplink Transmission Management"},
1066 {19, "Compact beamforming information for multiple port"},
1067 {20, "Puncturing extension"},
1068 {21, "Variable PRB group size for channel information"},
1069 {22, "ACK/NACK request"},
1070 {23, "Multiple symbol modulation compression parameters"},
1071 {24, "PUSCH DMRS configuration"},
1072 {25, "Symbol reordering for DMRS-BF"},
1073 {26, "Frequency offset feedback"},
1074 {27, "O-DU controlled dimensionality reduction"},
1075 {28, "O-DU controlled frequency resolution for SINR reporting"},
1076 {29, "Cyclic delay adjustment"},
1077 {30, "PUSCH repetition indication"},
1078 {31, "MCS Information"},
1079 {32, "Rank and TPMI measurement request"},
1080 {0, NULL((void*)0)}
1081};
1082static 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) }
;
1083
1084
1085/**************************************************************************************/
1086/* Keep track for each Section Extension, which section types are allowed to carry it */
1087typedef struct {
1088 bool_Bool ST0;
1089 bool_Bool ST1;
1090 bool_Bool ST3;
1091 bool_Bool ST5;
1092 bool_Bool ST6;
1093 bool_Bool ST10;
1094 bool_Bool ST11;
1095} AllowedCTs_t;
1096
1097
1098static const AllowedCTs_t ext_cts[HIGHEST_EXTTYPE32] = {
1099 /* ST0 ST1 ST3 ST5 ST6 ST10 ST11 */
1100 { false0, true1, true1, false0, false0, false0, false0}, // SE 1 (1,3)
1101 { false0, true1, true1, false0, false0, false0, false0}, // SE 2 (1,3)
1102 { false0, true1, true1, false0, false0, false0, false0}, // SE 3 (1,3)
1103 { false0, true1, true1, true1, false0, false0, false0}, // SE 4 (1,3,5)
1104 { false0, true1, true1, true1, false0, false0, false0}, // SE 5 (1,3,5)
1105 { false0, true1, true1, true1, false0, true1, true1 }, // SE 6 (1,3,5,10,11)
1106 { true1, false0, false0, false0, false0, false0, false0}, // SE 7 (0)
1107 { false0, false0, false0, true1, false0, false0, false0}, // SE 8 (5)
1108 { true1, true1, true1, true1, true1, true1, true1 }, // SE 9 (all)
1109 { false0, true1, true1, true1, false0, false0, false0}, // SE 10 (1,3,5)
1110 { false0, true1, true1, false0, false0, false0, false0}, // SE 11 (1,3)
1111 { false0, true1, true1, true1, false0, true1, true1 }, // SE 12 (1,3,5,10,11)
1112 { false0, true1, true1, true1, false0, false0, false0}, // SE 13 (1,3,5)
1113 { false0, false0, false0, true1, false0, false0, false0}, // SE 14 (5)
1114 { false0, false0, false0, true1, true1, false0, false0}, // SE 15 (5,6)
1115 { false0, false0, false0, true1, false0, false0, false0}, // SE 16 (5)
1116 { false0, false0, false0, true1, false0, false0, false0}, // SE 17 (5)
1117 { false0, true1, true1, true1, false0, false0, false0}, // SE 18 (1,3,5)
1118 { false0, true1, true1, false0, false0, false0, false0}, // SE 19 (1,3)
1119 { true1, true1, true1, true1, true1, true1, true1 }, // SE 20 (0,1,3,5,10,11)
1120 { false0, false0, false0, true1, true1, false0, false0}, // SE 21 (5,6)
1121 { true1, true1, true1, true1, true1, true1, true1 }, // SE 22 (all)
1122 { false0, true1, true1, true1, false0, false0, false0}, // SE 23 (1,3,5)
1123 { false0, false0, false0, true1, false0, false0, false0}, // SE 24 (5)
1124 { false0, false0, false0, true1, false0, false0, false0}, // SE 25 (5)
1125 { false0, false0, false0, true1, false0, false0, false0}, // SE 26 (5)
1126 { false0, false0, false0, true1, false0, false0, false0}, // SE 27 (5)
1127 { false0, false0, false0, true1, false0, false0, false0}, // SE 28 (5)
1128 { false0, true1, true1, true1, false0, false0, false0}, // SE 29 (1,3,5)
1129 { false0, false0, false0, true1, false0, false0, false0}, // SE 30 (5)
1130 { false0, true1, true1, true1, false0, false0, false0}, // SE 31 (1,3,5)
1131 { false0, false0, false0, true1, false0, false0, false0}, // SE 32 (5)
1132};
1133
1134static bool_Bool se_allowed_in_st(unsigned se, unsigned st)
1135{
1136 if (se==0 || se>HIGHEST_EXTTYPE32) {
1137 /* Don't know about new SE, so don't complain.. */
1138 return true1;
1139 }
1140
1141 switch (st) {
1142 case 0:
1143 return ext_cts[se-1].ST0;
1144 case 1:
1145 return ext_cts[se-1].ST1;
1146 case 3:
1147 return ext_cts[se-1].ST3;
1148 case 5:
1149 return ext_cts[se-1].ST5;
1150 case 6:
1151 return ext_cts[se-1].ST6;
1152 case 10:
1153 return ext_cts[se-1].ST10;
1154 case 11:
1155 return ext_cts[se-1].ST11;
1156 default:
1157 /* New/unknown section type that includes 'ef'.. assume ok */
1158 return true1;
1159 }
1160}
1161
1162/************************************************************************************/
1163
1164/* Table 7.7.1.2-2 */
1165static const value_string bfw_comp_headers_iq_width[] = {
1166 {0, "I and Q are 16 bits wide"},
1167 {1, "I and Q are 1 bit wide"},
1168 {2, "I and Q are 2 bits wide"},
1169 {3, "I and Q are 3 bits wide"},
1170 {4, "I and Q are 4 bits wide"},
1171 {5, "I and Q are 5 bits wide"},
1172 {6, "I and Q are 6 bits wide"},
1173 {7, "I and Q are 7 bits wide"},
1174 {8, "I and Q are 8 bits wide"},
1175 {9, "I and Q are 9 bits wide"},
1176 {10, "I and Q are 10 bits wide"},
1177 {11, "I and Q are 11 bits wide"},
1178 {12, "I and Q are 12 bits wide"},
1179 {13, "I and Q are 13 bits wide"},
1180 {14, "I and Q are 14 bits wide"},
1181 {15, "I and Q are 15 bits wide"},
1182 {0, NULL((void*)0)}
1183};
1184
1185/* Table 7.7.1.2-3 */
1186static const value_string bfw_comp_headers_comp_meth[] = {
1187 {COMP_NONE0, "no compression"},
1188 {COMP_BLOCK_FP1, "block floating point"},
1189 {COMP_BLOCK_SCALE2, "block scaling"},
1190 {COMP_U_LAW3, "u-law"},
1191 {4, "beamspace compression type I"},
1192 {5, "beamspace compression type II"},
1193 {0, NULL((void*)0)}
1194};
1195
1196/* 7.7.6.2 rbgSize (resource block group size) */
1197static const value_string rbg_size_vals[] = {
1198 {0, "reserved"},
1199 {1, "1"},
1200 {2, "2"},
1201 {3, "3"},
1202 {4, "4"},
1203 {5, "6"},
1204 {6, "8"},
1205 {7, "16"},
1206 {0, NULL((void*)0)}
1207};
1208
1209/* 7.7.6.5 */
1210static const value_string priority_vals[] = {
1211 {0, "0"},
1212 {1, "+1"},
1213 {2, "-2 (reserved, should not be used)"},
1214 {3, "-1"},
1215 {0, NULL((void*)0)}
1216};
1217
1218/* 7.7.10.2 beamGroupType */
1219static const value_string beam_group_type_vals[] = {
1220 {0x0, "common beam"},
1221 {0x1, "beam matrix indication"},
1222 {0x2, "beam vector listing"},
1223 {0x3, "beamId/ueId listing with associated port-list index"},
1224 {0, NULL((void*)0)}
1225};
1226
1227/* 7.7.9.2 technology (interface name) */
1228static const value_string interface_name_vals[] = {
1229 {0x0, "LTE"},
1230 {0x1, "NR"},
1231 {0, NULL((void*)0)}
1232};
1233
1234/* 7.7.18.4 toT (type of transmission) */
1235static const value_string type_of_transmission_vals[] = {
1236 {0x0, "normal transmission mode, data can be distributed in any way the O-RU is implemented to transmit data"},
1237 {0x1, "uniformly distributed over the transmission window"},
1238 {0x2, "Reserved"},
1239 {0x3, "Reserved"},
1240 {0, NULL((void*)0)}
1241};
1242
1243/* 7.7.2.2 (width of bfa parameters) */
1244static const value_string bfa_bw_vals[] = {
1245 {0, "no bits, the field is not applicable (e.g., O-RU does not support it) or the default value shall be used"},
1246 {1, "2-bit bitwidth"},
1247 {2, "3-bit bitwidth"},
1248 {3, "4-bit bitwidth"},
1249 {4, "5-bit bitwidth"},
1250 {5, "6-bit bitwidth"},
1251 {6, "7-bit bitwidth"},
1252 {7, "8-bit bitwidth"},
1253 {0, NULL((void*)0)}
1254};
1255
1256/* 7.7.2.7 & 7.7.2.8 */
1257static const value_string sidelobe_suppression_vals[] = {
1258 {0, "10 dB"},
1259 {1, "15 dB"},
1260 {2, "20 dB"},
1261 {3, "25 dB"},
1262 {4, "30 dB"},
1263 {5, "35 dB"},
1264 {6, "40 dB"},
1265 {7, ">= 45 dB"},
1266 {0, NULL((void*)0)}
1267};
1268
1269static const value_string lbtTrafficClass_vals[] = {
1270 {1, "Priority 1"},
1271 {2, "Priority 2"},
1272 {3, "Priority 3"},
1273 {4, "Priority 4"},
1274 {0, NULL((void*)0)}
1275};
1276
1277/* 7.5.3.22 */
1278static const value_string lbtPdschRes_vals[] = {
1279 {0, "not sensing – indicates that the O-RU is transmitting data"},
1280 {1, "currently sensing – indicates the O-RU has not yet acquired the channel"},
1281 {2, "success – indicates that the channel was successfully acquired"},
1282 {3, "Failure – indicates expiration of the LBT timer. The LBT process should be reset"},
1283 {0, NULL((void*)0)}
1284};
1285
1286/* Table 7.5.2.15-3 */
1287static const value_string ci_comp_opt_vals[] = {
1288 {0, "compression per UE, one ciCompParam exists before the I/Q value of each UE"},
1289 {1, "compression per PRB, one ciCompParam exists before the I/Q value of each PRB"},
1290 {0, NULL((void*)0)}
1291};
1292
1293/* 7.5.2.17 */
1294static const range_string cmd_scope_vals[] = {
1295 {0, 0, "ARRAY-COMMAND"},
1296 {1, 1, "CARRIER-COMMAND"},
1297 {2, 2, "O-RU-COMMAND"},
1298 {3, 15, "reserved"},
1299 {0, 0, NULL((void*)0)}
1300};
1301
1302/* N.B., table in 7.5.3.38 is truncated.. */
1303static const range_string st4_cmd_type_vals[] = {
1304 {0, 0, "reserved for future command types"},
1305 {1, 1, "TIME_DOMAIN_BEAM_CONFIG"},
1306 {2, 2, "TDD_CONFIG_PATTERN"},
1307 {3, 3, "TRX_CONTROL"},
1308 {4, 4, "ASM"},
1309 {5, 5, "TRX_CONTROL_BIDIR"},
1310 {6, 255, "reserved for future command types"},
1311 {0, 0, NULL((void*)0)}
1312};
1313
1314/* Table 7.5.3.51-1 */
1315static const value_string log2maskbits_vals[] = {
1316 {0, "reserved"},
1317 {1, "min antMask size is 16 bits.."},
1318 {2, "min antMask size is 16 bits.."},
1319 {3, "min antMask size is 16 bits.."},
1320 {4, "16 bits"},
1321 {5, "32 bits"},
1322 {6, "64 bits"},
1323 {7, "128 bits"},
1324 {8, "256 bits"},
1325 {9, "512 bits"},
1326 {10, "1024 bits"},
1327 {11, "2048 bits"},
1328 {12, "4096 bits"},
1329 {13, "8192 bits"},
1330 {14, "16384 bits"},
1331 {15, "reserved"},
1332 {0, NULL((void*)0)}
1333};
1334
1335/* Table 16.1-1 Sleep modes */
1336static const value_string sleep_mode_trx_vals[] = {
1337 { 0, "TRXC-mode0-wake-up-duration (symbol)"},
1338 { 1, "TRXC-mode1-wake-up-duration (L)"},
1339 { 2, "TRXC-mode2-wake-up-duration (M)"},
1340 { 3, "TRXC-mode3-wake-up-duration (N)"},
1341 { 0, NULL((void*)0)}
1342};
1343
1344static const value_string sleep_mode_asm_vals[] = {
1345 { 0, "ASM-mode0-wake-up-duration (symbol)"},
1346 { 1, "ASM-mode1-wake-up-duration (L)"},
1347 { 2, "ASM-mode2-wake-up-duration (M)"},
1348 { 3, "ASM-mode3-wake-up-duration (N)"},
1349 { 0, NULL((void*)0)}
1350};
1351
1352/* 7.7.21.3.1 */
1353static const value_string prg_size_st5_vals[] = {
1354 { 0, "reserved"},
1355 { 1, "Precoding resource block group size as WIDEBAND"},
1356 { 2, "Precoding resource block group size 2"},
1357 { 3, "Precoding resource block group size 4"},
1358 { 0, NULL((void*)0)}
1359};
1360
1361/* 7.7.21.3.2 */
1362static const value_string prg_size_st6_vals[] = {
1363 { 0, "if ciPrbGroupSize is 2 or 4, then ciPrbGroupSize, else WIDEBAND"},
1364 { 1, "Precoding resource block group size as WIDEBAND"},
1365 { 2, "Precoding resource block group size 2"},
1366 { 3, "Precoding resource block group size 4"},
1367 { 0, NULL((void*)0)}
1368};
1369
1370/* 7.7.24.4 */
1371static const value_string alpn_per_sym_vals[] = {
1372 { 0, "report one allocated IPN value per all allocated symbols with DMRS"},
1373 { 1, "report one allocated IPN value per group of consecutive DMRS symbols"},
1374 { 0, NULL((void*)0)}
1375};
1376
1377/* 7.7.24.5 */
1378static const value_string ant_dmrs_snr_vals[] = {
1379 { 0, "O-RU shall not report the MEAS_ANT_DMRS_SNR"},
1380 { 1, "O-RU shall report the MEAS_ANT_DMRS_SNR"},
1381 { 0, NULL((void*)0)}
1382};
1383
1384/* 7.7.24.14 */
1385static const value_string dtype_vals[] = {
1386 { 0, "assume DMRS configuration type 1"},
1387 { 1, "assume DMRS configuration type 2"},
1388 { 0, NULL((void*)0)}
1389};
1390
1391/* 7.7.24.17 */
1392static const value_string papr_type_vals[] = {
1393 { 0, "sequence generator type 1 for short sequence lengths"},
1394 { 1, "sequence generator type 1 for long sequence lengths"},
1395 { 2, "sequence generator type 2 for short sequence lengths"},
1396 { 3, "sequence generator type 2 for long sequence lengths"},
1397 { 0, NULL((void*)0)}
1398};
1399
1400/* 7.7.24.18 */
1401static const value_string hopping_mode_vals[] = {
1402 { 0, "neither group, nor sequence hopping is enabled"},
1403 { 1, "group hopping is enabled and sequence hopping is disabled"},
1404 { 2, "sequence hopping is enabled and group hopping is disabled"},
1405 { 3, "reserved"},
1406 { 0, NULL((void*)0)}
1407};
1408
1409/* Table 7.7.31.2-1 */
1410static const value_string mcs_table_vals[] = {
1411 { 0, "MCS index table 1 for PDSCH and PUSCH without transform precoding" },
1412 { 1, "MCS index table 2 for PDSCH and PUSCH without transform precoding" },
1413 { 2, "MCS index table 3 for PDSCH and PUSCH without transform precoding" },
1414 { 3, "MCS index table 4 for PDSCH" },
1415 { 4, "MCS index table for PUSCH with transform precoding and 64QAM" },
1416 { 5, "MCS index table 2 for PUSCH with transform precoding and 64QAM" },
1417 { 0, NULL((void*)0)}
1418};
1419
1420/* 7.7.32.9 */
1421static const value_string full_pwr_mode_vals[] = {
1422 { 0, "not configured"},
1423 { 1, "full power mode 0"},
1424 { 2, "full power mode 1"},
1425 { 3, "full power mode 2"},
1426 { 0, NULL((void*)0)}
1427};
1428
1429
1430static const true_false_string tfs_sfStatus =
1431{
1432 "subframe was transmitted",
1433 "subframe was dropped"
1434};
1435
1436static const true_false_string tfs_lbtBufErr =
1437{
1438 "buffer overflow – data received at O-RU is larger than the available buffer size",
1439 "reserved"
1440};
1441
1442static const true_false_string tfs_partial_full_sf = {
1443 "partial SF",
1444 "full SF"
1445};
1446
1447static const true_false_string disable_tdbfns_tfs = {
1448 "beam numbers excluded",
1449 "beam numbers included"
1450};
1451
1452static const true_false_string continuity_indication_tfs = {
1453 "continuity between current and next bundle",
1454 "discontinuity between current and next bundle"
1455};
1456
1457static const true_false_string prb_mode_tfs = {
1458 "PRB-BLOCK mode",
1459 "PRB-MASK mode"
1460};
1461
1462static const true_false_string symbol_direction_tfs = {
1463 "DL symbol",
1464 "UL symbol"
1465};
1466
1467static const true_false_string symbol_guard_tfs = {
1468 "guard symbol",
1469 "non-guard symbol"
1470};
1471
1472static const true_false_string beam_numbers_included_tfs = {
1473 "time-domain beam numbers excluded in this command",
1474 "time-domain beam numbers included in this command"
1475};
1476
1477static const true_false_string measurement_flag_tfs = {
1478 "at least one additional measurement report or command after the current one",
1479 "no additional measurement report or command"
1480};
1481
1482static const true_false_string repetition_se6_tfs = {
1483 "repeated highest priority data section in the C-Plane message",
1484 "no repetition"
1485};
1486
1487static const true_false_string repetition_se19_tfs = {
1488 "per port information not present in the extension",
1489 "per port info present in the extension"
1490};
1491
1492static const true_false_string tfs_report_no_report_pos_meas =
1493{
1494 "Report MEAS_UE_POS for UE",
1495 "Do not report UE_POS for UE"
1496};
1497
1498
1499/* Forward declaration */
1500static int dissect_udcompparam(tvbuff_t *tvb, packet_info *pinfo _U___attribute__((unused)), proto_tree *tree, unsigned offset,
1501 unsigned comp_meth,
1502 uint32_t *exponent, uint16_t *sReSMask, bool_Bool for_sinr);
1503
1504
1505static const true_false_string ready_tfs = {
1506 "message is a \"ready\" message",
1507 "message is a ACK message"
1508};
1509
1510static const true_false_string multi_sd_scope_tfs = {
1511 "Puncturing pattern applies to current and following sections",
1512 "Puncturing pattern applies to current section"
1513};
1514
1515static const true_false_string tfs_ueid_reset = {
1516 "cannot assume same UE as in preceding slot",
1517 "can assume same UE as in preceding slot"
1518};
1519
1520
1521/* Config for (and later, worked-out allocations) bundles for ext11 (dynamic BFW) */
1522typedef struct {
1523 /* Ext 6 config */
1524 bool_Bool ext6_set;
1525 uint8_t ext6_rbg_size; /* number of PRBs allocated by bitmask */
1526
1527 uint8_t ext6_num_bits_set;
1528 uint8_t ext6_bits_set[28]; /* Which bit position this entry has */
1529 /* TODO: store an f value for each bit position? */
1530
1531 /* Ext 12 config */
1532 bool_Bool ext12_set;
1533 unsigned ext12_num_pairs;
1534#define MAX_BFW_EXT12_PAIRS128 128
1535 struct {
1536 uint8_t off_start_prb;
1537 uint8_t num_prb;
1538 } ext12_pairs[MAX_BFW_EXT12_PAIRS128];
1539
1540 /* Ext 13 config */
1541 bool_Bool ext13_set;
1542 unsigned ext13_num_start_prbs;
1543#define MAX_BFW_EXT13_ALLOCATIONS128 128
1544 unsigned ext13_start_prbs[MAX_BFW_EXT13_ALLOCATIONS128];
1545 /* TODO: store nextSymbolId here too? */
1546
1547 /* Ext 21 config */
1548 bool_Bool ext21_set;
1549 uint8_t ext21_ci_prb_group_size;
1550
1551 /* Results/settings (after calling ext11_work_out_bundles()) */
1552 uint32_t num_bundles;
1553#define MAX_BFW_BUNDLES512 512
1554 struct {
1555 uint32_t start; /* first prb of bundle */
1556 uint32_t end; /* last prb of bundle*/
1557 bool_Bool is_orphan; /* true if not complete (i.e., end-start < numBundPrb) */
1558 } bundles[MAX_BFW_BUNDLES512];
1559} ext11_settings_t;
1560
1561
1562/* Work out bundle allocation for ext 11. Take into account ext6/ext21, ext12 or ext13 in this section before ext 11. */
1563/* Won't be called with numBundPrb=0 */
1564static void ext11_work_out_bundles(unsigned startPrbc,
1565 unsigned numPrbc,
1566 unsigned numBundPrb, /* number of PRBs per (full) bundle */
1567 ext11_settings_t *settings)
1568{
1569 /* Allocation configured by ext 6 */
1570 if (settings->ext6_set) {
1571 unsigned bundles_per_entry = (settings->ext6_rbg_size / numBundPrb);
1572
1573 /* Need to cope with these not dividing exactly, or even having more PRbs in a bundle that
1574 rbg size. i.e. each bundle gets the correct number of PRBs until
1575 all rbg entries are consumed... */
1576
1577 /* TODO: need to check 7.9.4.2. Different cases depending upon value of RAD */
1578
1579 if (bundles_per_entry == 0) {
1580 bundles_per_entry = 1;
1581 }
1582
1583 /* Ext6 behaviour may also be affected by ext 21 */
1584 if (settings->ext21_set) {
1585 /* N.B., have already checked that numPrbc is not 0 */
1586
1587 /* ciPrbGroupSize overrides number of contiguous PRBs in group */
1588 bundles_per_entry = (settings->ext6_rbg_size / settings->ext21_ci_prb_group_size);
1589
1590 /* numPrbc is the number of PRB groups per antenna - handled in call to dissect_bfw_bundle() */
1591 }
1592
1593 unsigned bundles_set = 0;
1594 bool_Bool reached_orphan = false0;
1595 /* For each bit set in ext6 rbg mask.. */
1596 for (unsigned n=0;
1597 !reached_orphan && n < (settings->ext6_num_bits_set * settings->ext6_rbg_size) / numBundPrb;
1598 n++) {
1599
1600 /* Watch out for array bound */
1601 if (n >= 28) {
1602 break;
1603 }
1604
1605 /* For each bundle... */
1606
1607 /* TODO: Work out where first PRB is */
1608 /* May not be the start of an rbg block... */
1609 uint32_t prb_start = (settings->ext6_bits_set[n] * settings->ext6_rbg_size);
1610
1611 /* For each bundle within identified rbgSize block */
1612 for (unsigned m=0; !reached_orphan && m < bundles_per_entry; m++) {
1613
1614 settings->bundles[bundles_set].start = startPrbc+prb_start+(m*numBundPrb);
1615
1616 /* Start already beyond end, so doesn't count. */
1617 if (settings->bundles[bundles_set].start > (startPrbc+numPrbc-1)) {
1618 settings->num_bundles = bundles_set;
1619 return;
1620 }
1621
1622 /* Bundle consists of numBundPrb bundles */
1623 /* TODO: may involve PRBs from >1 rbg blocks.. */
1624 settings->bundles[bundles_set].end = startPrbc+prb_start+((m+1)*numBundPrb)-1;
1625 if (settings->bundles[bundles_set].end > (startPrbc+numPrbc-1)) {
1626 /* Extends beyond end, so counts but is an orphan bundle */
1627 settings->bundles[bundles_set].end = startPrbc+numPrbc-1;
1628 settings->bundles[bundles_set].is_orphan = true1;
1629 reached_orphan = true1;
1630 }
1631
1632 /* Get out if have reached array bound */
1633 if (++bundles_set == MAX_BFW_BUNDLES512) {
1634 return;
1635 }
1636 }
1637 }
1638 settings->num_bundles = bundles_set;
1639 }
1640
1641 /* Allocation configured by ext 12 */
1642 else if (settings->ext12_set) {
1643 /* First, allocate normally from startPrbc, numPrbc */
1644 settings->num_bundles = (numPrbc+numBundPrb-1) / numBundPrb;
1645
1646 /* Don't overflow settings->bundles[] ! */
1647 settings->num_bundles = MIN(MAX_BFW_BUNDLES, settings->num_bundles)(((512) < (settings->num_bundles)) ? (512) : (settings->
num_bundles))
;
1648
1649 for (uint32_t n=0; n < settings->num_bundles; n++) {
1650 settings->bundles[n].start = startPrbc + n*numBundPrb;
1651 settings->bundles[n].end = settings->bundles[n].start + numBundPrb-1;
1652 /* Does it go beyond the end? */
1653 if (settings->bundles[n].end > startPrbc+numPrbc) {
1654 settings->bundles[n].end = startPrbc+numPrbc;
1655 settings->bundles[n].is_orphan = true1;
1656 }
1657 }
1658 if (settings->num_bundles == MAX_BFW_BUNDLES512) {
1659 return;
1660 }
1661
1662 unsigned prb_offset = startPrbc + numPrbc;
1663
1664 /* Loop over pairs, adding bundles for each */
1665 for (unsigned p=0; p < settings->ext12_num_pairs; p++) {
1666 prb_offset += settings->ext12_pairs[p].off_start_prb;
1667 unsigned pair_bundles = (settings->ext12_pairs[p].num_prb+numBundPrb-1) / numBundPrb;
1668
1669 for (uint32_t n=0; n < pair_bundles; n++) {
1670 unsigned idx = settings->num_bundles;
1671
1672 settings->bundles[idx].start = prb_offset + n*numBundPrb;
1673 settings->bundles[idx].end = settings->bundles[idx].start + numBundPrb-1;
1674 /* Does it go beyond the end? */
1675 if (settings->bundles[idx].end > prb_offset + settings->ext12_pairs[p].num_prb) {
1676 settings->bundles[idx].end = prb_offset + settings->ext12_pairs[p].num_prb;
1677 settings->bundles[idx].is_orphan = true1;
1678 }
1679 /* Range check / return */
1680 settings->num_bundles++;
1681 if (settings->num_bundles == MAX_BFW_BUNDLES512) {
1682 return;
1683 }
1684 }
1685
1686 prb_offset += settings->ext12_pairs[p].num_prb;
1687 }
1688 }
1689
1690 /* Allocation configured by ext 13 */
1691 else if (settings->ext13_set) {
1692 unsigned alloc_size = (numPrbc+numBundPrb-1) / numBundPrb;
1693 settings->num_bundles = alloc_size * settings->ext13_num_start_prbs;
1694
1695 /* Don't overflow settings->bundles[] ! */
1696 settings->num_bundles = MIN(MAX_BFW_BUNDLES, settings->num_bundles)(((512) < (settings->num_bundles)) ? (512) : (settings->
num_bundles))
;
1697
1698 for (unsigned alloc=0; alloc < settings->ext13_num_start_prbs; alloc++) {
1699 unsigned alloc_start = alloc * alloc_size;
1700 for (uint32_t n=0; n < alloc_size; n++) {
1701 if ((alloc_start+n) >= MAX_BFW_BUNDLES512) {
1702 /* ERROR */
1703 return;
1704 }
1705 settings->bundles[alloc_start+n].start = settings->ext13_start_prbs[alloc] + startPrbc + n*numBundPrb;
1706 settings->bundles[alloc_start+n].end = settings->bundles[alloc_start+n].start + numBundPrb-1;
1707 if (settings->bundles[alloc_start+n].end > settings->ext13_start_prbs[alloc] + numPrbc) {
1708 settings->bundles[alloc_start+n].end = settings->ext13_start_prbs[alloc] + numPrbc;
1709 settings->bundles[alloc_start+n].is_orphan = true1;
1710 }
1711 }
1712 }
1713 }
1714
1715 /* Case where bundles are not controlled by other extensions - just divide up range into bundles we have */
1716 else {
1717 settings->num_bundles = (numPrbc+numBundPrb-1) / numBundPrb; /* rounded up */
1718
1719 /* Don't overflow settings->bundles[] */
1720 settings->num_bundles = MIN(MAX_BFW_BUNDLES, settings->num_bundles)(((512) < (settings->num_bundles)) ? (512) : (settings->
num_bundles))
;
1721
1722 /* For each bundle.. */
1723 for (uint32_t n=0; n < settings->num_bundles; n++) {
1724 /* Allocate start and end */
1725 settings->bundles[n].start = startPrbc + n*numBundPrb;
1726 settings->bundles[n].end = settings->bundles[n].start + numBundPrb - 1;
1727 /* If would go beyond end of PRBs, limit and identify as orphan */
1728 if (settings->bundles[n].end > startPrbc+numPrbc) {
1729 settings->bundles[n].end = startPrbc+numPrbc;
1730 settings->bundles[n].is_orphan = true1;
1731 }
1732 }
1733 }
1734}
1735
1736
1737/* Modulation Compression configuration */
1738typedef struct {
1739 /* Application of each entry is filtered by RE.
1740 * TODO: should also be filtered by PRB + symbol... */
1741 uint16_t mod_compr_re_mask;
1742
1743 /* Settings to apply */
1744 bool_Bool mod_compr_csf;
1745 float mod_compr_scaler;
1746} mod_compr_config_t;
1747
1748/* Multiple configs with a section */
1749typedef struct {
1750 uint16_t section_id;
1751 uint32_t num_configs;
1752
1753 #define MAX_MOD_COMPR_CONFIGS12 12
1754 mod_compr_config_t configs[MAX_MOD_COMPR_CONFIGS12];
1755} section_mod_compr_config_t;
1756
1757/* Flow has separate configs for each section */
1758typedef struct {
1759 uint16_t num_sections;
1760
1761 /* Separate config for each section */
1762 section_mod_compr_config_t sections[MAX_SECTION_IDs32];
1763} mod_compr_params_t;
1764
1765
1766typedef struct {
1767 uint32_t frame_number;
1768 nstime_t frame_time;
1769
1770 /* Timing to match */
1771 uint8_t frame;
1772 uint8_t subframe;
1773 uint8_t slot;
1774 uint8_t startSymbol;
1775
1776 bool_Bool in_use;
1777 uint16_t startPrb;
1778 uint16_t numPrb;
1779 uint16_t numSymbols;
1780 uint16_t beamIds[273];
1781} section_details_t;
1782
1783typedef struct {
1784 uint16_t sectionId;
1785 /* For the same sectionId, can have 2 currently active entries.. */
1786 section_details_t details[2];
1787} expected_section_data_t;
1788
1789
1790/*******************************************************/
1791/* Overall state of a flow (eAxC/plane) */
1792typedef struct {
1793 /* State for sequence analysis [each direction] */
1794 bool_Bool last_frame_seen[2];
1795 uint32_t last_frame[2];
1796 uint8_t next_expected_sequence_number[2];
1797
1798 /* expected frames. sectionId -> expected_section_data_t* */
1799 wmem_tree_t *expected_sections[2]; /* [direction] */
1800
1801 /* Table recording ackNack requests (ackNackId -> ack_nack_request_t*)
1802 Note that this assumes that the same ackNackId will not be reused within a state,
1803 which may well not be valid */
1804 wmem_tree_t *ack_nack_requests;
1805
1806 /* Store udCompHdr seen in C-Plane for UL - can be looked up and used by U-PLane.
1807 Note that this appears in the common section header parts of ST1, ST3, ST5,
1808 so can still be over-written per sectionId in the U-Plane */
1809 unsigned ul_ud_comp_hdr_frame;
1810 bool_Bool ul_ud_comp_hdr_set;
1811 unsigned ul_ud_comp_hdr_bit_width;
1812 int ul_ud_comp_hdr_compression;
1813
1814 bool_Bool udcomphdrDownlink_heuristic_result_set;
1815 bool_Bool udcomphdrDownlink_heuristic_result;
1816 bool_Bool udcomphdrUplink_heuristic_result_set;
1817 bool_Bool udcomphdrUplink_heuristic_result;
1818
1819 /* Modulation compression params */
1820 mod_compr_params_t mod_comp_params;
1821} flow_state_t;
1822
1823static section_mod_compr_config_t* get_mod_compr_section_to_write(flow_state_t *flow,
1824 unsigned sectionId)
1825{
1826 if (flow == NULL((void*)0)) {
1827 return NULL((void*)0);
1828 }
1829
1830 /* Look for this section among existing entries */
1831 for (unsigned s=0; s < flow->mod_comp_params.num_sections; s++) {
1832 if (flow->mod_comp_params.sections[s].section_id == sectionId) {
1833 return &flow->mod_comp_params.sections[s];
1834 }
1835 }
1836
1837 /* Not found, so try to add a new one */
1838 if (flow->mod_comp_params.num_sections >= MAX_SECTION_IDs32) {
1839 /* Can't allocate one! */
1840 return NULL((void*)0);
1841 }
1842 else {
1843 flow->mod_comp_params.sections[flow->mod_comp_params.num_sections].section_id = sectionId;
1844 return &flow->mod_comp_params.sections[flow->mod_comp_params.num_sections++];
1845 }
1846}
1847
1848static section_mod_compr_config_t* get_mod_compr_section_to_read(flow_state_t *flow,
1849 unsigned sectionId)
1850{
1851 if (flow == NULL((void*)0)) {
1852 return NULL((void*)0);
1853 }
1854
1855 /* Look for this section among existing entries */
1856 for (unsigned s=0; s < flow->mod_comp_params.num_sections; s++) {
1857 if (flow->mod_comp_params.sections[s].section_id == sectionId) {
1858 return &flow->mod_comp_params.sections[s];
1859 }
1860 }
1861
1862 /* Not found */
1863 return NULL((void*)0);
1864}
1865
1866
1867
1868typedef struct {
1869 uint32_t request_frame_number;
1870 nstime_t request_frame_time;
1871 enum {
1872 SE22,
1873 ST4Cmd1,
1874 ST4Cmd2,
1875 ST4Cmd3,
1876 ST4Cmd4
1877 } requestType;
1878
1879 uint32_t response_frame_number;
1880 nstime_t response_frame_time;
1881} ack_nack_request_t;
1882
1883static const value_string acknack_type_vals[] = {
1884 { SE22, "SE 22" },
1885 { ST4Cmd1, "ST4 (TIME_DOMAIN_BEAM_CONFIG)" },
1886 { ST4Cmd2, "ST4 (TDD_CONFIG_PATTERN)" },
1887 { ST4Cmd3, "ST4 (TRX_CONTROL)" },
1888 { ST4Cmd4, "ST4 (ASM)" },
1889 { 0, NULL((void*)0)}
1890};
1891
1892#define ORAN_C_PLANE0 0
1893#define ORAN_U_PLANE1 1
1894
1895/* Using parts of src/dst MAC address, so don't confuse UL messages with DL messages configuring UL.. */
1896static uint32_t make_flow_key(packet_info *pinfo, uint16_t eaxc_id, uint8_t plane, bool_Bool opposite_dir)
1897{
1898 uint16_t eth_bits = 0;
1899 if (pinfo->dl_src.len == 6 && pinfo->dl_dst.len == 6) {
1900 /* Only using (most of) 2 bytes from addresses for now, but reluctant to make key longer.. */
1901 const uint8_t *src_eth = (uint8_t*)pinfo->dl_src.data;
1902 const uint8_t *dst_eth = (uint8_t*)pinfo->dl_dst.data;
1903 if (!opposite_dir) {
1904 eth_bits = (src_eth[0]<<8) | dst_eth[5];
1905 }
1906 else {
1907 eth_bits = (dst_eth[0]<<8) | src_eth[5];
1908 }
1909 }
1910 return eaxc_id | (plane << 16) | (eth_bits << 17);
1911}
1912
1913
1914/* Table maintained on first pass from flow_key(uint32_t) -> flow_state_t* */
1915static wmem_tree_t *flow_states_table;
1916
1917typedef struct {
1918 uint32_t frame_number;
1919 uint16_t sectionId;
1920 uint32_t gap_in_usecs;
1921 /* TODO: could add PRB, symbol ranges here too? */
1922} corresponding_uplane_frame;
1923
1924/* Table consulted on subsequent passes: frame_num -> flow_result_t* */
1925static wmem_tree_t *flow_results_table;
1926
1927typedef struct {
1928 /* Sequence analysis */
1929 bool_Bool unexpected_seq_number;
1930 uint8_t expected_sequence_number;
1931 uint32_t previous_frame;
1932
1933 /* sectionId -> expected_section_data_t* */
1934 /* Frame only covers one direction */
1935 wmem_tree_t *expected_sections;
1936
1937 /* List of u-plane frames (corresponding_uplane_frame*) corresponding to a c-plane frame */
1938 wmem_list_t *u_plane_frames;
1939} flow_result_t;
1940
1941
1942/* Uplink timing */
1943/* For a given symbol, track first to last UL frame to find out first-last time */
1944/* frameId (8) + subframeId (4) + slotId (6) + symbolId (6) = 24 bits */
1945/* N.B. if a capture lasts > 2.5s, may see same timing come around again... */
1946static uint32_t get_timing_key(uint8_t frameId, uint8_t subframeId, uint8_t slotId, uint8_t symbolId)
1947{
1948 return symbolId + (slotId<<8) + (subframeId<<14) + (frameId<<18);
1949}
1950
1951typedef struct {
1952 uint32_t first_frame;
1953 nstime_t first_frame_time;
1954 uint32_t frames_seen_in_symbol;
1955 uint32_t last_frame_in_symbol;
1956} ul_timing_for_slot;
1957
1958/* Set during first pass. timing_key -> ul_timing_for_slot* */
1959static wmem_tree_t *ul_symbol_timing;
1960
1961
1962/* Tracking lifetimes of DL beamIds */
1963typedef struct {
1964 uint32_t frame_defined;
1965 uint32_t symbol_when_defined;
1966} bfw_definition;
1967
1968/* Maintained during first pass: beamId (from ext11) -> bfw_definition */
1969static wmem_tree_t *dl_beam_ids_defined;
1970/* Lookup where/when beamIds were defined (frameid:beamid) -> bfw_definition */
1971static wmem_tree_t *dl_beam_ids_results;
1972
1973
1974static void show_link_to_acknack_response(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo,
1975 ack_nack_request_t *response);
1976
1977
1978
1979
1980static void write_pdu_label_and_info(proto_item *ti1, proto_item *ti2,
1981 packet_info *pinfo, const char *format, ...) G_GNUC_PRINTF(4, 5)__attribute__((__format__ (__printf__, 4, 5)));
1982
1983 /* Write the given formatted text to:
1984 - the info column (if pinfo != NULL)
1985 - 1 or 2 other labels (optional)
1986 */
1987static void write_pdu_label_and_info(proto_item *ti1, proto_item *ti2,
1988 packet_info *pinfo, const char *format, ...)
1989{
1990#define MAX_INFO_BUFFER256 256
1991 char info_buffer[MAX_INFO_BUFFER256];
1992 va_list ap;
1993
1994 if ((ti1 == NULL((void*)0)) && (ti2 == NULL((void*)0)) && (pinfo == NULL((void*)0))) {
1995 return;
1996 }
1997
1998 va_start(ap, format)__builtin_va_start(ap, format);
1999 vsnprintf(info_buffer, MAX_INFO_BUFFER256, format, ap);
2000 va_end(ap)__builtin_va_end(ap);
2001
2002 /* Add to indicated places */
2003 if (pinfo != NULL((void*)0)) {
2004 col_append_str(pinfo->cinfo, COL_INFO, info_buffer);
2005 }
2006 if (ti1 != NULL((void*)0)) {
2007 proto_item_append_text(ti1, "%s", info_buffer);
2008 }
2009 if (ti2 != NULL((void*)0)) {
2010 proto_item_append_text(ti2, "%s", info_buffer);
2011 }
2012}
2013
2014/* Add section labels (type + PRB range) for C-Plane, U-Plane */
2015static void
2016write_section_info(proto_item *section_heading, packet_info *pinfo, proto_item *protocol_item,
2017 uint32_t section_id, uint32_t start_prbx, uint32_t num_prbx, uint32_t rb)
2018{
2019 switch (num_prbx) {
2020 case 0:
2021 /* None -> all */
2022 write_pdu_label_and_info(section_heading, protocol_item, pinfo, ", Id: %4d (all PRBs)", section_id);
2023 break;
2024 case 1:
2025 /* Single PRB */
2026 write_pdu_label_and_info(section_heading, protocol_item, pinfo, ", Id: %4d (PRB: %7u)", section_id, start_prbx);
2027 break;
2028 default:
2029 /* Range */
2030 write_pdu_label_and_info(section_heading, protocol_item, pinfo, ", Id: %4d (PRB: %3u-%3u%s)", section_id, start_prbx,
2031 start_prbx + (num_prbx-1)*(1+rb), rb ? " (every-other)" : "");
2032 }
2033}
2034
2035static void
2036write_channel_section_info(proto_item *section_heading, packet_info *pinfo,
2037 uint32_t section_id, uint32_t ueId, uint32_t start_prbx, uint32_t num_prbx,
2038 uint32_t num_trx)
2039{
2040 switch (num_prbx) {
2041 case 0:
2042 /* TODO: ?? */
2043 break;
2044 case 1:
2045 /* Single PRB */
2046 write_pdu_label_and_info(section_heading, NULL((void*)0), pinfo,
2047 ", Id: %4d (UEId=%5u PRB %7u, %2u antennas)",
2048 section_id, ueId, start_prbx, num_trx);
2049 break;
2050 default:
2051 /* Range */
2052 write_pdu_label_and_info(section_heading, NULL((void*)0), pinfo,
2053 ", Id: %4d (UEId=%5u PRBs %3u-%3u, %2u antennas)",
2054 section_id, ueId, start_prbx, start_prbx+num_prbx-1, num_trx);
2055 }
2056}
2057
2058/* Add a reserved field, and warn if value isn't 0 */
2059/* TODO: maybe add a pref not to output expert warning if becomes too annoying? */
2060static void add_reserved_field(proto_tree *tree, int hf, tvbuff_t *tvb, int offset, int len)
2061{
2062 uint32_t reserved;
2063 proto_item *res_ti = proto_tree_add_item_ret_uint(tree, hf, tvb, offset, len, ENC_NA0x00000000, &reserved);
2064 if (reserved != 0) {
2065 expert_add_info_format(NULL((void*)0), res_ti, &ei_oran_reserved_not_zero,
2066 "reserved field saw value of 0x%x", reserved);
2067 }
2068}
2069
2070/* 5.1.3.2.7 (real time control data / IQ data transfer message series identifier) */
2071static void
2072addPcOrRtcid(tvbuff_t *tvb, proto_tree *tree, unsigned *offset, int hf, uint16_t *eAxC, oran_tap_info *tap_info)
2073{
2074 /* Subtree */
2075 proto_item *oran_pcid_ti = proto_tree_add_item(tree, hf,
2076 tvb, *offset, 2, ENC_NA0x00000000);
2077 proto_tree *oran_pcid_tree = proto_item_add_subtree(oran_pcid_ti, ett_oran_ecpri_pcid);
2078
2079 uint64_t duPortId, bandSectorId, ccId, ruPortId = 0;
2080 int id_offset = *offset;
2081
2082 /* All parts of eAxC should be above 0, and should total 16 bits (breakdown controlled by preferences) */
2083 if (!((pref_du_port_id_bits > 0) && (pref_bandsector_id_bits > 0) && (pref_cc_id_bits > 0) && (pref_ru_port_id_bits > 0) &&
2084 ((pref_du_port_id_bits + pref_bandsector_id_bits + pref_cc_id_bits + pref_ru_port_id_bits) == 16))) {
2085 expert_add_info(NULL((void*)0), tree, &ei_oran_invalid_eaxc_bit_width);
2086 *eAxC = 0;
2087 *offset += 2;
2088 return;
2089 }
2090
2091 unsigned bit_offset = *offset * 8;
2092
2093 /* N.B. For sequence analysis / tapping, just interpret these 2 bytes as eAxC ID... */
2094 *eAxC = tvb_get_uint16(tvb, *offset, ENC_BIG_ENDIAN0x00000000);
2095
2096 /* DU Port ID */
2097 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);
2098 bit_offset += pref_du_port_id_bits;
2099 /* BandSector ID */
2100 proto_tree_add_bits_ret_val(oran_pcid_tree, hf_oran_bandsector_id, tvb, bit_offset, pref_bandsector_id_bits, &bandSectorId, ENC_BIG_ENDIAN0x00000000);
2101 bit_offset += pref_bandsector_id_bits;
2102 /* CC ID */
2103 proto_tree_add_bits_ret_val(oran_pcid_tree, hf_oran_cc_id, tvb, bit_offset, pref_cc_id_bits, &ccId, ENC_BIG_ENDIAN0x00000000);
2104 bit_offset += pref_cc_id_bits;
2105 /* RU Port ID */
2106 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);
2107 *offset += 2;
2108
2109 proto_item_append_text(oran_pcid_ti, " (DU_Port_ID: %d, BandSector_ID: %d, CC_ID: %d, RU_Port_ID: %d)",
2110 (int)duPortId, (int)bandSectorId, (int)ccId, (int)ruPortId);
2111 char id[16];
2112 snprintf(id, 16, "%x:%x:%x:%x", (int)duPortId, (int)bandSectorId, (int)ccId, (int)ruPortId);
2113 proto_item *pi = proto_tree_add_string(oran_pcid_tree, hf_oran_c_eAxC_ID, tvb, id_offset, 2, id);
2114 proto_item_set_generated(pi);
2115
2116 tap_info->eaxc = *eAxC;
2117 tap_info->eaxc_du_port_id = (uint16_t)duPortId;
2118 tap_info->eaxc_bandsector_id = (uint16_t)bandSectorId;
2119 tap_info->eaxc_cc_id = (uint16_t)ccId;
2120 tap_info->eaxc_ru_port_id = (uint16_t)ruPortId;
2121}
2122
2123/* Uniquely identify the U-plane stream that may need to be reassembled */
2124static uint32_t make_reassembly_id(uint32_t seqid, uint32_t direction, uint16_t eAxC,
2125 uint8_t frameid, uint8_t subframeid,
2126 uint8_t slotid, uint8_t symbolid)
2127{
2128 /* N.B., no room in 32-bits for all of this info, so cut down some of the fields
2129 and hope for no collisions */
2130 return (seqid << 24) | (direction << 23) | (slotid << 22) | (subframeid << 18) |
2131 (frameid << 9) | (symbolid << 6) | (eAxC & 0x3f);
2132}
2133
2134/* 5.1.3.2.8 ecpriSeqid (message identifier) */
2135/* Return out info that may be used for sequence number analysis and reassembly */
2136static int
2137addSeqid(tvbuff_t *tvb, proto_tree *oran_tree, int offset, int plane, uint32_t *seq_id, proto_item **seq_id_ti, packet_info *pinfo,
2138 uint32_t *subseqid, uint32_t *e)
2139{
2140 /* Subtree */
2141 proto_item *seqIdItem = proto_tree_add_item(oran_tree, hf_oran_ecpri_seqid, tvb, offset, 2, ENC_NA0x00000000);
2142 proto_tree *oran_seqid_tree = proto_item_add_subtree(seqIdItem, ett_oran_ecpri_seqid);
2143
2144 /* Sequence ID (8 bits) */
2145 *seq_id_ti = proto_tree_add_item_ret_uint(oran_seqid_tree, hf_oran_sequence_id, tvb, offset, 1, ENC_NA0x00000000, seq_id);
2146 offset += 1;
2147
2148 /* Show link back to previous sequence ID, if set */
2149 flow_result_t *result = wmem_tree_lookup32(flow_results_table, pinfo->num);
2150 if (result) {
2151 proto_item *prev_ti = proto_tree_add_uint(oran_seqid_tree, hf_oran_previous_frame, tvb, 0, 0, result->previous_frame);
2152 proto_item_set_generated(prev_ti);
2153 }
2154
2155 /* E bit */
2156 proto_tree_add_item_ret_uint(oran_seqid_tree, hf_oran_e_bit, tvb, offset, 1, ENC_NA0x00000000, e);
2157 /* Subsequence ID (7 bits) */
2158 proto_tree_add_item_ret_uint(oran_seqid_tree, hf_oran_subsequence_id, tvb, offset, 1, ENC_NA0x00000000, subseqid);
2159 offset += 1;
2160
2161 /* radio-transport fragmentation not allowed for C-Plane messages */
2162 if (plane == ORAN_C_PLANE0) {
2163 if (*e !=1 || *subseqid != 0) {
2164 expert_add_info(NULL((void*)0), seqIdItem, &ei_oran_radio_fragmentation_c_plane);
2165 }
2166 }
2167
2168 /* Summary */
2169 proto_item_append_text(seqIdItem, " (SeqId: %3d, E: %d, SubSeqId: %d)", *seq_id, *e, *subseqid);
2170 return offset;
2171}
2172
2173static int dissect_symbolmask(tvbuff_t *tvb, proto_tree *tree, int offset, uint32_t *symbol_mask, proto_item **ti)
2174{
2175 uint64_t temp_val;
2176
2177 static int * const symbol_mask_flags[] = {
2178 &hf_oran_symbol_mask_s13,
2179 &hf_oran_symbol_mask_s12,
2180 &hf_oran_symbol_mask_s11,
2181 &hf_oran_symbol_mask_s10,
2182 &hf_oran_symbol_mask_s9,
2183 &hf_oran_symbol_mask_s8,
2184 &hf_oran_symbol_mask_s7,
2185 &hf_oran_symbol_mask_s6,
2186 &hf_oran_symbol_mask_s5,
2187 &hf_oran_symbol_mask_s4,
2188 &hf_oran_symbol_mask_s3,
2189 &hf_oran_symbol_mask_s2,
2190 &hf_oran_symbol_mask_s1,
2191 &hf_oran_symbol_mask_s0,
2192 NULL((void*)0)
2193 };
2194
2195 proto_item *temp_ti = proto_tree_add_bitmask_ret_uint64(tree, tvb, offset,
2196 hf_oran_symbol_mask,
2197 ett_oran_symbol_mask, symbol_mask_flags,
2198 ENC_BIG_ENDIAN0x00000000, &temp_val);
2199 /* Set out parameters */
2200 if (symbol_mask) {
2201 *symbol_mask = (uint32_t)temp_val;
2202 }
2203 if (ti) {
2204 *ti = temp_ti;
2205 }
2206 return offset+2;
2207}
2208
2209/* 7.7.1.2 bfwCompHdr (beamforming weight compression header) */
2210static int dissect_bfwCompHdr(tvbuff_t *tvb, proto_tree *tree, int offset,
2211 uint32_t *iq_width, uint32_t *comp_meth, proto_item **comp_meth_ti)
2212{
2213 /* Subtree */
2214 proto_item *bfwcomphdr_ti = proto_tree_add_string_format(tree, hf_oran_bfwCompHdr,
2215 tvb, offset, 1, "",
2216 "bfwCompHdr");
2217 proto_tree *bfwcomphdr_tree = proto_item_add_subtree(bfwcomphdr_ti, ett_oran_bfwcomphdr);
2218
2219 /* Width and method */
2220 proto_tree_add_item_ret_uint(bfwcomphdr_tree, hf_oran_bfwCompHdr_iqWidth,
2221 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, iq_width);
2222 /* Special case: 0 -> 16 */
2223 *iq_width = (*iq_width==0) ? 16 : *iq_width;
2224 *comp_meth_ti = proto_tree_add_item_ret_uint(bfwcomphdr_tree, hf_oran_bfwCompHdr_compMeth,
2225 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, comp_meth);
2226 offset++;
2227
2228 /* Summary */
2229 proto_item_append_text(bfwcomphdr_ti, " (IqWidth=%u, compMeth=%s)",
2230 *iq_width,
2231 val_to_str_const(*comp_meth, bfw_comp_headers_comp_meth, "reserved"));
2232
2233 return offset;
2234}
2235
2236/* Return offset */
2237/* Returning number of entries set - would be good to also return an array of set TRX# so could show which array element
2238 each BFW is actually for.. */
2239static int dissect_active_beamspace_coefficient_mask(tvbuff_t *tvb, proto_tree *tree, int offset, unsigned *num_trx_entries, uint16_t **trx_entries)
2240{
2241 /* activeBeamspaceCoefficientMask - ceil(K/8) octets */
2242 /* K is the number of elements in uncompressed beamforming weight vector.
2243 * Calculated from parameters describing tx-array or tx-array */
2244 unsigned k_octets = (pref_num_bf_antennas + 7) / 8;
2245
2246 static uint16_t trx_enabled[1024];
2247
2248 /* TODO: could use a bigger bitmask array, but for now just uses this bytes-worth for each byte */
2249 static int * const mask_bits[] = {
2250 &hf_oran_active_beamspace_coefficient_n1,
2251 &hf_oran_active_beamspace_coefficient_n2,
2252 &hf_oran_active_beamspace_coefficient_n3,
2253 &hf_oran_active_beamspace_coefficient_n4,
2254 &hf_oran_active_beamspace_coefficient_n5,
2255 &hf_oran_active_beamspace_coefficient_n6,
2256 &hf_oran_active_beamspace_coefficient_n7,
2257 &hf_oran_active_beamspace_coefficient_n8,
2258 NULL((void*)0)
2259 };
2260
2261 *num_trx_entries = 0;
2262 uint64_t val;
2263 for (unsigned n=0; n < k_octets; n++) {
2264 proto_tree_add_bitmask_ret_uint64(tree, tvb, offset,
2265 hf_oran_activeBeamspaceCoefficientMask,
2266 ett_oran_active_beamspace_coefficient_mask, mask_bits,
2267 ENC_BIG_ENDIAN0x00000000, &val);
2268 offset++;
2269 /* Add up the set bits for this byte (but be careful not to count beyond last real K bit..) */
2270 for (unsigned b=0; b < 8; b++) {
2271 if ((1 << b) & (unsigned)val) {
2272 if (((n*8)+b) < pref_num_bf_antennas) {
2273 if (*num_trx_entries < 1024-1) { /* Don't write beyond array (which should be plenty big) */
2274 trx_enabled[(*num_trx_entries)++] = (n*8) + b + 1;
2275 }
2276 }
2277 }
2278 }
2279 }
2280 /* Set pointer to static array */
2281 *trx_entries = trx_enabled;
2282
2283 /* Show how many bits set */
2284 proto_item *ti = proto_tree_add_uint(tree, hf_oran_activeBeamspaceCoefficientMask_bits_set, tvb,
2285 offset-k_octets, k_octets, *num_trx_entries);
2286 proto_item_set_generated(ti);
2287
2288 return offset;
2289}
2290
2291static void add_beam_id_to_tap(oran_tap_info *tap_info, uint16_t beam_id)
2292{
2293 if (tap_info->num_beams < MAX_BEAMS_IN_FRAME32) {
2294 tap_info->beams[tap_info->num_beams++] = beam_id;
2295 }
2296}
2297
2298
2299/* 7.7.1.3 bfwCompParam (beamforming weight compression parameter).
2300 * Depends upon passed-in bfwCompMeth (field may be empty) */
2301static int dissect_bfwCompParam(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, int offset,
2302 proto_item *meth_ti, uint32_t *bfw_comp_method,
2303 uint32_t *exponent, bool_Bool *supported, unsigned *num_trx_entries, uint16_t **trx_entries)
2304{
2305 if (*bfw_comp_method == COMP_NONE0) {
2306 /* Absent! */
2307 *num_trx_entries = 0;
2308 *supported = true1;
2309 return offset;
2310 }
2311
2312 /* Subtree */
2313 proto_item *bfwcompparam_ti = proto_tree_add_string_format(tree, hf_oran_bfwCompParam,
2314 tvb, offset, 1, "",
2315 "bfwCompParam");
2316 proto_tree *bfwcompparam_tree = proto_item_add_subtree(bfwcompparam_ti, ett_oran_bfwcompparam);
2317
2318 proto_item_append_text(bfwcompparam_ti,
2319 " (meth=%s)", val_to_str_const(*bfw_comp_method, bfw_comp_headers_comp_meth, "reserved"));
2320
2321 *num_trx_entries = 0;
2322 *supported = false0;
2323 switch (*bfw_comp_method) {
2324 case COMP_BLOCK_FP1: /* block floating point */
2325 /* 4 reserved bits + exponent */
2326 add_reserved_field(bfwcompparam_tree, hf_oran_reserved_4bits, tvb, offset, 1);
2327 proto_tree_add_item_ret_uint(bfwcompparam_tree, hf_oran_exponent,
2328 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, exponent);
2329 proto_item_append_text(bfwcompparam_ti, " exponent=%u", *exponent);
2330 *supported = true1;
2331 offset++;
2332 break;
2333 case COMP_BLOCK_SCALE2: /* block scaling */
2334 /* Separate into integer and fractional bits? */
2335 proto_tree_add_item(bfwcompparam_tree, hf_oran_blockScaler,
2336 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
2337 offset++;
2338 break;
2339 case COMP_U_LAW3: /* u-law */
2340 /* compBitWidth, compShift */
2341 proto_tree_add_item(bfwcompparam_tree, hf_oran_compBitWidth,
2342 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
2343 proto_tree_add_item(bfwcompparam_tree, hf_oran_compShift,
2344 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
2345 offset++;
2346 break;
2347 case 4: /* beamspace I (BLOCK SCALING) */
2348 /* activeBeamspaceCoefficientMask */
2349 offset = dissect_active_beamspace_coefficient_mask(tvb, bfwcompparam_tree, offset, num_trx_entries, trx_entries);
2350 *bfw_comp_method = COMP_BLOCK_SCALE2;
2351 *supported = false0; /* TODO: true once BLOCK SCALE is supported */
2352 proto_tree_add_item(bfwcompparam_tree, hf_oran_blockScaler,
2353 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
2354 offset++;
2355 break;
2356 case 5: /* beamspace II (BLOCK FLOATING POINT) */
2357 /* activeBeamspaceCoefficientMask */
2358 offset = dissect_active_beamspace_coefficient_mask(tvb, bfwcompparam_tree, offset, num_trx_entries, trx_entries);
2359 /* reserved (4 bits) + exponent (4 bits) */
2360 add_reserved_field(bfwcompparam_tree, hf_oran_reserved_4bits, tvb, offset, 1);
2361 proto_tree_add_item_ret_uint(bfwcompparam_tree, hf_oran_exponent, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, exponent);
2362 offset += 1;
2363 *bfw_comp_method = COMP_BLOCK_FP1;
2364 *supported = true1;
2365 break;
2366
2367 default:
2368 /* Not handled */
2369 break;
2370 }
2371
2372 proto_item_set_end(bfwcompparam_ti, tvb, offset);
2373
2374 /* Can't go on if compression scheme not supported */
2375 if (!(*supported) && meth_ti) {
2376 expert_add_info_format(pinfo, meth_ti, &ei_oran_unsupported_bfw_compression_method,
2377 "BFW Compression method %u (%s) not decompressed by dissector",
2378 *bfw_comp_method,
2379 val_to_str_const(*bfw_comp_method, bfw_comp_headers_comp_meth, "reserved"));
2380 }
2381 return offset;
2382}
2383
2384
2385/* Special case for uncompressed/16-bit value */
2386static float uncompressed_to_float(uint32_t h)
2387{
2388 int16_t i16 = h & 0x0000ffff;
2389 if (show_unscaled_values) {
2390 return (float)i16;
2391 }
2392 return ((float)i16) / 0x7fff;
2393}
2394
2395/* Decompress I/Q value, taking into account method, width, exponent, other input-specific methods */
2396static float decompress_value(uint32_t bits, uint32_t comp_method, uint8_t iq_width,
2397 uint32_t exponent,
2398 /* Modulation compression settings. N.B. should also pass in PRB + symbol? */
2399 section_mod_compr_config_t *m_c_p, uint8_t re)
2400{
2401 switch (comp_method) {
2402 case COMP_NONE0: /* no compression */
2403 return uncompressed_to_float(bits);
2404
2405 case COMP_BLOCK_FP1: /* block floating point */
2406 case BFP_AND_SELECTIVE_RE5:
2407 {
2408 /* A.1.3 Block Floating Point Decompression Algorithm */
2409 int32_t cPRB = bits;
2410 uint32_t scaler = 1 << exponent; /* i.e. 2^exponent */
2411
2412 /* Check last bit, in case we need to flip to -ve */
2413 if (cPRB >= (1<<(iq_width-1))) {
2414 cPRB -= (1<<iq_width);
2415 }
2416
2417 /* Unscale (8.1.3.1) */
2418 cPRB *= scaler;
2419 if (show_unscaled_values) {
2420 return (float)cPRB;
2421 }
2422
2423 uint32_t mantissa_scale_factor = 1 << (iq_width-1); /* 2^(mantissabits-1) */
2424 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 */
2425
2426 float ret = cPRB / ((float)(mantissa_scale_factor*exp_scale_factor));
2427 return ret;
2428 }
2429
2430 case COMP_BLOCK_SCALE2:
2431 case COMP_U_LAW3:
2432 /* Not supported! But will be reported as expert info outside of this function! */
2433 return 0.0;
2434
2435 case COMP_MODULATION4:
2436 case MOD_COMPR_AND_SELECTIVE_RE6:
2437 {
2438 /* Described in A.5 (with pseudo code) */
2439 /* N.B., Applies to downlink data only - is not used for BFW */
2440
2441 /* Defaults if not overridden. TODO: what should these be? */
2442 bool_Bool csf = false0;
2443 float mcScaler = (float)(1 << 11);
2444
2445 /* Find csf + mcScaler to use. Non-default configs gleaned from SE 4,5,23 */
2446 /* TODO: should ideally be filtering by symbol and PRB too (as configured from SE23) */
2447 if (re > 0 && m_c_p && m_c_p->num_configs > 0) {
2448 for (unsigned c=0; c<m_c_p->num_configs; c++) {
2449 if (m_c_p->configs[c].mod_compr_re_mask & (1 << (12-re))) {
2450 /* Return first (should be only) found */
2451 csf = m_c_p->configs[c].mod_compr_csf;
2452 mcScaler = m_c_p->configs[c].mod_compr_scaler;
2453 break;
2454 }
2455 }
2456 }
2457
2458 int32_t cPRB = bits;
2459
2460 /* 2) Map iqSample to iqSampleFx */
2461 /* Check last bit, in case we need to flip to -ve */
2462 if (cPRB >= (1<<(iq_width-1))) {
2463 cPRB -= (1<<iq_width);
2464 }
2465 float iqSampleFx = (float)cPRB / (1 << (iq_width-1));
2466
2467
2468 /* 3) or 4) (b) - add unshifted value if csf set */
2469 float csf_to_add = 0.0;
2470 if (csf) {
2471 /* Unshift the constellation point */
2472 csf_to_add = (float)1.0 / (1 << (iq_width));
2473 }
2474 iqSampleFx += csf_to_add;
2475
2476 /* 3) or 4) (c) - unscaling */
2477 float iqSampleScaled = mcScaler * iqSampleFx * (float)sqrt(2);
2478 return iqSampleScaled;
2479 }
2480
2481 default:
2482 /* Not supported! But will be reported as expert info outside of this function! */
2483 return 0.0;
2484 }
2485}
2486
2487/* Out-of-range value used for special case */
2488#define ORPHAN_BUNDLE_NUMBER999 999
2489
2490/* Bundle of PRBs/TRX I/Q samples (ext 11) */
2491static uint32_t dissect_bfw_bundle(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, unsigned offset,
2492 proto_item *comp_meth_ti, uint32_t bfwcomphdr_comp_meth,
2493 section_mod_compr_config_t *mod_compr_params,
2494 uint32_t num_weights_per_bundle,
2495 uint8_t iq_width,
2496 unsigned bundle_number,
2497 unsigned first_prb, unsigned last_prb, bool_Bool is_orphan,
2498 uint32_t symbol_count,
2499 section_details_t *section_details,
2500 oran_tap_info *tap_info)
2501{
2502 /* Set bundle name */
2503 char bundle_name[32];
2504 if (!is_orphan) {
2505 snprintf(bundle_name, 32, "Bundle %3u", bundle_number);
2506 }
2507 else {
2508 (void) g_strlcpy(bundle_name, "Orphaned ", 32);
2509 }
2510
2511 /* Create Bundle root */
2512 proto_item *bundle_ti;
2513 if (first_prb != last_prb) {
2514 bundle_ti = proto_tree_add_string_format(tree, hf_oran_bfw_bundle,
2515 tvb, offset, 0, "",
2516 "%s: (PRBs %3u-%3u)",
2517 bundle_name,
2518 first_prb, last_prb);
2519 }
2520 else {
2521 bundle_ti = proto_tree_add_string_format(tree, hf_oran_bfw_bundle,
2522 tvb, offset, 0, "",
2523 "%s: (PRB %3u)",
2524 bundle_name,
2525 first_prb);
2526 }
2527 proto_tree *bundle_tree = proto_item_add_subtree(bundle_ti, ett_oran_bfw_bundle);
2528
2529 /* Generated bundle id */
2530 proto_item *bundleid_ti = proto_tree_add_uint(bundle_tree, hf_oran_bfw_bundle_id, tvb, 0, 0,
2531 bundle_number);
2532 proto_item_set_generated(bundleid_ti);
2533 proto_item_set_hidden(bundleid_ti);
2534
2535 /* bfwCompParam */
2536 bool_Bool compression_method_supported = false0;
2537 unsigned exponent = 0;
2538 unsigned num_trx_entries = 0;
2539 uint16_t *trx_entries;
2540 offset = dissect_bfwCompParam(tvb, bundle_tree, pinfo, offset, comp_meth_ti,
2541 &bfwcomphdr_comp_meth, &exponent, &compression_method_supported,
2542 &num_trx_entries, &trx_entries);
2543
2544 /* Create Bundle subtree */
2545 int bit_offset = offset*8;
2546 int bfw_offset;
2547
2548 /* contInd */
2549 proto_tree_add_item(bundle_tree, hf_oran_cont_ind,
2550 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
2551 /* beamId */
2552 uint32_t beam_id;
2553 proto_tree_add_item_ret_uint(bundle_tree, hf_oran_beam_id, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &beam_id);
2554 proto_item_append_text(bundle_ti, " (beamId:%u) ", beam_id);
2555 bit_offset += 16;
2556 add_beam_id_to_tap(tap_info, beam_id);
2557
2558 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
2559 if (section_details) {
2560 for (unsigned prb = first_prb; prb <= last_prb; prb++) {
2561 if (prb < 273) {
2562 section_details->beamIds[prb] = beam_id;
2563 }
2564 }
2565 }
2566 }
2567
2568 /* On first pass, record that beamId was defined here */
2569 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
2570 bfw_definition *definition = wmem_new0(wmem_file_scope(), bfw_definition)((bfw_definition*)wmem_alloc0((wmem_file_scope()), sizeof(bfw_definition
)))
;
2571 definition->frame_defined = pinfo->num;
2572 definition->symbol_when_defined = symbol_count;
2573 wmem_tree_insert32(dl_beam_ids_defined, beam_id, definition);
2574 }
2575
2576
2577 /* Number of weights per bundle (from preference) */
2578 proto_item *wpb_ti = proto_tree_add_uint(bundle_tree, hf_oran_num_weights_per_bundle, tvb, 0, 0,
2579 num_weights_per_bundle);
2580 proto_item_set_generated(wpb_ti);
2581
2582 /* Add the weights for this bundle. Overwrite with what was seen in bfwCompParam if beamspace */
2583 if (num_trx_entries != 0) {
2584 num_weights_per_bundle = num_trx_entries;
2585 }
2586
2587 bool_Bool non_zero_weights_seen = false0;
2588 int bit_offset_before_weights = bit_offset;
2589 for (unsigned w=0; w < num_weights_per_bundle; w++) {
2590
2591 uint16_t trx_index = (num_trx_entries) ? trx_entries[w] : w+1;
2592
2593 /* Create subtree */
2594 bfw_offset = bit_offset / 8;
2595 uint8_t bfw_extent = ((bit_offset + (iq_width*2)) / 8) - bfw_offset;
2596 proto_item *bfw_ti = proto_tree_add_string_format(bundle_tree, hf_oran_bfw,
2597 tvb, bfw_offset, bfw_extent,
2598 "", "TRX %3u: (", trx_index);
2599 proto_tree *bfw_tree = proto_item_add_subtree(bfw_ti, ett_oran_bfw);
2600
2601 /* I */
2602 /* Get bits, and convert to float. */
2603 uint32_t bits = tvb_get_bits32(tvb, bit_offset, iq_width, ENC_BIG_ENDIAN0x00000000);
2604 if (bits) {
2605 non_zero_weights_seen = true1;
2606 }
2607 float value = decompress_value(bits, bfwcomphdr_comp_meth, iq_width,
2608 exponent, mod_compr_params, 0 /* RE */);
2609 /* Add to tree. */
2610 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);
2611 bit_offset += iq_width;
2612 proto_item_append_text(bfw_ti, "I%u=%f ", w, value);
2613
2614 /* Q */
2615 /* Get bits, and convert to float. */
2616 bits = tvb_get_bits32(tvb, bit_offset, iq_width, ENC_BIG_ENDIAN0x00000000);
2617 if (bits) {
2618 non_zero_weights_seen = true1;
2619 }
2620
2621 value = decompress_value(bits, bfwcomphdr_comp_meth, iq_width,
2622 exponent, mod_compr_params, 0 /* RE */);
2623 /* Add to tree. */
2624 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);
2625 bit_offset += iq_width;
2626 proto_item_append_text(bfw_ti, "Q%u=%f)", w, value);
2627 }
2628
2629 if (!non_zero_weights_seen) {
2630 proto_tree_add_item(bundle_tree, hf_oran_bundle_weights_all_zero, tvb,
2631 bit_offset_before_weights, (bit_offset+7)/8 - (bit_offset_before_weights/8), ENC_NA0x00000000);
2632 }
2633
2634 /* Set extent of bundle */
2635 proto_item_set_end(bundle_ti, tvb, (bit_offset+7)/8);
2636
2637 return (bit_offset+7)/8;
2638}
2639
2640/* Return new bit offset. in/out will always be byte-aligned.. */
2641static int dissect_ciCompParam(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U___attribute__((unused)), unsigned bit_offset,
2642 unsigned comp_meth, uint8_t *exponent)
2643{
2644 if (comp_meth == COMP_NONE0) {
2645 /* Nothing in frame so don't even create subtree */
2646 return bit_offset;
2647 }
2648
2649 /* Subtree */
2650 proto_item *cicompparam_ti = proto_tree_add_string_format(tree, hf_oran_ciCompParam,
2651 tvb, bit_offset/8, 1, "",
2652 "ciCompParam");
2653 proto_tree *cicompparam_tree = proto_item_add_subtree(cicompparam_ti, ett_oran_cicompparam);
2654 uint32_t ci_exponent;
2655
2656 /* Contents differ by compression method */
2657 switch (comp_meth) {
2658 case COMP_BLOCK_FP1:
2659 add_reserved_field(cicompparam_tree, hf_oran_reserved_4bits, tvb, bit_offset/8, 1);
2660 proto_tree_add_item_ret_uint(cicompparam_tree, hf_oran_exponent,
2661 tvb, bit_offset/8, 1, ENC_BIG_ENDIAN0x00000000, &ci_exponent);
2662 *exponent = ci_exponent;
2663 proto_item_append_text(cicompparam_ti, " (Exponent=%u)", ci_exponent);
2664 bit_offset += 8; /* one byte */
2665 break;
2666 case COMP_BLOCK_SCALE2:
2667 /* Separate into integer (1) and fractional (7) bits? */
2668 proto_tree_add_item(cicompparam_tree, hf_oran_blockScaler,
2669 tvb, bit_offset/8, 1, ENC_BIG_ENDIAN0x00000000);
2670 bit_offset += 8;
2671 break;
2672 case COMP_U_LAW3:
2673 /* compBitWidth, compShift (4 bits each) */
2674 proto_tree_add_item(cicompparam_tree, hf_oran_compBitWidth,
2675 tvb, bit_offset/8, 1, ENC_BIG_ENDIAN0x00000000);
2676 proto_tree_add_item(cicompparam_tree, hf_oran_compShift,
2677 tvb, bit_offset/8, 1, ENC_BIG_ENDIAN0x00000000);
2678 bit_offset += 8;
2679 break;
2680
2681 default:
2682 /* reserved, ? bytes of zeros.. */
2683 break;
2684 }
2685
2686 return bit_offset;
2687}
2688
2689/* frameStructure (7.5.2.13) */
2690static unsigned dissect_frame_structure(proto_item *tree, tvbuff_t *tvb, unsigned offset,
2691 uint32_t subframeId, uint32_t slotId)
2692{
2693 uint32_t scs;
2694 /* FFT Size (4 bits) */
2695 proto_tree_add_item(tree, hf_oran_frameStructure_fft, tvb, offset, 1, ENC_NA0x00000000);
2696 /* Subcarrier spacing (SCS) */
2697 proto_tree_add_item_ret_uint(tree, hf_oran_frameStructure_subcarrier_spacing, tvb, offset, 1, ENC_NA0x00000000, &scs);
2698
2699 /* Show slot within frame as a generated field. See table 7.5.13-3 */
2700 uint32_t slots_per_subframe = 1;
2701 if (scs <= 4) {
2702 slots_per_subframe = 1 << scs;
2703 }
2704 if (scs <= 4 || scs >= 12) {
2705 proto_item *ti = proto_tree_add_uint(tree, hf_oran_slot_within_frame, tvb, 0, 0,
2706 (slots_per_subframe*subframeId) + slotId);
2707 proto_item_set_generated(ti);
2708 }
2709 return offset + 1;
2710}
2711
2712static unsigned dissect_csf(proto_item *tree, tvbuff_t *tvb, unsigned bit_offset,
2713 unsigned iq_width, bool_Bool *p_csf)
2714{
2715 proto_item *csf_ti;
2716 uint64_t csf;
2717 csf_ti = proto_tree_add_bits_ret_val(tree, hf_oran_csf, tvb, bit_offset, 1, &csf, ENC_BIG_ENDIAN0x00000000);
2718 if (csf) {
2719 /* Table 7.7.4.2-1 Constellation shift definition (index is udIqWidth) */
2720 const char* shift_value[] = { "n/a", "1/2", "1/4", "1/8", "1/16", "1/32" };
2721 if (iq_width >=1 && iq_width <= 5) {
2722 proto_item_append_text(csf_ti, " (Shift Value is %s)", shift_value[iq_width]);
2723 }
2724 }
2725
2726 /* Set out parameter */
2727 if (p_csf != NULL((void*)0)) {
2728 *p_csf = (csf!=0);
2729 }
2730 return bit_offset+1;
2731}
2732
2733
2734/* Section 7.
2735 * N.B. these are the green parts of the tables showing Section Types, differing by section Type */
2736static int dissect_oran_c_section(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo,
2737 flow_state_t* state,
2738 uint32_t sectionType, oran_tap_info *tap_info, proto_item *protocol_item,
2739 uint32_t subframeId, uint32_t frameId, uint32_t slotId, uint32_t startSymbolId,
2740 uint8_t ci_iq_width, uint8_t ci_comp_meth, unsigned ci_comp_opt,
2741 unsigned num_sinr_per_prb)
2742{
2743 unsigned offset = 0;
2744 proto_tree *c_section_tree = NULL((void*)0);
2745 proto_item *sectionHeading = NULL((void*)0);
2746
2747 /* Section subtree */
2748 sectionHeading = proto_tree_add_string_format(tree, hf_oran_c_section,
2749 tvb, offset, 0, "", "Section");
2750 c_section_tree = proto_item_add_subtree(sectionHeading, ett_oran_c_section);
2751
2752 uint32_t sectionId = 0;
2753
2754 uint32_t startPrbc=0, startPrbu=0;
2755 uint32_t numPrbc=0, numPrbu=0;
2756 uint32_t ueId = 0;
2757 proto_item *ueId_ti = NULL((void*)0);
2758 uint32_t section_beamId = 0;
2759 proto_item *section_beamId_ti = NULL((void*)0);
2760 bool_Bool section_beamId_ignored = false0;
2761
2762 proto_item *numsymbol_ti = NULL((void*)0);
2763 bool_Bool numsymbol_ignored = false0;
2764
2765 proto_item *numprbc_ti = NULL((void*)0);
2766
2767 /* Config affecting ext11 bundles (initially unset) */
2768 ext11_settings_t ext11_settings;
2769 memset(&ext11_settings, 0, sizeof(ext11_settings));
2770
2771 /* Section Type 10 needs to keep track of PRB range that should be reported
2772 for msgTypeId=5 (Interference plus Noise for unallocated PRBs) */
2773 /* All PRBs start as false */
2774#define MAX_PRBS273 273
2775 bool_Bool prbs_for_st10_type5[MAX_PRBS273];
2776 memset(&prbs_for_st10_type5, 0, sizeof(prbs_for_st10_type5));
2777
2778 /* These UEIds are set by ST5, ST10 (single value), and extended by SE10 */
2779#define MAX_UEIDS16 16
2780 uint32_t ueids[MAX_UEIDS16];
2781 uint32_t number_of_ueids = 0;
2782
2783
2784 bool_Bool extension_flag = false0;
2785
2786 /* These sections (ST0, ST1, ST2, ST3, ST5, ST9, ST10, ST11) are similar, so handle as common with per-type differences */
2787 if (((sectionType <= SEC_C_UE_SCHED) || (sectionType >= SEC_C_SINR_REPORTING)) &&
2788 (sectionType != SEC_C_SLOT_CONTROL)) {
2789
2790 /* sectionID */
2791 proto_item *ti = proto_tree_add_item_ret_uint(c_section_tree, hf_oran_section_id, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &sectionId);
2792 if (sectionId == 4095) {
2793 proto_item_append_text(ti, " (not default coupling C/U planes using sectionId)");
2794 }
2795 offset++;
2796
2797 if (tap_info->num_section_ids < MAX_SECTION_IDs32) {
2798 tap_info->section_ids[tap_info->num_section_ids++] = sectionId;
2799 }
2800
2801 /* rb */
2802 uint32_t rb;
2803 proto_tree_add_item_ret_uint(c_section_tree, hf_oran_rb, tvb, offset, 1, ENC_NA0x00000000, &rb);
2804 /* symInc (1 bit) */
2805 /* TODO: mark as ignored if SE6, SE12 or SE19 present */
2806 if (sectionType != SEC_C_RRM_MEAS_REPORTS && /* Section Type 10 */
2807 sectionType != SEC_C_REQUEST_RRM_MEAS) { /* Section Type 11 */
2808 unsigned int sym_inc;
2809 proto_item *sym_inc_ti = proto_tree_add_item_ret_uint(c_section_tree, hf_oran_symInc, tvb, offset, 1, ENC_NA0x00000000, &sym_inc);
2810 if (sym_inc !=0 && (sectionType == SEC_C_SINR_REPORTING)) { /* Section Type 9 */
2811 /* "0 shall be used" */
2812 proto_item_append_text(sym_inc_ti, " (should be 0)");
2813 }
2814 }
2815 else {
2816 /* reserved (1 bit) */
2817 add_reserved_field(c_section_tree, hf_oran_reserved_bit5, tvb, offset, 1);
2818 }
2819
2820 /* startPrbx and numPrbx */
2821 if (sectionType == SEC_C_SINR_REPORTING) {
2822 /* startPrbu (10 bits) */
2823 proto_tree_add_item_ret_uint(c_section_tree, hf_oran_startPrbu, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &startPrbu);
2824 offset += 2;
2825
2826 /* numPrbu */
2827 numprbc_ti = proto_tree_add_item_ret_uint(c_section_tree, hf_oran_numPrbu, tvb, offset, 1, ENC_NA0x00000000, &numPrbu);
2828 if (numPrbu == 0) {
2829 proto_item_append_text(numprbc_ti, " (all PRBs - configured as %u)", pref_data_plane_section_total_rbs);
2830 numPrbu = pref_data_plane_section_total_rbs;
2831 }
2832 offset += 1;
2833 }
2834 else {
2835 /* startPrbc (10 bits) */
2836 proto_tree_add_item_ret_uint(c_section_tree, hf_oran_startPrbc, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &startPrbc);
2837 offset += 2;
2838
2839 /* numPrbc */
2840 numprbc_ti = proto_tree_add_item_ret_uint(c_section_tree, hf_oran_numPrbc, tvb, offset, 1, ENC_NA0x00000000, &numPrbc);
2841 if (numPrbc == 0) {
2842 proto_item_append_text(numprbc_ti, " (all PRBs - configured as %u)", pref_data_plane_section_total_rbs);
2843 /* TODO: should probably set to pref_data_plane_section_total_rbs, and define MAX_PRBS to > 273 ? */
2844 numPrbc = MAX_PRBS273;
2845 }
2846 offset += 1;
2847 }
2848
2849 /* Start with range from section. May get changed by SE6, SE12, SE20 */
2850 for (unsigned n=startPrbc; n < startPrbc+numPrbc; n++) {
2851 if (n < MAX_PRBS273) {
2852 prbs_for_st10_type5[n] = true1;
2853 }
2854 }
2855
2856 if (sectionType != SEC_C_SINR_REPORTING) { /* *NOT* Section Type 9 */
2857 static int * const remask_flags[] = {
2858 &hf_oran_reMask_re1,
2859 &hf_oran_reMask_re2,
2860 &hf_oran_reMask_re3,
2861 &hf_oran_reMask_re4,
2862 &hf_oran_reMask_re5,
2863 &hf_oran_reMask_re6,
2864 &hf_oran_reMask_re7,
2865 &hf_oran_reMask_re8,
2866 &hf_oran_reMask_re9,
2867 &hf_oran_reMask_re10,
2868 &hf_oran_reMask_re11,
2869 &hf_oran_reMask_re12,
2870 NULL((void*)0)
2871 };
2872
2873 /* reMask */
2874 uint64_t remask;
2875 proto_tree_add_bitmask_ret_uint64(c_section_tree, tvb, offset,
2876 hf_oran_reMask, ett_oran_remask, remask_flags, ENC_BIG_ENDIAN0x00000000, &remask);
2877 offset++;
2878 /* numSymbol */
2879 uint32_t numSymbol;
2880 numsymbol_ti = proto_tree_add_item_ret_uint(c_section_tree, hf_oran_numSymbol, tvb, offset, 1, ENC_NA0x00000000, &numSymbol);
2881 if ((sectionType == SEC_C_RRM_MEAS_REPORTS) && (numSymbol != 14)) { /* Section type 10 must have 14 symbols */
2882 proto_item_append_text(numsymbol_ti, " (for ST10, should be 14!)");
2883 expert_add_info_format(pinfo, numsymbol_ti, &ei_oran_st10_numsymbol_not_14,
2884 "numSymbol should be 14 for ST10 - found %u", numSymbol);
2885 }
2886 if ((startSymbolId + numSymbol) > 14) {
2887 /* Warn if startSymbol + numSymbol would be > 14 */
2888 expert_add_info_format(pinfo, numsymbol_ti, &ei_oran_too_many_symbols,
2889 "startSymbolId (%u) + numSymbol (%u) exceeds max of 14",
2890 startSymbolId, numSymbol);
2891 }
2892 offset++;
2893
2894 /* [ef] (extension flag) */
2895 switch (sectionType) {
2896 case SEC_C_UNUSED_RB: /* Section Type 0 */
2897 case SEC_C_NORMAL: /* Section Type 1 */
2898 case SEC_C_PRACH: /* Section Type 3 */
2899 case SEC_C_UE_SCHED: /* Section Type 5 */
2900 case SEC_C_RRM_MEAS_REPORTS: /* Section Type 10 */
2901 case SEC_C_REQUEST_RRM_MEAS: /* Section Type 11 */
2902 proto_tree_add_item_ret_boolean(c_section_tree, hf_oran_ef, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &extension_flag);
2903 break;
2904 default:
2905 /* Other section types don't support extensions */
2906 break;
2907 }
2908
2909 write_section_info(sectionHeading, pinfo, protocol_item, sectionId, startPrbc, numPrbc, rb);
2910 proto_item_append_text(sectionHeading, ", Symbols: %2u", numSymbol);
2911
2912 if (numPrbc == 0) {
2913 /* Special case for all PRBs */
2914 numPrbc = pref_data_plane_section_total_rbs;
2915 startPrbc = 0; /* may already be 0... */
2916 }
2917 }
2918 else {
2919 /* Section Type 9 */
2920 write_section_info(sectionHeading, pinfo, protocol_item, sectionId, startPrbu, numPrbu, rb);
2921 proto_item_append_text(sectionHeading, ", numSinrPerPrb: %2u", num_sinr_per_prb);
2922 }
2923
2924 /* Section type specific fields (after 'numSymbol') */
2925 switch (sectionType) {
2926 case SEC_C_UNUSED_RB: /* Section Type 0 - Table 7.4.2-1 */
2927 /* reserved (15 bits) */
2928 add_reserved_field(c_section_tree, hf_oran_reserved_15bits, tvb, offset, 2);
2929 offset += 2;
2930 break;
2931
2932 case SEC_C_NORMAL: /* Section Type 1 - Table 7.4.3-1 */
2933 /* beamId */
2934 section_beamId_ti = proto_tree_add_item_ret_uint(c_section_tree, hf_oran_beamId, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &section_beamId);
2935 offset += 2;
2936
2937 /* beamId might get invalidated by e.g., ext-6, ext-11, so unused value will still be shown here.. */
2938 proto_item_append_text(sectionHeading, ", BeamId: %d", section_beamId);
2939 break;
2940
2941 case SEC_C_PRACH: /* Section Type 3 - Table 7.4.5-1 */
2942 {
2943 /* beamId */
2944 section_beamId_ti = proto_tree_add_item_ret_uint(c_section_tree, hf_oran_beamId, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &section_beamId);
2945 offset += 2;
2946
2947 /* freqOffset */
2948 int32_t freqOffset; /* Yes, this is signed, so the cast is intentional. */
2949 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);
2950 freqOffset |= 0xff000000; /* Must sign-extend */
2951 proto_item_set_text(freq_offset_item, "Frequency offset: %d \u0394f", freqOffset);
2952 offset += 3;
2953
2954 /* reserved (8 bits) */
2955 add_reserved_field(c_section_tree, hf_oran_reserved_8bits, tvb, offset, 1);
2956 offset += 1;
2957
2958 /* beamId might get invalidated by e.g., ext-6, ext-11, so unused value will still be shown here.. */
2959 proto_item_append_text(sectionHeading, ", BeamId: %d, FreqOffset: %d \u0394f", section_beamId, freqOffset);
2960 break;
2961 }
2962
2963 case SEC_C_UE_SCHED: /* Section Type 5 - Table 7.4.7-1 */
2964 case SEC_C_RRM_MEAS_REPORTS: /* Section Type 10 - Table 7.4.12-1 */
2965 /* ueId */
2966 ueId_ti = proto_tree_add_item_ret_uint(c_section_tree, hf_oran_ueId, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &ueId);
2967 offset += 2;
2968 if (ueId == 0x7fff) {
2969 proto_item_append_text(ueId_ti, " (PRBs not scheduled for eAxC ID in transport header)");
2970 }
2971 else {
2972 ueids[number_of_ueids++] = ueId;
2973 }
2974
2975 proto_item_append_text(sectionHeading, ", UEId: %d", ueId);
2976 break;
2977
2978 case SEC_C_SINR_REPORTING: /* Section Type 9 - SINR Reporting */
2979 {
2980 /* Hidden filter for bf (DMFS-BF) */
2981 proto_item *bf_ti = proto_tree_add_item(tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
2982 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
2983
2984 unsigned bit_offset = offset*8;
2985
2986 /* sinr iqWidth */
2987 proto_item *iq_width_item = proto_tree_add_uint(c_section_tree, hf_oran_sinrCompHdrIqWidth_pref, tvb, 0, 0, pref_sample_bit_width_sinr);
2988 proto_item_append_text(iq_width_item, " (from preferences)");
2989 proto_item_set_generated(iq_width_item);
2990
2991 /* sinr compMethod */
2992 proto_item *sinr_comp_meth_item = proto_tree_add_uint(c_section_tree, hf_oran_sinrCompHdrMeth_pref, tvb, 0, 0, pref_iqCompressionSINR);
2993 proto_item_append_text(sinr_comp_meth_item, " (from preferences)");
2994 proto_item_set_generated(sinr_comp_meth_item);
2995
2996 /* Add SINR entries for each PRB */
2997 for (unsigned prb=startPrbu; prb < startPrbu+numPrbu; prb++) {
2998 /* Create a subtree for each PRB */
2999 proto_item *prb_ti = proto_tree_add_string_format(c_section_tree, hf_oran_sinr_prb,
3000 tvb, offset, 0, "", "PRB %3u (", prb);
3001 proto_tree *prb_tree = proto_item_add_subtree(prb_ti, ett_oran_sinr_prb);
3002
3003 /* Each prb starts byte-aligned */
3004 bit_offset = ((bit_offset+7)/8) * 8;
3005
3006 /* N.B., using width/method from UL U-plane preferences, not certain that this is correct.. */
3007
3008 /* sinrCompParam (udCompParam format, may be empty) */
3009 uint32_t exponent = 0; /* N.B. init to silence warnings, but will always be set if read in COMP_BLOCK_FP case */
3010 uint16_t sReSMask;
3011 bit_offset = dissect_udcompparam(tvb, pinfo, prb_tree, bit_offset/8,
3012 pref_iqCompressionSINR, &exponent, &sReSMask,
3013 true1) * 8; /* last param is for_sinr */
3014
3015 /* sinrValues for this PRB. */
3016 /* TODO: not sure how numSinrPerPrb interacts with rb==1... */
3017 for (unsigned n=0; n < num_sinr_per_prb; n++) {
3018 unsigned sinr_bits = tvb_get_bits32(tvb, bit_offset, pref_sample_bit_width_sinr, ENC_BIG_ENDIAN0x00000000);
3019
3020 /* Using SINR compression settings from preferences */
3021 float value = decompress_value(sinr_bits,
3022 pref_iqCompressionSINR, pref_sample_bit_width_sinr,
3023 exponent,
3024 NULL((void*)0) /* no ModCompr for SINR */, 0 /* RE */);
3025 unsigned sample_len_in_bytes = ((bit_offset%8)+pref_sample_bit_width_sinr+7)/8;
3026 proto_item *val_ti = proto_tree_add_float(prb_tree, hf_oran_sinr_value, tvb,
3027 bit_offset/8, sample_len_in_bytes, value);
3028 proto_item_append_text(prb_ti, " %8f", value);
3029
3030 /* Show here which subcarriers share which values (they all divide 12..) */
3031 if (num_sinr_per_prb == 12) {
3032 proto_item_append_text(val_ti, " (PRB=%u, subcarrier %u)",
3033 startPrbu+((prb-startPrbu)*(rb+1)), n*(12/num_sinr_per_prb));
3034 }
3035 else {
3036 proto_item_append_text(val_ti, " (PRB=%u, subcarriers %u-%u)",
3037 startPrbu+((prb-startPrbu)*(rb+1)),
3038 n*(12/num_sinr_per_prb), (n+1)*(12/num_sinr_per_prb)-1);
3039 }
3040 bit_offset += pref_sample_bit_width_sinr;
3041 }
3042
3043 /* 1-byte alignment per PRB (7.2.11) */
3044 offset = (bit_offset+7)/8;
3045 bit_offset = offset*8;
3046
3047 proto_item_append_text(prb_ti, ")");
3048 proto_item_set_end(prb_ti, tvb, offset);
3049 }
3050 break;
3051 }
3052 case SEC_C_REQUEST_RRM_MEAS: /* Section Type 11 - Request RRM Measurements */
3053 /* Reserved (15 bits) */
3054 add_reserved_field(c_section_tree, hf_oran_reserved_15bits, tvb, offset, 2);
3055 offset += 2;
3056 break;
3057
3058 default:
3059 break;
3060 }
3061 }
3062 else if (sectionType == SEC_C_CH_INFO) { /* Section Type 6 */
3063 /* ef */
3064 proto_tree_add_item_ret_boolean(c_section_tree, hf_oran_ef, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &extension_flag);
3065 /* ueId */
3066 proto_tree_add_item_ret_uint(c_section_tree, hf_oran_ueId, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &ueId);
3067 offset += 2;
3068 /* regularizationFactor */
3069 proto_tree_add_item(c_section_tree, hf_oran_regularizationFactor, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
3070 offset += 2;
3071 /* reserved (4 bits) */
3072 add_reserved_field(c_section_tree, hf_oran_reserved_4bits, tvb, offset, 1);
3073 /* rb ("Value=0 shall be set") */
3074 uint32_t rb;
3075 proto_item *rb_ti = proto_tree_add_item_ret_uint(c_section_tree, hf_oran_rb, tvb, offset, 1, ENC_NA0x00000000, &rb);
3076 if (rb != 0) {
3077 proto_item_append_text(rb_ti, " (should be set to 0)");
3078 expert_add_info(pinfo, rb_ti, &ei_oran_st6_rb_shall_be_0);
3079 }
3080 /* symInc */
3081 proto_tree_add_item(c_section_tree, hf_oran_symInc, tvb, offset, 1, ENC_NA0x00000000);
3082 /* startPrbc */
3083 proto_tree_add_item_ret_uint(c_section_tree, hf_oran_startPrbc, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &startPrbc);
3084 offset += 2;
3085 /* numPrbc */
3086 proto_tree_add_item_ret_uint(c_section_tree, hf_oran_numPrbc, tvb, offset, 1, ENC_NA0x00000000, &numPrbc);
3087 offset += 1;
3088
3089 /* Hidden filter for bf */
3090 proto_item *bf_ti = proto_tree_add_item(tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
3091 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
3092
3093 /* ciIsample,ciQsample pairs */
3094 unsigned m;
3095 unsigned prb;
3096 uint32_t bit_offset = offset*8;
3097
3098 /* Antenna count from preference */
3099 unsigned num_trx = pref_num_bf_antennas;
3100
3101 write_channel_section_info(sectionHeading, pinfo,
3102 sectionId, ueId, startPrbc, numPrbc, num_trx);
3103
3104 bool_Bool first_prb = true1;
3105 uint8_t exponent = 0;
3106 for (prb=startPrbc; prb < startPrbc+numPrbc; prb++) {
3107
3108 /* PRB subtree */
3109 unsigned prb_start_offset = bit_offset;
3110 proto_item *prb_ti = proto_tree_add_string_format(c_section_tree, hf_oran_samples_prb,
3111 tvb, bit_offset/8, 0,
3112 "", "PRB=%u", prb);
3113 proto_tree *prb_tree = proto_item_add_subtree(prb_ti, ett_oran_prb_cisamples);
3114
3115 /* There may be a ciCompParam here.. */
3116 if (first_prb || ci_comp_opt==1) {
3117 bit_offset = dissect_ciCompParam(tvb, prb_tree, pinfo, bit_offset, ci_comp_meth, &exponent);
3118 }
3119 first_prb = false0;
3120
3121 /* Antennas */
3122 for (m=0; m < num_trx; m++) {
3123
3124 unsigned sample_offset = bit_offset / 8;
3125 uint8_t sample_extent = ((bit_offset + (ci_iq_width*2)) / 8) - sample_offset;
3126
3127 /* Create subtree for antenna */
3128 proto_item *sample_ti = proto_tree_add_string_format(prb_tree, hf_oran_ciSample,
3129 tvb, sample_offset, sample_extent,
3130 "", "TRX=%2u: ", m);
3131 proto_tree *sample_tree = proto_item_add_subtree(sample_ti, ett_oran_cisample);
3132
3133 /* I */
3134 /* Get bits, and convert to float. */
3135 uint32_t bits = tvb_get_bits32(tvb, bit_offset, ci_iq_width, ENC_BIG_ENDIAN0x00000000);
3136 float value = decompress_value(bits, ci_comp_meth, ci_iq_width, exponent, NULL((void*)0) /* no ModCompr for ST6 */, 0 /* RE */);
3137
3138 /* Add to tree. */
3139 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);
3140 bit_offset += ci_iq_width;
3141 proto_item_append_text(sample_ti, "I%u=%f ", m, value);
3142
3143 /* Q */
3144 /* Get bits, and convert to float. */
3145 bits = tvb_get_bits32(tvb, bit_offset, ci_iq_width, ENC_BIG_ENDIAN0x00000000);
3146 value = decompress_value(bits, ci_comp_meth, ci_iq_width, exponent, NULL((void*)0) /* no ModCompr for ST6 */, 0 /* RE */);
3147
3148 /* Add to tree. */
3149 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);
3150 bit_offset += ci_iq_width;
3151 proto_item_append_text(sample_ti, "Q%u=%f ", m, value);
3152 }
3153 proto_item_set_len(prb_ti, (bit_offset-prb_start_offset+7)/8);
3154 }
3155
3156 /* Pad out by 1 or 4 bytes, according to preference */
3157 if (!st6_4byte_alignment) {
3158 offset = (bit_offset + 7) / 8;
3159 }
3160 else {
3161 int mode = bit_offset % 32;
3162 if (mode != 0) {
3163 offset = (bit_offset + (32-mode))/8;
3164 }
3165 else {
3166 offset = bit_offset/8;
3167 }
3168 }
3169 proto_item_set_end(c_section_tree, tvb, offset);
3170 }
3171
3172
3173 expected_section_data_t *data_section = NULL((void*)0);
3174 unsigned index_to_use = 0;
3175
3176 /* On first pass, allocate a section entry to use */
3177 if (link_planes_together && !PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
3178
3179 /* Look for existing entry for sectionId to overwrite first. */
3180 uint8_t direction = !tap_info->uplink;
3181 data_section = wmem_tree_lookup32(state->expected_sections[direction],
3182 sectionId);
3183 if (data_section == NULL((void*)0)) {
3184 /* None, so create */
3185 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)))
;
3186 wmem_tree_insert32(state->expected_sections[direction],
3187 sectionId,
3188 data_section);
3189 }
3190
3191 /* If 2nd entry not in use, use that one */
3192 if (!data_section->details[1].in_use) {
3193 index_to_use = 1;
3194 }
3195 else {
3196 /* Both in use, so replace the older of the 2 entries */
3197 if (data_section->details[1].frame_number < data_section->details[0].frame_number) {
3198 index_to_use = 1;
3199 }
3200 }
3201
3202 if (data_section) {
3203 section_details_t *details = &data_section->details[index_to_use];
3204
3205 details->in_use = true1;
3206 details->frame = frameId;
3207 details->subframe = subframeId;
3208 details->slot = slotId;
3209 details->startSymbol = startSymbolId;
3210
3211 details->frame_number = pinfo->num;
3212 details->frame_time = pinfo->abs_ts;
3213 data_section->sectionId = sectionId;
3214 details->startPrb = startPrbc;
3215 details->numPrb = numPrbc;
3216 for (unsigned prb = startPrbc; prb <= startPrbc+numPrbc; prb++) {
3217 if (prb < 273) {
3218 details->beamIds[prb] = section_beamId;
3219 }
3220 }
3221 }
3222 }
3223
3224 bool_Bool seen_se10 = false0;
3225 uint32_t numPortc = 0;
3226 proto_item *bf_ti = NULL((void*)0);
3227
3228 /* Section extension commands */
3229 while (extension_flag) {
3230 int extension_start_offset = offset;
3231
3232 /* Prefetch extType so can use specific extension type ett */
3233 uint32_t exttype = tvb_get_uint8(tvb, offset) & 0x7f;
3234 uint32_t exttype_ett_index = exttype;
3235 if (exttype == 0 || exttype > HIGHEST_EXTTYPE32) {
3236 /* Just use first one if out of range */
3237 exttype_ett_index = 1;
3238 }
3239
3240 /* Create subtree for each extension (with summary) */
3241 proto_item *extension_ti = proto_tree_add_string_format(c_section_tree, hf_oran_extension,
3242 tvb, offset, 0, "", "Extension");
3243 proto_tree *extension_tree = proto_item_add_subtree(extension_ti, ett_oran_c_section_extension[exttype_ett_index-1]);
3244
3245 /* ef (i.e. another extension after this one?) */
3246 proto_tree_add_item_ret_boolean(extension_tree, hf_oran_ef, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &extension_flag);
3247
3248 /* extType */
3249 proto_item *exttype_ti;
3250 exttype_ti = proto_tree_add_item(extension_tree, hf_oran_exttype, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3251 offset++;
3252 proto_item_append_text(sectionHeading, " (ext-%u)", exttype);
3253
3254 proto_item_append_text(extension_ti, " (ext-%u: %s)", exttype, val_to_str_ext_const(exttype, &exttype_vals_ext, "Reserved"));
3255
3256 /* Don't tap if out of range. */
3257 if (exttype > 0 && exttype <= HIGHEST_EXTTYPE32) {
3258 tap_info->extensions[exttype] = true1;
3259 }
3260
3261 /* Is this SE allowed for this section type? */
3262 if (!se_allowed_in_st(exttype, sectionType)) {
3263 expert_add_info_format(pinfo, extension_tree, &ei_oran_se_on_unsupported_st,
3264 "SE %u (%s) should not appear in ST %u (%s)!",
3265 exttype, val_to_str_ext_const(exttype, &exttype_vals_ext, "Reserved"),
3266 sectionType, rval_to_str_const(sectionType, section_types, "Unknown"));
3267 }
3268
3269
3270 /* extLen (number of 32-bit words) */
3271 uint32_t extlen_len = ((exttype==11)||(exttype==19)||(exttype==20)) ? 2 : 1; /* Extensions 11/19/20 are special */
3272 uint32_t extlen;
3273 proto_item *extlen_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_extlen, tvb,
3274 offset, extlen_len, ENC_BIG_ENDIAN0x00000000, &extlen);
3275 proto_item_append_text(extlen_ti, " (%u bytes)", extlen*4);
3276 offset += extlen_len;
3277 if (extlen == 0) {
3278 expert_add_info(pinfo, extlen_ti, &ei_oran_extlen_zero);
3279 /* Break out to avoid infinitely looping! */
3280 break;
3281 }
3282
3283 bool_Bool ext_unhandled = false0;
3284
3285 switch (exttype) {
3286
3287 case 1: /* SE 1: Beamforming Weights */
3288 {
3289 uint32_t bfwcomphdr_iq_width, bfwcomphdr_comp_meth;
3290 proto_item *comp_meth_ti = NULL((void*)0);
3291
3292 /* Hidden filter for bf */
3293 bf_ti = proto_tree_add_item(tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
3294 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
3295
3296 /* bfwCompHdr (2 subheaders - bfwIqWidth and bfwCompMeth)*/
3297 offset = dissect_bfwCompHdr(tvb, extension_tree, offset,
3298 &bfwcomphdr_iq_width, &bfwcomphdr_comp_meth, &comp_meth_ti);
3299
3300 /* bfwCompParam */
3301 uint32_t exponent = 0;
3302 bool_Bool compression_method_supported = false0;
3303 unsigned num_trx = 0;
3304 uint16_t *trx; /* ptr to array */
3305 offset = dissect_bfwCompParam(tvb, extension_tree, pinfo, offset, comp_meth_ti,
3306 &bfwcomphdr_comp_meth, &exponent, &compression_method_supported,
3307 &num_trx, &trx);
3308
3309 /* Can't show details of unsupported compression method */
3310 if (!compression_method_supported) {
3311 break;
3312 }
3313
3314 /* We know:
3315 - iq_width (above)
3316 - numBfWeights (taken from preference)
3317 - remaining bytes in extension
3318 We can therefore derive TRX (number of antennas).
3319 */
3320
3321 bool_Bool using_array = false0;
3322
3323 /* I & Q samples
3324 May know how many entries from activeBeamspaceCoefficientMask. */
3325 if (num_trx == 0) {
3326 /* Don't know how many there will be, so just fill available bytes... */
3327 unsigned weights_bytes = (extlen*4)-3;
3328 unsigned num_weights_pairs = (weights_bytes*8) / (bfwcomphdr_iq_width*2);
3329 num_trx = num_weights_pairs;
3330 }
3331 else {
3332 using_array = true1;
3333 num_trx = pref_num_bf_antennas;
3334 }
3335
3336 int bit_offset = offset*8;
3337
3338 for (unsigned n=0; n < num_trx; n++) {
3339 /* Create antenna subtree */
3340 int bfw_offset = bit_offset / 8;
3341
3342 uint16_t trx_index = (using_array) ? trx[n] : n+1;
3343
3344 proto_item *bfw_ti = proto_tree_add_string_format(extension_tree, hf_oran_bfw,
3345 tvb, bfw_offset, 0, "", "TRX %3u: (", trx_index);
3346 proto_tree *bfw_tree = proto_item_add_subtree(bfw_ti, ett_oran_bfw);
3347
3348 /* I value */
3349 /* Get bits, and convert to float. */
3350 uint32_t bits = tvb_get_bits32(tvb, bit_offset, bfwcomphdr_iq_width, ENC_BIG_ENDIAN0x00000000);
3351 float value = decompress_value(bits, bfwcomphdr_comp_meth, bfwcomphdr_iq_width, exponent,
3352 NULL((void*)0) /* no ModCompr */, 0 /* RE */);
3353 /* Add to tree. */
3354 proto_tree_add_float(bfw_tree, hf_oran_bfw_i, tvb, bit_offset/8,
3355 (bfwcomphdr_iq_width+7)/8, value);
3356 bit_offset += bfwcomphdr_iq_width;
3357 proto_item_append_text(bfw_ti, "I=%f ", value);
3358
3359 /* Leave a gap between I and Q values */
3360 proto_item_append_text(bfw_ti, " ");
3361
3362 /* Q value */
3363 /* Get bits, and convert to float. */
3364 bits = tvb_get_bits32(tvb, bit_offset, bfwcomphdr_iq_width, ENC_BIG_ENDIAN0x00000000);
3365 value = decompress_value(bits, bfwcomphdr_comp_meth, bfwcomphdr_iq_width, exponent,
3366 NULL((void*)0) /* no ModCompr */, 0 /* RE */);
3367 /* Add to tree. */
3368 proto_tree_add_float(bfw_tree, hf_oran_bfw_q, tvb, bit_offset/8,
3369 (bfwcomphdr_iq_width+7)/8, value);
3370 bit_offset += bfwcomphdr_iq_width;
3371 proto_item_append_text(bfw_ti, "Q=%f", value);
3372
3373 proto_item_append_text(bfw_ti, ")");
3374 proto_item_set_len(bfw_ti, (bit_offset+7)/8 - bfw_offset);
3375 }
3376 /* Need to round to next byte */
3377 offset = (bit_offset+7)/8;
3378
3379 break;
3380 }
3381
3382 case 2: /* SE 2: Beamforming attributes */
3383 {
3384 /* Hidden filter for bf */
3385 bf_ti = proto_tree_add_item(tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
3386 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
3387
3388 /* bfaCompHdr (get widths of fields to follow) */
3389 uint32_t bfAzPtWidth, bfZePtWidth, bfAz3ddWidth, bfZe3ddWidth;
3390 /* subtree */
3391 proto_item *bfa_ti = proto_tree_add_string_format(extension_tree, hf_oran_bfaCompHdr,
3392 tvb, offset, 2, "", "bfaCompHdr");
3393 proto_tree *bfa_tree = proto_item_add_subtree(bfa_ti, ett_oran_bfacomphdr);
3394
3395 /* reserved (2 bits) */
3396 add_reserved_field(bfa_tree, hf_oran_reserved_2bits, tvb, offset, 1);
3397 /* bfAzPtWidth (3 bits) */
3398 proto_tree_add_item_ret_uint(bfa_tree, hf_oran_bfAzPtWidth, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &bfAzPtWidth);
3399 /* bfZePtWidth (3 bits) */
3400 proto_tree_add_item_ret_uint(bfa_tree, hf_oran_bfZePtWidth, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &bfZePtWidth);
3401 offset += 1;
3402
3403 /* reserved (2 bits) */
3404 add_reserved_field(bfa_tree, hf_oran_reserved_2bits, tvb, offset, 1);
3405 /* bfAz3ddWidth (3 bits) */
3406 proto_tree_add_item_ret_uint(bfa_tree, hf_oran_bfAz3ddWidth, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &bfAz3ddWidth);
3407 /* bfZe3ddWidth (3 bits) */
3408 proto_tree_add_item_ret_uint(bfa_tree, hf_oran_bfZe3ddWidth, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &bfZe3ddWidth);
3409 offset += 1;
3410
3411 unsigned bit_offset = offset*8;
3412
3413 /* bfAzPt */
3414 if (bfAzPtWidth > 0) {
3415 proto_tree_add_bits_item(extension_tree, hf_oran_bfAzPt, tvb, bit_offset, bfAzPtWidth+1, ENC_BIG_ENDIAN0x00000000);
3416 bit_offset += (bfAzPtWidth+1);
3417 }
3418 /* bfZePt */
3419 if (bfZePtWidth > 0) {
3420 proto_tree_add_bits_item(extension_tree, hf_oran_bfZePt, tvb, bit_offset, bfZePtWidth+1, ENC_BIG_ENDIAN0x00000000);
3421 bit_offset += (bfZePtWidth+1);
3422 }
3423 /* bfAz3dd */
3424 if (bfAz3ddWidth > 0) {
3425 proto_tree_add_bits_item(extension_tree, hf_oran_bfAz3dd, tvb, bit_offset, bfAz3ddWidth+1, ENC_BIG_ENDIAN0x00000000);
3426 bit_offset += (bfAz3ddWidth+1);
3427 }
3428 /* bfZe3dd */
3429 if (bfZe3ddWidth > 0) {
3430 proto_tree_add_bits_item(extension_tree, hf_oran_bfZe3dd, tvb, bit_offset, bfZe3ddWidth+1, ENC_BIG_ENDIAN0x00000000);
3431 bit_offset += (bfZe3ddWidth+1);
3432 }
3433
3434 /* Pad to next byte (unless last 2 fields already fit in this one) */
3435 if ((bit_offset % 8) > 2) {
3436 offset = (bit_offset+7) / 8;
3437 }
3438 else {
3439 offset = bit_offset / 8;
3440 }
3441
3442 /* bfAzSl (3 bits) */
3443 proto_tree_add_item(extension_tree, hf_oran_bfAzSl, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3444 /* bfZeSl (3 bits) */
3445 proto_tree_add_item(extension_tree, hf_oran_bfZeSl, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3446 offset += 1;
3447 break;
3448 }
3449
3450 case 3: /* SE 3: DL precoding parameters */
3451 {
3452 /* codebookindex (8 bits) */
3453 /* "This parameter is not used and shall be set to zero." */
3454 proto_tree_add_item(extension_tree, hf_oran_codebook_index, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3455 offset += 1;
3456 /* layerid */
3457 uint32_t layerid;
3458 proto_tree_add_item_ret_uint(extension_tree, hf_oran_layerid, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &layerid);
3459 /* numLayers */
3460 proto_tree_add_item(extension_tree, hf_oran_numlayers, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3461 offset += 1;
3462
3463 /* Stop here for non-first data layer */
3464 if (layerid != 0 && layerid != 0xf) {
3465 break;
3466 }
3467
3468 /* First data layer case */
3469 /* txScheme */
3470 proto_tree_add_item(extension_tree, hf_oran_txscheme, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3471 /* crsReMask */
3472 proto_tree_add_item(extension_tree, hf_oran_crs_remask, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
3473 offset += 2;
3474
3475 /* crsShift (1 bit) */
3476 proto_tree_add_item(extension_tree, hf_oran_crs_shift, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3477 /* reserved (3 bits) */
3478 add_reserved_field(extension_tree, hf_oran_reserved_bits123, tvb, offset, 1);
3479 /* crsSymNum (4 bits) */
3480 proto_tree_add_item(extension_tree, hf_oran_crs_symnum, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3481 offset += 1;
3482 /* reserved (8 bits) */
3483 add_reserved_field(extension_tree, hf_oran_reserved_8bits, tvb, offset, 1);
3484 offset += 1;
3485
3486 /* reserved (1 bit) */
3487 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
3488 /* beamIdAP1 (15 bits) */
3489 proto_tree_add_item(extension_tree, hf_oran_beamid_ap1, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
3490 offset += 2;
3491 /* reserved (1 bit) */
3492 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
3493 /* beamIdAP2 (15 bits) */
3494 proto_tree_add_item(extension_tree, hf_oran_beamid_ap2, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
3495 offset += 2;
3496 /* reserved (1 bit) */
3497 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
3498 /* beamIdAP3 (15 bits) */
3499 proto_tree_add_item(extension_tree, hf_oran_beamid_ap3, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
3500 offset += 2;
3501 break;
3502 }
3503
3504 case 4: /* SE 4: Modulation compression params (5.4.7.4) (single sets) */
3505 {
3506 /* csf */
3507 bool_Bool csf;
3508 dissect_csf(extension_tree, tvb, offset*8, ci_iq_width, &csf);
3509
3510 /* modCompScaler */
3511 uint32_t modCompScaler;
3512 proto_item *ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_modcompscaler,
3513 tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &modCompScaler);
3514 offset += 2;
3515
3516 /* Work out and show floating point value too. exponent and mantissa are both unsigned */
3517 uint16_t exponent = (modCompScaler >> 11) & 0x000f; /* m.s. 4 bits */
3518 uint16_t mantissa = modCompScaler & 0x07ff; /* l.s. 11 bits */
3519 float value = ((float)mantissa/(1<<11)) * ((float)1.0 / (1 << exponent));
3520 proto_item_append_text(ti, " (%f)", value);
3521
3522 section_mod_compr_config_t* sect_config = get_mod_compr_section_to_write(state, sectionId);
3523
3524 /* Store these params in this flow's state */
3525 if (sect_config && sect_config->num_configs < MAX_MOD_COMPR_CONFIGS12) {
3526 unsigned i = sect_config->num_configs;
3527 sect_config->configs[i].mod_compr_re_mask = 0xfff; /* Covers all REs */
3528 sect_config->configs[i].mod_compr_csf = csf;
3529 sect_config->configs[i].mod_compr_scaler = value;
3530 sect_config->num_configs++;
3531 }
3532 break;
3533 }
3534
3535 case 5: /* SE 5: Modulation Compression Additional Parameters (7.7.5) (multiple sets) */
3536 {
3537 /* Applies only to section types 1,3 and 5 */
3538 /* N.B. there may be multiple instances of this SE in the same frame */
3539
3540 /* There may be one or 2 entries, depending upon extlen */
3541 int sets = 1, reserved_bits = 0;
3542 switch (extlen) {
3543 case 2:
3544 sets = 1;
3545 reserved_bits = 20;
3546 break;
3547 case 3:
3548 sets = 2;
3549 reserved_bits = 24;
3550 break;
3551 case 4:
3552 /* sets can be 3 or 4, depending upon whether last 28 bits are 0.. */
3553 if ((tvb_get_ntohl(tvb, offset+10) & 0x0fffffff) == 0) {
3554 sets = 3;
3555 reserved_bits = 28;
3556 }
3557 else {
3558 sets = 4;
3559 reserved_bits = 0;
3560 }
3561 break;
3562
3563 default:
3564 /* Malformed error!!! */
3565 expert_add_info_format(pinfo, extlen_ti, &ei_oran_extlen_wrong,
3566 "For section 5, extlen must be 2, 3 or 4, but %u was dissected",
3567 extlen);
3568 break;
3569 }
3570
3571 unsigned bit_offset = offset*8;
3572 /* Dissect each set */
3573 for (int n=0; n < sets; n++) {
3574 /* Subtree for each set */
3575 unsigned set_start_offset = bit_offset/8;
3576 proto_item *set_ti = proto_tree_add_string(extension_tree, hf_oran_modcomp_param_set,
3577 tvb, set_start_offset, 0, "");
3578 proto_tree *set_tree = proto_item_add_subtree(set_ti, ett_oran_modcomp_param_set);
3579
3580 uint64_t mcScaleReMask, mcScaleOffset;
3581 bool_Bool csf;
3582
3583 /* mcScaleReMask (12 bits). Defines which REs the following csf and mcScaleOffset apply to */
3584 static int * const remask_flags[] = {
3585 &hf_oran_mc_scale_re_mask_re1,
3586 &hf_oran_mc_scale_re_mask_re2,
3587 &hf_oran_mc_scale_re_mask_re3,
3588 &hf_oran_mc_scale_re_mask_re4,
3589 &hf_oran_mc_scale_re_mask_re5,
3590 &hf_oran_mc_scale_re_mask_re6,
3591 &hf_oran_mc_scale_re_mask_re7,
3592 &hf_oran_mc_scale_re_mask_re8,
3593 &hf_oran_mc_scale_re_mask_re9,
3594 &hf_oran_mc_scale_re_mask_re10,
3595 &hf_oran_mc_scale_re_mask_re11,
3596 &hf_oran_mc_scale_re_mask_re12,
3597 NULL((void*)0)
3598 };
3599 /* Same as above, but offset by 4 bits */
3600 static int * const remask_flags_even[] = {
3601 &hf_oran_mc_scale_re_mask_re1_even,
3602 &hf_oran_mc_scale_re_mask_re2_even,
3603 &hf_oran_mc_scale_re_mask_re3_even,
3604 &hf_oran_mc_scale_re_mask_re4_even,
3605 &hf_oran_mc_scale_re_mask_re5_even,
3606 &hf_oran_mc_scale_re_mask_re6_even,
3607 &hf_oran_mc_scale_re_mask_re7_even,
3608 &hf_oran_mc_scale_re_mask_re8_even,
3609 &hf_oran_mc_scale_re_mask_re9_even,
3610 &hf_oran_mc_scale_re_mask_re10_even,
3611 &hf_oran_mc_scale_re_mask_re11_even,
3612 &hf_oran_mc_scale_re_mask_re12_even,
3613 NULL((void*)0)
3614 };
3615
3616 /* RE Mask (12 bits) */
3617 proto_tree_add_bitmask_ret_uint64(set_tree, tvb, bit_offset / 8,
3618 (n % 2) ? hf_oran_mc_scale_re_mask_even : hf_oran_mc_scale_re_mask,
3619 ett_oran_mc_scale_remask,
3620 (n % 2) ? remask_flags_even : remask_flags, ENC_BIG_ENDIAN0x00000000, &mcScaleReMask);
3621 bit_offset += 12;
3622
3623 /* csf (1 bit) */
3624 bit_offset = dissect_csf(set_tree, tvb, bit_offset, ci_iq_width, &csf);
3625 /* mcScaleOffset (15 bits) */
3626 proto_item *ti = proto_tree_add_bits_ret_val(set_tree, hf_oran_mc_scale_offset, tvb, bit_offset, 15, &mcScaleOffset, ENC_BIG_ENDIAN0x00000000);
3627 uint16_t exponent = (mcScaleOffset >> 11) & 0x000f; /* m.s. 4 bits */
3628 uint16_t mantissa = mcScaleOffset & 0x07ff; /* l.s. 11 bits */
3629 float mcScaleOffset_value = ((float)mantissa/(1<<11)) * ((float)1.0 / (1 << exponent));
3630 proto_item_append_text(ti, " (%f)", mcScaleOffset_value);
3631 bit_offset += 15;
3632
3633 section_mod_compr_config_t* sect_config = get_mod_compr_section_to_write(state, sectionId);
3634
3635 /* Record this config */
3636 if (sect_config && sect_config->num_configs < MAX_MOD_COMPR_CONFIGS12) {
3637 unsigned i = sect_config->num_configs;
3638 sect_config->configs[i].mod_compr_re_mask = (uint16_t)mcScaleReMask;
3639 sect_config->configs[i].mod_compr_csf = csf;
3640 sect_config->configs[i].mod_compr_scaler = mcScaleOffset_value;
3641 sect_config->num_configs++;
3642 }
3643
3644 /* Summary */
3645 proto_item_set_len(set_ti, (bit_offset+7)/8 - set_start_offset);
3646 proto_item_append_text(set_ti, " (mcScaleReMask=0x%03x csf=%5s mcScaleOffset=%f)",
3647 (unsigned)mcScaleReMask, tfs_get_true_false(csf)tfs_get_string(csf, ((void*)0)), mcScaleOffset_value);
3648 }
3649
3650 proto_item_append_text(extension_ti, " (%u sets)", sets);
3651
3652 /* Reserved (variable-length) */
3653 if (reserved_bits) {
3654 proto_tree_add_bits_item(extension_tree, hf_oran_reserved, tvb, bit_offset, reserved_bits, ENC_BIG_ENDIAN0x00000000);
3655 bit_offset += reserved_bits;
3656 }
3657
3658 offset = bit_offset/8;
3659 break;
3660 }
3661
3662 case 6: /* SE 6: Non-contiguous PRB allocation in time and frequency domain */
3663 {
3664 /* numSymbol not used in this case */
3665 if (numsymbol_ti && !numsymbol_ignored) {
3666 proto_item_append_text(numsymbol_ti, " (ignored)");
3667 numsymbol_ignored = true1;
3668 }
3669
3670 /* Will update ext6 recorded info */
3671 ext11_settings.ext6_set = true1;
3672
3673 /* repetition */
3674 proto_tree_add_bits_item(extension_tree, hf_oran_se6_repetition, tvb, offset*8, 1, ENC_BIG_ENDIAN0x00000000);
3675 /* rbgSize (PRBs per bit set in rbgMask) */
3676 uint32_t rbgSize;
3677 proto_item *rbg_size_ti;
3678 rbg_size_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_rbgSize, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &rbgSize);
3679 if (rbgSize == 0) {
3680 /* N.B. this is only true if "se6-rb-bit-supported" is set... */
3681 expert_add_info(pinfo, rbg_size_ti, &ei_oran_rbg_size_reserved);
3682 }
3683 /* rbgMask (28 bits) */
3684 uint32_t rbgMask;
3685 proto_item *rbgmask_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_rbgMask, tvb, offset, 4, ENC_BIG_ENDIAN0x00000000, &rbgMask);
3686 if (rbgSize == 0) {
3687 proto_item_append_text(rbgmask_ti, " (value ignored since rbgSize is 0)");
3688 }
3689
3690 /* TODO: if receiver detects non-zero bits outside the valid range, those shall be ignored. */
3691 offset += 4;
3692 /* priority */
3693 proto_tree_add_item(extension_tree, hf_oran_noncontig_priority, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3694 /* symbolMask */
3695 offset = dissect_symbolmask(tvb, extension_tree, offset, NULL((void*)0), NULL((void*)0));
3696
3697 /* Look up rbg_size enum -> value */
3698 switch (rbgSize) {
3699 case 0:
3700 /* N.B. reserved, but covered above with expert info (would remain 0) */
3701 break;
3702 case 1:
3703 ext11_settings.ext6_rbg_size = 1; break;
3704 case 2:
3705 ext11_settings.ext6_rbg_size = 2; break;
3706 case 3:
3707 ext11_settings.ext6_rbg_size = 3; break;
3708 case 4:
3709 ext11_settings.ext6_rbg_size = 4; break;
3710 case 5:
3711 ext11_settings.ext6_rbg_size = 6; break;
3712 case 6:
3713 ext11_settings.ext6_rbg_size = 8; break;
3714 case 7:
3715 ext11_settings.ext6_rbg_size = 16; break;
3716 /* N.B., encoded in 3 bits, so no other values are possible */
3717 }
3718
3719 /* Set to looked-up value */
3720 rbgSize = ext11_settings.ext6_rbg_size;
3721
3722 uint32_t lastRbgid = 0;
3723 if (rbgSize != 0) {
3724 /* The O-DU shall not use combinations of startPrbc, numPrbc and rbgSize leading to a value of lastRbgid larger than 27 */
3725 /* i.e., leftmost bit used should not need to go off left end of rbgMask! */
3726 lastRbgid = (uint32_t)ceil((numPrbc + (startPrbc % rbgSize)) / (float)rbgSize) - 1;
3727 if (lastRbgid > 27) {
3728 expert_add_info_format(pinfo, rbg_size_ti, &ei_oran_lastRbdid_out_of_range,
3729 "SE6: rbgSize (%u) not compatible with startPrbc(%u) and numPrbc(%u)",
3730 rbgSize, startPrbc, numPrbc);
3731 break;
3732 }
3733 }
3734
3735 /* Record (and count) which bits are set in rbgMask */
3736 bool_Bool first_seen = false0;
3737 unsigned first_seen_pos=0, last_seen_pos=0;
3738 for (unsigned n=0; n < 28 && ext11_settings.ext6_num_bits_set < 28; n++) {
3739 if ((rbgMask >> n) & 0x01) {
3740 ext11_settings.ext6_bits_set[ext11_settings.ext6_num_bits_set++] = n;
3741 if (!first_seen) {
3742 first_seen = true1;
3743 first_seen_pos = n;
3744 }
3745 last_seen_pos = n;
3746 }
3747 }
3748
3749 /* Show how many bits were set in rbgMask */
3750 proto_item_append_text(rbgmask_ti, " (%u bits set)", ext11_settings.ext6_num_bits_set);
3751 /* Also, that is the range of bits */
3752 if (first_seen) {
3753 proto_item_append_text(rbgmask_ti, " (%u bits spread)", last_seen_pos-first_seen_pos+1);
3754
3755 /* Complain if last set bit is beyond lastRbgid */
3756 if (last_seen_pos > lastRbgid) {
3757 expert_add_info_format(pinfo, rbgmask_ti, &ei_oran_rbgMask_beyond_last_rbdid,
3758 "SE6: rbgMask (0x%07x) has bit %u set, but lastRbgId is %u",
3759 rbgMask, last_seen_pos, lastRbgid);
3760 }
3761 }
3762
3763 /* Also update prbs_for_st10_type5[] */
3764 if (sectionType == 10 && rbgSize != 0) {
3765 /* Unset all entries */
3766 memset(&prbs_for_st10_type5, 0, sizeof(prbs_for_st10_type5));
3767
3768 /* Work out which PRB first bit corresponds to */
3769 unsigned firstPrbStart = (startPrbc/rbgSize) * rbgSize;
3770
3771 /* Add PRBs corresponding to each bit set */
3772 for (unsigned n=0; n < 28 ; n++) {
3773 if ((rbgMask >> n) & 0x01) {
3774 /* Lazy way to clip any values that lie outside of range for section */
3775 for (unsigned p=0; p < rbgSize; p++) {
3776 unsigned start = firstPrbStart + (n*rbgSize);
3777 if ((start+p < MAX_PRBS273) && (start+p >= startPrbc) && (start+p <= startPrbc+numPrbc-1)) {
3778 prbs_for_st10_type5[start+p] = true1;
3779 }
3780 }
3781 }
3782 }
3783 }
3784
3785 break;
3786 }
3787
3788 case 7: /* SE 7: eAxC mask */
3789 /* Allow ST0 to address multiple eAxC_ID values for transmission blanking */
3790 proto_tree_add_item(extension_tree, hf_oran_eAxC_mask, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
3791 offset += 2;
3792 break;
3793
3794 case 8: /* SE 8: Regularization factor */
3795 proto_tree_add_item(extension_tree, hf_oran_regularizationFactor, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
3796 offset += 2;
3797 break;
3798
3799 case 9: /* SE 9: Dynamic Spectrum Sharing parameters */
3800 proto_tree_add_item(extension_tree, hf_oran_technology, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3801 offset += 1;
3802 add_reserved_field(extension_tree, hf_oran_reserved_8bits, tvb, offset, 1);
3803 offset += 1;
3804 break;
3805
3806 case 10: /* SE 10: Group configuration of multiple ports */
3807 {
3808 seen_se10 = true1;
3809
3810 /* beamGroupType */
3811 uint32_t beam_group_type = 0;
3812 proto_item *bgt_ti;
3813 bgt_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_beamGroupType,
3814 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &beam_group_type);
3815 proto_item_append_text(extension_ti, " (%s)", val_to_str_const(beam_group_type, beam_group_type_vals, "Unknown"));
3816
3817 /* numPortc */
3818 proto_tree_add_item_ret_uint(extension_tree, hf_oran_numPortc,
3819 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &numPortc);
3820 offset++;
3821
3822 /* Will append all beamId values to extension_ti, regardless of beamGroupType */
3823 unsigned n;
3824
3825 switch (beam_group_type) {
3826 case 0x0: /* common beam */
3827 case 0x1: /* beam matrix indication */
3828 /* Reserved byte */
3829 add_reserved_field(extension_tree, hf_oran_reserved_8bits, tvb, offset, 1);
3830 offset++;
3831
3832 /* Explain how entries are allocated */
3833 if (beam_group_type == 0x0) {
3834 proto_item_append_text(extension_ti, " (all %u ueid/Beam entries are %u)", numPortc, ueId);
3835 }
3836 else {
3837 /* 'numPortc' consecutive BeamIds from section header */
3838 proto_item_append_text(extension_ti, " (ueId/beam entries are %u -> %u)", ueId, ueId+numPortc);
3839 }
3840
3841 if (sectionType == 5) {
3842 /* These types are not allowed */
3843 expert_add_info_format(pinfo, bgt_ti, &ei_oran_se10_not_allowed,
3844 "SE10: beamGroupType %u is not allowed for section type 5", beam_group_type);
3845 }
3846 break;
3847
3848 case 0x2: /* beam vector listing */
3849 {
3850 proto_item_append_text(extension_ti, " [ ");
3851
3852 /* Beam listing vector case */
3853 /* Work out how many port beam entries there is room for */
3854 /* Using numPortC as visible in issue 18116 */
3855 for (n=0; n < numPortc; n++) {
3856 /* 1 reserved bit */
3857 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
3858
3859 /* port beam ID (or UEID) (15 bits) */
3860 uint32_t id;
3861 proto_item *beamid_or_ueid_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_beamId,
3862 tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &id);
3863 proto_item_append_text(beamid_or_ueid_ti, " port #%u beam ID (or UEId) %u", n, id);
3864 offset += 2;
3865
3866 if (id != 0x7fff) {
3867 if (number_of_ueids < MAX_UEIDS16) {
3868 ueids[number_of_ueids++] = id;
3869 }
3870 }
3871
3872 proto_item_append_text(extension_ti, "%u ", id);
3873 }
3874
3875 proto_item_append_text(extension_ti, "]");
3876 break;
3877 }
3878 case 0x3: /* beamId/ueId listing with associated port-list index */
3879 {
3880 proto_item_append_text(extension_ti, " [ ");
3881
3882 if (numPortc > 0) {
3883 /* first portListIndex is outside loop */
3884 uint32_t port_list_index;
3885 proto_item *pli_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_port_list_index, tvb,
3886 offset, 1, ENC_BIG_ENDIAN0x00000000, &port_list_index);
3887 if (port_list_index == 0) {
3888 /* Value 0 is reserved */
3889 expert_add_info(pinfo, pli_ti, &ei_oran_port_list_index_zero);
3890 }
3891 offset += 1;
3892
3893 for (n=0; n < numPortc-1; n++) {
3894 /* 1 reserved bit */
3895 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
3896
3897 /* port beam ID (or UEID) */
3898 uint32_t id;
3899 proto_item *beamid_or_ueid_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_beamId,
3900 tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &id);
3901 proto_item_append_text(beamid_or_ueid_ti, " port #%u beam ID (or UEId) %u", n, id);
3902 offset += 2;
3903
3904 if (id != 0x7fff) {
3905 if (number_of_ueids < MAX_UEIDS16) {
3906 ueids[number_of_ueids++] = id;
3907 }
3908 }
3909
3910 /* subsequent portListIndex */
3911 pli_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_port_list_index, tvb,
3912 offset, 1, ENC_BIG_ENDIAN0x00000000, &port_list_index);
3913 if (port_list_index == 0) {
3914 /* Value 0 is reserved */
3915 expert_add_info(pinfo, pli_ti, &ei_oran_port_list_index_zero);
3916 }
3917 offset += 1;
3918
3919 proto_item_append_text(extension_ti, "%u:%u ", port_list_index, id);
3920 }
3921 }
3922
3923 proto_item_append_text(extension_ti, "]");
3924 break;
3925 }
3926
3927
3928 default:
3929 /* Warning for unsupported/reserved value */
3930 expert_add_info(NULL((void*)0), bgt_ti, &ei_oran_se10_unknown_beamgrouptype);
3931 break;
3932 }
3933 break;
3934 }
3935
3936 case 11: /* SE 11: Flexible Weights Extension Type */
3937 {
3938 /* Hidden filter for bf */
3939 bf_ti = proto_tree_add_item(tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
3940 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
3941
3942 /* beamId in section header should be ignored. Guard against appending multiple times.. */
3943 if (section_beamId_ti && !section_beamId_ignored) {
3944 proto_item_append_text(section_beamId_ti, " (ignored)");
3945 section_beamId_ignored = true1;
3946 }
3947
3948 bool_Bool disableBFWs;
3949 uint32_t numBundPrb;
3950 bool_Bool rad;
3951
3952 /* disableBFWs */
3953 proto_tree_add_item_ret_boolean(extension_tree, hf_oran_disable_bfws,
3954 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &disableBFWs);
3955 if (disableBFWs) {
3956 proto_item_append_text(extension_ti, " (disableBFWs)");
3957 }
3958
3959 /* RAD */
3960 proto_tree_add_item_ret_boolean(extension_tree, hf_oran_rad,
3961 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &rad);
3962 /* bundleOffset (6 bits) */
3963 proto_tree_add_item(extension_tree, hf_oran_bundle_offset, tvb,
3964 offset, 1, ENC_BIG_ENDIAN0x00000000);
3965 offset++;
3966
3967 /* numBundPrb (number of prbs in each bundle) */
3968 proto_item *num_bund_prb_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_num_bund_prbs,
3969 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &numBundPrb);
3970 offset++;
3971 /* value zero is reserved.. */
3972 if (numBundPrb == 0) {
3973 expert_add_info(pinfo, num_bund_prb_ti, &ei_oran_reserved_numBundPrb);
3974 }
3975
3976 uint32_t num_bundles;
3977 bool_Bool orphaned_prbs = false0;
3978
3979 /* N.B. glibly assuming that Mu=1 */
3980 uint32_t symbol_count = (frameId*20 + slotId) * 14 + startSymbolId;
3981
3982 if (!disableBFWs) {
3983 /********************************************/
3984 /* Table 7.7.1.1-1 */
3985 /********************************************/
3986
3987 uint32_t bfwcomphdr_iq_width, bfwcomphdr_comp_meth;
3988 proto_item *comp_meth_ti = NULL((void*)0);
3989
3990 /* bfwCompHdr (2 subheaders - bfwIqWidth and bfwCompMeth)*/
3991 offset = dissect_bfwCompHdr(tvb, extension_tree, offset,
3992 &bfwcomphdr_iq_width, &bfwcomphdr_comp_meth, &comp_meth_ti);
3993
3994 /* Work out number of bundles, but take care not to divide by zero. */
3995 if (numBundPrb == 0) {
3996 break;
3997 }
3998
3999 /* Work out bundles! */
4000 ext11_work_out_bundles(startPrbc, numPrbc, numBundPrb, &ext11_settings);
4001 num_bundles = ext11_settings.num_bundles;
4002
4003 /* Add (complete) bundles */
4004 for (unsigned b=0; b < num_bundles; b++) {
4005 offset = dissect_bfw_bundle(tvb, extension_tree, pinfo, offset,
4006 comp_meth_ti, bfwcomphdr_comp_meth,
4007 NULL((void*)0) /* no ModCompr */,
4008 (ext11_settings.ext21_set) ?
4009 numPrbc :
4010 pref_num_bf_antennas,
4011 bfwcomphdr_iq_width,
4012 b, /* bundle number */
4013 ext11_settings.bundles[b].start,
4014 ext11_settings.bundles[b].end,
4015 ext11_settings.bundles[b].is_orphan,
4016 symbol_count,
4017 (link_planes_together && data_section) ? &data_section->details[index_to_use] : NULL((void*)0),
4018 tap_info);
4019 if (!offset) {
4020 break;
4021 }
4022 }
4023 if (num_bundles > 0) {
4024 /* Set flag from last bundle entry */
4025 orphaned_prbs = ext11_settings.bundles[num_bundles-1].is_orphan;
4026 }
4027 }
4028 else {
4029 /********************************************/
4030 /* Table 7.7.1.1-2 */
4031 /* No weights in this case */
4032 /********************************************/
4033
4034 /* Work out number of bundles, but take care not to divide by zero. */
4035 if (numBundPrb == 0) {
4036 break;
4037 }
4038
4039 ext11_work_out_bundles(startPrbc, numPrbc, numBundPrb, &ext11_settings);
4040 num_bundles = ext11_settings.num_bundles;
4041
4042 for (unsigned n=0; n < num_bundles; n++) {
4043 /* contInd */
4044 proto_tree_add_item(extension_tree, hf_oran_cont_ind,
4045 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4046 /* beamId */
4047 /* N.B., only added to tap_info if not 0 or ignored (after SEs seen) */
4048 uint32_t beam_id;
4049 proto_item *beamid_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_beam_id,
4050 tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &beam_id);
4051 if (!ext11_settings.bundles[n].is_orphan) {
4052 proto_item_append_text(beamid_ti, " (PRBs %3u-%3u) (Bundle %2u)",
4053 ext11_settings.bundles[n].start,
4054 ext11_settings.bundles[n].end,
4055 n);
4056 }
4057 else {
4058 orphaned_prbs = true1;
4059 proto_item_append_text(beamid_ti, " (PRBs %3u-%3u) (Orphaned PRBs)",
4060 ext11_settings.bundles[n].start,
4061 ext11_settings.bundles[n].end);
4062 }
4063 offset += 2;
4064
4065 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
4066 if (data_section) {
4067 /* Set beamId only for range of PRBs */
4068 for (unsigned prb = ext11_settings.bundles[n].start; prb <= ext11_settings.bundles[n].end; prb++) {
4069 if (prb < 273) {
4070 data_section->details[index_to_use].beamIds[prb] = beam_id;
4071 }
4072 }
4073 }
4074 }
4075
4076 /* Look for where BFWs were sent for this beamId */
4077 bfw_definition *definition;
4078
4079 wmem_tree_key_t key[3];
4080 key[0].length = 1;
4081 key[0].key = &pinfo->num;
4082 key[1].length = 1;
4083 key[1].key = &beam_id;
4084 key[2].length = 0;
4085 key[2].key = NULL((void*)0);
4086
4087 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
4088 /* Look up current result */
4089 definition = wmem_tree_lookup32(dl_beam_ids_defined, beam_id);
4090 if (definition != NULL((void*)0)) {
4091 /* Add to results table for this frame */
4092 wmem_tree_insert32_array(dl_beam_ids_results, key, definition);
4093 }
4094 }
4095 else {
4096 /* Look up from result table */
4097 definition = wmem_tree_lookup32_array(dl_beam_ids_results, key);
4098 }
4099
4100 /* Show link back to frame where/when beamId was defined */
4101 if (definition && definition->frame_defined != 0 && definition->frame_defined != pinfo->num) {
4102 proto_item *defined_ti = proto_tree_add_uint(extension_tree, hf_oran_bfws_frame_defined, tvb, offset, 0, definition->frame_defined);
4103 proto_item_set_generated(defined_ti);
4104 proto_item *since_ti = proto_tree_add_uint(extension_tree, hf_oran_bfws_symbols_since_defined, tvb, offset, 0,
4105 symbol_count - definition->symbol_when_defined);
4106 proto_item_set_generated(since_ti);
4107 }
4108 else {
4109 expert_add_info_format(NULL((void*)0), beamid_ti, &ei_oran_beamid_bfws_not_found,
4110 "ext11 for beamId %u and disableBFWs set, but can't find definition", beam_id);
4111 }
4112 }
4113
4114 }
4115
4116 /* Add summary to extension root */
4117 if (orphaned_prbs) {
4118 proto_item_append_text(extension_ti, " (%u full bundles + orphaned)", num_bundles-1);
4119 }
4120 else {
4121 proto_item_append_text(extension_ti, " (%u bundles)", num_bundles);
4122 }
4123 }
4124
4125 break;
4126
4127 case 12: /* SE 12: Non-Contiguous PRB Allocation with Frequency Ranges */
4128 {
4129 /* numSymbol not used in this case */
4130 if (numsymbol_ti && !numsymbol_ignored) {
4131 proto_item_append_text(numsymbol_ti, " (ignored)");
4132 numsymbol_ignored = true1;
4133 }
4134
4135 ext11_settings.ext12_set = true1;
4136
4137 /* priority */
4138 proto_tree_add_item(extension_tree, hf_oran_noncontig_priority, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4139
4140 /* symbolMask */
4141 offset = dissect_symbolmask(tvb, extension_tree, offset, NULL((void*)0), NULL((void*)0));
4142
4143 /* There are now 'R' pairs of (offStartPrb, numPrb) values. Fill extlen bytes with values. If last one is not set,
4144 should be populated with 0s. */
4145 uint32_t extlen_remaining_bytes = (extlen*4) - 4;
4146 uint8_t prb_index;
4147
4148 /* This is for ST10/ST11. First pair starts after frames signalled there */
4149 uint16_t st10_st11_offset = startPrbc + numPrbc;
4150
4151 for (prb_index = 1; extlen_remaining_bytes > 0; prb_index++)
4152 {
4153 /* Create a subtree for each pair */
4154 proto_item *pair_ti = proto_tree_add_string(extension_tree, hf_oran_frequency_range,
4155 tvb, offset, 2, "");
4156 proto_tree *pair_tree = proto_item_add_subtree(pair_ti, ett_oran_frequency_range);
4157
4158 /* offStartPrb */
4159 uint32_t off_start_prb;
4160 proto_tree_add_item_ret_uint(pair_tree, hf_oran_off_start_prb, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &off_start_prb);
4161 offset++;
4162
4163 /* numPrb */
4164 uint32_t num_prb;
4165 proto_tree_add_item_ret_uint(pair_tree, hf_oran_num_prb, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &num_prb);
4166 offset++;
4167
4168 extlen_remaining_bytes -= 2;
4169
4170 /* Last pair may be 0,0 if not used. Check for this */
4171 if ((extlen_remaining_bytes == 0) && (off_start_prb == 0) && (num_prb == 0)) {
4172 proto_item_append_text(pair_ti, " (not used)");
4173 }
4174 /* Add summary to pair root item, and configure details in ext11_settings */
4175 else {
4176 proto_item_append_text(pair_ti, "(%u) [%u : %u]",
4177 prb_index, off_start_prb, num_prb);
4178 proto_item_append_text(extension_ti, "[%u : %u]",
4179 off_start_prb, num_prb);
4180 if (ext11_settings.ext12_num_pairs < MAX_BFW_EXT12_PAIRS128) {
4181 ext11_settings.ext12_pairs[ext11_settings.ext12_num_pairs].off_start_prb = off_start_prb;
4182 ext11_settings.ext12_pairs[ext11_settings.ext12_num_pairs++].num_prb = num_prb;
4183 }
4184
4185 /* Also update PRBs to be covered for ST10 type 5 */
4186 /* Original range from section is added to.. */
4187 /* TODO: I don't think this is quite right.. */
4188 for (unsigned prb=st10_st11_offset+off_start_prb; prb < st10_st11_offset+off_start_prb+num_prb; prb++) {
4189 if (prb < MAX_PRBS273) {
4190 prbs_for_st10_type5[prb] = true1;
4191 }
4192 }
4193
4194 /* Any next pair will begin after this one */
4195 st10_st11_offset += (off_start_prb + num_prb);
4196 }
4197 }
4198 break;
4199 }
4200
4201 case 13: /* SE 13: PRB Allocation with Frequency Hopping */
4202 {
4203 /* Will update settings for ext11 */
4204 ext11_settings.ext13_set = true1;
4205
4206 uint32_t extlen_remaining_bytes = (extlen*4) - 2;
4207 uint8_t allocation_index;
4208
4209 unsigned prev_next_symbol_id = 0, prev_next_start_prbc = 0;
4210
4211 for (allocation_index = 1; extlen_remaining_bytes > 0; allocation_index++)
4212 {
4213 /* Subtree for allocation */
4214 proto_item *allocation_ti = proto_tree_add_string(extension_tree, hf_oran_prb_allocation,
4215 tvb, offset, 2, "");
4216 proto_tree *allocation_tree = proto_item_add_subtree(allocation_ti, ett_oran_prb_allocation);
4217
4218 /* Reserved (2 bits) */
4219 add_reserved_field(allocation_tree, hf_oran_reserved_2bits, tvb, offset, 1);
4220
4221 /* nextSymbolId (4 bits) */
4222 uint32_t next_symbol_id;
4223 proto_tree_add_item_ret_uint(allocation_tree, hf_oran_nextSymbolId, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &next_symbol_id);
4224
4225 /* nextStartPrbc (10 bits) */
4226 uint32_t next_start_prbc;
4227 proto_tree_add_item_ret_uint(allocation_tree, hf_oran_nextStartPrbc, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &next_start_prbc);
4228 offset += 2;
4229
4230 /* Add summary to allocation root item */
4231 proto_item_append_text(allocation_ti, "(%u) nextSymbolId=%3u, nextStartPrbc=%u",
4232 allocation_index, next_symbol_id, next_start_prbc);
4233
4234 /* Checking for duplicates (expected if e.g. had only 2 entries but extlen bytes still to fill */
4235 if ((allocation_index > 1) && (next_symbol_id == prev_next_symbol_id) && (next_start_prbc == prev_next_start_prbc)) {
4236 proto_item_append_text(allocation_ti, " (repeated - to fill up extlen)");
4237 }
4238 else {
4239 /* Add entry for configuring ext11. don't store out of range */
4240 if (ext11_settings.ext13_num_start_prbs < MAX_BFW_EXT13_ALLOCATIONS128) {
4241 ext11_settings.ext13_start_prbs[ext11_settings.ext13_num_start_prbs++] = next_start_prbc;
4242 }
4243 }
4244 prev_next_symbol_id = next_symbol_id;
4245 prev_next_start_prbc = next_start_prbc;
4246
4247 extlen_remaining_bytes -= 2;
4248 }
4249 break;
4250 }
4251
4252 case 14: /* SE 14: Nulling-layer Info. for ueId-based beamforming */
4253 /* Hidden filter for bf (DMRS BF) */
4254 bf_ti = proto_tree_add_item(tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
4255 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
4256
4257 if (!seen_se10) {
4258 proto_tree_add_item(extension_tree, hf_oran_nullLayerInd, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4259 offset += 1;
4260 add_reserved_field(extension_tree, hf_oran_reserved_8bits, tvb, offset, 1);
4261 offset += 1;
4262 }
4263 else {
4264 /* Loop over numPortc++1 (from SE 10) nullLayerInd fields */
4265 for (unsigned port=0; port < numPortc+1; port++) {
4266 proto_tree_add_item(extension_tree, hf_oran_nullLayerInd, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4267 offset += 1;
4268 }
4269 }
4270 break;
4271
4272 case 15: /* SE 15: Mixed-numerology Info. for ueId-based beamforming */
4273 {
4274 /* frameStructure */
4275 offset = dissect_frame_structure(extension_tree, tvb, offset,
4276 subframeId, slotId);
4277 /* freqOffset */
4278 proto_tree_add_item(extension_tree, hf_oran_freqOffset, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
4279 offset += 3;
4280 /* cpLength */
4281 proto_item *cplength_ti = proto_tree_add_item(extension_tree, hf_oran_cpLength, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4282 if (sectionType != 0 && sectionType != 3) {
4283 proto_item_append_text(cplength_ti, " (ignored - used only with ST0 and ST3)");
4284 }
4285 offset += 2;
4286 break;
4287 }
4288
4289 case 16: /* SE 16: Antenna mapping in UE channel information based UL beamforming */
4290 {
4291 /* Just filling available bytes with antMask entries.
4292 N.B., if SE 10 also used, could associate each antMask with (beamId or UEId) RX eAxC */
4293 uint32_t extlen_remaining_bytes = (extlen*4) - 2;
4294 unsigned num_ant_masks = extlen_remaining_bytes / 8;
4295 for (unsigned n=0; n < num_ant_masks; n++) {
4296 proto_item *ti = proto_tree_add_item(extension_tree, hf_oran_antMask, tvb, offset, 8, ENC_BIG_ENDIAN0x00000000);
4297 proto_item_append_text(ti, " (RX eAxC #%u)", n+1);
4298 offset += 8;
4299 }
4300 break;
4301 }
4302
4303 case 17: /* SE 17: Indication of user port group. Applies to ST5 + SE10 with group type 1 (beam matrix indication) */
4304 {
4305 uint32_t extlen_remaining_bytes = (extlen*4) - 2;
4306 uint32_t end_bit = (offset+extlen_remaining_bytes) * 8;
4307 uint32_t ueid_index = 1;
4308
4309 /* "the preceding Section Type and extension messages implicitly provide the number of scheduled users" */
4310 for (uint32_t bit_offset=offset*8; (bit_offset < end_bit) && (ueid_index <= number_of_ueids); bit_offset+=4, ueid_index++) {
4311 /* numUeId (Number of UE Ids per user) */
4312 proto_item *ti = proto_tree_add_bits_item(extension_tree, hf_oran_num_ueid, tvb, bit_offset, 4, ENC_BIG_ENDIAN0x00000000);
4313 /* TODO: show ueids[ueid_index] here too? */
4314 proto_item_append_text(ti, " (user #%u)", ueid_index);
4315 }
4316 break;
4317 }
4318
4319 case 18: /* SE 18: Uplink transmission management */
4320 /* transmissionWindowOffset */
4321 proto_tree_add_item(extension_tree, hf_oran_transmissionWindowOffset, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4322 offset += 2;
4323 /* reserved (2 bits) */
4324 add_reserved_field(extension_tree, hf_oran_reserved_2bits, tvb, offset, 1);
4325 /* transmissionWindowSize (14 bits) */
4326 proto_tree_add_item(extension_tree, hf_oran_transmissionWindowSize, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4327 offset += 2;
4328
4329 /* reserved (6 bits) */
4330 add_reserved_field(extension_tree, hf_oran_reserved_6bits, tvb, offset, 1);
4331 /* toT (2 bits) */
4332 proto_tree_add_item(extension_tree, hf_oran_toT, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4333 offset += 1;
4334 break;
4335
4336 case 19: /* SE 19: Compact beamforming information for multiple port */
4337 {
4338 /* beamId in section header should be ignored. Guard against appending multiple times.. */
4339 if (section_beamId_ti && !section_beamId_ignored) {
4340 proto_item_append_text(section_beamId_ti, " (ignored)");
4341 section_beamId_ignored = true1;
4342 }
4343
4344 /* numSymbol not used in this case */
4345 if (numsymbol_ti && !numsymbol_ignored) {
4346 proto_item_append_text(numsymbol_ti, " (ignored)");
4347 numsymbol_ignored = true1;
4348 }
4349
4350 /* disableBFWs */
4351 bool_Bool disableBFWs;
4352 proto_tree_add_item_ret_boolean(extension_tree, hf_oran_disable_bfws,
4353 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &disableBFWs);
4354 if (disableBFWs) {
4355 proto_item_append_text(extension_ti, " (disableBFWs)");
4356 }
4357 /* repetition (1 bit) */
4358 uint64_t repetition;
4359 proto_tree_add_bits_ret_val(extension_tree, hf_oran_se19_repetition, tvb, (offset*8)+1, 1, &repetition, ENC_BIG_ENDIAN0x00000000);
4360 /* numPortc (6 bits) */
4361 proto_tree_add_item_ret_uint(extension_tree, hf_oran_numPortc,
4362 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &numPortc);
4363 offset++;
4364
4365 /* priority (2 bits) */
4366 proto_tree_add_item(extension_tree, hf_oran_noncontig_priority, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4367 /* symbolMask (14 bits) */
4368 offset = dissect_symbolmask(tvb, extension_tree, offset, NULL((void*)0), NULL((void*)0));
4369
4370 uint32_t bfwcomphdr_iq_width, bfwcomphdr_comp_meth;
4371 proto_item *comp_meth_ti = NULL((void*)0);
4372
4373 if (!repetition) {
4374
4375 if (!disableBFWs) {
4376 /* bfwCompHdr */
4377 offset = dissect_bfwCompHdr(tvb, extension_tree, offset,
4378 &bfwcomphdr_iq_width, &bfwcomphdr_comp_meth, &comp_meth_ti);
4379 }
4380
4381 /* Add entries for each port */
4382 for (unsigned port=0; port < numPortc; port++) {
4383
4384 /* Create subtree for port entry*/
4385 int port_start_offset = offset;
4386 proto_item *port_ti = proto_tree_add_string_format(extension_tree, hf_oran_ext19_port,
4387 tvb, offset, 0,
4388 "", "Port %u: ", port);
4389 proto_tree *port_tree = proto_item_add_subtree(port_ti, ett_oran_ext19_port);
4390
4391 /* Reserved (4 bits) */
4392 add_reserved_field(port_tree, hf_oran_reserved_4bits, tvb, offset, 1);
4393 /* portReMask (12 bits) */
4394 proto_tree_add_item(port_tree, hf_oran_portReMask, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4395 offset += 2;
4396
4397 /* Reserved (2 bits) */
4398 add_reserved_field(port_tree, hf_oran_reserved_2bits, tvb, offset, 1);
4399 /* portSymbolMask (14 bits) */
4400 proto_tree_add_item(port_tree, hf_oran_portSymbolMask, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4401 offset += 2;
4402
4403 /* Reserved (1 bit) */
4404 add_reserved_field(port_tree, hf_oran_reserved_1bit, tvb, offset, 1);
4405 /* beamID (15 bits) */
4406 uint16_t beamId;
4407 proto_tree_add_item_ret_uint16(port_tree, hf_oran_beamId, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &beamId);
4408 proto_item_append_text(port_ti, " (beamId=%u)", beamId);
4409 offset += 2;
4410
4411 /* No weights present */
4412 if (!disableBFWs) {
4413 /*******************************************************************/
4414 /* Table 7.7.19.1-1 (there is no part -2 for disableBFWs case...), */
4415 /* but for SE 11, bfwCompParam was only present for !disableBFWs */
4416 /*******************************************************************/
4417
4418 /* bfwCompParam */
4419 bool_Bool compression_method_supported = false0;
4420 uint32_t exponent = 0;
4421 unsigned num_trx_entries = 0;
4422 uint16_t *trx;
4423 offset = dissect_bfwCompParam(tvb, port_tree, pinfo, offset, comp_meth_ti,
4424 &bfwcomphdr_comp_meth, &exponent, &compression_method_supported,
4425 &num_trx_entries, &trx);
4426
4427 int bit_offset = offset*8;
4428 int bfw_offset;
4429
4430 /* Add weights for each TRX */
4431 unsigned trx_to_add = (num_trx_entries==0) ? pref_num_bf_antennas : num_trx_entries;
4432 for (unsigned b=0; b < trx_to_add; b++) {
4433
4434 uint16_t trx_index = (num_trx_entries) ? trx[b] : b+1;
4435
4436 /* Create BFW subtree */
4437 bfw_offset = bit_offset / 8;
4438 uint8_t bfw_extent = ((bit_offset + (bfwcomphdr_iq_width*2)) / 8) - bfw_offset;
4439 proto_item *bfw_ti = proto_tree_add_string_format(port_tree, hf_oran_bfw,
4440 tvb, bfw_offset, bfw_extent,
4441 "", "TRX %u: (", trx_index);
4442 proto_tree *bfw_tree = proto_item_add_subtree(bfw_ti, ett_oran_bfw);
4443
4444 /* I */
4445 uint32_t bits = tvb_get_bits32(tvb, bit_offset, bfwcomphdr_iq_width, ENC_BIG_ENDIAN0x00000000);
4446 float value = decompress_value(bits, bfwcomphdr_comp_meth, bfwcomphdr_iq_width, exponent, NULL((void*)0) /* no ModCompr */, 0 /* RE */);
4447 /* Add to tree. */
4448 proto_tree_add_float_format_value(bfw_tree, hf_oran_bfw_i, tvb, bit_offset/8,
4449 (bfwcomphdr_iq_width+7)/8, value, "#%u=%f", b, value);
4450 bit_offset += bfwcomphdr_iq_width;
4451 proto_item_append_text(bfw_ti, "I%u=%f ", b, value);
4452
4453 /* Q */
4454 bits = tvb_get_bits32(tvb, bit_offset, bfwcomphdr_iq_width, ENC_BIG_ENDIAN0x00000000);
4455 value = decompress_value(bits, bfwcomphdr_comp_meth, bfwcomphdr_iq_width, exponent, NULL((void*)0) /* no ModCompr */, 0 /* RE */);
4456 /* Add to tree. */
4457 proto_tree_add_float_format_value(bfw_tree, hf_oran_bfw_q, tvb, bit_offset/8,
4458 (bfwcomphdr_iq_width+7)/8, value, "#%u=%f", b, value);
4459 bit_offset += bfwcomphdr_iq_width;
4460 proto_item_append_text(bfw_ti, "Q%u=%f)", b, value);
4461 }
4462
4463 offset = (bit_offset+7)/8;
4464 }
4465 else {
4466 /* No weights... */
4467 }
4468
4469 /* Set length of this port entry */
4470 proto_item_set_len(port_ti, offset-port_start_offset);
4471 }
4472 }
4473 break;
4474 }
4475
4476 case 20: /* SE 20: Puncturing extension */
4477 {
4478 /* numPuncPatterns */
4479 uint32_t numPuncPatterns;
4480 proto_tree_add_item_ret_uint(extension_tree, hf_oran_numPuncPatterns, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &numPuncPatterns);
4481 offset += 1;
4482
4483 /* Add each puncturing pattern */
4484 for (uint32_t n=0; n < numPuncPatterns; n++) {
4485 unsigned pattern_start_offset = offset;
4486
4487 /* Subtree for this puncturing pattern */
4488 proto_item *pattern_ti = proto_tree_add_string_format(extension_tree, hf_oran_puncPattern,
4489 tvb, offset, 0,
4490 "", "Puncturing Pattern: %u/%u", n+1, numPuncPatterns);
4491 proto_tree *pattern_tree = proto_item_add_subtree(pattern_ti, ett_oran_punc_pattern);
4492
4493 /* SymbolMask (14 bits) */
4494 proto_tree_add_item(pattern_tree, hf_oran_symbolMask_ext20, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4495 offset += 1;
4496
4497 uint32_t startPuncPrb, numPuncPrb;
4498
4499 /* startPuncPrb (10 bits) */
4500 proto_tree_add_item_ret_uint(pattern_tree, hf_oran_startPuncPrb, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &startPuncPrb);
4501 offset += 2;
4502 /* numPuncPrb (8 bits) */
4503 proto_tree_add_item_ret_uint(pattern_tree, hf_oran_numPuncPrb, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &numPuncPrb);
4504 offset += 1;
4505
4506 proto_item_append_text(pattern_ti, " [%u->%u]", startPuncPrb, startPuncPrb+numPuncPrb-1);
4507
4508 /* Make a hole in range of PRBs to report */
4509 for (unsigned p=startPuncPrb; p < startPuncPrb+numPuncPrb; p++) {
4510 if (p < MAX_PRBS273) {
4511 prbs_for_st10_type5[p] = false0;
4512 }
4513 }
4514
4515 /* puncReMask (12 bits) */
4516 proto_tree_add_item(pattern_tree, hf_oran_puncReMask, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4517 offset += 1;
4518 /* rb (1 bit) */
4519 proto_item *rb_ti = proto_tree_add_item(pattern_tree, hf_oran_rb, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4520 /* reserved (1 bit) */
4521 add_reserved_field(pattern_tree, hf_oran_reserved_bit5, tvb, offset, 1);
4522 /* multiSDScope (1 bit) */
4523 proto_tree_add_item(pattern_tree, hf_oran_multiSDScope, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4524 /* rbgIncl (1 bit) */
4525 bool_Bool rbgIncl;
4526 proto_tree_add_item_ret_boolean(pattern_tree, hf_oran_RbgIncl, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &rbgIncl);
4527 offset += 1;
4528
4529 if (rbgIncl) {
4530 /* reserved (1 bit) */
4531 add_reserved_field(pattern_tree, hf_oran_reserved_1bit, tvb, offset, 1);
4532 /* rbgSize(3 bits) */
4533 proto_tree_add_item(pattern_tree, hf_oran_rbgSize, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4534 /* rbgMask (28 bits) */
4535 proto_tree_add_item(pattern_tree, hf_oran_rbgMask, tvb, offset, 4, ENC_BIG_ENDIAN0x00000000);
4536 offset += 4;
4537
4538 proto_item_append_text(rb_ti, " (ignored)");
4539 }
4540
4541 proto_item_set_len(pattern_ti, offset-pattern_start_offset);
4542 }
4543
4544 break;
4545 }
4546 case 21: /* SE 21: Variable PRB group size for channel information */
4547 {
4548 /* ciPrbGroupSize */
4549 uint32_t ci_prb_group_size;
4550 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);
4551 offset += 1;
4552
4553 switch (ci_prb_group_size) {
4554 case 0:
4555 case 1:
4556 case 255:
4557 /* Reserved value */
4558 expert_add_info_format(pinfo, prb_group_size_ti, &ei_oran_ci_prb_group_size_reserved,
4559 "SE 11 ciPrbGroupSize is reserved value %u - must be 2-254",
4560 ci_prb_group_size);
4561 break;
4562 default:
4563 /* This value affects how SE 11 is interpreted */
4564 ext11_settings.ext21_set = true1;
4565 ext11_settings.ext21_ci_prb_group_size = ci_prb_group_size;
4566
4567 if (numPrbc == 0) {
4568 expert_add_info(pinfo, numprbc_ti, &ei_oran_numprbc_ext21_zero);
4569 }
4570 break;
4571 }
4572
4573 /* reserved (6 bits) */
4574 add_reserved_field(extension_tree, hf_oran_reserved_6bits, tvb, offset, 1);
4575
4576 /* prgSize (2 bits). Interpretation depends upon section type (5 or 6), but also mplane parameters? */
4577 if (sectionType == SEC_C_UE_SCHED) { /* Section Type 5 */
4578 proto_tree_add_item(extension_tree, hf_oran_prg_size_st5, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4579 }
4580 else if (sectionType == SEC_C_CH_INFO) { /* Section Type 6 */
4581 proto_tree_add_item(extension_tree, hf_oran_prg_size_st6, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4582 }
4583 offset += 1;
4584 break;
4585 }
4586
4587 case 22: /* SE 22: ACK/NACK request */
4588 {
4589 uint32_t ack_nack_req_id;
4590 proto_tree_add_item_ret_uint(extension_tree, hf_oran_ack_nack_req_id, tvb, offset, 2,
4591 ENC_BIG_ENDIAN0x00000000, &ack_nack_req_id);
4592 offset += 2;
4593
4594 if (state) {
4595 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
4596 /* Add this request into conversation state on first pass */
4597 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)))
;
4598 request_details->request_frame_number = pinfo->num;
4599 request_details->request_frame_time = pinfo->abs_ts;
4600 request_details->requestType = SE22;
4601 /* Insert into flow's tree */
4602 wmem_tree_insert32(state->ack_nack_requests, ack_nack_req_id, request_details);
4603 }
4604 else {
4605 /* Try to link forward to ST8 response */
4606 ack_nack_request_t *response = wmem_tree_lookup32(state->ack_nack_requests,
4607 ack_nack_req_id);
4608 if (response) {
4609 show_link_to_acknack_response(extension_tree, tvb, pinfo, response);
4610 }
4611 }
4612 }
4613 break;
4614 }
4615
4616 case 23: /* SE 23: Arbitrary symbol pattern modulation compression parameters */
4617 {
4618 /* Green common header */
4619
4620 /* numSymPrbPattern (4 bits) */
4621 uint32_t num_sym_prb_pattern;
4622 proto_tree_add_item_ret_uint(extension_tree, hf_oran_num_sym_prb_pattern, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &num_sym_prb_pattern);
4623 /* reserved (3 bits) */
4624 add_reserved_field(extension_tree, hf_oran_reserved_bits456, tvb, offset, 1);
4625 /* prbMode (1 bit) */
4626 bool_Bool prb_mode;
4627 proto_tree_add_item_ret_boolean(extension_tree, hf_oran_prb_mode, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &prb_mode);
4628 offset += 1;
4629
4630 /* reserved (8 bits) */
4631 add_reserved_field(extension_tree, hf_oran_reserved_8bits, tvb, offset, 1);
4632 offset += 1;
4633
4634 /* Dissect each SymPrbPattern */
4635 for (uint32_t n=0; n < num_sym_prb_pattern; n++) {
4636
4637 /* Subtree */
4638 proto_item *pattern_ti = proto_tree_add_string_format(extension_tree, hf_oran_sym_prb_pattern,
4639 tvb, offset, 1, "",
4640 prb_mode ? "PRB-BLOCK" : "PRB-MASK");
4641 proto_tree *pattern_tree = proto_item_add_subtree(pattern_ti, ett_oran_sym_prb_pattern);
4642
4643
4644 /* Orange part */
4645
4646 /* Reserved (2 bits) */
4647 add_reserved_field(pattern_tree, hf_oran_reserved_2bits, tvb, offset, 1);
4648 /* symMask (14 bits) */
4649 proto_tree_add_item(pattern_tree, hf_oran_sym_mask, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4650 offset += 2;
4651 /* numMcScaleOffset (4 bits) */
4652 uint32_t numMcScaleOffset;
4653 proto_tree_add_item_ret_uint(pattern_tree, hf_oran_num_mc_scale_offset, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &numMcScaleOffset);
4654
4655 if (!prb_mode) { /* PRB-MASK */
4656 /* prbPattern (4 bits) */
4657 proto_tree_add_item(pattern_tree, hf_oran_prb_pattern, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4658 offset += 1;
4659 /* reserved (8 bits) */
4660 add_reserved_field(pattern_tree, hf_oran_reserved_8bits, tvb, offset, 1);
4661 offset += 1;
4662 }
4663 else { /* PRB-BLOCK */
4664 /* prbBlkOffset (8 bits) */
4665 proto_tree_add_item(pattern_tree, hf_oran_prb_block_offset, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4666 offset += 1;
4667 /* prbBlkSize (4 bits) */
4668 proto_tree_add_item(pattern_tree, hf_oran_prb_block_size, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4669 offset += 1;
4670 }
4671
4672 /* Yellowish part */
4673 if (prb_mode) { /* PRB-BLOCK */
4674 /* prbBlkSize (4 bits) */
4675 proto_tree_add_item(pattern_tree, hf_oran_prb_block_size, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4676 }
4677 else {
4678 /* reserved (4 bits) */
4679 add_reserved_field(pattern_tree, hf_oran_reserved_4bits, tvb, offset, 1);
4680 }
4681
4682 for (unsigned c=0; c < numMcScaleOffset; c++) {
4683
4684 if (c > 0) {
4685 /* reserved (4 bits) */
4686 add_reserved_field(pattern_tree, hf_oran_reserved_4bits, tvb, offset, 1);
4687 }
4688
4689 static int * const remask_flags_even[] = {
4690 &hf_oran_mc_scale_re_mask_re1_even,
4691 &hf_oran_mc_scale_re_mask_re2_even,
4692 &hf_oran_mc_scale_re_mask_re3_even,
4693 &hf_oran_mc_scale_re_mask_re4_even,
4694 &hf_oran_mc_scale_re_mask_re5_even,
4695 &hf_oran_mc_scale_re_mask_re6_even,
4696 &hf_oran_mc_scale_re_mask_re7_even,
4697 &hf_oran_mc_scale_re_mask_re8_even,
4698 &hf_oran_mc_scale_re_mask_re9_even,
4699 &hf_oran_mc_scale_re_mask_re10_even,
4700 &hf_oran_mc_scale_re_mask_re11_even,
4701 &hf_oran_mc_scale_re_mask_re12_even,
4702 NULL((void*)0)
4703 };
4704
4705 /* mcScaleReMask (12 bits). Defines which REs the following csf and mcScaleOffset apply to */
4706 uint64_t mcScaleReMask, mcScaleOffset;
4707 proto_tree_add_bitmask_ret_uint64(pattern_tree, tvb, offset,
4708 hf_oran_mc_scale_re_mask_even,
4709 ett_oran_mc_scale_remask,
4710 remask_flags_even, ENC_BIG_ENDIAN0x00000000, &mcScaleReMask);
4711
4712 offset += 2;
4713 /* csf (1 bit) */
4714 bool_Bool csf;
4715 dissect_csf(pattern_tree, tvb, offset*8, ci_iq_width, &csf);
4716 /* mcScaleOffset (15 bits) */
4717 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);
4718 uint16_t exponent = (mcScaleOffset >> 11) & 0x000f; /* m.s. 4 bits */
4719 uint16_t mantissa = mcScaleOffset & 0x07ff; /* l.s. 11 bits */
4720 float mcScaleOffset_value = ((float)mantissa/(1<<11)) * ((float)1.0 / (1 << exponent));
4721 proto_item_append_text(ti, " (%f)", mcScaleOffset_value);
4722
4723 offset += 2;
4724
4725 /* Record this config. */
4726 /* TODO: at some point, will also want to store/use PRB + symbol filters */
4727 section_mod_compr_config_t* sect_config = get_mod_compr_section_to_write(state, sectionId);
4728
4729 if (sect_config && sect_config->num_configs < MAX_MOD_COMPR_CONFIGS12) {
4730 unsigned i = sect_config->num_configs;
4731 sect_config->configs[i].mod_compr_re_mask = (uint16_t)mcScaleReMask;
4732 sect_config->configs[i].mod_compr_csf = csf;
4733 sect_config->configs[i].mod_compr_scaler = mcScaleOffset_value;
4734 sect_config->num_configs++;
4735 }
4736 }
4737
4738 proto_item_set_end(pattern_ti, tvb, offset);
4739 }
4740 break;
4741 }
4742
4743 case 24: /* SE 24: PUSCH DMRS configuration */
4744 {
4745 /* Hidden filter for bf (DMRS BF) */
4746 bf_ti = proto_tree_add_item(tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
4747 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
4748
4749 /* alpnPerSym (1 bit) */
4750 proto_tree_add_item(extension_tree, hf_oran_alpn_per_sym, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4751 /* antDmrsSnr (1 bit) */
4752 proto_tree_add_item(extension_tree, hf_oran_ant_dmrs_snr, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4753 /* reserved (1 bit) */
4754 add_reserved_field(extension_tree, hf_oran_reserved_bit2, tvb, offset, 1);
4755 /* userGroupSize (5 bits) */
4756 uint32_t user_group_size;
4757 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);
4758 if (user_group_size == 0) {
4759 proto_item_append_text(ugs_ti, " (not used)");
4760 }
4761 else if (user_group_size > 12) {
4762 proto_item_append_text(ugs_ti, " (reserved)");
4763 }
4764 offset += 1;
4765 /* userGroupId (8 bits)*/
4766 uint32_t user_group_id;
4767 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);
4768 if (user_group_id == 0) {
4769 /* TODO: Value 0 can happen in several cases, described in 7.7.24.7.. */
4770 }
4771 if (user_group_id == 255) {
4772 /* Value 255 is reserved */
4773 expert_add_info(pinfo, ugi_ti, &ei_oran_user_group_id_reserved_value);
4774 }
4775 offset += 1;
4776
4777 bool_Bool seen_value_to_inherit = false0;
4778 bool_Bool inherited_config_has_transform_precoding = false0;
4779 int dmrs_configs_seen = 0;
4780
4781 /* Dissect each entry until reach number of configured ueIds (or run out of extlen bytes..) */
4782 uint32_t ueid_index = 0;
4783 while ((offset < (extension_start_offset + extlen*4)) && (ueid_index < number_of_ueids)) {
4784 dmrs_configs_seen++;
4785
4786 /* Subtree */
4787 proto_item *entry_ti = proto_tree_add_string_format(extension_tree, hf_oran_dmrs_entry,
4788 tvb, offset, 0, "",
4789 "Entry");
4790 proto_tree *entry_tree = proto_item_add_subtree(entry_ti, ett_oran_dmrs_entry);
4791
4792 /* entryType (3 bits) */
4793 uint32_t entry_type;
4794 proto_item *entry_type_ti;
4795 entry_type_ti = proto_tree_add_item_ret_uint(entry_tree, hf_oran_entry_type, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &entry_type);
4796 if (entry_type > 3) {
4797 proto_item_append_text(entry_type_ti, " (reserved)");
4798 }
4799
4800 /* dmrsPortNumber (5 bits). Values 0-11 allowed */
4801 unsigned int dmrs_port_number;
4802 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);
4803 if (dmrs_port_number > 11) {
4804 proto_item_append_text(dpn_ti, " (12-31 are reserved)");
4805 }
4806 offset += 1;
4807
4808 /* What follows depends upon entryType */
4809 switch (entry_type) {
4810 case 0: /* dmrsPortNumber config same as previous, ueId ueIdReset=0 */
4811 case 1: /* dmrsPortNumber config same as previous, ueId ueIdReset=1 */
4812 /* No further fields for these */
4813 /* Error here if no previous values to inherit!! */
4814 if (!seen_value_to_inherit) {
4815 expert_add_info_format(pinfo, entry_type_ti, &ei_oran_se24_nothing_to_inherit,
4816 "SE24: have seen entry type %u, but no previous config (type 2 or 3) to inherit config from", entry_type);
4817
4818 }
4819 /* TODO: would be useful to repeat whole inherited config here? */
4820 break;
4821
4822 case 2: /* transform precoding disabled */
4823 case 3: /* transform precoding enabled */
4824 {
4825 /* Type 2/3 are very similar.. */
4826
4827 /* ueIdReset (1 bit) */
4828 proto_tree_add_item(entry_tree, hf_oran_ueid_reset, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4829 /* posMeas (1 bit) */
4830 proto_tree_add_item(entry_tree, hf_oran_pos_meas, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4831
4832 /* dmrsSymbolMask (14 bits) */
4833 static int * const dmrs_symbol_mask_flags[] = {
4834 &hf_oran_dmrs_symbol_mask_s13,
4835 &hf_oran_dmrs_symbol_mask_s12,
4836 &hf_oran_dmrs_symbol_mask_s11,
4837 &hf_oran_dmrs_symbol_mask_s10,
4838 &hf_oran_dmrs_symbol_mask_s9,
4839 &hf_oran_dmrs_symbol_mask_s8,
4840 &hf_oran_dmrs_symbol_mask_s7,
4841 &hf_oran_dmrs_symbol_mask_s6,
4842 &hf_oran_dmrs_symbol_mask_s5,
4843 &hf_oran_dmrs_symbol_mask_s4,
4844 &hf_oran_dmrs_symbol_mask_s3,
4845 &hf_oran_dmrs_symbol_mask_s2,
4846 &hf_oran_dmrs_symbol_mask_s1,
4847 &hf_oran_dmrs_symbol_mask_s0,
4848 NULL((void*)0)
4849 };
4850 proto_tree_add_bitmask(entry_tree, tvb, offset,
4851 hf_oran_dmrs_symbol_mask, ett_oran_dmrs_symbol_mask, dmrs_symbol_mask_flags, ENC_BIG_ENDIAN0x00000000);
4852 offset += 2;
4853
4854 /* scrambling */
4855 proto_tree_add_item(entry_tree, hf_oran_scrambling, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4856 offset += 2;
4857
4858 /* nscid (1 bit) */
4859 proto_tree_add_item(entry_tree, hf_oran_nscid, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4860
4861 /* These 5 bits differ depending upon entry type */
4862 if (entry_type == 2) { /* type 2 */
4863 /* dType (1 bit) */
4864 proto_tree_add_item(entry_tree, hf_oran_dtype, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4865 /* cdmWithoutData (2 bits) */
4866 proto_tree_add_item(entry_tree, hf_oran_cmd_without_data, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4867 /* lambda (2 bits) */
4868 proto_tree_add_item(entry_tree, hf_oran_lambda, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4869 }
4870 else { /* type 3 */
4871 /* reserved (1 bit) */
4872 add_reserved_field(entry_tree, hf_oran_reserved_bit1, tvb, offset, 1);
4873 /* lowPaprType (2 bits) */
4874 proto_tree_add_item(entry_tree, hf_oran_low_papr_type, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4875 /* hoppingMode (2 bits) */
4876 proto_tree_add_item(entry_tree, hf_oran_hopping_mode, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4877 }
4878
4879 /* firstPrb (9 bits) */
4880 proto_tree_add_item(entry_tree, hf_oran_first_prb, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4881 offset += 1;
4882 /* lastPrb (9 bits) */
4883 proto_tree_add_item(entry_tree, hf_oran_last_prb, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4884 offset += 2;
4885 /* Reserved (16 bits) */
4886 add_reserved_field(entry_tree, hf_oran_reserved_16bits, tvb, offset, 2);
4887 offset += 2;
4888
4889 /* Could now see entry types 0 or 1 - they have these values to inherit */
4890 seen_value_to_inherit = true1;
4891 inherited_config_has_transform_precoding = (entry_type == 3);
4892 break;
4893 }
4894
4895 default:
4896 /* reserved - expert info */
4897 break;
4898 }
4899
4900 proto_item_append_text(entry_ti, " [UEId=%u] (dmrsPortNumber=%2u) (type %u - %s) ",
4901 ueids[ueid_index++], dmrs_port_number, entry_type, val_to_str_const(entry_type, entry_type_vals, "Unknown"));
4902 proto_item_set_end(entry_ti, tvb, offset);
4903
4904 if (entry_type <= 1) {
4905 proto_item_append_text(entry_ti, " [transform-precoding %s]",
4906 inherited_config_has_transform_precoding ? "enabled" : "disabled");
4907 }
4908 }
4909
4910 proto_item_append_text(extension_ti, " (%d DMRS configs seen)", dmrs_configs_seen);
4911 break;
4912 }
4913
4914 case 25: /* SE 25: Symbol reordering for DMRS-BF */
4915 /* Just dissect each available block of 7 bytes as the 14 symbols for a layer,
4916 where each layer could be one or apply to all layers. */
4917 {
4918 /* TODO: should only appear in one section of a message - check? */
4919 unsigned layer = 0;
4920 proto_item *layer_ti;
4921 while (offset+7 <= (extension_start_offset + extlen*4)) {
4922 /* Layer subtree */
4923 layer_ti = proto_tree_add_string_format(extension_tree, hf_oran_symbol_reordering_layer,
4924 tvb, offset, 7, "",
4925 "Layer");
4926 proto_tree *layer_tree = proto_item_add_subtree(layer_ti, ett_oran_symbol_reordering_layer);
4927
4928 /* All 14 symbols for a layer (or all layers) */
4929 for (unsigned s=0; s < 14; s++) {
4930 proto_item *sym_ti;
4931 /* txWinForOnAirSymbol */
4932 unsigned int tx_win_for_on_air_symbol;
4933 sym_ti = proto_tree_add_item_ret_uint(layer_tree,
4934 (s % 2) ? hf_oran_tx_win_for_on_air_symbol_r : hf_oran_tx_win_for_on_air_symbol_l,
4935 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &tx_win_for_on_air_symbol);
4936 if (tx_win_for_on_air_symbol == 0x0F) {
4937 /* Ordering not affected */
4938 proto_item_append_text(sym_ti, " (sym %u - no info)", s);
4939 }
4940 else {
4941 proto_item_append_text(sym_ti, " (sym %u)", s);
4942 }
4943 if (s % 2) {
4944 offset += 1;
4945 }
4946 }
4947
4948 proto_item_append_text(layer_ti, " (layer %u)", ++layer);
4949 proto_item_append_text(extension_ti, " (layer %u)", layer);
4950 }
4951 /* Set layer subtree label */
4952 if (layer == 1) {
4953 proto_item_append_text(layer_ti, " (all)");
4954 proto_item_append_text(extension_ti, " (all)");
4955 }
4956 if (layer == 0) {
4957 /* TODO: are no layers valid? What does it mean? */
4958 proto_item_append_text(extension_ti, " (none)");
4959 }
4960 break;
4961 }
4962
4963 case 26: /* SE 26: Frequency offset feedback */
4964 /* Reserved (8 bits) */
4965 add_reserved_field(extension_tree, hf_oran_reserved_8bits, tvb, offset, 1);
4966 offset += 1;
4967 /* Reserved (1 bit) */
4968 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
4969 /* numFoFb (7 bits) */
4970 unsigned num_fo_fb;
4971 proto_tree_add_item_ret_uint(extension_tree, hf_oran_num_fo_fb, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &num_fo_fb);
4972 offset += 1;
4973
4974 /* Add each freqOffsetFb value */
4975 for (unsigned n=0; n < num_fo_fb; n++) {
4976 unsigned freq_offset_fb;
4977 /* freqOffsetFb (16 bits) */
4978 proto_item *offset_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_freq_offset_fb,
4979 tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &freq_offset_fb);
4980 /* Show if maps onto a -ve number */
4981 if ((freq_offset_fb >= 0x8ad0) && (freq_offset_fb <= 0xffff)) {
4982 proto_item_append_text(offset_ti, "(value %d)", -1 - (0xffff-freq_offset_fb));
4983 }
4984 proto_item_append_text(offset_ti, " [#%u]", n+1);
4985 offset += 2;
4986 }
4987 break;
4988
4989 case 27: /* SE 27: O-DU controlled dimensionality reduction */
4990 {
4991 /* Hidden filter for bf (DMRS BF) */
4992 bf_ti = proto_tree_add_item(tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
4993 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
4994
4995 /* beamType (2 bits) */
4996 unsigned beam_type;
4997 proto_tree_add_item_ret_uint(extension_tree, hf_oran_beam_type, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &beam_type);
4998 /* reserved (6 bits) */
4999 add_reserved_field(extension_tree, hf_oran_reserved_last_6bits, tvb, offset, 1);
5000 offset += 1;
5001
5002 /* numElements */
5003 unsigned num_elements;
5004 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);
5005 if (num_elements == 0) {
5006 num_elements = 256;
5007 proto_item_append_text(num_elements_ti, " (256");
5008 }
5009
5010 offset += 1;
5011
5012 /* beamId value(s) */
5013 switch (beam_type) {
5014 case 0:
5015 for (unsigned n=0; n < num_elements; n++) {
5016 /* reserved (1 bit) + beamId */
5017 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
5018 proto_tree_add_item(c_section_tree, hf_oran_beamId, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
5019 offset += 2;
5020 }
5021 break;
5022 case 1:
5023 /* reserved (1 bit) + beamId */
5024 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
5025 proto_tree_add_item(c_section_tree, hf_oran_beamId, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
5026 offset += 2;
5027 break;
5028 default:
5029 /* Unknown type... */
5030 break;
5031 }
5032 break;
5033 }
5034
5035 case 28: /* SE 28: O-DU controlled frequency resolution for SINR reporting */
5036 {
5037 /* reserved (3 bits) */
5038 add_reserved_field(extension_tree, hf_oran_reserved_3bits, tvb, offset, 1);
5039 /* numUeSinrRpt (5 bits) */
5040 uint32_t num_ue_sinr_rpt;
5041 proto_tree_add_item_ret_uint(extension_tree, hf_oran_num_ue_sinr_rpt, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &num_ue_sinr_rpt);
5042 offset += 1;
5043
5044 for (uint32_t n=0; n < num_ue_sinr_rpt; n++) {
5045 /* reserved (1 bit) */
5046 add_reserved_field(extension_tree, (n % 2) ? hf_oran_reserved_bit4 : hf_oran_reserved_1bit,
5047 tvb, offset, 1);
5048
5049 /* numSinrPerPrb (3 bits). Taken from alternate nibbles within byte. */
5050 proto_tree_add_item(extension_tree, (n % 2) ? hf_oran_num_sinr_per_prb_right : hf_oran_num_sinr_per_prb,
5051 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5052 if (n % 2) {
5053 offset += 1;
5054 }
5055 }
5056
5057 /* May need to skip beyond half-used byte */
5058 if (num_ue_sinr_rpt % 2) {
5059 offset += 1;
5060 }
5061 break;
5062 }
5063
5064 case 29: /* SE 29: Cyclic delay adjustment */
5065 /* reserved (4 bits) */
5066 add_reserved_field(extension_tree, hf_oran_reserved_4bits, tvb, offset, 1);
5067 /* cdScgSize (4 bits) */
5068 proto_tree_add_item(extension_tree, hf_oran_cd_scg_size, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5069 offset += 1;
5070
5071 /* cdScgPhaseStep */
5072 proto_tree_add_item(extension_tree, hf_oran_cd_scg_phase_step, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5073 offset += 1;
5074 break;
5075
5076 case 30: /* SE 30: PUSCH repetition indication */
5077 {
5078 /* Only valid for UL */
5079 if (!tap_info->uplink) {
5080 expert_add_info(pinfo, extension_ti, &ei_oran_se30_not_ul);
5081 }
5082
5083 /* ueids[], number_of_ueids may have been rewritten by SE10 */
5084
5085 /* reserved (4 bits) */
5086 add_reserved_field(extension_tree, hf_oran_reserved_4bits, tvb, offset, 1);
5087 /* numRepUe (4 bits) */
5088 uint8_t num_rep_ue;
5089 proto_tree_add_item_ret_uint8(extension_tree, hf_oran_num_rep_ue, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &num_rep_ue);
5090 offset ++;
5091 /* reserved (8 bits) */
5092 add_reserved_field(extension_tree, hf_oran_reserved_8bits, tvb, offset, 1);
5093 offset += 1;
5094
5095 if (num_rep_ue == 1) {
5096 /* SE10 *not* present. N.B. this should tally with number_of_ueids being set to only 1? */
5097 /* reserved (1 bit) */
5098 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
5099 /* isLastRep (1 bit). Value meaningless here? */
5100 proto_tree_add_item(extension_tree, hf_oran_is_last_rep, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5101 /* repIndex (6 bits) */
5102 proto_tree_add_item(extension_tree, hf_oran_rep_index, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5103 offset += 1;
5104
5105 /* reserved (2 bits) */
5106 add_reserved_field(extension_tree, hf_oran_reserved_2bits, tvb, offset, 1);
5107 /* numReps (6 bits) */
5108 uint8_t num_reps;
5109 proto_tree_add_item_ret_uint8(extension_tree, hf_oran_num_reps, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &num_reps);
5110 /* TODO: should numReps be 0 here? */
5111 offset += 1;
5112
5113 /* reserved (2 bits) */
5114 add_reserved_field(extension_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5115 offset += 2;
5116
5117 }
5118 else {
5119 /* SE10 present */
5120 bool_Bool is_last_rep = false0;
5121 /* TODO: should is_last_rep (also) cause loop exit? */
5122 for (uint8_t ue_idx=0; (ue_idx < num_rep_ue) && !is_last_rep; ue_idx++) {
5123 /* reserved (1 bit) */
5124 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
5125 /* isLastRep (1 bit) */
5126 proto_tree_add_item_ret_boolean(extension_tree, hf_oran_is_last_rep, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &is_last_rep);
5127 /* repIndex (6 bits) */
5128 proto_tree_add_item(extension_tree, hf_oran_rep_index, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5129 offset += 1;
5130
5131 /* reserved (2 bits) */
5132 add_reserved_field(extension_tree, hf_oran_reserved_2bits, tvb, offset, 1);
5133 /* numReps (6 bits) */
5134 uint8_t num_reps;
5135 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);
5136 /* TODO: values 33-63 are reserved */
5137 if (num_reps > 32) {
5138 proto_item_append_text(num_reps_ti, " (reserved)");
5139 }
5140 offset += 1;
5141
5142 for (uint8_t rep=0; rep < num_reps; rep++) {
5143 /* reserved (1 bit) */
5144 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
5145 /* repUeId (15 bits) */
5146 /* TODO: should be fetching and comparing with ueids[] from SE10? */
5147 uint16_t ueid;
5148 proto_item *ueid_ti = proto_tree_add_item_ret_uint16(extension_tree, hf_oran_rep_ueid, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &ueid);
5149
5150 /* Check that this ueid is recognised (among ueids[], number_of_ueids) */
5151 bool_Bool matched = false0;
5152 for (unsigned u=0; u < number_of_ueids; u++) {
5153 if (ueid == ueids[u])
5154 matched = true1;
5155 }
5156 if (!matched) {
5157 expert_add_info_format(pinfo, ueid_ti, &ei_oran_se30_unknown_ueid,
5158 "SE 30 mentions UEId %u - not seen in SE10", ueid);
5159 }
5160 offset += 2;
5161 }
5162 }
5163 }
5164 break;
5165 }
5166 case 31: /* SE 31: MCS Information */
5167 {
5168 /* TODO: show ueid (from ST5 or SE10) as generated field? Maybe add a subtree for each entry? */
5169 for (uint32_t u=0; u < number_of_ueids; u++) {
5170 /* reserved (4 bits) */
5171 add_reserved_field(extension_tree, hf_oran_reserved_4bits, tvb, offset, 1);
5172 /* mcsTable (4 bits) */
5173 proto_tree_add_item(extension_tree, hf_oran_mcs_table, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5174 offset += 1;
5175
5176 /* reserved (2 bits) */
5177 add_reserved_field(extension_tree, hf_oran_reserved_4bits, tvb, offset, 1);
5178 /* mcsIndex (6 bits) */
5179 proto_tree_add_item(extension_tree, hf_oran_mcs_index, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5180 }
5181 break;
5182 }
5183
5184 case 32: /* SE 32: Rank and TPMI measurement request */
5185 {
5186 /* reserved (3 bits) */
5187 add_reserved_field(extension_tree, hf_oran_reserved_3bits, tvb, offset, 1);
5188 /* numMeasReq (5 bits) */
5189 uint8_t num_meas_req;
5190 proto_tree_add_item_ret_uint8(extension_tree, hf_oran_num_meas_req, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &num_meas_req);
5191 offset += 1;
5192
5193 /* reserved (8 bits) */
5194 add_reserved_field(extension_tree, hf_oran_reserved_8bits, tvb, offset, 1);
5195 offset += 1;
5196
5197 /* Show each measurement request */
5198 for (unsigned r=0; r < num_meas_req; r++) {
5199 /* Reserved (1 bit) */
5200 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
5201 /* ueId (14 bits) */
5202 proto_tree_add_item(extension_tree, hf_oran_ueId, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
5203 offset += 2;
5204
5205 /* numOfUeAntPorts (4 bits) */
5206 proto_tree_add_item(extension_tree, hf_oran_num_of_ue_ant_ports, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5207 /* ueRank (4 bits) */
5208 proto_tree_add_item(extension_tree, hf_oran_ue_rank, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5209 offset += 1;
5210
5211 /* codebookSubset (2 bits) */
5212 proto_tree_add_item(extension_tree, hf_oran_codebook_subset, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5213 /* TODO: tpmiIndex (6 bits) */
5214 offset += 1;
5215
5216 /* fullPwrMode (2 bits) */
5217 proto_tree_add_item(extension_tree, hf_oran_full_pwr_mode, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5218 /* fullPwrMode2TmpiGroup (14 bits) */
5219 /* TODO: add as a bitset */
5220 proto_tree_add_item(extension_tree, hf_oran_full_pwr_mode_2_tpmi_group, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
5221 offset += 2;
5222
5223 /* reserved (2 bytes) */
5224 add_reserved_field(extension_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5225 offset += 2;
5226 }
5227 break;
5228 }
5229
5230 default:
5231 /* Other/unexpected extension types */
5232 expert_add_info_format(pinfo, exttype_ti, &ei_oran_unhandled_se,
5233 "SE %u (%s) not supported by dissector",
5234 exttype, val_to_str_ext_const(exttype, &exttype_vals_ext, "Reserved"));
5235 ext_unhandled = true1;
5236 break;
5237 }
5238
5239 /* Check offset compared with extlen. There should be 0-3 bytes of padding */
5240 int num_padding_bytes = (extension_start_offset + (extlen*4) - offset);
5241 if (!ext_unhandled && ((num_padding_bytes<0) || (num_padding_bytes>3))) {
5242 expert_add_info_format(pinfo, extlen_ti, &ei_oran_extlen_wrong,
5243 "extlen signalled %u bytes (+ 0-3 bytes padding), but %u were dissected",
5244 extlen*4, offset-extension_start_offset);
5245 }
5246
5247 /* Move offset to beyond signalled length of extension */
5248 offset = extension_start_offset + (extlen*4);
5249
5250 /* Set length of extension header. */
5251 proto_item_set_len(extension_ti, extlen*4);
5252 }
5253 /* End of section extension handling */
5254
5255 /* Tap section beamId if not overwritten by SEs */
5256 if (!section_beamId_ignored && section_beamId != 0) {
5257 add_beam_id_to_tap(tap_info, section_beamId);
5258 }
5259
5260
5261 /* RRM measurement reports have measurement reports *after* extensions */
5262 if (sectionType == SEC_C_RRM_MEAS_REPORTS) /* Section Type 10 */
5263 {
5264 /* Hidden filter for bf (DMFS-BF). No BF weights though.. */
5265 bf_ti = proto_tree_add_item(c_section_tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
5266 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
5267
5268 bool_Bool mf;
5269 do {
5270 /* Measurement report subtree */
5271 proto_item *mr_ti = proto_tree_add_string_format(c_section_tree, hf_oran_measurement_report,
5272 tvb, offset, 1, "", "Measurement Report");
5273 proto_tree *mr_tree = proto_item_add_subtree(mr_ti, ett_oran_measurement_report);
5274 unsigned report_start_offset = offset;
5275
5276 /* measurement flag (i.e., more reports after this one) (1 bit) */
5277 proto_tree_add_item_ret_boolean(mr_tree, hf_oran_mf, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &mf);
5278
5279 /* measTypeId (7 bits) */
5280 uint32_t meas_type_id;
5281 proto_item *meas_type_id_ti;
5282 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);
5283 offset += 1;
5284
5285 /* Common to all measurement types */
5286 unsigned num_elements = 0;
5287 if (meas_type_id == 6) {
5288 /* numElements */
5289 proto_tree_add_item_ret_uint(mr_tree, hf_oran_num_elements, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &num_elements);
5290 }
5291 else {
5292 /* All other meas ids have a reserved byte */
5293 add_reserved_field(mr_tree, hf_oran_reserved_8bits, tvb, offset, 1);
5294 }
5295 offset += 1;
5296
5297 /* measDataSize (16 bits). N.B. begins at mf field, i.e. 2 bytes before this one */
5298 unsigned meas_data_size;
5299 proto_item *meas_data_size_ti;
5300 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);
5301 meas_data_size *= 4;
5302 proto_item_append_text(meas_data_size_ti, " (%u bytes)", meas_data_size);
5303 offset += 2;
5304
5305 /* Summary for measurement report root */
5306 proto_item_append_text(mr_ti, " (measTypeId=%u - %s)",
5307 meas_type_id, val_to_str_const(meas_type_id, meas_type_id_vals, "unknown"));
5308 /* And section header */
5309 proto_item_append_text(tree, " (%s)", val_to_str_const(meas_type_id, meas_type_id_vals, "unknown"));
5310 /* And Info column */
5311 col_append_fstr(pinfo->cinfo, COL_INFO, " (%s)", val_to_str_const(meas_type_id, meas_type_id_vals, "unknown"));
5312
5313 /* Handle specific message type fields */
5314 switch (meas_type_id) {
5315 case 1:
5316 {
5317 /* ueTae */
5318 unsigned ue_tae;
5319 proto_item *ue_tae_ti;
5320 ue_tae_ti = proto_tree_add_item_ret_uint(mr_tree, hf_oran_ue_tae, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &ue_tae);
5321 /* Show if maps onto a -ve number */
5322 if ((ue_tae >= 0x8ad0) && (ue_tae <= 0xffff)) {
5323 proto_item_append_text(ue_tae_ti, "(value %d)", -1 - (0xffff-ue_tae));
5324 }
5325 offset += 2;
5326
5327 /* Reserved (16 bits) */
5328 add_reserved_field(mr_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5329 offset += 2;
5330 break;
5331 }
5332 case 2:
5333 /* ueLayerPower entries (how many? for now just use up meas_data_size..) */
5334 /* TODO: add number of distinct dmrsPortNumber entries seen in SE24 and save in state? */
5335 /* Or would it make sense to use the preference 'pref_num_bf_antennas' ? */
5336 for (unsigned n=0; n < (meas_data_size-4)/2; n++) {
5337 unsigned ue_layer_power;
5338 proto_item *ue_layer_power_ti;
5339 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);
5340 /* Show if maps onto a -ve number */
5341 if ((ue_layer_power >= 0x8ad0) && (ue_layer_power <= 0xffff)) {
5342 proto_item_append_text(ue_layer_power_ti, "(value %d)", -1 - (0xffff-ue_layer_power));
5343 }
5344 offset += 2;
5345 }
5346 /* padding out to 4 bytes */
5347 break;
5348 case 3:
5349 {
5350 /* ueFreqOffset */
5351 unsigned ue_freq_offset;
5352 proto_item *ue_freq_offset_ti;
5353 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);
5354 /* Show if maps onto a -ve number */
5355 if ((ue_freq_offset >= 0x8ad0) && (ue_freq_offset <= 0xffff)) {
5356 proto_item_append_text(ue_freq_offset_ti, "(value %d)", -1 - (0xffff-ue_freq_offset));
5357 }
5358 offset += 2;
5359
5360 /* Reserved (16 bits) */
5361 add_reserved_field(mr_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5362 offset += 2;
5363 break;
5364 }
5365 case 4:
5366 case 5:
5367 /* reserved (2 bits) */
5368 add_reserved_field(mr_tree, hf_oran_reserved_2bits, tvb, offset, 1);
5369 /* symbolMask (14 bits) */
5370 offset = dissect_symbolmask(tvb, mr_tree, offset, NULL((void*)0), NULL((void*)0));
5371
5372 /* 2 bytes for each PRB ipnPower */
5373 for (unsigned prb=0; prb<MAX_PRBS273; prb++) {
5374 /* Skip if should not be reported */
5375 if (!prbs_for_st10_type5[prb]) {
5376 continue;
5377 }
5378 unsigned ipn_power;
5379 proto_item *ipn_power_ti;
5380 /* ipnPower (2 bytes) */
5381 ipn_power_ti = proto_tree_add_item_ret_uint(mr_tree, hf_oran_ipn_power, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &ipn_power);
5382 proto_item_append_text(ipn_power_ti, " (PRB %3d)", prb);
5383 /* Show if maps onto a -ve number */
5384 if ((ipn_power >= 0x8ad0) && (ipn_power <= 0xffff)) {
5385 proto_item_append_text(ipn_power_ti, " (value %d)", -1 - (0xffff-ipn_power));
5386 }
5387 offset += 2;
5388 }
5389 /* padding out to 4 bytes */
5390 break;
5391 case 6:
5392 /* antDmrsSnrVal entries */
5393 for (unsigned n=0; n < num_elements; n++) {
5394 unsigned snr_value;
5395 proto_item *snr_value_ti;
5396 /* antDmrsSnrVal (2 bytes) */
5397 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);
5398 proto_item_append_text(snr_value_ti, " (elem %2u)", n+1);
5399 /* Show if maps onto a -ve number */
5400 if ((snr_value >= 0x8ad0) && (snr_value <= 0xffff)) {
5401 proto_item_append_text(snr_value_ti, " (value %d)", -1 - (0xffff-snr_value));
5402 }
5403 offset += 2;
5404 }
5405 break;
5406 case 7:
5407 {
5408 /* UE positioning measurement report */
5409 float start_value;
5410
5411 /* ueAzAoa (16 bits) */
5412 uint32_t ue_az_aoa;
5413 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);
5414 if (ue_az_aoa <= 0xE0F) {
5415 if (ue_az_aoa >= 0x0708) {
5416 start_value = (ue_az_aoa-0x0708) * (float)0.1;
5417 proto_item_append_text(ue_az_aoa_ti, " (%.1f <= val < %.1f degrees)", start_value, start_value + (float)0.1);
5418 }
5419 else {
5420 start_value = 180 + (ue_az_aoa * (float)0.1);
5421 proto_item_append_text(ue_az_aoa_ti, " (%.1f <= val < %.1f degrees)", start_value, start_value + (float)0.1);
5422 }
5423 }
5424 else if (ue_az_aoa == 0xffff) {
5425 proto_item_append_text(ue_az_aoa_ti, " (invalid measurement result)");
5426 }
5427 else {
5428 proto_item_append_text(ue_az_aoa_ti, " (reserved)");
5429 }
5430 offset += 2;
5431
5432 /* Reserved (16 bits) */
5433 add_reserved_field(mr_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5434 offset += 2;
5435
5436 /* ueZeAoa (16 bits) */
5437 uint32_t ue_ze_aoa;
5438 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);
5439 if (ue_ze_aoa <= 0x707) {
5440 start_value = ue_ze_aoa * (float)0.1;
5441 proto_item_append_text(ue_ze_aoa_ti, " (%.1f <= val < %.1f degrees)", start_value, start_value + (float)0.1);
5442 }
5443 else if (ue_az_aoa == 0xffff) {
5444 proto_item_append_text(ue_ze_aoa_ti, " (invalid measurement result)");
5445 }
5446 else {
5447 proto_item_append_text(ue_ze_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 /* uePosToaOffset (16 bits) */
5456 uint32_t ue_pos_toa_offset;
5457 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);
5458 if (ue_pos_toa_offset == 0) {
5459 proto_item_append_text(ue_pos_toa_offset_ti, " (no UE ToA offset, 0 symbols)");
5460 }
5461 else if (ue_pos_toa_offset <= 0x7fff) {
5462 proto_item_append_text(ue_pos_toa_offset_ti, " (+ve UE ToA offset)");
5463 }
5464 else if (ue_pos_toa_offset == 0x8000) {
5465 proto_item_append_text(ue_pos_toa_offset_ti, " (invalid measurement result)");
5466 }
5467 else {
5468 proto_item_append_text(ue_pos_toa_offset_ti, " (-ve UE ToA offset)");
5469 }
5470 offset += 2;
5471
5472 /* Reserved (16 bits) */
5473 add_reserved_field(mr_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5474 offset += 2;
5475 break;
5476 }
5477 case 8:
5478 {
5479 /* UE radial speed measurement report */
5480
5481 /* ueRadialSpeed (16 bits) */
5482 uint32_t radial_speed;
5483 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);
5484 if (radial_speed <= 10000) {
5485 proto_item_append_text(radial_speed_ti, " (%.1f km/h)", radial_speed * (float)0.1);
5486 }
5487 else if (radial_speed == 0x8000) {
5488 proto_item_append_text(radial_speed_ti, " (invalid measurement result)");
5489 }
5490 else {
5491 proto_item_append_text(radial_speed_ti, " (reserved value)");
5492 }
5493 offset += 2;
5494
5495 /* Reserved (16 bits) */
5496 add_reserved_field(mr_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5497 offset += 2;
5498 break;
5499 }
5500 case 9:
5501 {
5502 /* TODO: UE post-equalization MU interference measurement */
5503
5504 /* reserved (16 bits) */
5505 add_reserved_field(mr_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5506 offset += 2;
5507
5508 /* TODO: muInterferenceLevel (all layers * all PRB blocks) */
5509 break;
5510 }
5511 case 10:
5512 {
5513 /* TODO: UE TPMI and rank recommendation measurement */
5514
5515 /* numCandRanks (4 bits) */
5516 add_reserved_field(mr_tree, hf_oran_num_cand_ranks, tvb, offset, 1);
5517 /* uePrefRank (4 bits) */
5518 add_reserved_field(mr_tree, hf_oran_ue_pref_rank, tvb, offset, 1);
5519 offset += 1;
5520
5521 /* TODO: ueTpmiRank1 (1 byte) */
5522 offset += 1;
5523
5524 /* TODO: ueTpmiRank1Sinr1 (2 bytes) */
5525 offset += 2;
5526
5527 /* TODO: various Sinr depending upon numCandRanks value.. */
5528 break;
5529 }
5530 case 11:
5531 {
5532 /* TODO: UE layer pre-equalization SINR report */
5533
5534 /* TODO: 1st to last layer ueLayerPreEqSinr (2 bytes each) */
5535 break;
5536 }
5537
5538 default:
5539 /* Anything else is not expected */
5540 expert_add_info_format(pinfo, meas_type_id_ti, &ei_oran_unexpected_measTypeId,
5541 "measTypeId %u (%s) not supported - only 1-6 are expected",
5542 meas_type_id,
5543 val_to_str_const(meas_type_id, meas_type_id_vals, "reserved"));
5544 break;
5545
5546 }
5547
5548 /* Pad out to next 4 bytes */
5549 offset += WS_PADDING_TO_4(offset-report_start_offset)((4U - ((offset-report_start_offset) % 4U)) % 4U);
5550
5551 /* TODO: verify dissected size of report vs meas_data_size? */
5552
5553 /* End of measurement report tree */
5554 proto_item_set_end(mr_ti, tvb, offset);
5555 } while (mf);
5556 }
5557
5558 /* Request for RRM Measurements has measurement commands after extensions */
5559 else if (sectionType == SEC_C_REQUEST_RRM_MEAS) /* Section Type 11 */
5560 {
5561 bool_Bool mf = true1;
5562 do {
5563 /* Measurement command subtree */
5564 proto_item *mc_ti = proto_tree_add_string_format(c_section_tree, hf_oran_measurement_command,
5565 tvb, offset, 8, "", "Measurement Command");
5566 proto_tree *mc_tree = proto_item_add_subtree(mc_ti, ett_oran_measurement_command);
5567
5568 /* mf (1 bit). 1st measurement command is always preset */
5569 proto_tree_add_item_ret_boolean(mc_tree, hf_oran_mf, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &mf);
5570
5571 /* measTypeId (7 bits) */
5572 uint32_t meas_type_id;
5573 proto_item *meas_type_id_ti;
5574 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);
5575 offset += 1;
5576
5577 proto_item *meas_command_ti;
5578 uint32_t meas_command_size;
5579
5580 switch (meas_type_id) {
5581 case 5: /* command for IpN for unallocated PRBs */
5582 /* reserved (1 byte) */
5583 add_reserved_field(mc_tree, hf_oran_reserved_8bits, tvb, offset, 1);
5584 offset += 1;
5585 /* measCmdSize. Presumably number of words so in future could skip unrecognised command types.. */
5586 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);
5587 proto_item_append_text(meas_command_ti, " (%u bytes)", meas_command_size*4);
5588 offset += 2;
5589 /* reserved (2 bits) */
5590 add_reserved_field(mc_tree, hf_oran_reserved_2bits, tvb, offset, 1);
5591 /* symbolMask (14 bits) */
5592 offset = dissect_symbolmask(tvb, mc_tree, offset, NULL((void*)0), NULL((void*)0));
5593 /* reserved (16 bits) */
5594 add_reserved_field(mc_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5595 offset += 2;
5596 break;
5597
5598 default:
5599 /* Anything else is not expected */
5600 expert_add_info_format(pinfo, meas_type_id_ti, &ei_oran_unexpected_measTypeId,
5601 "measTypeId %u (%s) not supported - only 5 is expected",
5602 meas_type_id,
5603 val_to_str_const(meas_type_id, meas_type_id_vals, "reserved"));
5604 break;
5605 }
5606 proto_item_append_text(mc_ti, " (%s)", val_to_str_const(meas_type_id, meas_type_id_vals, "unknown"));
5607
5608 } while (mf);
5609 }
5610
5611 /* Set extent of overall section */
5612 proto_item_set_len(sectionHeading, offset);
5613
5614 return offset;
5615}
5616
5617/* Dissect udCompHdr (user data compression header, 7.5.2.10) */
5618/* bit_width and comp_meth are out params */
5619static int dissect_udcomphdr(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset,
5620 bool_Bool cplane, bool_Bool ignore,
5621 unsigned *bit_width, unsigned *comp_meth, proto_item **comp_meth_ti,
5622 oran_tap_info *tap_info)
5623{
5624 /* Subtree */
5625 proto_item *udcomphdr_ti = proto_tree_add_string_format(tree, hf_oran_udCompHdr,
5626 tvb, offset, 1, "",
5627 "udCompHdr");
5628 proto_tree *udcomphdr_tree = proto_item_add_subtree(udcomphdr_ti, ett_oran_udcomphdr);
5629
5630 /* udIqWidth */
5631 uint32_t hdr_iq_width;
5632 proto_item *iq_width_item = proto_tree_add_item_ret_uint(udcomphdr_tree, hf_oran_udCompHdrIqWidth , tvb, offset, 1, ENC_NA0x00000000, &hdr_iq_width);
5633 *bit_width = (hdr_iq_width) ? hdr_iq_width : 16;
5634 proto_item_append_text(iq_width_item, " (%u bits)", *bit_width);
5635
5636 /* udCompMeth */
5637 uint32_t ud_comp_meth;
5638 *comp_meth_ti = proto_tree_add_item_ret_uint(udcomphdr_tree, hf_oran_udCompHdrMeth, tvb, offset, 1, ENC_NA0x00000000, &ud_comp_meth);
5639 if (comp_meth) {
5640 *comp_meth = ud_comp_meth;
5641 }
5642
5643 /* Populate tap header with compression settings */
5644 if (!ignore) {
5645 tap_info->compression_methods |= (1 << ud_comp_meth);
5646 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))
;
5647 /* Summary */
5648 proto_item_append_text(udcomphdr_ti, " (IqWidth=%u, udCompMeth=%s)",
5649 *bit_width, rval_to_str_const(ud_comp_meth, ud_comp_header_meth, "Unknown"));
5650 }
5651 else {
5652 proto_item_append_text(udcomphdr_ti, " (ignored)");
5653 if (hdr_iq_width || ud_comp_meth) {
5654 if (cplane) {
5655 /* Only ignore DL for cplane */
5656 expert_add_info_format(pinfo, udcomphdr_ti, &ei_oran_udpcomphdr_should_be_zero,
5657 "udCompHdr in C-Plane for DL should be 0 - found 0x%02x",
5658 tvb_get_uint8(tvb, offset));
5659 }
5660 else {
5661 /* TODO: Ignore UL if using m-plane/preference setting rather than c-plane, but wrong to be set? */
5662 /* expert_add_info_format(pinfo, udcomphdr_ti, &ei_oran_udpcomphdr_should_be_zero,
5663 "udCompHdr in C-Plane for UL should be 0 - found 0x%02x",
5664 tvb_get_uint8(tvb, offset));
5665 */
5666 }
5667
5668 }
5669 }
5670 return offset+1;
5671}
5672
5673/* Dissect udCompParam (user data compression parameter, 8.3.3.15) */
5674/* bit_width and comp_meth are out params */
5675static int dissect_udcompparam(tvbuff_t *tvb, packet_info *pinfo _U___attribute__((unused)), proto_tree *tree, unsigned offset,
5676 unsigned comp_meth,
5677 uint32_t *exponent, uint16_t *sReSMask,
5678 bool_Bool for_sinr)
5679{
5680 if (for_sinr && (comp_meth != COMP_BLOCK_FP1)) {
5681 /* sinrCompParam only present when bfp is used */
5682 return offset;
5683 }
5684
5685 if (comp_meth == COMP_NONE0 ||
5686 comp_meth == COMP_MODULATION4 ||
5687 comp_meth == MOD_COMPR_AND_SELECTIVE_RE_WITH_MASKS8) {
5688
5689 /* Not even creating a subtree for udCompMeth 0, 4, 8 */
5690 return offset;
5691 }
5692
5693 /* Subtree */
5694 unsigned start_offset = offset;
5695 proto_item *udcompparam_ti = proto_tree_add_string_format(tree, hf_oran_udCompParam,
5696 tvb, offset, 1, "",
5697 (for_sinr) ? "sinrCompParam" : "udCompParam");
5698 proto_tree *udcompparam_tree = proto_item_add_subtree(udcompparam_ti, ett_oran_udcompparam);
5699
5700 /* Show comp_meth as a generated field */
5701 proto_item *meth_ti = proto_tree_add_uint(udcompparam_tree, hf_oran_udCompHdrMeth_pref, tvb, 0, 0, comp_meth);
5702 proto_item_set_generated(meth_ti);
5703
5704 uint32_t param_exponent;
5705 uint64_t param_sresmask;
5706
5707 static int * const sres_mask_flags[] = {
5708 &hf_oran_sReSMask_re12,
5709 &hf_oran_sReSMask_re11,
5710 &hf_oran_sReSMask_re10,
5711 &hf_oran_sReSMask_re9,
5712 &hf_oran_sReSMask_re8,
5713 &hf_oran_sReSMask_re7,
5714 &hf_oran_sReSMask_re6,
5715 &hf_oran_sReSMask_re5,
5716 &hf_oran_sReSMask_re4,
5717 &hf_oran_sReSMask_re3,
5718 &hf_oran_sReSMask_re2,
5719 &hf_oran_sReSMask_re1,
5720 NULL((void*)0)
5721 };
5722
5723 switch (comp_meth) {
5724 case COMP_BLOCK_FP1: /* 1 */
5725 case BFP_AND_SELECTIVE_RE_WITH_MASKS7: /* 7 */
5726 /* reserved (4 bits) */
5727 add_reserved_field(udcompparam_tree, hf_oran_reserved_4bits, tvb, offset, 1);
5728 /* exponent (4 bits) */
5729 proto_tree_add_item_ret_uint(udcompparam_tree, hf_oran_exponent,
5730 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &param_exponent);
5731 *exponent = param_exponent;
5732 proto_item_append_text(udcompparam_ti, " (Exponent=%u)", param_exponent);
5733 offset += 1;
5734 break;
5735
5736 case COMP_BLOCK_SCALE2: /* 2 */
5737 /* Separate into integer and fractional bits? */
5738 proto_tree_add_item(udcompparam_tree, hf_oran_blockScaler,
5739 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5740 offset++;
5741 break;
5742
5743 case COMP_U_LAW3: /* 3 */
5744 /* compBitWidth, compShift */
5745 proto_tree_add_item(udcompparam_tree, hf_oran_compBitWidth,
5746 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5747 proto_tree_add_item(udcompparam_tree, hf_oran_compShift,
5748 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5749 offset += 1;
5750 break;
5751
5752 case BFP_AND_SELECTIVE_RE5: /* 5 */
5753 {
5754 /* sReSMask (exponent in middle!) */
5755 proto_item *sresmask_ti;
5756 sresmask_ti = proto_tree_add_bitmask_ret_uint64(udcompparam_tree, tvb, offset,
5757 hf_oran_sReSMask,
5758 ett_oran_sresmask,
5759 sres_mask_flags,
5760 ENC_NA0x00000000,
5761 &param_sresmask);
5762
5763 /* Get rid of exponent-shaped gap */
5764 param_sresmask = ((param_sresmask >> 4) & 0x0f00) | (param_sresmask & 0xff);
5765 unsigned res = 0;
5766 for (unsigned n=0; n < 12; n++) {
5767 if ((param_sresmask >> n) & 0x1) {
5768 res++;
5769 }
5770 }
5771 proto_item_append_text(sresmask_ti, " (%2u REs)", res);
5772
5773 /* exponent */
5774 proto_tree_add_item_ret_uint(udcompparam_tree, hf_oran_exponent,
5775 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &param_exponent);
5776 *sReSMask = (uint16_t)param_sresmask;
5777 *exponent = param_exponent;
5778
5779 proto_item_append_text(udcompparam_ti, " (exponent=%u, %u REs)", *exponent, res);
5780 offset += 2;
5781 break;
5782 }
5783
5784 case MOD_COMPR_AND_SELECTIVE_RE6: /* 6 */
5785 {
5786 /* sReSMask (exponent in middle!) */
5787 proto_item *sresmask_ti;
5788
5789 sresmask_ti = proto_tree_add_bitmask_ret_uint64(udcompparam_tree, tvb, offset,
5790 hf_oran_sReSMask,
5791 ett_oran_sresmask,
5792 sres_mask_flags,
5793 ENC_NA0x00000000,
5794 &param_sresmask);
5795
5796 /* Get rid of reserved-shaped gap */
5797 param_sresmask = ((param_sresmask >> 4) & 0x0f00) | (param_sresmask & 0xff);
5798 unsigned res = 0;
5799 for (unsigned n=0; n < 12; n++) {
5800 if ((param_sresmask >> n) & 0x1) {
5801 res++;
5802 }
5803 }
5804 proto_item_append_text(sresmask_ti, " (%u REs)", res);
5805
5806 /* reserved (4 bits) */
5807 add_reserved_field(udcompparam_tree, hf_oran_reserved_last_4bits, tvb, offset, 1);
5808 *sReSMask = (uint16_t)param_sresmask;
5809
5810 proto_item_append_text(udcompparam_ti, " (%u REs)", res);
5811 offset += 2;
5812 break;
5813 }
5814
5815 default:
5816 /* reserved (set to all zeros), but how many bytes?? */
5817 break;
5818 }
5819
5820 proto_item_set_len(udcompparam_ti, offset-start_offset);
5821 return offset;
5822}
5823
5824
5825/* Dissect ciCompHdr (channel information compression header, 7.5.2.15) */
5826/* bit_width and comp_meth are out params */
5827static int dissect_cicomphdr(tvbuff_t *tvb, packet_info *pinfo _U___attribute__((unused)), proto_tree *tree, unsigned offset,
5828 unsigned *bit_width, unsigned *comp_meth, uint8_t *comp_opt)
5829{
5830 /* Subtree */
5831 proto_item *cicomphdr_ti = proto_tree_add_string_format(tree, hf_oran_ciCompHdr,
5832 tvb, offset, 1, "",
5833 "ciCompHdr");
5834 proto_tree *cicomphdr_tree = proto_item_add_subtree(cicomphdr_ti, ett_oran_cicomphdr);
5835
5836 /* ciIqWidth */
5837 uint32_t hdr_iq_width;
5838 proto_item *iq_width_item = proto_tree_add_item_ret_uint(cicomphdr_tree, hf_oran_ciCompHdrIqWidth , tvb, offset, 1, ENC_NA0x00000000, &hdr_iq_width);
5839 hdr_iq_width = (hdr_iq_width) ? hdr_iq_width : 16;
5840 if (bit_width) {
5841 *bit_width = hdr_iq_width;
5842 }
5843 proto_item_append_text(iq_width_item, " (%u bits)", hdr_iq_width);
5844
5845 /* ciCompMeth */
5846 uint32_t ci_comp_meth;
5847 proto_tree_add_item_ret_uint(cicomphdr_tree, hf_oran_ciCompHdrMeth, tvb, offset, 1, ENC_NA0x00000000, &ci_comp_meth);
5848 if (comp_meth) {
5849 *comp_meth = ci_comp_meth;
5850 }
5851
5852 /* ciCompOpt */
5853 uint32_t opt;
5854 proto_tree_add_item_ret_uint(cicomphdr_tree, hf_oran_ciCompOpt, tvb, offset, 1, ENC_NA0x00000000, &opt);
5855 *comp_opt = opt;
5856 offset += 1;
5857
5858 /* Summary */
5859 proto_item_append_text(cicomphdr_ti, " (IqWidth=%u, ciCompMeth=%s, ciCompOpt=%s)",
5860 hdr_iq_width,
5861 rval_to_str_const(ci_comp_meth, ud_comp_header_meth, "Unknown"),
5862 (*comp_opt) ? "compression per PRB" : "compression per UE");
5863 return offset;
5864}
5865
5866static void dissect_payload_version(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, unsigned offset)
5867{
5868 unsigned version;
5869 proto_item *ti = proto_tree_add_item_ret_uint(tree, hf_oran_payload_version, tvb, offset, 1, ENC_NA0x00000000, &version);
5870 if (version != 1) {
5871 expert_add_info_format(pinfo, ti, &ei_oran_version_unsupported,
5872 "PayloadVersion %u not supported by dissector (only 1 is known)",
5873 version);
5874 /* TODO: should throw an exception? */
5875 }
5876}
5877
5878static void show_link_to_acknack_request(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo,
5879 ack_nack_request_t *request)
5880{
5881 /* Request frame */
5882 proto_item *ti = proto_tree_add_uint(tree, hf_oran_acknack_request_frame,
5883 tvb, 0, 0, request->request_frame_number);
5884 PROTO_ITEM_SET_GENERATED(ti)proto_item_set_generated((ti));
5885
5886 /* Work out gap between frames (in ms) */
5887 int seconds_between_packets = (int)
5888 (pinfo->abs_ts.secs - request->request_frame_time.secs);
5889 int nseconds_between_packets =
5890 pinfo->abs_ts.nsecs - request->request_frame_time.nsecs;
5891
5892 int total_gap = (seconds_between_packets*1000) +
5893 ((nseconds_between_packets+500000) / 1000000);
5894
5895 ti = proto_tree_add_uint(tree, hf_oran_acknack_request_time,
5896 tvb, 0, 0, total_gap);
5897 PROTO_ITEM_SET_GENERATED(ti)proto_item_set_generated((ti));
5898
5899 /* Type of request */
5900 ti = proto_tree_add_uint(tree, hf_oran_acknack_request_type,
5901 tvb, 0, 0, request->requestType);
5902 PROTO_ITEM_SET_GENERATED(ti)proto_item_set_generated((ti));
5903}
5904
5905static void show_link_to_acknack_response(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo,
5906 ack_nack_request_t *response)
5907{
5908 if (response->response_frame_number == 0) {
5909 /* Requests may not get a response, and can't always tell when to expect one */
5910 return;
5911 }
5912
5913 /* Response frame */
5914 proto_item *ti = proto_tree_add_uint(tree, hf_oran_acknack_response_frame,
5915 tvb, 0, 0, response->response_frame_number);
5916 PROTO_ITEM_SET_GENERATED(ti)proto_item_set_generated((ti));
5917
5918 /* Work out gap between frames (in ms) */
5919 int seconds_between_packets = (int)
5920 (response->response_frame_time.secs - pinfo->abs_ts.secs);
5921 int nseconds_between_packets =
5922 response->response_frame_time.nsecs - pinfo->abs_ts.nsecs;
5923
5924 int total_gap = (seconds_between_packets*1000) +
5925 ((nseconds_between_packets+500000) / 1000000);
5926
5927 ti = proto_tree_add_uint(tree, hf_oran_acknack_response_time,
5928 tvb, 0, 0, total_gap);
5929 PROTO_ITEM_SET_GENERATED(ti)proto_item_set_generated((ti));
5930}
5931
5932
5933
5934/* Control plane dissector (section 7). */
5935static int dissect_oran_c(tvbuff_t *tvb, packet_info *pinfo,
5936 proto_tree *tree, oran_tap_info *tap_info, void *data _U___attribute__((unused)))
5937{
5938 /* Hidden filter for plane */
5939 proto_item *plane_ti = proto_tree_add_item(tree, hf_oran_cplane, tvb, 0, 0, ENC_NA0x00000000);
5940 PROTO_ITEM_SET_HIDDEN(plane_ti)proto_item_set_hidden((plane_ti));
5941
5942 /* Set up structures needed to add the protocol subtree and manage it */
5943 unsigned offset = 0;
5944
5945 col_set_str(pinfo->cinfo, COL_PROTOCOL, "O-RAN-FH-C");
5946 col_set_str(pinfo->cinfo, COL_INFO, "C-Plane");
5947
5948 tap_info->userplane = false0;
5949
5950 /* Create display subtree for the protocol */
5951 proto_item *protocol_item = proto_tree_add_item(tree, proto_oran, tvb, 0, -1, ENC_NA0x00000000);
5952 proto_item_append_text(protocol_item, "-C");
5953 proto_tree *oran_tree = proto_item_add_subtree(protocol_item, ett_oran);
5954
5955 /* ecpriRtcid (eAxC ID) */
5956 uint16_t eAxC;
5957 addPcOrRtcid(tvb, oran_tree, &offset, hf_oran_ecpri_rtcid, &eAxC, tap_info);
5958 tap_info->eaxc = eAxC;
5959
5960 /* Look up any existing conversation state for eAxC+plane */
5961 uint32_t key = make_flow_key(pinfo, eAxC, ORAN_C_PLANE0, false0);
5962 flow_state_t* state = (flow_state_t*)wmem_tree_lookup32(flow_states_table, key);
5963
5964 /* Message identifier */
5965 uint32_t seq_id, sub_seq_id, e;
5966 proto_item *seq_id_ti;
5967 offset = addSeqid(tvb, oran_tree, offset, ORAN_C_PLANE0, &seq_id, &seq_id_ti, pinfo, &sub_seq_id, &e);
5968
5969 /* Section common subtree */
5970 int section_tree_offset = offset;
5971 proto_item *sectionHeading = proto_tree_add_string_format(oran_tree, hf_oran_c_section_common,
5972 tvb, offset, 0, "", "C-Plane Section Type ");
5973 proto_tree *section_tree = proto_item_add_subtree(sectionHeading, ett_oran_c_section_common);
5974
5975 /* Peek ahead at the section type */
5976 uint32_t sectionType = 0;
5977 sectionType = tvb_get_uint8(tvb, offset+5);
5978
5979 uint32_t scs = 0;
5980 proto_item *scs_ti = NULL((void*)0);
5981
5982 /* dataDirection */
5983 uint32_t direction = 0;
5984 proto_item *datadir_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_data_direction, tvb, offset, 1, ENC_NA0x00000000, &direction);
5985 tap_info->uplink = (direction==0);
5986
5987 /* Update/report status of conversation */
5988 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
5989
5990 if (state == NULL((void*)0)) {
5991 /* Allocate new state */
5992 state = wmem_new0(wmem_file_scope(), flow_state_t)((flow_state_t*)wmem_alloc0((wmem_file_scope()), sizeof(flow_state_t
)))
;
5993 state->ack_nack_requests = wmem_tree_new(wmem_file_scope());
5994 wmem_tree_insert32(flow_states_table, key, state);
5995 /* Tables for each direction */
5996 state->expected_sections[0] = wmem_tree_new(wmem_file_scope());
5997 state->expected_sections[1] = wmem_tree_new(wmem_file_scope());
5998 }
5999
6000 /* Check sequence analysis status */
6001 if (state->last_frame_seen[direction] && (seq_id != state->next_expected_sequence_number[direction])) {
6002 /* Store this result */
6003 flow_result_t *result = wmem_new0(wmem_file_scope(), flow_result_t)((flow_result_t*)wmem_alloc0((wmem_file_scope()), sizeof(flow_result_t
)))
;
6004 result->unexpected_seq_number = true1;
6005 result->expected_sequence_number = state->next_expected_sequence_number[direction];
6006 result->previous_frame = state->last_frame[direction];
6007 result->u_plane_frames = wmem_list_new(wmem_file_scope());
6008 wmem_tree_insert32(flow_results_table, pinfo->num, result);
6009 }
6010 /* Update conversation info */
6011 state->last_frame[direction] = pinfo->num;
6012 state->last_frame_seen[direction] = true1;
6013 state->next_expected_sequence_number[direction] = (seq_id+1) % 256;
6014 }
6015
6016 /* Show any issues associated with this frame number */
6017 flow_result_t *result = wmem_tree_lookup32(flow_results_table, pinfo->num);
6018 if (result!=NULL((void*)0) && result->unexpected_seq_number) {
6019 expert_add_info_format(pinfo, seq_id_ti,
6020 (direction == DIR_UPLINK0) ?
6021 &ei_oran_cplane_unexpected_sequence_number_ul :
6022 &ei_oran_cplane_unexpected_sequence_number_dl,
6023 "Sequence number %u expected, but got %u",
6024 result->expected_sequence_number, seq_id);
6025
6026 /* Update tap info */
6027 uint32_t missing_sns = (256 + seq_id - result->expected_sequence_number) % 256;
6028 /* Don't get confused by being slightly out of order.. */
6029 if (missing_sns < 128) {
6030 tap_info->missing_sns = missing_sns;
6031 }
6032 else {
6033 tap_info->missing_sns = 0;
6034 }
6035
6036 /* TODO: could add previous/next frames (in seqId tree?) ? */
6037 }
6038
6039 /* payloadVersion */
6040 dissect_payload_version(section_tree, tvb, pinfo, offset);
6041
6042 /* filterIndex */
6043 if (sectionType == SEC_C_SLOT_CONTROL || sectionType == SEC_C_ACK_NACK_FEEDBACK) {
6044 /* scs (for ST4 and ST8) */
6045 scs_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_frameStructure_subcarrier_spacing, tvb, offset, 1, ENC_NA0x00000000, &scs);
6046 }
6047 else if (sectionType == SEC_C_RRM_MEAS_REPORTS || sectionType == SEC_C_REQUEST_RRM_MEAS) {
6048 /* reserved (4 bits) */
6049 add_reserved_field(section_tree, hf_oran_reserved_last_4bits, tvb, offset, 1);
6050 }
6051 else if (sectionType != SEC_C_LAA) {
6052 /* filterIndex (most common case) */
6053 proto_tree_add_item(section_tree, hf_oran_filter_index, tvb, offset, 1, ENC_NA0x00000000);
6054 }
6055 offset += 1;
6056
6057 unsigned ref_a_offset = offset;
6058 /* frameId */
6059 uint32_t frameId = 0;
6060 proto_tree_add_item_ret_uint(section_tree, hf_oran_frame_id, tvb, offset, 1, ENC_NA0x00000000, &frameId);
6061 tap_info->frame = frameId;
6062 offset += 1;
6063
6064 /* subframeId */
6065 uint32_t subframeId = 0;
6066 proto_tree_add_item_ret_uint(section_tree, hf_oran_subframe_id, tvb, offset, 1, ENC_NA0x00000000, &subframeId);
6067 /* slotId */
6068 uint32_t slotId = 0;
6069 proto_tree_add_item_ret_uint(section_tree, hf_oran_slot_id, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &slotId);
6070 tap_info->slot = slotId;
6071 offset++;
6072
6073 /* startSymbolId */
6074 uint32_t startSymbolId = 0;
6075 proto_item *ssid_ti = NULL((void*)0);
6076 if ((sectionType == SEC_C_ACK_NACK_FEEDBACK) || /* Section Type 8 */
6077 (sectionType == SEC_C_SINR_REPORTING)) { /* Section Type 9 */
6078 /* symbolId */
6079 proto_tree_add_item_ret_uint(section_tree, hf_oran_symbolId, tvb, offset, 1, ENC_NA0x00000000, &startSymbolId);
6080 }
6081 else if (sectionType != SEC_C_LAA) {
6082 /* startSymbolId is in most section types */
6083 ssid_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_start_symbol_id, tvb, offset, 1, ENC_NA0x00000000, &startSymbolId);
6084 if (startSymbolId && (sectionType == SEC_C_RRM_MEAS_REPORTS)) { /* Section Type 10 */
6085 proto_item_append_text(ssid_ti, " (should be 0 for ST10!)");
6086 expert_add_info_format(pinfo, ssid_ti, &ei_oran_st10_startsymbolid_not_0,
6087 "startSymbolId should be 0 for ST10 - found %u", startSymbolId);
6088 }
6089 }
6090 else {
6091 /* reserved (6 bits) */
6092 add_reserved_field(section_tree, hf_oran_reserved_last_6bits, tvb, offset, 1);
6093 }
6094 offset++;
6095
6096
6097 char id[16];
6098 snprintf(id, 16, "%u-%u-%u-%u", frameId, subframeId, slotId, startSymbolId);
6099 proto_item *pi = proto_tree_add_string(section_tree, hf_oran_refa, tvb, ref_a_offset, 3, id);
6100 proto_item_set_generated(pi);
6101
6102 uint32_t cmd_scope = 0;
6103 bool_Bool st8_ready = false0;
6104
6105 /* numberOfSections (or whatever section has instead) */
6106 uint32_t nSections = 0;
6107 if (sectionType == SEC_C_SLOT_CONTROL) { /* Section Type 4 */
6108 /* Slot Control has these fields instead */
6109 /* reserved (4 bits) */
6110 add_reserved_field(section_tree, hf_oran_reserved_4bits, tvb, offset, 1);
6111 /* cmdScope (4 bits) */
6112 proto_tree_add_item_ret_uint(section_tree, hf_oran_cmd_scope, tvb, offset, 1, ENC_NA0x00000000, &cmd_scope);
6113 }
6114 else if (sectionType == SEC_C_ACK_NACK_FEEDBACK) { /* Section Type 8 */
6115 /* reserved (7 bits) */
6116 add_reserved_field(section_tree, hf_oran_reserved_7bits, tvb, offset, 1);
6117 /* ready (1 bit) */
6118 /* TODO: when set, ready in slotId+1.. */
6119 proto_tree_add_item_ret_boolean(section_tree, hf_oran_ready, tvb, offset, 1, ENC_NA0x00000000, &st8_ready);
6120 if (!st8_ready) {
6121 /* SCS value is ignored, and may be set to any value by O-RU */
6122 proto_item_append_text(scs_ti, " (ignored)");
6123 }
6124 }
6125 else if (sectionType != SEC_C_LAA) {
6126 /* numberOfSections */
6127 proto_tree_add_item_ret_uint(section_tree, hf_oran_numberOfSections, tvb, offset, 1, ENC_NA0x00000000, &nSections);
6128 }
6129 else {
6130 add_reserved_field(section_tree, hf_oran_reserved_8bits, tvb, offset, 1);
6131 }
6132 offset++;
6133
6134 /* sectionType */
6135 proto_tree_add_item_ret_uint(section_tree, hf_oran_sectionType, tvb, offset, 1, ENC_NA0x00000000, &sectionType);
6136 offset += 1;
6137
6138 /* Check that dataDirection is consistent with section type */
6139 if (sectionType == SEC_C_SINR_REPORTING && direction != 0) { /* Section Type 9 */
6140 expert_add_info(pinfo, datadir_ti, &ei_oran_st9_not_ul);
6141 }
6142 if (sectionType == SEC_C_RRM_MEAS_REPORTS && direction != 0) { /* Section Type 10 */
6143 expert_add_info(pinfo, datadir_ti, &ei_oran_st10_not_ul);
6144 }
6145
6146 /* Note this section type in stats */
6147 if (sectionType < SEC_C_MAX_INDEX) {
6148 tap_info->section_types[sectionType] = true1;
6149 }
6150
6151 /* Section-type-specific fields following common header (white entries in Section Type diagrams) */
6152 unsigned bit_width = 0;
6153 unsigned comp_meth = 0;
6154 proto_item *comp_meth_ti;
6155 unsigned ci_comp_method = 0;
6156 uint8_t ci_comp_opt = 0;
6157
6158 uint32_t num_ues = 0;
6159 uint32_t number_of_acks = 0, number_of_nacks = 0;
6160
6161 uint32_t num_sinr_per_prb = 0;
6162
6163 switch (sectionType) {
6164 case SEC_C_UNUSED_RB: /* Section Type 0 */
6165 /* timeOffset */
6166 proto_tree_add_item(section_tree, hf_oran_timeOffset, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6167 offset += 2;
6168 /* frameStructure */
6169 offset = dissect_frame_structure(section_tree, tvb, offset,
6170 subframeId, slotId);
6171
6172 /* cpLength */
6173 proto_tree_add_item(section_tree, hf_oran_cpLength, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6174 offset += 2;
6175 /* reserved (8 bits) */
6176 add_reserved_field(section_tree, hf_oran_reserved_8bits, tvb, offset, 1);
6177 offset += 1;
6178 break;
6179
6180 case SEC_C_NORMAL: /* Section Type 1 */
6181 case SEC_C_UE_SCHED: /* Section Type 5 */
6182 /* udCompHdr */
6183 offset = dissect_udcomphdr(tvb, pinfo, section_tree, offset,
6184 true1, direction==0 && pref_override_ul_compression, /* ignore for DL or if using mplane for UL settings */
6185 &bit_width, &comp_meth, &comp_meth_ti, tap_info);
6186 /* reserved (8 bits) */
6187 add_reserved_field(section_tree, hf_oran_reserved_8bits, tvb, offset, 1);
6188 offset += 1;
6189 break;
6190
6191 case SEC_C_SLOT_CONTROL: /* Section Type 4 */
6192 break;
6193
6194 case SEC_C_PRACH: /* Section Type 3 */
6195 /* timeOffset */
6196 proto_tree_add_item(section_tree, hf_oran_timeOffset, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6197 offset += 2;
6198 /* frameStructure */
6199 offset = dissect_frame_structure(section_tree, tvb, offset,
6200 subframeId, slotId);
6201 /* cpLength */
6202 proto_tree_add_item(section_tree, hf_oran_cpLength, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6203 offset += 2;
6204 /* udCompHdr */
6205 offset = dissect_udcomphdr(tvb, pinfo, section_tree, offset,
6206 true1, direction==0 && pref_override_ul_compression, /* ignore for DL or if using mplane for UL settings */
6207 &bit_width, &comp_meth, &comp_meth_ti, tap_info);
6208 break;
6209
6210 case SEC_C_CH_INFO: /* Section Type 6 */
6211 /* numberOfUEs */
6212 proto_tree_add_item_ret_uint(section_tree, hf_oran_numberOfUEs, tvb, offset, 1, ENC_NA0x00000000, &num_ues);
6213 offset += 1;
6214 /* ciCompHdr (was reserved) */
6215 offset = dissect_cicomphdr(tvb, pinfo, section_tree, offset, &bit_width, &ci_comp_method, &ci_comp_opt);
6216
6217 /* Number of sections may not be filled in (at all, or correctly), so set to the number of UEs.
6218 The data entries are per-UE... they don't have a sectionID, but they could have section extensions... */
6219 if (nSections == 0 || num_ues > nSections) {
6220 nSections = num_ues;
6221 }
6222 break;
6223
6224 case SEC_C_RSVD2:
6225 break;
6226
6227 case SEC_C_LAA: /* Section Type 7 */
6228 add_reserved_field(section_tree, hf_oran_reserved_16bits, tvb, offset, 2);
6229 offset += 2;
6230 break;
6231
6232 case SEC_C_ACK_NACK_FEEDBACK: /* Section Type 8 */
6233 /* numberOfAcks (1 byte) */
6234 proto_tree_add_item_ret_uint(section_tree, hf_oran_number_of_acks, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &number_of_acks);
6235 offset += 1;
6236 /* numberOfNacks (1 byte) */
6237 proto_tree_add_item_ret_uint(section_tree, hf_oran_number_of_nacks, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &number_of_nacks);
6238 offset += 1;
6239
6240 /* Show ACKs and NACKs. For both, try to link back to request. */
6241 for (unsigned int n=1; n <= number_of_acks; n++) {
6242 uint32_t ackid;
6243 proto_item *ack_ti;
6244 ack_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_ackid, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &ackid);
6245 offset += 2;
6246
6247 /* Look up request table in state (which really should be set by now, but test anyway). */
6248 if (state && state->ack_nack_requests) {
6249 ack_nack_request_t *request = wmem_tree_lookup32(state->ack_nack_requests, ackid);
6250 if (request != NULL((void*)0)) {
6251 /* On first pass, update with this response */
6252 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
6253 request->response_frame_number = pinfo->num;
6254 request->response_frame_time = pinfo->abs_ts;
6255 }
6256
6257 /* Show request details */
6258 show_link_to_acknack_request(section_tree, tvb, pinfo, request);
6259 }
6260 else {
6261 /* Request not found */
6262 expert_add_info_format(pinfo, ack_ti, &ei_oran_acknack_no_request,
6263 "Response for ackId=%u received, but no request found",
6264 ackid);
6265 }
6266 }
6267 }
6268 for (unsigned int m=1; m <= number_of_nacks; m++) {
6269 uint32_t nackid;
6270 proto_item *nack_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_nackid, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &nackid);
6271 offset += 2;
6272
6273 expert_add_info_format(pinfo, nack_ti, &ei_oran_st8_nackid,
6274 "Received Nack for ackNackId=%u",
6275 nackid);
6276
6277 /* Look up request table in state. */
6278 if (state && state->ack_nack_requests) {
6279 ack_nack_request_t *request = wmem_tree_lookup32(state->ack_nack_requests, nackid);
6280 if (request) {
6281 /* On first pass, update with this response */
6282 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
6283 request->response_frame_number = pinfo->num;
6284 request->response_frame_time = pinfo->abs_ts;
6285 }
6286
6287 /* Show request details */
6288 show_link_to_acknack_request(section_tree, tvb, pinfo, request);
6289 }
6290 else {
6291 /* Request not found */
6292 expert_add_info_format(pinfo, nack_ti, &ei_oran_acknack_no_request,
6293 "Response for nackId=%u received, but no request found",
6294 nackid);
6295 }
6296 }
6297 }
6298 break;
6299
6300 case SEC_C_SINR_REPORTING: /* Section Type 9 */
6301 {
6302 /* numSinrPerPrb (3 bits) */
6303 proto_item *nspp_ti;
6304 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);
6305 switch (num_sinr_per_prb) {
6306 case 0:
6307 num_sinr_per_prb = 1; break;
6308 case 1:
6309 num_sinr_per_prb = 2; break;
6310 case 2:
6311 num_sinr_per_prb = 3; break;
6312 case 3:
6313 num_sinr_per_prb = 4; break;
6314 case 4:
6315 num_sinr_per_prb = 6; break;
6316 case 5:
6317 num_sinr_per_prb = 12; break;
6318
6319 default:
6320 proto_item_append_text(nspp_ti, " (invalid)");
6321 num_sinr_per_prb = 1;
6322 expert_add_info_format(pinfo, nspp_ti, &ei_oran_num_sinr_per_prb_unknown,
6323 "Invalid numSinrPerPrb value (%u)",
6324 num_sinr_per_prb);
6325 }
6326
6327 /* oruControlSinrSlotMaskId (5 bits) */
6328 proto_tree_add_item(section_tree, hf_oran_oru_control_sinr_slot_mask_id, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6329 offset += 1;
6330 /* reserved (8 bits) */
6331 add_reserved_field(section_tree, hf_oran_reserved_8bits, tvb, offset, 1);
6332 offset += 1;
6333 break;
6334 }
6335
6336 case SEC_C_RRM_MEAS_REPORTS: /* Section Type 10 */
6337 case SEC_C_REQUEST_RRM_MEAS: /* Section Type 11 */
6338 /* reserved (16 bits) */
6339 add_reserved_field(section_tree, hf_oran_reserved_16bits, tvb, offset, 2);
6340 offset += 2;
6341 break;
6342 };
6343
6344 /* Update udCompHdr details in state for UL U-Plane */
6345 if (state && direction==0) {
6346 switch (sectionType) {
6347 case SEC_C_NORMAL: /* Section Type 1 */
6348 case SEC_C_PRACH: /* Section Type 3 */
6349 case SEC_C_UE_SCHED: /* Section Type 5 */
6350 state->ul_ud_comp_hdr_set = true1;
6351 state->ul_ud_comp_hdr_bit_width = bit_width;
6352 state->ul_ud_comp_hdr_compression = comp_meth;
6353 state->ul_ud_comp_hdr_frame = pinfo->num;
6354 break;
6355 default:
6356 break;
6357 }
6358 }
6359
6360
6361 proto_item_append_text(sectionHeading, "%d, %s, frameId: %d, subframeId: %d, slotId: %d, startSymbolId: %d",
6362 sectionType, val_to_str_const(direction, data_direction_vals, "Unknown"),
6363 frameId, subframeId, slotId, startSymbolId);
6364 if (nSections) {
6365 proto_item_append_text(sectionHeading, ", numberOfSections=%u", nSections);
6366 }
6367
6368 write_pdu_label_and_info(protocol_item, NULL((void*)0), pinfo, ", Type: %2d %s", sectionType,
6369 rval_to_str_const(sectionType, section_types_short, "Unknown"));
6370
6371 /* Set actual length of C-Plane section header */
6372 proto_item_set_len(section_tree, offset - section_tree_offset);
6373
6374 if (sectionType == SEC_C_ACK_NACK_FEEDBACK) {
6375 write_pdu_label_and_info(oran_tree, section_tree, pinfo,
6376 (st8_ready) ? " (Ready)" : " (ACK)");
6377 }
6378
6379
6380 /* Section type 4 doesn't have normal sections, so deal with here before normal sections */
6381 if (sectionType == SEC_C_SLOT_CONTROL) {
6382 /* numberOfST4Cmds */
6383 uint32_t no_st4_cmds, st4_cmd_len, num_slots, ack_nack_req_id, st4_cmd_type;
6384 proto_item *no_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_number_of_st4_cmds,
6385 tvb, offset, 1, ENC_NA0x00000000, &no_st4_cmds);
6386 if (no_st4_cmds == 0) {
6387 expert_add_info(pinfo, no_ti, &ei_oran_st4_no_cmds);
6388 }
6389 offset += 1;
6390
6391 /* reserved (1 byte) */
6392 add_reserved_field(section_tree, hf_oran_reserved_8bits, tvb, offset, 1);
6393 offset += 1;
6394
6395 /* Loop over commands. Each has 8-byte common header, followed by cmd-specific payload */
6396 proto_item *len_ti;
6397 for (uint32_t n=0; n < no_st4_cmds; n++) {
6398 /* Table 7.4.6-2: Section Type 4 Command common header format */
6399 proto_item *hdr_ti = proto_tree_add_string_format(section_tree, hf_oran_st4_cmd_header,
6400 tvb, offset, 8, "",
6401 "Type 4 Command common header");
6402 proto_tree *hdr_tree = proto_item_add_subtree(hdr_ti, ett_oran_st4_cmd_header);
6403
6404 /* st4CmdType */
6405 proto_tree_add_item_ret_uint(hdr_tree, hf_oran_st4_cmd_type, tvb, offset, 1, ENC_NA0x00000000, &st4_cmd_type);
6406 offset += 1;
6407
6408 /* st4CmdLen */
6409 len_ti = proto_tree_add_item_ret_uint(hdr_tree, hf_oran_st4_cmd_len, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &st4_cmd_len);
6410 if (st4_cmd_len == 0) {
6411 /* Meaning of 0 not yet defined (v15.00) */
6412 proto_item_append_text(len_ti, " (reserved)");
6413 expert_add_info(pinfo, len_ti, &ei_oran_st4_zero_len_cmd);
6414 }
6415 else {
6416 proto_item_append_text(len_ti, " (%u bytes)", st4_cmd_len*4);
6417 }
6418 offset += 2;
6419
6420 /* numSlots */
6421 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);
6422 if (num_slots == 0) {
6423 proto_item_append_text(slots_ti, " (until changed)");
6424 }
6425 offset += 1;
6426
6427 /* ackNackReqId */
6428 proto_item *ack_nack_req_id_ti;
6429 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);
6430 offset += 2;
6431 if (ack_nack_req_id == 0) {
6432 proto_item_append_text(ack_nack_req_id_ti, " (no Section type 8 response expected)");
6433 }
6434
6435 /* reserved (16 bits) */
6436 add_reserved_field(hdr_tree, hf_oran_reserved_16bits, tvb, offset, 2);
6437 offset += 2;
6438
6439 /* Set common header summary */
6440 proto_item_append_text(hdr_ti, " (cmd=%s, len=%u, slots=%u, ackNackReqId=%u)",
6441 rval_to_str_const(st4_cmd_type, st4_cmd_type_vals, "Unknown"),
6442 st4_cmd_len, num_slots, ack_nack_req_id);
6443
6444 col_append_fstr(pinfo->cinfo, COL_INFO, " (%s)",
6445 rval_to_str_const(st4_cmd_type, st4_cmd_type_vals, "Unknown"));
6446
6447
6448 /* Subtree for this command body */
6449 proto_item *command_ti = proto_tree_add_string_format(section_tree, hf_oran_st4_cmd,
6450 tvb, offset, 0, "",
6451 "Type 4 Command (%s)", rval_to_str_const(st4_cmd_type, st4_cmd_type_vals, "Unknown"));
6452 proto_tree *command_tree = proto_item_add_subtree(command_ti, ett_oran_st4_cmd);
6453
6454 unsigned command_start_offset = offset;
6455
6456 /* Check fields compatible with chosen command. */
6457 if (st4_cmd_type==1) {
6458 if (num_slots != 0) {
6459 /* "the value of numSlots should be set to zero for this command type" */
6460 expert_add_info_format(pinfo, slots_ti, &ei_oran_numslots_not_zero,
6461 "numSlots should be zero for ST4 command 1 - found %u",
6462 num_slots);
6463 }
6464 }
6465
6466 if (st4_cmd_type==3 || st4_cmd_type==4) {
6467 if (startSymbolId != 0) {
6468 /* "expected reception window for the commands is the symbol zero reception window" */
6469 expert_add_info_format(pinfo, ssid_ti, &ei_oran_start_symbol_id_not_zero,
6470 "startSymbolId should be zero for ST4 commands 3&4 - found %u",
6471 startSymbolId);
6472 }
6473 }
6474
6475 /* Add format for this command */
6476 switch (st4_cmd_type) {
6477 case 1: /* TIME_DOMAIN_BEAM_CONFIG */
6478 {
6479 bool_Bool disable_tdbfns;
6480 uint32_t bfwcomphdr_iq_width, bfwcomphdr_comp_meth;
6481
6482 /* Hidden filter for bf */
6483 proto_item *bf_ti = proto_tree_add_item(command_tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
6484 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
6485
6486 /* reserved (2 bits) */
6487 add_reserved_field(command_tree, hf_oran_reserved_2bits, tvb, offset, 1);
6488 /* symbolMask (14 bits) */
6489 uint32_t symbol_mask;
6490 proto_item *symbol_mask_ti;
6491 offset = dissect_symbolmask(tvb, command_tree, offset, &symbol_mask, &symbol_mask_ti);
6492 /* 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 */
6493 /* lsb is symbol 0 */
6494 for (unsigned s=0; s < 14; s++) {
6495 if ((startSymbolId & (1 << s)) && (startSymbolId > s)) {
6496 proto_item_append_text(symbol_mask_ti, " (startSymbolId is %u, so some lower symbol bits ignored!)", startSymbolId);
6497 expert_add_info(pinfo, symbol_mask_ti, &ei_oran_start_symbol_id_bits_ignored);
6498 break;
6499 }
6500 }
6501
6502 /* disableTDBFNs (1 bit) */
6503 proto_tree_add_item_ret_boolean(command_tree, hf_oran_disable_tdbfns, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &disable_tdbfns);
6504
6505 /* tdBeamNum (15 bits) */
6506 proto_tree_add_item(command_tree, hf_oran_td_beam_num, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6507 offset += 2;
6508
6509 /* bfwCompHdr (2 subheaders - bfwIqWidth and bfwCompMeth)*/
6510 offset = dissect_bfwCompHdr(tvb, command_tree, offset,
6511 &bfwcomphdr_iq_width, &bfwcomphdr_comp_meth, &comp_meth_ti);
6512 /* reserved (3 bytes) */
6513 proto_tree_add_bits_item(command_tree, hf_oran_reserved, tvb, offset*8, 24, ENC_BIG_ENDIAN0x00000000);
6514 offset += 3;
6515
6516 if (disable_tdbfns) {
6517 /* No beamnum information to show so get out. */
6518 break;
6519 }
6520
6521 /* Read beam entries until reach end of command length */
6522 while ((offset - command_start_offset) < (st4_cmd_len * 4)) {
6523
6524 /* disableTDBFWs (1 bit) */
6525 bool_Bool disable_tdbfws;
6526 proto_tree_add_item_ret_boolean(command_tree, hf_oran_disable_tdbfws, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &disable_tdbfws);
6527
6528 /* tdBeamNum (15 bits) */
6529 proto_tree_add_item(command_tree, hf_oran_td_beam_num, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6530 offset += 2;
6531
6532 /* Showing BFWs? */
6533 if (!disable_tdbfws) {
6534
6535 /* bfwCompParam */
6536 unsigned exponent = 0;
6537 bool_Bool supported = false0;
6538 unsigned num_trx_entries;
6539 uint16_t *trx_entries;
6540 offset = dissect_bfwCompParam(tvb, command_tree, pinfo, offset, comp_meth_ti,
6541 &bfwcomphdr_comp_meth, &exponent, &supported,
6542 &num_trx_entries, &trx_entries);
6543
6544 /* Antenna count from preference */
6545 unsigned num_trx = pref_num_bf_antennas;
6546 int bit_offset = offset*8;
6547
6548 for (unsigned trx=0; trx < num_trx; trx++) {
6549 /* Create antenna subtree */
6550 int bfw_offset = bit_offset / 8;
6551 proto_item *bfw_ti = proto_tree_add_string_format(command_tree, hf_oran_bfw,
6552 tvb, bfw_offset, 0, "", "TRX %3u: (", trx);
6553 proto_tree *bfw_tree = proto_item_add_subtree(bfw_ti, ett_oran_bfw);
6554
6555 /* I value */
6556 /* Get bits, and convert to float. */
6557 uint32_t bits = tvb_get_bits32(tvb, bit_offset, bfwcomphdr_iq_width, ENC_BIG_ENDIAN0x00000000);
6558 float value = decompress_value(bits, bfwcomphdr_comp_meth, bfwcomphdr_iq_width, exponent, NULL((void*)0) /* no ModCompr*/, 0 /* RE */);
6559 /* Add to tree. */
6560 proto_tree_add_float(bfw_tree, hf_oran_bfw_i, tvb, bit_offset/8,
6561 (bfwcomphdr_iq_width+7)/8, value);
6562 bit_offset += bfwcomphdr_iq_width;
6563 proto_item_append_text(bfw_ti, "I=%f ", value);
6564
6565 /* Leave a gap between I and Q values */
6566 proto_item_append_text(bfw_ti, " ");
6567
6568 /* Q value */
6569 /* Get bits, and convert to float. */
6570 bits = tvb_get_bits32(tvb, bit_offset, bfwcomphdr_iq_width, ENC_BIG_ENDIAN0x00000000);
6571 value = decompress_value(bits, bfwcomphdr_comp_meth, bfwcomphdr_iq_width, exponent, NULL((void*)0) /* no ModCompr*/, 0 /* RE */);
6572 /* Add to tree. */
6573 proto_tree_add_float(bfw_tree, hf_oran_bfw_q, tvb, bit_offset/8,
6574 (bfwcomphdr_iq_width+7)/8, value);
6575 bit_offset += bfwcomphdr_iq_width;
6576 proto_item_append_text(bfw_ti, "Q=%f", value);
6577
6578 proto_item_append_text(bfw_ti, ")");
6579 proto_item_set_len(bfw_ti, (bit_offset+7)/8 - bfw_offset);
6580 }
6581 /* Need to round to next byte */
6582 offset = (bit_offset+7)/8;
6583 }
6584 }
6585 break;
6586 }
6587 case 2: /* TDD_CONFIG_PATTERN */
6588 /* reserved (2 bits) */
6589 add_reserved_field(command_tree, hf_oran_reserved_2bits, tvb, offset, 1);
6590 /* dirPattern (14 bits) */
6591 proto_tree_add_item(command_tree, hf_oran_dir_pattern, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6592 offset += 2;
6593
6594 /* reserved (2 bits) */
6595 add_reserved_field(command_tree, hf_oran_reserved_2bits, tvb, offset, 1);
6596 /* guardPattern (14 bits) */
6597 proto_tree_add_item(command_tree, hf_oran_guard_pattern, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6598 offset += 2;
6599 break;
6600
6601 case 3: /* TRX_CONTROL */
6602 case 5: /* TRX_CONTROL_BIDIR */
6603 {
6604 /* Only allowed cmdScope is ARRAY-COMMAND */
6605 if (cmd_scope != 0) {
6606 expert_add_info(pinfo, command_tree, &ei_oran_trx_control_cmd_scope);
6607 }
6608
6609 /* reserved (2 bits) */
6610 add_reserved_field(command_tree, hf_oran_reserved_2bits, tvb, offset, 1);
6611 /* log2MaskBits (4 bits) */
6612 unsigned log2maskbits;
6613 proto_tree_add_item_ret_uint(command_tree, hf_oran_log2maskbits, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &log2maskbits);
6614 /* sleepMode (2 bits) */
6615 uint32_t sleep_mode;
6616 proto_tree_add_item_ret_uint(command_tree, hf_oran_sleepmode_trx, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &sleep_mode);
6617 offset += 1;
6618
6619 /* reserved (4 bits) */
6620 add_reserved_field(command_tree, hf_oran_reserved_4bits, tvb, offset, 1);
6621 /* numSlotsExt (20 bits) */
6622 uint32_t num_slots_ext;
6623 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);
6624 if (num_slots==0 && num_slots_ext==0) {
6625 proto_item_append_text(num_slots_ext_ti, " (undefined sleep period)");
6626 }
6627 else {
6628 /* Time should be rounded up according to SCS */
6629 float total = (float)(num_slots + num_slots_ext);
6630 /* From table 7.5.2.13-3 */
6631 const float slot_length_by_scs[16] = { 1000, 500, 250, 125, 62.5, 31.25,
6632 0, 0, 0, 0, 0, 0, /* reserved */
6633 1000, 1000, 1000, 1000 };
6634 float slot_length = slot_length_by_scs[scs];
6635 /* Only using valid SCS. TODO: is this test ok? */
6636 if (slot_length != 0) {
6637 /* Round up to next slot */
6638 total = ((int)(total / slot_length) + 1) * slot_length;
6639 proto_item_append_text(num_slots_ext_ti, " (defined sleep period of %f us)", total);
6640 }
6641 }
6642 offset += 3;
6643
6644 /* reserved (2 bits) */
6645 add_reserved_field(command_tree, hf_oran_reserved_2bits, tvb, offset, 1);
6646
6647 /* symbolMask (14 bits) */
6648 uint32_t symbol_mask;
6649 proto_item *sm_ti;
6650 offset = dissect_symbolmask(tvb, command_tree, offset, &symbol_mask, &sm_ti);
6651 if (symbol_mask == 0x0) {
6652 proto_item_append_text(sm_ti, " (wake)");
6653 col_append_str(pinfo->cinfo, COL_INFO, " (wake)");
6654 }
6655 else if (symbol_mask == 0x3fff) {
6656 proto_item_append_text(sm_ti, " (sleep)");
6657 col_append_str(pinfo->cinfo, COL_INFO, " (sleep)");
6658 }
6659 else {
6660 expert_add_info_format(pinfo, sm_ti, &ei_oran_bad_symbolmask,
6661 "For non-zero sleepMode (%u), symbolMask should be 0x0 or 0x3fff - found 0x%05x",
6662 sleep_mode, symbol_mask);
6663 }
6664 offset += 2;
6665
6666 /* antMask (16-2048 bits). Size is lookup from log2MaskBits enum.. */
6667 unsigned antmask_length = 2;
6668 if (log2maskbits >= 4) {
6669 antmask_length = (1 << log2maskbits) / 8;
6670 }
6671 proto_item *ant_mask_ti = proto_tree_add_item(command_tree, hf_oran_antMask_trx_control, tvb, offset, antmask_length, ENC_NA0x00000000);
6672 /* show count */
6673 unsigned antenna_count = 0;
6674 for (unsigned b=0; b < antmask_length; b++) {
6675 uint8_t byte = tvb_get_uint8(tvb, offset+b);
6676 for (unsigned bit=0; bit < 8; bit++) {
6677 if ((1 << bit) & byte) {
6678 antenna_count++;
6679 }
6680 }
6681 }
6682 proto_item_append_text(ant_mask_ti, " (%u antennas)", antenna_count);
6683 offset += antmask_length;
6684
6685 /* Pad to next 4-byte boundary */
6686 offset = WS_ROUNDUP_4(offset)(((offset) + ((unsigned)(4U-1U))) & (~((unsigned)(4U-1U))
))
;
6687 break;
6688 }
6689
6690 case 4: /* ASM (advanced sleep mode) */
6691 /* reserved (2+4=6 bits) */
6692 add_reserved_field(command_tree, hf_oran_reserved_6bits, tvb, offset, 1);
6693 /* sleepMode (2 bits) */
6694 uint32_t sleep_mode;
6695 proto_tree_add_item_ret_uint(command_tree, hf_oran_sleepmode_asm, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &sleep_mode);
6696 offset += 1;
6697
6698 /* reserved (4 bits) */
6699 add_reserved_field(command_tree, hf_oran_reserved_4bits, tvb, offset, 1);
6700 /* numSlotsExt (20 bits) */
6701 proto_tree_add_item(command_tree, hf_oran_num_slots_ext, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6702 offset += 3;
6703
6704 /* reserved (2 bits) */
6705 add_reserved_field(command_tree, hf_oran_reserved_2bits, tvb, offset, 1);
6706 /* symbolMask (14 bits) */
6707 uint32_t symbol_mask;
6708 proto_item *sm_ti;
6709 offset = dissect_symbolmask(tvb, command_tree, offset, &symbol_mask, &sm_ti);
6710 if (symbol_mask == 0x0) {
6711 proto_item_append_text(sm_ti, " (wake)");
6712 col_append_str(pinfo->cinfo, COL_INFO, " (wake)");
6713 }
6714 else if (symbol_mask == 0x3fff) {
6715 proto_item_append_text(sm_ti, " (sleep)");
6716 col_append_str(pinfo->cinfo, COL_INFO, " (sleep)");
6717 }
6718 else {
6719 expert_add_info_format(pinfo, sm_ti, &ei_oran_bad_symbolmask,
6720 "For non-zero sleepMode (%u), symbolMask should be 0x0 or 0x3fff - found 0x%05x",
6721 sleep_mode, symbol_mask);
6722 }
6723 offset += 2;
6724
6725 /* reserved (2 bytes) */
6726 add_reserved_field(command_tree, hf_oran_reserved_16bits, tvb, offset, 2);
6727 offset += 2;
6728 break;
6729
6730 default:
6731 /* Error! */
6732 expert_add_info_format(pinfo, len_ti, &ei_oran_st4_unknown_cmd,
6733 "Dissected ST4 command (%u) not recognised",
6734 st4_cmd_type);
6735 break;
6736 }
6737
6738 /* Check apparent size of padding (0-3 bytes ok) */
6739 long padding_remaining = command_start_offset + (st4_cmd_len * 4) - offset;
6740 if (padding_remaining > 3) {
6741 expert_add_info_format(pinfo, len_ti, &ei_oran_st4_wrong_len_cmd,
6742 "Dissected ST4 command does not match signalled st4CmdLen - set to %u (%u bytes) but dissected %u bytes",
6743 st4_cmd_len, st4_cmd_len*4, offset-command_start_offset);
6744 }
6745
6746 /* Advance by signalled length (needs to be aligned on 4-byte boundary) */
6747 offset = command_start_offset + (st4_cmd_len * 4);
6748
6749 /* Set end of command tree */
6750 proto_item_set_end(command_ti, tvb, offset);
6751
6752 if (ack_nack_req_id != 0 && state && state->ack_nack_requests) {
6753 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
6754 /* Add this request into conversation state on first pass */
6755 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)))
;
6756 request_details->request_frame_number = pinfo->num;
6757 request_details->request_frame_time = pinfo->abs_ts;
6758 request_details->requestType = ST4Cmd1+st4_cmd_type-1;
6759
6760 wmem_tree_insert32(state->ack_nack_requests,
6761 ack_nack_req_id,
6762 request_details);
6763 }
6764 else {
6765 /* On later passes, try to link forward to ST8 response */
6766 ack_nack_request_t *response = wmem_tree_lookup32(state->ack_nack_requests,
6767 ack_nack_req_id);
6768 if (response) {
6769 show_link_to_acknack_response(section_tree, tvb, pinfo, response);
6770 }
6771 }
6772 }
6773 }
6774 }
6775 /* LAA doesn't have sections either.. */
6776 else if (sectionType == SEC_C_LAA) { /* Section Type 7 */
6777 /* 7.2.5 Table 6.4-6 */
6778 unsigned mcot;
6779 proto_item *mcot_ti;
6780
6781 /* laaMsgType */
6782 uint32_t laa_msg_type;
6783 proto_item *laa_msg_type_ti;
6784 laa_msg_type_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_laaMsgType, tvb, offset, 1, ENC_NA0x00000000, &laa_msg_type);
6785 /* laaMsgLen */
6786 uint32_t laa_msg_len;
6787 proto_item *len_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_laaMsgLen, tvb, offset, 1, ENC_NA0x00000000, &laa_msg_len);
6788 proto_item_append_text(len_ti, " (%u bytes)", 4*laa_msg_len);
6789 if (laa_msg_len == 0) {
6790 proto_item_append_text(len_ti, " (reserved)");
6791 }
6792 offset += 1;
6793
6794 int payload_offset = offset;
6795
6796 /* Payload */
6797 switch (laa_msg_type) {
6798 case 0:
6799 /* LBT_PDSCH_REQ */
6800 /* lbtHandle (16 bits) */
6801 proto_tree_add_item(section_tree, hf_oran_lbtHandle, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6802 offset += 2;
6803 /* lbtOffset (10 bits) */
6804 proto_tree_add_item(section_tree, hf_oran_lbtOffset, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6805 offset += 1;
6806 /* lbtMode (2 bits) */
6807 proto_tree_add_bits_item(section_tree, hf_oran_lbtMode, tvb, offset*8+2, 2, ENC_BIG_ENDIAN0x00000000);
6808 /* reserved (1 bit) */
6809 add_reserved_field(section_tree, hf_oran_reserved_bit4, tvb, offset, 1);
6810 /* lbtDeferFactor (3 bits) */
6811 proto_tree_add_item(section_tree, hf_oran_lbtDeferFactor, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6812 offset += 1;
6813 /* lbtBackoffCounter (10 bits) */
6814 proto_tree_add_item(section_tree, hf_oran_lbtBackoffCounter, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6815 offset += 1;
6816 /* MCOT (4 bits) */
6817 mcot_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_MCOT, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &mcot);
6818 if (mcot<1 || mcot>10) {
6819 proto_item_append_text(mcot_ti, " (should be in range 1-10!)");
6820 expert_add_info_format(pinfo, mcot_ti, &ei_oran_mcot_out_of_range,
6821 "MCOT seen with value %u (must be 1-10)", mcot);
6822
6823 }
6824 /* reserved (10 bits) */
6825 proto_tree_add_bits_item(section_tree, hf_oran_reserved, tvb, (offset*8)+6, 10, ENC_BIG_ENDIAN0x00000000);
6826 break;
6827 case 1:
6828 /* LBT_DRS_REQ */
6829 /* lbtHandle (16 bits) */
6830 proto_tree_add_item(section_tree, hf_oran_lbtHandle, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6831 offset += 2;
6832 /* lbtOffset (10 bits) */
6833 proto_tree_add_item(section_tree, hf_oran_lbtOffset, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6834 offset += 1;
6835 /* lbtMode (2 bits) */
6836 proto_tree_add_bits_item(section_tree, hf_oran_lbtMode, tvb, offset*8+2, 2, ENC_BIG_ENDIAN0x00000000);
6837 /* reserved (28 bits) */
6838 proto_tree_add_bits_item(section_tree, hf_oran_reserved, tvb, (offset*8)+4, 28, ENC_BIG_ENDIAN0x00000000);
6839 break;
6840 case 2:
6841 /* LBT_PDSCH_RSP */
6842 /* lbtHandle (16 bits) */
6843 proto_tree_add_item(section_tree, hf_oran_lbtHandle, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6844 offset += 2;
6845 /* lbtPdschRes (2 bits) */
6846 proto_tree_add_item(section_tree, hf_oran_lbtPdschRes, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6847 /* inParSF (1 bit) */
6848 proto_tree_add_item(section_tree, hf_oran_initialPartialSF, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6849 /* sfStatus (1 bit) */
6850 proto_tree_add_item(section_tree, hf_oran_sfStatus, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6851 /* sfnSf (12 bits) */
6852 proto_tree_add_item(section_tree, hf_oran_sfnSfEnd, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6853 offset += 2;
6854 /* reserved (24 bits) */
6855 proto_tree_add_bits_item(section_tree, hf_oran_reserved, tvb, (offset*8), 24, ENC_BIG_ENDIAN0x00000000);
6856 break;
6857 case 3:
6858 /* LBT_DRS_RSP */
6859 /* lbtHandle (16 bits) */
6860 proto_tree_add_item(section_tree, hf_oran_lbtHandle, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6861 offset += 2;
6862 /* lbtDrsRes (1 bit) */
6863 proto_tree_add_item(section_tree, hf_oran_lbtDrsRes, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6864 /* reserved (7 bits) */
6865 add_reserved_field(section_tree, hf_oran_reserved_last_7bits, tvb, offset, 1);
6866 break;
6867 case 4:
6868 /* LBT_Buffer_Error */
6869 /* lbtHandle (16 bits) */
6870 proto_tree_add_item(section_tree, hf_oran_lbtHandle, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6871 offset += 2;
6872 /* lbtBufErr (1 bit) */
6873 proto_tree_add_item(section_tree, hf_oran_lbtBufErr, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6874 /* reserved (7 bits) */
6875 add_reserved_field(section_tree, hf_oran_reserved_last_7bits, tvb, offset, 1);
6876 break;
6877 case 5:
6878 /* LBT_CWCONFIG_REQ */
6879 /* lbtHandle (16 bits) */
6880 proto_tree_add_item(section_tree, hf_oran_lbtHandle, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6881 offset += 2;
6882 /* lbtCWConfig_H (8 bits) */
6883 proto_tree_add_item(section_tree, hf_oran_lbtCWConfig_H, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6884 offset += 1;
6885 /* lbtCWConfig_T (8 bits) */
6886 proto_tree_add_item(section_tree, hf_oran_lbtCWConfig_T, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6887 offset += 1;
6888 /* lbtMode (2 bits) */
6889 proto_tree_add_bits_item(section_tree, hf_oran_lbtMode, tvb, offset*8, 2, ENC_BIG_ENDIAN0x00000000);
6890 /* lbtTrafficClass (3 bits) */
6891 proto_tree_add_item(section_tree, hf_oran_lbtTrafficClass, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6892 /* reserved (19 bits) */
6893 proto_tree_add_bits_item(section_tree, hf_oran_reserved, tvb, (offset*8)+5, 19, ENC_BIG_ENDIAN0x00000000);
6894 break;
6895 case 6:
6896 /* LBT_CWCONFIG_RSP */
6897 /* lbtHandle (16 bits) */
6898 proto_tree_add_item(section_tree, hf_oran_lbtHandle, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6899 offset += 2;
6900 /* lbtCWR_Rst (1 bit) */
6901 proto_tree_add_item(section_tree, hf_oran_lbtCWR_Rst, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6902 /* reserved (7 bits) */
6903 add_reserved_field(section_tree, hf_oran_reserved_last_7bits, tvb, offset, 1);
6904 break;
6905
6906 default:
6907 /* Unhandled! */
6908 expert_add_info_format(pinfo, laa_msg_type_ti, &ei_oran_laa_msg_type_unsupported,
6909 "laaMsgType %u not supported by dissector",
6910 laa_msg_type);
6911
6912 break;
6913 }
6914 /* For now just skip indicated length of bytes */
6915 offset = payload_offset + 4*(laa_msg_len+1);
6916 }
6917
6918
6919 /* Dissect each C section */
6920 for (uint32_t i = 0; i < nSections; ++i) {
6921 tvbuff_t *section_tvb = tvb_new_subset_remaining(tvb, offset);
6922 offset += dissect_oran_c_section(section_tvb, oran_tree, pinfo, state, sectionType, tap_info,
6923 protocol_item,
6924 subframeId, frameId, slotId, startSymbolId,
6925 bit_width, ci_comp_method, ci_comp_opt,
6926 num_sinr_per_prb);
6927 }
6928
6929 /* Expert error if we are short of tvb by > 3 bytes */
6930 if (tvb_reported_length_remaining(tvb, offset) > 3) {
6931 expert_add_info_format(pinfo, protocol_item, &ei_oran_frame_length,
6932 "%u bytes remain at end of frame - should be 0-3",
6933 tvb_reported_length_remaining(tvb, offset));
6934 }
6935
6936 if (PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
6937 /* Show list of frames that have corresponding U-plane data */
6938 wmem_list_frame_t *list_frame;
6939 for (list_frame = wmem_list_head(result->u_plane_frames); list_frame != NULL((void*)0); list_frame = wmem_list_frame_next(list_frame)) {
6940 corresponding_uplane_frame *frame = wmem_list_frame_data(list_frame);
6941 proto_item *uplane_frame_ti = proto_tree_add_uint(oran_tree, hf_oran_corresponding_uplane_frame, tvb, 0, 0,
6942 frame->frame_number);
6943 proto_item_append_text(uplane_frame_ti, " sectionId:%u (in %uus)", frame->sectionId, frame->gap_in_usecs);
6944 proto_item_set_generated(uplane_frame_ti);
6945 }
6946 }
6947
6948 return tvb_captured_length(tvb);
6949}
6950
6951static int dissect_oran_u_re(tvbuff_t *tvb, proto_tree *tree,
6952 unsigned sample_number, int samples_offset,
6953 oran_tap_info *tap_info,
6954 unsigned sample_bit_width,
6955 int comp_meth,
6956 uint32_t exponent,
6957 section_mod_compr_config_t *mod_compr_params,
6958 uint8_t re)
6959{
6960 /* I */
6961 unsigned i_bits = tvb_get_bits32(tvb, samples_offset, sample_bit_width, ENC_BIG_ENDIAN0x00000000);
6962 float i_value = decompress_value(i_bits, comp_meth, sample_bit_width, exponent, mod_compr_params, re);
6963 unsigned sample_len_in_bytes = ((samples_offset%8)+sample_bit_width+7)/8;
6964 proto_item *i_ti = proto_tree_add_float(tree, hf_oran_iSample, tvb, samples_offset/8, sample_len_in_bytes, i_value);
6965 proto_item_set_text(i_ti, "iSample: % 0.7f 0x%04x (RE-%2u in the PRB)", i_value, i_bits, sample_number);
6966 samples_offset += sample_bit_width;
6967 /* Q */
6968 unsigned q_bits = tvb_get_bits32(tvb, samples_offset, sample_bit_width, ENC_BIG_ENDIAN0x00000000);
6969 float q_value = decompress_value(q_bits, comp_meth, sample_bit_width, exponent, mod_compr_params, re);
6970 sample_len_in_bytes = ((samples_offset%8)+sample_bit_width+7)/8;
6971 proto_item *q_ti = proto_tree_add_float(tree, hf_oran_qSample, tvb, samples_offset/8, sample_len_in_bytes, q_value);
6972 proto_item_set_text(q_ti, "qSample: % 0.7f 0x%04x (RE-%2u in the PRB)", q_value, q_bits, sample_number);
6973 samples_offset += sample_bit_width;
6974
6975 /* Update RE stats */
6976 tap_info->num_res++;
6977 /* if (i_value == 0.0 && q_value == 0.0) { */
6978 /* TODO: is just checking bits from frame good enough - assuming this always corresponds to a zero value? */
6979 if (i_bits == 0 && q_bits == 0) {
6980 tap_info->num_res_zero++;
6981 }
6982 else {
6983 tap_info->non_zero_re_in_current_prb = true1;
6984 }
6985 return samples_offset;
6986}
6987
6988
6989static bool_Bool udcomplen_appears_present(bool_Bool udcomphdr_present, tvbuff_t *tvb, int offset)
6990{
6991 if (!udcomplen_heuristic_result_set) {
6992 /* All sections will start the same way */
6993 unsigned int section_bytes_before_field = (udcomphdr_present) ? 6 : 4;
6994
6995 /* Move offset back to the start of the section */
6996 offset -= section_bytes_before_field;
6997
6998 do {
6999 /* This field appears several bytes into the U-plane section */
7000 uint32_t length_remaining = tvb_reported_length_remaining(tvb, offset);
7001 /* Are there enough bytes to still read the length field? */
7002 if (section_bytes_before_field+2 > length_remaining) {
7003 udcomplen_heuristic_result = false0;
7004 udcomplen_heuristic_result_set = true1;
7005 break;
7006 }
7007
7008 /* Read the length field */
7009 uint16_t udcomplen = tvb_get_ntohs(tvb, offset+section_bytes_before_field);
7010
7011 /* Is this less than a valid section? Realistic minimal section will be bigger than this..
7012 * Could take into account numPrbU, etc */
7013 if (udcomplen < section_bytes_before_field+2) {
7014 udcomplen_heuristic_result = false0;
7015 udcomplen_heuristic_result_set = true1;
7016 break;
7017 }
7018
7019 /* Does this section fit into the frame? */
7020 if (udcomplen > length_remaining) {
7021 udcomplen_heuristic_result = false0;
7022 udcomplen_heuristic_result_set = true1;
7023 break;
7024 }
7025
7026 /* Move past this section */
7027 offset += udcomplen;
7028
7029 /* Are we at the end of the frame? */
7030 /* TODO: if frame is less than 60 bytes, there may be > 4 bytes, likely zeros.. */
7031 if (tvb_reported_length_remaining(tvb, offset) < 4) {
7032 udcomplen_heuristic_result = true1;
7033 udcomplen_heuristic_result_set = true1;
7034 }
7035 } while (!udcomplen_heuristic_result_set);
7036 }
7037 return udcomplen_heuristic_result;
7038}
7039
7040static bool_Bool at_udcomphdr(tvbuff_t *tvb, int offset)
7041{
7042 if (tvb_captured_length_remaining(tvb, offset) < 2) {
7043 return false0;
7044 }
7045 uint8_t first_byte = tvb_get_uint8(tvb, offset);
7046 uint8_t reserved_byte = tvb_get_uint8(tvb, offset+1);
7047
7048 /* - iq width could be anything, though unlikely to be signalled as (say) < 1-3? */
7049 /* - meth should be 0-8 */
7050 /* - reserved byte should be 0 */
7051 return (((first_byte & 0x0f) <= MOD_COMPR_AND_SELECTIVE_RE_WITH_MASKS8) && (reserved_byte == 0));
7052}
7053
7054static bool_Bool udcomphdr_appears_present(flow_state_t *flow, uint32_t direction, tvbuff_t *tvb, int offset)
7055{
7056 /* Should really not happen, but guard against this anyway. */
7057 if (flow == NULL((void*)0)) {
7058 /* No state to update. */
7059 return false0;
7060 }
7061
7062 if (direction == DIR_UPLINK0) {
7063 if (flow->udcomphdrUplink_heuristic_result_set) {
7064 /* Return cached value */
7065 return flow->udcomphdrUplink_heuristic_result;
7066 }
7067 else {
7068 /* Work it out, and save answer for next time */
7069 flow->udcomphdrUplink_heuristic_result_set = true1;
7070 flow->udcomphdrUplink_heuristic_result = at_udcomphdr(tvb, offset);
7071 return flow->udcomphdrUplink_heuristic_result;
7072 }
7073 }
7074 else {
7075 /* Downlink */
7076 if (flow->udcomphdrDownlink_heuristic_result_set) {
7077 /* Return cached value */
7078 return flow->udcomphdrDownlink_heuristic_result;
7079 }
7080 else {
7081 /* Work it out, and save answer for next time */
7082 flow->udcomphdrDownlink_heuristic_result_set = true1;
7083 flow->udcomphdrDownlink_heuristic_result = at_udcomphdr(tvb, offset);
7084 return flow->udcomphdrDownlink_heuristic_result;
7085 }
7086 }
7087}
7088
7089static bool_Bool copy_section_entry(const void *key, void* value, void *userdata)
7090{
7091 /* Cast parameters to their types */
7092 uint32_t sectionId = GPOINTER_TO_UINT(key)((guint) (gulong) (key));
7093 expected_section_data_t *result_value = (expected_section_data_t *)value;
7094 wmem_tree_t *result_tree = (wmem_tree_t*)userdata;
7095
7096 /* Deep copy of section data */
7097 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)))
;
7098 *copy = *result_value;
7099
7100 /* Add into result tree */
7101 wmem_tree_insert32(result_tree, sectionId, copy);
7102
7103 return false0;
7104}
7105
7106/* User plane dissector (section 8) */
7107static int
7108dissect_oran_u(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
7109 oran_tap_info *tap_info, void *data _U___attribute__((unused)))
7110{
7111 /* Hidden filter for plane */
7112 proto_item *plane_ti = proto_tree_add_item(tree, hf_oran_uplane, tvb, 0, 0, ENC_NA0x00000000);
7113 PROTO_ITEM_SET_HIDDEN(plane_ti)proto_item_set_hidden((plane_ti));
7114
7115 /* Set up structures needed to add the protocol subtree and manage it */
7116 unsigned offset = 0;
7117
7118 col_set_str(pinfo->cinfo, COL_PROTOCOL, "O-RAN-FH-U");
7119 col_set_str(pinfo->cinfo, COL_INFO, "U-Plane");
7120
7121 tap_info->userplane = true1;
7122
7123 /* Create display subtree for the protocol */
7124 proto_item *protocol_item = proto_tree_add_item(tree, proto_oran, tvb, 0, -1, ENC_NA0x00000000);
7125 proto_item_append_text(protocol_item, "-U");
7126 proto_tree *oran_tree = proto_item_add_subtree(protocol_item, ett_oran);
7127
7128 /* Transport header */
7129 /* Real-time control data / IQ data transfer message series identifier */
7130 uint16_t eAxC;
7131 addPcOrRtcid(tvb, oran_tree, &offset, hf_oran_ecpri_pcid, &eAxC, tap_info);
7132 tap_info->eaxc = eAxC;
7133
7134 /* Update/report status of conversation */
7135 uint32_t key = make_flow_key(pinfo, eAxC, ORAN_U_PLANE1, false0);
7136 flow_state_t* state = (flow_state_t*)wmem_tree_lookup32(flow_states_table, key);
7137
7138 flow_result_t *result = NULL((void*)0);
7139
7140 /* Message identifier */
7141 proto_item *seqIdItem;
7142 uint32_t seqId, subSeqId, e;
7143 offset = addSeqid(tvb, oran_tree, offset, ORAN_U_PLANE1, &seqId, &seqIdItem, pinfo, &subSeqId, &e);
7144
7145 /* Common header for time reference */
7146 proto_item *timingHeader = proto_tree_add_string_format(oran_tree, hf_oran_timing_header,
7147 tvb, offset, 4, "", "Timing Header (");
7148 proto_tree *timing_header_tree = proto_item_add_subtree(timingHeader, ett_oran_u_timing);
7149
7150 /* dataDirection */
7151 uint32_t direction;
7152 proto_tree_add_item_ret_uint(timing_header_tree, hf_oran_data_direction, tvb, offset, 1, ENC_NA0x00000000, &direction);
7153 tap_info->uplink = (direction==0);
1
Assuming 'direction' is not equal to 0
7154 /* payloadVersion */
7155 dissect_payload_version(timing_header_tree, tvb, pinfo, offset);
7156 /* filterIndex */
7157 proto_tree_add_item(timing_header_tree, hf_oran_filter_index, tvb, offset, 1, ENC_NA0x00000000);
7158 offset += 1;
7159
7160 int ref_a_offset = offset;
7161
7162 /* frameId */
7163 uint32_t frameId = 0;
7164 proto_tree_add_item_ret_uint(timing_header_tree, hf_oran_frame_id, tvb, offset, 1, ENC_NA0x00000000, &frameId);
7165 tap_info->frame = frameId;
7166 offset += 1;
7167
7168 /* subframeId */
7169 uint32_t subframeId = 0;
7170 proto_tree_add_item_ret_uint(timing_header_tree, hf_oran_subframe_id, tvb, offset, 1, ENC_NA0x00000000, &subframeId);
7171 /* slotId */
7172 uint32_t slotId = 0;
7173 proto_tree_add_item_ret_uint(timing_header_tree, hf_oran_slot_id, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &slotId);
7174 tap_info->slot = slotId;
7175 offset++;
7176 /* symbolId */
7177 uint32_t symbolId = 0;
7178 proto_tree_add_item_ret_uint(timing_header_tree, hf_oran_symbolId, tvb, offset, 1, ENC_NA0x00000000, &symbolId);
7179 offset++;
7180
7181 char id[16];
7182 snprintf(id, 16, "%u-%u-%u-%u", frameId, subframeId, slotId, symbolId);
7183 proto_item *pi = proto_tree_add_string(timing_header_tree, hf_oran_refa, tvb, ref_a_offset, 3, id);
7184 proto_item_set_generated(pi);
7185
7186 proto_item_append_text(timingHeader, "%s, frameId: %d, subframeId: %d, slotId: %d, symbolId: %d)",
7187 val_to_str_const(direction, data_direction_vals, "Unknown"), frameId, subframeId, slotId, symbolId);
7188
7189 unsigned sample_bit_width;
7190 unsigned compression;
7191 int includeUdCompHeader;
7192
7193 /* Also lookup C-PLANE state (sent in opposite direction for UL) so may check current compression settings */
7194 uint32_t cplane_key = make_flow_key(pinfo, eAxC, ORAN_C_PLANE0, direction
1.1
'direction' is not equal to 0
== 0);
7195 flow_state_t* cplane_state = (flow_state_t*)wmem_tree_lookup32(flow_states_table, cplane_key);
7196
7197 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
2
Assuming field 'visited' is not equal to 0
3
Taking false branch
7198 /* Create state/conversation if doesn't exist yet */
7199 if (!state) {
7200 /* Allocate new state */
7201 state = wmem_new0(wmem_file_scope(), flow_state_t)((flow_state_t*)wmem_alloc0((wmem_file_scope()), sizeof(flow_state_t
)))
;
7202 state->ack_nack_requests = wmem_tree_new(wmem_file_scope());
7203 state->expected_sections[0] = wmem_tree_new(wmem_file_scope());
7204 state->expected_sections[1] = wmem_tree_new(wmem_file_scope());
7205 wmem_tree_insert32(flow_states_table, key, state);
7206 }
7207
7208 result = wmem_new0(wmem_file_scope(), flow_result_t)((flow_result_t*)wmem_alloc0((wmem_file_scope()), sizeof(flow_result_t
)))
;
7209 result->expected_sections = wmem_tree_new(wmem_file_scope());
7210 wmem_tree_insert32(flow_results_table, pinfo->num, result);
7211
7212 /* Check sequence analysis status (but not if later part of radio layer fragmentation) */
7213 if (state->last_frame_seen[direction] && (subSeqId==0) && (seqId != state->next_expected_sequence_number[direction])) {
7214 /* Store this result */
7215 result->unexpected_seq_number = true1;
7216 result->expected_sequence_number = state->next_expected_sequence_number[direction];
7217 result->previous_frame = state->last_frame[direction];
7218 }
7219 /* Update sequence analysis state */
7220 state->last_frame[direction] = pinfo->num;
7221 state->last_frame_seen[direction] = true1;
7222 state->next_expected_sequence_number[direction] = (seqId+1) % 256;
7223 }
7224
7225 /* Show any issues associated with this frame number */
7226 result = wmem_tree_lookup32(flow_results_table, pinfo->num);
4
Value assigned to 'result'
7227 if (result) {
5
Assuming 'result' is null
7228 if (result->unexpected_seq_number) {
7229 expert_add_info_format(pinfo, seqIdItem,
7230 (direction == DIR_UPLINK0) ?
7231 &ei_oran_uplane_unexpected_sequence_number_ul :
7232 &ei_oran_uplane_unexpected_sequence_number_dl,
7233 "Sequence number %u expected, but got %u",
7234 result->expected_sequence_number, seqId);
7235 tap_info->missing_sns = (256 + seqId - result->expected_sequence_number) % 256;
7236 /* TODO: could add previous/next frame (in seqId tree?) ? */
7237 }
7238 }
7239
7240 /* Checking UL timing within current slot. Disabled if limit set to 0. */
7241 /* N.B., timing is relative to first seen frame,
7242 not some notion of the beginning of the slot from sync, offset by some timing.. */
7243 if (direction
5.1
'direction' is not equal to DIR_UPLINK
== DIR_UPLINK0 && us_allowed_for_ul_in_symbol > 0) {
7244 uint32_t timing_key = get_timing_key(frameId, subframeId, slotId, symbolId);
7245 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
7246 /* Set state on first pass */
7247 ul_timing_for_slot* timing = (ul_timing_for_slot*)wmem_tree_lookup32(ul_symbol_timing, timing_key);
7248 if (!timing) {
7249 /* Allocate new state */
7250 timing = wmem_new0(wmem_file_scope(), ul_timing_for_slot)((ul_timing_for_slot*)wmem_alloc0((wmem_file_scope()), sizeof
(ul_timing_for_slot)))
;
7251 timing->first_frame = pinfo->num;
7252 timing->first_frame_time = pinfo->abs_ts;
7253 timing->frames_seen_in_symbol = 1;
7254 timing->last_frame_in_symbol = pinfo->num;
7255 wmem_tree_insert32(ul_symbol_timing, timing_key, timing);
7256 }
7257 else {
7258 /* Update existing state */
7259 timing->frames_seen_in_symbol++;
7260 timing->last_frame_in_symbol = pinfo->num;
7261 }
7262 }
7263 else {
7264 /* Subsequent passes - look up result */
7265 ul_timing_for_slot* timing = (ul_timing_for_slot*)wmem_tree_lookup32(ul_symbol_timing, timing_key);
7266 if (timing) { /* Really shouldn't fail! */
7267 if (timing->frames_seen_in_symbol > 1) {
7268 /* Work out gap between frames (in microseconds) back to frame carrying first seen symbol */
7269 int seconds_between_packets = (int)
7270 (pinfo->abs_ts.secs - timing->first_frame_time.secs);
7271 int nseconds_between_packets =
7272 pinfo->abs_ts.nsecs - timing->first_frame_time.nsecs;
7273
7274 /* Round to nearest microsecond. */
7275 uint32_t total_gap = (seconds_between_packets*1000000) +
7276 ((nseconds_between_packets+500) / 1000);
7277
7278 /* Show how long it has been */
7279 proto_item *ti = NULL((void*)0);
7280 if (pinfo->num != timing->first_frame) {
7281 ti = proto_tree_add_uint(timingHeader, hf_oran_u_section_ul_symbol_time, tvb, 0, 0, total_gap);
7282 proto_item_set_generated(ti);
7283 }
7284
7285 if (total_gap > us_allowed_for_ul_in_symbol) {
7286 expert_add_info_format(pinfo, ti, &ei_oran_ul_uplane_symbol_too_long,
7287 "UL U-Plane Tx took longer (%u us) than limit set in preferences (%u us)",
7288 total_gap, us_allowed_for_ul_in_symbol);
7289 proto_item_append_text(timingHeader, " (%uus since first frame seen for symbol)", total_gap);
7290 }
7291
7292 /* Show how many frames were received */
7293 ti = proto_tree_add_uint(timingHeader, hf_oran_u_section_ul_symbol_frames, tvb, 0, 0, timing->frames_seen_in_symbol);
7294 proto_item_set_generated(ti);
7295
7296 /* Link to first frame for this symbol */
7297 if (pinfo->num != timing->first_frame) {
7298 ti = proto_tree_add_uint(timingHeader, hf_oran_u_section_ul_symbol_first_frame, tvb, 0, 0, timing->first_frame);
7299 proto_item_set_generated(ti);
7300 }
7301
7302 /* And also last frame */
7303 if (pinfo->num != timing->last_frame_in_symbol) {
7304 ti = proto_tree_add_uint(timingHeader, hf_oran_u_section_ul_symbol_last_frame, tvb, 0, 0, timing->last_frame_in_symbol);
7305 proto_item_set_generated(ti);
7306 }
7307
7308 tap_info->ul_delay_in_us = total_gap;
7309 }
7310 }
7311 }
7312 }
7313
7314
7315 /* Look up preferences for samples */
7316 if (direction
5.2
'direction' is not equal to DIR_UPLINK
== DIR_UPLINK0) {
6
Taking false branch
7317 sample_bit_width = pref_sample_bit_width_uplink;
7318 compression = pref_iqCompressionUplink;
7319 includeUdCompHeader = pref_includeUdCompHeaderUplink;
7320 } else {
7321 sample_bit_width = pref_sample_bit_width_downlink;
7322 compression = pref_iqCompressionDownlink;
7323 includeUdCompHeader = pref_includeUdCompHeaderDownlink;
7324 }
7325
7326 /* If uplink, load any udCompHdr settings written by C-Plane */
7327 bool_Bool ud_cmp_hdr_cplane = false0;
7328 if (cplane_state && direction
7.1
'direction' is not equal to 0
== 0) {
7
Assuming 'cplane_state' is non-null
8
Taking false branch
7329 /* Initialise settings from udpCompHdr from C-Plane */
7330 if (cplane_state->ul_ud_comp_hdr_set && !pref_override_ul_compression) {
7331 sample_bit_width = cplane_state->ul_ud_comp_hdr_bit_width;
7332 compression = cplane_state->ul_ud_comp_hdr_compression;
7333 ud_cmp_hdr_cplane = true1;
7334 }
7335 }
7336
7337 /* Need a valid value (e.g. 9, 14). 0 definitely won't work, as won't progress around loop! */
7338 /* N.B. may yet be overwritten by udCompHdr settings in sections below! */
7339 if (sample_bit_width == 0) {
9
Assuming 'sample_bit_width' is not equal to 0
10
Taking false branch
7340 expert_add_info_format(pinfo, protocol_item, &ei_oran_invalid_sample_bit_width,
7341 "%cL Sample bit width from %s (%u) not valid, so can't decode sections",
7342 (direction == DIR_UPLINK0) ? 'U' : 'D',
7343 !ud_cmp_hdr_cplane ? "preference" : "C-Plane",
7344 sample_bit_width);
7345 return offset;
7346 }
7347
7348 unsigned bytesLeft;
7349 unsigned number_of_sections = 0;
7350 unsigned nBytesPerPrb =0;
7351
7352 if (link_planes_together && !PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited) && cplane_state) {
11
Assuming 'link_planes_together' is false
7353 /* Take a deep-copy of this state on first pass */
7354 wmem_tree_foreach(cplane_state->expected_sections[direction], copy_section_entry, result->expected_sections);
7355 }
7356
7357 /* Add each section (not from count, just keep parsing until payload used) */
7358 do {
7359 /* Section subtree */
7360 unsigned section_start_offset = offset;
7361 proto_item *sectionHeading = proto_tree_add_string_format(oran_tree, hf_oran_u_section,
7362 tvb, offset, 0, "", "Section");
7363 proto_tree *section_tree = proto_item_add_subtree(sectionHeading, ett_oran_u_section);
7364
7365 /* Section Header fields (darker green part) */
7366
7367 /* sectionId */
7368 uint32_t sectionId = 0;
7369 proto_item *ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_section_id, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &sectionId);
7370 if (sectionId == 4095) {
12
Assuming 'sectionId' is not equal to 4095
13
Taking false branch
7371 proto_item_append_text(ti, " (not default coupling C/U planes using sectionId)");
7372 }
7373 offset++;
7374
7375 if (tap_info->num_section_ids < MAX_SECTION_IDs32) {
14
Assuming field 'num_section_ids' is >= MAX_SECTION_IDs
15
Taking false branch
7376 tap_info->section_ids[tap_info->num_section_ids++] = sectionId;
7377 }
7378
7379 section_details_t *section_details = NULL((void*)0);
7380
7381 /* Lookup corresponding C-plane frame/info */
7382 if (link_planes_together) {
16
Assuming 'link_planes_together' is true
17
Taking true branch
7383 if (cplane_state
17.1
'cplane_state' is not equal to NULL
!= NULL((void*)0)) {
18
Taking true branch
7384
7385 expected_section_data_t *section_data = NULL((void*)0);
7386 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')
7387
7388 if (section_data) {
7389 /* Need to work out which of 2 entries is in use for this data frame */
7390 unsigned index_to_use = 0;
7391
7392 /* Does the first entry match the timing for this frame? */
7393 if (section_data->details[0].frame == frameId &&
7394 section_data->details[0].subframe == subframeId &&
7395 section_data->details[0].slot == slotId &&
7396 /* Check that symbolId is in range */
7397 section_data->details[0].startSymbol <= symbolId &&
7398 (unsigned)(section_data->details[0].startSymbol + section_data->details[0].numSymbols) <= (unsigned)symbolId) {
7399
7400 index_to_use = 0;
7401 }
7402 else if (section_data->details[1].frame == frameId &&
7403 section_data->details[1].subframe == subframeId &&
7404 section_data->details[1].slot == slotId &&
7405 /* Check that symbolId is in range */
7406 section_data->details[1].startSymbol <= symbolId &&
7407 (unsigned)(section_data->details[1].startSymbol + section_data->details[1].numSymbols) <= (unsigned)symbolId) {
7408
7409 index_to_use = 1;
7410 }
7411 else {
7412 /* TODO: expert info warning? */
7413 }
7414
7415 section_details = &section_data->details[index_to_use];
7416
7417 /* Cplane frame number */
7418 proto_item *cplane_frame_ti = proto_tree_add_uint(section_tree, hf_oran_corresponding_cplane_frame, tvb, 0, 0,
7419 section_details->frame_number);
7420 proto_item_set_generated(cplane_frame_ti);
7421
7422 /* usecs since cplane frame */
7423 time_t total_gap = 0;
7424
7425 if ((pinfo->abs_ts.secs == section_details->frame_time.secs) || (pinfo->abs_ts.secs == section_details->frame_time.secs+1)) {
7426 total_gap = ((pinfo->abs_ts.secs - section_details->frame_time.secs) * 1000000) +
7427 ((pinfo->abs_ts.nsecs - section_details->frame_time.nsecs)/1000);
7428 }
7429
7430 if (total_gap > 0) {
7431 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);
7432 proto_item_set_generated(cplane_delta_ti);
7433 }
7434
7435 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
7436 /* Look up 'result' for c-plane frame, and tell it about this frame.. */
7437 flow_result_t *cplane_result = wmem_tree_lookup32(flow_results_table, section_details->frame_number);
7438 if (!cplane_result) {
7439 cplane_result = wmem_new0(wmem_file_scope(), flow_result_t)((flow_result_t*)wmem_alloc0((wmem_file_scope()), sizeof(flow_result_t
)))
;
7440 cplane_result->u_plane_frames = wmem_list_new(wmem_file_scope());
7441 wmem_tree_insert32(flow_results_table, section_details->frame_number, cplane_result);
7442 }
7443 /* TODO: add more details? If move this further down, can include prb and symbol info.. */
7444
7445 corresponding_uplane_frame *details = wmem_new(wmem_file_scope(), corresponding_uplane_frame)((corresponding_uplane_frame*)wmem_alloc((wmem_file_scope()),
sizeof(corresponding_uplane_frame)))
;
7446 details->frame_number = pinfo->num;
7447 details->gap_in_usecs = (uint32_t)total_gap;
7448 details->sectionId = sectionId;
7449
7450 wmem_list_append(cplane_result->u_plane_frames, details);
7451 }
7452 }
7453 }
7454 }
7455
7456 /* rb */
7457 uint32_t rb;
7458 proto_tree_add_item_ret_uint(section_tree, hf_oran_rb, tvb, offset, 1, ENC_NA0x00000000, &rb);
7459 /* symInc. "use of symInc=1 shall be prohibited in the U-plane" */
7460 uint8_t syminc;
7461 proto_item *syminc_ti = proto_tree_add_item_ret_uint8(section_tree, hf_oran_symInc, tvb, offset, 1, ENC_NA0x00000000, &syminc);
7462 if (syminc) {
7463 expert_add_info(NULL((void*)0), syminc_ti, &ei_oran_syminc_set_for_uplane);
7464 }
7465 /* startPrbu */
7466 uint32_t startPrbu = 0;
7467 proto_tree_add_item_ret_uint(section_tree, hf_oran_startPrbu, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &startPrbu);
7468 offset += 2;
7469
7470 /* numPrbu */
7471 uint32_t numPrbu = 0;
7472 proto_tree_add_item_ret_uint(section_tree, hf_oran_numPrbu, tvb, offset, 1, ENC_NA0x00000000, &numPrbu);
7473 offset += 1;
7474
7475 proto_item *ud_comp_meth_item, *ud_comp_len_ti=NULL((void*)0);
7476 uint32_t ud_comp_len = 0;
7477
7478 /* udCompHdr (if preferences indicate will be present) */
7479 bool_Bool included = (includeUdCompHeader==1) || /* 1 means present.. */
7480 (includeUdCompHeader==2 && udcomphdr_appears_present(state, direction, tvb, offset));
7481 if (included) {
7482 /* 7.5.2.10 */
7483 /* Extract these values to inform how wide IQ samples in each PRB will be. */
7484 offset = dissect_udcomphdr(tvb, pinfo, section_tree, offset, false0, direction == 0, &sample_bit_width,
7485 &compression, &ud_comp_meth_item, tap_info);
7486
7487 /* Not part of udCompHdr */
7488 uint32_t reserved;
7489 proto_item *res_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_reserved_8bits, tvb, offset, 1, ENC_NA0x00000000, &reserved);
7490 offset += 1;
7491 if (reserved != 0) {
7492 expert_add_info_format(pinfo, res_ti, &ei_oran_reserved_not_zero,
7493 "reserved field (0x%x) not zero - perhaps udCompHdr is not really present?",
7494 reserved);
7495 }
7496 }
7497 else {
7498 /* No fields to dissect - just showing comp values from prefs */
7499 /* iqWidth */
7500 proto_item *iq_width_item = proto_tree_add_uint(section_tree, hf_oran_udCompHdrIqWidth_pref, tvb, 0, 0, sample_bit_width);
7501 proto_item_append_text(iq_width_item, (ud_cmp_hdr_cplane) ? " (from c-plane)" : " (from preferences)");
7502 proto_item_set_generated(iq_width_item);
7503
7504 /* udCompMethod */
7505 ud_comp_meth_item = proto_tree_add_uint(section_tree, hf_oran_udCompHdrMeth_pref, tvb, 0, 0, compression);
7506 proto_item_append_text(ud_comp_meth_item, (ud_cmp_hdr_cplane) ? " (from c-plane)" : " (from preferences)");
7507 proto_item_set_generated(ud_comp_meth_item);
7508
7509 /* Point back to C-Plane, if used */
7510 /* TODO: doesn't work with multiple port mappings using SE10.. */
7511 if (ud_cmp_hdr_cplane) {
7512 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);
7513 proto_item_set_generated(cplane_ti);
7514 }
7515
7516 tap_info->compression_methods |= (1 << compression);
7517 tap_info->compression_width = sample_bit_width;
7518 }
7519
7520 /* Consider fragmentation after first section header */
7521 if (do_radio_transport_layer_reassembly && (number_of_sections == 0) && (e !=1 || subSeqId!= 0)) {
7522
7523 /* Set fragmented flag. */
7524 bool_Bool save_fragmented = pinfo->fragmented;
7525 pinfo->fragmented = true1;
7526 fragment_head *fh;
7527 unsigned frag_data_len = tvb_reported_length_remaining(tvb, offset);
7528
7529 /* Add this fragment into reassembly table */
7530 uint32_t reassembly_id = make_reassembly_id(seqId, direction, eAxC,
7531 frameId, subframeId, slotId, symbolId);
7532 fh = fragment_add_seq(&oran_reassembly_table, tvb, offset, pinfo,
7533 reassembly_id, /* id */
7534 GUINT_TO_POINTER(reassembly_id)((gpointer) (gulong) (reassembly_id)), /* data */
7535 subSeqId, /* frag_number */
7536 frag_data_len, /* frag_data_len */
7537 !e, /* more_frags */
7538 0);
7539
7540 bool_Bool update_col_info = true1;
7541
7542 /* See if this completes an SDU */
7543 tvbuff_t *original_tvb = tvb;
7544 tvbuff_t *next_tvb = process_reassembled_data(tvb, offset, pinfo, "Reassembled O-RAN FH CUS Payload",
7545 fh, &oran_frag_items,
7546 &update_col_info, oran_tree);
7547 if (next_tvb) {
7548 /* Have reassembled data */
7549 proto_tree_add_item(oran_tree, hf_oran_payload, next_tvb, 0, -1, ENC_NA0x00000000);
7550 col_append_fstr(pinfo->cinfo, COL_INFO, " Reassembled Data (%u bytes)", tvb_reported_length(next_tvb));
7551 /* Dissection should resume at start of reassembled tvb */
7552 offset = 0;
7553 }
7554 /* Will continue with either reassembled tvb or NULL */
7555 tvb = next_tvb;
7556
7557 /* Restore fragmented flag */
7558 pinfo->fragmented = save_fragmented;
7559
7560 /* Don't dissect any more if not complete yet.. */
7561 if (tvb == NULL((void*)0)) {
7562 return tvb_captured_length(original_tvb);
7563 }
7564 }
7565
7566
7567 /* Not supported! TODO: other places where comp method is looked up (e.g., bfw?) */
7568 switch (compression) {
7569 case COMP_NONE0:
7570 case COMP_BLOCK_FP1:
7571 case BFP_AND_SELECTIVE_RE5:
7572 case COMP_MODULATION4:
7573 case MOD_COMPR_AND_SELECTIVE_RE6:
7574 break;
7575 default:
7576 expert_add_info_format(pinfo, ud_comp_meth_item, &ei_oran_unsupported_compression_method,
7577 "Compression method %u (%s) not supported by dissector",
7578 compression,
7579 rval_to_str_const(compression, ud_comp_header_meth, "reserved"));
7580 }
7581
7582 /* udCompLen (when supported, methods 5,6,7,8) */
7583 if (compression >= BFP_AND_SELECTIVE_RE5) {
7584 bool_Bool supported = (pref_support_udcompLen==1) || /* supported */
7585 (pref_support_udcompLen==2 && udcomplen_appears_present(includeUdCompHeader, tvb, offset));
7586
7587 if (supported) {
7588 ud_comp_len_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_udCompLen, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &ud_comp_len);
7589 if (ud_comp_len <= 1) {
7590 proto_item_append_text(ud_comp_len_ti, " (reserved)");
7591 }
7592 /* TODO: report if less than a viable section in frame? */
7593 /* Check that there is this much length left in the frame */
7594 if (ud_comp_len > tvb_reported_length_remaining(tvb, section_start_offset)) {
7595 expert_add_info_format(pinfo, ud_comp_len_ti, &ei_oran_ud_comp_len_wrong_size,
7596 "udCompLen indicates %u bytes in section, but only %u are left in frame",
7597 ud_comp_len, tvb_reported_length_remaining(tvb, section_start_offset));
7598 }
7599 /* Actual length of section will be checked below, at the end of the section */
7600 offset += 2;
7601 }
7602 }
7603
7604 /* sReSMask1 + sReSMask2 (depends upon compression method) */
7605 uint64_t sresmask1=0, sresmask2=0;
7606 if (compression == BFP_AND_SELECTIVE_RE_WITH_MASKS7 ||
7607 compression == MOD_COMPR_AND_SELECTIVE_RE_WITH_MASKS8)
7608 {
7609 static int * const sres_mask1_2_flags[] = {
7610 &hf_oran_sReSMask1_2_re12,
7611 &hf_oran_sReSMask1_2_re11,
7612 &hf_oran_sReSMask1_2_re10,
7613 &hf_oran_sReSMask1_2_re9,
7614 &hf_oran_sReSMask_re8,
7615 &hf_oran_sReSMask_re7,
7616 &hf_oran_sReSMask_re6,
7617 &hf_oran_sReSMask_re5,
7618 &hf_oran_sReSMask_re4,
7619 &hf_oran_sReSMask_re3,
7620 &hf_oran_sReSMask_re2,
7621 &hf_oran_sReSMask_re1,
7622 NULL((void*)0)
7623 };
7624
7625 /* reserved (4 bits) */
7626 add_reserved_field(section_tree, hf_oran_reserved_4bits, tvb, offset, 1);
7627 /* sReSMask1 (12 bits) */
7628 proto_item *sresmask_ti;
7629 sresmask_ti = proto_tree_add_bitmask_ret_uint64(section_tree, tvb, offset,
7630 hf_oran_sReSMask1,
7631 ett_oran_sresmask,
7632 sres_mask1_2_flags,
7633 ENC_NA0x00000000,
7634 &sresmask1);
7635 offset += 2;
7636 /* Count REs present */
7637 unsigned res = 0;
7638 for (unsigned n=0; n < 12; n++) {
7639 if ((sresmask1 >> n) & 0x1) {
7640 res++;
7641 }
7642 }
7643 proto_item_append_text(sresmask_ti, " (%u REs)", res);
7644
7645
7646 /* reserved (4 bits) */
7647 add_reserved_field(section_tree, hf_oran_reserved_4bits, tvb, offset, 1);
7648 /* sReSMask2 (12 bits) */
7649 sresmask_ti = proto_tree_add_bitmask_ret_uint64(section_tree, tvb, offset,
7650 hf_oran_sReSMask2,
7651 ett_oran_sresmask,
7652 sres_mask1_2_flags,
7653 ENC_NA0x00000000,
7654 &sresmask2);
7655 offset += 2;
7656
7657 if (rb == 1) {
7658 proto_item_append_text(sresmask_ti, " (ignored)");
7659 if (sresmask2 != 0) {
7660 expert_add_info(pinfo, ud_comp_len_ti, &ei_oran_sresmask2_not_zero_with_rb);
7661 }
7662 }
7663 else {
7664 /* Count REs present */
7665 res = 0;
7666 for (unsigned n=0; n < 12; n++) {
7667 if ((sresmask2 >> n) & 0x1) {
7668 res++;
7669 }
7670 }
7671 proto_item_append_text(sresmask_ti, " (%u REs)", res);
7672 }
7673 }
7674
7675 write_section_info(sectionHeading, pinfo, protocol_item, sectionId, startPrbu, numPrbu, rb);
7676
7677 /* TODO: should this use the same pref as c-plane? */
7678 if (numPrbu == 0) {
7679 /* Special case for all PRBs (NR: the total number of PRBs may be > 255) */
7680 numPrbu = pref_data_plane_section_total_rbs;
7681 startPrbu = 0; /* may already be 0... */
7682 }
7683
7684 section_mod_compr_config_t* mod_compr_config = get_mod_compr_section_to_read(cplane_state, sectionId);
7685
7686 /* Add each PRB */
7687 for (unsigned i = 0; i < numPrbu; i++) {
7688 /* Create subtree */
7689 proto_item *prbHeading = proto_tree_add_string_format(section_tree, hf_oran_samples_prb,
7690 tvb, offset, 0,
7691 "", "PRB");
7692 proto_tree *rb_tree = proto_item_add_subtree(prbHeading, ett_oran_u_prb);
7693 uint32_t exponent = 0;
7694 uint16_t sresmask = 0;
7695
7696 /* udCompParam (depends upon compression method) */
7697 int before = offset;
7698 offset = dissect_udcompparam(tvb, pinfo, rb_tree, offset, compression, &exponent, &sresmask, false0);
7699 int udcompparam_len = offset-before;
7700
7701 /* Show PRB number in root */
7702 proto_item_append_text(prbHeading, " %3u", startPrbu + i*(1+rb));
7703
7704 /* Work out how many REs / PRB */
7705 unsigned res_per_prb = 12;
7706 uint16_t sresmask_to_use = 0x0fff;
7707
7708 if (compression >= BFP_AND_SELECTIVE_RE5) {
7709 /* Work out which mask should be used */
7710 if (compression==BFP_AND_SELECTIVE_RE5 || compression==MOD_COMPR_AND_SELECTIVE_RE6) {
7711 /* Selective RE cases, use value from compModParam */
7712 sresmask_to_use = (uint16_t)sresmask;
7713 }
7714 else {
7715 /* With masks (in section). Choose between sresmask1 and sresmask2 */
7716 if (rb==1 || (i%2)==0) {
7717 /* Even values */
7718 sresmask_to_use = (uint16_t)sresmask1;
7719 }
7720 else {
7721 /* Odd values */
7722 sresmask_to_use = (uint16_t)sresmask2;
7723 }
7724 }
7725
7726 /* Count REs present using sresmask */
7727 res_per_prb = 0;
7728 /* Use sresmask to pick out which REs are present */
7729 for (unsigned n=0; n<12; n++) {
7730 if (sresmask_to_use & (1<<n)) {
7731 res_per_prb++;
7732 }
7733 }
7734 }
7735
7736 /* N.B. bytes for samples need to be padded out to next byte
7737 (certainly where there aren't 12 REs in PRB..) */
7738 unsigned nBytesForSamples = (sample_bit_width * res_per_prb * 2 + 7) / 8;
7739 nBytesPerPrb = nBytesForSamples + udcompparam_len;
7740
7741 proto_tree_add_item(rb_tree, hf_oran_iq_user_data, tvb, offset, nBytesForSamples, ENC_NA0x00000000);
7742
7743 if (section_details) {
7744 if ((startPrbu + i*(1+rb)) < 273) {
7745 proto_item *beamid_ti = proto_tree_add_uint(rb_tree, hf_oran_beamId, tvb, 0, 0,
7746 section_details->beamIds[startPrbu + i*(1+rb)]);
7747 proto_item_set_generated(beamid_ti);
7748 }
7749 }
7750
7751
7752 tap_info->non_zero_re_in_current_prb = false0;
7753
7754 /* Optionally trying to show I/Q RE values */
7755 if (pref_showIQSampleValues) {
7756 /* Individual values */
7757 unsigned samples_offset = offset*8;
7758 unsigned samples_start = offset;
7759 unsigned samples = 0;
7760
7761 if (compression >= BFP_AND_SELECTIVE_RE5) {
7762 /* Use sresmask to pick out which REs are present */
7763 for (unsigned n=1; n<=12; n++) {
7764 if (sresmask_to_use & (1<<(n-1))) {
7765 samples_offset = dissect_oran_u_re(tvb, rb_tree,
7766 n, samples_offset, tap_info, sample_bit_width, compression, exponent, mod_compr_config, n);
7767 samples++;
7768 }
7769 }
7770 }
7771 else {
7772 /* All 12 REs are present */
7773 for (unsigned n=1; n<=12; n++) {
7774 samples_offset = dissect_oran_u_re(tvb, rb_tree,
7775 n, samples_offset, tap_info, sample_bit_width, compression, exponent, mod_compr_config, n);
7776 samples++;
7777 }
7778 }
7779 proto_item_append_text(prbHeading, " (%u REs)", samples);
7780 if (section_details) {
7781 if ((startPrbu + i*(1+rb)) < 273) {
7782 proto_item_append_text(prbHeading, " [BeamId:%u]", section_details->beamIds[startPrbu + i*(1+rb)]);
7783 }
7784 }
7785
7786 /* Was this PRB all zeros? */
7787 if (!tap_info->non_zero_re_in_current_prb) {
7788 tap_info->num_prbs_zero++;
7789 /* Add a filter to make zero-valued PRBs more findable */
7790 proto_item *zero_ti = proto_tree_add_item(rb_tree, hf_oran_zero_prb, tvb,
7791 samples_start, nBytesForSamples, ENC_NA0x00000000);
7792 proto_item_set_hidden(zero_ti);
7793 proto_item_append_text(prbHeading, " (all zeros)");
7794 }
7795 else {
7796 proto_item *nonzero_ti = proto_tree_add_item(rb_tree, hf_oran_nonzero_prb, tvb, samples_start, nBytesForSamples, ENC_NA0x00000000);
7797 proto_item_set_hidden(nonzero_ti);
7798 }
7799 }
7800
7801 tap_info->num_prbs++;
7802
7803
7804 /* Advance past samples */
7805 offset += nBytesForSamples;
7806
7807 /* Set end of prb subtree */
7808 proto_item_set_end(prbHeading, tvb, offset);
7809 }
7810
7811 /* Set extent of section */
7812 proto_item_set_len(sectionHeading, offset-section_start_offset);
7813 if (ud_comp_len_ti != NULL((void*)0) && ((offset-section_start_offset != ud_comp_len))) {
7814 expert_add_info_format(pinfo, ud_comp_len_ti, &ei_oran_ud_comp_len_wrong_size,
7815 "udCompLen indicates %u bytes in section, but dissected %u instead",
7816 ud_comp_len, offset-section_start_offset);
7817 }
7818
7819 bytesLeft = tvb_captured_length(tvb) - offset;
7820 number_of_sections++;
7821 } while (bytesLeft >= (4 + nBytesPerPrb)); /* FIXME: bad heuristic */
7822
7823 /* Show number of sections found */
7824 proto_item *ti = proto_tree_add_uint(oran_tree, hf_oran_numberOfSections, tvb, 0, 0, number_of_sections);
7825 proto_item_set_generated(ti);
7826
7827 /* Expert error if we are short of tvb by > 3 bytes */
7828 if (tvb_reported_length_remaining(tvb, offset) > 3) {
7829 expert_add_info_format(pinfo, protocol_item, &ei_oran_frame_length,
7830 "%u bytes remain at end of frame - should be 0-3",
7831 tvb_reported_length_remaining(tvb, offset));
7832 }
7833
7834 return tvb_captured_length(tvb);
7835}
7836
7837
7838/**********************************************************************/
7839/* Main dissection function. */
7840/* N.B. ecpri message type passed in as 'data' arg by eCPRI dissector */
7841static int
7842dissect_oran(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
7843{
7844 uint32_t ecpri_message_type = *(uint32_t *)data;
7845 unsigned offset = 0;
7846
7847 /* Allocate and zero tap struct */
7848 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
)))
;
7849 tap_info->pdu_size = pinfo->fd->pkt_len;
7850 tap_info->ul_delay_configured_max = us_allowed_for_ul_in_symbol;
7851
7852 switch (ecpri_message_type) {
7853 case ECPRI_MT_IQ_DATA0:
7854 offset = dissect_oran_u(tvb, pinfo, tree, tap_info, data);
7855 break;
7856 case ECPRI_MT_RT_CTRL_DATA2:
7857 offset = dissect_oran_c(tvb, pinfo, tree, tap_info, data);
7858 break;
7859 default:
7860 /* Not dissecting other types - assume these are handled by eCPRI dissector */
7861 return 0;
7862 }
7863
7864 tap_queue_packet(oran_tap, pinfo, tap_info);
7865
7866 return offset;
7867}
7868
7869static void oran_init_protocol(void)
7870{
7871 udcomplen_heuristic_result_set = false0;
7872 udcomplen_heuristic_result = false0;
7873}
7874
7875
7876/* Register the protocol with Wireshark. */
7877void
7878proto_register_oran(void)
7879{
7880 static hf_register_info hf[] = {
7881
7882 /* Section 5.1.3.2.7 */
7883 { &hf_oran_du_port_id,
7884 { "DU Port ID", "oran_fh_cus.du_port_id",
7885 FT_UINT16, BASE_DEC,
7886 NULL((void*)0), 0x0,
7887 "Processing unit at O-RU - width set in dissector preference", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
7888 },
7889
7890 /* Section 5.1.3.2.7 */
7891 { &hf_oran_bandsector_id,
7892 { "BandSector ID", "oran_fh_cus.bandsector_id",
7893 FT_UINT16, BASE_DEC,
7894 NULL((void*)0), 0x0,
7895 "Aggregated cell identified - width set in dissector preference", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
7896 },
7897
7898 /* Section 5.1.3.2.7 */
7899 { &hf_oran_cc_id,
7900 { "CC ID", "oran_fh_cus.cc_id",
7901 FT_UINT16, BASE_DEC,
7902 NULL((void*)0), 0x0,
7903 "Component Carrier - width set in dissector preference", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
7904 },
7905
7906 /* Section 5.1.3.2.7 */
7907 { &hf_oran_ru_port_id,
7908 { "RU Port ID", "oran_fh_cus.ru_port_id",
7909 FT_UINT16, BASE_DEC,
7910 NULL((void*)0), 0x0,
7911 "Logical flow - width set in dissector preference", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
7912 },
7913
7914 /* Section 5.1.3.2.8 */
7915 { &hf_oran_sequence_id,
7916 { "Sequence ID", "oran_fh_cus.sequence_id",
7917 FT_UINT8, BASE_DEC,
7918 NULL((void*)0), 0x0,
7919 "The Sequence ID wraps around individually per eAxC", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
7920 },
7921
7922 /* Section 5.1.3.2.8 */
7923 { &hf_oran_e_bit,
7924 { "E Bit", "oran_fh_cus.e_bit",
7925 FT_UINT8, BASE_DEC,
7926 VALS(e_bit)((0 ? (const struct _value_string*)0 : ((e_bit)))), 0x80,
7927 "Indicate the last message of a subsequence (U-Plane only)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
7928 },
7929
7930 /* Section 5.1.3.2.8 */
7931 { &hf_oran_subsequence_id,
7932 { "Subsequence ID", "oran_fh_cus.subsequence_id",
7933 FT_UINT8, BASE_DEC,
7934 NULL((void*)0), 0x7f,
7935 "The subsequence ID (for eCPRI layer fragmentation)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
7936 },
7937
7938 { &hf_oran_previous_frame,
7939 { "Previous frame in stream", "oran_fh_cus.previous-frame",
7940 FT_FRAMENUM, BASE_NONE,
7941 FRAMENUM_TYPE(FT_FRAMENUM_NONE)((gpointer) (glong) (FT_FRAMENUM_NONE)), 0x0,
7942 "Previous frame in sequence", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
7943 },
7944
7945 /* Section 7.5.2.1 */
7946 { &hf_oran_data_direction,
7947 { "Data Direction", "oran_fh_cus.data_direction",
7948 FT_UINT8, BASE_DEC,
7949 VALS(data_direction_vals)((0 ? (const struct _value_string*)0 : ((data_direction_vals)
)))
, 0x80,
7950 "gNB data direction", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
7951 },
7952
7953 /* Section 7.5.2.2 */
7954 { &hf_oran_payload_version,
7955 { "Payload Version", "oran_fh_cus.payloadVersion",
7956 FT_UINT8, BASE_DEC,
7957 NULL((void*)0), 0x70,
7958 "Payload protocol version the following IEs", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7959 },
7960
7961 /* Section 7.5.2.3 */
7962 { &hf_oran_filter_index,
7963 { "Filter Index", "oran_fh_cus.filterIndex",
7964 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
7965 RVALS(filter_indices)((0 ? (const struct _range_string*)0 : ((filter_indices)))), 0x0f,
7966 "used between IQ data and air interface, both in DL and UL", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7967 },
7968
7969 /* Section 7.5.2.4 */
7970 { &hf_oran_frame_id,
7971 { "Frame ID", "oran_fh_cus.frameId",
7972 FT_UINT8, BASE_DEC,
7973 NULL((void*)0), 0x0,
7974 "A counter for 10 ms frames (wrapping period 2.56 seconds)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7975 },
7976
7977 /* Section 7.5.2.5 */
7978 { &hf_oran_subframe_id,
7979 { "Subframe ID", "oran_fh_cus.subframe_id",
7980 FT_UINT8, BASE_DEC,
7981 NULL((void*)0), 0xf0,
7982 "A counter for 1 ms sub-frames within 10ms frame", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7983 },
7984
7985 /* Section 7.5.2.6 */
7986 { &hf_oran_slot_id,
7987 { "Slot ID", "oran_fh_cus.slotId",
7988 FT_UINT16, BASE_DEC,
7989 NULL((void*)0), 0x0fc0,
7990 "Slot number within a 1ms sub-frame", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7991 },
7992
7993 /* Generated for convenience */
7994 { &hf_oran_slot_within_frame,
7995 { "Slot within frame", "oran_fh_cus.slot-within-frame",
7996 FT_UINT16, BASE_DEC,
7997 NULL((void*)0), 0x0,
7998 "Slot within frame, to match DCT logs", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7999 },
8000
8001 /* Section 7.5.2.7 */
8002 { &hf_oran_start_symbol_id,
8003 { "Start Symbol ID", "oran_fh_cus.startSymbolId",
8004 FT_UINT8, BASE_DEC,
8005 NULL((void*)0), 0x3f,
8006 "The first symbol number within slot affected", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8007 },
8008
8009 /* Section 7.5.2.8 */
8010 { &hf_oran_numberOfSections,
8011 { "Number of Sections", "oran_fh_cus.numberOfSections",
8012 FT_UINT8, BASE_DEC,
8013 NULL((void*)0), 0x0,
8014 "The number of section IDs included in this message", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8015 },
8016
8017 /* Section 7.5.2.9 */
8018 { &hf_oran_sectionType,
8019 { "Section Type", "oran_fh_cus.sectionType",
8020 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
8021 RVALS(section_types)((0 ? (const struct _range_string*)0 : ((section_types)))), 0x0,
8022 "Determines the characteristics of U-plane data", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8023 },
8024
8025 /* Section 7.5.2.10 */
8026 { &hf_oran_udCompHdr,
8027 { "udCompHdr", "oran_fh_cus.udCompHdr",
8028 FT_STRING, BASE_NONE,
8029 NULL((void*)0), 0x0,
8030 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8031 },
8032
8033 /* Section 7.5.2.11 */
8034 { &hf_oran_numberOfUEs,
8035 { "Number Of UEs", "oran_fh_cus.numberOfUEs",
8036 FT_UINT8, BASE_DEC,
8037 NULL((void*)0), 0x0,
8038 "Indicates number of UEs for which channel info is provided", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8039 },
8040
8041 /* Section 7.5.2.12 */
8042 { &hf_oran_timeOffset,
8043 { "Time Offset", "oran_fh_cus.timeOffset",
8044 FT_UINT16, BASE_DEC,
8045 NULL((void*)0), 0x0,
8046 "from start of the slot to start of CP in samples", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8047 },
8048
8049 /* Section 7.5.2.13 */
8050 { &hf_oran_frameStructure_fft,
8051 { "FFT Size", "oran_fh_cus.frameStructure.fft",
8052 FT_UINT8, BASE_HEX | BASE_RANGE_STRING0x00000100,
8053 RVALS(frame_structure_fft)((0 ? (const struct _range_string*)0 : ((frame_structure_fft)
)))
, 0xf0,
8054 "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) }
8055 },
8056
8057 /* Section 7.5.2.13 */
8058 { &hf_oran_frameStructure_subcarrier_spacing,
8059 { "Subcarrier Spacing", "oran_fh_cus.frameStructure.spacing",
8060 FT_UINT8, BASE_HEX | BASE_RANGE_STRING0x00000100,
8061 RVALS(subcarrier_spacings)((0 ? (const struct _range_string*)0 : ((subcarrier_spacings)
)))
, 0x0f,
8062 "The sub carrier spacing as well as the number of slots per 1ms sub-frame",
8063 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
8064 },
8065
8066 /* Section 7.5.2.14 */
8067 { &hf_oran_cpLength,
8068 { "cpLength", "oran_fh_cus.cpLength",
8069 FT_UINT16, BASE_DEC,
8070 NULL((void*)0), 0x0,
8071 "cyclic prefix length", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8072 },
8073
8074 { &hf_oran_timing_header,
8075 { "Timing Header", "oran_fh_cus.timingHeader",
8076 FT_STRING, BASE_NONE,
8077 NULL((void*)0), 0x0,
8078 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8079 },
8080
8081 /* Section 7.5.3.1 */
8082 { &hf_oran_section_id,
8083 { "sectionId", "oran_fh_cus.sectionId",
8084 FT_UINT16, BASE_DEC,
8085 NULL((void*)0), 0xfff0,
8086 "section identifier of data", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8087 },
8088
8089 /* Section 7.5.3.2 */
8090 { &hf_oran_rb,
8091 { "rb", "oran_fh_cus.rb",
8092 FT_UINT8, BASE_DEC,
8093 VALS(rb_vals)((0 ? (const struct _value_string*)0 : ((rb_vals)))), 0x08,
8094 "resource block indicator", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8095 },
8096
8097 /* Section 7.5.5.3 */
8098 { &hf_oran_symInc,
8099 { "symInc", "oran_fh_cus.symInc",
8100 FT_UINT8, BASE_DEC,
8101 VALS(sym_inc_vals)((0 ? (const struct _value_string*)0 : ((sym_inc_vals)))), 0x04,
8102 "Symbol Number Increment Command", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8103 },
8104
8105 /* Section 7.5.3.4 */
8106 { &hf_oran_startPrbc,
8107 { "startPrbc", "oran_fh_cus.startPrbc",
8108 FT_UINT16, BASE_DEC,
8109 NULL((void*)0), 0x03ff,
8110 "Starting PRB of Control Plane Section", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8111 },
8112
8113 /* Section 7.5.3.5 */
8114 { &hf_oran_reMask_re1,
8115 { "RE 1", "oran_fh_cus.reMask-RE1",
8116 FT_BOOLEAN, 16,
8117 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x8000,
8118 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8119 },
8120 { &hf_oran_reMask_re2,
8121 { "RE 2", "oran_fh_cus.reMask-RE2",
8122 FT_BOOLEAN, 16,
8123 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x4000,
8124 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8125 },
8126 { &hf_oran_reMask_re3,
8127 { "RE 3", "oran_fh_cus.reMask-RE3",
8128 FT_BOOLEAN, 16,
8129 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x2000,
8130 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8131 },
8132 { &hf_oran_reMask_re4,
8133 { "RE 4", "oran_fh_cus.reMask-RE4",
8134 FT_BOOLEAN, 16,
8135 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x1000,
8136 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8137 },
8138 { &hf_oran_reMask_re5,
8139 { "RE 5", "oran_fh_cus.reMask-RE5",
8140 FT_BOOLEAN, 16,
8141 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0800,
8142 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8143 },
8144 { &hf_oran_reMask_re6,
8145 { "RE 6", "oran_fh_cus.reMask-RE6",
8146 FT_BOOLEAN, 16,
8147 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0400,
8148 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8149 },
8150 { &hf_oran_reMask_re7,
8151 { "RE 7", "oran_fh_cus.reMask-RE7",
8152 FT_BOOLEAN, 16,
8153 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0200,
8154 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8155 },
8156 { &hf_oran_reMask_re8,
8157 { "RE 8", "oran_fh_cus.reMask-RE8",
8158 FT_BOOLEAN, 16,
8159 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0100,
8160 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8161 },
8162 { &hf_oran_reMask_re9,
8163 { "RE 9", "oran_fh_cus.reMask-RE9",
8164 FT_BOOLEAN, 16,
8165 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0080,
8166 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8167 },
8168 { &hf_oran_reMask_re10,
8169 { "RE 10", "oran_fh_cus.reMask-RE10",
8170 FT_BOOLEAN, 16,
8171 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0040,
8172 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8173 },
8174 { &hf_oran_reMask_re11,
8175 { "RE 11", "oran_fh_cus.reMask-RE11",
8176 FT_BOOLEAN, 16,
8177 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0020,
8178 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8179 },
8180 { &hf_oran_reMask_re12,
8181 { "RE 12", "oran_fh_cus.reMask-RE12",
8182 FT_BOOLEAN, 16,
8183 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0010,
8184 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8185 },
8186 { &hf_oran_reMask,
8187 { "RE Mask", "oran_fh_cus.reMask",
8188 FT_UINT16, BASE_HEX,
8189 NULL((void*)0), 0xfff0,
8190 "The Resource Element (RE) mask within a PRB", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8191 },
8192
8193 /* Section 7.5.3.6 */
8194 { &hf_oran_numPrbc,
8195 { "numPrbc", "oran_fh_cus.numPrbc",
8196 FT_UINT8, BASE_DEC,
8197 NULL((void*)0), 0x0,
8198 "Number of contiguous PRBs per data section description", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8199 },
8200 /* Section 7.5.3.7 */
8201 { &hf_oran_numSymbol,
8202 { "Number of Symbols", "oran_fh_cus.numSymbol",
8203 FT_UINT8, BASE_DEC,
8204 NULL((void*)0), 0x0f,
8205 "Defines number of symbols to which the section control is applicable", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8206 },
8207 /* Section 7.5.3.8 */
8208 { &hf_oran_ef,
8209 { "Extension Flag", "oran_fh_cus.ef",
8210 FT_BOOLEAN, 8,
8211 NULL((void*)0), 0x80,
8212 "Indicates if more section extensions follow", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8213 },
8214 /* Section 7.5.3.9 */
8215 { &hf_oran_beamId,
8216 { "Beam ID", "oran_fh_cus.beamId",
8217 FT_UINT16, BASE_DEC,
8218 NULL((void*)0), 0x7fff,
8219 "Defines the beam pattern to be applied to the U-Plane data", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8220 },
8221
8222 { &hf_oran_extension,
8223 { "Extension", "oran_fh_cus.extension",
8224 FT_STRING, BASE_NONE,
8225 NULL((void*)0), 0x0,
8226 "Section extension", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8227 },
8228
8229 /* Section 7.6.2.1 */
8230 { &hf_oran_exttype,
8231 { "extType", "oran_fh_cus.extType",
8232 FT_UINT8, BASE_DEC|BASE_EXT_STRING0x00000200,
8233 &exttype_vals_ext, 0x7f,
8234 "The extension type, which provides additional parameters specific to subject data extension", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8235 },
8236
8237 /* Section 7.6.2.3 */
8238 { &hf_oran_extlen,
8239 { "extLen", "oran_fh_cus.extLen",
8240 FT_UINT16, BASE_DEC,
8241 NULL((void*)0), 0x0,
8242 "Extension length in 32-bit words", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8243 },
8244
8245 /* Section 7.7.1 */
8246 { &hf_oran_bfw,
8247 { "bfw", "oran_fh_cus.bfw",
8248 FT_STRING, BASE_NONE,
8249 NULL((void*)0), 0x0,
8250 "Set of weights for a particular antenna", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8251 },
8252 { &hf_oran_bfw_bundle,
8253 { "Bundle", "oran_fh_cus.bfw.bundle",
8254 FT_STRING, BASE_NONE,
8255 NULL((void*)0), 0x0,
8256 "Bundle of BFWs", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8257 },
8258 { &hf_oran_bfw_bundle_id,
8259 { "Bundle Id", "oran_fh_cus.bfw.bundleId",
8260 FT_UINT32, BASE_DEC,
8261 NULL((void*)0), 0x0,
8262 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8263 },
8264 /* Section 7.7.1.4 */
8265 { &hf_oran_bfw_i,
8266 { "bfwI", "oran_fh_cus.bfwI",
8267 FT_FLOAT, BASE_NONE,
8268 NULL((void*)0), 0x0,
8269 "In-phase", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8270 },
8271 /* Section 7.7.1.5 */
8272 { &hf_oran_bfw_q,
8273 { "bfwQ", "oran_fh_cus.bfwQ",
8274 FT_FLOAT, BASE_NONE,
8275 NULL((void*)0), 0x0,
8276 "Quadrature", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8277 },
8278
8279 /* Section 7.5.3.10 */
8280 { &hf_oran_ueId,
8281 { "UE ID", "oran_fh_cus.ueId",
8282 FT_UINT16, BASE_DEC,
8283 NULL((void*)0), 0x7fff,
8284 "logical identifier for set of channel info", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8285 },
8286 /* Section 7.5.3.11 */
8287 { &hf_oran_freqOffset,
8288 { "Frequency Offset", "oran_fh_cus.freqOffset",
8289 FT_UINT24, BASE_DEC,
8290 NULL((void*)0), 0x0,
8291 "with respect to the carrier center frequency before additional filtering", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8292 },
8293
8294 /* Section 7.5.3.12 */
8295 { &hf_oran_regularizationFactor,
8296 { "Regularization Factor", "oran_fh_cus.regularizationFactor",
8297 FT_INT16, BASE_DEC,
8298 NULL((void*)0), 0x0,
8299 "Signed value to support MMSE operation within O-RU", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8300 },
8301 /* Section 7.5.3.14 */
8302 { &hf_oran_laaMsgType,
8303 { "LAA Message Type", "oran_fh_cus.laaMsgType",
8304 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
8305 RVALS(laaMsgTypes)((0 ? (const struct _range_string*)0 : ((laaMsgTypes)))), 0xf0,
8306 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8307 },
8308 /* Section 7.5.3.15 */
8309 { &hf_oran_laaMsgLen,
8310 { "LAA Message Length", "oran_fh_cus.laaMsgLen",
8311 FT_UINT8, BASE_DEC,
8312 NULL((void*)0), 0x0f,
8313 "number of 32-bit words in the LAA section", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8314 },
8315 /* Section 7.5.3.16 */
8316 { &hf_oran_lbtHandle,
8317 { "LBT Handle", "oran_fh_cus.lbtHandle",
8318 FT_UINT16, BASE_HEX,
8319 NULL((void*)0), 0x0,
8320 "label to identify transaction", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8321 },
8322 /* Section 7.5.3.17 */
8323 { &hf_oran_lbtDeferFactor,
8324 { "Defer Factor", "oran_fh_cus.lbtDeferFactor",
8325 FT_UINT8, BASE_DEC,
8326 NULL((void*)0), 0x07,
8327 "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)}
8328 },
8329 /* Section 7.5.3.18 */
8330 { &hf_oran_lbtBackoffCounter,
8331 { "Backoff Counter", "oran_fh_cus.lbtBackoffCounter",
8332 FT_UINT16, BASE_DEC,
8333 NULL((void*)0), 0xffc0,
8334 "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)}
8335 },
8336 /* Section 7.5.3.19 */
8337 { &hf_oran_lbtOffset,
8338 { "LBT Offset", "oran_fh_cus.lbtOffset",
8339 FT_UINT16, BASE_DEC,
8340 NULL((void*)0), 0xffc0,
8341 "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)}
8342 },
8343 /* Section 7.5.3.20 */
8344 { &hf_oran_MCOT,
8345 { "Maximum Channel Occupancy Time", "oran_fh_cus.MCOT",
8346 FT_UINT8, BASE_DEC,
8347 NULL((void*)0), 0x3c,
8348 "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)}
8349 },
8350 /* Section 7.5.3.21 */
8351 { &hf_oran_lbtMode,
8352 { "LBT Mode", "oran_fh_cus.lbtMode",
8353 FT_UINT8, BASE_DEC,
8354 VALS(lbtMode_vals)((0 ? (const struct _value_string*)0 : ((lbtMode_vals)))), 0x0,
8355 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8356 },
8357 /* Section 7.5.3.22 */
8358 { &hf_oran_lbtPdschRes,
8359 { "lbtPdschRes", "oran_fh_cus.lbtPdschRes",
8360 FT_UINT8, BASE_DEC,
8361 VALS(lbtPdschRes_vals)((0 ? (const struct _value_string*)0 : ((lbtPdschRes_vals)))), 0xc0,
8362 "LBT result of SFN/SF", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8363 },
8364 /* Section 7.5.3.23 */
8365 { &hf_oran_sfStatus,
8366 { "sfStatus", "oran_fh_cus.sfStatus",
8367 FT_BOOLEAN, 8,
8368 TFS(&tfs_sfStatus)((0 ? (const struct true_false_string*)0 : ((&tfs_sfStatus
))))
, 0x10,
8369 "Indicates whether the subframe was dropped or transmitted", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8370 },
8371 /* Section 7.5.3.24 */
8372 { &hf_oran_lbtDrsRes,
8373 { "lbtDrsRes", "oran_fh_cus.lbtDrsRes",
8374 FT_BOOLEAN, 8,
8375 TFS(&tfs_fail_success)((0 ? (const struct true_false_string*)0 : ((&tfs_fail_success
))))
, 0x80,
8376 "Indicates whether the subframe was dropped or transmitted", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8377 },
8378 /* Section 7.5.3.25 */
8379 { &hf_oran_initialPartialSF,
8380 { "Initial partial SF", "oran_fh_cus.initialPartialSF",
8381 FT_BOOLEAN, 8,
8382 TFS(&tfs_partial_full_sf)((0 ? (const struct true_false_string*)0 : ((&tfs_partial_full_sf
))))
, 0x40,
8383 "Indicates whether the initial SF in the LBT process is full or partial", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8384 },
8385 /* Section 7.5.3.26. */
8386 { &hf_oran_lbtBufErr,
8387 { "lbtBufErr", "oran_fh_cus.lbtBufErr",
8388 FT_BOOLEAN, 8,
8389 TFS(&tfs_lbtBufErr)((0 ? (const struct true_false_string*)0 : ((&tfs_lbtBufErr
))))
, 0x80,
8390 "LBT buffer error", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8391 },
8392 /* Section 7.5.3.27 */
8393 { &hf_oran_sfnSfEnd,
8394 { "SFN/SF End", "oran_fh_cus.sfnSfEnd",
8395 FT_UINT16, BASE_DEC,
8396 NULL((void*)0), 0x0fff,
8397 "SFN/SF by which the DRS window must end", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8398 },
8399 /* Section 7.5.3.28 */
8400 { &hf_oran_lbtCWConfig_H,
8401 { "lbtCWConfig_H", "oran_fh_cus.lbtCWConfig_H",
8402 FT_UINT8, BASE_DEC,
8403 NULL((void*)0), 0x0,
8404 "HARQ parameters for congestion window management", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8405 },
8406 /* Section 7.5.3.29 */
8407 { &hf_oran_lbtCWConfig_T,
8408 { "lbtCWConfig_T", "oran_fh_cus.lbtCWConfig_T",
8409 FT_UINT8, BASE_DEC,
8410 NULL((void*)0), 0x0,
8411 "TB parameters for congestion window management", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8412 },
8413 /* Section 7.5.3.30 */
8414 { &hf_oran_lbtTrafficClass,
8415 { "lbtTrafficClass", "oran_fh_cus.lbtTrafficClass",
8416 FT_UINT8, BASE_DEC,
8417 VALS(lbtTrafficClass_vals)((0 ? (const struct _value_string*)0 : ((lbtTrafficClass_vals
))))
, 0x38,
8418 "Traffic class priority for congestion window management", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8419 },
8420 /* Section 7.5.3.31 */
8421 { &hf_oran_lbtCWR_Rst,
8422 { "lbtCWR_Rst", "oran_fh_cus.lbtCWR_Rst",
8423 FT_BOOLEAN, 8,
8424 TFS(&tfs_fail_success)((0 ? (const struct true_false_string*)0 : ((&tfs_fail_success
))))
, 0x80,
8425 "notification about packet reception successful or not", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8426 },
8427
8428 /* Reserved fields */
8429 { &hf_oran_reserved,
8430 { "reserved", "oran_fh_cus.reserved",
8431 FT_UINT64, BASE_HEX,
8432 NULL((void*)0), 0x0,
8433 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8434 },
8435 { &hf_oran_reserved_1bit,
8436 { "reserved", "oran_fh_cus.reserved",
8437 FT_UINT8, BASE_HEX,
8438 NULL((void*)0), 0x80,
8439 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8440 },
8441 { &hf_oran_reserved_2bits,
8442 { "reserved", "oran_fh_cus.reserved",
8443 FT_UINT8, BASE_HEX,
8444 NULL((void*)0), 0xc0,
8445 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8446 },
8447 { &hf_oran_reserved_3bits,
8448 { "reserved", "oran_fh_cus.reserved",
8449 FT_UINT8, BASE_HEX,
8450 NULL((void*)0), 0xe0,
8451 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8452 },
8453 { &hf_oran_reserved_4bits,
8454 { "reserved", "oran_fh_cus.reserved",
8455 FT_UINT8, BASE_HEX,
8456 NULL((void*)0), 0xf0,
8457 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8458 },
8459 { &hf_oran_reserved_last_4bits,
8460 { "reserved", "oran_fh_cus.reserved",
8461 FT_UINT8, BASE_HEX,
8462 NULL((void*)0), 0x0f,
8463 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8464 },
8465 { &hf_oran_reserved_last_5bits,
8466 { "reserved", "oran_fh_cus.reserved",
8467 FT_UINT8, BASE_HEX,
8468 NULL((void*)0), 0x1f,
8469 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8470 },
8471 { &hf_oran_reserved_6bits,
8472 { "reserved", "oran_fh_cus.reserved",
8473 FT_UINT8, BASE_HEX,
8474 NULL((void*)0), 0xfc,
8475 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8476 },
8477 { &hf_oran_reserved_last_6bits,
8478 { "reserved", "oran_fh_cus.reserved",
8479 FT_UINT8, BASE_HEX,
8480 NULL((void*)0), 0x3f,
8481 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8482 },
8483 { &hf_oran_reserved_7bits,
8484 { "reserved", "oran_fh_cus.reserved",
8485 FT_UINT8, BASE_HEX,
8486 NULL((void*)0), 0xfe,
8487 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8488 },
8489 { &hf_oran_reserved_last_7bits,
8490 { "reserved", "oran_fh_cus.reserved",
8491 FT_UINT8, BASE_HEX,
8492 NULL((void*)0), 0x7f,
8493 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8494 },
8495 { &hf_oran_reserved_8bits,
8496 { "reserved", "oran_fh_cus.reserved",
8497 FT_UINT8, BASE_HEX,
8498 NULL((void*)0), 0x0,
8499 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8500 },
8501 { &hf_oran_reserved_16bits,
8502 { "reserved", "oran_fh_cus.reserved",
8503 FT_UINT16, BASE_HEX,
8504 NULL((void*)0), 0x0,
8505 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8506 },
8507 { &hf_oran_reserved_15bits,
8508 { "reserved", "oran_fh_cus.reserved",
8509 FT_UINT16, BASE_HEX,
8510 NULL((void*)0), 0x7fff,
8511 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8512 },
8513 { &hf_oran_reserved_bit1,
8514 { "reserved", "oran_fh_cus.reserved",
8515 FT_UINT8, BASE_HEX,
8516 NULL((void*)0), 0x40,
8517 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8518 },
8519 { &hf_oran_reserved_bit2,
8520 { "reserved", "oran_fh_cus.reserved",
8521 FT_UINT8, BASE_HEX,
8522 NULL((void*)0), 0x20,
8523 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8524 },
8525 { &hf_oran_reserved_bit4,
8526 { "reserved", "oran_fh_cus.reserved",
8527 FT_UINT8, BASE_HEX,
8528 NULL((void*)0), 0x08,
8529 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8530 },
8531 { &hf_oran_reserved_bit5,
8532 { "reserved", "oran_fh_cus.reserved",
8533 FT_UINT8, BASE_HEX,
8534 NULL((void*)0), 0x04,
8535 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8536 },
8537 { &hf_oran_reserved_bits123,
8538 { "reserved", "oran_fh_cus.reserved",
8539 FT_UINT8, BASE_HEX,
8540 NULL((void*)0), 0x70,
8541 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8542 },
8543 { &hf_oran_reserved_bits456,
8544 { "reserved", "oran_fh_cus.reserved",
8545 FT_UINT8, BASE_HEX,
8546 NULL((void*)0), 0x0e,
8547 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8548 },
8549
8550 /* 7.7.11.9 */
8551 { &hf_oran_cont_ind,
8552 { "contInd", "oran_fh_cus.contInd",
8553 FT_BOOLEAN, 8,
8554 TFS(&continuity_indication_tfs)((0 ? (const struct true_false_string*)0 : ((&continuity_indication_tfs
))))
, 0x80,
8555 "PRB region continuity flag", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8556 },
8557 /* 7.7.11.10 */
8558 { &hf_oran_bundle_offset,
8559 { "BundleOffset", "oran_fh_cus.bundleOffset",
8560 FT_UINT8, BASE_DEC,
8561 NULL((void*)0), 0x3f,
8562 "offset between start of first PRB bundle and startPrbc", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8563 },
8564
8565 /* 7.7.1.2 bfwCompHdr (beamforming weight compression header) */
8566 { &hf_oran_bfwCompHdr,
8567 { "bfwCompHdr", "oran_fh_cus.bfwCompHdr",
8568 FT_STRING, BASE_NONE,
8569 NULL((void*)0), 0x0,
8570 "Compression method and IQ bit width for beamforming weights", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8571 },
8572 { &hf_oran_bfwCompHdr_iqWidth,
8573 { "IQ Bit Width", "oran_fh_cus.bfwCompHdr_iqWidth",
8574 FT_UINT8, BASE_HEX,
8575 VALS(bfw_comp_headers_iq_width)((0 ? (const struct _value_string*)0 : ((bfw_comp_headers_iq_width
))))
, 0xf0,
8576 "IQ bit width for the beamforming weights", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8577 },
8578 { &hf_oran_bfwCompHdr_compMeth,
8579 { "Compression Method", "oran_fh_cus.bfwCompHdr_compMeth",
8580 FT_UINT8, BASE_HEX,
8581 VALS(bfw_comp_headers_comp_meth)((0 ? (const struct _value_string*)0 : ((bfw_comp_headers_comp_meth
))))
, 0x0f,
8582 "compression method for the beamforming weights", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8583 },
8584
8585 /* 7.5.3.32 */
8586 { &hf_oran_ciCompParam,
8587 { "ciCompParam", "oran_fh_cus.ciCompParam",
8588 FT_STRING, BASE_NONE,
8589 NULL((void*)0), 0x0,
8590 "channel information compression parameter", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8591 },
8592
8593 /* Table 7.5.3.32-1 */
8594 { &hf_oran_blockScaler,
8595 { "blockScaler", "oran_fh_cus.blockScaler",
8596 FT_UINT8, BASE_HEX,
8597 NULL((void*)0), 0x0,
8598 "unsigned, 1 integer bit, 7 fractional bits", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8599 },
8600 { &hf_oran_compBitWidth,
8601 { "compBitWidth", "oran_fh_cus.compBitWidth",
8602 FT_UINT8, BASE_DEC,
8603 NULL((void*)0), 0xf0,
8604 "Length of I bits and length of Q bits after compression over entire PRB", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8605 },
8606 { &hf_oran_compShift,
8607 { "compShift", "oran_fh_cus.compShift",
8608 FT_UINT8, BASE_DEC,
8609 NULL((void*)0), 0x0f,
8610 "The shift applied to the entire PRB", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8611 },
8612
8613 { &hf_oran_active_beamspace_coefficient_n1,
8614 { "N1", "oran_fh_cus.activeBeamspace_Coefficient_n1",
8615 FT_BOOLEAN, 8,
8616 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x80,
8617 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8618 },
8619 { &hf_oran_active_beamspace_coefficient_n2,
8620 { "N2", "oran_fh_cus.activeBeamspace_Coefficient_n2",
8621 FT_BOOLEAN, 8,
8622 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x40,
8623 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8624 },
8625 { &hf_oran_active_beamspace_coefficient_n3,
8626 { "N3", "oran_fh_cus.activeBeamspace_Coefficient_n3",
8627 FT_BOOLEAN, 8,
8628 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x20,
8629 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8630 },
8631 { &hf_oran_active_beamspace_coefficient_n4,
8632 { "N4", "oran_fh_cus.activeBeamspace_Coefficient_n4",
8633 FT_BOOLEAN, 8,
8634 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x10,
8635 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8636 },
8637 { &hf_oran_active_beamspace_coefficient_n5,
8638 { "N5", "oran_fh_cus.activeBeamspace_Coefficient_n5",
8639 FT_BOOLEAN, 8,
8640 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x08,
8641 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8642 },
8643 { &hf_oran_active_beamspace_coefficient_n6,
8644 { "N6", "oran_fh_cus.activeBeamspace_Coefficient_n6",
8645 FT_BOOLEAN, 8,
8646 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x04,
8647 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8648 },
8649 { &hf_oran_active_beamspace_coefficient_n7,
8650 { "N7", "oran_fh_cus.activeBeamspace_Coefficient_n7",
8651 FT_BOOLEAN, 8,
8652 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x02,
8653 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8654 },
8655 { &hf_oran_active_beamspace_coefficient_n8,
8656 { "N8", "oran_fh_cus.activeBeamspace_Coefficient_n8",
8657 FT_BOOLEAN, 8,
8658 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x01,
8659 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8660 },
8661
8662 { &hf_oran_activeBeamspaceCoefficientMask,
8663 { "activeBeamspaceCoefficientMask", "oran_fh_cus.activeBeamspaceCoefficientMask",
8664 FT_UINT8, BASE_HEX,
8665 NULL((void*)0), 0xff,
8666 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8667 },
8668 { &hf_oran_activeBeamspaceCoefficientMask_bits_set,
8669 { "Array elements set", "oran_fh_cus.activeBeamspaceCoefficientMask.bits-set",
8670 FT_UINT32, BASE_DEC,
8671 NULL((void*)0), 0x0,
8672 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8673 },
8674
8675 /* Section 7.7.6.6 */
8676 { &hf_oran_se6_repetition,
8677 { "repetition", "oran_fh_cus.repetition",
8678 FT_BOOLEAN, BASE_NONE,
8679 TFS(&repetition_se6_tfs)((0 ? (const struct true_false_string*)0 : ((&repetition_se6_tfs
))))
, 0x0,
8680 "Repetition of a highest priority data section for C-Plane", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8681 },
8682 /* 7.7.20.9 */
8683 { &hf_oran_rbgSize,
8684 { "rbgSize", "oran_fh_cus.rbgSize",
8685 FT_UINT8, BASE_HEX,
8686 VALS(rbg_size_vals)((0 ? (const struct _value_string*)0 : ((rbg_size_vals)))), 0x70,
8687 "Number of PRBs of the resource block groups allocated by the bit mask", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8688 },
8689 /* 7.7.20.10 */
8690 { &hf_oran_rbgMask,
8691 { "rbgMask", "oran_fh_cus.rbgMask",
8692 FT_UINT32, BASE_HEX,
8693 NULL((void*)0), 0x0fffffff,
8694 "Each bit indicates whether a corresponding resource block group is present", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8695 },
8696 /* 7.7.6.5. Also 7.7.12.3 and 7.7.19.5 */
8697 { &hf_oran_noncontig_priority,
8698 { "priority", "oran_fh_cus.priority",
8699 FT_UINT8, BASE_HEX,
8700 VALS(priority_vals)((0 ? (const struct _value_string*)0 : ((priority_vals)))), 0xc0,
8701 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8702 },
8703
8704 /* 7.7.6.4 */
8705 { &hf_oran_symbol_mask,
8706 { "symbolMask", "oran_fh_cus.symbolMask",
8707 FT_UINT16, BASE_HEX,
8708 NULL((void*)0), 0x3fff,
8709 "Each bit indicates whether the rbgMask applies to a given symbol in the slot", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8710 },
8711 { &hf_oran_symbol_mask_s13,
8712 { "symbol 13", "oran_fh_cus.symbolMask.symbol-13",
8713 FT_BOOLEAN, 16,
8714 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x2000,
8715 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8716 },
8717 { &hf_oran_symbol_mask_s12,
8718 { "symbol 12", "oran_fh_cus.symbolMask.symbol-12",
8719 FT_BOOLEAN, 16,
8720 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x1000,
8721 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8722 },
8723 { &hf_oran_symbol_mask_s11,
8724 { "symbol 11", "oran_fh_cus.symbolMask.symbol-11",
8725 FT_BOOLEAN, 16,
8726 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0800,
8727 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8728 },
8729 { &hf_oran_symbol_mask_s10,
8730 { "symbol 10", "oran_fh_cus.symbolMask.symbol-10",
8731 FT_BOOLEAN, 16,
8732 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0400,
8733 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8734 },
8735 { &hf_oran_symbol_mask_s9,
8736 { "symbol 9", "oran_fh_cus.symbolMask.symbol-9",
8737 FT_BOOLEAN, 16,
8738 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0200,
8739 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8740 },
8741 { &hf_oran_symbol_mask_s8,
8742 { "symbol 8", "oran_fh_cus.symbolMask.symbol-8",
8743 FT_BOOLEAN, 16,
8744 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0100,
8745 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8746 },
8747 { &hf_oran_symbol_mask_s7,
8748 { "symbol 7", "oran_fh_cus.symbolMask.symbol-7",
8749 FT_BOOLEAN, 16,
8750 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0080,
8751 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8752 },
8753 { &hf_oran_symbol_mask_s6,
8754 { "symbol 6", "oran_fh_cus.symbolMask.symbol-6",
8755 FT_BOOLEAN, 16,
8756 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0040,
8757 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8758 },
8759 { &hf_oran_symbol_mask_s5,
8760 { "symbol 5", "oran_fh_cus.symbolMask.symbol-5",
8761 FT_BOOLEAN, 16,
8762 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0020,
8763 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8764 },
8765 { &hf_oran_symbol_mask_s4,
8766 { "symbol 4", "oran_fh_cus.symbolMask.symbol-4",
8767 FT_BOOLEAN, 16,
8768 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0010,
8769 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8770 },
8771 { &hf_oran_symbol_mask_s3,
8772 { "symbol 3", "oran_fh_cus.symbolMask.symbol-3",
8773 FT_BOOLEAN, 16,
8774 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0008,
8775 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8776 },
8777 { &hf_oran_symbol_mask_s2,
8778 { "symbol 2", "oran_fh_cus.symbolMask.symbol-2",
8779 FT_BOOLEAN, 16,
8780 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0004,
8781 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8782 },
8783 { &hf_oran_symbol_mask_s1,
8784 { "symbol 1", "oran_fh_cus.symbolMask.symbol-1",
8785 FT_BOOLEAN, 16,
8786 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0002,
8787 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8788 },
8789 { &hf_oran_symbol_mask_s0,
8790 { "symbol 0", "oran_fh_cus.symbolMask.symbol-0",
8791 FT_BOOLEAN, 16,
8792 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0001,
8793 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8794 },
8795
8796
8797 /* 7.7.22.2 */
8798 { &hf_oran_ack_nack_req_id,
8799 { "ackNackReqId", "oran_fh_cus.ackNackReqId",
8800 FT_UINT16, BASE_HEX,
8801 NULL((void*)0), 0x0,
8802 "Indicates the ACK/NACK request ID of a section description", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8803 },
8804
8805 /* Subtree for next 2 items */
8806 { &hf_oran_frequency_range,
8807 { "Frequency Range", "oran_fh_cus.frequencyRange",
8808 FT_STRING, BASE_NONE,
8809 NULL((void*)0), 0x0,
8810 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8811 },
8812
8813 /* 7.7.12.4 */
8814 { &hf_oran_off_start_prb,
8815 { "offStartPrb", "oran_fh_cus.offStartPrb",
8816 FT_UINT8, BASE_DEC,
8817 NULL((void*)0), 0x0,
8818 "Offset of PRB range start", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8819 },
8820 /* 7.7.12.5 */
8821 { &hf_oran_num_prb,
8822 { "numPrb", "oran_fh_cus.numPrb",
8823 FT_UINT8, BASE_DEC,
8824 NULL((void*)0), 0x0,
8825 "Number of PRBs in PRB range", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8826 },
8827
8828 /* symbolId 8.3.3.7 */
8829 { &hf_oran_symbolId,
8830 { "Symbol Identifier", "oran_fh_cus.symbolId",
8831 FT_UINT8, BASE_DEC,
8832 NULL((void*)0), 0x3f,
8833 "Identifies a symbol number within a slot", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8834 },
8835
8836 /* startPrbu 8.3.3.11 */
8837 { &hf_oran_startPrbu,
8838 { "startPrbu", "oran_fh_cus.startPrbu",
8839 FT_UINT16, BASE_DEC,
8840 NULL((void*)0), 0x03ff,
8841 "starting PRB of user plane section", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8842 },
8843
8844 /* numPrbu 8.3.3.12 */
8845 { &hf_oran_numPrbu,
8846 { "numPrbu", "oran_fh_cus.numPrbu",
8847 FT_UINT8, BASE_DEC,
8848 NULL((void*)0), 0x0,
8849 "number of PRBs per user plane section", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8850 },
8851
8852 /* 7.7.1.3 */
8853 { &hf_oran_bfwCompParam,
8854 { "bfwCompParam", "oran_fh_cus.bfwCompParam",
8855 FT_STRING, BASE_NONE,
8856 NULL((void*)0), 0x0,
8857 "Beamforming weight compression parameter", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8858 },
8859
8860 /* 6.3.3.13 */
8861 { &hf_oran_udCompHdrMeth,
8862 { "User Data Compression Method", "oran_fh_cus.udCompHdrMeth",
8863 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
8864 RVALS(ud_comp_header_meth)((0 ? (const struct _range_string*)0 : ((ud_comp_header_meth)
)))
, 0x0f,
8865 "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)}
8866 },
8867 { &hf_oran_udCompHdrMeth_pref,
8868 { "User Data Compression Method", "oran_fh_cus.udCompHdrMeth",
8869 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
8870 RVALS(ud_comp_header_meth)((0 ? (const struct _range_string*)0 : ((ud_comp_header_meth)
)))
, 0x0,
8871 "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)}
8872 },
8873 /* 8.3.3.18 */
8874 { &hf_oran_udCompLen,
8875 { "udCompLen", "oran_fh_cus.udCompLen",
8876 FT_UINT16, BASE_DEC,
8877 NULL((void*)0), 0x0,
8878 "PRB field length in octets", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8879 },
8880
8881 /* 7.5.2.10 */
8882 { &hf_oran_udCompHdrIqWidth,
8883 { "User Data IQ width", "oran_fh_cus.udCompHdrWidth",
8884 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
8885 RVALS(ud_comp_header_width)((0 ? (const struct _range_string*)0 : ((ud_comp_header_width
))))
, 0xf0,
8886 "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)}
8887 },
8888 { &hf_oran_udCompHdrIqWidth_pref,
8889 { "User Data IQ width", "oran_fh_cus.udCompHdrWidth.pref",
8890 FT_UINT8, BASE_DEC,
8891 NULL((void*)0), 0x0,
8892 "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)}
8893 },
8894
8895 { &hf_oran_sinrCompHdrIqWidth_pref,
8896 { "SINR IQ width", "oran_fh_cus.sinrCompHdrWidth",
8897 FT_UINT8, BASE_DEC,
8898 NULL((void*)0), 0x0,
8899 "Defines the IQ bit width for SINR data in section type 9", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8900 },
8901 { &hf_oran_sinrCompHdrMeth_pref,
8902 { "SINR Compression Method", "oran_fh_cus.sinrCompHdrMeth",
8903 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
8904 RVALS(ud_comp_header_meth)((0 ? (const struct _range_string*)0 : ((ud_comp_header_meth)
)))
, 0x0,
8905 "Defines the compression method for SINR data in section type 9", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8906 },
8907
8908 /* Section 8.3.3.15 (not always present - depends upon meth) */
8909 { &hf_oran_udCompParam,
8910 { "User Data Compression Parameter", "oran_fh_cus.udCompParam",
8911 FT_STRING, BASE_NONE,
8912 NULL((void*)0), 0x0,
8913 "Applies to whatever compression method is specified by the associated sectionID's compMeth value", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8914 },
8915 /* 8.3.3.18 */
8916 { &hf_oran_sReSMask,
8917 { "sReSMask", "oran_fh_cus.sReSMask",
8918 FT_UINT16, BASE_HEX,
8919 NULL((void*)0), 0xf0ff,
8920 "selective RE sending mask", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8921 },
8922
8923 { &hf_oran_sReSMask_re12,
8924 { "RE-12", "oran_fh_cus.sReSMask-re12",
8925 FT_BOOLEAN, 16,
8926 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x8000,
8927 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8928 },
8929 { &hf_oran_sReSMask_re11,
8930 { "RE-11", "oran_fh_cus.sReSMask-re11",
8931 FT_BOOLEAN, 16,
8932 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x4000,
8933 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8934 },
8935 { &hf_oran_sReSMask_re10,
8936 { "RE-10", "oran_fh_cus.sReSMask-re10",
8937 FT_BOOLEAN, 16,
8938 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x2000,
8939 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8940 },
8941 { &hf_oran_sReSMask_re9,
8942 { "RE-9", "oran_fh_cus.sReSMask-re9",
8943 FT_BOOLEAN, 16,
8944 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x1000,
8945 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8946 },
8947 { &hf_oran_sReSMask_re8,
8948 { "RE-8", "oran_fh_cus.sReSMask-re8",
8949 FT_BOOLEAN, 16,
8950 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0080,
8951 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8952 },
8953 { &hf_oran_sReSMask_re7,
8954 { "RE-7", "oran_fh_cus.sReSMask-re7",
8955 FT_BOOLEAN, 16,
8956 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0040,
8957 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8958 },
8959 { &hf_oran_sReSMask_re6,
8960 { "RE-6", "oran_fh_cus.sReSMask-re6",
8961 FT_BOOLEAN, 16,
8962 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0020,
8963 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8964 },
8965 { &hf_oran_sReSMask_re5,
8966 { "RE-5", "oran_fh_cus.sReSMask-re5",
8967 FT_BOOLEAN, 16,
8968 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0010,
8969 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8970 },
8971 { &hf_oran_sReSMask_re4,
8972 { "RE-4", "oran_fh_cus.sReSMask-re4",
8973 FT_BOOLEAN, 16,
8974 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0008,
8975 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8976 },
8977 { &hf_oran_sReSMask_re3,
8978 { "RE-3", "oran_fh_cus.sReSMask-re3",
8979 FT_BOOLEAN, 16,
8980 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0004,
8981 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8982 },
8983 { &hf_oran_sReSMask_re2,
8984 { "RE-2", "oran_fh_cus.sReSMask-re2",
8985 FT_BOOLEAN, 16,
8986 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0002,
8987 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8988 },
8989 { &hf_oran_sReSMask_re1,
8990 { "RE-1", "oran_fh_cus.sReSMask-re1",
8991 FT_BOOLEAN, 16,
8992 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0001,
8993 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8994 },
8995
8996 /* 8.3.3.20 */
8997 { &hf_oran_sReSMask1,
8998 { "sReSMask1", "oran_fh_cus.sReSMask1",
8999 FT_UINT16, BASE_HEX,
9000 NULL((void*)0), 0x0fff,
9001 "selective RE sending mask 1", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9002 },
9003 /* 8.3.3.21 */
9004 { &hf_oran_sReSMask2,
9005 { "sReSMask2", "oran_fh_cus.sReSMask2",
9006 FT_UINT16, BASE_HEX,
9007 NULL((void*)0), 0x0fff,
9008 "selective RE sending mask 2", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9009 },
9010
9011 { &hf_oran_sReSMask1_2_re12,
9012 { "RE-12", "oran_fh_cus.sReSMask-re12",
9013 FT_BOOLEAN, 16,
9014 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0800,
9015 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9016 },
9017 { &hf_oran_sReSMask1_2_re11,
9018 { "RE-11", "oran_fh_cus.sReSMask-re11",
9019 FT_BOOLEAN, 16,
9020 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0400,
9021 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9022 },
9023 { &hf_oran_sReSMask1_2_re10,
9024 { "RE-10", "oran_fh_cus.sReSMask-re10",
9025 FT_BOOLEAN, 16,
9026 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0200,
9027 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9028 },
9029 { &hf_oran_sReSMask1_2_re9,
9030 { "RE-9", "oran_fh_cus.sReSMask-re9",
9031 FT_BOOLEAN, 16,
9032 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0100,
9033 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9034 },
9035
9036 /* Section 6.3.3.15 */
9037 { &hf_oran_iSample,
9038 { "iSample", "oran_fh_cus.iSample",
9039 FT_FLOAT, BASE_NONE,
9040 NULL((void*)0), 0x0,
9041 "In-phase Sample value", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9042 },
9043
9044 /* Section 6.3.3.16 */
9045 { &hf_oran_qSample,
9046 { "qSample", "oran_fh_cus.qSample",
9047 FT_FLOAT, BASE_NONE,
9048 NULL((void*)0), 0x0,
9049 "Quadrature Sample value", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9050 },
9051
9052 { &hf_oran_exponent,
9053 { "Exponent", "oran_fh_cus.exponent",
9054 FT_UINT8, BASE_DEC,
9055 NULL((void*)0), 0x0f,
9056 "Exponent applicable to the I & Q mantissas", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9057 },
9058
9059 { &hf_oran_iq_user_data,
9060 { "IQ User Data", "oran_fh_cus.iq_user_data",
9061 FT_BYTES, BASE_NONE,
9062 NULL((void*)0), 0x0,
9063 "Used for the In-phase and Quadrature sample mantissa", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9064 },
9065
9066
9067 { &hf_oran_u_section_ul_symbol_time,
9068 { "Microseconds since first UL U-plane frame for this symbol", "oran_fh_cus.us-since-first-ul-frame",
9069 FT_UINT32, BASE_DEC,
9070 NULL((void*)0), 0x0,
9071 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9072 },
9073 { &hf_oran_u_section_ul_symbol_frames,
9074 { "Number of UL frames sent for this symbol", "oran_fh_cus.number-ul-frames-in-symbol",
9075 FT_UINT32, BASE_DEC,
9076 NULL((void*)0), 0x0,
9077 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9078 },
9079 { &hf_oran_u_section_ul_symbol_first_frame,
9080 { "First UL frame for this symbol", "oran_fh_cus.first-ul-frame-in-symbol",
9081 FT_FRAMENUM, BASE_NONE,
9082 FRAMENUM_TYPE(FT_FRAMENUM_NONE)((gpointer) (glong) (FT_FRAMENUM_NONE)), 0x0,
9083 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9084 },
9085 { &hf_oran_u_section_ul_symbol_last_frame,
9086 { "Last UL frame for this symbol", "oran_fh_cus.last-ul-frame-in-symbol",
9087 FT_FRAMENUM, BASE_NONE,
9088 FRAMENUM_TYPE(FT_FRAMENUM_NONE)((gpointer) (glong) (FT_FRAMENUM_NONE)), 0x0,
9089 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9090 },
9091
9092 { &hf_oran_c_eAxC_ID,
9093 { "c_eAxC_ID", "oran_fh_cus.c_eaxc_id",
9094 FT_STRING, BASE_NONE,
9095 NULL((void*)0), 0x0,
9096 "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) }
9097 },
9098
9099 { &hf_oran_refa,
9100 { "RefA", "oran_fh_cus.refa",
9101 FT_STRING, BASE_NONE,
9102 NULL((void*)0), 0x0,
9103 "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) }
9104 },
9105
9106
9107 /* Section 7.5.2.15 */
9108 { &hf_oran_ciCompHdr,
9109 { "ciCompHdr", "oran_fh_cus.ciCompHdr",
9110 FT_STRING, BASE_NONE,
9111 NULL((void*)0), 0x0,
9112 "Channel Information Compression Header", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9113 },
9114 { &hf_oran_ciCompHdrMeth,
9115 { "User Data Compression Method", "oran_fh_cus.ciCompHdrMeth",
9116 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
9117 RVALS(ud_comp_header_meth)((0 ? (const struct _range_string*)0 : ((ud_comp_header_meth)
)))
, 0x0e,
9118 "Compression method for Channel Information", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9119 },
9120 { &hf_oran_ciCompHdrIqWidth,
9121 { "User Data IQ width", "oran_fh_cus.ciCompHdrWidth",
9122 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
9123 RVALS(ud_comp_header_width)((0 ? (const struct _range_string*)0 : ((ud_comp_header_width
))))
, 0xf0,
9124 "IQ bit width for Channel Information", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9125 },
9126 { &hf_oran_ciCompOpt,
9127 { "ciCompOpt", "oran_fh_cus.ciCompOpt",
9128 FT_UINT8, BASE_DEC,
9129 VALS(ci_comp_opt_vals)((0 ? (const struct _value_string*)0 : ((ci_comp_opt_vals)))), 0x01,
9130 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9131 },
9132
9133 /* 7.7.11.7 */
9134 { &hf_oran_disable_bfws,
9135 { "disableBFWs", "oran_fh_cus.disableBFWs",
9136 FT_BOOLEAN, 8,
9137 NULL((void*)0), 0x80,
9138 "Indicate if BFWs under section extension are disabled", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9139 },
9140 /* 7.7.11.8 */
9141 { &hf_oran_rad,
9142 { "RAD", "oran_fh_cus.rad",
9143 FT_BOOLEAN, 8,
9144 NULL((void*)0), 0x40,
9145 "Reset After PRB Discontinuity", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9146 },
9147 /* 7.7.11.4 */
9148 { &hf_oran_num_bund_prbs,
9149 { "numBundPrb", "oran_fh_cus.numBundPrb",
9150 FT_UINT8, BASE_DEC,
9151 NULL((void*)0), 0x0,
9152 "Number of bundled PRBs per BFWs", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9153 },
9154 { &hf_oran_beam_id,
9155 { "beamId", "oran_fh_cus.beamId",
9156 FT_UINT16, BASE_DEC,
9157 NULL((void*)0), 0x7fff,
9158 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9159 },
9160 { &hf_oran_num_weights_per_bundle,
9161 { "Num weights per bundle", "oran_fh_cus.num_weights_per_bundle",
9162 FT_UINT16, BASE_DEC,
9163 NULL((void*)0), 0x0,
9164 "From dissector preference", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9165 },
9166
9167 { &hf_oran_samples_prb,
9168 {"PRB", "oran_fh_cus.prb",
9169 FT_STRING, BASE_NONE,
9170 NULL((void*)0), 0x0,
9171 "Grouping of samples for a particular Physical Resource Block", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9172 },
9173
9174 /* 7.5.3.13 */
9175 { &hf_oran_ciSample,
9176 { "ciSample", "oran_fh_cus.ciSample",
9177 FT_STRING, BASE_NONE,
9178 NULL((void*)0), 0x0,
9179 "Sample (I and Q values)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9180 },
9181 { &hf_oran_ciIsample,
9182 { "ciIsample", "oran_fh_cus.ciISample",
9183 FT_FLOAT, BASE_NONE,
9184 NULL((void*)0), 0x0,
9185 "Channel information complex value - I part", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9186 },
9187 { &hf_oran_ciQsample,
9188 { "ciQsample", "oran_fh_cus.ciQSample",
9189 FT_FLOAT, BASE_NONE,
9190 NULL((void*)0), 0x0,
9191 "Channel information complex value - Q part", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9192 },
9193
9194 /* 7.7.10.2 */
9195 { &hf_oran_beamGroupType,
9196 { "beamGroupType", "oran_fh_cus.beamGroupType",
9197 FT_UINT8, BASE_DEC,
9198 VALS(beam_group_type_vals)((0 ? (const struct _value_string*)0 : ((beam_group_type_vals
))))
, 0xc0,
9199 "The type of beam grouping", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9200 },
9201 /* 7.7.10.3 */
9202 { &hf_oran_numPortc,
9203 { "numPortc", "oran_fh_cus.numPortc",
9204 FT_UINT8, BASE_DEC,
9205 NULL((void*)0), 0x3f,
9206 "The number of eAxC ports", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9207 },
9208
9209 /* 7.7.4.2 (1 bit) */
9210 { &hf_oran_csf,
9211 { "csf", "oran_fh_cus.csf",
9212 FT_BOOLEAN, BASE_NONE,
9213 NULL((void*)0), 0x0,
9214 "constellation shift flag", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9215 },
9216 /* 7.7.4.3 */
9217 { &hf_oran_modcompscaler,
9218 { "modCompScaler", "oran_fh_cus.modcompscaler",
9219 FT_UINT16, BASE_DEC,
9220 NULL((void*)0), 0x7fff,
9221 "modulation compression scaler value", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9222 },
9223
9224 /* 7.7.5.1 */
9225 { &hf_oran_modcomp_param_set,
9226 { "Set", "oran_fh_cus.modcomp-param-set",
9227 FT_STRING, BASE_NONE,
9228 NULL((void*)0), 0x0,
9229 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9230 },
9231
9232
9233
9234 /* mcScaleReMask 7.7.5.2 (12 bits) */
9235
9236 /* First entry (starts with msb within byte) */
9237 { &hf_oran_mc_scale_re_mask_re1,
9238 { "RE 1", "oran_fh_cus.mcscalermask-RE1",
9239 FT_BOOLEAN, 16,
9240 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x8000,
9241 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9242 },
9243 { &hf_oran_mc_scale_re_mask_re2,
9244 { "RE 2", "oran_fh_cus.mcscalermask-RE2",
9245 FT_BOOLEAN, 16,
9246 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x4000,
9247 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9248 },
9249 { &hf_oran_mc_scale_re_mask_re3,
9250 { "RE 3", "oran_fh_cus.mcscalermask-RE3",
9251 FT_BOOLEAN, 16,
9252 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x2000,
9253 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9254 },
9255 { &hf_oran_mc_scale_re_mask_re4,
9256 { "RE 4", "oran_fh_cus.mcscalermask-RE4",
9257 FT_BOOLEAN, 16,
9258 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x1000,
9259 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9260 },
9261 { &hf_oran_mc_scale_re_mask_re5,
9262 { "RE 5", "oran_fh_cus.mcscalermask-RE5",
9263 FT_BOOLEAN, 16,
9264 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0800,
9265 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9266 },
9267 { &hf_oran_mc_scale_re_mask_re6,
9268 { "RE 6", "oran_fh_cus.mcscalermask-RE6",
9269 FT_BOOLEAN, 16,
9270 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0400,
9271 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9272 },
9273 { &hf_oran_mc_scale_re_mask_re7,
9274 { "RE 7", "oran_fh_cus.mcscalermask-RE7",
9275 FT_BOOLEAN, 16,
9276 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0200,
9277 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9278 },
9279 { &hf_oran_mc_scale_re_mask_re8,
9280 { "RE 8", "oran_fh_cus.mcscalermask-RE8",
9281 FT_BOOLEAN, 16,
9282 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0100,
9283 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9284 },
9285 { &hf_oran_mc_scale_re_mask_re9,
9286 { "RE 9", "oran_fh_cus.mcscalermask-RE9",
9287 FT_BOOLEAN, 16,
9288 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0080,
9289 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9290 },
9291 { &hf_oran_mc_scale_re_mask_re10,
9292 { "RE 10", "oran_fh_cus.mcscalermask-RE10",
9293 FT_BOOLEAN, 16,
9294 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0040,
9295 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9296 },
9297 { &hf_oran_mc_scale_re_mask_re11,
9298 { "RE 11", "oran_fh_cus.mcscalermask-RE11",
9299 FT_BOOLEAN, 16,
9300 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0020,
9301 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9302 },
9303 { &hf_oran_mc_scale_re_mask_re12,
9304 { "RE 12", "oran_fh_cus.mcscalermask-RE12",
9305 FT_BOOLEAN, 16,
9306 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0010,
9307 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9308 },
9309
9310 /* Even tries entry (starts with 5th bit within byte) */
9311 { &hf_oran_mc_scale_re_mask_re1_even,
9312 { "RE 1", "oran_fh_cus.mcscalermask-RE1",
9313 FT_BOOLEAN, 16,
9314 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0800,
9315 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9316 },
9317 { &hf_oran_mc_scale_re_mask_re2_even,
9318 { "RE 2", "oran_fh_cus.mcscalermask-RE2",
9319 FT_BOOLEAN, 16,
9320 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0400,
9321 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9322 },
9323 { &hf_oran_mc_scale_re_mask_re3_even,
9324 { "RE 3", "oran_fh_cus.mcscalermask-RE3",
9325 FT_BOOLEAN, 16,
9326 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0200,
9327 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9328 },
9329 { &hf_oran_mc_scale_re_mask_re4_even,
9330 { "RE 4", "oran_fh_cus.mcscalermask-RE4",
9331 FT_BOOLEAN, 16,
9332 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0100,
9333 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9334 },
9335 { &hf_oran_mc_scale_re_mask_re5_even,
9336 { "RE 5", "oran_fh_cus.mcscalermask-RE5",
9337 FT_BOOLEAN, 16,
9338 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0080,
9339 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9340 },
9341 { &hf_oran_mc_scale_re_mask_re6_even,
9342 { "RE 6", "oran_fh_cus.mcscalermask-RE6",
9343 FT_BOOLEAN, 16,
9344 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0040,
9345 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9346 },
9347 { &hf_oran_mc_scale_re_mask_re7_even,
9348 { "RE 7", "oran_fh_cus.mcscalermask-RE7",
9349 FT_BOOLEAN, 16,
9350 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0020,
9351 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9352 },
9353 { &hf_oran_mc_scale_re_mask_re8_even,
9354 { "RE 8", "oran_fh_cus.mcscalermask-RE8",
9355 FT_BOOLEAN, 16,
9356 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0010,
9357 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9358 },
9359 { &hf_oran_mc_scale_re_mask_re9_even,
9360 { "RE 9", "oran_fh_cus.mcscalermask-RE9",
9361 FT_BOOLEAN, 16,
9362 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0008,
9363 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9364 },
9365 { &hf_oran_mc_scale_re_mask_re10_even,
9366 { "RE 10", "oran_fh_cus.mcscalermask-RE10",
9367 FT_BOOLEAN, 16,
9368 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0004,
9369 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9370 },
9371 { &hf_oran_mc_scale_re_mask_re11_even,
9372 { "RE 11", "oran_fh_cus.mcscalermask-RE11",
9373 FT_BOOLEAN, 16,
9374 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0002,
9375 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9376 },
9377 { &hf_oran_mc_scale_re_mask_re12_even,
9378 { "RE 12", "oran_fh_cus.mcscalermask-RE12",
9379 FT_BOOLEAN, 16,
9380 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0001,
9381 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9382 },
9383
9384 { &hf_oran_mc_scale_re_mask,
9385 { "mcScaleReMask", "oran_fh_cus.mcscaleremask",
9386 FT_UINT16, BASE_HEX,
9387 NULL((void*)0), 0xfff0,
9388 "modulation compression power scale RE mask", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9389 },
9390 { &hf_oran_mc_scale_re_mask_even,
9391 { "mcScaleReMask", "oran_fh_cus.mcscaleremask",
9392 FT_UINT16, BASE_HEX,
9393 NULL((void*)0), 0x0fff,
9394 "modulation compression power scale RE mask", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9395 },
9396
9397 /* mcScaleOffset 7.7.5.4 (15 bits) */
9398 { &hf_oran_mc_scale_offset,
9399 { "mcScaleOffset", "oran_fh_cus.mcscaleoffset",
9400 FT_UINT24, BASE_DEC,
9401 NULL((void*)0), 0x0,
9402 "scaling value for modulation compression", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9403 },
9404 /* eAxCmask (7.7.7.2) */
9405 { &hf_oran_eAxC_mask,
9406 { "eAxC Mask", "oran_fh_cus.eaxcmask",
9407 FT_UINT16, BASE_HEX,
9408 NULL((void*)0), 0xffff,
9409 "Which eAxC_ID values the C-Plane message applies to", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9410 },
9411 /* technology (interface name) 7.7.9.2 */
9412 { &hf_oran_technology,
9413 { "Technology", "oran_fh_cus.technology",
9414 FT_UINT8, BASE_DEC,
9415 VALS(interface_name_vals)((0 ? (const struct _value_string*)0 : ((interface_name_vals)
)))
, 0x0,
9416 "Interface name (that C-PLane section applies to)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9417 },
9418 /* Exttype 14 (7.7.14.2) */
9419 { &hf_oran_nullLayerInd,
9420 { "nullLayerInd", "oran_fh_cus.nulllayerind",
9421 FT_BOOLEAN, BASE_NONE,
9422 NULL((void*)0), 0x0,
9423 "Whether corresponding layer is nulling-layer or not", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9424 },
9425
9426 /* Exttype 19 */
9427 /* 7.7.19.3 */
9428 { &hf_oran_se19_repetition,
9429 { "repetition", "oran_fh_cus.repetition",
9430 FT_BOOLEAN, BASE_NONE,
9431 TFS(&repetition_se19_tfs)((0 ? (const struct true_false_string*)0 : ((&repetition_se19_tfs
))))
, 0x0,
9432 "repeat port info flag", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9433 },
9434 /* 7.7.19.8 */
9435 /* TODO: break down into each RE as done for 7.5.3.5 ? */
9436 { &hf_oran_portReMask,
9437 { "portReMask", "oran_fh_cus.portReMask",
9438 FT_BOOLEAN, 16,
9439 TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, 0x0fff,
9440 "RE bitmask per port", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9441 },
9442 /* 7.7.19.9 */
9443 { &hf_oran_portSymbolMask,
9444 { "portSymbolMask", "oran_fh_cus.portSymbolMask",
9445 FT_BOOLEAN, 16,
9446 TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, 0x3fff,
9447 "Symbol bitmask port port", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9448 },
9449
9450 { &hf_oran_ext19_port,
9451 {"Port", "oran_fh_cus.ext19.port",
9452 FT_STRING, BASE_NONE,
9453 NULL((void*)0), 0x0,
9454 "Entry for a given port in ext19", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9455 },
9456
9457 /* Ext 13 */
9458 { &hf_oran_prb_allocation,
9459 {"PRB allocation", "oran_fh_cus.prb-allocation",
9460 FT_STRING, BASE_NONE,
9461 NULL((void*)0), 0x0,
9462 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9463 },
9464 /* 7.7.13.2 */
9465 { &hf_oran_nextSymbolId,
9466 { "nextSymbolId", "oran_fh_cus.nextSymbolId",
9467 FT_UINT8, BASE_DEC,
9468 NULL((void*)0), 0x3c,
9469 "offset of PRB range start", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9470 },
9471 /* 7.7.13.3 */
9472 { &hf_oran_nextStartPrbc,
9473 { "nextStartPrbc", "oran_fh_cus.nextStartPrbc",
9474 FT_UINT16, BASE_DEC,
9475 NULL((void*)0), 0x03ff,
9476 "number of PRBs in PRB range", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9477 },
9478
9479 /* Puncturing patters as appears in SE 20 */
9480 { &hf_oran_puncPattern,
9481 { "puncPattern", "oran_fh_cus.puncPattern",
9482 FT_STRING, BASE_NONE,
9483 NULL((void*)0), 0x0,
9484 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9485 },
9486
9487 /* 7.7.20.2 numPuncPatterns */
9488 { &hf_oran_numPuncPatterns,
9489 { "numPuncPatterns", "oran_fh_cus.numPuncPatterns",
9490 FT_UINT8, BASE_DEC,
9491 NULL((void*)0), 0x0,
9492 "number of puncturing patterns", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9493 },
9494 /* 7.7.20.3 symbolMask */
9495 { &hf_oran_symbolMask_ext20,
9496 { "symbolMask", "oran_fh_cus.symbolMask",
9497 FT_UINT16, BASE_HEX,
9498 NULL((void*)0), 0xfffc,
9499 "Bitmask where each bit indicates the symbols associated with the puncturing pattern", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9500 },
9501 /* 7.7.20.4 startPuncPrb */
9502 { &hf_oran_startPuncPrb,
9503 { "startPuncPrb", "oran_fh_cus.startPuncPrb",
9504 FT_UINT16, BASE_DEC,
9505 NULL((void*)0), 0x03ff,
9506 "starting PRB to which one puncturing pattern applies", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9507 },
9508 /* 7.7.20.5 numPuncPrb */
9509 { &hf_oran_numPuncPrb,
9510 { "numPuncPrb", "oran_fh_cus.numPuncPrb",
9511 FT_UINT8, BASE_DEC,
9512 NULL((void*)0), 0x0,
9513 "the number of PRBs of the puncturing pattern", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9514 },
9515 /* 7.7.20.6 puncReMask */
9516 { &hf_oran_puncReMask,
9517 { "puncReMask", "oran_fh_cus.puncReMask",
9518 FT_UINT16, BASE_DEC,
9519 NULL((void*)0), 0xffc0,
9520 "puncturing pattern RE mask", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9521 },
9522 /* 7.7.20.12 multiSDScope */
9523 { &hf_oran_multiSDScope,
9524 { "multiSDScope", "oran_fh_cus.multiSDScope",
9525 FT_BOOLEAN, 8,
9526 TFS(&multi_sd_scope_tfs)((0 ? (const struct true_false_string*)0 : ((&multi_sd_scope_tfs
))))
, 0x02,
9527 "multiple section description scope flag", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9528 },
9529 /* 7.7.20.4 rbgIncl */
9530 { &hf_oran_RbgIncl,
9531 { "rbgIncl", "oran_fh_cus.rbgIncl",
9532 FT_BOOLEAN, 8,
9533 NULL((void*)0), 0x01,
9534 "rbg included flag", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9535 },
9536
9537 /* 7.7.21.2 ciPrbGroupSize */
9538 { &hf_oran_ci_prb_group_size,
9539 { "ciPrbGroupSize", "oran_fh_cus.ciPrbGroupSize",
9540 FT_UINT8, BASE_DEC,
9541 NULL((void*)0), 0x0,
9542 "channel information PRB group size", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9543 },
9544 /* 7.21.3 */
9545 { &hf_oran_prg_size_st5,
9546 { "prgSize", "oran_fh_cus.prgSize",
9547 FT_UINT8, BASE_DEC,
9548 VALS(prg_size_st5_vals)((0 ? (const struct _value_string*)0 : ((prg_size_st5_vals)))
)
, 0x03,
9549 "precoding resource block group size", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9550 },
9551 { &hf_oran_prg_size_st6,
9552 { "prgSize", "oran_fh_cus.prgSize",
9553 FT_UINT8, BASE_DEC,
9554 VALS(prg_size_st6_vals)((0 ? (const struct _value_string*)0 : ((prg_size_st6_vals)))
)
, 0x03,
9555 "precoding resource block group size", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9556 },
9557
9558 /* 7.7.17.2 numUeID */
9559 { &hf_oran_num_ueid,
9560 { "numUeID", "oran_fh_cus.numUeID",
9561 FT_UINT8, BASE_DEC,
9562 NULL((void*)0), 0x0,
9563 "number of ueIDs per user", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9564 },
9565
9566 /* 7.7.16.2 antMask */
9567 { &hf_oran_antMask,
9568 { "antMask", "oran_fh_cus.antMask",
9569 FT_UINT64, BASE_HEX,
9570 NULL((void*)0), 0xffffffffffffffff,
9571 "indices of antennas to be pre-combined per RX endpoint", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9572 },
9573
9574 /* 7.7.18.2 transmissionWindowOffset */
9575 { &hf_oran_transmissionWindowOffset,
9576 { "transmissionWindowOffset", "oran_fh_cus.transmissionWindowOffset",
9577 FT_UINT16, BASE_DEC,
9578 NULL((void*)0), 0x0,
9579 "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)}
9580 },
9581 /* 7.7.18.3 transmissionWindowSize */
9582 { &hf_oran_transmissionWindowSize,
9583 { "transmissionWindowSize", "oran_fh_cus.transmissionWindowSize",
9584 FT_UINT16, BASE_DEC,
9585 NULL((void*)0), 0x3fff,
9586 "size of the transmission window in resolution µs", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9587 },
9588 /* 7.7.18.4 toT */
9589 { &hf_oran_toT,
9590 { "toT", "oran_fh_cus.toT",
9591 FT_UINT8, BASE_DEC,
9592 VALS(type_of_transmission_vals)((0 ? (const struct _value_string*)0 : ((type_of_transmission_vals
))))
, 0x03,
9593 "type of transmission", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9594 },
9595
9596 /* 7.7.2.2 bfaCompHdr */
9597 { &hf_oran_bfaCompHdr,
9598 { "bfaCompHdr", "oran_fh_cus.bfaCompHdr",
9599 FT_STRING, BASE_NONE,
9600 NULL((void*)0), 0x0,
9601 "beamforming attributes compression header", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9602 },
9603 /* 7.7.2.2-2: bfAzPtWidth */
9604 { &hf_oran_bfAzPtWidth,
9605 { "bfAzPtWidth", "oran_fh_cus.bfAzPtWidth",
9606 FT_UINT8, BASE_DEC,
9607 VALS(bfa_bw_vals)((0 ? (const struct _value_string*)0 : ((bfa_bw_vals)))), 0x38,
9608 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9609 },
9610 /* 7.7.2.2-3: bfZePtWidth */
9611 { &hf_oran_bfZePtWidth,
9612 { "bfZePtWidth", "oran_fh_cus.bfZePtWidth",
9613 FT_UINT8, BASE_DEC,
9614 VALS(bfa_bw_vals)((0 ? (const struct _value_string*)0 : ((bfa_bw_vals)))), 0x07,
9615 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9616 },
9617 /* 7.7.2.2-4: bfAz3ddWidth */
9618 { &hf_oran_bfAz3ddWidth,
9619 { "bfAz3ddWidth", "oran_fh_cus.bfAz3ddWidth",
9620 FT_UINT8, BASE_DEC,
9621 VALS(bfa_bw_vals)((0 ? (const struct _value_string*)0 : ((bfa_bw_vals)))), 0x38,
9622 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9623 },
9624 /* 7.7.2.2-5: bfZe3ddWidth */
9625 { &hf_oran_bfZe3ddWidth,
9626 { "bfZe3ddWidth", "oran_fh_cus.bfZe3ddWidth",
9627 FT_UINT8, BASE_DEC,
9628 VALS(bfa_bw_vals)((0 ? (const struct _value_string*)0 : ((bfa_bw_vals)))), 0x07,
9629 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9630 },
9631
9632 /* 7.7.2.3 bfAzPt */
9633 { &hf_oran_bfAzPt,
9634 { "bfAzPt", "oran_fh_cus.bfAzPt",
9635 FT_UINT8, BASE_DEC,
9636 NULL((void*)0), 0x0,
9637 "beamforming azimuth pointing parameter", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9638 },
9639 /* 7.7.2.4 bfZePt */
9640 { &hf_oran_bfZePt,
9641 { "bfZePt", "oran_fh_cus.bfZePt",
9642 FT_UINT8, BASE_DEC,
9643 NULL((void*)0), 0x0,
9644 "beamforming zenith pointing parameter", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9645 },
9646 /* 7.7.2.5 bfAz3dd */
9647 { &hf_oran_bfAz3dd,
9648 { "bfAz3dd", "oran_fh_cus.bfAz3dd",
9649 FT_UINT8, BASE_DEC,
9650 NULL((void*)0), 0x0,
9651 "beamforming azimuth beamwidth parameter", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9652 },
9653 /* 7.7.2.6 bfZe3dd */
9654 { &hf_oran_bfZe3dd,
9655 { "bfZe3dd", "oran_fh_cus.bfZe3dd",
9656 FT_UINT8, BASE_DEC,
9657 NULL((void*)0), 0x0,
9658 "beamforming zenith beamwidth parameter", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9659 },
9660
9661 /* 7.7.2.7 bfAzSl */
9662 { &hf_oran_bfAzSl,
9663 { "bfAzSl", "oran_fh_cus.bfAzSl",
9664 FT_UINT8, BASE_DEC,
9665 VALS(sidelobe_suppression_vals)((0 ? (const struct _value_string*)0 : ((sidelobe_suppression_vals
))))
, 0x38,
9666 "beamforming azimuth sidelobe parameter", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9667 },
9668 /* 7.7.2.8 bfZeSl */
9669 { &hf_oran_bfZeSl,
9670 { "bfZeSl", "oran_fh_cus.bfZeSl",
9671 FT_UINT8, BASE_DEC,
9672 VALS(sidelobe_suppression_vals)((0 ? (const struct _value_string*)0 : ((sidelobe_suppression_vals
))))
, 0x07,
9673 "beamforming zenith sidelobe parameter", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9674 },
9675
9676 /* 7.5.2.17 */
9677 { &hf_oran_cmd_scope,
9678 { "cmdScope", "oran_fh_cus.cmdScope",
9679 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
9680 RVALS(cmd_scope_vals)((0 ? (const struct _range_string*)0 : ((cmd_scope_vals)))), 0x0f,
9681 "command scope", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9682 },
9683 /* 7.5.2.18 */
9684 { &hf_oran_number_of_st4_cmds,
9685 { "numberOfST4Cmds", "oran_fh_cus.numberOfST4Cmds",
9686 FT_UINT8, BASE_DEC,
9687 NULL((void*)0), 0x0,
9688 "Number of Section Type 4 commands", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9689 },
9690
9691 { &hf_oran_st4_cmd_header,
9692 { "Command common header", "oran_fh_cus.st4CmdCommonHeader",
9693 FT_STRING, BASE_NONE,
9694 NULL((void*)0), 0x0,
9695 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9696 },
9697
9698 /* 7.5.3.38 */
9699 { &hf_oran_st4_cmd_type,
9700 { "st4CmdType", "oran_fh_cus.st4CmdType",
9701 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
9702 RVALS(st4_cmd_type_vals)((0 ? (const struct _range_string*)0 : ((st4_cmd_type_vals)))
)
, 0x0,
9703 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9704 },
9705 /* 7.5.3.39 */
9706 { &hf_oran_st4_cmd_len,
9707 { "st4CmdLen", "oran_fh_cus.st4CmdLen",
9708 FT_UINT16, BASE_DEC,
9709 NULL((void*)0), 0x0,
9710 "Length of command in 32-bit words", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9711 },
9712 /* 7.5.3.40 */
9713 { &hf_oran_st4_cmd_num_slots,
9714 { "numSlots", "oran_fh_cus.st4NumSlots",
9715 FT_UINT8, BASE_DEC,
9716 NULL((void*)0), 0x0,
9717 "Contiguous slots for which command is applicable", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9718 },
9719 /* 7.5.3.41 */
9720 { &hf_oran_st4_cmd_ack_nack_req_id,
9721 { "ackNackReqId", "oran_fh_cus.ackNackReqId",
9722 FT_UINT16, BASE_DEC,
9723 NULL((void*)0), 0x0,
9724 "ACK/NACK Request Id", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9725 },
9726
9727 { &hf_oran_st4_cmd,
9728 { "Command", "oran_fh_cus.st4Cmd",
9729 FT_STRING, BASE_NONE,
9730 NULL((void*)0), 0x0,
9731 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9732 },
9733
9734 /* 7.5.3.52 */
9735 { &hf_oran_sleepmode_trx,
9736 { "sleepMode", "oran_fh_cus.sleepMode",
9737 FT_UINT8, BASE_HEX,
9738 VALS(sleep_mode_trx_vals)((0 ? (const struct _value_string*)0 : ((sleep_mode_trx_vals)
)))
, 0x03,
9739 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9740 },
9741 { &hf_oran_sleepmode_asm,
9742 { "sleepMode", "oran_fh_cus.sleepMode",
9743 FT_UINT8, BASE_HEX,
9744 VALS(sleep_mode_asm_vals)((0 ? (const struct _value_string*)0 : ((sleep_mode_asm_vals)
)))
, 0x03,
9745 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9746 },
9747
9748 /* 7.5.3.51 */
9749 { &hf_oran_log2maskbits,
9750 { "log2MaskBits", "oran_fh_cus.log2MaskBits",
9751 FT_UINT8, BASE_HEX,
9752 VALS(log2maskbits_vals)((0 ? (const struct _value_string*)0 : ((log2maskbits_vals)))
)
, 0x3c,
9753 "Number of bits to appear in antMask", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9754 },
9755 /* 7.5.3.53 */
9756 { &hf_oran_num_slots_ext,
9757 { "numSlotsExt", "oran_fh_cus.numSlotsExt",
9758 FT_UINT24, BASE_HEX,
9759 NULL((void*)0), 0x0fffff,
9760 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9761 },
9762 /* 7.5.3.54 */
9763 { &hf_oran_antMask_trx_control,
9764 { "antMask", "oran_fh_cus.trxControl.antMask",
9765 FT_BYTES, BASE_NONE,
9766 NULL((void*)0), 0x0,
9767 "which antennas should sleep or wake-up", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9768 },
9769 /* 7.5.3.55 */
9770 { &hf_oran_ready,
9771 { "ready", "oran_fh_cus.ready",
9772 FT_BOOLEAN, 8,
9773 TFS(&ready_tfs)((0 ? (const struct true_false_string*)0 : ((&ready_tfs))
))
, 0x01,
9774 "wake-up ready indicator", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9775 },
9776 /* 7.5.3.34 */
9777 { &hf_oran_number_of_acks,
9778 { "numberOfAcks", "oran_fh_cus.numberOfAcks",
9779 FT_UINT8, BASE_DEC,
9780 NULL((void*)0), 0x0,
9781 "number of ACKs for one eAxC_ID", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9782 },
9783 /* 7.5.3.35 */
9784 { &hf_oran_number_of_nacks,
9785 { "numberOfNacks", "oran_fh_cus.numberOfNacks",
9786 FT_UINT8, BASE_DEC,
9787 NULL((void*)0), 0x0,
9788 "number of NACKs for one eAxC_ID", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9789 },
9790 /* 7.5.3.36 */
9791 { &hf_oran_ackid,
9792 { "ackId", "oran_fh_cus.ackId",
9793 FT_UINT16, BASE_DEC,
9794 NULL((void*)0), 0x0,
9795 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9796 },
9797 /* 7.5.3.37 */
9798 { &hf_oran_nackid,
9799 { "nackId", "oran_fh_cus.nackId",
9800 FT_UINT16, BASE_DEC,
9801 NULL((void*)0), 0x0,
9802 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9803 },
9804
9805 /* Links between acknack requests & responses */
9806 { &hf_oran_acknack_request_frame,
9807 { "Request Frame", "oran_fh_cus.ackNackId.request-frame",
9808 FT_FRAMENUM, BASE_NONE,
9809 FRAMENUM_TYPE(FT_FRAMENUM_REQUEST)((gpointer) (glong) (FT_FRAMENUM_REQUEST)), 0x0,
9810 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9811 },
9812 { &hf_oran_acknack_request_time,
9813 { "Time since request in ms", "oran_fh_cus.ackNackId.time-since-request",
9814 FT_UINT32, BASE_DEC,
9815 NULL((void*)0), 0x0,
9816 "Time between request and response", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9817 },
9818 { &hf_oran_acknack_request_type,
9819 { "Request Type", "oran_fh_cus.ackNackId.request-type",
9820 FT_UINT32, BASE_DEC,
9821 VALS(acknack_type_vals)((0 ? (const struct _value_string*)0 : ((acknack_type_vals)))
)
, 0x0,
9822 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9823 },
9824 { &hf_oran_acknack_response_frame,
9825 { "Response Frame", "oran_fh_cus.ackNackId.response-frame",
9826 FT_FRAMENUM, BASE_NONE,
9827 FRAMENUM_TYPE(FT_FRAMENUM_RESPONSE)((gpointer) (glong) (FT_FRAMENUM_RESPONSE)), 0x0,
9828 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9829 },
9830 { &hf_oran_acknack_response_time,
9831 { "Time to response in ms", "oran_fh_cus.ackNackId.time-to-response",
9832 FT_UINT32, BASE_DEC,
9833 NULL((void*)0), 0x0,
9834 "Time between request and response", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9835 },
9836
9837 /* 7.5.3.43 */
9838 { &hf_oran_disable_tdbfns,
9839 { "disableTDBFNs", "oran_fh_cus.disableTDBFNs",
9840 FT_BOOLEAN, 8,
9841 TFS(&disable_tdbfns_tfs)((0 ? (const struct true_false_string*)0 : ((&disable_tdbfns_tfs
))))
, 0x80,
9842 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9843 },
9844
9845 /* 7.5.3.44 */
9846 { &hf_oran_td_beam_group,
9847 { "tdBeamGrp", "oran_fh_cus.tdBeamGrp",
9848 FT_UINT16, BASE_HEX,
9849 NULL((void*)0), 0x7fff,
9850 "Applies to symbolMask in command header", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9851 },
9852 /* 7.5.3.43 */
9853 { &hf_oran_disable_tdbfws,
9854 { "disableTDBFWs", "oran_fh_cus.disableTDBFWs",
9855 FT_BOOLEAN, 8,
9856 TFS(&beam_numbers_included_tfs)((0 ? (const struct true_false_string*)0 : ((&beam_numbers_included_tfs
))))
, 0x80,
9857 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9858 },
9859
9860 /* 7.5.3.56 */
9861 { &hf_oran_td_beam_num,
9862 { "tdBeamNum", "oran_fh_cus.tdBeamNum",
9863 FT_UINT16, BASE_HEX,
9864 NULL((void*)0), 0x7fff,
9865 "time-domain beam number", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9866 },
9867
9868 /* 7.5.3.49 */
9869 { &hf_oran_dir_pattern,
9870 { "dirPattern", "oran_fh_cus.dirPattern",
9871 FT_BOOLEAN, 16,
9872 TFS(&symbol_direction_tfs)((0 ? (const struct true_false_string*)0 : ((&symbol_direction_tfs
))))
, 0x3fff,
9873 "symbol data direction (gNB Tx/Rx) pattern", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9874 },
9875 /* 7.5.3.50 */
9876 { &hf_oran_guard_pattern,
9877 { "guardPattern", "oran_fh_cus.guardPattern",
9878 FT_BOOLEAN, 16,
9879 TFS(&symbol_guard_tfs)((0 ? (const struct true_false_string*)0 : ((&symbol_guard_tfs
))))
, 0x3fff,
9880 "guard pattern bitmask", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9881 },
9882
9883 /* For convenient filtering */
9884 { &hf_oran_cplane,
9885 { "C-Plane", "oran_fh_cus.c-plane",
9886 FT_NONE, BASE_NONE,
9887 NULL((void*)0), 0x0,
9888 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9889 },
9890 { &hf_oran_uplane,
9891 { "U-Plane", "oran_fh_cus.u-plane",
9892 FT_NONE, BASE_NONE,
9893 NULL((void*)0), 0x0,
9894 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9895 },
9896 { &hf_oran_bf,
9897 { "BeamForming", "oran_fh_cus.bf",
9898 FT_NONE, BASE_NONE,
9899 NULL((void*)0), 0x0,
9900 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9901 },
9902 { &hf_oran_zero_prb,
9903 { "Zero PRB", "oran_fh_cus.zero-prb",
9904 FT_NONE, BASE_NONE,
9905 NULL((void*)0), 0x0,
9906 "All of the REs in this PRB are zero", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9907 },
9908 { &hf_oran_nonzero_prb,
9909 { "Non-Zero PRB", "oran_fh_cus.nonzero-prb",
9910 FT_NONE, BASE_NONE,
9911 NULL((void*)0), 0x0,
9912 "Not all of the REs in this PRB are zero", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9913 },
9914 { &hf_oran_bundle_weights_all_zero,
9915 { "Bundle Weights all zero", "oran_fh_cus.zero-bundle",
9916 FT_NONE, BASE_NONE,
9917 NULL((void*)0), 0x0,
9918 "All of the weights in a bundle are zero", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9919 },
9920
9921
9922 /* 5.1.3.2.7 */
9923 { &hf_oran_ecpri_pcid,
9924 { "ecpriPcid", "oran_fh_cus.ecpriPcid",
9925 FT_NONE, BASE_NONE,
9926 NULL((void*)0), 0x0,
9927 "IQ data transfer message series identifier", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9928 },
9929 { &hf_oran_ecpri_rtcid,
9930 { "ecpriRtcid", "oran_fh_cus.ecpriRtcid",
9931 FT_NONE, BASE_NONE,
9932 NULL((void*)0), 0x0,
9933 "Real time control data identifier", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9934 },
9935 /* 5.1.3.2.8 */
9936 { &hf_oran_ecpri_seqid,
9937 { "ecpriSeqid", "oran_fh_cus.ecpriSeqid",
9938 FT_NONE, BASE_NONE,
9939 NULL((void*)0), 0x0,
9940 "message identifier", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9941 },
9942
9943 /* 7.7.23.2 */
9944 { &hf_oran_num_sym_prb_pattern,
9945 { "numSymPrbPattern", "oran_fh_cus.numSymPrbPattern",
9946 FT_UINT8, BASE_DEC,
9947 NULL((void*)0), 0xf0,
9948 "number of symbol and resource block patterns", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9949 },
9950 /* 7.7.23.11 */
9951 { &hf_oran_prb_mode,
9952 { "prbMode", "oran_fh_cus.prbMode",
9953 FT_BOOLEAN, 8,
9954 TFS(&prb_mode_tfs)((0 ? (const struct true_false_string*)0 : ((&prb_mode_tfs
))))
, 0x01,
9955 "PRB Mode", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9956 },
9957
9958 { &hf_oran_sym_prb_pattern,
9959 { "symPrbPattern", "oran_fh_cus.symPrbPattern",
9960 FT_STRING, BASE_NONE,
9961 NULL((void*)0), 0x0,
9962 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9963 },
9964
9965 /* 7.7.23.3 */
9966 { &hf_oran_sym_mask,
9967 { "symMask", "oran_fh_cus.symMask",
9968 FT_UINT16, BASE_HEX,
9969 NULL((void*)0), 0x3fff,
9970 "symbol mask part of symPrbPattern", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9971 },
9972 /* 7.7.23.5 */
9973 {&hf_oran_num_mc_scale_offset,
9974 {"numMcScaleOffset", "oran_fh_cus.numMcScaleOffset",
9975 FT_UINT8, BASE_DEC,
9976 NULL((void*)0), 0xf0,
9977 "number of modulation compression scaling value per symPrbPattern",
9978 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9979 },
9980 /* 7.7.23.4 */
9981 { &hf_oran_prb_pattern,
9982 { "prbPattern", "oran_fh_cus.prbPattern",
9983 FT_UINT8, BASE_DEC,
9984 NULL((void*)0), 0x0f,
9985 "resource block pattern part of symPrbPattern", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9986 },
9987
9988 /* 7.7.3.2 */
9989 { &hf_oran_codebook_index,
9990 { "codebookIndex", "oran_fh_cus.codebookIndex",
9991 FT_UINT8, BASE_DEC,
9992 NULL((void*)0), 0x0,
9993 "precoder codebook used for transmission", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9994 },
9995 /* 7.7.3.3 */
9996 { &hf_oran_layerid,
9997 { "layerID", "oran_fh_cus.layerID",
9998 FT_UINT8, BASE_DEC,
9999 NULL((void*)0), 0xf0,
10000 "Layer ID for DL transmission", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10001 },
10002 /* 7.7.3.5 */
10003 { &hf_oran_numlayers,
10004 { "numLayers", "oran_fh_cus.numLayers",
10005 FT_UINT8, BASE_DEC,
10006 NULL((void*)0), 0x0f,
10007 "number of layers for DL transmission", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10008 },
10009 /* 7.7.3.4 */
10010 { &hf_oran_txscheme,
10011 { "txScheme", "oran_fh_cus.txScheme",
10012 FT_UINT8, BASE_DEC,
10013 NULL((void*)0), 0xf0,
10014 "transmission scheme", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10015 },
10016 /* 7.7.3.6 */
10017 { &hf_oran_crs_remask,
10018 { "crsReMask", "oran_fh_cus.crsReMask",
10019 FT_UINT16, BASE_HEX,
10020 NULL((void*)0), 0x0fff,
10021 "CRS resource element mask", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10022 },
10023 /* 7.7.3.8 */
10024 { &hf_oran_crs_shift,
10025 { "crsShift", "oran_fh_cus.crsShift",
10026 FT_UINT8, BASE_HEX,
10027 NULL((void*)0), 0x80,
10028 "CRS resource element mask", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10029 },
10030 /* 7.7.3.7 */
10031 { &hf_oran_crs_symnum,
10032 { "crsSymNum", "oran_fh_cus.crsSymNum",
10033 FT_UINT8, BASE_DEC,
10034 NULL((void*)0), 0x0f,
10035 "CRS symbol number indication", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10036 },
10037 /* 7.7.3.9 */
10038 { &hf_oran_beamid_ap1,
10039 { "beamIdAP1", "oran_fh_cus.beamIdAP1",
10040 FT_UINT16, BASE_DEC,
10041 NULL((void*)0), 0x7f,
10042 "beam id to be used for antenna port 1", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10043 },
10044 /* 7.7.3.10 */
10045 { &hf_oran_beamid_ap2,
10046 { "beamIdAP2", "oran_fh_cus.beamIdAP2",
10047 FT_UINT16, BASE_DEC,
10048 NULL((void*)0), 0x7f,
10049 "beam id to be used for antenna port 2", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10050 },
10051 /* 7.7.3.11 */
10052 { &hf_oran_beamid_ap3,
10053 { "beamIdAP3", "oran_fh_cus.beamIdAP3",
10054 FT_UINT16, BASE_DEC,
10055 NULL((void*)0), 0x7f,
10056 "beam id to be used for antenna port 3", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10057 },
10058
10059 /* 7.7.10.3a */
10060 { &hf_oran_port_list_index,
10061 { "portListIndex", "oran_fh_cus.portListIndex",
10062 FT_UINT8, BASE_DEC,
10063 NULL((void*)0), 0x0,
10064 "the index of an eAxC_ID in the port-list", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10065 },
10066
10067 { &hf_oran_alpn_per_sym,
10068 { "alpnPerSym", "oran_fh_cus.alpnPerSym",
10069 FT_UINT8, BASE_HEX,
10070 VALS(alpn_per_sym_vals)((0 ? (const struct _value_string*)0 : ((alpn_per_sym_vals)))
)
, 0x80,
10071 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10072 },
10073 { &hf_oran_ant_dmrs_snr,
10074 { "antDmrsSnr", "oran_fh_cus.antDmrsSnr",
10075 FT_UINT8, BASE_HEX,
10076 VALS(ant_dmrs_snr_vals)((0 ? (const struct _value_string*)0 : ((ant_dmrs_snr_vals)))
)
, 0x40,
10077 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10078 },
10079
10080 /* 7.7.24.6 */
10081 { &hf_oran_user_group_size,
10082 { "userGroupSize", "oran_fh_cus.userGroupSize",
10083 FT_UINT8, BASE_DEC,
10084 NULL((void*)0), 0x1f,
10085 "number of UE data layers in the user group identified by userGroupId", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10086 },
10087 /* 7.7.24.7 */
10088 { &hf_oran_user_group_id,
10089 { "userGroupId", "oran_fh_cus.userGroupId",
10090 FT_UINT8, BASE_DEC,
10091 NULL((void*)0), 0x0,
10092 "indicates user group described by the section", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10093 },
10094 /* 7.7.24.8 */
10095 { &hf_oran_entry_type,
10096 { "entryType", "oran_fh_cus.entryType",
10097 FT_UINT8, BASE_DEC,
10098 VALS(entry_type_vals)((0 ? (const struct _value_string*)0 : ((entry_type_vals)))), 0xe0,
10099 "indicates format of the entry", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10100 },
10101 /* 7.7.24.9 */
10102 { &hf_oran_dmrs_port_number,
10103 { "dmrsPortNumber", "oran_fh_cus.dmrsPortNumber",
10104 FT_UINT8, BASE_DEC,
10105 NULL((void*)0), 0x1f,
10106 "DMRS antenna port number for the associated ueId", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10107 },
10108 /* 7.7.24.10 */
10109 { &hf_oran_ueid_reset,
10110 { "ueidReset", "oran_fh_cus.ueidReset",
10111 FT_BOOLEAN, 8,
10112 TFS(&tfs_ueid_reset)((0 ? (const struct true_false_string*)0 : ((&tfs_ueid_reset
))))
, 0x80,
10113 "same UEID as the previous slot", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10114 },
10115 /* 7.7.24.11 */
10116 { &hf_oran_dmrs_symbol_mask,
10117 { "dmrsSymbolMask", "oran_fh_cus.dmrsSymbolMask",
10118 FT_UINT16, BASE_HEX,
10119 NULL((void*)0), 0x3fff,
10120 "symbols within the slot containing DMRS", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10121 },
10122 { &hf_oran_dmrs_symbol_mask_s13,
10123 { "symbol 13", "oran_fh_cus.dmrsSymbolMask.symbol-13",
10124 FT_BOOLEAN, 16,
10125 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x2000,
10126 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10127 },
10128 { &hf_oran_dmrs_symbol_mask_s12,
10129 { "symbol 12", "oran_fh_cus.dmrsSymbolMask.symbol-12",
10130 FT_BOOLEAN, 16,
10131 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x1000,
10132 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10133 },
10134 { &hf_oran_dmrs_symbol_mask_s11,
10135 { "symbol 11", "oran_fh_cus.dmrsSymbolMask.symbol-11",
10136 FT_BOOLEAN, 16,
10137 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0800,
10138 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10139 },
10140 { &hf_oran_dmrs_symbol_mask_s10,
10141 { "symbol 10", "oran_fh_cus.dmrsSymbolMask.symbol-10",
10142 FT_BOOLEAN, 16,
10143 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0400,
10144 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10145 },
10146 { &hf_oran_dmrs_symbol_mask_s9,
10147 { "symbol 9", "oran_fh_cus.dmrsSymbolMask.symbol-9",
10148 FT_BOOLEAN, 16,
10149 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0200,
10150 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10151 },
10152 { &hf_oran_dmrs_symbol_mask_s8,
10153 { "symbol 8", "oran_fh_cus.dmrsSymbolMask.symbol-8",
10154 FT_BOOLEAN, 16,
10155 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0100,
10156 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10157 },
10158 { &hf_oran_dmrs_symbol_mask_s7,
10159 { "symbol 7", "oran_fh_cus.dmrsSymbolMask.symbol-7",
10160 FT_BOOLEAN, 16,
10161 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0080,
10162 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10163 },
10164 { &hf_oran_dmrs_symbol_mask_s6,
10165 { "symbol 6", "oran_fh_cus.dmrsSymbolMask.symbol-6",
10166 FT_BOOLEAN, 16,
10167 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0040,
10168 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10169 },
10170 { &hf_oran_dmrs_symbol_mask_s5,
10171 { "symbol 5", "oran_fh_cus.dmrsSymbolMask.symbol-5",
10172 FT_BOOLEAN, 16,
10173 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0020,
10174 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10175 },
10176 { &hf_oran_dmrs_symbol_mask_s4,
10177 { "symbol 4", "oran_fh_cus.dmrsSymbolMask.symbol-4",
10178 FT_BOOLEAN, 16,
10179 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0010,
10180 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10181 },
10182 { &hf_oran_dmrs_symbol_mask_s3,
10183 { "symbol 3", "oran_fh_cus.dmrsSymbolMask.symbol-3",
10184 FT_BOOLEAN, 16,
10185 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0008,
10186 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10187 },
10188 { &hf_oran_dmrs_symbol_mask_s2,
10189 { "symbol 2", "oran_fh_cus.dmrsSymbolMask.symbol-2",
10190 FT_BOOLEAN, 16,
10191 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0004,
10192 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10193 },
10194 { &hf_oran_dmrs_symbol_mask_s1,
10195 { "symbol 1", "oran_fh_cus.dmrsSymbolMask.symbol-1",
10196 FT_BOOLEAN, 16,
10197 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0002,
10198 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10199 },
10200 { &hf_oran_dmrs_symbol_mask_s0,
10201 { "symbol 0", "oran_fh_cus.dmrsSymbolMask.symbol-0",
10202 FT_BOOLEAN, 16,
10203 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0001,
10204 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10205 },
10206
10207 /* 7.7.24.12 */
10208 { &hf_oran_scrambling,
10209 { "scrambling", "oran_fh_cus.scrambling",
10210 FT_UINT16, BASE_HEX,
10211 NULL((void*)0), 0x0,
10212 "used to calculate the seed value required to initialize pseudo-random generator", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10213 },
10214 /* 7.7.24.13 */
10215 { &hf_oran_nscid,
10216 { "nscid", "oran_fh_cus.nscid",
10217 FT_UINT8, BASE_HEX,
10218 NULL((void*)0), 0x80,
10219 "used to calculate the seed value for pseudo-random generator", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10220 },
10221 /* 7.7.24.14 */
10222 { &hf_oran_dtype,
10223 { "dType", "oran_fh_cus.dType",
10224 FT_UINT8, BASE_HEX,
10225 VALS(dtype_vals)((0 ? (const struct _value_string*)0 : ((dtype_vals)))), 0x40,
10226 "PUSCH DMRS configuration type", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10227 },
10228 /* 7.7.24.15 */
10229 { &hf_oran_cmd_without_data,
10230 { "cmdWithoutData", "oran_fh_cus.cmdWithoutData",
10231 FT_UINT8, BASE_HEX,
10232 NULL((void*)0), 0x30,
10233 "number of DMRS CDM groups without data", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10234 },
10235 /* 7.7.24.16 */
10236 { &hf_oran_lambda,
10237 { "lambda", "oran_fh_cus.lambda",
10238 FT_UINT8, BASE_HEX,
10239 NULL((void*)0), 0x0c,
10240 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10241 },
10242 /* 7.7.24.19 */
10243 { &hf_oran_first_prb,
10244 { "firstPrb", "oran_fh_cus.firstPrb",
10245 FT_UINT16, BASE_DEC,
10246 NULL((void*)0), 0x03fe,
10247 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10248 },
10249 /* 7.7.24.20 */
10250 { &hf_oran_last_prb,
10251 { "lastPrb", "oran_fh_cus.lastPrb",
10252 FT_UINT16, BASE_DEC,
10253 NULL((void*)0), 0x01ff,
10254 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10255 },
10256
10257 /* 7.7.24.17 */
10258 /* TODO: add value_string */
10259 { &hf_oran_low_papr_type,
10260 { "lowPaprType", "oran_fh_cus.lowPaprType",
10261 FT_UINT8, BASE_HEX,
10262 VALS(papr_type_vals)((0 ? (const struct _value_string*)0 : ((papr_type_vals)))), 0x30,
10263 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10264 },
10265 /* 7.7.24.18 */
10266 { &hf_oran_hopping_mode,
10267 { "hoppingMode", "oran_fh_cus.hoppingMode",
10268 FT_UINT8, BASE_HEX,
10269 VALS(hopping_mode_vals)((0 ? (const struct _value_string*)0 : ((hopping_mode_vals)))
)
, 0x0c,
10270 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10271 },
10272
10273 { &hf_oran_tx_win_for_on_air_symbol_l,
10274 { "txWinForOnAirSymbol", "oran_fh_cus.txWinForOnAirSymbol",
10275 FT_UINT8, BASE_DEC,
10276 NULL((void*)0), 0xf0,
10277 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10278 },
10279 { &hf_oran_tx_win_for_on_air_symbol_r,
10280 { "txWinForOnAirSymbol", "oran_fh_cus.txWinForOnAirSymbol",
10281 FT_UINT8, BASE_DEC,
10282 NULL((void*)0), 0x0f,
10283 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10284 },
10285 /* 7.7.26.2 */
10286 { &hf_oran_num_fo_fb,
10287 { "numFoFb", "oran_fh_cus.numFoFb",
10288 FT_UINT8, BASE_DEC,
10289 NULL((void*)0), 0x7f,
10290 "number of frequency offset feedback", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10291 },
10292 /* 7.7.26.3 */
10293 { &hf_oran_freq_offset_fb,
10294 { "freqOffsetFb", "oran_fh_cus.freqOffsetFb",
10295 FT_UINT16, BASE_HEX_DEC | BASE_RANGE_STRING0x00000100,
10296 RVALS(freq_offset_fb_values)((0 ? (const struct _range_string*)0 : ((freq_offset_fb_values
))))
, 0x0,
10297 "UE frequency offset feedback", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10298 },
10299
10300 /* 7.7.28.2 */
10301 { &hf_oran_num_ue_sinr_rpt,
10302 { "numUeSinrRpt", "oran_fh_cus.numUeSinrRpt",
10303 FT_UINT8, BASE_DEC,
10304 NULL((void*)0), 0x1f,
10305 "number of sinr reported UEs {1 - 12}", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10306 },
10307
10308 /* 7.5.2.19 */
10309 { &hf_oran_num_sinr_per_prb,
10310 { "numSinrPerPrb", "oran_fh_cus.numSinrPerPrb",
10311 FT_UINT8, BASE_DEC,
10312 VALS(num_sinr_per_prb_vals)((0 ? (const struct _value_string*)0 : ((num_sinr_per_prb_vals
))))
, 0x70,
10313 "number of SINR values per PRB", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10314 },
10315 { &hf_oran_num_sinr_per_prb_right,
10316 { "numSinrPerPrb", "oran_fh_cus.numSinrPerPrb",
10317 FT_UINT8, BASE_DEC,
10318 VALS(num_sinr_per_prb_vals)((0 ? (const struct _value_string*)0 : ((num_sinr_per_prb_vals
))))
, 0x07,
10319 "number of SINR values per PRB", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10320 },
10321
10322 /* 7.5.3.68 */
10323 { &hf_oran_sinr_value,
10324 { "sinrValue", "oran_fh_cus.sinrValue",
10325 FT_FLOAT, BASE_NONE,
10326 NULL((void*)0), 0x0,
10327 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10328 },
10329
10330 { &hf_oran_measurement_report,
10331 { "Measurement Report", "oran_fh_cus.measurement-report",
10332 FT_STRING, BASE_NONE,
10333 NULL((void*)0), 0x0,
10334 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10335 },
10336 /* 7.5.3.57 */
10337 { &hf_oran_mf,
10338 { "mf", "oran_fh_cus.mf",
10339 FT_BOOLEAN, 8,
10340 TFS(&measurement_flag_tfs)((0 ? (const struct true_false_string*)0 : ((&measurement_flag_tfs
))))
, 0x80,
10341 "measurement flag", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10342 },
10343 /* 7.5.3.59 */
10344 { &hf_oran_meas_data_size,
10345 { "measDataSize", "oran_fh_cus.measDataSize",
10346 FT_UINT16, BASE_DEC,
10347 NULL((void*)0), 0x0,
10348 "measurement data size (in words)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10349 },
10350
10351 /* 7.5.3.58 */
10352 { &hf_oran_meas_type_id,
10353 { "measTypeId", "oran_fh_cus.measTypeId",
10354 FT_UINT8, BASE_DEC,
10355 VALS(meas_type_id_vals)((0 ? (const struct _value_string*)0 : ((meas_type_id_vals)))
)
, 0x7F,
10356 "measurement report type identifier", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10357 },
10358 /* 7.5.3.66 */
10359 { &hf_oran_num_elements,
10360 { "numElements", "oran_fh_cus.numElements",
10361 FT_UINT8, BASE_DEC,
10362 NULL((void*)0), 0x0,
10363 "measurement report type identifier", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10364 },
10365 /* 7.5.3.60 */
10366 { &hf_oran_ue_tae,
10367 { "ueTae", "oran_fh_cus.ueTae",
10368 FT_UINT16, BASE_DEC | BASE_RANGE_STRING0x00000100,
10369 RVALS(freq_offset_fb_values)((0 ? (const struct _range_string*)0 : ((freq_offset_fb_values
))))
, 0x0,
10370 "UE Timing Advance Error", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10371 },
10372 /* 7.5.3.61 */
10373 { &hf_oran_ue_layer_power,
10374 { "ueLayerPower", "oran_fh_cus.ueLayerPower",
10375 FT_UINT16, BASE_DEC | BASE_RANGE_STRING0x00000100,
10376 RVALS(freq_offset_fb_values)((0 ? (const struct _range_string*)0 : ((freq_offset_fb_values
))))
, 0x0,
10377 "UE Layer Power", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10378 },
10379
10380 /* 7.5.3.62 */
10381 { &hf_oran_ue_freq_offset,
10382 { "ueFreqOffset", "oran_fh_cus.ueFreqOffset",
10383 FT_UINT16, BASE_DEC | BASE_RANGE_STRING0x00000100,
10384 RVALS(freq_offset_fb_values)((0 ? (const struct _range_string*)0 : ((freq_offset_fb_values
))))
, 0x0,
10385 "UE frequency offset", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10386 },
10387 /* 7.5.3.63 */
10388 { &hf_oran_ipn_power,
10389 { "ipnPower", "oran_fh_cus.ipnPower",
10390 FT_UINT16, BASE_DEC | BASE_RANGE_STRING0x00000100,
10391 RVALS(freq_offset_fb_values)((0 ? (const struct _range_string*)0 : ((freq_offset_fb_values
))))
, 0x0,
10392 "Interference plus Noise power", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10393 },
10394 /* 7.5.3.64 */
10395 { &hf_oran_ant_dmrs_snr_val,
10396 { "antDmrsSnrVal", "oran_fh_cus.antDmrsSnrVal",
10397 FT_UINT16, BASE_DEC | BASE_RANGE_STRING0x00000100,
10398 RVALS(freq_offset_fb_values)((0 ? (const struct _range_string*)0 : ((freq_offset_fb_values
))))
, 0x0,
10399 "antenna DMRS-SNR", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10400 },
10401
10402 { &hf_oran_measurement_command,
10403 { "Measurement Command", "oran_fh_cus.measurement-command",
10404 FT_STRING, BASE_NONE,
10405 NULL((void*)0), 0x0,
10406 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10407 },
10408
10409 /* 7.5.27.2 */
10410 { &hf_oran_beam_type,
10411 {"beamType", "oran_fh_cus.beamType",
10412 FT_UINT16, BASE_DEC,
10413 VALS(beam_type_vals)((0 ? (const struct _value_string*)0 : ((beam_type_vals)))), 0xc0,
10414 NULL((void*)0),
10415 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10416 },
10417 /* 7.5.3.65 */
10418 { &hf_oran_meas_cmd_size,
10419 {"measCmdSize", "oran_fh_cus.measCmdSize",
10420 FT_UINT16, BASE_DEC,
10421 NULL((void*)0), 0x0,
10422 "measurement command size in words",
10423 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10424 },
10425
10426 { &hf_oran_symbol_reordering_layer,
10427 { "Layer", "oran_fh_cus.layer",
10428 FT_STRING, BASE_NONE,
10429 NULL((void*)0), 0x0,
10430 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10431 },
10432 { &hf_oran_dmrs_entry,
10433 { "Entry", "oran_fh_cus.dmrs-entry",
10434 FT_STRING, BASE_NONE,
10435 NULL((void*)0), 0x0,
10436 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10437 },
10438
10439 /* 7.7.29.3 */
10440 { &hf_oran_cd_scg_size,
10441 {"cdScgSize", "oran_fh_cus.cdScgSize",
10442 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
10443 RVALS(cd_scg_size_vals)((0 ? (const struct _range_string*)0 : ((cd_scg_size_vals)))), 0x0f,
10444 "Cyclic delay subcarrier group size",
10445 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10446 },
10447 /* 7.7.29.4 */
10448 { &hf_oran_cd_scg_phase_step,
10449 {"cdScgPhaseStep", "oran_fh_cus.cdScgPhaseStep",
10450 FT_INT8, BASE_DEC,
10451 NULL((void*)0), 0x0,
10452 "Cyclic delay subcarrier group phase step",
10453 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10454 },
10455
10456 { &hf_oran_sinr_prb,
10457 { "PRB", "oran_fh_cus.sinr.prb",
10458 FT_STRING, BASE_NONE,
10459 NULL((void*)0), 0x0,
10460 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10461 },
10462 /* 7.5.2.20 */
10463 { &hf_oran_oru_control_sinr_slot_mask_id,
10464 {"oruControlSinrSlotMaskId", "oran_fh_cus.oruControlSinrSlotMaskId",
10465 FT_UINT8, BASE_DEC,
10466 NULL((void*)0), 0x1f,
10467 "SINR time resolution",
10468 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10469 },
10470 /* 7.7.24.21 */
10471 { &hf_oran_pos_meas,
10472 {"posMeas", "oran_fh_cus.posMeas",
10473 FT_BOOLEAN, 8,
10474 TFS(&tfs_report_no_report_pos_meas)((0 ? (const struct true_false_string*)0 : ((&tfs_report_no_report_pos_meas
))))
, 0x40,
10475 "Positioning measurement report request",
10476 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10477 },
10478
10479 /* 7.5.3.69 */
10480 { &hf_oran_ue_radial_speed,
10481 {"ueRadialSpeed", "oran_fh_cus.ueRadialSpeed",
10482 FT_UINT16, BASE_DEC,
10483 NULL((void*)0), 0x0,
10484 "UE radial speed",
10485 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10486 },
10487 /* 7.5.3.70 */
10488 { &hf_oran_ue_az_aoa,
10489 {"ueAzAoa", "oran_fh_cus.ueAzAoa",
10490 FT_UINT16, BASE_DEC,
10491 NULL((void*)0), 0x0,
10492 "UE azimuth angle of arrival",
10493 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10494 },
10495 /* 7.5.3.71 */
10496 { &hf_oran_ue_ze_aoa,
10497 {"ueZeAoa", "oran_fh_cus.ueZeAoa",
10498 FT_UINT16, BASE_DEC,
10499 NULL((void*)0), 0x0,
10500 "UE zenith angle of arrival",
10501 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10502 },
10503 /* 7.5.3.72 */
10504 { &hf_oran_ue_pos_toa_offset,
10505 {"uePosToaOffset", "oran_fh_cus.uePosToaOffset",
10506 FT_UINT16, BASE_DEC,
10507 NULL((void*)0), 0x0,
10508 "UE positioning time of arrival offset",
10509 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10510 },
10511
10512 /* 7.7.30.2 */
10513 { &hf_oran_num_rep_ue,
10514 {"numRepUe", "oran_fh_cus.numRepUe",
10515 FT_UINT8, BASE_DEC,
10516 NULL((void*)0), 0x0f,
10517 "Number of UEs with PUSCH repetition",
10518 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10519 },
10520 /* 7.7.30.3 */
10521 { &hf_oran_rep_ueid,
10522 {"repUeId", "oran_fh_cus.repUeId",
10523 FT_UINT16, BASE_DEC,
10524 NULL((void*)0), 0x7fff,
10525 "UEId the PUSCH is part of",
10526 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10527 },
10528 /* 7.7.30.4 */
10529 { &hf_oran_is_last_rep,
10530 {"isLastRep", "oran_fh_cus.isLastRep",
10531 FT_BOOLEAN, 8,
10532 NULL((void*)0), 0x40,
10533 "Last transmission in the repetition",
10534 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10535 },
10536 /* 7.7.30.5 */
10537 { &hf_oran_rep_index,
10538 {"repIndex", "oran_fh_cus.repIndex",
10539 FT_UINT8, BASE_DEC,
10540 NULL((void*)0), 0x3f,
10541 "Repetition index of the PUSCH transmission",
10542 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10543 },
10544 /* 7.7.30.6 */
10545 { &hf_oran_num_reps,
10546 {"numReps", "oran_fh_cus.numReps",
10547 FT_UINT8, BASE_DEC,
10548 NULL((void*)0), 0x3f,
10549 "The number of total PUSCH repetitions",
10550 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10551 },
10552
10553 /* 7.7.31.2 */
10554 { &hf_oran_mcs_table,
10555 {"mcsTable", "oran_fh_cus.mcsTable",
10556 FT_UINT8, BASE_DEC,
10557 VALS(mcs_table_vals)((0 ? (const struct _value_string*)0 : ((mcs_table_vals)))), 0x0f,
10558 "MCS index table",
10559 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10560 },
10561 /* 7.7.31.3 */
10562 { &hf_oran_mcs_index,
10563 {"mcsIndex", "oran_fh_cus.mcsIndex",
10564 FT_UINT8, BASE_DEC,
10565 NULL((void*)0), 0x3f,
10566 "MCS index value",
10567 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10568 },
10569
10570 /* 7.7.33.3 */
10571 { &hf_oran_num_meas_req,
10572 {"numMeasReq", "oran_fh_cus.numMeasReq",
10573 FT_UINT8, BASE_DEC,
10574 NULL((void*)0), 0x1f,
10575 "Number of UEs for which meas is requested",
10576 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10577 },
10578 /* 7.7.32.5 */
10579 { &hf_oran_ue_rank,
10580 {"ueRank", "oran_fh_cus.ueRank",
10581 FT_UINT8, BASE_DEC,
10582 VALS(ue_rank_vals)((0 ? (const struct _value_string*)0 : ((ue_rank_vals)))), 0x0f,
10583 "Number of UE layers under evaluation",
10584 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10585 },
10586 /* 7.7.32.6 */
10587 { &hf_oran_num_of_ue_ant_ports,
10588 {"numOfUeAntPorts", "oran_fh_cus.numofUeAntPorts",
10589 FT_UINT8, BASE_DEC,
10590 VALS(num_of_ue_ant_ports_vals)((0 ? (const struct _value_string*)0 : ((num_of_ue_ant_ports_vals
))))
, 0xf0,
10591 "Used for the PUSCH tx under evaluation",
10592 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10593 },
10594 /* 7.7.32.8 */
10595 { &hf_oran_codebook_subset,
10596 {"codebookSubset", "oran_fh_cus.codebookSubset",
10597 FT_UINT8, BASE_DEC,
10598 VALS(codebook_subset_vals)((0 ? (const struct _value_string*)0 : ((codebook_subset_vals
))))
, 0xc0,
10599 "UE capability wrt ULTPMI sets",
10600 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10601 },
10602 /* 7.7.32.9 */
10603 { &hf_oran_full_pwr_mode,
10604 {"fullPwrMode", "oran_fh_cus.fullPwrMode",
10605 FT_UINT8, BASE_DEC,
10606 VALS(full_pwr_mode_vals)((0 ? (const struct _value_string*)0 : ((full_pwr_mode_vals))
))
, 0xc0,
10607 "Transmission mode",
10608 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10609 },
10610 /* 7.7.32.10 */
10611 { &hf_oran_full_pwr_mode_2_tpmi_group,
10612 {"fullPwrMode2TpmiGroup", "oran_fh_cus.fullPwrMode2TpmiGroup",
10613 FT_UINT16, BASE_HEX,
10614 NULL((void*)0), 0x3fff,
10615 "Capabilities",
10616 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10617 },
10618
10619 /* 7.5.3.75 */
10620 { &hf_oran_num_cand_ranks,
10621 {"numCandRanks", "oran_fh_cus.numCandRanks",
10622 FT_UINT8, BASE_DEC,
10623 NULL((void*)0), 0xf0,
10624 NULL((void*)0),
10625 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10626 },
10627 /* 7.5.3.76 */
10628 { &hf_oran_ue_pref_rank,
10629 {"uePrefRank", "oran_fh_cus.uePrefRank",
10630 FT_UINT8, BASE_DEC,
10631 NULL((void*)0), 0x0f,
10632 "Most optimal UL Tx rank for UE",
10633 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10634 },
10635
10636 { &hf_oran_c_section_common,
10637 { "Common Section", "oran_fh_cus.c-plane.section.common",
10638 FT_STRING, BASE_NONE,
10639 NULL((void*)0), 0x0,
10640 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10641 },
10642 { &hf_oran_c_section,
10643 { "Section", "oran_fh_cus.c-plane.section",
10644 FT_STRING, BASE_NONE,
10645 NULL((void*)0), 0x0,
10646 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10647 },
10648 { &hf_oran_u_section,
10649 { "Section", "oran_fh_cus.u-plane.section",
10650 FT_STRING, BASE_NONE,
10651 NULL((void*)0), 0x0,
10652 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10653 },
10654
10655 /* Link back to UL C-plane where udCompHdr was recorded */
10656 { &hf_oran_ul_cplane_ud_comp_hdr_frame,
10657 { "C-Plane UL udCompHdr frame", "oran_fh_cus.ul-cplane.udCompHdr",
10658 FT_FRAMENUM, BASE_NONE,
10659 FRAMENUM_TYPE(FT_FRAMENUM_REQUEST)((gpointer) (glong) (FT_FRAMENUM_REQUEST)), 0x0,
10660 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10661 },
10662
10663 /* For ext11, where was a beamId (last) defined? */
10664 { &hf_oran_bfws_frame_defined,
10665 { "Beam defined in frame", "oran_fh_cus.bfw-defined",
10666 FT_FRAMENUM, BASE_NONE,
10667 FRAMENUM_TYPE(FT_FRAMENUM_RETRANS_PREV)((gpointer) (glong) (FT_FRAMENUM_RETRANS_PREV)), 0x0,
10668 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10669 },
10670 { &hf_oran_bfws_symbols_since_defined,
10671 { "Symbols since BFWs defined", "oran_fh_cus.symbols-since-bfw-defined",
10672 FT_UINT32, BASE_DEC,
10673 NULL((void*)0), 0x0,
10674 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10675 },
10676
10677 /* Corresponding C-plane frame for DL U-plane */
10678 { &hf_oran_corresponding_cplane_frame,
10679 { "C-plane frame", "oran_fh_cus.cplane-frame",
10680 FT_FRAMENUM, BASE_NONE,
10681 FRAMENUM_TYPE(FT_FRAMENUM_REQUEST)((gpointer) (glong) (FT_FRAMENUM_REQUEST)), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10682 },
10683 /* Time since corresponding C-plane frame for U-plane */
10684 { &hf_oran_corresponding_cplane_frame_time_delta,
10685 { "Time since C-plane frame", "oran_fh_cus.cplane-frame-time-delta",
10686 FT_UINT32, BASE_DEC, NULL((void*)0), 0x0,
10687 "Microseconds since C-plane frame", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10688 },
10689 /* Corresponding U-plane frame for C-plane */
10690 { &hf_oran_corresponding_uplane_frame,
10691 { "U-plane frame", "oran_fh_cus.uplane-frame",
10692 FT_FRAMENUM, BASE_NONE,
10693 FRAMENUM_TYPE(FT_FRAMENUM_RESPONSE)((gpointer) (glong) (FT_FRAMENUM_RESPONSE)), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10694 },
10695
10696 /* Reassembly */
10697 { &hf_oran_fragment,
10698 { "Fragment", "oran_fh_cus.fragment", FT_FRAMENUM, BASE_NONE,
10699 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10700 { &hf_oran_fragments,
10701 { "Fragments", "oran_fh_cus.fragments", FT_BYTES, BASE_NONE,
10702 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10703 { &hf_oran_fragment_overlap,
10704 { "Fragment overlap", "oran_fh_cus.fragment.overlap", FT_BOOLEAN, BASE_NONE,
10705 NULL((void*)0), 0x0, "Fragment overlaps with other fragments", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10706 { &hf_oran_fragment_overlap_conflict,
10707 { "Conflicting data in fragment overlap", "oran_fh_cus.fragment.overlap.conflict",
10708 FT_BOOLEAN, BASE_NONE, NULL((void*)0), 0x0,
10709 "Overlapping fragments contained conflicting data", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10710 { &hf_oran_fragment_multiple_tails,
10711 { "Multiple tail fragments found", "oran_fh_cus.fragment.multipletails",
10712 FT_BOOLEAN, BASE_NONE, NULL((void*)0), 0x0,
10713 "Several tails were found when defragmenting the packet", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10714 { &hf_oran_fragment_too_long_fragment,
10715 { "Fragment too long", "oran_fh_cus.fragment.toolongfragment",
10716 FT_BOOLEAN, BASE_NONE, NULL((void*)0), 0x0,
10717 "Fragment contained data past end of packet", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10718 { &hf_oran_fragment_error,
10719 { "Defragmentation error", "oran_fh_cus.fragment.error", FT_FRAMENUM, BASE_NONE,
10720 NULL((void*)0), 0x0, "Defragmentation error due to illegal fragments", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10721 { &hf_oran_fragment_count,
10722 { "Fragment count", "oran_fh_cus.fragment.count", FT_UINT32, BASE_DEC,
10723 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10724 { &hf_oran_reassembled_in,
10725 { "Reassembled payload in frame", "oran_fh_cus.reassembled_in", FT_FRAMENUM, BASE_NONE,
10726 NULL((void*)0), 0x0, "This payload packet is reassembled in this frame", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10727 { &hf_oran_reassembled_length,
10728 { "Reassembled payload length", "oran_fh_cus.reassembled.length", FT_UINT32, BASE_DEC,
10729 NULL((void*)0), 0x0, "The total length of the reassembled payload", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10730 { &hf_oran_reassembled_data,
10731 { "Reassembled data", "oran_fh_cus.reassembled.data", FT_BYTES, BASE_NONE,
10732 NULL((void*)0), 0x0, "The reassembled payload", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10733
10734 { &hf_oran_payload,
10735 { "Payload", "oran_fh_cus.payload", FT_BYTES, BASE_SHOW_ASCII_PRINTABLE0x00010000,
10736 NULL((void*)0), 0x0, "Complete or reassembled payload", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10737 };
10738
10739 /* Setup protocol subtree array */
10740 static int *ett[] = {
10741 &ett_oran,
10742 &ett_oran_ecpri_pcid,
10743 &ett_oran_ecpri_rtcid,
10744 &ett_oran_ecpri_seqid,
10745 &ett_oran_section_type,
10746 &ett_oran_u_timing,
10747 &ett_oran_u_section,
10748 &ett_oran_u_prb,
10749 &ett_oran_section,
10750 &ett_oran_iq,
10751 &ett_oran_bfw_bundle,
10752 &ett_oran_bfw,
10753 &ett_oran_frequency_range,
10754 &ett_oran_prb_cisamples,
10755 &ett_oran_cisample,
10756 &ett_oran_udcomphdr,
10757 &ett_oran_udcompparam,
10758 &ett_oran_cicomphdr,
10759 &ett_oran_cicompparam,
10760 &ett_oran_bfwcomphdr,
10761 &ett_oran_bfwcompparam,
10762 &ett_oran_ext19_port,
10763 &ett_oran_prb_allocation,
10764 &ett_oran_punc_pattern,
10765 &ett_oran_bfacomphdr,
10766 &ett_oran_modcomp_param_set,
10767 &ett_oran_st4_cmd_header,
10768 &ett_oran_st4_cmd,
10769 &ett_oran_sym_prb_pattern,
10770 &ett_oran_measurement_report,
10771 &ett_oran_measurement_command,
10772 &ett_oran_sresmask,
10773 &ett_oran_c_section_common,
10774 &ett_oran_c_section,
10775 &ett_oran_remask,
10776 &ett_oran_mc_scale_remask,
10777 &ett_oran_symbol_reordering_layer,
10778 &ett_oran_dmrs_entry,
10779 &ett_oran_dmrs_symbol_mask,
10780 &ett_oran_symbol_mask,
10781 &ett_oran_active_beamspace_coefficient_mask,
10782 &ett_oran_sinr_prb,
10783
10784 &ett_oran_fragment,
10785 &ett_oran_fragments
10786 };
10787
10788 /* Separate subtree array for extensions. Used with [ext-1] */
10789 static int *ext_ett[HIGHEST_EXTTYPE32];
10790 for (unsigned extno=0; extno<HIGHEST_EXTTYPE32; extno++) {
10791 ext_ett[extno] = &ett_oran_c_section_extension[extno];
10792 }
10793
10794 expert_module_t* expert_oran;
10795
10796 static ei_register_info ei[] = {
10797 { &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)}}
}},
10798 { &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)}}
}},
10799 { &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)}}
}},
10800 { &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)}}
}},
10801 { &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)}}
}},
10802 { &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)}}
}},
10803 { &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)}}
}},
10804 { &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)}}
}},
10805 { &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)}}
}},
10806 { &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)}}
}},
10807 { &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)}}
}},
10808 { &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)}}
}},
10809 { &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)}}
}},
10810 { &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)}}
}},
10811 { &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)}}
}},
10812 { &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)}}
}},
10813 { &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)}}
}},
10814 { &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)}}
}},
10815 { &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)}}
}},
10816 { &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)}}
}},
10817 { &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)}}
}},
10818 { &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)}}
}},
10819 { &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)}}
}},
10820 { &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)}}
}},
10821 { &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)}}
}},
10822 { &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)}}
}},
10823 { &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)}}
}},
10824 { &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)}}
}},
10825 { &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)}}
}},
10826 { &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)}}
}},
10827 { &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)}}
}},
10828 { &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)}}
}},
10829 { &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)}}
}},
10830 { &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)}}
}},
10831 { &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)}}
}},
10832 { &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)}}
}},
10833 { &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)}}
}},
10834 { &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)}}
}},
10835 { &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)}}
}},
10836 { &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)}}
}},
10837 { &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)}}
}},
10838 { &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)}}
}},
10839 { &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)}}
}},
10840 { &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)}}
}},
10841 { &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)}}
}},
10842 { &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)}}
}},
10843 { &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)}}
}},
10844 { &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)}}
}},
10845 { &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)}}
}},
10846 { &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)}}
}},
10847 { &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)}}
}},
10848 { &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)}}
}},
10849 { &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)}}
}},
10850 { &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)}}
}},
10851 { &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)}}
}},
10852 { &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)}}
}}
10853 };
10854
10855 /* Register the protocol name and description */
10856 proto_oran = proto_register_protocol("O-RAN Fronthaul CUS", "O-RAN FH CUS", "oran_fh_cus");
10857
10858 /* Allow dissector to find be found by name. */
10859 register_dissector("oran_fh_cus", dissect_oran, proto_oran);
10860
10861 /* Register the tap name. */
10862 oran_tap = register_tap("oran-fh-cus");
10863
10864 /* Required function calls to register the header fields and subtrees */
10865 proto_register_field_array(proto_oran, hf, array_length(hf)(sizeof (hf) / sizeof (hf)[0]));
10866 proto_register_subtree_array(ett, array_length(ett)(sizeof (ett) / sizeof (ett)[0]));
10867 proto_register_subtree_array(ext_ett, array_length(ext_ett)(sizeof (ext_ett) / sizeof (ext_ett)[0]));
10868
10869 expert_oran = expert_register_protocol(proto_oran);
10870 expert_register_field_array(expert_oran, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
10871
10872
10873 /* Preferences */
10874 module_t * oran_module = prefs_register_protocol(proto_oran, NULL((void*)0));
10875
10876 /* Register bit width/compression preferences separately by direction. */
10877 prefs_register_uint_preference(oran_module, "oran.du_port_id_bits", "DU Port ID bits [a]",
10878 "The bit width of DU Port ID - sum of a,b,c&d (eAxC) must be 16", 10, &pref_du_port_id_bits);
10879 prefs_register_uint_preference(oran_module, "oran.bandsector_id_bits", "BandSector ID bits [b]",
10880 "The bit width of BandSector ID - sum of a,b,c&d (eAxC) must be 16", 10, &pref_bandsector_id_bits);
10881 prefs_register_uint_preference(oran_module, "oran.cc_id_bits", "CC ID bits [c]",
10882 "The bit width of CC ID - sum of a,b,c&d (eAxC) must be 16", 10, &pref_cc_id_bits);
10883 prefs_register_uint_preference(oran_module, "oran.ru_port_id_bits", "RU Port ID bits [d]",
10884 "The bit width of RU Port ID - sum of a,b,c&d (eAxC) must be 16", 10, &pref_ru_port_id_bits);
10885
10886 /* Uplink userplane */
10887 prefs_register_static_text_preference(oran_module, "oran.ul", "", "");
10888 prefs_register_uint_preference(oran_module, "oran.iq_bitwidth_up", "IQ Bitwidth Uplink",
10889 "The bit width of a sample in the Uplink (if no udcompHdr and no C-Plane)", 10, &pref_sample_bit_width_uplink);
10890 prefs_register_enum_preference(oran_module, "oran.ud_comp_up", "Uplink User Data Compression",
10891 "Uplink User Data Compression (if no udcompHdr and no C-Plane)", &pref_iqCompressionUplink, ul_compression_options, false0);
10892 prefs_register_enum_preference(oran_module, "oran.ud_comp_hdr_up", "udCompHdr field is present for uplink",
10893 "The udCompHdr field in U-Plane messages may or may not be present, depending on the "
10894 "configuration of the O-RU. This preference instructs the dissector to expect "
10895 "this field to be present in uplink messages",
10896 &pref_includeUdCompHeaderUplink, udcomphdr_present_options, false0);
10897 prefs_register_bool_preference(oran_module, "oran.ignore_cplane_ul_udcomphdr", "Ignore UL compression settings from C-plane",
10898 "When set, override udCompHdr from UL C-Plane with compression method and width configured here", &pref_override_ul_compression);
10899 prefs_register_uint_preference(oran_module, "oran.ul_slot_us_limit", "Microseconds allowed for UL tx in symbol",
10900 "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",
10901 10, &us_allowed_for_ul_in_symbol);
10902
10903 /* Downlink userplane */
10904 prefs_register_static_text_preference(oran_module, "oran.dl", "", "");
10905 prefs_register_uint_preference(oran_module, "oran.iq_bitwidth_down", "IQ Bitwidth Downlink",
10906 "The bit width of a sample in the Downlink (if no udcompHdr)", 10, &pref_sample_bit_width_downlink);
10907 prefs_register_enum_preference(oran_module, "oran.ud_comp_down", "Downlink User Data Compression",
10908 "Downlink User Data Compression", &pref_iqCompressionDownlink, dl_compression_options, false0);
10909 prefs_register_enum_preference(oran_module, "oran.ud_comp_hdr_down", "udCompHdr field is present for downlink",
10910 "The udCompHdr field in U-Plane messages may or may not be present, depending on the "
10911 "configuration of the O-RU. This preference instructs the dissector to expect "
10912 "this field to be present in downlink messages",
10913 &pref_includeUdCompHeaderDownlink, udcomphdr_present_options, false0);
10914
10915 /* SINR */
10916 prefs_register_static_text_preference(oran_module, "oran.sinr", "", "");
10917 prefs_register_uint_preference(oran_module, "oran.iq_bitwidth_sinr", "IQ Bitwidth SINR",
10918 "The bit width of a sample in SINR", 10, &pref_sample_bit_width_sinr);
10919 prefs_register_enum_preference(oran_module, "oran.ud_comp_sinr", "SINR Compression",
10920 "SINR Compression", &pref_iqCompressionSINR, ul_compression_options, false0);
10921
10922 /* BF-related */
10923 prefs_register_static_text_preference(oran_module, "oran.bf", "", "");
10924 prefs_register_uint_preference(oran_module, "oran.num_bf_antennas", "Number of beam weights",
10925 "Number of array elements that BF weights will be provided for", 10, &pref_num_bf_antennas);
10926 prefs_register_obsolete_preference(oran_module, "oran.num_weights_per_bundle");
10927 prefs_register_obsolete_preference(oran_module, "oran.num_bf_weights");
10928 prefs_register_bool_preference(oran_module, "oran.st6_4byte_alignment_required", "Use 4-byte alignment for ST6 sections",
10929 "Default is 1-byte alignment", &st6_4byte_alignment);
10930
10931 /* Misc (and will seldom need to be accessed) */
10932 prefs_register_static_text_preference(oran_module, "oran.misc", "", "");
10933 prefs_register_bool_preference(oran_module, "oran.show_iq_samples", "Show IQ Sample values",
10934 "When enabled, for U-Plane frames show each I and Q value in PRB", &pref_showIQSampleValues);
10935 prefs_register_enum_preference(oran_module, "oran.support_udcomplen", "udCompLen supported",
10936 "When enabled, U-Plane messages with relevant compression schemes will include udCompLen",
10937 &pref_support_udcompLen, udcomplen_support_options, false0);
10938 prefs_register_uint_preference(oran_module, "oran.rbs_in_uplane_section", "Total RBs in User-Plane data section",
10939 "This is used if numPrbu is signalled as 0", 10, &pref_data_plane_section_total_rbs);
10940 prefs_register_bool_preference(oran_module, "oran.unscaled_iq", "Show unscaled I/Q values",
10941 "", &show_unscaled_values);
10942 prefs_register_bool_preference(oran_module, "oran.attempt_reassembly",
10943 "Attempt Radio Transport layer reassembly", "",
10944 &do_radio_transport_layer_reassembly);
10945 prefs_register_obsolete_preference(oran_module, "oran.k_antenna_ports");
10946
10947 prefs_register_bool_preference(oran_module, "oran.link_planes",
10948 "Link C-plane and U-plane using sectionId", "",
10949 &link_planes_together);
10950
10951
10952 flow_states_table = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
10953 flow_results_table = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
10954 ul_symbol_timing = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
10955
10956 dl_beam_ids_defined = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
10957 dl_beam_ids_results = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
10958
10959 register_init_routine(&oran_init_protocol);
10960
10961 /* Register reassembly table. */
10962 reassembly_table_register(&oran_reassembly_table,
10963 &oran_reassembly_table_functions);
10964}
10965
10966/*
10967* Editor modelines - http://www.wireshark.org/tools/modelines.html
10968*
10969* Local Variables:
10970* c-basic-offset: 4
10971* tab-width: 8
10972* indent-tabs-mode: nil
10973* End:
10974*
10975* ex: set shiftwidth=4 tabstop=8 expandtab:
10976* :indentSize=4:tabSize=8:noTabs=true:
10977*/