Bug Summary

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

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name packet-oran.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -fno-delete-null-pointer-checks -mframe-pointer=all -relaxed-aliasing -fmath-errno -ffp-contract=on -fno-rounding-math -ffloat16-excess-precision=fast -fbfloat16-excess-precision=fast -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/builds/wireshark/wireshark/build -fcoverage-compilation-dir=/builds/wireshark/wireshark/build -resource-dir /usr/lib/llvm-22/lib/clang/22 -isystem /usr/include/glib-2.0 -isystem /usr/lib/x86_64-linux-gnu/glib-2.0/include -isystem /builds/wireshark/wireshark/epan/dissectors -isystem /builds/wireshark/wireshark/build/epan/dissectors -isystem /usr/include/mit-krb5 -isystem /usr/include/libxml2 -isystem /builds/wireshark/wireshark/epan -D CARES_NO_DEPRECATED -D G_DISABLE_DEPRECATED -D G_DISABLE_SINGLE_INCLUDES -D WS_BUILD_DLL -D WS_DEBUG -D WS_DEBUG_UTF_8 -I /builds/wireshark/wireshark/build -I /builds/wireshark/wireshark -I /builds/wireshark/wireshark/include -D _GLIBCXX_ASSERTIONS -internal-isystem /usr/lib/llvm-22/lib/clang/22/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fmacro-prefix-map=/builds/wireshark/wireshark/= -fmacro-prefix-map=/builds/wireshark/wireshark/build/= -fmacro-prefix-map=../= -Wno-format-nonliteral -std=gnu17 -ferror-limit 19 -fvisibility=hidden -fwrapv -fwrapv-pointer -fstrict-flex-arrays=3 -stack-protector 2 -fstack-clash-protection -fcf-protection=full -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fexceptions -fcolor-diagnostics -analyzer-output=html -faddrsig -fdwarf2-cfi-asm -o /builds/wireshark/wireshark/sbout/2026-07-03-100307-3576-1 -x c /builds/wireshark/wireshark/epan/dissectors/packet-oran.c
1/* packet-oran.c
2 * Routines for O-RAN fronthaul UC-plane dissection
3 * Copyright 2020, Jan Schiefer, Keysight Technologies, Inc.
4 * Copyright 2020- Martin Mathieson
5 *
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
9 *
10 * SPDX-License-Identifier: GPL-2.0-or-later
11 */
12
13 /*
14 * Dissector for the O-RAN Fronthaul CUS protocol specification.
15 * See https://specifications.o-ran.org/specifications, WG4, Fronthaul Interfaces Workgroup
16 * The current implementation is based on the ORAN-WG4.CUS.0-v20.00 specification.
17 * Note that other eCPRI message types are handled in packet-ecpri.c
18 */
19
20#include <config.h>
21
22#include <math.h>
23
24#include <epan/packet.h>
25#include <epan/expert.h>
26#include <epan/prefs.h>
27#include <epan/tap.h>
28#include <epan/tfs.h>
29#include <epan/reassemble.h>
30
31#include <wsutil/ws_roundup.h>
32#include <wsutil/ws_padding_to.h>
33
34#include "epan/dissectors/packet-oran.h"
35
36/* N.B. dissector preferences are taking the place of (some) M-plane parameters,
37 * so unfortunately it can be fiddly to get the preferences into a good state to
38 * decode a given capture..
39 * TODO:
40 * - for U-Plane, track back to last C-Plane frame for that eAxC
41 * doing, but this matching can be tricky see 7.8.1 Coupling of C-Plane and U-Plane
42 * - Detect/indicate signs of application layer fragmentation?
43 * same eAxC in same symbol (same/different section ID?)
44 * - Not handling M-plane setting for "little endian byte order" as applied to
45 * IQ samples and beam weights does anyone use this?
46 * - for section extensions, check more constraints (which other extension types
47 * appear with them, order, repeated)
48 * - re-order items (decl and hf definitions) to match spec order?
49 * - track energy-saving status, and identify TRX or ASM commands as 'Sleep extension'
50 */
51
52/* Prototypes */
53void proto_register_oran(void);
54
55/* Initialize the protocol and registered fields */
56static int proto_oran;
57
58static int oran_tap = -1;
59
60static int hf_oran_du_port_id;
61static int hf_oran_bandsector_id;
62static int hf_oran_cc_id;
63static int hf_oran_ru_port_id;
64static int hf_oran_sequence_id;
65static int hf_oran_e_bit;
66static int hf_oran_subsequence_id;
67static int hf_oran_previous_frame;
68
69static int hf_oran_data_direction;
70static int hf_oran_payload_version;
71static int hf_oran_filter_index;
72static int hf_oran_frame_id;
73static int hf_oran_subframe_id;
74static int hf_oran_slot_id;
75static int hf_oran_slot_within_frame;
76static int hf_oran_start_symbol_id;
77static int hf_oran_numberOfSections;
78static int hf_oran_sectionType;
79
80static int hf_oran_udCompHdr;
81static int hf_oran_udCompHdrIqWidth;
82static int hf_oran_udCompHdrIqWidth_pref;
83static int hf_oran_udCompHdrMeth;
84static int hf_oran_udCompHdrMeth_pref;
85static int hf_oran_udCompLen;
86static int hf_oran_numberOfUEs;
87static int hf_oran_timeOffset;
88static int hf_oran_frameStructure_fft;
89static int hf_oran_frameStructure_subcarrier_spacing;
90static int hf_oran_cpLength;
91static int hf_oran_timing_header;
92static int hf_oran_section_id;
93static int hf_oran_rb;
94static int hf_oran_symInc;
95static int hf_oran_startPrbc;
96static int hf_oran_reMask_re1;
97static int hf_oran_reMask_re2;
98static int hf_oran_reMask_re3;
99static int hf_oran_reMask_re4;
100static int hf_oran_reMask_re5;
101static int hf_oran_reMask_re6;
102static int hf_oran_reMask_re7;
103static int hf_oran_reMask_re8;
104static int hf_oran_reMask_re9;
105static int hf_oran_reMask_re10;
106static int hf_oran_reMask_re11;
107static int hf_oran_reMask_re12;
108static int hf_oran_reMask;
109static int hf_oran_numPrbc;
110static int hf_oran_numSymbol;
111static int hf_oran_ef;
112static int hf_oran_beamId;
113
114static int hf_oran_sinrCompHdrIqWidth_pref;
115static int hf_oran_sinrCompHdrMeth_pref;
116
117static int hf_oran_ciCompHdr;
118static int hf_oran_ciCompHdrIqWidth;
119static int hf_oran_ciCompHdrMeth;
120static int hf_oran_ciCompOpt;
121
122static int hf_oran_extension;
123static int hf_oran_exttype;
124static int hf_oran_extlen;
125
126static int hf_oran_bfw_bundle;
127static int hf_oran_bfw_bundle_id;
128static int hf_oran_bfw;
129static int hf_oran_bfw_i;
130static int hf_oran_bfw_q;
131
132static int hf_oran_ueId;
133static int hf_oran_freqOffset;
134static int hf_oran_regularizationFactor;
135static int hf_oran_laaMsgType;
136static int hf_oran_laaMsgLen;
137static int hf_oran_lbtHandle;
138static int hf_oran_lbtDeferFactor;
139static int hf_oran_lbtBackoffCounter;
140static int hf_oran_lbtOffset;
141static int hf_oran_MCOT;
142static int hf_oran_lbtMode;
143static int hf_oran_sfnSfEnd;
144static int hf_oran_lbtPdschRes;
145static int hf_oran_sfStatus;
146static int hf_oran_initialPartialSF;
147static int hf_oran_lbtDrsRes;
148static int hf_oran_lbtBufErr;
149static int hf_oran_lbtTrafficClass;
150static int hf_oran_lbtCWConfig_H;
151static int hf_oran_lbtCWConfig_T;
152static int hf_oran_lbtCWR_Rst;
153
154static int hf_oran_reserved;
155static int hf_oran_reserved_1bit;
156static int hf_oran_reserved_2bits;
157static int hf_oran_reserved_3bits;
158static int hf_oran_reserved_4bits;
159static int hf_oran_reserved_last_4bits;
160static int hf_oran_reserved_last_5bits;
161static int hf_oran_reserved_6bits;
162static int hf_oran_reserved_last_6bits;
163static int hf_oran_reserved_7bits;
164static int hf_oran_reserved_last_7bits;
165static int hf_oran_reserved_8bits;
166static int hf_oran_reserved_16bits;
167static int hf_oran_reserved_15bits;
168static int hf_oran_reserved_bit1;
169static int hf_oran_reserved_bit2;
170static int hf_oran_reserved_bit4;
171static int hf_oran_reserved_bit5;
172static int hf_oran_reserved_bits123;
173static int hf_oran_reserved_bits456;
174
175static int hf_oran_bundle_offset;
176static int hf_oran_cont_ind;
177
178static int hf_oran_bfwCompHdr;
179static int hf_oran_bfwCompHdr_iqWidth;
180static int hf_oran_bfwCompHdr_compMeth;
181static int hf_oran_symbolId;
182static int hf_oran_startPrbu;
183static int hf_oran_numPrbu;
184
185static int hf_oran_udCompParam;
186static int hf_oran_sReSMask;
187static int hf_oran_sReSMask_re12;
188static int hf_oran_sReSMask_re11;
189static int hf_oran_sReSMask_re10;
190static int hf_oran_sReSMask_re9;
191static int hf_oran_sReSMask_re8;
192static int hf_oran_sReSMask_re7;
193static int hf_oran_sReSMask_re6;
194static int hf_oran_sReSMask_re5;
195static int hf_oran_sReSMask_re4;
196static int hf_oran_sReSMask_re3;
197static int hf_oran_sReSMask_re2;
198static int hf_oran_sReSMask_re1;
199
200static int hf_oran_sReSMask1;
201static int hf_oran_sReSMask2;
202static int hf_oran_sReSMask1_2_re12;
203static int hf_oran_sReSMask1_2_re11;
204static int hf_oran_sReSMask1_2_re10;
205static int hf_oran_sReSMask1_2_re9;
206
207static int hf_oran_bfwCompParam;
208
209static int hf_oran_iSample;
210static int hf_oran_qSample;
211
212static int hf_oran_ciCompParam;
213
214static int hf_oran_blockScaler;
215static int hf_oran_compBitWidth;
216static int hf_oran_compShift;
217
218static int hf_oran_active_beamspace_coefficient_n1;
219static int hf_oran_active_beamspace_coefficient_n2;
220static int hf_oran_active_beamspace_coefficient_n3;
221static int hf_oran_active_beamspace_coefficient_n4;
222static int hf_oran_active_beamspace_coefficient_n5;
223static int hf_oran_active_beamspace_coefficient_n6;
224static int hf_oran_active_beamspace_coefficient_n7;
225static int hf_oran_active_beamspace_coefficient_n8;
226static int hf_oran_activeBeamspaceCoefficientMask;
227static int hf_oran_activeBeamspaceCoefficientMask_bits_set;
228
229static int hf_oran_se6_repetition;
230
231static int hf_oran_rbgSize;
232static int hf_oran_rbgMask;
233static int hf_oran_noncontig_priority;
234
235static int hf_oran_symbol_mask;
236static int hf_oran_symbol_mask_s13;
237static int hf_oran_symbol_mask_s12;
238static int hf_oran_symbol_mask_s11;
239static int hf_oran_symbol_mask_s10;
240static int hf_oran_symbol_mask_s9;
241static int hf_oran_symbol_mask_s8;
242static int hf_oran_symbol_mask_s7;
243static int hf_oran_symbol_mask_s6;
244static int hf_oran_symbol_mask_s5;
245static int hf_oran_symbol_mask_s4;
246static int hf_oran_symbol_mask_s3;
247static int hf_oran_symbol_mask_s2;
248static int hf_oran_symbol_mask_s1;
249static int hf_oran_symbol_mask_s0;
250
251static int hf_oran_exponent;
252static int hf_oran_iq_user_data;
253
254static int hf_oran_disable_bfws;
255static int hf_oran_rad;
256static int hf_oran_num_bund_prbs;
257static int hf_oran_beam_id;
258static int hf_oran_num_weights_per_bundle;
259
260static int hf_oran_ack_nack_req_id;
261
262static int hf_oran_frequency_range;
263static int hf_oran_off_start_prb;
264static int hf_oran_num_prb;
265
266static int hf_oran_samples_prb;
267static int hf_oran_ciSample;
268static int hf_oran_ciIsample;
269static int hf_oran_ciQsample;
270
271static int hf_oran_beamGroupType;
272static int hf_oran_numPortc;
273
274static int hf_oran_csf;
275static int hf_oran_modcompscaler;
276
277static int hf_oran_modcomp_param_set;
278static int hf_oran_mc_scale_re_mask_re1;
279static int hf_oran_mc_scale_re_mask_re2;
280static int hf_oran_mc_scale_re_mask_re3;
281static int hf_oran_mc_scale_re_mask_re4;
282static int hf_oran_mc_scale_re_mask_re5;
283static int hf_oran_mc_scale_re_mask_re6;
284static int hf_oran_mc_scale_re_mask_re7;
285static int hf_oran_mc_scale_re_mask_re8;
286static int hf_oran_mc_scale_re_mask_re9;
287static int hf_oran_mc_scale_re_mask_re10;
288static int hf_oran_mc_scale_re_mask_re11;
289static int hf_oran_mc_scale_re_mask_re12;
290static int hf_oran_mc_scale_re_mask_re1_even;
291static int hf_oran_mc_scale_re_mask_re2_even;
292static int hf_oran_mc_scale_re_mask_re3_even;
293static int hf_oran_mc_scale_re_mask_re4_even;
294static int hf_oran_mc_scale_re_mask_re5_even;
295static int hf_oran_mc_scale_re_mask_re6_even;
296static int hf_oran_mc_scale_re_mask_re7_even;
297static int hf_oran_mc_scale_re_mask_re8_even;
298static int hf_oran_mc_scale_re_mask_re9_even;
299static int hf_oran_mc_scale_re_mask_re10_even;
300static int hf_oran_mc_scale_re_mask_re11_even;
301static int hf_oran_mc_scale_re_mask_re12_even;
302
303static int hf_oran_mc_scale_re_mask;
304static int hf_oran_mc_scale_re_mask_even;
305
306static int hf_oran_mc_scale_offset;
307
308static int hf_oran_eAxC_mask;
309static int hf_oran_technology;
310static int hf_oran_nullLayerInd;
311
312static int hf_oran_se19_repetition;
313static int hf_oran_portReMask;
314static int hf_oran_portSymbolMask;
315
316static int hf_oran_ext19_port;
317
318static int hf_oran_prb_allocation;
319static int hf_oran_nextSymbolId;
320static int hf_oran_nextStartPrbc;
321
322static int hf_oran_puncPattern;
323static int hf_oran_numPuncPatterns;
324static int hf_oran_symbolMask_ext20;
325static int hf_oran_startPuncPrb;
326static int hf_oran_numPuncPrb;
327static int hf_oran_puncReMask;
328static int hf_oran_multiSDScope;
329static int hf_oran_RbgIncl;
330
331static int hf_oran_ci_prb_group_size;
332static int hf_oran_prg_size_st5;
333static int hf_oran_prg_size_st6;
334
335static int hf_oran_num_ueid;
336
337static int hf_oran_antMask;
338
339static int hf_oran_transmissionWindowOffset;
340static int hf_oran_transmissionWindowSize;
341static int hf_oran_toT;
342
343static int hf_oran_bfaCompHdr;
344static int hf_oran_bfAzPtWidth;
345static int hf_oran_bfZePtWidth;
346static int hf_oran_bfAz3ddWidth;
347static int hf_oran_bfZe3ddWidth;
348static int hf_oran_bfAzPt;
349static int hf_oran_bfZePt;
350static int hf_oran_bfAz3dd;
351static int hf_oran_bfZe3dd;
352static int hf_oran_bfAzSl;
353static int hf_oran_bfZeSl;
354
355static int hf_oran_cmd_scope;
356static int hf_oran_number_of_st4_cmds;
357
358static int hf_oran_st4_cmd_header;
359static int hf_oran_st4_cmd_type;
360static int hf_oran_st4_cmd_len;
361static int hf_oran_st4_cmd_num_slots;
362static int hf_oran_st4_cmd_ack_nack_req_id;
363
364static int hf_oran_st4_cmd;
365
366static int hf_oran_sleepmode_trx;
367static int hf_oran_sleepmode_asm;
368static int hf_oran_log2maskbits;
369static int hf_oran_num_slots_ext;
370static int hf_oran_antMask_trx_control;
371
372static int hf_oran_ready;
373static int hf_oran_number_of_acks;
374static int hf_oran_number_of_nacks;
375static int hf_oran_ackid;
376static int hf_oran_nackid;
377
378static int hf_oran_acknack_request_frame;
379static int hf_oran_acknack_request_time;
380static int hf_oran_acknack_request_type;
381static int hf_oran_acknack_response_frame;
382static int hf_oran_acknack_response_time;
383
384static int hf_oran_disable_tdbfns;
385static int hf_oran_td_beam_group;
386static int hf_oran_disable_tdbfws;
387static int hf_oran_td_beam_num;
388
389static int hf_oran_dir_pattern;
390static int hf_oran_guard_pattern;
391
392static int hf_oran_ecpri_pcid;
393static int hf_oran_ecpri_rtcid;
394static int hf_oran_ecpri_seqid;
395
396static int hf_oran_num_sym_prb_pattern;
397static int hf_oran_prb_mode;
398static int hf_oran_sym_prb_pattern;
399static int hf_oran_sym_mask;
400static int hf_oran_num_mc_scale_offset;
401static int hf_oran_prb_pattern;
402static int hf_oran_prb_block_offset;
403static int hf_oran_prb_block_size;
404
405static int hf_oran_codebook_index;
406static int hf_oran_layerid;
407static int hf_oran_numlayers;
408static int hf_oran_txscheme;
409static int hf_oran_crs_remask;
410static int hf_oran_crs_shift;
411static int hf_oran_crs_symnum;
412static int hf_oran_beamid_ap1;
413static int hf_oran_beamid_ap2;
414static int hf_oran_beamid_ap3;
415
416static int hf_oran_port_list_index;
417static int hf_oran_alpn_per_sym;
418static int hf_oran_ant_dmrs_snr;
419static int hf_oran_user_group_size;
420static int hf_oran_user_group_id;
421static int hf_oran_entry_type;
422static int hf_oran_dmrs_port_number;
423static int hf_oran_ueid_reset;
424
425static int hf_oran_dmrs_symbol_mask;
426static int hf_oran_dmrs_symbol_mask_s13;
427static int hf_oran_dmrs_symbol_mask_s12;
428static int hf_oran_dmrs_symbol_mask_s11;
429static int hf_oran_dmrs_symbol_mask_s10;
430static int hf_oran_dmrs_symbol_mask_s9;
431static int hf_oran_dmrs_symbol_mask_s8;
432static int hf_oran_dmrs_symbol_mask_s7;
433static int hf_oran_dmrs_symbol_mask_s6;
434static int hf_oran_dmrs_symbol_mask_s5;
435static int hf_oran_dmrs_symbol_mask_s4;
436static int hf_oran_dmrs_symbol_mask_s3;
437static int hf_oran_dmrs_symbol_mask_s2;
438static int hf_oran_dmrs_symbol_mask_s1;
439static int hf_oran_dmrs_symbol_mask_s0;
440
441static int hf_oran_scrambling;
442static int hf_oran_nscid;
443static int hf_oran_dtype;
444static int hf_oran_cmd_without_data;
445static int hf_oran_lambda;
446static int hf_oran_first_prb;
447static int hf_oran_last_prb;
448static int hf_oran_low_papr_type;
449static int hf_oran_hopping_mode;
450
451static int hf_oran_tx_win_for_on_air_symbol_l;
452static int hf_oran_tx_win_for_on_air_symbol_r;
453
454static int hf_oran_num_fo_fb;
455static int hf_oran_freq_offset_fb;
456
457static int hf_oran_num_ue_sinr_rpt;
458static int hf_oran_num_sinr_per_prb;
459static int hf_oran_num_sinr_per_prb_right;
460
461static int hf_oran_sinr_value;
462
463static int hf_oran_measurement_report;
464static int hf_oran_mf;
465static int hf_oran_meas_data_size;
466static int hf_oran_meas_type_id;
467static int hf_oran_ipn_power;
468static int hf_oran_ue_tae;
469static int hf_oran_ue_layer_power;
470static int hf_oran_num_elements;
471static int hf_oran_ant_dmrs_snr_val;
472static int hf_oran_ue_freq_offset;
473
474static int hf_oran_measurement_command;
475
476static int hf_oran_beam_type;
477static int hf_oran_meas_cmd_size;
478
479static int hf_oran_symbol_reordering_layer;
480static int hf_oran_dmrs_entry;
481
482static int hf_oran_c_section_common;
483static int hf_oran_c_section;
484static int hf_oran_u_section;
485
486static int hf_oran_u_section_ul_symbol_time;
487static int hf_oran_u_section_ul_symbol_frames;
488static int hf_oran_u_section_ul_symbol_first_frame;
489static int hf_oran_u_section_ul_symbol_last_frame;
490
491static int hf_oran_cd_scg_size;
492static int hf_oran_cd_scg_phase_step;
493
494static int hf_oran_sinr_prb;
495static int hf_oran_oru_control_sinr_slot_mask_id;
496static int hf_oran_pos_meas;
497
498static int hf_oran_ue_radial_speed;
499static int hf_oran_ue_az_aoa;
500static int hf_oran_ue_ze_aoa;
501static int hf_oran_ue_pos_toa_offset;
502
503static int hf_oran_num_rep_ue;
504static int hf_oran_rep_ueid;
505static int hf_oran_is_last_rep;
506static int hf_oran_rep_index;
507static int hf_oran_num_reps;
508
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;
531
532
533/* Convenient fields for filtering, mostly shown as hidden */
534static int hf_oran_cplane;
535static int hf_oran_uplane;
536static int hf_oran_bf; /* to match frames that configure beamforming in any way */
537static int hf_oran_zero_prb;
538static int hf_oran_nonzero_prb;
539static int hf_oran_bundle_weights_all_zero;
540
541static int hf_oran_ul_cplane_ud_comp_hdr_frame;
542
543/* For reassembly */
544static int hf_oran_fragments;
545static int hf_oran_fragment;
546static int hf_oran_fragment_overlap;
547static int hf_oran_fragment_overlap_conflict;
548static int hf_oran_fragment_multiple_tails;
549static int hf_oran_fragment_too_long_fragment;
550static int hf_oran_fragment_error;
551static int hf_oran_fragment_count;
552static int hf_oran_reassembled_in;
553static int hf_oran_reassembled_length;
554static int hf_oran_reassembled_data;
555
556static int hf_oran_payload;
557
558
559/* Subtrees */
560static int ett_oran;
561static int ett_oran_ecpri_rtcid;
562static int ett_oran_ecpri_pcid;
563static int ett_oran_ecpri_seqid;
564static int ett_oran_section;
565static int ett_oran_section_type;
566static int ett_oran_u_timing;
567static int ett_oran_u_section;
568static int ett_oran_u_prb;
569static int ett_oran_iq;
570static int ett_oran_bfw_bundle;
571static int ett_oran_bfw;
572static int ett_oran_frequency_range;
573static int ett_oran_prb_cisamples;
574static int ett_oran_cisample;
575static int ett_oran_udcomphdr;
576static int ett_oran_udcompparam;
577static int ett_oran_cicomphdr;
578static int ett_oran_cicompparam;
579static int ett_oran_bfwcomphdr;
580static int ett_oran_bfwcompparam;
581static int ett_oran_ext19_port;
582static int ett_oran_prb_allocation;
583static int ett_oran_punc_pattern;
584static int ett_oran_bfacomphdr;
585static int ett_oran_modcomp_param_set;
586static int ett_oran_st4_cmd_header;
587static int ett_oran_st4_cmd;
588static int ett_oran_sym_prb_pattern;
589static int ett_oran_measurement_report;
590static int ett_oran_measurement_command;
591static int ett_oran_sresmask;
592static int ett_oran_c_section_common;
593static int ett_oran_c_section;
594static int ett_oran_remask;
595static int ett_oran_mc_scale_remask;
596static int ett_oran_symbol_reordering_layer;
597static int ett_oran_dmrs_entry;
598static int ett_oran_dmrs_symbol_mask;
599static int ett_oran_symbol_mask;
600static int ett_oran_active_beamspace_coefficient_mask;
601static int ett_oran_sinr_prb;
602
603static int ett_oran_fragment;
604static int ett_oran_fragments;
605
606/* Reassembly table. */
607static reassembly_table oran_reassembly_table;
608
609static void *oran_key(const packet_info *pinfo _U___attribute__((unused)), const uint32_t id _U___attribute__((unused)), const void *data)
610{
611 return (void *)data;
612}
613
614static void oran_free_key(void *ptr _U___attribute__((unused)))
615{
616}
617
618static reassembly_table_functions oran_reassembly_table_functions =
619{
620 g_direct_hash,
621 g_direct_equal,
622 oran_key,
623 oran_key,
624 oran_free_key,
625 oran_free_key
626};
627
628static const fragment_items oran_frag_items = {
629 &ett_oran_fragment,
630 &ett_oran_fragments,
631 &hf_oran_fragments,
632 &hf_oran_fragment,
633 &hf_oran_fragment_overlap,
634 &hf_oran_fragment_overlap_conflict,
635 &hf_oran_fragment_multiple_tails,
636 &hf_oran_fragment_too_long_fragment,
637 &hf_oran_fragment_error,
638 &hf_oran_fragment_count,
639 &hf_oran_reassembled_in,
640 &hf_oran_reassembled_length,
641 &hf_oran_reassembled_data,
642 "O-RAN FH CUS fragments"
643};
644
645
646
647/* Don't want all extensions to open and close together. Use [extType-1] entry */
648static int ett_oran_c_section_extension[HIGHEST_EXTTYPE32];
649
650/* Expert info */
651static expert_field ei_oran_unsupported_bfw_compression_method;
652static expert_field ei_oran_invalid_sample_bit_width;
653static expert_field ei_oran_reserved_numBundPrb;
654static expert_field ei_oran_extlen_wrong;
655static expert_field ei_oran_invalid_eaxc_bit_width;
656static expert_field ei_oran_extlen_zero;
657static expert_field ei_oran_rbg_size_reserved;
658static expert_field ei_oran_frame_length;
659static expert_field ei_oran_numprbc_ext21_zero;
660static expert_field ei_oran_ci_prb_group_size_reserved;
661static expert_field ei_oran_st8_nackid;
662static expert_field ei_oran_st4_no_cmds;
663static expert_field ei_oran_st4_zero_len_cmd;
664static expert_field ei_oran_st4_wrong_len_cmd;
665static expert_field ei_oran_st4_unknown_cmd;
666static expert_field ei_oran_mcot_out_of_range;
667static expert_field ei_oran_se10_unknown_beamgrouptype;
668static expert_field ei_oran_se10_not_allowed;
669static expert_field ei_oran_start_symbol_id_not_zero;
670static expert_field ei_oran_trx_control_cmd_scope;
671static expert_field ei_oran_unhandled_se;
672static expert_field ei_oran_bad_symbolmask;
673static expert_field ei_oran_numslots_not_zero;
674static expert_field ei_oran_version_unsupported;
675static expert_field ei_oran_laa_msg_type_unsupported;
676static expert_field ei_oran_se_on_unsupported_st;
677static expert_field ei_oran_cplane_unexpected_sequence_number_ul;
678static expert_field ei_oran_cplane_unexpected_sequence_number_dl;
679static expert_field ei_oran_uplane_unexpected_sequence_number_ul;
680static expert_field ei_oran_uplane_unexpected_sequence_number_dl;
681static expert_field ei_oran_acknack_no_request;
682static expert_field ei_oran_udpcomphdr_should_be_zero;
683static expert_field ei_oran_radio_fragmentation_c_plane;
684static expert_field ei_oran_lastRbdid_out_of_range;
685static expert_field ei_oran_rbgMask_beyond_last_rbdid;
686static expert_field ei_oran_unexpected_measTypeId;
687static expert_field ei_oran_unsupported_compression_method;
688static expert_field ei_oran_ud_comp_len_wrong_size;
689static expert_field ei_oran_sresmask2_not_zero_with_rb;
690static expert_field ei_oran_st6_rb_shall_be_0;
691static expert_field ei_oran_st9_not_ul;
692static expert_field ei_oran_st10_numsymbol_not_14;
693static expert_field ei_oran_st10_startsymbolid_not_0;
694static expert_field ei_oran_st10_not_ul;
695static expert_field ei_oran_se24_nothing_to_inherit;
696static expert_field ei_oran_num_sinr_per_prb_unknown;
697static expert_field ei_oran_start_symbol_id_bits_ignored;
698static expert_field ei_oran_user_group_id_reserved_value;
699static expert_field ei_oran_port_list_index_zero;
700static expert_field ei_oran_ul_uplane_symbol_too_long;
701static expert_field ei_oran_reserved_not_zero;
702static expert_field ei_oran_too_many_symbols;
703static expert_field ei_oran_se30_not_ul;
704static expert_field ei_oran_se30_unknown_ueid;
705static expert_field ei_oran_beamid_bfws_not_found;
706static expert_field ei_oran_syminc_set_for_uplane;
707
708
709
710/* These are the message types handled by this dissector. Others have handling in packet-ecpri.c */
711#define ECPRI_MT_IQ_DATA0 0
712#define ECPRI_MT_RT_CTRL_DATA2 2
713
714
715/* Preference settings - try to set reasonable defaults */
716static unsigned pref_du_port_id_bits = 4;
717static unsigned pref_bandsector_id_bits = 4;
718static unsigned pref_cc_id_bits = 4;
719static unsigned pref_ru_port_id_bits = 4;
720
721/* TODO: ideally should be per-flow */
722static unsigned pref_sample_bit_width_uplink = 14;
723static unsigned pref_sample_bit_width_downlink = 14;
724static unsigned pref_sample_bit_width_sinr = 14;
725
726/* TODO: these ideally should be per-flow too */
727static int pref_iqCompressionUplink = COMP_BLOCK_FP1;
728static int pref_iqCompressionDownlink = COMP_BLOCK_FP1;
729
730static int pref_iqCompressionSINR = COMP_BLOCK_FP1;
731
732
733/* Is udCompHeader present (both directions) */
734static int pref_includeUdCompHeaderUplink = 2; /* start using heuristic */
735static int pref_includeUdCompHeaderDownlink = 2; /* start using heuristic */
736
737/* Are we ignoring UL C-Plane udCompHdr? */
738static bool_Bool pref_override_ul_compression = false0;
739
740static unsigned pref_data_plane_section_total_rbs = 273;
741static unsigned pref_num_bf_antennas = 32;
742static bool_Bool pref_showIQSampleValues = true1;
743
744/* Based upon m-plane param, so will be system-wide */
745static int pref_support_udcompLen = 2; /* start heuristic, can force other settings if necessary */
746static bool_Bool udcomplen_heuristic_result_set = false0;
747static bool_Bool udcomplen_heuristic_result = false0;
748
749/* st6-4byte-alignment-required */
750static bool_Bool st6_4byte_alignment = false0;
751
752/* Requested, allows I/Q to be stored as integers.. */
753static bool_Bool show_unscaled_values = false0;
754
755/* Initialized off. Timing is in microseconds. */
756static unsigned us_allowed_for_ul_in_symbol = 0;
757
758/* Reassemble U-Plane (at Radio Transport layer) */
759static bool_Bool do_radio_transport_layer_reassembly = true1;
760
761/* Link U-plane back to C-plane using sectionIds */
762static bool_Bool link_planes_together = true1;
763
764static const enum_val_t dl_compression_options[] = {
765 { "COMP_NONE", "No Compression", COMP_NONE0 },
766 { "COMP_BLOCK_FP", "Block Floating Point Compression", COMP_BLOCK_FP1 },
767 { "COMP_BLOCK_SCALE", "Block Scaling Compression", COMP_BLOCK_SCALE2 },
768 { "COMP_U_LAW", "u-Law Compression", COMP_U_LAW3 },
769 { "COMP_MODULATION", "Modulation Compression", COMP_MODULATION4 },
770 { "BFP_AND_SELECTIVE_RE", "Block Floating Point + selective RE sending", BFP_AND_SELECTIVE_RE5 },
771 { "MOD_COMPR_AND_SELECTIVE_RE", "Modulation Compression + selective RE sending", MOD_COMPR_AND_SELECTIVE_RE6 },
772 { "BFP_AND_SELECTIVE_RE_WITH_MASKS", "Block Floating Point + selective RE sending with masks in section header", BFP_AND_SELECTIVE_RE_WITH_MASKS7 },
773 { "MOD_COMPR_AND_SELECTIVE_RE_WITH_MASKS", "Modulation Compression + selective RE sending with masks in section header", MOD_COMPR_AND_SELECTIVE_RE6 },
774 { NULL((void*)0), NULL((void*)0), 0 }
775};
776
777/* No Modulation compression in UL.. */
778static const enum_val_t ul_compression_options[] = {
779 { "COMP_NONE", "No Compression", COMP_NONE0 },
780 { "COMP_BLOCK_FP", "Block Floating Point Compression", COMP_BLOCK_FP1 },
781 { "COMP_BLOCK_SCALE", "Block Scaling Compression", COMP_BLOCK_SCALE2 },
782 { "COMP_U_LAW", "u-Law Compression", COMP_U_LAW3 },
783 { "BFP_AND_SELECTIVE_RE", "Block Floating Point + selective RE sending", BFP_AND_SELECTIVE_RE5 },
784 { "BFP_AND_SELECTIVE_RE_WITH_MASKS", "Block Floating Point + selective RE sending with masks in section header", BFP_AND_SELECTIVE_RE_WITH_MASKS7 },
785 { NULL((void*)0), NULL((void*)0), 0 }
786};
787
788static const enum_val_t udcomplen_support_options[] = {
789 { "NOT_SUPPORTED", "Not Supported", 0 },
790 { "SUPPORTED", "Supported", 1 },
791 { "HEURISTIC", "Attempt Heuristic", 2 },
792 { NULL((void*)0), NULL((void*)0), 0 }
793};
794
795static const enum_val_t udcomphdr_present_options[] = {
796 { "NOT_PRESENT", "Not Present", 0 },
797 { "PRESENT", "Present", 1 },
798 { "HEURISTIC", "Attempt Heuristic", 2 },
799 { NULL((void*)0), NULL((void*)0), 0 }
800};
801
802
803
804static const value_string e_bit[] = {
805 { 0, "More fragments follow" },
806 { 1, "Last fragment" },
807 { 0, NULL((void*)0)}
808};
809
810#define DIR_UPLINK0 0
811#define DIR_DOWNLINK1 1
812
813
814static const value_string data_direction_vals[] = {
815 { DIR_UPLINK0, "Uplink" }, /* gNB Rx */
816 { DIR_DOWNLINK1, "Downlink" }, /* gNB Tx */
817 { 0, NULL((void*)0)}
818};
819
820static const value_string rb_vals[] = {
821 { 0, "Every RB used" },
822 { 1, "Every other RB used" },
823 { 0, NULL((void*)0)}
824};
825
826static const value_string sym_inc_vals[] = {
827 { 0, "Use the current symbol number" },
828 { 1, "Increment the current symbol number" },
829 { 0, NULL((void*)0)}
830};
831
832static const value_string lbtMode_vals[] = {
833 { 0, "Full LBT (regular LBT, sending reservation signal until the beginning of the SF/slot)" },
834 { 1, "Partial LBT (looking back 25 usec prior to transmission" },
835 { 2, "Partial LBT (looking back 34 usec prior to transmission" },
836 { 3, "Full LBT and stop (regular LBT, without sending reservation signal" },
837 { 0, NULL((void*)0)}
838};
839
840static const value_string ue_rank_vals[] = {
841 { 1, "1" },
842 { 2, "2" },
843 { 3, "3" },
844 { 4, "4" },
845 { 0, NULL((void*)0)}
846};
847
848static const value_string num_of_ue_ant_ports_vals[] = {
849 { 2, "2" },
850 { 4, "4" },
851 { 0, NULL((void*)0)}
852};
853
854static const value_string codebook_subset_vals[] = {
855 { 0, "nonCoherent" },
856 { 1, "partialAndNonCoherent" },
857 { 2, "fullyAndPartialAndNonCoherent" },
858 { 3, "reserved" },
859 { 0, NULL((void*)0)}
860};
861
862
863static const range_string filter_indices[] = {
864 {0, 0, "standard channel filter"},
865 {1, 1, "UL filter for PRACH preamble formats 0, 1, 2; min. passband 839 x 1.25kHz = 1048.75 kHz"},
866 {2, 2, "UL filter for PRACH preamble format 3, min. passband 839 x 5 kHz = 4195 kHz"},
867 {3, 3, "UL filter for PRACH preamble formats A1, A2, A3, B1, B2, B3, B4, C0, C2; min. passband 139 x \u0394fRA"},
868 {4, 4, "UL filter for NPRACH 0, 1; min. passband 48 x 3.75KHz = 180 KHz"},
869 {5, 5, "UL filter for PRACH preamble formats"},
870 {8, 8, "UL filter NPUSCH"},
871 {9, 9, "Mixed numerology and other channels except PRACH and NB-IoT"},
872 {9, 15, "Reserved"},
873 {0, 0, NULL((void*)0)}
874};
875
876/* 7.3.1-1 */
877static const range_string section_types[] = {
878 { SEC_C_UNUSED_RB, SEC_C_UNUSED_RB, "Unused Resource Blocks or symbols in Downlink or Uplink" },
879 { SEC_C_NORMAL, SEC_C_NORMAL, "Most DL/UL radio channels" },
880 { SEC_C_RSVD2, SEC_C_RSVD2, "Reserved for future use" },
881 { SEC_C_PRACH, SEC_C_PRACH, "PRACH and mixed-numerology channels" },
882 { SEC_C_SLOT_CONTROL, SEC_C_SLOT_CONTROL, "Slot Configuration Control" },
883 { SEC_C_UE_SCHED, SEC_C_UE_SCHED, "UE scheduling information (UE-ID assignment to section)" },
884 { SEC_C_CH_INFO, SEC_C_CH_INFO, "Channel information" },
885 { SEC_C_LAA, SEC_C_LAA, "LAA (License Assisted Access)" },
886 { SEC_C_ACK_NACK_FEEDBACK, SEC_C_ACK_NACK_FEEDBACK, "ACK/NACK Feedback" },
887 { SEC_C_SINR_REPORTING, SEC_C_SINR_REPORTING, "SINR Reporting" },
888 { SEC_C_RRM_MEAS_REPORTS, SEC_C_RRM_MEAS_REPORTS, "RRM Measurement Reports" },
889 { SEC_C_REQUEST_RRM_MEAS, SEC_C_REQUEST_RRM_MEAS, "Request RRM Measurements" },
890 { 12, 255, "Reserved for future use" },
891 { 0, 0, NULL((void*)0)} };
892
893static const range_string section_types_short[] = {
894 { SEC_C_UNUSED_RB, SEC_C_UNUSED_RB, "(Unused RBs) " },
895 { SEC_C_NORMAL, SEC_C_NORMAL, "(Most channels) " },
896 { SEC_C_RSVD2, SEC_C_RSVD2, "(reserved) " },
897 { SEC_C_PRACH, SEC_C_PRACH, "(PRACH/mixed-\u03bc)" },
898 { SEC_C_SLOT_CONTROL, SEC_C_SLOT_CONTROL, "(Slot info) " },
899 { SEC_C_UE_SCHED, SEC_C_UE_SCHED, "(UE scheduling info)" },
900 { SEC_C_CH_INFO, SEC_C_CH_INFO, "(Channel info) " },
901 { SEC_C_LAA, SEC_C_LAA, "(LAA) " },
902 { SEC_C_ACK_NACK_FEEDBACK, SEC_C_ACK_NACK_FEEDBACK, "(ACK/NACK) " },
903 { SEC_C_SINR_REPORTING, SEC_C_SINR_REPORTING, "(SINR Reporting) " },
904 { SEC_C_RRM_MEAS_REPORTS, SEC_C_RRM_MEAS_REPORTS, "(RRM Meas Reports) " },
905 { SEC_C_REQUEST_RRM_MEAS, SEC_C_REQUEST_RRM_MEAS, "(Req RRM Meas) " },
906 { 12, 255, "Reserved for future use" },
907 { 0, 0, NULL((void*)0) }
908};
909
910static const range_string ud_comp_header_width[] = {
911 {0, 0, "I and Q are each 16 bits wide"},
912 {1, 15, "Bit width of I and Q"},
913 {0, 0, NULL((void*)0)} };
914
915/* Table 8.3.3.13-3 */
916static const range_string ud_comp_header_meth[] = {
917 {COMP_NONE0, COMP_NONE0, "No compression" },
918 {COMP_BLOCK_FP1, COMP_BLOCK_FP1, "Block floating point compression" },
919 {COMP_BLOCK_SCALE2, COMP_BLOCK_SCALE2, "Block scaling" },
920 {COMP_U_LAW3, COMP_U_LAW3, "Mu - law" },
921 {COMP_MODULATION4, COMP_MODULATION4, "Modulation compression" },
922 {BFP_AND_SELECTIVE_RE5, BFP_AND_SELECTIVE_RE5, "BFP + selective RE sending" },
923 {MOD_COMPR_AND_SELECTIVE_RE6, MOD_COMPR_AND_SELECTIVE_RE6, "mod-compr + selective RE sending" },
924 {BFP_AND_SELECTIVE_RE_WITH_MASKS7, BFP_AND_SELECTIVE_RE_WITH_MASKS7, "BFP + selective RE sending with masks in section header" },
925 {MOD_COMPR_AND_SELECTIVE_RE_WITH_MASKS8, MOD_COMPR_AND_SELECTIVE_RE_WITH_MASKS8, "mod-compr + selective RE sending with masks in section header"},
926 {9, 15, "Reserved"},
927 {0, 0, NULL((void*)0)}
928};
929
930/* Table 7.5.2.13-2 */
931static const range_string frame_structure_fft[] = {
932 {0, 0, "Reserved (no FFT/iFFT processing)"},
933 {1, 3, "Reserved"},
934 {4, 4, "FFT size 16"},
935 {5, 5, "FFT size 32"},
936 {6, 6, "FFT size 64"},
937 {7, 7, "FFT size 128"},
938 {8, 8, "FFT size 256"},
939 {9, 9, "FFT size 512"},
940 {10, 10, "FFT size 1024"},
941 {11, 11, "FFT size 2048"},
942 {12, 12, "FFT size 4096"},
943 {13, 13, "FFT size 1536"},
944 {14, 14, "FFT size 3072"},
945 {15, 15, "Reserved"},
946 {0, 0, NULL((void*)0)}
947};
948
949/* Table 7.5.2.13-3 */
950static const range_string subcarrier_spacings[] = {
951 { 0, 0, "SCS 15 kHz, 1 slot/subframe, slot length 1 ms" },
952 { 1, 1, "SCS 30 kHz, 2 slots/subframe, slot length 500 \u03bcs" },
953 { 2, 2, "SCS 60 kHz, 4 slots/subframe, slot length 250 \u03bcs" },
954 { 3, 3, "SCS 120 kHz, 8 slots/subframe, slot length 125 \u03bcs" },
955 { 4, 4, "SCS 240 kHz, 16 slots/subframe, slot length 62.5 \u03bcs" },
956 { 5, 11, "Reserved" }, /* N.B., 5 was 480kHz in early spec versions */
957 { 12, 12, "SCS 1.25 kHz, 1 slot/subframe, slot length 1 ms" },
958 { 13, 13, "SCS 3.75 kHz(LTE - specific), 1 slot/subframe, slot length 1 ms" },
959 { 14, 14, "SCS 5 kHz, 1 slot/subframe, slot length 1 ms" },
960 { 15, 15, "SCS 7.5 kHz(LTE - specific), 1 slot/subframe, slot length 1 ms" },
961 { 0, 0, NULL((void*)0) }
962};
963
964/* Table 7.5.3.14-1 laaMsgType definition */
965static const range_string laaMsgTypes[] = {
966 {0, 0, "LBT_PDSCH_REQ - lls - O-DU to O-RU request to obtain a PDSCH channel"},
967 {1, 1, "LBT_DRS_REQ - lls - O-DU to O-RU request to obtain the channel and send DRS"},
968 {2, 2, "LBT_PDSCH_RSP - O-RU to O-DU response, channel acq success or failure"},
969 {3, 3, "LBT_DRS_RSP - O-RU to O-DU response, DRS sending success or failure"},
970 {4, 4, "LBT_Buffer_Error - O-RU to O-DU response, reporting buffer overflow"},
971 {5, 5, "LBT_CWCONFIG_REQ - O-DU to O-RU request, congestion window configuration"},
972 {6, 6, "LBT_CWCONFIG_RST - O-RU to O-DU request, congestion window config, response"},
973 {7, 15, "reserved for future methods"},
974 {0, 0, NULL((void*)0)}
975};
976
977/* 7.7.26.3 */
978static const range_string freq_offset_fb_values[] = {
979 {0, 0, "no frequency offset"},
980 {8000, 8000, "value not provided"},
981 {1, 30000, "positive frequency offset, (0, +0.5] subcarrier"},
982 {0x8ad0, 0xffff, "negative frequency offset, [-0.5, 0) subcarrier"},
983 {0x0, 0xffff, "reserved"},
984 {0, 0, NULL((void*)0)}
985};
986
987/* Table 7.5.2.19-1 */
988static const value_string num_sinr_per_prb_vals[] = {
989 { 0, "1" },
990 { 1, "2" },
991 { 2, "3" },
992 { 3, "4" },
993 { 4, "6" },
994 { 5, "12" },
995 { 6, "1 SINR value per section for DFT-s-OFDM" },
996 { 7, "reserved" },
997 { 0, NULL((void*)0)}
998};
999
1000static const value_string meas_type_id_vals[] = {
1001 { 1, "UE Timing Advance Error" },
1002 { 2, "UE Layer power" },
1003 { 3, "UE frequency offset" },
1004 { 4, "Interference plus Noise for allocated PRBs" },
1005 { 5, "Interference plus Noise for unallocated PRBs" },
1006 { 6, "DMRS-SNR per antenna" },
1007 { 7, "UE positioning measurement report" },
1008 { 8, "UE radial speed measurement report" },
1009 { 9, "UE post-equalization MU inteference measurement" },
1010 { 10, "UE TPMI and rank recommendation measurement" },
1011 { 11, "UE layer pre-equalization SINR report" },
1012 { 0, NULL((void*)0)}
1013};
1014
1015static const value_string beam_type_vals[] = {
1016 { 0, "List of beamId values" },
1017 { 1, "Range of beamId values" },
1018 { 0, NULL((void*)0)}
1019};
1020
1021/* 7.7.24.3 */
1022static const value_string entry_type_vals[] = {
1023 { 0, "inherit config from preceding entry (2 or 3) ueIdReset=0" },
1024 { 1, "inherit config from preceding entry (2 or 3) ueIdReset=1" },
1025 { 2, "related parameters if have transform precoding disabled " },
1026 { 3, "related parameters if have transform precoding enabled " },
1027 { 0, NULL((void*)0)}
1028};
1029
1030/* Table 7.7.29.3-1 */
1031static const range_string cd_scg_size_vals[] = {
1032 { 0, 0, "1 subcarrier" },
1033 { 1, 1, "1 RB x N subcarriers" },
1034 { 2, 2, "2 RB x N subcarriers" },
1035 { 3, 3, "4 RB x N subcarriers" },
1036 { 4, 4, "8 RB x N subcarriers" },
1037 { 5, 5, "16 RB x N subcarriers" },
1038 { 6, 6, "32 RB x N subcarriers" },
1039 { 7, 15, "reserved"},
1040 { 0, 0, NULL((void*)0)}
1041};
1042
1043
1044/* Table 7.6.1-1 */
1045static const value_string exttype_vals[] = {
1046 {0, "Reserved"},
1047 {1, "Beamforming weights"},
1048 {2, "Beamforming attributes"},
1049 {3, "DL Precoding configuration parameters and indications"},
1050 {4, "Modulation compr. params"},
1051 {5, "Modulation compression additional scaling parameters"},
1052 {6, "Non-contiguous PRB allocation"},
1053 {7, "Multiple-eAxC designation"},
1054 {8, "Regularization factor"},
1055 {9, "Dynamic Spectrum Sharing parameters"},
1056 {10, "Multiple ports grouping"},
1057 {11, "Flexible BF weights"},
1058 {12, "Non-Contiguous PRB Allocation with Frequency Ranges"},
1059 {13, "PRB Allocation with Frequency Hopping"},
1060 {14, "Nulling-layer Info. for ueId-based beamforming"},
1061 {15, "Mixed-numerology Info. for ueId-based beamforming"},
1062 {16, "Section description for antenna mapping in UE channel information based UL beamforming"},
1063 {17, "Section description for indication of user port group"},
1064 {18, "Section description for Uplink Transmission Management"},
1065 {19, "Compact beamforming information for multiple port"},
1066 {20, "Puncturing extension"},
1067 {21, "Variable PRB group size for channel information"},
1068 {22, "ACK/NACK request"},
1069 {23, "Multiple symbol modulation compression parameters"},
1070 {24, "PUSCH DMRS configuration"},
1071 {25, "Symbol reordering for DMRS-BF"},
1072 {26, "Frequency offset feedback"},
1073 {27, "O-DU controlled dimensionality reduction"},
1074 {28, "O-DU controlled frequency resolution for SINR reporting"},
1075 {29, "Cyclic delay adjustment"},
1076 {30, "PUSCH repetition indication"},
1077 {31, "MCS Information"},
1078 {32, "Rank and TPMI measurement request"},
1079 {0, NULL((void*)0)}
1080};
1081static 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) }
;
1082
1083
1084/**************************************************************************************/
1085/* Keep track for each Section Extension, which section types are allowed to carry it */
1086typedef struct {
1087 bool_Bool ST0;
1088 bool_Bool ST1;
1089 bool_Bool ST3;
1090 bool_Bool ST5;
1091 bool_Bool ST6;
1092 bool_Bool ST10;
1093 bool_Bool ST11;
1094} AllowedCTs_t;
1095
1096
1097static const AllowedCTs_t ext_cts[HIGHEST_EXTTYPE32] = {
1098 /* ST0 ST1 ST3 ST5 ST6 ST10 ST11 */
1099 { false0, true1, true1, false0, false0, false0, false0}, // SE 1 (1,3)
1100 { false0, true1, true1, false0, false0, false0, false0}, // SE 2 (1,3)
1101 { false0, true1, true1, false0, false0, false0, false0}, // SE 3 (1,3)
1102 { false0, true1, true1, true1, false0, false0, false0}, // SE 4 (1,3,5)
1103 { false0, true1, true1, true1, false0, false0, false0}, // SE 5 (1,3,5)
1104 { false0, true1, true1, true1, false0, true1, true1 }, // SE 6 (1,3,5,10,11)
1105 { true1, false0, false0, false0, false0, false0, false0}, // SE 7 (0)
1106 { false0, false0, false0, true1, false0, false0, false0}, // SE 8 (5)
1107 { true1, true1, true1, true1, true1, true1, true1 }, // SE 9 (all)
1108 { false0, true1, true1, true1, false0, false0, false0}, // SE 10 (1,3,5)
1109 { false0, true1, true1, false0, false0, false0, false0}, // SE 11 (1,3)
1110 { false0, true1, true1, true1, false0, true1, true1 }, // SE 12 (1,3,5,10,11)
1111 { false0, true1, true1, true1, false0, false0, false0}, // SE 13 (1,3,5)
1112 { false0, false0, false0, true1, false0, false0, false0}, // SE 14 (5)
1113 { false0, false0, false0, true1, true1, false0, false0}, // SE 15 (5,6)
1114 { false0, false0, false0, true1, false0, false0, false0}, // SE 16 (5)
1115 { false0, false0, false0, true1, false0, false0, false0}, // SE 17 (5)
1116 { false0, true1, true1, true1, false0, false0, false0}, // SE 18 (1,3,5)
1117 { false0, true1, true1, false0, false0, false0, false0}, // SE 19 (1,3)
1118 { true1, true1, true1, true1, true1, true1, true1 }, // SE 20 (0,1,3,5,10,11)
1119 { false0, false0, false0, true1, true1, false0, false0}, // SE 21 (5,6)
1120 { true1, true1, true1, true1, true1, true1, true1 }, // SE 22 (all)
1121 { false0, true1, true1, true1, false0, false0, false0}, // SE 23 (1,3,5)
1122 { false0, false0, false0, true1, false0, false0, false0}, // SE 24 (5)
1123 { false0, false0, false0, true1, false0, false0, false0}, // SE 25 (5)
1124 { false0, false0, false0, true1, false0, false0, false0}, // SE 26 (5)
1125 { false0, false0, false0, true1, false0, false0, false0}, // SE 27 (5)
1126 { false0, false0, false0, true1, false0, false0, false0}, // SE 28 (5)
1127 { false0, true1, true1, true1, false0, false0, false0}, // SE 29 (1,3,5)
1128 { false0, false0, false0, true1, false0, false0, false0}, // SE 30 (5)
1129 { false0, true1, true1, true1, false0, false0, false0}, // SE 31 (1,3,5)
1130 { false0, false0, false0, true1, false0, false0, false0}, // SE 32 (5)
1131};
1132
1133static bool_Bool se_allowed_in_st(unsigned se, unsigned st)
1134{
1135 if (se==0 || se>HIGHEST_EXTTYPE32) {
1136 /* Don't know about new SE, so don't complain.. */
1137 return true1;
1138 }
1139
1140 switch (st) {
1141 case 0:
1142 return ext_cts[se-1].ST0;
1143 case 1:
1144 return ext_cts[se-1].ST1;
1145 case 3:
1146 return ext_cts[se-1].ST3;
1147 case 5:
1148 return ext_cts[se-1].ST5;
1149 case 6:
1150 return ext_cts[se-1].ST6;
1151 case 10:
1152 return ext_cts[se-1].ST10;
1153 case 11:
1154 return ext_cts[se-1].ST11;
1155 default:
1156 /* New/unknown section type that includes 'ef'.. assume ok */
1157 return true1;
1158 }
1159}
1160
1161/************************************************************************************/
1162
1163/* Table 7.7.1.2-2 */
1164static const value_string bfw_comp_headers_iq_width[] = {
1165 {0, "I and Q are 16 bits wide"},
1166 {1, "I and Q are 1 bit wide"},
1167 {2, "I and Q are 2 bits wide"},
1168 {3, "I and Q are 3 bits wide"},
1169 {4, "I and Q are 4 bits wide"},
1170 {5, "I and Q are 5 bits wide"},
1171 {6, "I and Q are 6 bits wide"},
1172 {7, "I and Q are 7 bits wide"},
1173 {8, "I and Q are 8 bits wide"},
1174 {9, "I and Q are 9 bits wide"},
1175 {10, "I and Q are 10 bits wide"},
1176 {11, "I and Q are 11 bits wide"},
1177 {12, "I and Q are 12 bits wide"},
1178 {13, "I and Q are 13 bits wide"},
1179 {14, "I and Q are 14 bits wide"},
1180 {15, "I and Q are 15 bits wide"},
1181 {0, NULL((void*)0)}
1182};
1183
1184/* Table 7.7.1.2-3 */
1185static const value_string bfw_comp_headers_comp_meth[] = {
1186 {COMP_NONE0, "no compression"},
1187 {COMP_BLOCK_FP1, "block floating point"},
1188 {COMP_BLOCK_SCALE2, "block scaling"},
1189 {COMP_U_LAW3, "u-law"},
1190 {4, "beamspace compression type I"},
1191 {5, "beamspace compression type II"},
1192 {0, NULL((void*)0)}
1193};
1194
1195/* 7.7.6.2 rbgSize (resource block group size) */
1196static const value_string rbg_size_vals[] = {
1197 {0, "reserved"},
1198 {1, "1"},
1199 {2, "2"},
1200 {3, "3"},
1201 {4, "4"},
1202 {5, "6"},
1203 {6, "8"},
1204 {7, "16"},
1205 {0, NULL((void*)0)}
1206};
1207
1208/* 7.7.6.5 */
1209static const value_string priority_vals[] = {
1210 {0, "0"},
1211 {1, "+1"},
1212 {2, "-2 (reserved, should not be used)"},
1213 {3, "-1"},
1214 {0, NULL((void*)0)}
1215};
1216
1217/* 7.7.10.2 beamGroupType */
1218static const value_string beam_group_type_vals[] = {
1219 {0x0, "common beam"},
1220 {0x1, "beam matrix indication"},
1221 {0x2, "beam vector listing"},
1222 {0x3, "beamId/ueId listing with associated port-list index"},
1223 {0, NULL((void*)0)}
1224};
1225
1226/* 7.7.9.2 technology (interface name) */
1227static const value_string interface_name_vals[] = {
1228 {0x0, "LTE"},
1229 {0x1, "NR"},
1230 {0, NULL((void*)0)}
1231};
1232
1233/* 7.7.18.4 toT (type of transmission) */
1234static const value_string type_of_transmission_vals[] = {
1235 {0x0, "normal transmission mode, data can be distributed in any way the O-RU is implemented to transmit data"},
1236 {0x1, "uniformly distributed over the transmission window"},
1237 {0x2, "Reserved"},
1238 {0x3, "Reserved"},
1239 {0, NULL((void*)0)}
1240};
1241
1242/* 7.7.2.2 (width of bfa parameters) */
1243static const value_string bfa_bw_vals[] = {
1244 {0, "no bits, the field is not applicable (e.g., O-RU does not support it) or the default value shall be used"},
1245 {1, "2-bit bitwidth"},
1246 {2, "3-bit bitwidth"},
1247 {3, "4-bit bitwidth"},
1248 {4, "5-bit bitwidth"},
1249 {5, "6-bit bitwidth"},
1250 {6, "7-bit bitwidth"},
1251 {7, "8-bit bitwidth"},
1252 {0, NULL((void*)0)}
1253};
1254
1255/* 7.7.2.7 & 7.7.2.8 */
1256static const value_string sidelobe_suppression_vals[] = {
1257 {0, "10 dB"},
1258 {1, "15 dB"},
1259 {2, "20 dB"},
1260 {3, "25 dB"},
1261 {4, "30 dB"},
1262 {5, "35 dB"},
1263 {6, "40 dB"},
1264 {7, ">= 45 dB"},
1265 {0, NULL((void*)0)}
1266};
1267
1268static const value_string lbtTrafficClass_vals[] = {
1269 {1, "Priority 1"},
1270 {2, "Priority 2"},
1271 {3, "Priority 3"},
1272 {4, "Priority 4"},
1273 {0, NULL((void*)0)}
1274};
1275
1276/* 7.5.3.22 */
1277static const value_string lbtPdschRes_vals[] = {
1278 {0, "not sensing – indicates that the O-RU is transmitting data"},
1279 {1, "currently sensing – indicates the O-RU has not yet acquired the channel"},
1280 {2, "success – indicates that the channel was successfully acquired"},
1281 {3, "Failure – indicates expiration of the LBT timer. The LBT process should be reset"},
1282 {0, NULL((void*)0)}
1283};
1284
1285/* Table 7.5.2.15-3 */
1286static const value_string ci_comp_opt_vals[] = {
1287 {0, "compression per UE, one ciCompParam exists before the I/Q value of each UE"},
1288 {1, "compression per PRB, one ciCompParam exists before the I/Q value of each PRB"},
1289 {0, NULL((void*)0)}
1290};
1291
1292/* 7.5.2.17 */
1293static const range_string cmd_scope_vals[] = {
1294 {0, 0, "ARRAY-COMMAND"},
1295 {1, 1, "CARRIER-COMMAND"},
1296 {2, 2, "O-RU-COMMAND"},
1297 {3, 15, "reserved"},
1298 {0, 0, NULL((void*)0)}
1299};
1300
1301/* N.B., table in 7.5.3.38 is truncated.. */
1302static const range_string st4_cmd_type_vals[] = {
1303 {0, 0, "reserved for future command types"},
1304 {1, 1, "TIME_DOMAIN_BEAM_CONFIG"},
1305 {2, 2, "TDD_CONFIG_PATTERN"},
1306 {3, 3, "TRX_CONTROL"},
1307 {4, 4, "ASM"},
1308 {5, 5, "TRX_CONTROL_BIDIR"},
1309 {6, 255, "reserved for future command types"},
1310 {0, 0, NULL((void*)0)}
1311};
1312
1313/* Table 7.5.3.51-1 */
1314static const value_string log2maskbits_vals[] = {
1315 {0, "reserved"},
1316 {1, "min antMask size is 16 bits.."},
1317 {2, "min antMask size is 16 bits.."},
1318 {3, "min antMask size is 16 bits.."},
1319 {4, "16 bits"},
1320 {5, "32 bits"},
1321 {6, "64 bits"},
1322 {7, "128 bits"},
1323 {8, "256 bits"},
1324 {9, "512 bits"},
1325 {10, "1024 bits"},
1326 {11, "2048 bits"},
1327 {12, "4096 bits"},
1328 {13, "8192 bits"},
1329 {14, "16384 bits"},
1330 {15, "reserved"},
1331 {0, NULL((void*)0)}
1332};
1333
1334/* Table 16.1-1 Sleep modes */
1335static const value_string sleep_mode_trx_vals[] = {
1336 { 0, "TRXC-mode0-wake-up-duration (symbol)"},
1337 { 1, "TRXC-mode1-wake-up-duration (L)"},
1338 { 2, "TRXC-mode2-wake-up-duration (M)"},
1339 { 3, "TRXC-mode3-wake-up-duration (N)"},
1340 { 0, NULL((void*)0)}
1341};
1342
1343static const value_string sleep_mode_asm_vals[] = {
1344 { 0, "ASM-mode0-wake-up-duration (symbol)"},
1345 { 1, "ASM-mode1-wake-up-duration (L)"},
1346 { 2, "ASM-mode2-wake-up-duration (M)"},
1347 { 3, "ASM-mode3-wake-up-duration (N)"},
1348 { 0, NULL((void*)0)}
1349};
1350
1351/* 7.7.21.3.1 */
1352static const value_string prg_size_st5_vals[] = {
1353 { 0, "reserved"},
1354 { 1, "Precoding resource block group size as WIDEBAND"},
1355 { 2, "Precoding resource block group size 2"},
1356 { 3, "Precoding resource block group size 4"},
1357 { 0, NULL((void*)0)}
1358};
1359
1360/* 7.7.21.3.2 */
1361static const value_string prg_size_st6_vals[] = {
1362 { 0, "if ciPrbGroupSize is 2 or 4, then ciPrbGroupSize, else WIDEBAND"},
1363 { 1, "Precoding resource block group size as WIDEBAND"},
1364 { 2, "Precoding resource block group size 2"},
1365 { 3, "Precoding resource block group size 4"},
1366 { 0, NULL((void*)0)}
1367};
1368
1369/* 7.7.24.4 */
1370static const value_string alpn_per_sym_vals[] = {
1371 { 0, "report one allocated IPN value per all allocated symbols with DMRS"},
1372 { 1, "report one allocated IPN value per group of consecutive DMRS symbols"},
1373 { 0, NULL((void*)0)}
1374};
1375
1376/* 7.7.24.5 */
1377static const value_string ant_dmrs_snr_vals[] = {
1378 { 0, "O-RU shall not report the MEAS_ANT_DMRS_SNR"},
1379 { 1, "O-RU shall report the MEAS_ANT_DMRS_SNR"},
1380 { 0, NULL((void*)0)}
1381};
1382
1383/* 7.7.24.14 */
1384static const value_string dtype_vals[] = {
1385 { 0, "assume DMRS configuration type 1"},
1386 { 1, "assume DMRS configuration type 2"},
1387 { 0, NULL((void*)0)}
1388};
1389
1390/* 7.7.24.17 */
1391static const value_string papr_type_vals[] = {
1392 { 0, "sequence generator type 1 for short sequence lengths"},
1393 { 1, "sequence generator type 1 for long sequence lengths"},
1394 { 2, "sequence generator type 2 for short sequence lengths"},
1395 { 3, "sequence generator type 2 for long sequence lengths"},
1396 { 0, NULL((void*)0)}
1397};
1398
1399/* 7.7.24.18 */
1400static const value_string hopping_mode_vals[] = {
1401 { 0, "neither group, nor sequence hopping is enabled"},
1402 { 1, "group hopping is enabled and sequence hopping is disabled"},
1403 { 2, "sequence hopping is enabled and group hopping is disabled"},
1404 { 3, "reserved"},
1405 { 0, NULL((void*)0)}
1406};
1407
1408/* Table 7.7.31.2-1 */
1409static const value_string mcs_table_vals[] = {
1410 { 0, "MCS index table 1 for PDSCH and PUSCH without transform precoding" },
1411 { 1, "MCS index table 2 for PDSCH and PUSCH without transform precoding" },
1412 { 2, "MCS index table 3 for PDSCH and PUSCH without transform precoding" },
1413 { 3, "MCS index table 4 for PDSCH" },
1414 { 4, "MCS index table for PUSCH with transform precoding and 64QAM" },
1415 { 5, "MCS index table 2 for PUSCH with transform precoding and 64QAM" },
1416 { 0, NULL((void*)0)}
1417};
1418
1419/* 7.7.32.9 */
1420static const value_string full_pwr_mode_vals[] = {
1421 { 0, "not configured"},
1422 { 1, "full power mode 0"},
1423 { 2, "full power mode 1"},
1424 { 3, "full power mode 2"},
1425 { 0, NULL((void*)0)}
1426};
1427
1428
1429static const true_false_string tfs_sfStatus =
1430{
1431 "subframe was transmitted",
1432 "subframe was dropped"
1433};
1434
1435static const true_false_string tfs_lbtBufErr =
1436{
1437 "buffer overflow – data received at O-RU is larger than the available buffer size",
1438 "reserved"
1439};
1440
1441static const true_false_string tfs_partial_full_sf = {
1442 "partial SF",
1443 "full SF"
1444};
1445
1446static const true_false_string disable_tdbfns_tfs = {
1447 "beam numbers excluded",
1448 "beam numbers included"
1449};
1450
1451static const true_false_string continuity_indication_tfs = {
1452 "continuity between current and next bundle",
1453 "discontinuity between current and next bundle"
1454};
1455
1456static const true_false_string prb_mode_tfs = {
1457 "PRB-BLOCK mode",
1458 "PRB-MASK mode"
1459};
1460
1461static const true_false_string symbol_direction_tfs = {
1462 "DL symbol",
1463 "UL symbol"
1464};
1465
1466static const true_false_string symbol_guard_tfs = {
1467 "guard symbol",
1468 "non-guard symbol"
1469};
1470
1471static const true_false_string beam_numbers_included_tfs = {
1472 "time-domain beam numbers excluded in this command",
1473 "time-domain beam numbers included in this command"
1474};
1475
1476static const true_false_string measurement_flag_tfs = {
1477 "at least one additional measurement report or command after the current one",
1478 "no additional measurement report or command"
1479};
1480
1481static const true_false_string repetition_se6_tfs = {
1482 "repeated highest priority data section in the C-Plane message",
1483 "no repetition"
1484};
1485
1486static const true_false_string repetition_se19_tfs = {
1487 "per port information not present in the extension",
1488 "per port info present in the extension"
1489};
1490
1491static const true_false_string tfs_report_no_report_pos_meas =
1492{
1493 "Report MEAS_UE_POS for UE",
1494 "Do not report UE_POS for UE"
1495};
1496
1497
1498/* Forward declaration */
1499static int dissect_udcompparam(tvbuff_t *tvb, packet_info *pinfo _U___attribute__((unused)), proto_tree *tree, unsigned offset,
1500 unsigned comp_meth,
1501 uint32_t *exponent, uint16_t *sReSMask, bool_Bool for_sinr);
1502
1503
1504static const true_false_string ready_tfs = {
1505 "message is a \"ready\" message",
1506 "message is a ACK message"
1507};
1508
1509static const true_false_string multi_sd_scope_tfs = {
1510 "Puncturing pattern applies to current and following sections",
1511 "Puncturing pattern applies to current section"
1512};
1513
1514static const true_false_string tfs_ueid_reset = {
1515 "cannot assume same UE as in preceding slot",
1516 "can assume same UE as in preceding slot"
1517};
1518
1519
1520/* Config for (and later, worked-out allocations) bundles for ext11 (dynamic BFW) */
1521typedef struct {
1522 /* Ext 6 config */
1523 bool_Bool ext6_set;
1524 uint8_t ext6_rbg_size; /* number of PRBs allocated by bitmask */
1525
1526 uint8_t ext6_num_bits_set;
1527 uint8_t ext6_bits_set[28]; /* Which bit position this entry has */
1528 /* TODO: store an f value for each bit position? */
1529
1530 /* Ext 12 config */
1531 bool_Bool ext12_set;
1532 unsigned ext12_num_pairs;
1533#define MAX_BFW_EXT12_PAIRS128 128
1534 struct {
1535 uint8_t off_start_prb;
1536 uint8_t num_prb;
1537 } ext12_pairs[MAX_BFW_EXT12_PAIRS128];
1538
1539 /* Ext 13 config */
1540 bool_Bool ext13_set;
1541 unsigned ext13_num_start_prbs;
1542#define MAX_BFW_EXT13_ALLOCATIONS128 128
1543 unsigned ext13_start_prbs[MAX_BFW_EXT13_ALLOCATIONS128];
1544 /* TODO: store nextSymbolId here too? */
1545
1546 /* Ext 21 config */
1547 bool_Bool ext21_set;
1548 uint8_t ext21_ci_prb_group_size;
1549
1550 /* Results/settings (after calling ext11_work_out_bundles()) */
1551 uint32_t num_bundles;
1552#define MAX_BFW_BUNDLES512 512
1553 struct {
1554 uint32_t start; /* first prb of bundle */
1555 uint32_t end; /* last prb of bundle*/
1556 bool_Bool is_orphan; /* true if not complete (i.e., end-start < numBundPrb) */
1557 } bundles[MAX_BFW_BUNDLES512];
1558} ext11_settings_t;
1559
1560
1561/* Work out bundle allocation for ext 11. Take into account ext6/ext21, ext12 or ext13 in this section before ext 11. */
1562/* Won't be called with numBundPrb=0 */
1563static void ext11_work_out_bundles(unsigned startPrbc,
1564 unsigned numPrbc,
1565 unsigned numBundPrb, /* number of PRBs per (full) bundle */
1566 ext11_settings_t *settings)
1567{
1568 /* Allocation configured by ext 6 */
1569 if (settings->ext6_set) {
1570 unsigned bundles_per_entry = (settings->ext6_rbg_size / numBundPrb);
1571
1572 /* Need to cope with these not dividing exactly, or even having more PRbs in a bundle that
1573 rbg size. i.e. each bundle gets the correct number of PRBs until
1574 all rbg entries are consumed... */
1575
1576 /* TODO: need to check 7.9.4.2. Different cases depending upon value of RAD */
1577
1578 if (bundles_per_entry == 0) {
1579 bundles_per_entry = 1;
1580 }
1581
1582 /* Ext6 behaviour may also be affected by ext 21 */
1583 if (settings->ext21_set) {
1584 /* N.B., have already checked that numPrbc is not 0 */
1585
1586 /* ciPrbGroupSize overrides number of contiguous PRBs in group */
1587 bundles_per_entry = (settings->ext6_rbg_size / settings->ext21_ci_prb_group_size);
1588
1589 /* numPrbc is the number of PRB groups per antenna - handled in call to dissect_bfw_bundle() */
1590 }
1591
1592 unsigned bundles_set = 0;
1593 bool_Bool reached_orphan = false0;
1594 /* For each bit set in ext6 rbg mask.. */
1595 for (unsigned n=0;
1596 !reached_orphan && n < (settings->ext6_num_bits_set * settings->ext6_rbg_size) / numBundPrb;
1597 n++) {
1598
1599 /* Watch out for array bound */
1600 if (n >= 28) {
1601 break;
1602 }
1603
1604 /* For each bundle... */
1605
1606 /* TODO: Work out where first PRB is */
1607 /* May not be the start of an rbg block... */
1608 uint32_t prb_start = (settings->ext6_bits_set[n] * settings->ext6_rbg_size);
1609
1610 /* For each bundle within identified rbgSize block */
1611 for (unsigned m=0; !reached_orphan && m < bundles_per_entry; m++) {
1612
1613 settings->bundles[bundles_set].start = startPrbc+prb_start+(m*numBundPrb);
1614
1615 /* Start already beyond end, so doesn't count. */
1616 if (settings->bundles[bundles_set].start > (startPrbc+numPrbc-1)) {
1617 settings->num_bundles = bundles_set;
1618 return;
1619 }
1620
1621 /* Bundle consists of numBundPrb bundles */
1622 /* TODO: may involve PRBs from >1 rbg blocks.. */
1623 settings->bundles[bundles_set].end = startPrbc+prb_start+((m+1)*numBundPrb)-1;
1624 if (settings->bundles[bundles_set].end > (startPrbc+numPrbc-1)) {
1625 /* Extends beyond end, so counts but is an orphan bundle */
1626 settings->bundles[bundles_set].end = startPrbc+numPrbc-1;
1627 settings->bundles[bundles_set].is_orphan = true1;
1628 reached_orphan = true1;
1629 }
1630
1631 /* Get out if have reached array bound */
1632 if (++bundles_set == MAX_BFW_BUNDLES512) {
1633 return;
1634 }
1635 }
1636 }
1637 settings->num_bundles = bundles_set;
1638 }
1639
1640 /* Allocation configured by ext 12 */
1641 else if (settings->ext12_set) {
1642 /* First, allocate normally from startPrbc, numPrbc */
1643 settings->num_bundles = (numPrbc+numBundPrb-1) / numBundPrb;
1644
1645 /* Don't overflow settings->bundles[] ! */
1646 settings->num_bundles = MIN(MAX_BFW_BUNDLES, settings->num_bundles)(((512) < (settings->num_bundles)) ? (512) : (settings->
num_bundles))
;
1647
1648 for (uint32_t n=0; n < settings->num_bundles; n++) {
1649 settings->bundles[n].start = startPrbc + n*numBundPrb;
1650 settings->bundles[n].end = settings->bundles[n].start + numBundPrb-1;
1651 /* Does it go beyond the end? */
1652 if (settings->bundles[n].end > startPrbc+numPrbc) {
1653 settings->bundles[n].end = startPrbc+numPrbc;
1654 settings->bundles[n].is_orphan = true1;
1655 }
1656 }
1657 if (settings->num_bundles == MAX_BFW_BUNDLES512) {
1658 return;
1659 }
1660
1661 unsigned prb_offset = startPrbc + numPrbc;
1662
1663 /* Loop over pairs, adding bundles for each */
1664 for (unsigned p=0; p < settings->ext12_num_pairs; p++) {
1665 prb_offset += settings->ext12_pairs[p].off_start_prb;
1666 unsigned pair_bundles = (settings->ext12_pairs[p].num_prb+numBundPrb-1) / numBundPrb;
1667
1668 for (uint32_t n=0; n < pair_bundles; n++) {
1669 unsigned idx = settings->num_bundles;
1670
1671 settings->bundles[idx].start = prb_offset + n*numBundPrb;
1672 settings->bundles[idx].end = settings->bundles[idx].start + numBundPrb-1;
1673 /* Does it go beyond the end? */
1674 if (settings->bundles[idx].end > prb_offset + settings->ext12_pairs[p].num_prb) {
1675 settings->bundles[idx].end = prb_offset + settings->ext12_pairs[p].num_prb;
1676 settings->bundles[idx].is_orphan = true1;
1677 }
1678 /* Range check / return */
1679 settings->num_bundles++;
1680 if (settings->num_bundles == MAX_BFW_BUNDLES512) {
1681 return;
1682 }
1683 }
1684
1685 prb_offset += settings->ext12_pairs[p].num_prb;
1686 }
1687 }
1688
1689 /* Allocation configured by ext 13 */
1690 else if (settings->ext13_set) {
1691 unsigned alloc_size = (numPrbc+numBundPrb-1) / numBundPrb;
1692 settings->num_bundles = alloc_size * settings->ext13_num_start_prbs;
1693
1694 /* Don't overflow settings->bundles[] ! */
1695 settings->num_bundles = MIN(MAX_BFW_BUNDLES, settings->num_bundles)(((512) < (settings->num_bundles)) ? (512) : (settings->
num_bundles))
;
1696
1697 for (unsigned alloc=0; alloc < settings->ext13_num_start_prbs; alloc++) {
1698 unsigned alloc_start = alloc * alloc_size;
1699 for (uint32_t n=0; n < alloc_size; n++) {
1700 if ((alloc_start+n) >= MAX_BFW_BUNDLES512) {
1701 /* ERROR */
1702 return;
1703 }
1704 settings->bundles[alloc_start+n].start = settings->ext13_start_prbs[alloc] + startPrbc + n*numBundPrb;
1705 settings->bundles[alloc_start+n].end = settings->bundles[alloc_start+n].start + numBundPrb-1;
1706 if (settings->bundles[alloc_start+n].end > settings->ext13_start_prbs[alloc] + numPrbc) {
1707 settings->bundles[alloc_start+n].end = settings->ext13_start_prbs[alloc] + numPrbc;
1708 settings->bundles[alloc_start+n].is_orphan = true1;
1709 }
1710 }
1711 }
1712 }
1713
1714 /* Case where bundles are not controlled by other extensions - just divide up range into bundles we have */
1715 else {
1716 settings->num_bundles = (numPrbc+numBundPrb-1) / numBundPrb; /* rounded up */
1717
1718 /* Don't overflow settings->bundles[] */
1719 settings->num_bundles = MIN(MAX_BFW_BUNDLES, settings->num_bundles)(((512) < (settings->num_bundles)) ? (512) : (settings->
num_bundles))
;
1720
1721 /* For each bundle.. */
1722 for (uint32_t n=0; n < settings->num_bundles; n++) {
1723 /* Allocate start and end */
1724 settings->bundles[n].start = startPrbc + n*numBundPrb;
1725 settings->bundles[n].end = settings->bundles[n].start + numBundPrb - 1;
1726 /* If would go beyond end of PRBs, limit and identify as orphan */
1727 if (settings->bundles[n].end > startPrbc+numPrbc) {
1728 settings->bundles[n].end = startPrbc+numPrbc;
1729 settings->bundles[n].is_orphan = true1;
1730 }
1731 }
1732 }
1733}
1734
1735
1736/* Modulation Compression configuration */
1737typedef struct {
1738 /* Application of each entry is filtered by RE.
1739 * TODO: should also be filtered by PRB + symbol... */
1740 uint16_t mod_compr_re_mask;
1741
1742 /* Settings to apply */
1743 bool_Bool mod_compr_csf;
1744 float mod_compr_scaler;
1745} mod_compr_config_t;
1746
1747/* Multiple configs with a section */
1748typedef struct {
1749 uint16_t section_id;
1750 uint32_t num_configs;
1751
1752 #define MAX_MOD_COMPR_CONFIGS12 12
1753 mod_compr_config_t configs[MAX_MOD_COMPR_CONFIGS12];
1754} section_mod_compr_config_t;
1755
1756/* Flow has separate configs for each section */
1757typedef struct {
1758 uint16_t num_sections;
1759
1760 /* Separate config for each section */
1761 section_mod_compr_config_t sections[MAX_SECTION_IDs32];
1762} mod_compr_params_t;
1763
1764
1765typedef struct {
1766 uint32_t frame_number;
1767 nstime_t frame_time;
1768
1769 /* Timing to match */
1770 uint8_t frame;
1771 uint8_t subframe;
1772 uint8_t slot;
1773 uint8_t startSymbol;
1774
1775 bool_Bool in_use;
1776 uint16_t startPrb;
1777 uint16_t numPrb;
1778 uint16_t numSymbols;
1779 uint16_t beamIds[273];
1780} section_details_t;
1781
1782typedef struct {
1783 uint16_t sectionId;
1784 /* For the same sectionId, can have 2 currently active entries.. */
1785 section_details_t details[2];
1786} expected_section_data_t;
1787
1788
1789/*******************************************************/
1790/* Overall state of a flow (eAxC/plane) */
1791typedef struct {
1792 /* State for sequence analysis [each direction] */
1793 bool_Bool last_frame_seen[2];
1794 uint32_t last_frame[2];
1795 uint8_t next_expected_sequence_number[2];
1796
1797 /* DL expected frames. sectionId -> expected_section_data_t* */
1798 wmem_tree_t *expected_dl_sections;
1799
1800 /* Table recording ackNack requests (ackNackId -> ack_nack_request_t*)
1801 Note that this assumes that the same ackNackId will not be reused within a state,
1802 which may well not be valid */
1803 wmem_tree_t *ack_nack_requests;
1804
1805 /* Store udCompHdr seen in C-Plane for UL - can be looked up and used by U-PLane.
1806 Note that this appears in the common section header parts of ST1, ST3, ST5,
1807 so can still be over-written per sectionId in the U-Plane */
1808 unsigned ul_ud_comp_hdr_frame;
1809 bool_Bool ul_ud_comp_hdr_set;
1810 unsigned ul_ud_comp_hdr_bit_width;
1811 int ul_ud_comp_hdr_compression;
1812
1813 bool_Bool udcomphdrDownlink_heuristic_result_set;
1814 bool_Bool udcomphdrDownlink_heuristic_result;
1815 bool_Bool udcomphdrUplink_heuristic_result_set;
1816 bool_Bool udcomphdrUplink_heuristic_result;
1817
1818 /* Modulation compression params */
1819 mod_compr_params_t mod_comp_params;
1820} flow_state_t;
1821
1822static section_mod_compr_config_t* get_mod_compr_section_to_write(flow_state_t *flow,
1823 unsigned sectionId)
1824{
1825 if (flow == NULL((void*)0)) {
1826 return NULL((void*)0);
1827 }
1828
1829 /* Look for this section among existing entries */
1830 for (unsigned s=0; s < flow->mod_comp_params.num_sections; s++) {
1831 if (flow->mod_comp_params.sections[s].section_id == sectionId) {
1832 return &flow->mod_comp_params.sections[s];
1833 }
1834 }
1835
1836 /* Not found, so try to add a new one */
1837 if (flow->mod_comp_params.num_sections >= MAX_SECTION_IDs32) {
1838 /* Can't allocate one! */
1839 return NULL((void*)0);
1840 }
1841 else {
1842 flow->mod_comp_params.sections[flow->mod_comp_params.num_sections].section_id = sectionId;
1843 return &flow->mod_comp_params.sections[flow->mod_comp_params.num_sections++];
1844 }
1845}
1846
1847static section_mod_compr_config_t* get_mod_compr_section_to_read(flow_state_t *flow,
1848 unsigned sectionId)
1849{
1850 if (flow == NULL((void*)0)) {
1851 return NULL((void*)0);
1852 }
1853
1854 /* Look for this section among existing entries */
1855 for (unsigned s=0; s < flow->mod_comp_params.num_sections; s++) {
1856 if (flow->mod_comp_params.sections[s].section_id == sectionId) {
1857 return &flow->mod_comp_params.sections[s];
1858 }
1859 }
1860
1861 /* Not found */
1862 return NULL((void*)0);
1863}
1864
1865
1866
1867typedef struct {
1868 uint32_t request_frame_number;
1869 nstime_t request_frame_time;
1870 enum {
1871 SE22,
1872 ST4Cmd1,
1873 ST4Cmd2,
1874 ST4Cmd3,
1875 ST4Cmd4
1876 } requestType;
1877
1878 uint32_t response_frame_number;
1879 nstime_t response_frame_time;
1880} ack_nack_request_t;
1881
1882static const value_string acknack_type_vals[] = {
1883 { SE22, "SE 22" },
1884 { ST4Cmd1, "ST4 (TIME_DOMAIN_BEAM_CONFIG)" },
1885 { ST4Cmd2, "ST4 (TDD_CONFIG_PATTERN)" },
1886 { ST4Cmd3, "ST4 (TRX_CONTROL)" },
1887 { ST4Cmd4, "ST4 (ASM)" },
1888 { 0, NULL((void*)0)}
1889};
1890
1891#define ORAN_C_PLANE0 0
1892#define ORAN_U_PLANE1 1
1893
1894/* Using parts of src/dst MAC address, so don't confuse UL messages with DL messages configuring UL.. */
1895static uint32_t make_flow_key(packet_info *pinfo, uint16_t eaxc_id, uint8_t plane, bool_Bool opposite_dir)
1896{
1897 uint16_t eth_bits = 0;
1898 if (pinfo->dl_src.len == 6 && pinfo->dl_dst.len == 6) {
1899 /* Only using (most of) 2 bytes from addresses for now, but reluctant to make key longer.. */
1900 const uint8_t *src_eth = (uint8_t*)pinfo->dl_src.data;
1901 const uint8_t *dst_eth = (uint8_t*)pinfo->dl_dst.data;
1902 if (!opposite_dir) {
1903 eth_bits = (src_eth[0]<<8) | dst_eth[5];
1904 }
1905 else {
1906 eth_bits = (dst_eth[0]<<8) | src_eth[5];
1907 }
1908 }
1909 return eaxc_id | (plane << 16) | (eth_bits << 17);
1910}
1911
1912
1913/* Table maintained on first pass from flow_key(uint32_t) -> flow_state_t* */
1914static wmem_tree_t *flow_states_table;
1915
1916/* Table consulted on subsequent passes: frame_num -> flow_result_t* */
1917static wmem_tree_t *flow_results_table;
1918
1919typedef struct {
1920 /* Sequence analysis */
1921 bool_Bool unexpected_seq_number;
1922 uint8_t expected_sequence_number;
1923 uint32_t previous_frame;
1924
1925 /* sectionId -> expected_section_data_t* */
1926 wmem_tree_t *expected_dl_sections;
1927
1928} flow_result_t;
1929
1930
1931/* Uplink timing */
1932/* For a given symbol, track first to last UL frame to find out first-last time */
1933/* frameId (8) + subframeId (4) + slotId (6) + symbolId (6) = 24 bits */
1934/* N.B. if a capture lasts > 2.5s, may see same timing come around again... */
1935static uint32_t get_timing_key(uint8_t frameId, uint8_t subframeId, uint8_t slotId, uint8_t symbolId)
1936{
1937 return symbolId + (slotId<<8) + (subframeId<<14) + (frameId<<18);
1938}
1939
1940typedef struct {
1941 uint32_t first_frame;
1942 nstime_t first_frame_time;
1943 uint32_t frames_seen_in_symbol;
1944 uint32_t last_frame_in_symbol;
1945} ul_timing_for_slot;
1946
1947/* Set during first pass. timing_key -> ul_timing_for_slot* */
1948static wmem_tree_t *ul_symbol_timing;
1949
1950
1951/* Tracking lifetimes of DL beamIds */
1952typedef struct {
1953 uint32_t frame_defined;
1954 uint32_t symbol_when_defined;
1955} bfw_definition;
1956
1957/* Maintained during first pass: beamId (from ext11) -> bfw_definition */
1958static wmem_tree_t *dl_beam_ids_defined;
1959/* Lookup where/when beamIds were defined (frameid:beamid) -> bfw_definition */
1960static wmem_tree_t *dl_beam_ids_results;
1961
1962
1963static void show_link_to_acknack_response(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo,
1964 ack_nack_request_t *response);
1965
1966
1967
1968
1969static void write_pdu_label_and_info(proto_item *ti1, proto_item *ti2,
1970 packet_info *pinfo, const char *format, ...) G_GNUC_PRINTF(4, 5)__attribute__((__format__ (__printf__, 4, 5)));
1971
1972 /* Write the given formatted text to:
1973 - the info column (if pinfo != NULL)
1974 - 1 or 2 other labels (optional)
1975 */
1976static void write_pdu_label_and_info(proto_item *ti1, proto_item *ti2,
1977 packet_info *pinfo, const char *format, ...)
1978{
1979#define MAX_INFO_BUFFER256 256
1980 char info_buffer[MAX_INFO_BUFFER256];
1981 va_list ap;
1982
1983 if ((ti1 == NULL((void*)0)) && (ti2 == NULL((void*)0)) && (pinfo == NULL((void*)0))) {
1984 return;
1985 }
1986
1987 va_start(ap, format)__builtin_va_start(ap, format);
1988 vsnprintf(info_buffer, MAX_INFO_BUFFER256, format, ap);
1989 va_end(ap)__builtin_va_end(ap);
1990
1991 /* Add to indicated places */
1992 if (pinfo != NULL((void*)0)) {
1993 col_append_str(pinfo->cinfo, COL_INFO, info_buffer);
1994 }
1995 if (ti1 != NULL((void*)0)) {
1996 proto_item_append_text(ti1, "%s", info_buffer);
1997 }
1998 if (ti2 != NULL((void*)0)) {
1999 proto_item_append_text(ti2, "%s", info_buffer);
2000 }
2001}
2002
2003/* Add section labels (type + PRB range) for C-Plane, U-Plane */
2004static void
2005write_section_info(proto_item *section_heading, packet_info *pinfo, proto_item *protocol_item,
2006 uint32_t section_id, uint32_t start_prbx, uint32_t num_prbx, uint32_t rb)
2007{
2008 switch (num_prbx) {
2009 case 0:
2010 /* None -> all */
2011 write_pdu_label_and_info(section_heading, protocol_item, pinfo, ", Id: %4d (all PRBs)", section_id);
2012 break;
2013 case 1:
2014 /* Single PRB */
2015 write_pdu_label_and_info(section_heading, protocol_item, pinfo, ", Id: %4d (PRB: %7u)", section_id, start_prbx);
2016 break;
2017 default:
2018 /* Range */
2019 write_pdu_label_and_info(section_heading, protocol_item, pinfo, ", Id: %4d (PRB: %3u-%3u%s)", section_id, start_prbx,
2020 start_prbx + (num_prbx-1)*(1+rb), rb ? " (every-other)" : "");
2021 }
2022}
2023
2024static void
2025write_channel_section_info(proto_item *section_heading, packet_info *pinfo,
2026 uint32_t section_id, uint32_t ueId, uint32_t start_prbx, uint32_t num_prbx,
2027 uint32_t num_trx)
2028{
2029 switch (num_prbx) {
2030 case 0:
2031 /* TODO: ?? */
2032 break;
2033 case 1:
2034 /* Single PRB */
2035 write_pdu_label_and_info(section_heading, NULL((void*)0), pinfo,
2036 ", Id: %4d (UEId=%5u PRB %7u, %2u antennas)",
2037 section_id, ueId, start_prbx, num_trx);
2038 break;
2039 default:
2040 /* Range */
2041 write_pdu_label_and_info(section_heading, NULL((void*)0), pinfo,
2042 ", Id: %4d (UEId=%5u PRBs %3u-%3u, %2u antennas)",
2043 section_id, ueId, start_prbx, start_prbx+num_prbx-1, num_trx);
2044 }
2045}
2046
2047/* Add a reserved field, and warn if value isn't 0 */
2048/* TODO: maybe add a pref not to output expert warning if becomes too annoying? */
2049static void add_reserved_field(proto_tree *tree, int hf, tvbuff_t *tvb, int offset, int len)
2050{
2051 uint32_t reserved;
2052 proto_item *res_ti = proto_tree_add_item_ret_uint(tree, hf, tvb, offset, len, ENC_NA0x00000000, &reserved);
2053 if (reserved != 0) {
2054 expert_add_info_format(NULL((void*)0), res_ti, &ei_oran_reserved_not_zero,
2055 "reserved field saw value of 0x%x", reserved);
2056 }
2057}
2058
2059/* 5.1.3.2.7 (real time control data / IQ data transfer message series identifier) */
2060static void
2061addPcOrRtcid(tvbuff_t *tvb, proto_tree *tree, unsigned *offset, int hf, uint16_t *eAxC, oran_tap_info *tap_info)
2062{
2063 /* Subtree */
2064 proto_item *oran_pcid_ti = proto_tree_add_item(tree, hf,
2065 tvb, *offset, 2, ENC_NA0x00000000);
2066 proto_tree *oran_pcid_tree = proto_item_add_subtree(oran_pcid_ti, ett_oran_ecpri_pcid);
2067
2068 uint64_t duPortId, bandSectorId, ccId, ruPortId = 0;
2069 int id_offset = *offset;
2070
2071 /* All parts of eAxC should be above 0, and should total 16 bits (breakdown controlled by preferences) */
2072 if (!((pref_du_port_id_bits > 0) && (pref_bandsector_id_bits > 0) && (pref_cc_id_bits > 0) && (pref_ru_port_id_bits > 0) &&
2073 ((pref_du_port_id_bits + pref_bandsector_id_bits + pref_cc_id_bits + pref_ru_port_id_bits) == 16))) {
2074 expert_add_info(NULL((void*)0), tree, &ei_oran_invalid_eaxc_bit_width);
2075 *eAxC = 0;
2076 *offset += 2;
2077 return;
2078 }
2079
2080 unsigned bit_offset = *offset * 8;
2081
2082 /* N.B. For sequence analysis / tapping, just interpret these 2 bytes as eAxC ID... */
2083 *eAxC = tvb_get_uint16(tvb, *offset, ENC_BIG_ENDIAN0x00000000);
2084
2085 /* DU Port ID */
2086 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);
2087 bit_offset += pref_du_port_id_bits;
2088 /* BandSector ID */
2089 proto_tree_add_bits_ret_val(oran_pcid_tree, hf_oran_bandsector_id, tvb, bit_offset, pref_bandsector_id_bits, &bandSectorId, ENC_BIG_ENDIAN0x00000000);
2090 bit_offset += pref_bandsector_id_bits;
2091 /* CC ID */
2092 proto_tree_add_bits_ret_val(oran_pcid_tree, hf_oran_cc_id, tvb, bit_offset, pref_cc_id_bits, &ccId, ENC_BIG_ENDIAN0x00000000);
2093 bit_offset += pref_cc_id_bits;
2094 /* RU Port ID */
2095 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);
2096 *offset += 2;
2097
2098 proto_item_append_text(oran_pcid_ti, " (DU_Port_ID: %d, BandSector_ID: %d, CC_ID: %d, RU_Port_ID: %d)",
2099 (int)duPortId, (int)bandSectorId, (int)ccId, (int)ruPortId);
2100 char id[16];
2101 snprintf(id, 16, "%x:%x:%x:%x", (int)duPortId, (int)bandSectorId, (int)ccId, (int)ruPortId);
2102 proto_item *pi = proto_tree_add_string(oran_pcid_tree, hf_oran_c_eAxC_ID, tvb, id_offset, 2, id);
2103 proto_item_set_generated(pi);
2104
2105 tap_info->eaxc = *eAxC;
2106 tap_info->eaxc_du_port_id = (uint16_t)duPortId;
2107 tap_info->eaxc_bandsector_id = (uint16_t)bandSectorId;
2108 tap_info->eaxc_cc_id = (uint16_t)ccId;
2109 tap_info->eaxc_ru_port_id = (uint16_t)ruPortId;
2110}
2111
2112/* Uniquely identify the U-plane stream that may need to be reassembled */
2113static uint32_t make_reassembly_id(uint32_t seqid, uint32_t direction, uint16_t eAxC,
2114 uint8_t frameid, uint8_t subframeid,
2115 uint8_t slotid, uint8_t symbolid)
2116{
2117 /* N.B., no room in 32-bits for all of this info, so cut down some of the fields
2118 and hope for no collisions */
2119 return (seqid << 24) | (direction << 23) | (slotid << 22) | (subframeid << 18) |
2120 (frameid << 9) | (symbolid << 6) | (eAxC & 0x3f);
2121}
2122
2123/* 5.1.3.2.8 ecpriSeqid (message identifier) */
2124/* Return out info that may be used for sequence number analysis and reassembly */
2125static int
2126addSeqid(tvbuff_t *tvb, proto_tree *oran_tree, int offset, int plane, uint32_t *seq_id, proto_item **seq_id_ti, packet_info *pinfo,
2127 uint32_t *subseqid, uint32_t *e)
2128{
2129 /* Subtree */
2130 proto_item *seqIdItem = proto_tree_add_item(oran_tree, hf_oran_ecpri_seqid, tvb, offset, 2, ENC_NA0x00000000);
2131 proto_tree *oran_seqid_tree = proto_item_add_subtree(seqIdItem, ett_oran_ecpri_seqid);
2132
2133 /* Sequence ID (8 bits) */
2134 *seq_id_ti = proto_tree_add_item_ret_uint(oran_seqid_tree, hf_oran_sequence_id, tvb, offset, 1, ENC_NA0x00000000, seq_id);
2135 offset += 1;
2136
2137 /* Show link back to previous sequence ID, if set */
2138 flow_result_t *result = wmem_tree_lookup32(flow_results_table, pinfo->num);
2139 if (result) {
2140 proto_item *prev_ti = proto_tree_add_uint(oran_seqid_tree, hf_oran_previous_frame, tvb, 0, 0, result->previous_frame);
2141 proto_item_set_generated(prev_ti);
2142 }
2143
2144 /* E bit */
2145 proto_tree_add_item_ret_uint(oran_seqid_tree, hf_oran_e_bit, tvb, offset, 1, ENC_NA0x00000000, e);
2146 /* Subsequence ID (7 bits) */
2147 proto_tree_add_item_ret_uint(oran_seqid_tree, hf_oran_subsequence_id, tvb, offset, 1, ENC_NA0x00000000, subseqid);
2148 offset += 1;
2149
2150 /* radio-transport fragmentation not allowed for C-Plane messages */
2151 if (plane == ORAN_C_PLANE0) {
2152 if (*e !=1 || *subseqid != 0) {
2153 expert_add_info(NULL((void*)0), seqIdItem, &ei_oran_radio_fragmentation_c_plane);
2154 }
2155 }
2156
2157 /* Summary */
2158 proto_item_append_text(seqIdItem, " (SeqId: %3d, E: %d, SubSeqId: %d)", *seq_id, *e, *subseqid);
2159 return offset;
2160}
2161
2162static int dissect_symbolmask(tvbuff_t *tvb, proto_tree *tree, int offset, uint32_t *symbol_mask, proto_item **ti)
2163{
2164 uint64_t temp_val;
2165
2166 static int * const symbol_mask_flags[] = {
2167 &hf_oran_symbol_mask_s13,
2168 &hf_oran_symbol_mask_s12,
2169 &hf_oran_symbol_mask_s11,
2170 &hf_oran_symbol_mask_s10,
2171 &hf_oran_symbol_mask_s9,
2172 &hf_oran_symbol_mask_s8,
2173 &hf_oran_symbol_mask_s7,
2174 &hf_oran_symbol_mask_s6,
2175 &hf_oran_symbol_mask_s5,
2176 &hf_oran_symbol_mask_s4,
2177 &hf_oran_symbol_mask_s3,
2178 &hf_oran_symbol_mask_s2,
2179 &hf_oran_symbol_mask_s1,
2180 &hf_oran_symbol_mask_s0,
2181 NULL((void*)0)
2182 };
2183
2184 proto_item *temp_ti = proto_tree_add_bitmask_ret_uint64(tree, tvb, offset,
2185 hf_oran_symbol_mask,
2186 ett_oran_symbol_mask, symbol_mask_flags,
2187 ENC_BIG_ENDIAN0x00000000, &temp_val);
2188 /* Set out parameters */
2189 if (symbol_mask) {
2190 *symbol_mask = (uint32_t)temp_val;
2191 }
2192 if (ti) {
2193 *ti = temp_ti;
2194 }
2195 return offset+2;
2196}
2197
2198/* 7.7.1.2 bfwCompHdr (beamforming weight compression header) */
2199static int dissect_bfwCompHdr(tvbuff_t *tvb, proto_tree *tree, int offset,
2200 uint32_t *iq_width, uint32_t *comp_meth, proto_item **comp_meth_ti)
2201{
2202 /* Subtree */
2203 proto_item *bfwcomphdr_ti = proto_tree_add_string_format(tree, hf_oran_bfwCompHdr,
2204 tvb, offset, 1, "",
2205 "bfwCompHdr");
2206 proto_tree *bfwcomphdr_tree = proto_item_add_subtree(bfwcomphdr_ti, ett_oran_bfwcomphdr);
2207
2208 /* Width and method */
2209 proto_tree_add_item_ret_uint(bfwcomphdr_tree, hf_oran_bfwCompHdr_iqWidth,
2210 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, iq_width);
2211 /* Special case: 0 -> 16 */
2212 *iq_width = (*iq_width==0) ? 16 : *iq_width;
2213 *comp_meth_ti = proto_tree_add_item_ret_uint(bfwcomphdr_tree, hf_oran_bfwCompHdr_compMeth,
2214 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, comp_meth);
2215 offset++;
2216
2217 /* Summary */
2218 proto_item_append_text(bfwcomphdr_ti, " (IqWidth=%u, compMeth=%s)",
2219 *iq_width,
2220 val_to_str_const(*comp_meth, bfw_comp_headers_comp_meth, "reserved"));
2221
2222 return offset;
2223}
2224
2225/* Return offset */
2226/* Returning number of entries set - would be good to also return an array of set TRX# so could show which array element
2227 each BFW is actually for.. */
2228static int dissect_active_beamspace_coefficient_mask(tvbuff_t *tvb, proto_tree *tree, int offset, unsigned *num_trx_entries, uint16_t **trx_entries)
2229{
2230 /* activeBeamspaceCoefficientMask - ceil(K/8) octets */
2231 /* K is the number of elements in uncompressed beamforming weight vector.
2232 * Calculated from parameters describing tx-array or tx-array */
2233 unsigned k_octets = (pref_num_bf_antennas + 7) / 8;
2234
2235 static uint16_t trx_enabled[1024];
2236
2237 /* TODO: could use a bigger bitmask array, but for now just uses this bytes-worth for each byte */
2238 static int * const mask_bits[] = {
2239 &hf_oran_active_beamspace_coefficient_n1,
2240 &hf_oran_active_beamspace_coefficient_n2,
2241 &hf_oran_active_beamspace_coefficient_n3,
2242 &hf_oran_active_beamspace_coefficient_n4,
2243 &hf_oran_active_beamspace_coefficient_n5,
2244 &hf_oran_active_beamspace_coefficient_n6,
2245 &hf_oran_active_beamspace_coefficient_n7,
2246 &hf_oran_active_beamspace_coefficient_n8,
2247 NULL((void*)0)
2248 };
2249
2250 *num_trx_entries = 0;
2251 uint64_t val;
2252 for (unsigned n=0; n < k_octets; n++) {
2253 proto_tree_add_bitmask_ret_uint64(tree, tvb, offset,
2254 hf_oran_activeBeamspaceCoefficientMask,
2255 ett_oran_active_beamspace_coefficient_mask, mask_bits,
2256 ENC_BIG_ENDIAN0x00000000, &val);
2257 offset++;
2258 /* Add up the set bits for this byte (but be careful not to count beyond last real K bit..) */
2259 for (unsigned b=0; b < 8; b++) {
2260 if ((1 << b) & (unsigned)val) {
2261 if (((n*8)+b) < pref_num_bf_antennas) {
2262 if (*num_trx_entries < 1024-1) { /* Don't write beyond array (which should be plenty big) */
2263 trx_enabled[(*num_trx_entries)++] = (n*8) + b + 1;
2264 }
2265 }
2266 }
2267 }
2268 }
2269 /* Set pointer to static array */
2270 *trx_entries = trx_enabled;
2271
2272 /* Show how many bits set */
2273 proto_item *ti = proto_tree_add_uint(tree, hf_oran_activeBeamspaceCoefficientMask_bits_set, tvb,
2274 offset-k_octets, k_octets, *num_trx_entries);
2275 proto_item_set_generated(ti);
2276
2277 return offset;
2278}
2279
2280static void add_beam_id_to_tap(oran_tap_info *tap_info, uint16_t beam_id)
2281{
2282 if (tap_info->num_beams < MAX_BEAMS_IN_FRAME32) {
2283 tap_info->beams[tap_info->num_beams++] = beam_id;
2284 }
2285}
2286
2287
2288/* 7.7.1.3 bfwCompParam (beamforming weight compression parameter).
2289 * Depends upon passed-in bfwCompMeth (field may be empty) */
2290static int dissect_bfwCompParam(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, int offset,
2291 proto_item *meth_ti, uint32_t *bfw_comp_method,
2292 uint32_t *exponent, bool_Bool *supported, unsigned *num_trx_entries, uint16_t **trx_entries)
2293{
2294 if (*bfw_comp_method == COMP_NONE0) {
2295 /* Absent! */
2296 *num_trx_entries = 0;
2297 *supported = true1;
2298 return offset;
2299 }
2300
2301 /* Subtree */
2302 proto_item *bfwcompparam_ti = proto_tree_add_string_format(tree, hf_oran_bfwCompParam,
2303 tvb, offset, 1, "",
2304 "bfwCompParam");
2305 proto_tree *bfwcompparam_tree = proto_item_add_subtree(bfwcompparam_ti, ett_oran_bfwcompparam);
2306
2307 proto_item_append_text(bfwcompparam_ti,
2308 " (meth=%s)", val_to_str_const(*bfw_comp_method, bfw_comp_headers_comp_meth, "reserved"));
2309
2310 *num_trx_entries = 0;
2311 *supported = false0;
2312 switch (*bfw_comp_method) {
2313 case COMP_BLOCK_FP1: /* block floating point */
2314 /* 4 reserved bits + exponent */
2315 add_reserved_field(bfwcompparam_tree, hf_oran_reserved_4bits, tvb, offset, 1);
2316 proto_tree_add_item_ret_uint(bfwcompparam_tree, hf_oran_exponent,
2317 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, exponent);
2318 proto_item_append_text(bfwcompparam_ti, " exponent=%u", *exponent);
2319 *supported = true1;
2320 offset++;
2321 break;
2322 case COMP_BLOCK_SCALE2: /* block scaling */
2323 /* Separate into integer and fractional bits? */
2324 proto_tree_add_item(bfwcompparam_tree, hf_oran_blockScaler,
2325 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
2326 offset++;
2327 break;
2328 case COMP_U_LAW3: /* u-law */
2329 /* compBitWidth, compShift */
2330 proto_tree_add_item(bfwcompparam_tree, hf_oran_compBitWidth,
2331 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
2332 proto_tree_add_item(bfwcompparam_tree, hf_oran_compShift,
2333 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
2334 offset++;
2335 break;
2336 case 4: /* beamspace I (BLOCK SCALING) */
2337 /* activeBeamspaceCoefficientMask */
2338 offset = dissect_active_beamspace_coefficient_mask(tvb, bfwcompparam_tree, offset, num_trx_entries, trx_entries);
2339 *bfw_comp_method = COMP_BLOCK_SCALE2;
2340 *supported = false0; /* TODO: true once BLOCK SCALE is supported */
2341 proto_tree_add_item(bfwcompparam_tree, hf_oran_blockScaler,
2342 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
2343 offset++;
2344 break;
2345 case 5: /* beamspace II (BLOCK FLOATING POINT) */
2346 /* activeBeamspaceCoefficientMask */
2347 offset = dissect_active_beamspace_coefficient_mask(tvb, bfwcompparam_tree, offset, num_trx_entries, trx_entries);
2348 /* reserved (4 bits) + exponent (4 bits) */
2349 add_reserved_field(bfwcompparam_tree, hf_oran_reserved_4bits, tvb, offset, 1);
2350 proto_tree_add_item_ret_uint(bfwcompparam_tree, hf_oran_exponent, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, exponent);
2351 offset += 1;
2352 *bfw_comp_method = COMP_BLOCK_FP1;
2353 *supported = true1;
2354 break;
2355
2356 default:
2357 /* Not handled */
2358 break;
2359 }
2360
2361 proto_item_set_end(bfwcompparam_ti, tvb, offset);
2362
2363 /* Can't go on if compression scheme not supported */
2364 if (!(*supported) && meth_ti) {
2365 expert_add_info_format(pinfo, meth_ti, &ei_oran_unsupported_bfw_compression_method,
2366 "BFW Compression method %u (%s) not decompressed by dissector",
2367 *bfw_comp_method,
2368 val_to_str_const(*bfw_comp_method, bfw_comp_headers_comp_meth, "reserved"));
2369 }
2370 return offset;
2371}
2372
2373
2374/* Special case for uncompressed/16-bit value */
2375static float uncompressed_to_float(uint32_t h)
2376{
2377 int16_t i16 = h & 0x0000ffff;
2378 if (show_unscaled_values) {
2379 return (float)i16;
2380 }
2381 return ((float)i16) / 0x7fff;
2382}
2383
2384/* Decompress I/Q value, taking into account method, width, exponent, other input-specific methods */
2385static float decompress_value(uint32_t bits, uint32_t comp_method, uint8_t iq_width,
2386 uint32_t exponent,
2387 /* Modulation compression settings. N.B. should also pass in PRB + symbol? */
2388 section_mod_compr_config_t *m_c_p, uint8_t re)
2389{
2390 switch (comp_method) {
2391 case COMP_NONE0: /* no compression */
2392 return uncompressed_to_float(bits);
2393
2394 case COMP_BLOCK_FP1: /* block floating point */
2395 case BFP_AND_SELECTIVE_RE5:
2396 {
2397 /* A.1.3 Block Floating Point Decompression Algorithm */
2398 int32_t cPRB = bits;
2399 uint32_t scaler = 1 << exponent; /* i.e. 2^exponent */
2400
2401 /* Check last bit, in case we need to flip to -ve */
2402 if (cPRB >= (1<<(iq_width-1))) {
2403 cPRB -= (1<<iq_width);
2404 }
2405
2406 /* Unscale (8.1.3.1) */
2407 cPRB *= scaler;
2408 if (show_unscaled_values) {
2409 return (float)cPRB;
2410 }
2411
2412 uint32_t mantissa_scale_factor = 1 << (iq_width-1); /* 2^(mantissabits-1) */
2413 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 */
2414
2415 float ret = cPRB / ((float)(mantissa_scale_factor*exp_scale_factor));
2416 return ret;
2417 }
2418
2419 case COMP_BLOCK_SCALE2:
2420 case COMP_U_LAW3:
2421 /* Not supported! But will be reported as expert info outside of this function! */
2422 return 0.0;
2423
2424 case COMP_MODULATION4:
2425 case MOD_COMPR_AND_SELECTIVE_RE6:
2426 {
2427 /* Described in A.5 (with pseudo code) */
2428 /* N.B., Applies to downlink data only - is not used for BFW */
2429
2430 /* Defaults if not overridden. TODO: what should these be? */
2431 bool_Bool csf = false0;
2432 float mcScaler = (float)(1 << 11);
2433
2434 /* Find csf + mcScaler to use. Non-default configs gleaned from SE 4,5,23 */
2435 /* TODO: should ideally be filtering by symbol and PRB too (as configured from SE23) */
2436 if (re > 0 && m_c_p && m_c_p->num_configs > 0) {
2437 for (unsigned c=0; c<m_c_p->num_configs; c++) {
2438 if (m_c_p->configs[c].mod_compr_re_mask & (1 << (12-re))) {
2439 /* Return first (should be only) found */
2440 csf = m_c_p->configs[c].mod_compr_csf;
2441 mcScaler = m_c_p->configs[c].mod_compr_scaler;
2442 break;
2443 }
2444 }
2445 }
2446
2447 int32_t cPRB = bits;
2448
2449 /* 2) Map iqSample to iqSampleFx */
2450 /* Check last bit, in case we need to flip to -ve */
2451 if (cPRB >= (1<<(iq_width-1))) {
2452 cPRB -= (1<<iq_width);
2453 }
2454 float iqSampleFx = (float)cPRB / (1 << (iq_width-1));
2455
2456
2457 /* 3) or 4) (b) - add unshifted value if csf set */
2458 float csf_to_add = 0.0;
2459 if (csf) {
2460 /* Unshift the constellation point */
2461 csf_to_add = (float)1.0 / (1 << (iq_width));
2462 }
2463 iqSampleFx += csf_to_add;
2464
2465 /* 3) or 4) (c) - unscaling */
2466 float iqSampleScaled = mcScaler * iqSampleFx * (float)sqrt(2);
2467 return iqSampleScaled;
2468 }
2469
2470 default:
2471 /* Not supported! But will be reported as expert info outside of this function! */
2472 return 0.0;
2473 }
2474}
2475
2476/* Out-of-range value used for special case */
2477#define ORPHAN_BUNDLE_NUMBER999 999
2478
2479/* Bundle of PRBs/TRX I/Q samples (ext 11) */
2480static uint32_t dissect_bfw_bundle(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, unsigned offset,
2481 proto_item *comp_meth_ti, uint32_t bfwcomphdr_comp_meth,
2482 section_mod_compr_config_t *mod_compr_params,
2483 uint32_t num_weights_per_bundle,
2484 uint8_t iq_width,
2485 unsigned bundle_number,
2486 unsigned first_prb, unsigned last_prb, bool_Bool is_orphan,
2487 uint32_t symbol_count,
2488 section_details_t *section_details,
2489 oran_tap_info *tap_info)
2490{
2491 /* Set bundle name */
2492 char bundle_name[32];
2493 if (!is_orphan) {
2494 snprintf(bundle_name, 32, "Bundle %3u", bundle_number);
2495 }
2496 else {
2497 (void) g_strlcpy(bundle_name, "Orphaned ", 32);
2498 }
2499
2500 /* Create Bundle root */
2501 proto_item *bundle_ti;
2502 if (first_prb != last_prb) {
2503 bundle_ti = proto_tree_add_string_format(tree, hf_oran_bfw_bundle,
2504 tvb, offset, 0, "",
2505 "%s: (PRBs %3u-%3u)",
2506 bundle_name,
2507 first_prb, last_prb);
2508 }
2509 else {
2510 bundle_ti = proto_tree_add_string_format(tree, hf_oran_bfw_bundle,
2511 tvb, offset, 0, "",
2512 "%s: (PRB %3u)",
2513 bundle_name,
2514 first_prb);
2515 }
2516 proto_tree *bundle_tree = proto_item_add_subtree(bundle_ti, ett_oran_bfw_bundle);
2517
2518 /* Generated bundle id */
2519 proto_item *bundleid_ti = proto_tree_add_uint(bundle_tree, hf_oran_bfw_bundle_id, tvb, 0, 0,
2520 bundle_number);
2521 proto_item_set_generated(bundleid_ti);
2522 proto_item_set_hidden(bundleid_ti);
2523
2524 /* bfwCompParam */
2525 bool_Bool compression_method_supported = false0;
2526 unsigned exponent = 0;
2527 unsigned num_trx_entries = 0;
2528 uint16_t *trx_entries;
2529 offset = dissect_bfwCompParam(tvb, bundle_tree, pinfo, offset, comp_meth_ti,
2530 &bfwcomphdr_comp_meth, &exponent, &compression_method_supported,
2531 &num_trx_entries, &trx_entries);
2532
2533 /* Create Bundle subtree */
2534 int bit_offset = offset*8;
2535 int bfw_offset;
2536
2537 /* contInd */
2538 proto_tree_add_item(bundle_tree, hf_oran_cont_ind,
2539 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
2540 /* beamId */
2541 uint32_t beam_id;
2542 proto_tree_add_item_ret_uint(bundle_tree, hf_oran_beam_id, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &beam_id);
2543 proto_item_append_text(bundle_ti, " (beamId:%u) ", beam_id);
2544 bit_offset += 16;
2545 add_beam_id_to_tap(tap_info, beam_id);
2546
2547 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
2548 if (section_details) {
2549 for (unsigned prb = first_prb; prb <= last_prb; prb++) {
2550 if (prb < 273) {
2551 section_details->beamIds[prb] = beam_id;
2552 }
2553 }
2554 }
2555 }
2556
2557 /* On first pass, record that beamId was defined here */
2558 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
2559 bfw_definition *definition = wmem_new0(wmem_file_scope(), bfw_definition)((bfw_definition*)wmem_alloc0((wmem_file_scope()), sizeof(bfw_definition
)))
;
2560 definition->frame_defined = pinfo->num;
2561 definition->symbol_when_defined = symbol_count;
2562 wmem_tree_insert32(dl_beam_ids_defined, beam_id, definition);
2563 }
2564
2565
2566 /* Number of weights per bundle (from preference) */
2567 proto_item *wpb_ti = proto_tree_add_uint(bundle_tree, hf_oran_num_weights_per_bundle, tvb, 0, 0,
2568 num_weights_per_bundle);
2569 proto_item_set_generated(wpb_ti);
2570
2571 /* Add the weights for this bundle. Overwrite with what was seen in bfwCompParam if beamspace */
2572 if (num_trx_entries != 0) {
2573 num_weights_per_bundle = num_trx_entries;
2574 }
2575
2576 bool_Bool non_zero_weights_seen = false0;
2577 int bit_offset_before_weights = bit_offset;
2578 for (unsigned w=0; w < num_weights_per_bundle; w++) {
2579
2580 uint16_t trx_index = (num_trx_entries) ? trx_entries[w] : w+1;
2581
2582 /* Create subtree */
2583 bfw_offset = bit_offset / 8;
2584 uint8_t bfw_extent = ((bit_offset + (iq_width*2)) / 8) - bfw_offset;
2585 proto_item *bfw_ti = proto_tree_add_string_format(bundle_tree, hf_oran_bfw,
2586 tvb, bfw_offset, bfw_extent,
2587 "", "TRX %3u: (", trx_index);
2588 proto_tree *bfw_tree = proto_item_add_subtree(bfw_ti, ett_oran_bfw);
2589
2590 /* I */
2591 /* Get bits, and convert to float. */
2592 uint32_t bits = tvb_get_bits32(tvb, bit_offset, iq_width, ENC_BIG_ENDIAN0x00000000);
2593 if (bits) {
2594 non_zero_weights_seen = true1;
2595 }
2596 float value = decompress_value(bits, bfwcomphdr_comp_meth, iq_width,
2597 exponent, mod_compr_params, 0 /* RE */);
2598 /* Add to tree. */
2599 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);
2600 bit_offset += iq_width;
2601 proto_item_append_text(bfw_ti, "I%u=%f ", w, value);
2602
2603 /* Q */
2604 /* Get bits, and convert to float. */
2605 bits = tvb_get_bits32(tvb, bit_offset, iq_width, ENC_BIG_ENDIAN0x00000000);
2606 if (bits) {
2607 non_zero_weights_seen = true1;
2608 }
2609
2610 value = decompress_value(bits, bfwcomphdr_comp_meth, iq_width,
2611 exponent, mod_compr_params, 0 /* RE */);
2612 /* Add to tree. */
2613 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);
2614 bit_offset += iq_width;
2615 proto_item_append_text(bfw_ti, "Q%u=%f)", w, value);
2616 }
2617
2618 if (!non_zero_weights_seen) {
2619 proto_tree_add_item(bundle_tree, hf_oran_bundle_weights_all_zero, tvb,
2620 bit_offset_before_weights, (bit_offset+7)/8 - (bit_offset_before_weights/8), ENC_NA0x00000000);
2621 }
2622
2623 /* Set extent of bundle */
2624 proto_item_set_end(bundle_ti, tvb, (bit_offset+7)/8);
2625
2626 return (bit_offset+7)/8;
2627}
2628
2629/* Return new bit offset. in/out will always be byte-aligned.. */
2630static int dissect_ciCompParam(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U___attribute__((unused)), unsigned bit_offset,
2631 unsigned comp_meth, uint8_t *exponent)
2632{
2633 if (comp_meth == COMP_NONE0) {
2634 /* Nothing in frame so don't even create subtree */
2635 return bit_offset;
2636 }
2637
2638 /* Subtree */
2639 proto_item *cicompparam_ti = proto_tree_add_string_format(tree, hf_oran_ciCompParam,
2640 tvb, bit_offset/8, 1, "",
2641 "ciCompParam");
2642 proto_tree *cicompparam_tree = proto_item_add_subtree(cicompparam_ti, ett_oran_cicompparam);
2643 uint32_t ci_exponent;
2644
2645 /* Contents differ by compression method */
2646 switch (comp_meth) {
2647 case COMP_BLOCK_FP1:
2648 add_reserved_field(cicompparam_tree, hf_oran_reserved_4bits, tvb, bit_offset/8, 1);
2649 proto_tree_add_item_ret_uint(cicompparam_tree, hf_oran_exponent,
2650 tvb, bit_offset/8, 1, ENC_BIG_ENDIAN0x00000000, &ci_exponent);
2651 *exponent = ci_exponent;
2652 proto_item_append_text(cicompparam_ti, " (Exponent=%u)", ci_exponent);
2653 bit_offset += 8; /* one byte */
2654 break;
2655 case COMP_BLOCK_SCALE2:
2656 /* Separate into integer (1) and fractional (7) bits? */
2657 proto_tree_add_item(cicompparam_tree, hf_oran_blockScaler,
2658 tvb, bit_offset/8, 1, ENC_BIG_ENDIAN0x00000000);
2659 bit_offset += 8;
2660 break;
2661 case COMP_U_LAW3:
2662 /* compBitWidth, compShift (4 bits each) */
2663 proto_tree_add_item(cicompparam_tree, hf_oran_compBitWidth,
2664 tvb, bit_offset/8, 1, ENC_BIG_ENDIAN0x00000000);
2665 proto_tree_add_item(cicompparam_tree, hf_oran_compShift,
2666 tvb, bit_offset/8, 1, ENC_BIG_ENDIAN0x00000000);
2667 bit_offset += 8;
2668 break;
2669
2670 default:
2671 /* reserved, ? bytes of zeros.. */
2672 break;
2673 }
2674
2675 return bit_offset;
2676}
2677
2678/* frameStructure (7.5.2.13) */
2679static unsigned dissect_frame_structure(proto_item *tree, tvbuff_t *tvb, unsigned offset,
2680 uint32_t subframeId, uint32_t slotId)
2681{
2682 uint32_t scs;
2683 /* FFT Size (4 bits) */
2684 proto_tree_add_item(tree, hf_oran_frameStructure_fft, tvb, offset, 1, ENC_NA0x00000000);
2685 /* Subcarrier spacing (SCS) */
2686 proto_tree_add_item_ret_uint(tree, hf_oran_frameStructure_subcarrier_spacing, tvb, offset, 1, ENC_NA0x00000000, &scs);
2687
2688 /* Show slot within frame as a generated field. See table 7.5.13-3 */
2689 uint32_t slots_per_subframe = 1;
2690 if (scs <= 4) {
2691 slots_per_subframe = 1 << scs;
2692 }
2693 if (scs <= 4 || scs >= 12) {
2694 proto_item *ti = proto_tree_add_uint(tree, hf_oran_slot_within_frame, tvb, 0, 0,
2695 (slots_per_subframe*subframeId) + slotId);
2696 proto_item_set_generated(ti);
2697 }
2698 return offset + 1;
2699}
2700
2701static unsigned dissect_csf(proto_item *tree, tvbuff_t *tvb, unsigned bit_offset,
2702 unsigned iq_width, bool_Bool *p_csf)
2703{
2704 proto_item *csf_ti;
2705 uint64_t csf;
2706 csf_ti = proto_tree_add_bits_ret_val(tree, hf_oran_csf, tvb, bit_offset, 1, &csf, ENC_BIG_ENDIAN0x00000000);
2707 if (csf) {
2708 /* Table 7.7.4.2-1 Constellation shift definition (index is udIqWidth) */
2709 const char* shift_value[] = { "n/a", "1/2", "1/4", "1/8", "1/16", "1/32" };
2710 if (iq_width >=1 && iq_width <= 5) {
2711 proto_item_append_text(csf_ti, " (Shift Value is %s)", shift_value[iq_width]);
2712 }
2713 }
2714
2715 /* Set out parameter */
2716 if (p_csf != NULL((void*)0)) {
2717 *p_csf = (csf!=0);
2718 }
2719 return bit_offset+1;
2720}
2721
2722
2723/* Section 7.
2724 * N.B. these are the green parts of the tables showing Section Types, differing by section Type */
2725static int dissect_oran_c_section(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo,
2726 flow_state_t* state,
2727 uint32_t sectionType, oran_tap_info *tap_info, proto_item *protocol_item,
2728 uint32_t subframeId, uint32_t frameId, uint32_t slotId, uint32_t startSymbolId,
2729 uint8_t ci_iq_width, uint8_t ci_comp_meth, unsigned ci_comp_opt,
2730 unsigned num_sinr_per_prb)
2731{
2732 unsigned offset = 0;
2733 proto_tree *c_section_tree = NULL((void*)0);
2734 proto_item *sectionHeading = NULL((void*)0);
2735
2736 /* Section subtree */
2737 sectionHeading = proto_tree_add_string_format(tree, hf_oran_c_section,
2738 tvb, offset, 0, "", "Section");
2739 c_section_tree = proto_item_add_subtree(sectionHeading, ett_oran_c_section);
2740
2741 uint32_t sectionId = 0;
2742
2743 uint32_t startPrbc=0, startPrbu=0;
2744 uint32_t numPrbc=0, numPrbu=0;
2745 uint32_t ueId = 0;
2746 proto_item *ueId_ti = NULL((void*)0);
2747 uint32_t section_beamId = 0;
2748 proto_item *section_beamId_ti = NULL((void*)0);
2749 bool_Bool section_beamId_ignored = false0;
2750
2751 proto_item *numsymbol_ti = NULL((void*)0);
2752 bool_Bool numsymbol_ignored = false0;
2753
2754 proto_item *numprbc_ti = NULL((void*)0);
2755
2756 /* Config affecting ext11 bundles (initially unset) */
2757 ext11_settings_t ext11_settings;
2758 memset(&ext11_settings, 0, sizeof(ext11_settings));
2759
2760 /* Section Type 10 needs to keep track of PRB range that should be reported
2761 for msgTypeId=5 (Interference plus Noise for unallocated PRBs) */
2762 /* All PRBs start as false */
2763#define MAX_PRBS273 273
2764 bool_Bool prbs_for_st10_type5[MAX_PRBS273];
2765 memset(&prbs_for_st10_type5, 0, sizeof(prbs_for_st10_type5));
2766
2767 /* These UEIds are set by ST5, ST10 (single value), and extended by SE10 */
2768#define MAX_UEIDS16 16
2769 uint32_t ueids[MAX_UEIDS16];
2770 uint32_t number_of_ueids = 0;
2771
2772
2773 bool_Bool extension_flag = false0;
2774
2775 /* These sections (ST0, ST1, ST2, ST3, ST5, ST9, ST10, ST11) are similar, so handle as common with per-type differences */
2776 if (((sectionType <= SEC_C_UE_SCHED) || (sectionType >= SEC_C_SINR_REPORTING)) &&
2777 (sectionType != SEC_C_SLOT_CONTROL)) {
2778
2779 /* sectionID */
2780 proto_item *ti = proto_tree_add_item_ret_uint(c_section_tree, hf_oran_section_id, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &sectionId);
2781 if (sectionId == 4095) {
2782 proto_item_append_text(ti, " (not default coupling C/U planes using sectionId)");
2783 }
2784 offset++;
2785
2786 if (tap_info->num_section_ids < MAX_SECTION_IDs32) {
2787 tap_info->section_ids[tap_info->num_section_ids++] = sectionId;
2788 }
2789
2790 /* rb */
2791 uint32_t rb;
2792 proto_tree_add_item_ret_uint(c_section_tree, hf_oran_rb, tvb, offset, 1, ENC_NA0x00000000, &rb);
2793 /* symInc (1 bit) */
2794 /* TODO: mark as ignored if SE6, SE12 or SE19 present */
2795 if (sectionType != SEC_C_RRM_MEAS_REPORTS && /* Section Type 10 */
2796 sectionType != SEC_C_REQUEST_RRM_MEAS) { /* Section Type 11 */
2797 unsigned int sym_inc;
2798 proto_item *sym_inc_ti = proto_tree_add_item_ret_uint(c_section_tree, hf_oran_symInc, tvb, offset, 1, ENC_NA0x00000000, &sym_inc);
2799 if (sym_inc !=0 && (sectionType == SEC_C_SINR_REPORTING)) { /* Section Type 9 */
2800 /* "0 shall be used" */
2801 proto_item_append_text(sym_inc_ti, " (should be 0)");
2802 }
2803 }
2804 else {
2805 /* reserved (1 bit) */
2806 add_reserved_field(c_section_tree, hf_oran_reserved_bit5, tvb, offset, 1);
2807 }
2808
2809 /* startPrbx and numPrbx */
2810 if (sectionType == SEC_C_SINR_REPORTING) {
2811 /* startPrbu (10 bits) */
2812 proto_tree_add_item_ret_uint(c_section_tree, hf_oran_startPrbu, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &startPrbu);
2813 offset += 2;
2814
2815 /* numPrbu */
2816 numprbc_ti = proto_tree_add_item_ret_uint(c_section_tree, hf_oran_numPrbu, tvb, offset, 1, ENC_NA0x00000000, &numPrbu);
2817 if (numPrbu == 0) {
2818 proto_item_append_text(numprbc_ti, " (all PRBs - configured as %u)", pref_data_plane_section_total_rbs);
2819 numPrbu = pref_data_plane_section_total_rbs;
2820 }
2821 offset += 1;
2822 }
2823 else {
2824 /* startPrbc (10 bits) */
2825 proto_tree_add_item_ret_uint(c_section_tree, hf_oran_startPrbc, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &startPrbc);
2826 offset += 2;
2827
2828 /* numPrbc */
2829 numprbc_ti = proto_tree_add_item_ret_uint(c_section_tree, hf_oran_numPrbc, tvb, offset, 1, ENC_NA0x00000000, &numPrbc);
2830 if (numPrbc == 0) {
2831 proto_item_append_text(numprbc_ti, " (all PRBs - configured as %u)", pref_data_plane_section_total_rbs);
2832 /* TODO: should probably set to pref_data_plane_section_total_rbs, and define MAX_PRBS to > 273 ? */
2833 numPrbc = MAX_PRBS273;
2834 }
2835 offset += 1;
2836 }
2837
2838 /* Start with range from section. May get changed by SE6, SE12, SE20 */
2839 for (unsigned n=startPrbc; n < startPrbc+numPrbc; n++) {
2840 if (n < MAX_PRBS273) {
2841 prbs_for_st10_type5[n] = true1;
2842 }
2843 }
2844
2845 if (sectionType != SEC_C_SINR_REPORTING) { /* *NOT* Section Type 9 */
2846 static int * const remask_flags[] = {
2847 &hf_oran_reMask_re1,
2848 &hf_oran_reMask_re2,
2849 &hf_oran_reMask_re3,
2850 &hf_oran_reMask_re4,
2851 &hf_oran_reMask_re5,
2852 &hf_oran_reMask_re6,
2853 &hf_oran_reMask_re7,
2854 &hf_oran_reMask_re8,
2855 &hf_oran_reMask_re9,
2856 &hf_oran_reMask_re10,
2857 &hf_oran_reMask_re11,
2858 &hf_oran_reMask_re12,
2859 NULL((void*)0)
2860 };
2861
2862 /* reMask */
2863 uint64_t remask;
2864 proto_tree_add_bitmask_ret_uint64(c_section_tree, tvb, offset,
2865 hf_oran_reMask, ett_oran_remask, remask_flags, ENC_BIG_ENDIAN0x00000000, &remask);
2866 offset++;
2867 /* numSymbol */
2868 uint32_t numSymbol;
2869 numsymbol_ti = proto_tree_add_item_ret_uint(c_section_tree, hf_oran_numSymbol, tvb, offset, 1, ENC_NA0x00000000, &numSymbol);
2870 if ((sectionType == SEC_C_RRM_MEAS_REPORTS) && (numSymbol != 14)) { /* Section type 10 must have 14 symbols */
2871 proto_item_append_text(numsymbol_ti, " (for ST10, should be 14!)");
2872 expert_add_info_format(pinfo, numsymbol_ti, &ei_oran_st10_numsymbol_not_14,
2873 "numSymbol should be 14 for ST10 - found %u", numSymbol);
2874 }
2875 if ((startSymbolId + numSymbol) > 14) {
2876 /* Warn if startSymbol + numSymbol would be > 14 */
2877 expert_add_info_format(pinfo, numsymbol_ti, &ei_oran_too_many_symbols,
2878 "startSymbolId (%u) + numSymbol (%u) exceeds max of 14",
2879 startSymbolId, numSymbol);
2880 }
2881 offset++;
2882
2883 /* [ef] (extension flag) */
2884 switch (sectionType) {
2885 case SEC_C_UNUSED_RB: /* Section Type 0 */
2886 case SEC_C_NORMAL: /* Section Type 1 */
2887 case SEC_C_PRACH: /* Section Type 3 */
2888 case SEC_C_UE_SCHED: /* Section Type 5 */
2889 case SEC_C_RRM_MEAS_REPORTS: /* Section Type 10 */
2890 case SEC_C_REQUEST_RRM_MEAS: /* Section Type 11 */
2891 proto_tree_add_item_ret_boolean(c_section_tree, hf_oran_ef, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &extension_flag);
2892 break;
2893 default:
2894 /* Other section types don't support extensions */
2895 break;
2896 }
2897
2898 write_section_info(sectionHeading, pinfo, protocol_item, sectionId, startPrbc, numPrbc, rb);
2899 proto_item_append_text(sectionHeading, ", Symbols: %2u", numSymbol);
2900
2901 if (numPrbc == 0) {
2902 /* Special case for all PRBs */
2903 numPrbc = pref_data_plane_section_total_rbs;
2904 startPrbc = 0; /* may already be 0... */
2905 }
2906 }
2907 else {
2908 /* Section Type 9 */
2909 write_section_info(sectionHeading, pinfo, protocol_item, sectionId, startPrbu, numPrbu, rb);
2910 proto_item_append_text(sectionHeading, ", numSinrPerPrb: %2u", num_sinr_per_prb);
2911 }
2912
2913 /* Section type specific fields (after 'numSymbol') */
2914 switch (sectionType) {
2915 case SEC_C_UNUSED_RB: /* Section Type 0 - Table 7.4.2-1 */
2916 /* reserved (15 bits) */
2917 add_reserved_field(c_section_tree, hf_oran_reserved_15bits, tvb, offset, 2);
2918 offset += 2;
2919 break;
2920
2921 case SEC_C_NORMAL: /* Section Type 1 - Table 7.4.3-1 */
2922 /* beamId */
2923 section_beamId_ti = proto_tree_add_item_ret_uint(c_section_tree, hf_oran_beamId, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &section_beamId);
2924 offset += 2;
2925
2926 /* beamId might get invalidated by e.g., ext-6, ext-11, so unused value will still be shown here.. */
2927 proto_item_append_text(sectionHeading, ", BeamId: %d", section_beamId);
2928 break;
2929
2930 case SEC_C_PRACH: /* Section Type 3 - Table 7.4.5-1 */
2931 {
2932 /* beamId */
2933 section_beamId_ti = proto_tree_add_item_ret_uint(c_section_tree, hf_oran_beamId, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &section_beamId);
2934 offset += 2;
2935
2936 /* freqOffset */
2937 int32_t freqOffset; /* Yes, this is signed, so the cast is intentional. */
2938 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);
2939 freqOffset |= 0xff000000; /* Must sign-extend */
2940 proto_item_set_text(freq_offset_item, "Frequency offset: %d \u0394f", freqOffset);
2941 offset += 3;
2942
2943 /* reserved (8 bits) */
2944 add_reserved_field(c_section_tree, hf_oran_reserved_8bits, tvb, offset, 1);
2945 offset += 1;
2946
2947 /* beamId might get invalidated by e.g., ext-6, ext-11, so unused value will still be shown here.. */
2948 proto_item_append_text(sectionHeading, ", BeamId: %d, FreqOffset: %d \u0394f", section_beamId, freqOffset);
2949 break;
2950 }
2951
2952 case SEC_C_UE_SCHED: /* Section Type 5 - Table 7.4.7-1 */
2953 case SEC_C_RRM_MEAS_REPORTS: /* Section Type 10 - Table 7.4.12-1 */
2954 /* ueId */
2955 ueId_ti = proto_tree_add_item_ret_uint(c_section_tree, hf_oran_ueId, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &ueId);
2956 offset += 2;
2957 if (ueId == 0x7fff) {
2958 proto_item_append_text(ueId_ti, " (PRBs not scheduled for eAxC ID in transport header)");
2959 }
2960 else {
2961 ueids[number_of_ueids++] = ueId;
2962 }
2963
2964 proto_item_append_text(sectionHeading, ", UEId: %d", ueId);
2965 break;
2966
2967 case SEC_C_SINR_REPORTING: /* Section Type 9 - SINR Reporting */
2968 {
2969 /* Hidden filter for bf (DMFS-BF) */
2970 proto_item *bf_ti = proto_tree_add_item(tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
2971 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
2972
2973 unsigned bit_offset = offset*8;
2974
2975 /* sinr iqWidth */
2976 proto_item *iq_width_item = proto_tree_add_uint(c_section_tree, hf_oran_sinrCompHdrIqWidth_pref, tvb, 0, 0, pref_sample_bit_width_sinr);
2977 proto_item_append_text(iq_width_item, " (from preferences)");
2978 proto_item_set_generated(iq_width_item);
2979
2980 /* sinr compMethod */
2981 proto_item *sinr_comp_meth_item = proto_tree_add_uint(c_section_tree, hf_oran_sinrCompHdrMeth_pref, tvb, 0, 0, pref_iqCompressionSINR);
2982 proto_item_append_text(sinr_comp_meth_item, " (from preferences)");
2983 proto_item_set_generated(sinr_comp_meth_item);
2984
2985 /* Add SINR entries for each PRB */
2986 for (unsigned prb=startPrbu; prb < startPrbu+numPrbu; prb++) {
2987 /* Create a subtree for each PRB */
2988 proto_item *prb_ti = proto_tree_add_string_format(c_section_tree, hf_oran_sinr_prb,
2989 tvb, offset, 0, "", "PRB %3u (", prb);
2990 proto_tree *prb_tree = proto_item_add_subtree(prb_ti, ett_oran_sinr_prb);
2991
2992 /* Each prb starts byte-aligned */
2993 bit_offset = ((bit_offset+7)/8) * 8;
2994
2995 /* N.B., using width/method from UL U-plane preferences, not certain that this is correct.. */
2996
2997 /* sinrCompParam (udCompParam format, may be empty) */
2998 uint32_t exponent = 0; /* N.B. init to silence warnings, but will always be set if read in COMP_BLOCK_FP case */
2999 uint16_t sReSMask;
3000 bit_offset = dissect_udcompparam(tvb, pinfo, prb_tree, bit_offset/8,
3001 pref_iqCompressionSINR, &exponent, &sReSMask,
3002 true1) * 8; /* last param is for_sinr */
3003
3004 /* sinrValues for this PRB. */
3005 /* TODO: not sure how numSinrPerPrb interacts with rb==1... */
3006 for (unsigned n=0; n < num_sinr_per_prb; n++) {
3007 unsigned sinr_bits = tvb_get_bits32(tvb, bit_offset, pref_sample_bit_width_sinr, ENC_BIG_ENDIAN0x00000000);
3008
3009 /* Using SINR compression settings from preferences */
3010 float value = decompress_value(sinr_bits,
3011 pref_iqCompressionSINR, pref_sample_bit_width_sinr,
3012 exponent,
3013 NULL((void*)0) /* no ModCompr for SINR */, 0 /* RE */);
3014 unsigned sample_len_in_bytes = ((bit_offset%8)+pref_sample_bit_width_sinr+7)/8;
3015 proto_item *val_ti = proto_tree_add_float(prb_tree, hf_oran_sinr_value, tvb,
3016 bit_offset/8, sample_len_in_bytes, value);
3017 proto_item_append_text(prb_ti, " %8f", value);
3018
3019 /* Show here which subcarriers share which values (they all divide 12..) */
3020 if (num_sinr_per_prb == 12) {
3021 proto_item_append_text(val_ti, " (PRB=%u, subcarrier %u)",
3022 startPrbu+((prb-startPrbu)*(rb+1)), n*(12/num_sinr_per_prb));
3023 }
3024 else {
3025 proto_item_append_text(val_ti, " (PRB=%u, subcarriers %u-%u)",
3026 startPrbu+((prb-startPrbu)*(rb+1)),
3027 n*(12/num_sinr_per_prb), (n+1)*(12/num_sinr_per_prb)-1);
3028 }
3029 bit_offset += pref_sample_bit_width_sinr;
3030 }
3031
3032 /* 1-byte alignment per PRB (7.2.11) */
3033 offset = (bit_offset+7)/8;
3034 bit_offset = offset*8;
3035
3036 proto_item_append_text(prb_ti, ")");
3037 proto_item_set_end(prb_ti, tvb, offset);
3038 }
3039 break;
3040 }
3041 case SEC_C_REQUEST_RRM_MEAS: /* Section Type 11 - Request RRM Measurements */
3042 /* Reserved (15 bits) */
3043 add_reserved_field(c_section_tree, hf_oran_reserved_15bits, tvb, offset, 2);
3044 offset += 2;
3045 break;
3046
3047 default:
3048 break;
3049 }
3050 }
3051 else if (sectionType == SEC_C_CH_INFO) { /* Section Type 6 */
3052 /* ef */
3053 proto_tree_add_item_ret_boolean(c_section_tree, hf_oran_ef, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &extension_flag);
3054 /* ueId */
3055 proto_tree_add_item_ret_uint(c_section_tree, hf_oran_ueId, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &ueId);
3056 offset += 2;
3057 /* regularizationFactor */
3058 proto_tree_add_item(c_section_tree, hf_oran_regularizationFactor, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
3059 offset += 2;
3060 /* reserved (4 bits) */
3061 add_reserved_field(c_section_tree, hf_oran_reserved_4bits, tvb, offset, 1);
3062 /* rb ("Value=0 shall be set") */
3063 uint32_t rb;
3064 proto_item *rb_ti = proto_tree_add_item_ret_uint(c_section_tree, hf_oran_rb, tvb, offset, 1, ENC_NA0x00000000, &rb);
3065 if (rb != 0) {
3066 proto_item_append_text(rb_ti, " (should be set to 0)");
3067 expert_add_info(pinfo, rb_ti, &ei_oran_st6_rb_shall_be_0);
3068 }
3069 /* symInc */
3070 proto_tree_add_item(c_section_tree, hf_oran_symInc, tvb, offset, 1, ENC_NA0x00000000);
3071 /* startPrbc */
3072 proto_tree_add_item_ret_uint(c_section_tree, hf_oran_startPrbc, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &startPrbc);
3073 offset += 2;
3074 /* numPrbc */
3075 proto_tree_add_item_ret_uint(c_section_tree, hf_oran_numPrbc, tvb, offset, 1, ENC_NA0x00000000, &numPrbc);
3076 offset += 1;
3077
3078 /* Hidden filter for bf */
3079 proto_item *bf_ti = proto_tree_add_item(tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
3080 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
3081
3082 /* ciIsample,ciQsample pairs */
3083 unsigned m;
3084 unsigned prb;
3085 uint32_t bit_offset = offset*8;
3086
3087 /* Antenna count from preference */
3088 unsigned num_trx = pref_num_bf_antennas;
3089
3090 write_channel_section_info(sectionHeading, pinfo,
3091 sectionId, ueId, startPrbc, numPrbc, num_trx);
3092
3093 bool_Bool first_prb = true1;
3094 uint8_t exponent = 0;
3095 for (prb=startPrbc; prb < startPrbc+numPrbc; prb++) {
3096
3097 /* PRB subtree */
3098 unsigned prb_start_offset = bit_offset;
3099 proto_item *prb_ti = proto_tree_add_string_format(c_section_tree, hf_oran_samples_prb,
3100 tvb, bit_offset/8, 0,
3101 "", "PRB=%u", prb);
3102 proto_tree *prb_tree = proto_item_add_subtree(prb_ti, ett_oran_prb_cisamples);
3103
3104 /* There may be a ciCompParam here.. */
3105 if (first_prb || ci_comp_opt==1) {
3106 bit_offset = dissect_ciCompParam(tvb, prb_tree, pinfo, bit_offset, ci_comp_meth, &exponent);
3107 }
3108 first_prb = false0;
3109
3110 /* Antennas */
3111 for (m=0; m < num_trx; m++) {
3112
3113 unsigned sample_offset = bit_offset / 8;
3114 uint8_t sample_extent = ((bit_offset + (ci_iq_width*2)) / 8) - sample_offset;
3115
3116 /* Create subtree for antenna */
3117 proto_item *sample_ti = proto_tree_add_string_format(prb_tree, hf_oran_ciSample,
3118 tvb, sample_offset, sample_extent,
3119 "", "TRX=%2u: ", m);
3120 proto_tree *sample_tree = proto_item_add_subtree(sample_ti, ett_oran_cisample);
3121
3122 /* I */
3123 /* Get bits, and convert to float. */
3124 uint32_t bits = tvb_get_bits32(tvb, bit_offset, ci_iq_width, ENC_BIG_ENDIAN0x00000000);
3125 float value = decompress_value(bits, ci_comp_meth, ci_iq_width, exponent, NULL((void*)0) /* no ModCompr for ST6 */, 0 /* RE */);
3126
3127 /* Add to tree. */
3128 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);
3129 bit_offset += ci_iq_width;
3130 proto_item_append_text(sample_ti, "I%u=%f ", m, value);
3131
3132 /* Q */
3133 /* Get bits, and convert to float. */
3134 bits = tvb_get_bits32(tvb, bit_offset, ci_iq_width, ENC_BIG_ENDIAN0x00000000);
3135 value = decompress_value(bits, ci_comp_meth, ci_iq_width, exponent, NULL((void*)0) /* no ModCompr for ST6 */, 0 /* RE */);
3136
3137 /* Add to tree. */
3138 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);
3139 bit_offset += ci_iq_width;
3140 proto_item_append_text(sample_ti, "Q%u=%f ", m, value);
3141 }
3142 proto_item_set_len(prb_ti, (bit_offset-prb_start_offset+7)/8);
3143 }
3144
3145 /* Pad out by 1 or 4 bytes, according to preference */
3146 if (!st6_4byte_alignment) {
3147 offset = (bit_offset + 7) / 8;
3148 }
3149 else {
3150 int mode = bit_offset % 32;
3151 if (mode != 0) {
3152 offset = (bit_offset + (32-mode))/8;
3153 }
3154 else {
3155 offset = bit_offset/8;
3156 }
3157 }
3158 proto_item_set_end(c_section_tree, tvb, offset);
3159 }
3160
3161
3162 expected_section_data_t *dl_data_section = NULL((void*)0);
3163 unsigned index_to_use = 0;
3164
3165 /* On first pass, allocate a section entry to use */
3166 if (link_planes_together && !PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
3167
3168 if (!tap_info->uplink) {
3169 /* Look for existing entry for sectionId to overwrite first. */
3170 dl_data_section = wmem_tree_lookup32(state->expected_dl_sections,
3171 sectionId);
3172 if (dl_data_section == NULL((void*)0)) {
3173 /* None, so create */
3174 dl_data_section = wmem_new0(wmem_file_scope(), expected_section_data_t)((expected_section_data_t*)wmem_alloc0((wmem_file_scope()), sizeof
(expected_section_data_t)))
;
3175 wmem_tree_insert32(state->expected_dl_sections,
3176 sectionId,
3177 dl_data_section);
3178 }
3179
3180 /* If 2nd entry not in use, use that one */
3181 if (!dl_data_section->details[1].in_use) {
3182 index_to_use = 1;
3183 }
3184 else {
3185 /* Both in use, so replace the older of the 2 entries */
3186 if (dl_data_section->details[1].frame_number < dl_data_section->details[0].frame_number) {
3187 index_to_use = 1;
3188 }
3189 }
3190
3191 if (dl_data_section) {
3192 section_details_t *details = &dl_data_section->details[index_to_use];
3193
3194 details->in_use = true1;
3195 details->frame = frameId;
3196 details->subframe = subframeId;
3197 details->slot = slotId;
3198 details->startSymbol = startSymbolId;
3199
3200 details->frame_number = pinfo->num;
3201 details->frame_time = pinfo->abs_ts;
3202 dl_data_section->sectionId = sectionId;
3203 details->startPrb = startPrbc;
3204 details->numPrb = numPrbc;
3205 for (unsigned prb = startPrbc; prb <= startPrbc+numPrbc; prb++) {
3206 if (prb < 273) {
3207 details->beamIds[prb] = section_beamId;
3208 }
3209 }
3210 }
3211 }
3212 }
3213
3214 bool_Bool seen_se10 = false0;
3215 uint32_t numPortc = 0;
3216 proto_item *bf_ti = NULL((void*)0);
3217
3218 /* Section extension commands */
3219 while (extension_flag) {
3220 int extension_start_offset = offset;
3221
3222 /* Prefetch extType so can use specific extension type ett */
3223 uint32_t exttype = tvb_get_uint8(tvb, offset) & 0x7f;
3224 uint32_t exttype_ett_index = exttype;
3225 if (exttype == 0 || exttype > HIGHEST_EXTTYPE32) {
3226 /* Just use first one if out of range */
3227 exttype_ett_index = 1;
3228 }
3229
3230 /* Create subtree for each extension (with summary) */
3231 proto_item *extension_ti = proto_tree_add_string_format(c_section_tree, hf_oran_extension,
3232 tvb, offset, 0, "", "Extension");
3233 proto_tree *extension_tree = proto_item_add_subtree(extension_ti, ett_oran_c_section_extension[exttype_ett_index-1]);
3234
3235 /* ef (i.e. another extension after this one?) */
3236 proto_tree_add_item_ret_boolean(extension_tree, hf_oran_ef, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &extension_flag);
3237
3238 /* extType */
3239 proto_item *exttype_ti;
3240 exttype_ti = proto_tree_add_item(extension_tree, hf_oran_exttype, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3241 offset++;
3242 proto_item_append_text(sectionHeading, " (ext-%u)", exttype);
3243
3244 proto_item_append_text(extension_ti, " (ext-%u: %s)", exttype, val_to_str_ext_const(exttype, &exttype_vals_ext, "Reserved"));
3245
3246 /* Don't tap if out of range. */
3247 if (exttype > 0 && exttype <= HIGHEST_EXTTYPE32) {
3248 tap_info->extensions[exttype] = true1;
3249 }
3250
3251 /* Is this SE allowed for this section type? */
3252 if (!se_allowed_in_st(exttype, sectionType)) {
3253 expert_add_info_format(pinfo, extension_tree, &ei_oran_se_on_unsupported_st,
3254 "SE %u (%s) should not appear in ST %u (%s)!",
3255 exttype, val_to_str_ext_const(exttype, &exttype_vals_ext, "Reserved"),
3256 sectionType, rval_to_str_const(sectionType, section_types, "Unknown"));
3257 }
3258
3259
3260 /* extLen (number of 32-bit words) */
3261 uint32_t extlen_len = ((exttype==11)||(exttype==19)||(exttype==20)) ? 2 : 1; /* Extensions 11/19/20 are special */
3262 uint32_t extlen;
3263 proto_item *extlen_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_extlen, tvb,
3264 offset, extlen_len, ENC_BIG_ENDIAN0x00000000, &extlen);
3265 proto_item_append_text(extlen_ti, " (%u bytes)", extlen*4);
3266 offset += extlen_len;
3267 if (extlen == 0) {
3268 expert_add_info(pinfo, extlen_ti, &ei_oran_extlen_zero);
3269 /* Break out to avoid infinitely looping! */
3270 break;
3271 }
3272
3273 bool_Bool ext_unhandled = false0;
3274
3275 switch (exttype) {
3276
3277 case 1: /* SE 1: Beamforming Weights */
3278 {
3279 uint32_t bfwcomphdr_iq_width, bfwcomphdr_comp_meth;
3280 proto_item *comp_meth_ti = NULL((void*)0);
3281
3282 /* Hidden filter for bf */
3283 bf_ti = proto_tree_add_item(tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
3284 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
3285
3286 /* bfwCompHdr (2 subheaders - bfwIqWidth and bfwCompMeth)*/
3287 offset = dissect_bfwCompHdr(tvb, extension_tree, offset,
3288 &bfwcomphdr_iq_width, &bfwcomphdr_comp_meth, &comp_meth_ti);
3289
3290 /* bfwCompParam */
3291 uint32_t exponent = 0;
3292 bool_Bool compression_method_supported = false0;
3293 unsigned num_trx = 0;
3294 uint16_t *trx; /* ptr to array */
3295 offset = dissect_bfwCompParam(tvb, extension_tree, pinfo, offset, comp_meth_ti,
3296 &bfwcomphdr_comp_meth, &exponent, &compression_method_supported,
3297 &num_trx, &trx);
3298
3299 /* Can't show details of unsupported compression method */
3300 if (!compression_method_supported) {
3301 break;
3302 }
3303
3304 /* We know:
3305 - iq_width (above)
3306 - numBfWeights (taken from preference)
3307 - remaining bytes in extension
3308 We can therefore derive TRX (number of antennas).
3309 */
3310
3311 bool_Bool using_array = false0;
3312
3313 /* I & Q samples
3314 May know how many entries from activeBeamspaceCoefficientMask. */
3315 if (num_trx == 0) {
3316 /* Don't know how many there will be, so just fill available bytes... */
3317 unsigned weights_bytes = (extlen*4)-3;
3318 unsigned num_weights_pairs = (weights_bytes*8) / (bfwcomphdr_iq_width*2);
3319 num_trx = num_weights_pairs;
3320 }
3321 else {
3322 using_array = true1;
3323 num_trx = pref_num_bf_antennas;
3324 }
3325
3326 int bit_offset = offset*8;
3327
3328 for (unsigned n=0; n < num_trx; n++) {
3329 /* Create antenna subtree */
3330 int bfw_offset = bit_offset / 8;
3331
3332 uint16_t trx_index = (using_array) ? trx[n] : n+1;
3333
3334 proto_item *bfw_ti = proto_tree_add_string_format(extension_tree, hf_oran_bfw,
3335 tvb, bfw_offset, 0, "", "TRX %3u: (", trx_index);
3336 proto_tree *bfw_tree = proto_item_add_subtree(bfw_ti, ett_oran_bfw);
3337
3338 /* I value */
3339 /* Get bits, and convert to float. */
3340 uint32_t bits = tvb_get_bits32(tvb, bit_offset, bfwcomphdr_iq_width, ENC_BIG_ENDIAN0x00000000);
3341 float value = decompress_value(bits, bfwcomphdr_comp_meth, bfwcomphdr_iq_width, exponent,
3342 NULL((void*)0) /* no ModCompr */, 0 /* RE */);
3343 /* Add to tree. */
3344 proto_tree_add_float(bfw_tree, hf_oran_bfw_i, tvb, bit_offset/8,
3345 (bfwcomphdr_iq_width+7)/8, value);
3346 bit_offset += bfwcomphdr_iq_width;
3347 proto_item_append_text(bfw_ti, "I=%f ", value);
3348
3349 /* Leave a gap between I and Q values */
3350 proto_item_append_text(bfw_ti, " ");
3351
3352 /* Q value */
3353 /* Get bits, and convert to float. */
3354 bits = tvb_get_bits32(tvb, bit_offset, bfwcomphdr_iq_width, ENC_BIG_ENDIAN0x00000000);
3355 value = decompress_value(bits, bfwcomphdr_comp_meth, bfwcomphdr_iq_width, exponent,
3356 NULL((void*)0) /* no ModCompr */, 0 /* RE */);
3357 /* Add to tree. */
3358 proto_tree_add_float(bfw_tree, hf_oran_bfw_q, tvb, bit_offset/8,
3359 (bfwcomphdr_iq_width+7)/8, value);
3360 bit_offset += bfwcomphdr_iq_width;
3361 proto_item_append_text(bfw_ti, "Q=%f", value);
3362
3363 proto_item_append_text(bfw_ti, ")");
3364 proto_item_set_len(bfw_ti, (bit_offset+7)/8 - bfw_offset);
3365 }
3366 /* Need to round to next byte */
3367 offset = (bit_offset+7)/8;
3368
3369 break;
3370 }
3371
3372 case 2: /* SE 2: Beamforming attributes */
3373 {
3374 /* Hidden filter for bf */
3375 bf_ti = proto_tree_add_item(tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
3376 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
3377
3378 /* bfaCompHdr (get widths of fields to follow) */
3379 uint32_t bfAzPtWidth, bfZePtWidth, bfAz3ddWidth, bfZe3ddWidth;
3380 /* subtree */
3381 proto_item *bfa_ti = proto_tree_add_string_format(extension_tree, hf_oran_bfaCompHdr,
3382 tvb, offset, 2, "", "bfaCompHdr");
3383 proto_tree *bfa_tree = proto_item_add_subtree(bfa_ti, ett_oran_bfacomphdr);
3384
3385 /* reserved (2 bits) */
3386 add_reserved_field(bfa_tree, hf_oran_reserved_2bits, tvb, offset, 1);
3387 /* bfAzPtWidth (3 bits) */
3388 proto_tree_add_item_ret_uint(bfa_tree, hf_oran_bfAzPtWidth, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &bfAzPtWidth);
3389 /* bfZePtWidth (3 bits) */
3390 proto_tree_add_item_ret_uint(bfa_tree, hf_oran_bfZePtWidth, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &bfZePtWidth);
3391 offset += 1;
3392
3393 /* reserved (2 bits) */
3394 add_reserved_field(bfa_tree, hf_oran_reserved_2bits, tvb, offset, 1);
3395 /* bfAz3ddWidth (3 bits) */
3396 proto_tree_add_item_ret_uint(bfa_tree, hf_oran_bfAz3ddWidth, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &bfAz3ddWidth);
3397 /* bfZe3ddWidth (3 bits) */
3398 proto_tree_add_item_ret_uint(bfa_tree, hf_oran_bfZe3ddWidth, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &bfZe3ddWidth);
3399 offset += 1;
3400
3401 unsigned bit_offset = offset*8;
3402
3403 /* bfAzPt */
3404 if (bfAzPtWidth > 0) {
3405 proto_tree_add_bits_item(extension_tree, hf_oran_bfAzPt, tvb, bit_offset, bfAzPtWidth+1, ENC_BIG_ENDIAN0x00000000);
3406 bit_offset += (bfAzPtWidth+1);
3407 }
3408 /* bfZePt */
3409 if (bfZePtWidth > 0) {
3410 proto_tree_add_bits_item(extension_tree, hf_oran_bfZePt, tvb, bit_offset, bfZePtWidth+1, ENC_BIG_ENDIAN0x00000000);
3411 bit_offset += (bfZePtWidth+1);
3412 }
3413 /* bfAz3dd */
3414 if (bfAz3ddWidth > 0) {
3415 proto_tree_add_bits_item(extension_tree, hf_oran_bfAz3dd, tvb, bit_offset, bfAz3ddWidth+1, ENC_BIG_ENDIAN0x00000000);
3416 bit_offset += (bfAz3ddWidth+1);
3417 }
3418 /* bfZe3dd */
3419 if (bfZe3ddWidth > 0) {
3420 proto_tree_add_bits_item(extension_tree, hf_oran_bfZe3dd, tvb, bit_offset, bfZe3ddWidth+1, ENC_BIG_ENDIAN0x00000000);
3421 bit_offset += (bfZe3ddWidth+1);
3422 }
3423
3424 /* Pad to next byte (unless last 2 fields already fit in this one) */
3425 if ((bit_offset % 8) > 2) {
3426 offset = (bit_offset+7) / 8;
3427 }
3428 else {
3429 offset = bit_offset / 8;
3430 }
3431
3432 /* bfAzSl (3 bits) */
3433 proto_tree_add_item(extension_tree, hf_oran_bfAzSl, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3434 /* bfZeSl (3 bits) */
3435 proto_tree_add_item(extension_tree, hf_oran_bfZeSl, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3436 offset += 1;
3437 break;
3438 }
3439
3440 case 3: /* SE 3: DL precoding parameters */
3441 {
3442 /* codebookindex (8 bits) */
3443 /* "This parameter is not used and shall be set to zero." */
3444 proto_tree_add_item(extension_tree, hf_oran_codebook_index, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3445 offset += 1;
3446 /* layerid */
3447 uint32_t layerid;
3448 proto_tree_add_item_ret_uint(extension_tree, hf_oran_layerid, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &layerid);
3449 /* numLayers */
3450 proto_tree_add_item(extension_tree, hf_oran_numlayers, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3451 offset += 1;
3452
3453 /* Stop here for non-first data layer */
3454 if (layerid != 0 && layerid != 0xf) {
3455 break;
3456 }
3457
3458 /* First data layer case */
3459 /* txScheme */
3460 proto_tree_add_item(extension_tree, hf_oran_txscheme, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3461 /* crsReMask */
3462 proto_tree_add_item(extension_tree, hf_oran_crs_remask, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
3463 offset += 2;
3464
3465 /* crsShift (1 bit) */
3466 proto_tree_add_item(extension_tree, hf_oran_crs_shift, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3467 /* reserved (3 bits) */
3468 add_reserved_field(extension_tree, hf_oran_reserved_bits123, tvb, offset, 1);
3469 /* crsSymNum (4 bits) */
3470 proto_tree_add_item(extension_tree, hf_oran_crs_symnum, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3471 offset += 1;
3472 /* reserved (8 bits) */
3473 add_reserved_field(extension_tree, hf_oran_reserved_8bits, tvb, offset, 1);
3474 offset += 1;
3475
3476 /* reserved (1 bit) */
3477 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
3478 /* beamIdAP1 (15 bits) */
3479 proto_tree_add_item(extension_tree, hf_oran_beamid_ap1, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
3480 offset += 2;
3481 /* reserved (1 bit) */
3482 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
3483 /* beamIdAP2 (15 bits) */
3484 proto_tree_add_item(extension_tree, hf_oran_beamid_ap2, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
3485 offset += 2;
3486 /* reserved (1 bit) */
3487 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
3488 /* beamIdAP3 (15 bits) */
3489 proto_tree_add_item(extension_tree, hf_oran_beamid_ap3, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
3490 offset += 2;
3491 break;
3492 }
3493
3494 case 4: /* SE 4: Modulation compression params (5.4.7.4) (single sets) */
3495 {
3496 /* csf */
3497 bool_Bool csf;
3498 dissect_csf(extension_tree, tvb, offset*8, ci_iq_width, &csf);
3499
3500 /* modCompScaler */
3501 uint32_t modCompScaler;
3502 proto_item *ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_modcompscaler,
3503 tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &modCompScaler);
3504 offset += 2;
3505
3506 /* Work out and show floating point value too. exponent and mantissa are both unsigned */
3507 uint16_t exponent = (modCompScaler >> 11) & 0x000f; /* m.s. 4 bits */
3508 uint16_t mantissa = modCompScaler & 0x07ff; /* l.s. 11 bits */
3509 float value = ((float)mantissa/(1<<11)) * ((float)1.0 / (1 << exponent));
3510 proto_item_append_text(ti, " (%f)", value);
3511
3512 section_mod_compr_config_t* sect_config = get_mod_compr_section_to_write(state, sectionId);
3513
3514 /* Store these params in this flow's state */
3515 if (sect_config && sect_config->num_configs < MAX_MOD_COMPR_CONFIGS12) {
3516 unsigned i = sect_config->num_configs;
3517 sect_config->configs[i].mod_compr_re_mask = 0xfff; /* Covers all REs */
3518 sect_config->configs[i].mod_compr_csf = csf;
3519 sect_config->configs[i].mod_compr_scaler = value;
3520 sect_config->num_configs++;
3521 }
3522 break;
3523 }
3524
3525 case 5: /* SE 5: Modulation Compression Additional Parameters (7.7.5) (multiple sets) */
3526 {
3527 /* Applies only to section types 1,3 and 5 */
3528 /* N.B. there may be multiple instances of this SE in the same frame */
3529
3530 /* There may be one or 2 entries, depending upon extlen */
3531 int sets = 1, reserved_bits = 0;
3532 switch (extlen) {
3533 case 2:
3534 sets = 1;
3535 reserved_bits = 20;
3536 break;
3537 case 3:
3538 sets = 2;
3539 reserved_bits = 24;
3540 break;
3541 case 4:
3542 /* sets can be 3 or 4, depending upon whether last 28 bits are 0.. */
3543 if ((tvb_get_ntohl(tvb, offset+10) & 0x0fffffff) == 0) {
3544 sets = 3;
3545 reserved_bits = 28;
3546 }
3547 else {
3548 sets = 4;
3549 reserved_bits = 0;
3550 }
3551 break;
3552
3553 default:
3554 /* Malformed error!!! */
3555 expert_add_info_format(pinfo, extlen_ti, &ei_oran_extlen_wrong,
3556 "For section 5, extlen must be 2, 3 or 4, but %u was dissected",
3557 extlen);
3558 break;
3559 }
3560
3561 unsigned bit_offset = offset*8;
3562 /* Dissect each set */
3563 for (int n=0; n < sets; n++) {
3564 /* Subtree for each set */
3565 unsigned set_start_offset = bit_offset/8;
3566 proto_item *set_ti = proto_tree_add_string(extension_tree, hf_oran_modcomp_param_set,
3567 tvb, set_start_offset, 0, "");
3568 proto_tree *set_tree = proto_item_add_subtree(set_ti, ett_oran_modcomp_param_set);
3569
3570 uint64_t mcScaleReMask, mcScaleOffset;
3571 bool_Bool csf;
3572
3573 /* mcScaleReMask (12 bits). Defines which REs the following csf and mcScaleOffset apply to */
3574 static int * const remask_flags[] = {
3575 &hf_oran_mc_scale_re_mask_re1,
3576 &hf_oran_mc_scale_re_mask_re2,
3577 &hf_oran_mc_scale_re_mask_re3,
3578 &hf_oran_mc_scale_re_mask_re4,
3579 &hf_oran_mc_scale_re_mask_re5,
3580 &hf_oran_mc_scale_re_mask_re6,
3581 &hf_oran_mc_scale_re_mask_re7,
3582 &hf_oran_mc_scale_re_mask_re8,
3583 &hf_oran_mc_scale_re_mask_re9,
3584 &hf_oran_mc_scale_re_mask_re10,
3585 &hf_oran_mc_scale_re_mask_re11,
3586 &hf_oran_mc_scale_re_mask_re12,
3587 NULL((void*)0)
3588 };
3589 /* Same as above, but offset by 4 bits */
3590 static int * const remask_flags_even[] = {
3591 &hf_oran_mc_scale_re_mask_re1_even,
3592 &hf_oran_mc_scale_re_mask_re2_even,
3593 &hf_oran_mc_scale_re_mask_re3_even,
3594 &hf_oran_mc_scale_re_mask_re4_even,
3595 &hf_oran_mc_scale_re_mask_re5_even,
3596 &hf_oran_mc_scale_re_mask_re6_even,
3597 &hf_oran_mc_scale_re_mask_re7_even,
3598 &hf_oran_mc_scale_re_mask_re8_even,
3599 &hf_oran_mc_scale_re_mask_re9_even,
3600 &hf_oran_mc_scale_re_mask_re10_even,
3601 &hf_oran_mc_scale_re_mask_re11_even,
3602 &hf_oran_mc_scale_re_mask_re12_even,
3603 NULL((void*)0)
3604 };
3605
3606 /* RE Mask (12 bits) */
3607 proto_tree_add_bitmask_ret_uint64(set_tree, tvb, bit_offset / 8,
3608 (n % 2) ? hf_oran_mc_scale_re_mask_even : hf_oran_mc_scale_re_mask,
3609 ett_oran_mc_scale_remask,
3610 (n % 2) ? remask_flags_even : remask_flags, ENC_BIG_ENDIAN0x00000000, &mcScaleReMask);
3611 bit_offset += 12;
3612
3613 /* csf (1 bit) */
3614 bit_offset = dissect_csf(set_tree, tvb, bit_offset, ci_iq_width, &csf);
3615 /* mcScaleOffset (15 bits) */
3616 proto_item *ti = proto_tree_add_bits_ret_val(set_tree, hf_oran_mc_scale_offset, tvb, bit_offset, 15, &mcScaleOffset, ENC_BIG_ENDIAN0x00000000);
3617 uint16_t exponent = (mcScaleOffset >> 11) & 0x000f; /* m.s. 4 bits */
3618 uint16_t mantissa = mcScaleOffset & 0x07ff; /* l.s. 11 bits */
3619 float mcScaleOffset_value = ((float)mantissa/(1<<11)) * ((float)1.0 / (1 << exponent));
3620 proto_item_append_text(ti, " (%f)", mcScaleOffset_value);
3621 bit_offset += 15;
3622
3623 section_mod_compr_config_t* sect_config = get_mod_compr_section_to_write(state, sectionId);
3624
3625 /* Record this config */
3626 if (sect_config && sect_config->num_configs < MAX_MOD_COMPR_CONFIGS12) {
3627 unsigned i = sect_config->num_configs;
3628 sect_config->configs[i].mod_compr_re_mask = (uint16_t)mcScaleReMask;
3629 sect_config->configs[i].mod_compr_csf = csf;
3630 sect_config->configs[i].mod_compr_scaler = mcScaleOffset_value;
3631 sect_config->num_configs++;
3632 }
3633
3634 /* Summary */
3635 proto_item_set_len(set_ti, (bit_offset+7)/8 - set_start_offset);
3636 proto_item_append_text(set_ti, " (mcScaleReMask=0x%03x csf=%5s mcScaleOffset=%f)",
3637 (unsigned)mcScaleReMask, tfs_get_true_false(csf)tfs_get_string(csf, ((void*)0)), mcScaleOffset_value);
3638 }
3639
3640 proto_item_append_text(extension_ti, " (%u sets)", sets);
3641
3642 /* Reserved (variable-length) */
3643 if (reserved_bits) {
3644 proto_tree_add_bits_item(extension_tree, hf_oran_reserved, tvb, bit_offset, reserved_bits, ENC_BIG_ENDIAN0x00000000);
3645 bit_offset += reserved_bits;
3646 }
3647
3648 offset = bit_offset/8;
3649 break;
3650 }
3651
3652 case 6: /* SE 6: Non-contiguous PRB allocation in time and frequency domain */
3653 {
3654 /* numSymbol not used in this case */
3655 if (numsymbol_ti && !numsymbol_ignored) {
3656 proto_item_append_text(numsymbol_ti, " (ignored)");
3657 numsymbol_ignored = true1;
3658 }
3659
3660 /* Will update ext6 recorded info */
3661 ext11_settings.ext6_set = true1;
3662
3663 /* repetition */
3664 proto_tree_add_bits_item(extension_tree, hf_oran_se6_repetition, tvb, offset*8, 1, ENC_BIG_ENDIAN0x00000000);
3665 /* rbgSize (PRBs per bit set in rbgMask) */
3666 uint32_t rbgSize;
3667 proto_item *rbg_size_ti;
3668 rbg_size_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_rbgSize, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &rbgSize);
3669 if (rbgSize == 0) {
3670 /* N.B. this is only true if "se6-rb-bit-supported" is set... */
3671 expert_add_info(pinfo, rbg_size_ti, &ei_oran_rbg_size_reserved);
3672 }
3673 /* rbgMask (28 bits) */
3674 uint32_t rbgMask;
3675 proto_item *rbgmask_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_rbgMask, tvb, offset, 4, ENC_BIG_ENDIAN0x00000000, &rbgMask);
3676 if (rbgSize == 0) {
3677 proto_item_append_text(rbgmask_ti, " (value ignored since rbgSize is 0)");
3678 }
3679
3680 /* TODO: if receiver detects non-zero bits outside the valid range, those shall be ignored. */
3681 offset += 4;
3682 /* priority */
3683 proto_tree_add_item(extension_tree, hf_oran_noncontig_priority, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3684 /* symbolMask */
3685 offset = dissect_symbolmask(tvb, extension_tree, offset, NULL((void*)0), NULL((void*)0));
3686
3687 /* Look up rbg_size enum -> value */
3688 switch (rbgSize) {
3689 case 0:
3690 /* N.B. reserved, but covered above with expert info (would remain 0) */
3691 break;
3692 case 1:
3693 ext11_settings.ext6_rbg_size = 1; break;
3694 case 2:
3695 ext11_settings.ext6_rbg_size = 2; break;
3696 case 3:
3697 ext11_settings.ext6_rbg_size = 3; break;
3698 case 4:
3699 ext11_settings.ext6_rbg_size = 4; break;
3700 case 5:
3701 ext11_settings.ext6_rbg_size = 6; break;
3702 case 6:
3703 ext11_settings.ext6_rbg_size = 8; break;
3704 case 7:
3705 ext11_settings.ext6_rbg_size = 16; break;
3706 /* N.B., encoded in 3 bits, so no other values are possible */
3707 }
3708
3709 /* Set to looked-up value */
3710 rbgSize = ext11_settings.ext6_rbg_size;
3711
3712 uint32_t lastRbgid = 0;
3713 if (rbgSize != 0) {
3714 /* The O-DU shall not use combinations of startPrbc, numPrbc and rbgSize leading to a value of lastRbgid larger than 27 */
3715 /* i.e., leftmost bit used should not need to go off left end of rbgMask! */
3716 lastRbgid = (uint32_t)ceil((numPrbc + (startPrbc % rbgSize)) / (float)rbgSize) - 1;
3717 if (lastRbgid > 27) {
3718 expert_add_info_format(pinfo, rbg_size_ti, &ei_oran_lastRbdid_out_of_range,
3719 "SE6: rbgSize (%u) not compatible with startPrbc(%u) and numPrbc(%u)",
3720 rbgSize, startPrbc, numPrbc);
3721 break;
3722 }
3723 }
3724
3725 /* Record (and count) which bits are set in rbgMask */
3726 bool_Bool first_seen = false0;
3727 unsigned first_seen_pos=0, last_seen_pos=0;
3728 for (unsigned n=0; n < 28 && ext11_settings.ext6_num_bits_set < 28; n++) {
3729 if ((rbgMask >> n) & 0x01) {
3730 ext11_settings.ext6_bits_set[ext11_settings.ext6_num_bits_set++] = n;
3731 if (!first_seen) {
3732 first_seen = true1;
3733 first_seen_pos = n;
3734 }
3735 last_seen_pos = n;
3736 }
3737 }
3738
3739 /* Show how many bits were set in rbgMask */
3740 proto_item_append_text(rbgmask_ti, " (%u bits set)", ext11_settings.ext6_num_bits_set);
3741 /* Also, that is the range of bits */
3742 if (first_seen) {
3743 proto_item_append_text(rbgmask_ti, " (%u bits spread)", last_seen_pos-first_seen_pos+1);
3744
3745 /* Complain if last set bit is beyond lastRbgid */
3746 if (last_seen_pos > lastRbgid) {
3747 expert_add_info_format(pinfo, rbgmask_ti, &ei_oran_rbgMask_beyond_last_rbdid,
3748 "SE6: rbgMask (0x%07x) has bit %u set, but lastRbgId is %u",
3749 rbgMask, last_seen_pos, lastRbgid);
3750 }
3751 }
3752
3753 /* Also update prbs_for_st10_type5[] */
3754 if (sectionType == 10 && rbgSize != 0) {
3755 /* Unset all entries */
3756 memset(&prbs_for_st10_type5, 0, sizeof(prbs_for_st10_type5));
3757
3758 /* Work out which PRB first bit corresponds to */
3759 unsigned firstPrbStart = (startPrbc/rbgSize) * rbgSize;
3760
3761 /* Add PRBs corresponding to each bit set */
3762 for (unsigned n=0; n < 28 ; n++) {
3763 if ((rbgMask >> n) & 0x01) {
3764 /* Lazy way to clip any values that lie outside of range for section */
3765 for (unsigned p=0; p < rbgSize; p++) {
3766 unsigned start = firstPrbStart + (n*rbgSize);
3767 if ((start+p < MAX_PRBS273) && (start+p >= startPrbc) && (start+p <= startPrbc+numPrbc-1)) {
3768 prbs_for_st10_type5[start+p] = true1;
3769 }
3770 }
3771 }
3772 }
3773 }
3774
3775 break;
3776 }
3777
3778 case 7: /* SE 7: eAxC mask */
3779 /* Allow ST0 to address multiple eAxC_ID values for transmission blanking */
3780 proto_tree_add_item(extension_tree, hf_oran_eAxC_mask, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
3781 offset += 2;
3782 break;
3783
3784 case 8: /* SE 8: Regularization factor */
3785 proto_tree_add_item(extension_tree, hf_oran_regularizationFactor, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
3786 offset += 2;
3787 break;
3788
3789 case 9: /* SE 9: Dynamic Spectrum Sharing parameters */
3790 proto_tree_add_item(extension_tree, hf_oran_technology, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3791 offset += 1;
3792 add_reserved_field(extension_tree, hf_oran_reserved_8bits, tvb, offset, 1);
3793 offset += 1;
3794 break;
3795
3796 case 10: /* SE 10: Group configuration of multiple ports */
3797 {
3798 seen_se10 = true1;
3799
3800 /* beamGroupType */
3801 uint32_t beam_group_type = 0;
3802 proto_item *bgt_ti;
3803 bgt_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_beamGroupType,
3804 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &beam_group_type);
3805 proto_item_append_text(extension_ti, " (%s)", val_to_str_const(beam_group_type, beam_group_type_vals, "Unknown"));
3806
3807 /* numPortc */
3808 proto_tree_add_item_ret_uint(extension_tree, hf_oran_numPortc,
3809 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &numPortc);
3810 offset++;
3811
3812 /* Will append all beamId values to extension_ti, regardless of beamGroupType */
3813 unsigned n;
3814
3815 switch (beam_group_type) {
3816 case 0x0: /* common beam */
3817 case 0x1: /* beam matrix indication */
3818 /* Reserved byte */
3819 add_reserved_field(extension_tree, hf_oran_reserved_8bits, tvb, offset, 1);
3820 offset++;
3821
3822 /* Explain how entries are allocated */
3823 if (beam_group_type == 0x0) {
3824 proto_item_append_text(extension_ti, " (all %u ueid/Beam entries are %u)", numPortc, ueId);
3825 }
3826 else {
3827 /* 'numPortc' consecutive BeamIds from section header */
3828 proto_item_append_text(extension_ti, " (ueId/beam entries are %u -> %u)", ueId, ueId+numPortc);
3829 }
3830
3831 if (sectionType == 5) {
3832 /* These types are not allowed */
3833 expert_add_info_format(pinfo, bgt_ti, &ei_oran_se10_not_allowed,
3834 "SE10: beamGroupType %u is not allowed for section type 5", beam_group_type);
3835 }
3836 break;
3837
3838 case 0x2: /* beam vector listing */
3839 {
3840 proto_item_append_text(extension_ti, " [ ");
3841
3842 /* Beam listing vector case */
3843 /* Work out how many port beam entries there is room for */
3844 /* Using numPortC as visible in issue 18116 */
3845 for (n=0; n < numPortc; n++) {
3846 /* 1 reserved bit */
3847 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
3848
3849 /* port beam ID (or UEID) (15 bits) */
3850 uint32_t id;
3851 proto_item *beamid_or_ueid_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_beamId,
3852 tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &id);
3853 proto_item_append_text(beamid_or_ueid_ti, " port #%u beam ID (or UEId) %u", n, id);
3854 offset += 2;
3855
3856 if (id != 0x7fff) {
3857 if (number_of_ueids < MAX_UEIDS16) {
3858 ueids[number_of_ueids++] = id;
3859 }
3860 }
3861
3862 proto_item_append_text(extension_ti, "%u ", id);
3863 }
3864
3865 proto_item_append_text(extension_ti, "]");
3866 break;
3867 }
3868 case 0x3: /* beamId/ueId listing with associated port-list index */
3869 {
3870 proto_item_append_text(extension_ti, " [ ");
3871
3872 if (numPortc > 0) {
3873 /* first portListIndex is outside loop */
3874 uint32_t port_list_index;
3875 proto_item *pli_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_port_list_index, tvb,
3876 offset, 1, ENC_BIG_ENDIAN0x00000000, &port_list_index);
3877 if (port_list_index == 0) {
3878 /* Value 0 is reserved */
3879 expert_add_info(pinfo, pli_ti, &ei_oran_port_list_index_zero);
3880 }
3881 offset += 1;
3882
3883 for (n=0; n < numPortc-1; n++) {
3884 /* 1 reserved bit */
3885 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
3886
3887 /* port beam ID (or UEID) */
3888 uint32_t id;
3889 proto_item *beamid_or_ueid_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_beamId,
3890 tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &id);
3891 proto_item_append_text(beamid_or_ueid_ti, " port #%u beam ID (or UEId) %u", n, id);
3892 offset += 2;
3893
3894 if (id != 0x7fff) {
3895 if (number_of_ueids < MAX_UEIDS16) {
3896 ueids[number_of_ueids++] = id;
3897 }
3898 }
3899
3900 /* subsequent portListIndex */
3901 pli_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_port_list_index, tvb,
3902 offset, 1, ENC_BIG_ENDIAN0x00000000, &port_list_index);
3903 if (port_list_index == 0) {
3904 /* Value 0 is reserved */
3905 expert_add_info(pinfo, pli_ti, &ei_oran_port_list_index_zero);
3906 }
3907 offset += 1;
3908
3909 proto_item_append_text(extension_ti, "%u:%u ", port_list_index, id);
3910 }
3911 }
3912
3913 proto_item_append_text(extension_ti, "]");
3914 break;
3915 }
3916
3917
3918 default:
3919 /* Warning for unsupported/reserved value */
3920 expert_add_info(NULL((void*)0), bgt_ti, &ei_oran_se10_unknown_beamgrouptype);
3921 break;
3922 }
3923 break;
3924 }
3925
3926 case 11: /* SE 11: Flexible Weights Extension Type */
3927 {
3928 /* Hidden filter for bf */
3929 bf_ti = proto_tree_add_item(tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
3930 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
3931
3932 /* beamId in section header should be ignored. Guard against appending multiple times.. */
3933 if (section_beamId_ti && !section_beamId_ignored) {
3934 proto_item_append_text(section_beamId_ti, " (ignored)");
3935 section_beamId_ignored = true1;
3936 }
3937
3938 bool_Bool disableBFWs;
3939 uint32_t numBundPrb;
3940 bool_Bool rad;
3941
3942 /* disableBFWs */
3943 proto_tree_add_item_ret_boolean(extension_tree, hf_oran_disable_bfws,
3944 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &disableBFWs);
3945 if (disableBFWs) {
3946 proto_item_append_text(extension_ti, " (disableBFWs)");
3947 }
3948
3949 /* RAD */
3950 proto_tree_add_item_ret_boolean(extension_tree, hf_oran_rad,
3951 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &rad);
3952 /* bundleOffset (6 bits) */
3953 proto_tree_add_item(extension_tree, hf_oran_bundle_offset, tvb,
3954 offset, 1, ENC_BIG_ENDIAN0x00000000);
3955 offset++;
3956
3957 /* numBundPrb (number of prbs in each bundle) */
3958 proto_item *num_bund_prb_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_num_bund_prbs,
3959 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &numBundPrb);
3960 offset++;
3961 /* value zero is reserved.. */
3962 if (numBundPrb == 0) {
3963 expert_add_info(pinfo, num_bund_prb_ti, &ei_oran_reserved_numBundPrb);
3964 }
3965
3966 uint32_t num_bundles;
3967 bool_Bool orphaned_prbs = false0;
3968
3969 /* N.B. glibly assuming that Mu=1 */
3970 uint32_t symbol_count = (frameId*20 + slotId) * 14 + startSymbolId;
3971
3972 if (!disableBFWs) {
3973 /********************************************/
3974 /* Table 7.7.1.1-1 */
3975 /********************************************/
3976
3977 uint32_t bfwcomphdr_iq_width, bfwcomphdr_comp_meth;
3978 proto_item *comp_meth_ti = NULL((void*)0);
3979
3980 /* bfwCompHdr (2 subheaders - bfwIqWidth and bfwCompMeth)*/
3981 offset = dissect_bfwCompHdr(tvb, extension_tree, offset,
3982 &bfwcomphdr_iq_width, &bfwcomphdr_comp_meth, &comp_meth_ti);
3983
3984 /* Work out number of bundles, but take care not to divide by zero. */
3985 if (numBundPrb == 0) {
3986 break;
3987 }
3988
3989 /* Work out bundles! */
3990 ext11_work_out_bundles(startPrbc, numPrbc, numBundPrb, &ext11_settings);
3991 num_bundles = ext11_settings.num_bundles;
3992
3993 /* Add (complete) bundles */
3994 for (unsigned b=0; b < num_bundles; b++) {
3995 offset = dissect_bfw_bundle(tvb, extension_tree, pinfo, offset,
3996 comp_meth_ti, bfwcomphdr_comp_meth,
3997 NULL((void*)0) /* no ModCompr */,
3998 (ext11_settings.ext21_set) ?
3999 numPrbc :
4000 pref_num_bf_antennas,
4001 bfwcomphdr_iq_width,
4002 b, /* bundle number */
4003 ext11_settings.bundles[b].start,
4004 ext11_settings.bundles[b].end,
4005 ext11_settings.bundles[b].is_orphan,
4006 symbol_count,
4007 (link_planes_together && dl_data_section) ? &dl_data_section->details[index_to_use] : NULL((void*)0),
4008 tap_info);
4009 if (!offset) {
4010 break;
4011 }
4012 }
4013 if (num_bundles > 0) {
4014 /* Set flag from last bundle entry */
4015 orphaned_prbs = ext11_settings.bundles[num_bundles-1].is_orphan;
4016 }
4017 }
4018 else {
4019 /********************************************/
4020 /* Table 7.7.1.1-2 */
4021 /* No weights in this case */
4022 /********************************************/
4023
4024 /* Work out number of bundles, but take care not to divide by zero. */
4025 if (numBundPrb == 0) {
4026 break;
4027 }
4028
4029 ext11_work_out_bundles(startPrbc, numPrbc, numBundPrb, &ext11_settings);
4030 num_bundles = ext11_settings.num_bundles;
4031
4032 for (unsigned n=0; n < num_bundles; n++) {
4033 /* contInd */
4034 proto_tree_add_item(extension_tree, hf_oran_cont_ind,
4035 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4036 /* beamId */
4037 /* N.B., only added to tap_info if not 0 or ignored (after SEs seen) */
4038 uint32_t beam_id;
4039 proto_item *beamid_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_beam_id,
4040 tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &beam_id);
4041 if (!ext11_settings.bundles[n].is_orphan) {
4042 proto_item_append_text(beamid_ti, " (PRBs %3u-%3u) (Bundle %2u)",
4043 ext11_settings.bundles[n].start,
4044 ext11_settings.bundles[n].end,
4045 n);
4046 }
4047 else {
4048 orphaned_prbs = true1;
4049 proto_item_append_text(beamid_ti, " (PRBs %3u-%3u) (Orphaned PRBs)",
4050 ext11_settings.bundles[n].start,
4051 ext11_settings.bundles[n].end);
4052 }
4053 offset += 2;
4054
4055 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
4056 if (dl_data_section) {
4057 /* Set beamId only for range of PRBs */
4058 for (unsigned prb = ext11_settings.bundles[n].start; prb <= ext11_settings.bundles[n].end; prb++) {
4059 if (prb < 273) {
4060 dl_data_section->details[index_to_use].beamIds[prb] = beam_id;
4061 }
4062 }
4063 }
4064 }
4065
4066 /* Look for where BFWs were sent for this beamId */
4067 bfw_definition *definition;
4068
4069 wmem_tree_key_t key[3];
4070 key[0].length = 1;
4071 key[0].key = &pinfo->num;
4072 key[1].length = 1;
4073 key[1].key = &beam_id;
4074 key[2].length = 0;
4075 key[2].key = NULL((void*)0);
4076
4077 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
4078 /* Look up current result */
4079 definition = wmem_tree_lookup32(dl_beam_ids_defined, beam_id);
4080 if (definition != NULL((void*)0)) {
4081 /* Add to results table for this frame */
4082 wmem_tree_insert32_array(dl_beam_ids_results, key, definition);
4083 }
4084 }
4085 else {
4086 /* Look up from result table */
4087 definition = wmem_tree_lookup32_array(dl_beam_ids_results, key);
4088 }
4089
4090 /* Show link back to frame where/when beamId was defined */
4091 if (definition && definition->frame_defined != 0 && definition->frame_defined != pinfo->num) {
4092 proto_item *defined_ti = proto_tree_add_uint(extension_tree, hf_oran_bfws_frame_defined, tvb, offset, 0, definition->frame_defined);
4093 proto_item_set_generated(defined_ti);
4094 proto_item *since_ti = proto_tree_add_uint(extension_tree, hf_oran_bfws_symbols_since_defined, tvb, offset, 0,
4095 symbol_count - definition->symbol_when_defined);
4096 proto_item_set_generated(since_ti);
4097 }
4098 else {
4099 expert_add_info_format(NULL((void*)0), beamid_ti, &ei_oran_beamid_bfws_not_found,
4100 "ext11 for beamId %u and disableBFWs set, but can't find definition", beam_id);
4101 }
4102 }
4103
4104 }
4105
4106 /* Add summary to extension root */
4107 if (orphaned_prbs) {
4108 proto_item_append_text(extension_ti, " (%u full bundles + orphaned)", num_bundles-1);
4109 }
4110 else {
4111 proto_item_append_text(extension_ti, " (%u bundles)", num_bundles);
4112 }
4113 }
4114
4115 break;
4116
4117 case 12: /* SE 12: Non-Contiguous PRB Allocation with Frequency Ranges */
4118 {
4119 /* numSymbol not used in this case */
4120 if (numsymbol_ti && !numsymbol_ignored) {
4121 proto_item_append_text(numsymbol_ti, " (ignored)");
4122 numsymbol_ignored = true1;
4123 }
4124
4125 ext11_settings.ext12_set = true1;
4126
4127 /* priority */
4128 proto_tree_add_item(extension_tree, hf_oran_noncontig_priority, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4129
4130 /* symbolMask */
4131 offset = dissect_symbolmask(tvb, extension_tree, offset, NULL((void*)0), NULL((void*)0));
4132
4133 /* There are now 'R' pairs of (offStartPrb, numPrb) values. Fill extlen bytes with values. If last one is not set,
4134 should be populated with 0s. */
4135 uint32_t extlen_remaining_bytes = (extlen*4) - 4;
4136 uint8_t prb_index;
4137
4138 /* This is for ST10/ST11. First pair starts after frames signalled there */
4139 uint16_t st10_st11_offset = startPrbc + numPrbc;
4140
4141 for (prb_index = 1; extlen_remaining_bytes > 0; prb_index++)
4142 {
4143 /* Create a subtree for each pair */
4144 proto_item *pair_ti = proto_tree_add_string(extension_tree, hf_oran_frequency_range,
4145 tvb, offset, 2, "");
4146 proto_tree *pair_tree = proto_item_add_subtree(pair_ti, ett_oran_frequency_range);
4147
4148 /* offStartPrb */
4149 uint32_t off_start_prb;
4150 proto_tree_add_item_ret_uint(pair_tree, hf_oran_off_start_prb, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &off_start_prb);
4151 offset++;
4152
4153 /* numPrb */
4154 uint32_t num_prb;
4155 proto_tree_add_item_ret_uint(pair_tree, hf_oran_num_prb, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &num_prb);
4156 offset++;
4157
4158 extlen_remaining_bytes -= 2;
4159
4160 /* Last pair may be 0,0 if not used. Check for this */
4161 if ((extlen_remaining_bytes == 0) && (off_start_prb == 0) && (num_prb == 0)) {
4162 proto_item_append_text(pair_ti, " (not used)");
4163 }
4164 /* Add summary to pair root item, and configure details in ext11_settings */
4165 else {
4166 proto_item_append_text(pair_ti, "(%u) [%u : %u]",
4167 prb_index, off_start_prb, num_prb);
4168 proto_item_append_text(extension_ti, "[%u : %u]",
4169 off_start_prb, num_prb);
4170 if (ext11_settings.ext12_num_pairs < MAX_BFW_EXT12_PAIRS128) {
4171 ext11_settings.ext12_pairs[ext11_settings.ext12_num_pairs].off_start_prb = off_start_prb;
4172 ext11_settings.ext12_pairs[ext11_settings.ext12_num_pairs++].num_prb = num_prb;
4173 }
4174
4175 /* Also update PRBs to be covered for ST10 type 5 */
4176 /* Original range from section is added to.. */
4177 /* TODO: I don't think this is quite right.. */
4178 for (unsigned prb=st10_st11_offset+off_start_prb; prb < st10_st11_offset+off_start_prb+num_prb; prb++) {
4179 if (prb < MAX_PRBS273) {
4180 prbs_for_st10_type5[prb] = true1;
4181 }
4182 }
4183
4184 /* Any next pair will begin after this one */
4185 st10_st11_offset += (off_start_prb + num_prb);
4186 }
4187 }
4188 break;
4189 }
4190
4191 case 13: /* SE 13: PRB Allocation with Frequency Hopping */
4192 {
4193 /* Will update settings for ext11 */
4194 ext11_settings.ext13_set = true1;
4195
4196 uint32_t extlen_remaining_bytes = (extlen*4) - 2;
4197 uint8_t allocation_index;
4198
4199 unsigned prev_next_symbol_id = 0, prev_next_start_prbc = 0;
4200
4201 for (allocation_index = 1; extlen_remaining_bytes > 0; allocation_index++)
4202 {
4203 /* Subtree for allocation */
4204 proto_item *allocation_ti = proto_tree_add_string(extension_tree, hf_oran_prb_allocation,
4205 tvb, offset, 2, "");
4206 proto_tree *allocation_tree = proto_item_add_subtree(allocation_ti, ett_oran_prb_allocation);
4207
4208 /* Reserved (2 bits) */
4209 add_reserved_field(allocation_tree, hf_oran_reserved_2bits, tvb, offset, 1);
4210
4211 /* nextSymbolId (4 bits) */
4212 uint32_t next_symbol_id;
4213 proto_tree_add_item_ret_uint(allocation_tree, hf_oran_nextSymbolId, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &next_symbol_id);
4214
4215 /* nextStartPrbc (10 bits) */
4216 uint32_t next_start_prbc;
4217 proto_tree_add_item_ret_uint(allocation_tree, hf_oran_nextStartPrbc, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &next_start_prbc);
4218 offset += 2;
4219
4220 /* Add summary to allocation root item */
4221 proto_item_append_text(allocation_ti, "(%u) nextSymbolId=%3u, nextStartPrbc=%u",
4222 allocation_index, next_symbol_id, next_start_prbc);
4223
4224 /* Checking for duplicates (expected if e.g. had only 2 entries but extlen bytes still to fill */
4225 if ((allocation_index > 1) && (next_symbol_id == prev_next_symbol_id) && (next_start_prbc == prev_next_start_prbc)) {
4226 proto_item_append_text(allocation_ti, " (repeated - to fill up extlen)");
4227 }
4228 else {
4229 /* Add entry for configuring ext11. don't store out of range */
4230 if (ext11_settings.ext13_num_start_prbs < MAX_BFW_EXT13_ALLOCATIONS128) {
4231 ext11_settings.ext13_start_prbs[ext11_settings.ext13_num_start_prbs++] = next_start_prbc;
4232 }
4233 }
4234 prev_next_symbol_id = next_symbol_id;
4235 prev_next_start_prbc = next_start_prbc;
4236
4237 extlen_remaining_bytes -= 2;
4238 }
4239 break;
4240 }
4241
4242 case 14: /* SE 14: Nulling-layer Info. for ueId-based beamforming */
4243 /* Hidden filter for bf (DMRS BF) */
4244 bf_ti = proto_tree_add_item(tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
4245 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
4246
4247 if (!seen_se10) {
4248 proto_tree_add_item(extension_tree, hf_oran_nullLayerInd, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4249 offset += 1;
4250 add_reserved_field(extension_tree, hf_oran_reserved_8bits, tvb, offset, 1);
4251 offset += 1;
4252 }
4253 else {
4254 /* Loop over numPortc++1 (from SE 10) nullLayerInd fields */
4255 for (unsigned port=0; port < numPortc+1; port++) {
4256 proto_tree_add_item(extension_tree, hf_oran_nullLayerInd, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4257 offset += 1;
4258 }
4259 }
4260 break;
4261
4262 case 15: /* SE 15: Mixed-numerology Info. for ueId-based beamforming */
4263 {
4264 /* frameStructure */
4265 offset = dissect_frame_structure(extension_tree, tvb, offset,
4266 subframeId, slotId);
4267 /* freqOffset */
4268 proto_tree_add_item(extension_tree, hf_oran_freqOffset, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
4269 offset += 3;
4270 /* cpLength */
4271 proto_item *cplength_ti = proto_tree_add_item(extension_tree, hf_oran_cpLength, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4272 if (sectionType != 0 && sectionType != 3) {
4273 proto_item_append_text(cplength_ti, " (ignored - used only with ST0 and ST3)");
4274 }
4275 offset += 2;
4276 break;
4277 }
4278
4279 case 16: /* SE 16: Antenna mapping in UE channel information based UL beamforming */
4280 {
4281 /* Just filling available bytes with antMask entries.
4282 N.B., if SE 10 also used, could associate each antMask with (beamId or UEId) RX eAxC */
4283 uint32_t extlen_remaining_bytes = (extlen*4) - 2;
4284 unsigned num_ant_masks = extlen_remaining_bytes / 8;
4285 for (unsigned n=0; n < num_ant_masks; n++) {
4286 proto_item *ti = proto_tree_add_item(extension_tree, hf_oran_antMask, tvb, offset, 8, ENC_BIG_ENDIAN0x00000000);
4287 proto_item_append_text(ti, " (RX eAxC #%u)", n+1);
4288 offset += 8;
4289 }
4290 break;
4291 }
4292
4293 case 17: /* SE 17: Indication of user port group. Applies to ST5 + SE10 with group type 1 (beam matrix indication) */
4294 {
4295 uint32_t extlen_remaining_bytes = (extlen*4) - 2;
4296 uint32_t end_bit = (offset+extlen_remaining_bytes) * 8;
4297 uint32_t ueid_index = 1;
4298
4299 /* "the preceding Section Type and extension messages implicitly provide the number of scheduled users" */
4300 for (uint32_t bit_offset=offset*8; (bit_offset < end_bit) && (ueid_index <= number_of_ueids); bit_offset+=4, ueid_index++) {
4301 /* numUeId (Number of UE Ids per user) */
4302 proto_item *ti = proto_tree_add_bits_item(extension_tree, hf_oran_num_ueid, tvb, bit_offset, 4, ENC_BIG_ENDIAN0x00000000);
4303 /* TODO: show ueids[ueid_index] here too? */
4304 proto_item_append_text(ti, " (user #%u)", ueid_index);
4305 }
4306 break;
4307 }
4308
4309 case 18: /* SE 18: Uplink transmission management */
4310 /* transmissionWindowOffset */
4311 proto_tree_add_item(extension_tree, hf_oran_transmissionWindowOffset, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4312 offset += 2;
4313 /* reserved (2 bits) */
4314 add_reserved_field(extension_tree, hf_oran_reserved_2bits, tvb, offset, 1);
4315 /* transmissionWindowSize (14 bits) */
4316 proto_tree_add_item(extension_tree, hf_oran_transmissionWindowSize, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4317 offset += 2;
4318
4319 /* reserved (6 bits) */
4320 add_reserved_field(extension_tree, hf_oran_reserved_6bits, tvb, offset, 1);
4321 /* toT (2 bits) */
4322 proto_tree_add_item(extension_tree, hf_oran_toT, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4323 offset += 1;
4324 break;
4325
4326 case 19: /* SE 19: Compact beamforming information for multiple port */
4327 {
4328 /* beamId in section header should be ignored. Guard against appending multiple times.. */
4329 if (section_beamId_ti && !section_beamId_ignored) {
4330 proto_item_append_text(section_beamId_ti, " (ignored)");
4331 section_beamId_ignored = true1;
4332 }
4333
4334 /* numSymbol not used in this case */
4335 if (numsymbol_ti && !numsymbol_ignored) {
4336 proto_item_append_text(numsymbol_ti, " (ignored)");
4337 numsymbol_ignored = true1;
4338 }
4339
4340 /* disableBFWs */
4341 bool_Bool disableBFWs;
4342 proto_tree_add_item_ret_boolean(extension_tree, hf_oran_disable_bfws,
4343 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &disableBFWs);
4344 if (disableBFWs) {
4345 proto_item_append_text(extension_ti, " (disableBFWs)");
4346 }
4347 /* repetition (1 bit) */
4348 uint64_t repetition;
4349 proto_tree_add_bits_ret_val(extension_tree, hf_oran_se19_repetition, tvb, (offset*8)+1, 1, &repetition, ENC_BIG_ENDIAN0x00000000);
4350 /* numPortc (6 bits) */
4351 proto_tree_add_item_ret_uint(extension_tree, hf_oran_numPortc,
4352 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &numPortc);
4353 offset++;
4354
4355 /* priority (2 bits) */
4356 proto_tree_add_item(extension_tree, hf_oran_noncontig_priority, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4357 /* symbolMask (14 bits) */
4358 offset = dissect_symbolmask(tvb, extension_tree, offset, NULL((void*)0), NULL((void*)0));
4359
4360 uint32_t bfwcomphdr_iq_width, bfwcomphdr_comp_meth;
4361 proto_item *comp_meth_ti = NULL((void*)0);
4362
4363 if (!repetition) {
4364
4365 if (!disableBFWs) {
4366 /* bfwCompHdr */
4367 offset = dissect_bfwCompHdr(tvb, extension_tree, offset,
4368 &bfwcomphdr_iq_width, &bfwcomphdr_comp_meth, &comp_meth_ti);
4369 }
4370
4371 /* Add entries for each port */
4372 for (unsigned port=0; port < numPortc; port++) {
4373
4374 /* Create subtree for port entry*/
4375 int port_start_offset = offset;
4376 proto_item *port_ti = proto_tree_add_string_format(extension_tree, hf_oran_ext19_port,
4377 tvb, offset, 0,
4378 "", "Port %u: ", port);
4379 proto_tree *port_tree = proto_item_add_subtree(port_ti, ett_oran_ext19_port);
4380
4381 /* Reserved (4 bits) */
4382 add_reserved_field(port_tree, hf_oran_reserved_4bits, tvb, offset, 1);
4383 /* portReMask (12 bits) */
4384 proto_tree_add_item(port_tree, hf_oran_portReMask, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4385 offset += 2;
4386
4387 /* Reserved (2 bits) */
4388 add_reserved_field(port_tree, hf_oran_reserved_2bits, tvb, offset, 1);
4389 /* portSymbolMask (14 bits) */
4390 proto_tree_add_item(port_tree, hf_oran_portSymbolMask, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4391 offset += 2;
4392
4393 /* Reserved (1 bit) */
4394 add_reserved_field(port_tree, hf_oran_reserved_1bit, tvb, offset, 1);
4395 /* beamID (15 bits) */
4396 uint16_t beamId;
4397 proto_tree_add_item_ret_uint16(port_tree, hf_oran_beamId, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &beamId);
4398 proto_item_append_text(port_ti, " (beamId=%u)", beamId);
4399 offset += 2;
4400
4401 /* No weights present */
4402 if (!disableBFWs) {
4403 /*******************************************************************/
4404 /* Table 7.7.19.1-1 (there is no part -2 for disableBFWs case...), */
4405 /* but for SE 11, bfwCompParam was only present for !disableBFWs */
4406 /*******************************************************************/
4407
4408 /* bfwCompParam */
4409 bool_Bool compression_method_supported = false0;
4410 uint32_t exponent = 0;
4411 unsigned num_trx_entries = 0;
4412 uint16_t *trx;
4413 offset = dissect_bfwCompParam(tvb, port_tree, pinfo, offset, comp_meth_ti,
4414 &bfwcomphdr_comp_meth, &exponent, &compression_method_supported,
4415 &num_trx_entries, &trx);
4416
4417 int bit_offset = offset*8;
4418 int bfw_offset;
4419
4420 /* Add weights for each TRX */
4421 unsigned trx_to_add = (num_trx_entries==0) ? pref_num_bf_antennas : num_trx_entries;
4422 for (unsigned b=0; b < trx_to_add; b++) {
4423
4424 uint16_t trx_index = (num_trx_entries) ? trx[b] : b+1;
4425
4426 /* Create BFW subtree */
4427 bfw_offset = bit_offset / 8;
4428 uint8_t bfw_extent = ((bit_offset + (bfwcomphdr_iq_width*2)) / 8) - bfw_offset;
4429 proto_item *bfw_ti = proto_tree_add_string_format(port_tree, hf_oran_bfw,
4430 tvb, bfw_offset, bfw_extent,
4431 "", "TRX %u: (", trx_index);
4432 proto_tree *bfw_tree = proto_item_add_subtree(bfw_ti, ett_oran_bfw);
4433
4434 /* I */
4435 uint32_t bits = tvb_get_bits32(tvb, bit_offset, bfwcomphdr_iq_width, ENC_BIG_ENDIAN0x00000000);
4436 float value = decompress_value(bits, bfwcomphdr_comp_meth, bfwcomphdr_iq_width, exponent, NULL((void*)0) /* no ModCompr */, 0 /* RE */);
4437 /* Add to tree. */
4438 proto_tree_add_float_format_value(bfw_tree, hf_oran_bfw_i, tvb, bit_offset/8,
4439 (bfwcomphdr_iq_width+7)/8, value, "#%u=%f", b, value);
4440 bit_offset += bfwcomphdr_iq_width;
4441 proto_item_append_text(bfw_ti, "I%u=%f ", b, value);
4442
4443 /* Q */
4444 bits = tvb_get_bits32(tvb, bit_offset, bfwcomphdr_iq_width, ENC_BIG_ENDIAN0x00000000);
4445 value = decompress_value(bits, bfwcomphdr_comp_meth, bfwcomphdr_iq_width, exponent, NULL((void*)0) /* no ModCompr */, 0 /* RE */);
4446 /* Add to tree. */
4447 proto_tree_add_float_format_value(bfw_tree, hf_oran_bfw_q, tvb, bit_offset/8,
4448 (bfwcomphdr_iq_width+7)/8, value, "#%u=%f", b, value);
4449 bit_offset += bfwcomphdr_iq_width;
4450 proto_item_append_text(bfw_ti, "Q%u=%f)", b, value);
4451 }
4452
4453 offset = (bit_offset+7)/8;
4454 }
4455 else {
4456 /* No weights... */
4457 }
4458
4459 /* Set length of this port entry */
4460 proto_item_set_len(port_ti, offset-port_start_offset);
4461 }
4462 }
4463 break;
4464 }
4465
4466 case 20: /* SE 20: Puncturing extension */
4467 {
4468 /* numPuncPatterns */
4469 uint32_t numPuncPatterns;
4470 proto_tree_add_item_ret_uint(extension_tree, hf_oran_numPuncPatterns, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &numPuncPatterns);
4471 offset += 1;
4472
4473 /* Add each puncturing pattern */
4474 for (uint32_t n=0; n < numPuncPatterns; n++) {
4475 unsigned pattern_start_offset = offset;
4476
4477 /* Subtree for this puncturing pattern */
4478 proto_item *pattern_ti = proto_tree_add_string_format(extension_tree, hf_oran_puncPattern,
4479 tvb, offset, 0,
4480 "", "Puncturing Pattern: %u/%u", n+1, numPuncPatterns);
4481 proto_tree *pattern_tree = proto_item_add_subtree(pattern_ti, ett_oran_punc_pattern);
4482
4483 /* SymbolMask (14 bits) */
4484 proto_tree_add_item(pattern_tree, hf_oran_symbolMask_ext20, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4485 offset += 1;
4486
4487 uint32_t startPuncPrb, numPuncPrb;
4488
4489 /* startPuncPrb (10 bits) */
4490 proto_tree_add_item_ret_uint(pattern_tree, hf_oran_startPuncPrb, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &startPuncPrb);
4491 offset += 2;
4492 /* numPuncPrb (8 bits) */
4493 proto_tree_add_item_ret_uint(pattern_tree, hf_oran_numPuncPrb, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &numPuncPrb);
4494 offset += 1;
4495
4496 proto_item_append_text(pattern_ti, " [%u->%u]", startPuncPrb, startPuncPrb+numPuncPrb-1);
4497
4498 /* Make a hole in range of PRBs to report */
4499 for (unsigned p=startPuncPrb; p < startPuncPrb+numPuncPrb; p++) {
4500 if (p < MAX_PRBS273) {
4501 prbs_for_st10_type5[p] = false0;
4502 }
4503 }
4504
4505 /* puncReMask (12 bits) */
4506 proto_tree_add_item(pattern_tree, hf_oran_puncReMask, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4507 offset += 1;
4508 /* rb (1 bit) */
4509 proto_item *rb_ti = proto_tree_add_item(pattern_tree, hf_oran_rb, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4510 /* reserved (1 bit) */
4511 add_reserved_field(pattern_tree, hf_oran_reserved_bit5, tvb, offset, 1);
4512 /* multiSDScope (1 bit) */
4513 proto_tree_add_item(pattern_tree, hf_oran_multiSDScope, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4514 /* rbgIncl (1 bit) */
4515 bool_Bool rbgIncl;
4516 proto_tree_add_item_ret_boolean(pattern_tree, hf_oran_RbgIncl, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &rbgIncl);
4517 offset += 1;
4518
4519 if (rbgIncl) {
4520 /* reserved (1 bit) */
4521 add_reserved_field(pattern_tree, hf_oran_reserved_1bit, tvb, offset, 1);
4522 /* rbgSize(3 bits) */
4523 proto_tree_add_item(pattern_tree, hf_oran_rbgSize, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4524 /* rbgMask (28 bits) */
4525 proto_tree_add_item(pattern_tree, hf_oran_rbgMask, tvb, offset, 4, ENC_BIG_ENDIAN0x00000000);
4526 offset += 4;
4527
4528 proto_item_append_text(rb_ti, " (ignored)");
4529 }
4530
4531 proto_item_set_len(pattern_ti, offset-pattern_start_offset);
4532 }
4533
4534 break;
4535 }
4536 case 21: /* SE 21: Variable PRB group size for channel information */
4537 {
4538 /* ciPrbGroupSize */
4539 uint32_t ci_prb_group_size;
4540 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);
4541 offset += 1;
4542
4543 switch (ci_prb_group_size) {
4544 case 0:
4545 case 1:
4546 case 255:
4547 /* Reserved value */
4548 expert_add_info_format(pinfo, prb_group_size_ti, &ei_oran_ci_prb_group_size_reserved,
4549 "SE 11 ciPrbGroupSize is reserved value %u - must be 2-254",
4550 ci_prb_group_size);
4551 break;
4552 default:
4553 /* This value affects how SE 11 is interpreted */
4554 ext11_settings.ext21_set = true1;
4555 ext11_settings.ext21_ci_prb_group_size = ci_prb_group_size;
4556
4557 if (numPrbc == 0) {
4558 expert_add_info(pinfo, numprbc_ti, &ei_oran_numprbc_ext21_zero);
4559 }
4560 break;
4561 }
4562
4563 /* reserved (6 bits) */
4564 add_reserved_field(extension_tree, hf_oran_reserved_6bits, tvb, offset, 1);
4565
4566 /* prgSize (2 bits). Interpretation depends upon section type (5 or 6), but also mplane parameters? */
4567 if (sectionType == SEC_C_UE_SCHED) { /* Section Type 5 */
4568 proto_tree_add_item(extension_tree, hf_oran_prg_size_st5, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4569 }
4570 else if (sectionType == SEC_C_CH_INFO) { /* Section Type 6 */
4571 proto_tree_add_item(extension_tree, hf_oran_prg_size_st6, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4572 }
4573 offset += 1;
4574 break;
4575 }
4576
4577 case 22: /* SE 22: ACK/NACK request */
4578 {
4579 uint32_t ack_nack_req_id;
4580 proto_tree_add_item_ret_uint(extension_tree, hf_oran_ack_nack_req_id, tvb, offset, 2,
4581 ENC_BIG_ENDIAN0x00000000, &ack_nack_req_id);
4582 offset += 2;
4583
4584 if (state) {
4585 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
4586 /* Add this request into conversation state on first pass */
4587 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)))
;
4588 request_details->request_frame_number = pinfo->num;
4589 request_details->request_frame_time = pinfo->abs_ts;
4590 request_details->requestType = SE22;
4591 /* Insert into flow's tree */
4592 wmem_tree_insert32(state->ack_nack_requests, ack_nack_req_id, request_details);
4593 }
4594 else {
4595 /* Try to link forward to ST8 response */
4596 ack_nack_request_t *response = wmem_tree_lookup32(state->ack_nack_requests,
4597 ack_nack_req_id);
4598 if (response) {
4599 show_link_to_acknack_response(extension_tree, tvb, pinfo, response);
4600 }
4601 }
4602 }
4603 break;
4604 }
4605
4606 case 23: /* SE 23: Arbitrary symbol pattern modulation compression parameters */
4607 {
4608 /* Green common header */
4609
4610 /* numSymPrbPattern (4 bits) */
4611 uint32_t num_sym_prb_pattern;
4612 proto_tree_add_item_ret_uint(extension_tree, hf_oran_num_sym_prb_pattern, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &num_sym_prb_pattern);
4613 /* reserved (3 bits) */
4614 add_reserved_field(extension_tree, hf_oran_reserved_bits456, tvb, offset, 1);
4615 /* prbMode (1 bit) */
4616 bool_Bool prb_mode;
4617 proto_tree_add_item_ret_boolean(extension_tree, hf_oran_prb_mode, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &prb_mode);
4618 offset += 1;
4619
4620 /* reserved (8 bits) */
4621 add_reserved_field(extension_tree, hf_oran_reserved_8bits, tvb, offset, 1);
4622 offset += 1;
4623
4624 /* Dissect each SymPrbPattern */
4625 for (uint32_t n=0; n < num_sym_prb_pattern; n++) {
4626
4627 /* Subtree */
4628 proto_item *pattern_ti = proto_tree_add_string_format(extension_tree, hf_oran_sym_prb_pattern,
4629 tvb, offset, 1, "",
4630 prb_mode ? "PRB-BLOCK" : "PRB-MASK");
4631 proto_tree *pattern_tree = proto_item_add_subtree(pattern_ti, ett_oran_sym_prb_pattern);
4632
4633
4634 /* Orange part */
4635
4636 /* Reserved (2 bits) */
4637 add_reserved_field(pattern_tree, hf_oran_reserved_2bits, tvb, offset, 1);
4638 /* symMask (14 bits) */
4639 proto_tree_add_item(pattern_tree, hf_oran_sym_mask, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4640 offset += 2;
4641 /* numMcScaleOffset (4 bits) */
4642 uint32_t numMcScaleOffset;
4643 proto_tree_add_item_ret_uint(pattern_tree, hf_oran_num_mc_scale_offset, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &numMcScaleOffset);
4644
4645 if (!prb_mode) { /* PRB-MASK */
4646 /* prbPattern (4 bits) */
4647 proto_tree_add_item(pattern_tree, hf_oran_prb_pattern, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4648 offset += 1;
4649 /* reserved (8 bits) */
4650 add_reserved_field(pattern_tree, hf_oran_reserved_8bits, tvb, offset, 1);
4651 offset += 1;
4652 }
4653 else { /* PRB-BLOCK */
4654 /* prbBlkOffset (8 bits) */
4655 proto_tree_add_item(pattern_tree, hf_oran_prb_block_offset, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4656 offset += 1;
4657 /* prbBlkSize (4 bits) */
4658 proto_tree_add_item(pattern_tree, hf_oran_prb_block_size, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4659 offset += 1;
4660 }
4661
4662 /* Yellowish part */
4663 if (prb_mode) { /* PRB-BLOCK */
4664 /* prbBlkSize (4 bits) */
4665 proto_tree_add_item(pattern_tree, hf_oran_prb_block_size, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4666 }
4667 else {
4668 /* reserved (4 bits) */
4669 add_reserved_field(pattern_tree, hf_oran_reserved_4bits, tvb, offset, 1);
4670 }
4671
4672 for (unsigned c=0; c < numMcScaleOffset; c++) {
4673
4674 if (c > 0) {
4675 /* reserved (4 bits) */
4676 add_reserved_field(pattern_tree, hf_oran_reserved_4bits, tvb, offset, 1);
4677 }
4678
4679 static int * const remask_flags_even[] = {
4680 &hf_oran_mc_scale_re_mask_re1_even,
4681 &hf_oran_mc_scale_re_mask_re2_even,
4682 &hf_oran_mc_scale_re_mask_re3_even,
4683 &hf_oran_mc_scale_re_mask_re4_even,
4684 &hf_oran_mc_scale_re_mask_re5_even,
4685 &hf_oran_mc_scale_re_mask_re6_even,
4686 &hf_oran_mc_scale_re_mask_re7_even,
4687 &hf_oran_mc_scale_re_mask_re8_even,
4688 &hf_oran_mc_scale_re_mask_re9_even,
4689 &hf_oran_mc_scale_re_mask_re10_even,
4690 &hf_oran_mc_scale_re_mask_re11_even,
4691 &hf_oran_mc_scale_re_mask_re12_even,
4692 NULL((void*)0)
4693 };
4694
4695 /* mcScaleReMask (12 bits). Defines which REs the following csf and mcScaleOffset apply to */
4696 uint64_t mcScaleReMask, mcScaleOffset;
4697 proto_tree_add_bitmask_ret_uint64(pattern_tree, tvb, offset,
4698 hf_oran_mc_scale_re_mask_even,
4699 ett_oran_mc_scale_remask,
4700 remask_flags_even, ENC_BIG_ENDIAN0x00000000, &mcScaleReMask);
4701
4702 offset += 2;
4703 /* csf (1 bit) */
4704 bool_Bool csf;
4705 dissect_csf(pattern_tree, tvb, offset*8, ci_iq_width, &csf);
4706 /* mcScaleOffset (15 bits) */
4707 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);
4708 uint16_t exponent = (mcScaleOffset >> 11) & 0x000f; /* m.s. 4 bits */
4709 uint16_t mantissa = mcScaleOffset & 0x07ff; /* l.s. 11 bits */
4710 float mcScaleOffset_value = ((float)mantissa/(1<<11)) * ((float)1.0 / (1 << exponent));
4711 proto_item_append_text(ti, " (%f)", mcScaleOffset_value);
4712
4713 offset += 2;
4714
4715 /* Record this config. */
4716 /* TODO: at some point, will also want to store/use PRB + symbol filters */
4717 section_mod_compr_config_t* sect_config = get_mod_compr_section_to_write(state, sectionId);
4718
4719 if (sect_config && sect_config->num_configs < MAX_MOD_COMPR_CONFIGS12) {
4720 unsigned i = sect_config->num_configs;
4721 sect_config->configs[i].mod_compr_re_mask = (uint16_t)mcScaleReMask;
4722 sect_config->configs[i].mod_compr_csf = csf;
4723 sect_config->configs[i].mod_compr_scaler = mcScaleOffset_value;
4724 sect_config->num_configs++;
4725 }
4726 }
4727
4728 proto_item_set_end(pattern_ti, tvb, offset);
4729 }
4730 break;
4731 }
4732
4733 case 24: /* SE 24: PUSCH DMRS configuration */
4734 {
4735 /* Hidden filter for bf (DMRS BF) */
4736 bf_ti = proto_tree_add_item(tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
4737 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
4738
4739 /* alpnPerSym (1 bit) */
4740 proto_tree_add_item(extension_tree, hf_oran_alpn_per_sym, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4741 /* antDmrsSnr (1 bit) */
4742 proto_tree_add_item(extension_tree, hf_oran_ant_dmrs_snr, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4743 /* reserved (1 bit) */
4744 add_reserved_field(extension_tree, hf_oran_reserved_bit2, tvb, offset, 1);
4745 /* userGroupSize (5 bits) */
4746 uint32_t user_group_size;
4747 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);
4748 if (user_group_size == 0) {
4749 proto_item_append_text(ugs_ti, " (not used)");
4750 }
4751 else if (user_group_size > 12) {
4752 proto_item_append_text(ugs_ti, " (reserved)");
4753 }
4754 offset += 1;
4755 /* userGroupId (8 bits)*/
4756 uint32_t user_group_id;
4757 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);
4758 if (user_group_id == 0) {
4759 /* TODO: Value 0 can happen in several cases, described in 7.7.24.7.. */
4760 }
4761 if (user_group_id == 255) {
4762 /* Value 255 is reserved */
4763 expert_add_info(pinfo, ugi_ti, &ei_oran_user_group_id_reserved_value);
4764 }
4765 offset += 1;
4766
4767 bool_Bool seen_value_to_inherit = false0;
4768 bool_Bool inherited_config_has_transform_precoding = false0;
4769 int dmrs_configs_seen = 0;
4770
4771 /* Dissect each entry until reach number of configured ueIds (or run out of extlen bytes..) */
4772 uint32_t ueid_index = 0;
4773 while ((offset < (extension_start_offset + extlen*4)) && (ueid_index < number_of_ueids)) {
4774 dmrs_configs_seen++;
4775
4776 /* Subtree */
4777 proto_item *entry_ti = proto_tree_add_string_format(extension_tree, hf_oran_dmrs_entry,
4778 tvb, offset, 0, "",
4779 "Entry");
4780 proto_tree *entry_tree = proto_item_add_subtree(entry_ti, ett_oran_dmrs_entry);
4781
4782 /* entryType (3 bits) */
4783 uint32_t entry_type;
4784 proto_item *entry_type_ti;
4785 entry_type_ti = proto_tree_add_item_ret_uint(entry_tree, hf_oran_entry_type, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &entry_type);
4786 if (entry_type > 3) {
4787 proto_item_append_text(entry_type_ti, " (reserved)");
4788 }
4789
4790 /* dmrsPortNumber (5 bits). Values 0-11 allowed */
4791 unsigned int dmrs_port_number;
4792 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);
4793 if (dmrs_port_number > 11) {
4794 proto_item_append_text(dpn_ti, " (12-31 are reserved)");
4795 }
4796 offset += 1;
4797
4798 /* What follows depends upon entryType */
4799 switch (entry_type) {
4800 case 0: /* dmrsPortNumber config same as previous, ueId ueIdReset=0 */
4801 case 1: /* dmrsPortNumber config same as previous, ueId ueIdReset=1 */
4802 /* No further fields for these */
4803 /* Error here if no previous values to inherit!! */
4804 if (!seen_value_to_inherit) {
4805 expert_add_info_format(pinfo, entry_type_ti, &ei_oran_se24_nothing_to_inherit,
4806 "SE24: have seen entry type %u, but no previous config (type 2 or 3) to inherit config from", entry_type);
4807
4808 }
4809 /* TODO: would be useful to repeat whole inherited config here? */
4810 break;
4811
4812 case 2: /* transform precoding disabled */
4813 case 3: /* transform precoding enabled */
4814 {
4815 /* Type 2/3 are very similar.. */
4816
4817 /* ueIdReset (1 bit) */
4818 proto_tree_add_item(entry_tree, hf_oran_ueid_reset, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4819 /* posMeas (1 bit) */
4820 proto_tree_add_item(entry_tree, hf_oran_pos_meas, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4821
4822 /* dmrsSymbolMask (14 bits) */
4823 static int * const dmrs_symbol_mask_flags[] = {
4824 &hf_oran_dmrs_symbol_mask_s13,
4825 &hf_oran_dmrs_symbol_mask_s12,
4826 &hf_oran_dmrs_symbol_mask_s11,
4827 &hf_oran_dmrs_symbol_mask_s10,
4828 &hf_oran_dmrs_symbol_mask_s9,
4829 &hf_oran_dmrs_symbol_mask_s8,
4830 &hf_oran_dmrs_symbol_mask_s7,
4831 &hf_oran_dmrs_symbol_mask_s6,
4832 &hf_oran_dmrs_symbol_mask_s5,
4833 &hf_oran_dmrs_symbol_mask_s4,
4834 &hf_oran_dmrs_symbol_mask_s3,
4835 &hf_oran_dmrs_symbol_mask_s2,
4836 &hf_oran_dmrs_symbol_mask_s1,
4837 &hf_oran_dmrs_symbol_mask_s0,
4838 NULL((void*)0)
4839 };
4840 proto_tree_add_bitmask(entry_tree, tvb, offset,
4841 hf_oran_dmrs_symbol_mask, ett_oran_dmrs_symbol_mask, dmrs_symbol_mask_flags, ENC_BIG_ENDIAN0x00000000);
4842 offset += 2;
4843
4844 /* scrambling */
4845 proto_tree_add_item(entry_tree, hf_oran_scrambling, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4846 offset += 2;
4847
4848 /* nscid (1 bit) */
4849 proto_tree_add_item(entry_tree, hf_oran_nscid, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4850
4851 /* These 5 bits differ depending upon entry type */
4852 if (entry_type == 2) { /* type 2 */
4853 /* dType (1 bit) */
4854 proto_tree_add_item(entry_tree, hf_oran_dtype, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4855 /* cdmWithoutData (2 bits) */
4856 proto_tree_add_item(entry_tree, hf_oran_cmd_without_data, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4857 /* lambda (2 bits) */
4858 proto_tree_add_item(entry_tree, hf_oran_lambda, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4859 }
4860 else { /* type 3 */
4861 /* reserved (1 bit) */
4862 add_reserved_field(entry_tree, hf_oran_reserved_bit1, tvb, offset, 1);
4863 /* lowPaprType (2 bits) */
4864 proto_tree_add_item(entry_tree, hf_oran_low_papr_type, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4865 /* hoppingMode (2 bits) */
4866 proto_tree_add_item(entry_tree, hf_oran_hopping_mode, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4867 }
4868
4869 /* firstPrb (9 bits) */
4870 proto_tree_add_item(entry_tree, hf_oran_first_prb, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4871 offset += 1;
4872 /* lastPrb (9 bits) */
4873 proto_tree_add_item(entry_tree, hf_oran_last_prb, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4874 offset += 2;
4875 /* Reserved (16 bits) */
4876 add_reserved_field(entry_tree, hf_oran_reserved_16bits, tvb, offset, 2);
4877 offset += 2;
4878
4879 /* Could now see entry types 0 or 1 - they have these values to inherit */
4880 seen_value_to_inherit = true1;
4881 inherited_config_has_transform_precoding = (entry_type == 3);
4882 break;
4883 }
4884
4885 default:
4886 /* reserved - expert info */
4887 break;
4888 }
4889
4890 proto_item_append_text(entry_ti, " [UEId=%u] (dmrsPortNumber=%2u) (type %u - %s) ",
4891 ueids[ueid_index++], dmrs_port_number, entry_type, val_to_str_const(entry_type, entry_type_vals, "Unknown"));
4892 proto_item_set_end(entry_ti, tvb, offset);
4893
4894 if (entry_type <= 1) {
4895 proto_item_append_text(entry_ti, " [transform-precoding %s]",
4896 inherited_config_has_transform_precoding ? "enabled" : "disabled");
4897 }
4898 }
4899
4900 proto_item_append_text(extension_ti, " (%d DMRS configs seen)", dmrs_configs_seen);
4901 break;
4902 }
4903
4904 case 25: /* SE 25: Symbol reordering for DMRS-BF */
4905 /* Just dissect each available block of 7 bytes as the 14 symbols for a layer,
4906 where each layer could be one or apply to all layers. */
4907 {
4908 /* TODO: should only appear in one section of a message - check? */
4909 unsigned layer = 0;
4910 proto_item *layer_ti;
4911 while (offset+7 <= (extension_start_offset + extlen*4)) {
4912 /* Layer subtree */
4913 layer_ti = proto_tree_add_string_format(extension_tree, hf_oran_symbol_reordering_layer,
4914 tvb, offset, 7, "",
4915 "Layer");
4916 proto_tree *layer_tree = proto_item_add_subtree(layer_ti, ett_oran_symbol_reordering_layer);
4917
4918 /* All 14 symbols for a layer (or all layers) */
4919 for (unsigned s=0; s < 14; s++) {
4920 proto_item *sym_ti;
4921 /* txWinForOnAirSymbol */
4922 unsigned int tx_win_for_on_air_symbol;
4923 sym_ti = proto_tree_add_item_ret_uint(layer_tree,
4924 (s % 2) ? hf_oran_tx_win_for_on_air_symbol_r : hf_oran_tx_win_for_on_air_symbol_l,
4925 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &tx_win_for_on_air_symbol);
4926 if (tx_win_for_on_air_symbol == 0x0F) {
4927 /* Ordering not affected */
4928 proto_item_append_text(sym_ti, " (sym %u - no info)", s);
4929 }
4930 else {
4931 proto_item_append_text(sym_ti, " (sym %u)", s);
4932 }
4933 if (s % 2) {
4934 offset += 1;
4935 }
4936 }
4937
4938 proto_item_append_text(layer_ti, " (layer %u)", ++layer);
4939 proto_item_append_text(extension_ti, " (layer %u)", layer);
4940 }
4941 /* Set layer subtree label */
4942 if (layer == 1) {
4943 proto_item_append_text(layer_ti, " (all)");
4944 proto_item_append_text(extension_ti, " (all)");
4945 }
4946 if (layer == 0) {
4947 /* TODO: are no layers valid? What does it mean? */
4948 proto_item_append_text(extension_ti, " (none)");
4949 }
4950 break;
4951 }
4952
4953 case 26: /* SE 26: Frequency offset feedback */
4954 /* Reserved (8 bits) */
4955 add_reserved_field(extension_tree, hf_oran_reserved_8bits, tvb, offset, 1);
4956 offset += 1;
4957 /* Reserved (1 bit) */
4958 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
4959 /* numFoFb (7 bits) */
4960 unsigned num_fo_fb;
4961 proto_tree_add_item_ret_uint(extension_tree, hf_oran_num_fo_fb, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &num_fo_fb);
4962 offset += 1;
4963
4964 /* Add each freqOffsetFb value */
4965 for (unsigned n=0; n < num_fo_fb; n++) {
4966 unsigned freq_offset_fb;
4967 /* freqOffsetFb (16 bits) */
4968 proto_item *offset_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_freq_offset_fb,
4969 tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &freq_offset_fb);
4970 /* Show if maps onto a -ve number */
4971 if ((freq_offset_fb >= 0x8ad0) && (freq_offset_fb <= 0xffff)) {
4972 proto_item_append_text(offset_ti, "(value %d)", -1 - (0xffff-freq_offset_fb));
4973 }
4974 proto_item_append_text(offset_ti, " [#%u]", n+1);
4975 offset += 2;
4976 }
4977 break;
4978
4979 case 27: /* SE 27: O-DU controlled dimensionality reduction */
4980 {
4981 /* Hidden filter for bf (DMRS BF) */
4982 bf_ti = proto_tree_add_item(tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
4983 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
4984
4985 /* beamType (2 bits) */
4986 unsigned beam_type;
4987 proto_tree_add_item_ret_uint(extension_tree, hf_oran_beam_type, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &beam_type);
4988 /* reserved (6 bits) */
4989 add_reserved_field(extension_tree, hf_oran_reserved_last_6bits, tvb, offset, 1);
4990 offset += 1;
4991
4992 /* numElements */
4993 unsigned num_elements;
4994 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);
4995 if (num_elements == 0) {
4996 num_elements = 256;
4997 proto_item_append_text(num_elements_ti, " (256");
4998 }
4999
5000 offset += 1;
5001
5002 /* beamId value(s) */
5003 switch (beam_type) {
5004 case 0:
5005 for (unsigned n=0; n < num_elements; n++) {
5006 /* reserved (1 bit) + beamId */
5007 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
5008 proto_tree_add_item(c_section_tree, hf_oran_beamId, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
5009 offset += 2;
5010 }
5011 break;
5012 case 1:
5013 /* reserved (1 bit) + beamId */
5014 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
5015 proto_tree_add_item(c_section_tree, hf_oran_beamId, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
5016 offset += 2;
5017 break;
5018 default:
5019 /* Unknown type... */
5020 break;
5021 }
5022 break;
5023 }
5024
5025 case 28: /* SE 28: O-DU controlled frequency resolution for SINR reporting */
5026 {
5027 /* reserved (3 bits) */
5028 add_reserved_field(extension_tree, hf_oran_reserved_3bits, tvb, offset, 1);
5029 /* numUeSinrRpt (5 bits) */
5030 uint32_t num_ue_sinr_rpt;
5031 proto_tree_add_item_ret_uint(extension_tree, hf_oran_num_ue_sinr_rpt, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &num_ue_sinr_rpt);
5032 offset += 1;
5033
5034 for (uint32_t n=0; n < num_ue_sinr_rpt; n++) {
5035 /* reserved (1 bit) */
5036 add_reserved_field(extension_tree, (n % 2) ? hf_oran_reserved_bit4 : hf_oran_reserved_1bit,
5037 tvb, offset, 1);
5038
5039 /* numSinrPerPrb (3 bits). Taken from alternate nibbles within byte. */
5040 proto_tree_add_item(extension_tree, (n % 2) ? hf_oran_num_sinr_per_prb_right : hf_oran_num_sinr_per_prb,
5041 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5042 if (n % 2) {
5043 offset += 1;
5044 }
5045 }
5046
5047 /* May need to skip beyond half-used byte */
5048 if (num_ue_sinr_rpt % 2) {
5049 offset += 1;
5050 }
5051 break;
5052 }
5053
5054 case 29: /* SE 29: Cyclic delay adjustment */
5055 /* reserved (4 bits) */
5056 add_reserved_field(extension_tree, hf_oran_reserved_4bits, tvb, offset, 1);
5057 /* cdScgSize (4 bits) */
5058 proto_tree_add_item(extension_tree, hf_oran_cd_scg_size, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5059 offset += 1;
5060
5061 /* cdScgPhaseStep */
5062 proto_tree_add_item(extension_tree, hf_oran_cd_scg_phase_step, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5063 offset += 1;
5064 break;
5065
5066 case 30: /* SE 30: PUSCH repetition indication */
5067 {
5068 /* Only valid for UL */
5069 if (!tap_info->uplink) {
5070 expert_add_info(pinfo, extension_ti, &ei_oran_se30_not_ul);
5071 }
5072
5073 /* ueids[], number_of_ueids may have been rewritten by SE10 */
5074
5075 /* reserved (4 bits) */
5076 add_reserved_field(extension_tree, hf_oran_reserved_4bits, tvb, offset, 1);
5077 /* numRepUe (4 bits) */
5078 uint8_t num_rep_ue;
5079 proto_tree_add_item_ret_uint8(extension_tree, hf_oran_num_rep_ue, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &num_rep_ue);
5080 offset ++;
5081 /* reserved (8 bits) */
5082 add_reserved_field(extension_tree, hf_oran_reserved_8bits, tvb, offset, 1);
5083 offset += 1;
5084
5085 if (num_rep_ue == 1) {
5086 /* SE10 *not* present. N.B. this should tally with number_of_ueids being set to only 1? */
5087 /* reserved (1 bit) */
5088 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
5089 /* isLastRep (1 bit). Value meaningless here? */
5090 proto_tree_add_item(extension_tree, hf_oran_is_last_rep, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5091 /* repIndex (6 bits) */
5092 proto_tree_add_item(extension_tree, hf_oran_rep_index, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5093 offset += 1;
5094
5095 /* reserved (2 bits) */
5096 add_reserved_field(extension_tree, hf_oran_reserved_2bits, tvb, offset, 1);
5097 /* numReps (6 bits) */
5098 uint8_t num_reps;
5099 proto_tree_add_item_ret_uint8(extension_tree, hf_oran_num_reps, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &num_reps);
5100 /* TODO: should numReps be 0 here? */
5101 offset += 1;
5102
5103 /* reserved (2 bits) */
5104 add_reserved_field(extension_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5105 offset += 2;
5106
5107 }
5108 else {
5109 /* SE10 present */
5110 bool_Bool is_last_rep = false0;
5111 /* TODO: should is_last_rep (also) cause loop exit? */
5112 for (uint8_t ue_idx=0; (ue_idx < num_rep_ue) && !is_last_rep; ue_idx++) {
5113 /* reserved (1 bit) */
5114 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
5115 /* isLastRep (1 bit) */
5116 proto_tree_add_item_ret_boolean(extension_tree, hf_oran_is_last_rep, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &is_last_rep);
5117 /* repIndex (6 bits) */
5118 proto_tree_add_item(extension_tree, hf_oran_rep_index, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5119 offset += 1;
5120
5121 /* reserved (2 bits) */
5122 add_reserved_field(extension_tree, hf_oran_reserved_2bits, tvb, offset, 1);
5123 /* numReps (6 bits) */
5124 uint8_t num_reps;
5125 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);
5126 /* TODO: values 33-63 are reserved */
5127 if (num_reps > 32) {
5128 proto_item_append_text(num_reps_ti, " (reserved)");
5129 }
5130 offset += 1;
5131
5132 for (uint8_t rep=0; rep < num_reps; rep++) {
5133 /* reserved (1 bit) */
5134 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
5135 /* repUeId (15 bits) */
5136 /* TODO: should be fetching and comparing with ueids[] from SE10? */
5137 uint16_t ueid;
5138 proto_item *ueid_ti = proto_tree_add_item_ret_uint16(extension_tree, hf_oran_rep_ueid, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &ueid);
5139
5140 /* Check that this ueid is recognised (among ueids[], number_of_ueids) */
5141 bool_Bool matched = false0;
5142 for (unsigned u=0; u < number_of_ueids; u++) {
5143 if (ueid == ueids[u])
5144 matched = true1;
5145 }
5146 if (!matched) {
5147 expert_add_info_format(pinfo, ueid_ti, &ei_oran_se30_unknown_ueid,
5148 "SE 30 mentions UEId %u - not seen in SE10", ueid);
5149 }
5150 offset += 2;
5151 }
5152 }
5153 }
5154 break;
5155 }
5156 case 31: /* SE 31: MCS Information */
5157 {
5158 /* TODO: show ueid (from ST5 or SE10) as generated field? Maybe add a subtree for each entry? */
5159 for (uint32_t u=0; u < number_of_ueids; u++) {
5160 /* reserved (4 bits) */
5161 add_reserved_field(extension_tree, hf_oran_reserved_4bits, tvb, offset, 1);
5162 /* mcsTable (4 bits) */
5163 proto_tree_add_item(extension_tree, hf_oran_mcs_table, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5164 offset += 1;
5165
5166 /* reserved (2 bits) */
5167 add_reserved_field(extension_tree, hf_oran_reserved_4bits, tvb, offset, 1);
5168 /* mcsIndex (6 bits) */
5169 proto_tree_add_item(extension_tree, hf_oran_mcs_index, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5170 }
5171 break;
5172 }
5173
5174 case 32: /* SE 32: Rank and TPMI measurement request */
5175 {
5176 /* reserved (3 bits) */
5177 add_reserved_field(extension_tree, hf_oran_reserved_3bits, tvb, offset, 1);
5178 /* numMeasReq (5 bits) */
5179 uint8_t num_meas_req;
5180 proto_tree_add_item_ret_uint8(extension_tree, hf_oran_num_meas_req, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &num_meas_req);
5181 offset += 1;
5182
5183 /* reserved (8 bits) */
5184 add_reserved_field(extension_tree, hf_oran_reserved_8bits, tvb, offset, 1);
5185 offset += 1;
5186
5187 /* Show each measurement request */
5188 for (unsigned r=0; r < num_meas_req; r++) {
5189 /* Reserved (1 bit) */
5190 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
5191 /* ueId (14 bits) */
5192 proto_tree_add_item(extension_tree, hf_oran_ueId, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
5193 offset += 2;
5194
5195 /* numOfUeAntPorts (4 bits) */
5196 proto_tree_add_item(extension_tree, hf_oran_num_of_ue_ant_ports, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5197 /* ueRank (4 bits) */
5198 proto_tree_add_item(extension_tree, hf_oran_ue_rank, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5199 offset += 1;
5200
5201 /* codebookSubset (2 bits) */
5202 proto_tree_add_item(extension_tree, hf_oran_codebook_subset, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5203 /* TODO: tpmiIndex (6 bits) */
5204 offset += 1;
5205
5206 /* fullPwrMode (2 bits) */
5207 proto_tree_add_item(extension_tree, hf_oran_full_pwr_mode, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5208 /* fullPwrMode2TmpiGroup (14 bits) */
5209 /* TODO: add as a bitset */
5210 proto_tree_add_item(extension_tree, hf_oran_full_pwr_mode_2_tpmi_group, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
5211 offset += 2;
5212
5213 /* reserved (2 bytes) */
5214 add_reserved_field(extension_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5215 offset += 2;
5216 }
5217 break;
5218 }
5219
5220 default:
5221 /* Other/unexpected extension types */
5222 expert_add_info_format(pinfo, exttype_ti, &ei_oran_unhandled_se,
5223 "SE %u (%s) not supported by dissector",
5224 exttype, val_to_str_ext_const(exttype, &exttype_vals_ext, "Reserved"));
5225 ext_unhandled = true1;
5226 break;
5227 }
5228
5229 /* Check offset compared with extlen. There should be 0-3 bytes of padding */
5230 int num_padding_bytes = (extension_start_offset + (extlen*4) - offset);
5231 if (!ext_unhandled && ((num_padding_bytes<0) || (num_padding_bytes>3))) {
5232 expert_add_info_format(pinfo, extlen_ti, &ei_oran_extlen_wrong,
5233 "extlen signalled %u bytes (+ 0-3 bytes padding), but %u were dissected",
5234 extlen*4, offset-extension_start_offset);
5235 }
5236
5237 /* Move offset to beyond signalled length of extension */
5238 offset = extension_start_offset + (extlen*4);
5239
5240 /* Set length of extension header. */
5241 proto_item_set_len(extension_ti, extlen*4);
5242 }
5243 /* End of section extension handling */
5244
5245 /* Tap section beamId if not overwritten by SEs */
5246 if (!section_beamId_ignored && section_beamId != 0) {
5247 add_beam_id_to_tap(tap_info, section_beamId);
5248 }
5249
5250
5251 /* RRM measurement reports have measurement reports *after* extensions */
5252 if (sectionType == SEC_C_RRM_MEAS_REPORTS) /* Section Type 10 */
5253 {
5254 /* Hidden filter for bf (DMFS-BF). No BF weights though.. */
5255 bf_ti = proto_tree_add_item(c_section_tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
5256 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
5257
5258 bool_Bool mf;
5259 do {
5260 /* Measurement report subtree */
5261 proto_item *mr_ti = proto_tree_add_string_format(c_section_tree, hf_oran_measurement_report,
5262 tvb, offset, 1, "", "Measurement Report");
5263 proto_tree *mr_tree = proto_item_add_subtree(mr_ti, ett_oran_measurement_report);
5264 unsigned report_start_offset = offset;
5265
5266 /* measurement flag (i.e., more reports after this one) (1 bit) */
5267 proto_tree_add_item_ret_boolean(mr_tree, hf_oran_mf, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &mf);
5268
5269 /* measTypeId (7 bits) */
5270 uint32_t meas_type_id;
5271 proto_item *meas_type_id_ti;
5272 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);
5273 offset += 1;
5274
5275 /* Common to all measurement types */
5276 unsigned num_elements = 0;
5277 if (meas_type_id == 6) {
5278 /* numElements */
5279 proto_tree_add_item_ret_uint(mr_tree, hf_oran_num_elements, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &num_elements);
5280 }
5281 else {
5282 /* All other meas ids have a reserved byte */
5283 add_reserved_field(mr_tree, hf_oran_reserved_8bits, tvb, offset, 1);
5284 }
5285 offset += 1;
5286
5287 /* measDataSize (16 bits). N.B. begins at mf field, i.e. 2 bytes before this one */
5288 unsigned meas_data_size;
5289 proto_item *meas_data_size_ti;
5290 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);
5291 meas_data_size *= 4;
5292 proto_item_append_text(meas_data_size_ti, " (%u bytes)", meas_data_size);
5293 offset += 2;
5294
5295 /* Summary for measurement report root */
5296 proto_item_append_text(mr_ti, " (measTypeId=%u - %s)",
5297 meas_type_id, val_to_str_const(meas_type_id, meas_type_id_vals, "unknown"));
5298 /* And section header */
5299 proto_item_append_text(tree, " (%s)", val_to_str_const(meas_type_id, meas_type_id_vals, "unknown"));
5300 /* And Info column */
5301 col_append_fstr(pinfo->cinfo, COL_INFO, " (%s)", val_to_str_const(meas_type_id, meas_type_id_vals, "unknown"));
5302
5303 /* Handle specific message type fields */
5304 switch (meas_type_id) {
5305 case 1:
5306 {
5307 /* ueTae */
5308 unsigned ue_tae;
5309 proto_item *ue_tae_ti;
5310 ue_tae_ti = proto_tree_add_item_ret_uint(mr_tree, hf_oran_ue_tae, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &ue_tae);
5311 /* Show if maps onto a -ve number */
5312 if ((ue_tae >= 0x8ad0) && (ue_tae <= 0xffff)) {
5313 proto_item_append_text(ue_tae_ti, "(value %d)", -1 - (0xffff-ue_tae));
5314 }
5315 offset += 2;
5316
5317 /* Reserved (16 bits) */
5318 add_reserved_field(mr_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5319 offset += 2;
5320 break;
5321 }
5322 case 2:
5323 /* ueLayerPower entries (how many? for now just use up meas_data_size..) */
5324 /* TODO: add number of distinct dmrsPortNumber entries seen in SE24 and save in state? */
5325 /* Or would it make sense to use the preference 'pref_num_bf_antennas' ? */
5326 for (unsigned n=0; n < (meas_data_size-4)/2; n++) {
5327 unsigned ue_layer_power;
5328 proto_item *ue_layer_power_ti;
5329 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);
5330 /* Show if maps onto a -ve number */
5331 if ((ue_layer_power >= 0x8ad0) && (ue_layer_power <= 0xffff)) {
5332 proto_item_append_text(ue_layer_power_ti, "(value %d)", -1 - (0xffff-ue_layer_power));
5333 }
5334 offset += 2;
5335 }
5336 /* padding out to 4 bytes */
5337 break;
5338 case 3:
5339 {
5340 /* ueFreqOffset */
5341 unsigned ue_freq_offset;
5342 proto_item *ue_freq_offset_ti;
5343 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);
5344 /* Show if maps onto a -ve number */
5345 if ((ue_freq_offset >= 0x8ad0) && (ue_freq_offset <= 0xffff)) {
5346 proto_item_append_text(ue_freq_offset_ti, "(value %d)", -1 - (0xffff-ue_freq_offset));
5347 }
5348 offset += 2;
5349
5350 /* Reserved (16 bits) */
5351 add_reserved_field(mr_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5352 offset += 2;
5353 break;
5354 }
5355 case 4:
5356 case 5:
5357 /* reserved (2 bits) */
5358 add_reserved_field(mr_tree, hf_oran_reserved_2bits, tvb, offset, 1);
5359 /* symbolMask (14 bits) */
5360 offset = dissect_symbolmask(tvb, mr_tree, offset, NULL((void*)0), NULL((void*)0));
5361
5362 /* 2 bytes for each PRB ipnPower */
5363 for (unsigned prb=0; prb<MAX_PRBS273; prb++) {
5364 /* Skip if should not be reported */
5365 if (!prbs_for_st10_type5[prb]) {
5366 continue;
5367 }
5368 unsigned ipn_power;
5369 proto_item *ipn_power_ti;
5370 /* ipnPower (2 bytes) */
5371 ipn_power_ti = proto_tree_add_item_ret_uint(mr_tree, hf_oran_ipn_power, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &ipn_power);
5372 proto_item_append_text(ipn_power_ti, " (PRB %3d)", prb);
5373 /* Show if maps onto a -ve number */
5374 if ((ipn_power >= 0x8ad0) && (ipn_power <= 0xffff)) {
5375 proto_item_append_text(ipn_power_ti, " (value %d)", -1 - (0xffff-ipn_power));
5376 }
5377 offset += 2;
5378 }
5379 /* padding out to 4 bytes */
5380 break;
5381 case 6:
5382 /* antDmrsSnrVal entries */
5383 for (unsigned n=0; n < num_elements; n++) {
5384 unsigned snr_value;
5385 proto_item *snr_value_ti;
5386 /* antDmrsSnrVal (2 bytes) */
5387 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);
5388 proto_item_append_text(snr_value_ti, " (elem %2u)", n+1);
5389 /* Show if maps onto a -ve number */
5390 if ((snr_value >= 0x8ad0) && (snr_value <= 0xffff)) {
5391 proto_item_append_text(snr_value_ti, " (value %d)", -1 - (0xffff-snr_value));
5392 }
5393 offset += 2;
5394 }
5395 break;
5396 case 7:
5397 {
5398 /* UE positioning measurement report */
5399 float start_value;
5400
5401 /* ueAzAoa (16 bits) */
5402 uint32_t ue_az_aoa;
5403 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);
5404 if (ue_az_aoa <= 0xE0F) {
5405 if (ue_az_aoa >= 0x0708) {
5406 start_value = (ue_az_aoa-0x0708) * (float)0.1;
5407 proto_item_append_text(ue_az_aoa_ti, " (%.1f <= val < %.1f degrees)", start_value, start_value + (float)0.1);
5408 }
5409 else {
5410 start_value = 180 + (ue_az_aoa * (float)0.1);
5411 proto_item_append_text(ue_az_aoa_ti, " (%.1f <= val < %.1f degrees)", start_value, start_value + (float)0.1);
5412 }
5413 }
5414 else if (ue_az_aoa == 0xffff) {
5415 proto_item_append_text(ue_az_aoa_ti, " (invalid measurement result)");
5416 }
5417 else {
5418 proto_item_append_text(ue_az_aoa_ti, " (reserved)");
5419 }
5420 offset += 2;
5421
5422 /* Reserved (16 bits) */
5423 add_reserved_field(mr_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5424 offset += 2;
5425
5426 /* ueZeAoa (16 bits) */
5427 uint32_t ue_ze_aoa;
5428 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);
5429 if (ue_ze_aoa <= 0x707) {
5430 start_value = ue_ze_aoa * (float)0.1;
5431 proto_item_append_text(ue_ze_aoa_ti, " (%.1f <= val < %.1f degrees)", start_value, start_value + (float)0.1);
5432 }
5433 else if (ue_az_aoa == 0xffff) {
5434 proto_item_append_text(ue_ze_aoa_ti, " (invalid measurement result)");
5435 }
5436 else {
5437 proto_item_append_text(ue_ze_aoa_ti, " (reserved)");
5438 }
5439 offset += 2;
5440
5441 /* Reserved (16 bits) */
5442 add_reserved_field(mr_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5443 offset += 2;
5444
5445 /* uePosToaOffset (16 bits) */
5446 uint32_t ue_pos_toa_offset;
5447 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);
5448 if (ue_pos_toa_offset == 0) {
5449 proto_item_append_text(ue_pos_toa_offset_ti, " (no UE ToA offset, 0 symbols)");
5450 }
5451 else if (ue_pos_toa_offset <= 0x7fff) {
5452 proto_item_append_text(ue_pos_toa_offset_ti, " (+ve UE ToA offset)");
5453 }
5454 else if (ue_pos_toa_offset == 0x8000) {
5455 proto_item_append_text(ue_pos_toa_offset_ti, " (invalid measurement result)");
5456 }
5457 else {
5458 proto_item_append_text(ue_pos_toa_offset_ti, " (-ve UE ToA offset)");
5459 }
5460 offset += 2;
5461
5462 /* Reserved (16 bits) */
5463 add_reserved_field(mr_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5464 offset += 2;
5465 break;
5466 }
5467 case 8:
5468 {
5469 /* UE radial speed measurement report */
5470
5471 /* ueRadialSpeed (16 bits) */
5472 uint32_t radial_speed;
5473 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);
5474 if (radial_speed <= 10000) {
5475 proto_item_append_text(radial_speed_ti, " (%.1f km/h)", radial_speed * (float)0.1);
5476 }
5477 else if (radial_speed == 0x8000) {
5478 proto_item_append_text(radial_speed_ti, " (invalid measurement result)");
5479 }
5480 else {
5481 proto_item_append_text(radial_speed_ti, " (reserved value)");
5482 }
5483 offset += 2;
5484
5485 /* Reserved (16 bits) */
5486 add_reserved_field(mr_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5487 offset += 2;
5488 break;
5489 }
5490 case 9:
5491 {
5492 /* TODO: UE post-equalization MU interference measurement */
5493
5494 /* reserved (16 bits) */
5495 add_reserved_field(mr_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5496 offset += 2;
5497
5498 /* TODO: muInterferenceLevel (all layers * all PRB blocks) */
5499 break;
5500 }
5501 case 10:
5502 {
5503 /* TODO: UE TPMI and rank recommendation measurement */
5504
5505 /* numCandRanks (4 bits) */
5506 add_reserved_field(mr_tree, hf_oran_num_cand_ranks, tvb, offset, 1);
5507 /* uePrefRank (4 bits) */
5508 add_reserved_field(mr_tree, hf_oran_ue_pref_rank, tvb, offset, 1);
5509 offset += 1;
5510
5511 /* TODO: ueTpmiRank1 (1 byte) */
5512 offset += 1;
5513
5514 /* TODO: ueTpmiRank1Sinr1 (2 bytes) */
5515 offset += 2;
5516
5517 /* TODO: various Sinr depending upon numCandRanks value.. */
5518 break;
5519 }
5520 case 11:
5521 {
5522 /* TODO: UE layer pre-equalization SINR report */
5523
5524 /* TODO: 1st to last layer ueLayerPreEqSinr (2 bytes each) */
5525 break;
5526 }
5527
5528 default:
5529 /* Anything else is not expected */
5530 expert_add_info_format(pinfo, meas_type_id_ti, &ei_oran_unexpected_measTypeId,
5531 "measTypeId %u (%s) not supported - only 1-6 are expected",
5532 meas_type_id,
5533 val_to_str_const(meas_type_id, meas_type_id_vals, "reserved"));
5534 break;
5535
5536 }
5537
5538 /* Pad out to next 4 bytes */
5539 offset += WS_PADDING_TO_4(offset-report_start_offset)((4U - ((offset-report_start_offset) % 4U)) % 4U);
5540
5541 /* TODO: verify dissected size of report vs meas_data_size? */
5542
5543 /* End of measurement report tree */
5544 proto_item_set_end(mr_ti, tvb, offset);
5545 } while (mf);
5546 }
5547
5548 /* Request for RRM Measurements has measurement commands after extensions */
5549 else if (sectionType == SEC_C_REQUEST_RRM_MEAS) /* Section Type 11 */
5550 {
5551 bool_Bool mf = true1;
5552 do {
5553 /* Measurement command subtree */
5554 proto_item *mc_ti = proto_tree_add_string_format(c_section_tree, hf_oran_measurement_command,
5555 tvb, offset, 8, "", "Measurement Command");
5556 proto_tree *mc_tree = proto_item_add_subtree(mc_ti, ett_oran_measurement_command);
5557
5558 /* mf (1 bit). 1st measurement command is always preset */
5559 proto_tree_add_item_ret_boolean(mc_tree, hf_oran_mf, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &mf);
5560
5561 /* measTypeId (7 bits) */
5562 uint32_t meas_type_id;
5563 proto_item *meas_type_id_ti;
5564 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);
5565 offset += 1;
5566
5567 proto_item *meas_command_ti;
5568 uint32_t meas_command_size;
5569
5570 switch (meas_type_id) {
5571 case 5: /* command for IpN for unallocated PRBs */
5572 /* reserved (1 byte) */
5573 add_reserved_field(mc_tree, hf_oran_reserved_8bits, tvb, offset, 1);
5574 offset += 1;
5575 /* measCmdSize. Presumably number of words so in future could skip unrecognised command types.. */
5576 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);
5577 proto_item_append_text(meas_command_ti, " (%u bytes)", meas_command_size*4);
5578 offset += 2;
5579 /* reserved (2 bits) */
5580 add_reserved_field(mc_tree, hf_oran_reserved_2bits, tvb, offset, 1);
5581 /* symbolMask (14 bits) */
5582 offset = dissect_symbolmask(tvb, mc_tree, offset, NULL((void*)0), NULL((void*)0));
5583 /* reserved (16 bits) */
5584 add_reserved_field(mc_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5585 offset += 2;
5586 break;
5587
5588 default:
5589 /* Anything else is not expected */
5590 expert_add_info_format(pinfo, meas_type_id_ti, &ei_oran_unexpected_measTypeId,
5591 "measTypeId %u (%s) not supported - only 5 is expected",
5592 meas_type_id,
5593 val_to_str_const(meas_type_id, meas_type_id_vals, "reserved"));
5594 break;
5595 }
5596 proto_item_append_text(mc_ti, " (%s)", val_to_str_const(meas_type_id, meas_type_id_vals, "unknown"));
5597
5598 } while (mf);
5599 }
5600
5601 /* Set extent of overall section */
5602 proto_item_set_len(sectionHeading, offset);
5603
5604 return offset;
5605}
5606
5607/* Dissect udCompHdr (user data compression header, 7.5.2.10) */
5608/* bit_width and comp_meth are out params */
5609static int dissect_udcomphdr(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset,
5610 bool_Bool cplane, bool_Bool ignore,
5611 unsigned *bit_width, unsigned *comp_meth, proto_item **comp_meth_ti,
5612 oran_tap_info *tap_info)
5613{
5614 /* Subtree */
5615 proto_item *udcomphdr_ti = proto_tree_add_string_format(tree, hf_oran_udCompHdr,
5616 tvb, offset, 1, "",
5617 "udCompHdr");
5618 proto_tree *udcomphdr_tree = proto_item_add_subtree(udcomphdr_ti, ett_oran_udcomphdr);
5619
5620 /* udIqWidth */
5621 uint32_t hdr_iq_width;
5622 proto_item *iq_width_item = proto_tree_add_item_ret_uint(udcomphdr_tree, hf_oran_udCompHdrIqWidth , tvb, offset, 1, ENC_NA0x00000000, &hdr_iq_width);
5623 *bit_width = (hdr_iq_width) ? hdr_iq_width : 16;
5624 proto_item_append_text(iq_width_item, " (%u bits)", *bit_width);
5625
5626 /* udCompMeth */
5627 uint32_t ud_comp_meth;
5628 *comp_meth_ti = proto_tree_add_item_ret_uint(udcomphdr_tree, hf_oran_udCompHdrMeth, tvb, offset, 1, ENC_NA0x00000000, &ud_comp_meth);
5629 if (comp_meth) {
5630 *comp_meth = ud_comp_meth;
5631 }
5632
5633 /* Populate tap header with compression settings */
5634 if (!ignore) {
5635 tap_info->compression_methods |= (1 << ud_comp_meth);
5636 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))
;
5637 /* Summary */
5638 proto_item_append_text(udcomphdr_ti, " (IqWidth=%u, udCompMeth=%s)",
5639 *bit_width, rval_to_str_const(ud_comp_meth, ud_comp_header_meth, "Unknown"));
5640 }
5641 else {
5642 proto_item_append_text(udcomphdr_ti, " (ignored)");
5643 if (hdr_iq_width || ud_comp_meth) {
5644 if (cplane) {
5645 /* Only ignore DL for cplane */
5646 expert_add_info_format(pinfo, udcomphdr_ti, &ei_oran_udpcomphdr_should_be_zero,
5647 "udCompHdr in C-Plane for DL should be 0 - found 0x%02x",
5648 tvb_get_uint8(tvb, offset));
5649 }
5650 else {
5651 /* TODO: Ignore UL if using m-plane/preference setting rather than c-plane, but wrong to be set? */
5652 /* expert_add_info_format(pinfo, udcomphdr_ti, &ei_oran_udpcomphdr_should_be_zero,
5653 "udCompHdr in C-Plane for UL should be 0 - found 0x%02x",
5654 tvb_get_uint8(tvb, offset));
5655 */
5656 }
5657
5658 }
5659 }
5660 return offset+1;
5661}
5662
5663/* Dissect udCompParam (user data compression parameter, 8.3.3.15) */
5664/* bit_width and comp_meth are out params */
5665static int dissect_udcompparam(tvbuff_t *tvb, packet_info *pinfo _U___attribute__((unused)), proto_tree *tree, unsigned offset,
5666 unsigned comp_meth,
5667 uint32_t *exponent, uint16_t *sReSMask,
5668 bool_Bool for_sinr)
5669{
5670 if (for_sinr && (comp_meth != COMP_BLOCK_FP1)) {
5671 /* sinrCompParam only present when bfp is used */
5672 return offset;
5673 }
5674
5675 if (comp_meth == COMP_NONE0 ||
5676 comp_meth == COMP_MODULATION4 ||
5677 comp_meth == MOD_COMPR_AND_SELECTIVE_RE_WITH_MASKS8) {
5678
5679 /* Not even creating a subtree for udCompMeth 0, 4, 8 */
5680 return offset;
5681 }
5682
5683 /* Subtree */
5684 unsigned start_offset = offset;
5685 proto_item *udcompparam_ti = proto_tree_add_string_format(tree, hf_oran_udCompParam,
5686 tvb, offset, 1, "",
5687 (for_sinr) ? "sinrCompParam" : "udCompParam");
5688 proto_tree *udcompparam_tree = proto_item_add_subtree(udcompparam_ti, ett_oran_udcompparam);
5689
5690 /* Show comp_meth as a generated field */
5691 proto_item *meth_ti = proto_tree_add_uint(udcompparam_tree, hf_oran_udCompHdrMeth_pref, tvb, 0, 0, comp_meth);
5692 proto_item_set_generated(meth_ti);
5693
5694 uint32_t param_exponent;
5695 uint64_t param_sresmask;
5696
5697 static int * const sres_mask_flags[] = {
5698 &hf_oran_sReSMask_re12,
5699 &hf_oran_sReSMask_re11,
5700 &hf_oran_sReSMask_re10,
5701 &hf_oran_sReSMask_re9,
5702 &hf_oran_sReSMask_re8,
5703 &hf_oran_sReSMask_re7,
5704 &hf_oran_sReSMask_re6,
5705 &hf_oran_sReSMask_re5,
5706 &hf_oran_sReSMask_re4,
5707 &hf_oran_sReSMask_re3,
5708 &hf_oran_sReSMask_re2,
5709 &hf_oran_sReSMask_re1,
5710 NULL((void*)0)
5711 };
5712
5713 switch (comp_meth) {
5714 case COMP_BLOCK_FP1: /* 1 */
5715 case BFP_AND_SELECTIVE_RE_WITH_MASKS7: /* 7 */
5716 /* reserved (4 bits) */
5717 add_reserved_field(udcompparam_tree, hf_oran_reserved_4bits, tvb, offset, 1);
5718 /* exponent (4 bits) */
5719 proto_tree_add_item_ret_uint(udcompparam_tree, hf_oran_exponent,
5720 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &param_exponent);
5721 *exponent = param_exponent;
5722 proto_item_append_text(udcompparam_ti, " (Exponent=%u)", param_exponent);
5723 offset += 1;
5724 break;
5725
5726 case COMP_BLOCK_SCALE2: /* 2 */
5727 /* Separate into integer and fractional bits? */
5728 proto_tree_add_item(udcompparam_tree, hf_oran_blockScaler,
5729 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5730 offset++;
5731 break;
5732
5733 case COMP_U_LAW3: /* 3 */
5734 /* compBitWidth, compShift */
5735 proto_tree_add_item(udcompparam_tree, hf_oran_compBitWidth,
5736 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5737 proto_tree_add_item(udcompparam_tree, hf_oran_compShift,
5738 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5739 offset += 1;
5740 break;
5741
5742 case BFP_AND_SELECTIVE_RE5: /* 5 */
5743 {
5744 /* sReSMask (exponent in middle!) */
5745 proto_item *sresmask_ti;
5746 sresmask_ti = proto_tree_add_bitmask_ret_uint64(udcompparam_tree, tvb, offset,
5747 hf_oran_sReSMask,
5748 ett_oran_sresmask,
5749 sres_mask_flags,
5750 ENC_NA0x00000000,
5751 &param_sresmask);
5752
5753 /* Get rid of exponent-shaped gap */
5754 param_sresmask = ((param_sresmask >> 4) & 0x0f00) | (param_sresmask & 0xff);
5755 unsigned res = 0;
5756 for (unsigned n=0; n < 12; n++) {
5757 if ((param_sresmask >> n) & 0x1) {
5758 res++;
5759 }
5760 }
5761 proto_item_append_text(sresmask_ti, " (%2u REs)", res);
5762
5763 /* exponent */
5764 proto_tree_add_item_ret_uint(udcompparam_tree, hf_oran_exponent,
5765 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &param_exponent);
5766 *sReSMask = (uint16_t)param_sresmask;
5767 *exponent = param_exponent;
5768
5769 proto_item_append_text(udcompparam_ti, " (exponent=%u, %u REs)", *exponent, res);
5770 offset += 2;
5771 break;
5772 }
5773
5774 case MOD_COMPR_AND_SELECTIVE_RE6: /* 6 */
5775 {
5776 /* sReSMask (exponent in middle!) */
5777 proto_item *sresmask_ti;
5778
5779 sresmask_ti = proto_tree_add_bitmask_ret_uint64(udcompparam_tree, tvb, offset,
5780 hf_oran_sReSMask,
5781 ett_oran_sresmask,
5782 sres_mask_flags,
5783 ENC_NA0x00000000,
5784 &param_sresmask);
5785
5786 /* Get rid of reserved-shaped gap */
5787 param_sresmask = ((param_sresmask >> 4) & 0x0f00) | (param_sresmask & 0xff);
5788 unsigned res = 0;
5789 for (unsigned n=0; n < 12; n++) {
5790 if ((param_sresmask >> n) & 0x1) {
5791 res++;
5792 }
5793 }
5794 proto_item_append_text(sresmask_ti, " (%u REs)", res);
5795
5796 /* reserved (4 bits) */
5797 add_reserved_field(udcompparam_tree, hf_oran_reserved_last_4bits, tvb, offset, 1);
5798 *sReSMask = (uint16_t)param_sresmask;
5799
5800 proto_item_append_text(udcompparam_ti, " (%u REs)", res);
5801 offset += 2;
5802 break;
5803 }
5804
5805 default:
5806 /* reserved (set to all zeros), but how many bytes?? */
5807 break;
5808 }
5809
5810 proto_item_set_len(udcompparam_ti, offset-start_offset);
5811 return offset;
5812}
5813
5814
5815/* Dissect ciCompHdr (channel information compression header, 7.5.2.15) */
5816/* bit_width and comp_meth are out params */
5817static int dissect_cicomphdr(tvbuff_t *tvb, packet_info *pinfo _U___attribute__((unused)), proto_tree *tree, unsigned offset,
5818 unsigned *bit_width, unsigned *comp_meth, uint8_t *comp_opt)
5819{
5820 /* Subtree */
5821 proto_item *cicomphdr_ti = proto_tree_add_string_format(tree, hf_oran_ciCompHdr,
5822 tvb, offset, 1, "",
5823 "ciCompHdr");
5824 proto_tree *cicomphdr_tree = proto_item_add_subtree(cicomphdr_ti, ett_oran_cicomphdr);
5825
5826 /* ciIqWidth */
5827 uint32_t hdr_iq_width;
5828 proto_item *iq_width_item = proto_tree_add_item_ret_uint(cicomphdr_tree, hf_oran_ciCompHdrIqWidth , tvb, offset, 1, ENC_NA0x00000000, &hdr_iq_width);
5829 hdr_iq_width = (hdr_iq_width) ? hdr_iq_width : 16;
5830 if (bit_width) {
5831 *bit_width = hdr_iq_width;
5832 }
5833 proto_item_append_text(iq_width_item, " (%u bits)", hdr_iq_width);
5834
5835 /* ciCompMeth */
5836 uint32_t ci_comp_meth;
5837 proto_tree_add_item_ret_uint(cicomphdr_tree, hf_oran_ciCompHdrMeth, tvb, offset, 1, ENC_NA0x00000000, &ci_comp_meth);
5838 if (comp_meth) {
5839 *comp_meth = ci_comp_meth;
5840 }
5841
5842 /* ciCompOpt */
5843 uint32_t opt;
5844 proto_tree_add_item_ret_uint(cicomphdr_tree, hf_oran_ciCompOpt, tvb, offset, 1, ENC_NA0x00000000, &opt);
5845 *comp_opt = opt;
5846 offset += 1;
5847
5848 /* Summary */
5849 proto_item_append_text(cicomphdr_ti, " (IqWidth=%u, ciCompMeth=%s, ciCompOpt=%s)",
5850 hdr_iq_width,
5851 rval_to_str_const(ci_comp_meth, ud_comp_header_meth, "Unknown"),
5852 (*comp_opt) ? "compression per PRB" : "compression per UE");
5853 return offset;
5854}
5855
5856static void dissect_payload_version(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, unsigned offset)
5857{
5858 unsigned version;
5859 proto_item *ti = proto_tree_add_item_ret_uint(tree, hf_oran_payload_version, tvb, offset, 1, ENC_NA0x00000000, &version);
5860 if (version != 1) {
5861 expert_add_info_format(pinfo, ti, &ei_oran_version_unsupported,
5862 "PayloadVersion %u not supported by dissector (only 1 is known)",
5863 version);
5864 /* TODO: should throw an exception? */
5865 }
5866}
5867
5868static void show_link_to_acknack_request(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo,
5869 ack_nack_request_t *request)
5870{
5871 /* Request frame */
5872 proto_item *ti = proto_tree_add_uint(tree, hf_oran_acknack_request_frame,
5873 tvb, 0, 0, request->request_frame_number);
5874 PROTO_ITEM_SET_GENERATED(ti)proto_item_set_generated((ti));
5875
5876 /* Work out gap between frames (in ms) */
5877 int seconds_between_packets = (int)
5878 (pinfo->abs_ts.secs - request->request_frame_time.secs);
5879 int nseconds_between_packets =
5880 pinfo->abs_ts.nsecs - request->request_frame_time.nsecs;
5881
5882 int total_gap = (seconds_between_packets*1000) +
5883 ((nseconds_between_packets+500000) / 1000000);
5884
5885 ti = proto_tree_add_uint(tree, hf_oran_acknack_request_time,
5886 tvb, 0, 0, total_gap);
5887 PROTO_ITEM_SET_GENERATED(ti)proto_item_set_generated((ti));
5888
5889 /* Type of request */
5890 ti = proto_tree_add_uint(tree, hf_oran_acknack_request_type,
5891 tvb, 0, 0, request->requestType);
5892 PROTO_ITEM_SET_GENERATED(ti)proto_item_set_generated((ti));
5893}
5894
5895static void show_link_to_acknack_response(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo,
5896 ack_nack_request_t *response)
5897{
5898 if (response->response_frame_number == 0) {
5899 /* Requests may not get a response, and can't always tell when to expect one */
5900 return;
5901 }
5902
5903 /* Response frame */
5904 proto_item *ti = proto_tree_add_uint(tree, hf_oran_acknack_response_frame,
5905 tvb, 0, 0, response->response_frame_number);
5906 PROTO_ITEM_SET_GENERATED(ti)proto_item_set_generated((ti));
5907
5908 /* Work out gap between frames (in ms) */
5909 int seconds_between_packets = (int)
5910 (response->response_frame_time.secs - pinfo->abs_ts.secs);
5911 int nseconds_between_packets =
5912 response->response_frame_time.nsecs - pinfo->abs_ts.nsecs;
5913
5914 int total_gap = (seconds_between_packets*1000) +
5915 ((nseconds_between_packets+500000) / 1000000);
5916
5917 ti = proto_tree_add_uint(tree, hf_oran_acknack_response_time,
5918 tvb, 0, 0, total_gap);
5919 PROTO_ITEM_SET_GENERATED(ti)proto_item_set_generated((ti));
5920}
5921
5922
5923
5924/* Control plane dissector (section 7). */
5925static int dissect_oran_c(tvbuff_t *tvb, packet_info *pinfo,
5926 proto_tree *tree, oran_tap_info *tap_info, void *data _U___attribute__((unused)))
5927{
5928 /* Hidden filter for plane */
5929 proto_item *plane_ti = proto_tree_add_item(tree, hf_oran_cplane, tvb, 0, 0, ENC_NA0x00000000);
5930 PROTO_ITEM_SET_HIDDEN(plane_ti)proto_item_set_hidden((plane_ti));
5931
5932 /* Set up structures needed to add the protocol subtree and manage it */
5933 unsigned offset = 0;
5934
5935 col_set_str(pinfo->cinfo, COL_PROTOCOL, "O-RAN-FH-C");
5936 col_set_str(pinfo->cinfo, COL_INFO, "C-Plane");
5937
5938 tap_info->userplane = false0;
5939
5940 /* Create display subtree for the protocol */
5941 proto_item *protocol_item = proto_tree_add_item(tree, proto_oran, tvb, 0, -1, ENC_NA0x00000000);
5942 proto_item_append_text(protocol_item, "-C");
5943 proto_tree *oran_tree = proto_item_add_subtree(protocol_item, ett_oran);
5944
5945 /* ecpriRtcid (eAxC ID) */
5946 uint16_t eAxC;
5947 addPcOrRtcid(tvb, oran_tree, &offset, hf_oran_ecpri_rtcid, &eAxC, tap_info);
5948 tap_info->eaxc = eAxC;
5949
5950 /* Look up any existing conversation state for eAxC+plane */
5951 uint32_t key = make_flow_key(pinfo, eAxC, ORAN_C_PLANE0, false0);
5952 flow_state_t* state = (flow_state_t*)wmem_tree_lookup32(flow_states_table, key);
5953
5954 /* Message identifier */
5955 uint32_t seq_id, sub_seq_id, e;
5956 proto_item *seq_id_ti;
5957 offset = addSeqid(tvb, oran_tree, offset, ORAN_C_PLANE0, &seq_id, &seq_id_ti, pinfo, &sub_seq_id, &e);
5958
5959 /* Section common subtree */
5960 int section_tree_offset = offset;
5961 proto_item *sectionHeading = proto_tree_add_string_format(oran_tree, hf_oran_c_section_common,
5962 tvb, offset, 0, "", "C-Plane Section Type ");
5963 proto_tree *section_tree = proto_item_add_subtree(sectionHeading, ett_oran_c_section_common);
5964
5965 /* Peek ahead at the section type */
5966 uint32_t sectionType = 0;
5967 sectionType = tvb_get_uint8(tvb, offset+5);
5968
5969 uint32_t scs = 0;
5970 proto_item *scs_ti = NULL((void*)0);
5971
5972 /* dataDirection */
5973 uint32_t direction = 0;
5974 proto_item *datadir_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_data_direction, tvb, offset, 1, ENC_NA0x00000000, &direction);
5975 tap_info->uplink = (direction==0);
5976
5977 /* Update/report status of conversation */
5978 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
5979
5980 if (state == NULL((void*)0)) {
5981 /* Allocate new state */
5982 state = wmem_new0(wmem_file_scope(), flow_state_t)((flow_state_t*)wmem_alloc0((wmem_file_scope()), sizeof(flow_state_t
)))
;
5983 state->ack_nack_requests = wmem_tree_new(wmem_file_scope());
5984 wmem_tree_insert32(flow_states_table, key, state);
5985 state->expected_dl_sections = wmem_tree_new(wmem_file_scope());
5986 }
5987
5988 /* Check sequence analysis status */
5989 if (state->last_frame_seen[direction] && (seq_id != state->next_expected_sequence_number[direction])) {
5990 /* Store this result */
5991 flow_result_t *result = wmem_new0(wmem_file_scope(), flow_result_t)((flow_result_t*)wmem_alloc0((wmem_file_scope()), sizeof(flow_result_t
)))
;
5992 result->unexpected_seq_number = true1;
5993 result->expected_sequence_number = state->next_expected_sequence_number[direction];
5994 result->previous_frame = state->last_frame[direction];
5995 wmem_tree_insert32(flow_results_table, pinfo->num, result);
5996 }
5997 /* Update conversation info */
5998 state->last_frame[direction] = pinfo->num;
5999 state->last_frame_seen[direction] = true1;
6000 state->next_expected_sequence_number[direction] = (seq_id+1) % 256;
6001 }
6002
6003 /* Show any issues associated with this frame number */
6004 flow_result_t *result = wmem_tree_lookup32(flow_results_table, pinfo->num);
6005 if (result!=NULL((void*)0) && result->unexpected_seq_number) {
6006 expert_add_info_format(pinfo, seq_id_ti,
6007 (direction == DIR_UPLINK0) ?
6008 &ei_oran_cplane_unexpected_sequence_number_ul :
6009 &ei_oran_cplane_unexpected_sequence_number_dl,
6010 "Sequence number %u expected, but got %u",
6011 result->expected_sequence_number, seq_id);
6012
6013 /* Update tap info */
6014 uint32_t missing_sns = (256 + seq_id - result->expected_sequence_number) % 256;
6015 /* Don't get confused by being slightly out of order.. */
6016 if (missing_sns < 128) {
6017 tap_info->missing_sns = missing_sns;
6018 }
6019 else {
6020 tap_info->missing_sns = 0;
6021 }
6022
6023 /* TODO: could add previous/next frames (in seqId tree?) ? */
6024 }
6025
6026 /* payloadVersion */
6027 dissect_payload_version(section_tree, tvb, pinfo, offset);
6028
6029 /* filterIndex */
6030 if (sectionType == SEC_C_SLOT_CONTROL || sectionType == SEC_C_ACK_NACK_FEEDBACK) {
6031 /* scs (for ST4 and ST8) */
6032 scs_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_frameStructure_subcarrier_spacing, tvb, offset, 1, ENC_NA0x00000000, &scs);
6033 }
6034 else if (sectionType == SEC_C_RRM_MEAS_REPORTS || sectionType == SEC_C_REQUEST_RRM_MEAS) {
6035 /* reserved (4 bits) */
6036 add_reserved_field(section_tree, hf_oran_reserved_last_4bits, tvb, offset, 1);
6037 }
6038 else if (sectionType != SEC_C_LAA) {
6039 /* filterIndex (most common case) */
6040 proto_tree_add_item(section_tree, hf_oran_filter_index, tvb, offset, 1, ENC_NA0x00000000);
6041 }
6042 offset += 1;
6043
6044 unsigned ref_a_offset = offset;
6045 /* frameId */
6046 uint32_t frameId = 0;
6047 proto_tree_add_item_ret_uint(section_tree, hf_oran_frame_id, tvb, offset, 1, ENC_NA0x00000000, &frameId);
6048 tap_info->frame = frameId;
6049 offset += 1;
6050
6051 /* subframeId */
6052 uint32_t subframeId = 0;
6053 proto_tree_add_item_ret_uint(section_tree, hf_oran_subframe_id, tvb, offset, 1, ENC_NA0x00000000, &subframeId);
6054 /* slotId */
6055 uint32_t slotId = 0;
6056 proto_tree_add_item_ret_uint(section_tree, hf_oran_slot_id, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &slotId);
6057 tap_info->slot = slotId;
6058 offset++;
6059
6060 /* startSymbolId */
6061 uint32_t startSymbolId = 0;
6062 proto_item *ssid_ti = NULL((void*)0);
6063 if ((sectionType == SEC_C_ACK_NACK_FEEDBACK) || /* Section Type 8 */
6064 (sectionType == SEC_C_SINR_REPORTING)) { /* Section Type 9 */
6065 /* symbolId */
6066 proto_tree_add_item_ret_uint(section_tree, hf_oran_symbolId, tvb, offset, 1, ENC_NA0x00000000, &startSymbolId);
6067 }
6068 else if (sectionType != SEC_C_LAA) {
6069 /* startSymbolId is in most section types */
6070 ssid_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_start_symbol_id, tvb, offset, 1, ENC_NA0x00000000, &startSymbolId);
6071 if (startSymbolId && (sectionType == SEC_C_RRM_MEAS_REPORTS)) { /* Section Type 10 */
6072 proto_item_append_text(ssid_ti, " (should be 0 for ST10!)");
6073 expert_add_info_format(pinfo, ssid_ti, &ei_oran_st10_startsymbolid_not_0,
6074 "startSymbolId should be 0 for ST10 - found %u", startSymbolId);
6075 }
6076 }
6077 else {
6078 /* reserved (6 bits) */
6079 add_reserved_field(section_tree, hf_oran_reserved_last_6bits, tvb, offset, 1);
6080 }
6081 offset++;
6082
6083
6084 char id[16];
6085 snprintf(id, 16, "%u-%u-%u-%u", frameId, subframeId, slotId, startSymbolId);
6086 proto_item *pi = proto_tree_add_string(section_tree, hf_oran_refa, tvb, ref_a_offset, 3, id);
6087 proto_item_set_generated(pi);
6088
6089 uint32_t cmd_scope = 0;
6090 bool_Bool st8_ready = false0;
6091
6092 /* numberOfSections (or whatever section has instead) */
6093 uint32_t nSections = 0;
6094 if (sectionType == SEC_C_SLOT_CONTROL) { /* Section Type 4 */
6095 /* Slot Control has these fields instead */
6096 /* reserved (4 bits) */
6097 add_reserved_field(section_tree, hf_oran_reserved_4bits, tvb, offset, 1);
6098 /* cmdScope (4 bits) */
6099 proto_tree_add_item_ret_uint(section_tree, hf_oran_cmd_scope, tvb, offset, 1, ENC_NA0x00000000, &cmd_scope);
6100 }
6101 else if (sectionType == SEC_C_ACK_NACK_FEEDBACK) { /* Section Type 8 */
6102 /* reserved (7 bits) */
6103 add_reserved_field(section_tree, hf_oran_reserved_7bits, tvb, offset, 1);
6104 /* ready (1 bit) */
6105 /* TODO: when set, ready in slotId+1.. */
6106 proto_tree_add_item_ret_boolean(section_tree, hf_oran_ready, tvb, offset, 1, ENC_NA0x00000000, &st8_ready);
6107 if (!st8_ready) {
6108 /* SCS value is ignored, and may be set to any value by O-RU */
6109 proto_item_append_text(scs_ti, " (ignored)");
6110 }
6111 }
6112 else if (sectionType != SEC_C_LAA) {
6113 /* numberOfSections */
6114 proto_tree_add_item_ret_uint(section_tree, hf_oran_numberOfSections, tvb, offset, 1, ENC_NA0x00000000, &nSections);
6115 }
6116 else {
6117 add_reserved_field(section_tree, hf_oran_reserved_8bits, tvb, offset, 1);
6118 }
6119 offset++;
6120
6121 /* sectionType */
6122 proto_tree_add_item_ret_uint(section_tree, hf_oran_sectionType, tvb, offset, 1, ENC_NA0x00000000, &sectionType);
6123 offset += 1;
6124
6125 /* Check that dataDirection is consistent with section type */
6126 if (sectionType == SEC_C_SINR_REPORTING && direction != 0) { /* Section Type 9 */
6127 expert_add_info(pinfo, datadir_ti, &ei_oran_st9_not_ul);
6128 }
6129 if (sectionType == SEC_C_RRM_MEAS_REPORTS && direction != 0) { /* Section Type 10 */
6130 expert_add_info(pinfo, datadir_ti, &ei_oran_st10_not_ul);
6131 }
6132
6133 /* Note this section type in stats */
6134 if (sectionType < SEC_C_MAX_INDEX) {
6135 tap_info->section_types[sectionType] = true1;
6136 }
6137
6138 /* Section-type-specific fields following common header (white entries in Section Type diagrams) */
6139 unsigned bit_width = 0;
6140 unsigned comp_meth = 0;
6141 proto_item *comp_meth_ti;
6142 unsigned ci_comp_method = 0;
6143 uint8_t ci_comp_opt = 0;
6144
6145 uint32_t num_ues = 0;
6146 uint32_t number_of_acks = 0, number_of_nacks = 0;
6147
6148 uint32_t num_sinr_per_prb = 0;
6149
6150 switch (sectionType) {
6151 case SEC_C_UNUSED_RB: /* Section Type 0 */
6152 /* timeOffset */
6153 proto_tree_add_item(section_tree, hf_oran_timeOffset, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6154 offset += 2;
6155 /* frameStructure */
6156 offset = dissect_frame_structure(section_tree, tvb, offset,
6157 subframeId, slotId);
6158
6159 /* cpLength */
6160 proto_tree_add_item(section_tree, hf_oran_cpLength, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6161 offset += 2;
6162 /* reserved (8 bits) */
6163 add_reserved_field(section_tree, hf_oran_reserved_8bits, tvb, offset, 1);
6164 offset += 1;
6165 break;
6166
6167 case SEC_C_NORMAL: /* Section Type 1 */
6168 case SEC_C_UE_SCHED: /* Section Type 5 */
6169 /* udCompHdr */
6170 offset = dissect_udcomphdr(tvb, pinfo, section_tree, offset,
6171 true1, direction==0 && pref_override_ul_compression, /* ignore for DL or if using mplane for UL settings */
6172 &bit_width, &comp_meth, &comp_meth_ti, tap_info);
6173 /* reserved (8 bits) */
6174 add_reserved_field(section_tree, hf_oran_reserved_8bits, tvb, offset, 1);
6175 offset += 1;
6176 break;
6177
6178 case SEC_C_SLOT_CONTROL: /* Section Type 4 */
6179 break;
6180
6181 case SEC_C_PRACH: /* Section Type 3 */
6182 /* timeOffset */
6183 proto_tree_add_item(section_tree, hf_oran_timeOffset, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6184 offset += 2;
6185 /* frameStructure */
6186 offset = dissect_frame_structure(section_tree, tvb, offset,
6187 subframeId, slotId);
6188 /* cpLength */
6189 proto_tree_add_item(section_tree, hf_oran_cpLength, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6190 offset += 2;
6191 /* udCompHdr */
6192 offset = dissect_udcomphdr(tvb, pinfo, section_tree, offset,
6193 true1, direction==0 && pref_override_ul_compression, /* ignore for DL or if using mplane for UL settings */
6194 &bit_width, &comp_meth, &comp_meth_ti, tap_info);
6195 break;
6196
6197 case SEC_C_CH_INFO: /* Section Type 6 */
6198 /* numberOfUEs */
6199 proto_tree_add_item_ret_uint(section_tree, hf_oran_numberOfUEs, tvb, offset, 1, ENC_NA0x00000000, &num_ues);
6200 offset += 1;
6201 /* ciCompHdr (was reserved) */
6202 offset = dissect_cicomphdr(tvb, pinfo, section_tree, offset, &bit_width, &ci_comp_method, &ci_comp_opt);
6203
6204 /* Number of sections may not be filled in (at all, or correctly), so set to the number of UEs.
6205 The data entries are per-UE... they don't have a sectionID, but they could have section extensions... */
6206 if (nSections == 0 || num_ues > nSections) {
6207 nSections = num_ues;
6208 }
6209 break;
6210
6211 case SEC_C_RSVD2:
6212 break;
6213
6214 case SEC_C_LAA: /* Section Type 7 */
6215 add_reserved_field(section_tree, hf_oran_reserved_16bits, tvb, offset, 2);
6216 offset += 2;
6217 break;
6218
6219 case SEC_C_ACK_NACK_FEEDBACK: /* Section Type 8 */
6220 /* numberOfAcks (1 byte) */
6221 proto_tree_add_item_ret_uint(section_tree, hf_oran_number_of_acks, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &number_of_acks);
6222 offset += 1;
6223 /* numberOfNacks (1 byte) */
6224 proto_tree_add_item_ret_uint(section_tree, hf_oran_number_of_nacks, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &number_of_nacks);
6225 offset += 1;
6226
6227 /* Show ACKs and NACKs. For both, try to link back to request. */
6228 for (unsigned int n=1; n <= number_of_acks; n++) {
6229 uint32_t ackid;
6230 proto_item *ack_ti;
6231 ack_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_ackid, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &ackid);
6232 offset += 2;
6233
6234 /* Look up request table in state (which really should be set by now, but test anyway). */
6235 if (state && state->ack_nack_requests) {
6236 ack_nack_request_t *request = wmem_tree_lookup32(state->ack_nack_requests, ackid);
6237 if (request != NULL((void*)0)) {
6238 /* On first pass, update with this response */
6239 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
6240 request->response_frame_number = pinfo->num;
6241 request->response_frame_time = pinfo->abs_ts;
6242 }
6243
6244 /* Show request details */
6245 show_link_to_acknack_request(section_tree, tvb, pinfo, request);
6246 }
6247 else {
6248 /* Request not found */
6249 expert_add_info_format(pinfo, ack_ti, &ei_oran_acknack_no_request,
6250 "Response for ackId=%u received, but no request found",
6251 ackid);
6252 }
6253 }
6254 }
6255 for (unsigned int m=1; m <= number_of_nacks; m++) {
6256 uint32_t nackid;
6257 proto_item *nack_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_nackid, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &nackid);
6258 offset += 2;
6259
6260 expert_add_info_format(pinfo, nack_ti, &ei_oran_st8_nackid,
6261 "Received Nack for ackNackId=%u",
6262 nackid);
6263
6264 /* Look up request table in state. */
6265 if (state && state->ack_nack_requests) {
6266 ack_nack_request_t *request = wmem_tree_lookup32(state->ack_nack_requests, nackid);
6267 if (request) {
6268 /* On first pass, update with this response */
6269 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
6270 request->response_frame_number = pinfo->num;
6271 request->response_frame_time = pinfo->abs_ts;
6272 }
6273
6274 /* Show request details */
6275 show_link_to_acknack_request(section_tree, tvb, pinfo, request);
6276 }
6277 else {
6278 /* Request not found */
6279 expert_add_info_format(pinfo, nack_ti, &ei_oran_acknack_no_request,
6280 "Response for nackId=%u received, but no request found",
6281 nackid);
6282 }
6283 }
6284 }
6285 break;
6286
6287 case SEC_C_SINR_REPORTING: /* Section Type 9 */
6288 {
6289 /* numSinrPerPrb (3 bits) */
6290 proto_item *nspp_ti;
6291 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);
6292 switch (num_sinr_per_prb) {
6293 case 0:
6294 num_sinr_per_prb = 1; break;
6295 case 1:
6296 num_sinr_per_prb = 2; break;
6297 case 2:
6298 num_sinr_per_prb = 3; break;
6299 case 3:
6300 num_sinr_per_prb = 4; break;
6301 case 4:
6302 num_sinr_per_prb = 6; break;
6303 case 5:
6304 num_sinr_per_prb = 12; break;
6305
6306 default:
6307 proto_item_append_text(nspp_ti, " (invalid)");
6308 num_sinr_per_prb = 1;
6309 expert_add_info_format(pinfo, nspp_ti, &ei_oran_num_sinr_per_prb_unknown,
6310 "Invalid numSinrPerPrb value (%u)",
6311 num_sinr_per_prb);
6312 }
6313
6314 /* oruControlSinrSlotMaskId (5 bits) */
6315 proto_tree_add_item(section_tree, hf_oran_oru_control_sinr_slot_mask_id, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6316 offset += 1;
6317 /* reserved (8 bits) */
6318 add_reserved_field(section_tree, hf_oran_reserved_8bits, tvb, offset, 1);
6319 offset += 1;
6320 break;
6321 }
6322
6323 case SEC_C_RRM_MEAS_REPORTS: /* Section Type 10 */
6324 case SEC_C_REQUEST_RRM_MEAS: /* Section Type 11 */
6325 /* reserved (16 bits) */
6326 add_reserved_field(section_tree, hf_oran_reserved_16bits, tvb, offset, 2);
6327 offset += 2;
6328 break;
6329 };
6330
6331 /* Update udCompHdr details in state for UL U-Plane */
6332 if (state && direction==0) {
6333 switch (sectionType) {
6334 case SEC_C_NORMAL: /* Section Type 1 */
6335 case SEC_C_PRACH: /* Section Type 3 */
6336 case SEC_C_UE_SCHED: /* Section Type 5 */
6337 state->ul_ud_comp_hdr_set = true1;
6338 state->ul_ud_comp_hdr_bit_width = bit_width;
6339 state->ul_ud_comp_hdr_compression = comp_meth;
6340 state->ul_ud_comp_hdr_frame = pinfo->num;
6341 break;
6342 default:
6343 break;
6344 }
6345 }
6346
6347
6348 proto_item_append_text(sectionHeading, "%d, %s, frameId: %d, subframeId: %d, slotId: %d, startSymbolId: %d",
6349 sectionType, val_to_str_const(direction, data_direction_vals, "Unknown"),
6350 frameId, subframeId, slotId, startSymbolId);
6351 if (nSections) {
6352 proto_item_append_text(sectionHeading, ", numberOfSections=%u", nSections);
6353 }
6354
6355 write_pdu_label_and_info(protocol_item, NULL((void*)0), pinfo, ", Type: %2d %s", sectionType,
6356 rval_to_str_const(sectionType, section_types_short, "Unknown"));
6357
6358 /* Set actual length of C-Plane section header */
6359 proto_item_set_len(section_tree, offset - section_tree_offset);
6360
6361 if (sectionType == SEC_C_ACK_NACK_FEEDBACK) {
6362 write_pdu_label_and_info(oran_tree, section_tree, pinfo,
6363 (st8_ready) ? " (Ready)" : " (ACK)");
6364 }
6365
6366
6367 /* Section type 4 doesn't have normal sections, so deal with here before normal sections */
6368 if (sectionType == SEC_C_SLOT_CONTROL) {
6369 /* numberOfST4Cmds */
6370 uint32_t no_st4_cmds, st4_cmd_len, num_slots, ack_nack_req_id, st4_cmd_type;
6371 proto_item *no_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_number_of_st4_cmds,
6372 tvb, offset, 1, ENC_NA0x00000000, &no_st4_cmds);
6373 if (no_st4_cmds == 0) {
6374 expert_add_info(pinfo, no_ti, &ei_oran_st4_no_cmds);
6375 }
6376 offset += 1;
6377
6378 /* reserved (1 byte) */
6379 add_reserved_field(section_tree, hf_oran_reserved_8bits, tvb, offset, 1);
6380 offset += 1;
6381
6382 /* Loop over commands. Each has 8-byte common header, followed by cmd-specific payload */
6383 proto_item *len_ti;
6384 for (uint32_t n=0; n < no_st4_cmds; n++) {
6385 /* Table 7.4.6-2: Section Type 4 Command common header format */
6386 proto_item *hdr_ti = proto_tree_add_string_format(section_tree, hf_oran_st4_cmd_header,
6387 tvb, offset, 8, "",
6388 "Type 4 Command common header");
6389 proto_tree *hdr_tree = proto_item_add_subtree(hdr_ti, ett_oran_st4_cmd_header);
6390
6391 /* st4CmdType */
6392 proto_tree_add_item_ret_uint(hdr_tree, hf_oran_st4_cmd_type, tvb, offset, 1, ENC_NA0x00000000, &st4_cmd_type);
6393 offset += 1;
6394
6395 /* st4CmdLen */
6396 len_ti = proto_tree_add_item_ret_uint(hdr_tree, hf_oran_st4_cmd_len, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &st4_cmd_len);
6397 if (st4_cmd_len == 0) {
6398 /* Meaning of 0 not yet defined (v15.00) */
6399 proto_item_append_text(len_ti, " (reserved)");
6400 expert_add_info(pinfo, len_ti, &ei_oran_st4_zero_len_cmd);
6401 }
6402 else {
6403 proto_item_append_text(len_ti, " (%u bytes)", st4_cmd_len*4);
6404 }
6405 offset += 2;
6406
6407 /* numSlots */
6408 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);
6409 if (num_slots == 0) {
6410 proto_item_append_text(slots_ti, " (until changed)");
6411 }
6412 offset += 1;
6413
6414 /* ackNackReqId */
6415 proto_item *ack_nack_req_id_ti;
6416 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);
6417 offset += 2;
6418 if (ack_nack_req_id == 0) {
6419 proto_item_append_text(ack_nack_req_id_ti, " (no Section type 8 response expected)");
6420 }
6421
6422 /* reserved (16 bits) */
6423 add_reserved_field(hdr_tree, hf_oran_reserved_16bits, tvb, offset, 2);
6424 offset += 2;
6425
6426 /* Set common header summary */
6427 proto_item_append_text(hdr_ti, " (cmd=%s, len=%u, slots=%u, ackNackReqId=%u)",
6428 rval_to_str_const(st4_cmd_type, st4_cmd_type_vals, "Unknown"),
6429 st4_cmd_len, num_slots, ack_nack_req_id);
6430
6431 col_append_fstr(pinfo->cinfo, COL_INFO, " (%s)",
6432 rval_to_str_const(st4_cmd_type, st4_cmd_type_vals, "Unknown"));
6433
6434
6435 /* Subtree for this command body */
6436 proto_item *command_ti = proto_tree_add_string_format(section_tree, hf_oran_st4_cmd,
6437 tvb, offset, 0, "",
6438 "Type 4 Command (%s)", rval_to_str_const(st4_cmd_type, st4_cmd_type_vals, "Unknown"));
6439 proto_tree *command_tree = proto_item_add_subtree(command_ti, ett_oran_st4_cmd);
6440
6441 unsigned command_start_offset = offset;
6442
6443 /* Check fields compatible with chosen command. */
6444 if (st4_cmd_type==1) {
6445 if (num_slots != 0) {
6446 /* "the value of numSlots should be set to zero for this command type" */
6447 expert_add_info_format(pinfo, slots_ti, &ei_oran_numslots_not_zero,
6448 "numSlots should be zero for ST4 command 1 - found %u",
6449 num_slots);
6450 }
6451 }
6452
6453 if (st4_cmd_type==3 || st4_cmd_type==4) {
6454 if (startSymbolId != 0) {
6455 /* "expected reception window for the commands is the symbol zero reception window" */
6456 expert_add_info_format(pinfo, ssid_ti, &ei_oran_start_symbol_id_not_zero,
6457 "startSymbolId should be zero for ST4 commands 3&4 - found %u",
6458 startSymbolId);
6459 }
6460 }
6461
6462 /* Add format for this command */
6463 switch (st4_cmd_type) {
6464 case 1: /* TIME_DOMAIN_BEAM_CONFIG */
6465 {
6466 bool_Bool disable_tdbfns;
6467 uint32_t bfwcomphdr_iq_width, bfwcomphdr_comp_meth;
6468
6469 /* Hidden filter for bf */
6470 proto_item *bf_ti = proto_tree_add_item(command_tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
6471 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
6472
6473 /* reserved (2 bits) */
6474 add_reserved_field(command_tree, hf_oran_reserved_2bits, tvb, offset, 1);
6475 /* symbolMask (14 bits) */
6476 uint32_t symbol_mask;
6477 proto_item *symbol_mask_ti;
6478 offset = dissect_symbolmask(tvb, command_tree, offset, &symbol_mask, &symbol_mask_ti);
6479 /* 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 */
6480 /* lsb is symbol 0 */
6481 for (unsigned s=0; s < 14; s++) {
6482 if ((startSymbolId & (1 << s)) && (startSymbolId > s)) {
6483 proto_item_append_text(symbol_mask_ti, " (startSymbolId is %u, so some lower symbol bits ignored!)", startSymbolId);
6484 expert_add_info(pinfo, symbol_mask_ti, &ei_oran_start_symbol_id_bits_ignored);
6485 break;
6486 }
6487 }
6488
6489 /* disableTDBFNs (1 bit) */
6490 proto_tree_add_item_ret_boolean(command_tree, hf_oran_disable_tdbfns, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &disable_tdbfns);
6491
6492 /* tdBeamNum (15 bits) */
6493 proto_tree_add_item(command_tree, hf_oran_td_beam_num, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6494 offset += 2;
6495
6496 /* bfwCompHdr (2 subheaders - bfwIqWidth and bfwCompMeth)*/
6497 offset = dissect_bfwCompHdr(tvb, command_tree, offset,
6498 &bfwcomphdr_iq_width, &bfwcomphdr_comp_meth, &comp_meth_ti);
6499 /* reserved (3 bytes) */
6500 proto_tree_add_bits_item(command_tree, hf_oran_reserved, tvb, offset*8, 24, ENC_BIG_ENDIAN0x00000000);
6501 offset += 3;
6502
6503 if (disable_tdbfns) {
6504 /* No beamnum information to show so get out. */
6505 break;
6506 }
6507
6508 /* Read beam entries until reach end of command length */
6509 while ((offset - command_start_offset) < (st4_cmd_len * 4)) {
6510
6511 /* disableTDBFWs (1 bit) */
6512 bool_Bool disable_tdbfws;
6513 proto_tree_add_item_ret_boolean(command_tree, hf_oran_disable_tdbfws, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &disable_tdbfws);
6514
6515 /* tdBeamNum (15 bits) */
6516 proto_tree_add_item(command_tree, hf_oran_td_beam_num, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6517 offset += 2;
6518
6519 /* Showing BFWs? */
6520 if (!disable_tdbfws) {
6521
6522 /* bfwCompParam */
6523 unsigned exponent = 0;
6524 bool_Bool supported = false0;
6525 unsigned num_trx_entries;
6526 uint16_t *trx_entries;
6527 offset = dissect_bfwCompParam(tvb, command_tree, pinfo, offset, comp_meth_ti,
6528 &bfwcomphdr_comp_meth, &exponent, &supported,
6529 &num_trx_entries, &trx_entries);
6530
6531 /* Antenna count from preference */
6532 unsigned num_trx = pref_num_bf_antennas;
6533 int bit_offset = offset*8;
6534
6535 for (unsigned trx=0; trx < num_trx; trx++) {
6536 /* Create antenna subtree */
6537 int bfw_offset = bit_offset / 8;
6538 proto_item *bfw_ti = proto_tree_add_string_format(command_tree, hf_oran_bfw,
6539 tvb, bfw_offset, 0, "", "TRX %3u: (", trx);
6540 proto_tree *bfw_tree = proto_item_add_subtree(bfw_ti, ett_oran_bfw);
6541
6542 /* I value */
6543 /* Get bits, and convert to float. */
6544 uint32_t bits = tvb_get_bits32(tvb, bit_offset, bfwcomphdr_iq_width, ENC_BIG_ENDIAN0x00000000);
6545 float value = decompress_value(bits, bfwcomphdr_comp_meth, bfwcomphdr_iq_width, exponent, NULL((void*)0) /* no ModCompr*/, 0 /* RE */);
6546 /* Add to tree. */
6547 proto_tree_add_float(bfw_tree, hf_oran_bfw_i, tvb, bit_offset/8,
6548 (bfwcomphdr_iq_width+7)/8, value);
6549 bit_offset += bfwcomphdr_iq_width;
6550 proto_item_append_text(bfw_ti, "I=%f ", value);
6551
6552 /* Leave a gap between I and Q values */
6553 proto_item_append_text(bfw_ti, " ");
6554
6555 /* Q value */
6556 /* Get bits, and convert to float. */
6557 bits = tvb_get_bits32(tvb, bit_offset, bfwcomphdr_iq_width, ENC_BIG_ENDIAN0x00000000);
6558 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_q, tvb, bit_offset/8,
6561 (bfwcomphdr_iq_width+7)/8, value);
6562 bit_offset += bfwcomphdr_iq_width;
6563 proto_item_append_text(bfw_ti, "Q=%f", value);
6564
6565 proto_item_append_text(bfw_ti, ")");
6566 proto_item_set_len(bfw_ti, (bit_offset+7)/8 - bfw_offset);
6567 }
6568 /* Need to round to next byte */
6569 offset = (bit_offset+7)/8;
6570 }
6571 }
6572 break;
6573 }
6574 case 2: /* TDD_CONFIG_PATTERN */
6575 /* reserved (2 bits) */
6576 add_reserved_field(command_tree, hf_oran_reserved_2bits, tvb, offset, 1);
6577 /* dirPattern (14 bits) */
6578 proto_tree_add_item(command_tree, hf_oran_dir_pattern, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6579 offset += 2;
6580
6581 /* reserved (2 bits) */
6582 add_reserved_field(command_tree, hf_oran_reserved_2bits, tvb, offset, 1);
6583 /* guardPattern (14 bits) */
6584 proto_tree_add_item(command_tree, hf_oran_guard_pattern, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6585 offset += 2;
6586 break;
6587
6588 case 3: /* TRX_CONTROL */
6589 case 5: /* TRX_CONTROL_BIDIR */
6590 {
6591 /* Only allowed cmdScope is ARRAY-COMMAND */
6592 if (cmd_scope != 0) {
6593 expert_add_info(pinfo, command_tree, &ei_oran_trx_control_cmd_scope);
6594 }
6595
6596 /* reserved (2 bits) */
6597 add_reserved_field(command_tree, hf_oran_reserved_2bits, tvb, offset, 1);
6598 /* log2MaskBits (4 bits) */
6599 unsigned log2maskbits;
6600 proto_tree_add_item_ret_uint(command_tree, hf_oran_log2maskbits, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &log2maskbits);
6601 /* sleepMode (2 bits) */
6602 uint32_t sleep_mode;
6603 proto_tree_add_item_ret_uint(command_tree, hf_oran_sleepmode_trx, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &sleep_mode);
6604 offset += 1;
6605
6606 /* reserved (4 bits) */
6607 add_reserved_field(command_tree, hf_oran_reserved_4bits, tvb, offset, 1);
6608 /* numSlotsExt (20 bits) */
6609 uint32_t num_slots_ext;
6610 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);
6611 if (num_slots==0 && num_slots_ext==0) {
6612 proto_item_append_text(num_slots_ext_ti, " (undefined sleep period)");
6613 }
6614 else {
6615 /* Time should be rounded up according to SCS */
6616 float total = (float)(num_slots + num_slots_ext);
6617 /* From table 7.5.2.13-3 */
6618 const float slot_length_by_scs[16] = { 1000, 500, 250, 125, 62.5, 31.25,
6619 0, 0, 0, 0, 0, 0, /* reserved */
6620 1000, 1000, 1000, 1000 };
6621 float slot_length = slot_length_by_scs[scs];
6622 /* Only using valid SCS. TODO: is this test ok? */
6623 if (slot_length != 0) {
6624 /* Round up to next slot */
6625 total = ((int)(total / slot_length) + 1) * slot_length;
6626 proto_item_append_text(num_slots_ext_ti, " (defined sleep period of %f us)", total);
6627 }
6628 }
6629 offset += 3;
6630
6631 /* reserved (2 bits) */
6632 add_reserved_field(command_tree, hf_oran_reserved_2bits, tvb, offset, 1);
6633
6634 /* symbolMask (14 bits) */
6635 uint32_t symbol_mask;
6636 proto_item *sm_ti;
6637 offset = dissect_symbolmask(tvb, command_tree, offset, &symbol_mask, &sm_ti);
6638 if (symbol_mask == 0x0) {
6639 proto_item_append_text(sm_ti, " (wake)");
6640 col_append_str(pinfo->cinfo, COL_INFO, " (wake)");
6641 }
6642 else if (symbol_mask == 0x3fff) {
6643 proto_item_append_text(sm_ti, " (sleep)");
6644 col_append_str(pinfo->cinfo, COL_INFO, " (sleep)");
6645 }
6646 else {
6647 expert_add_info_format(pinfo, sm_ti, &ei_oran_bad_symbolmask,
6648 "For non-zero sleepMode (%u), symbolMask should be 0x0 or 0x3fff - found 0x%05x",
6649 sleep_mode, symbol_mask);
6650 }
6651 offset += 2;
6652
6653 /* antMask (16-2048 bits). Size is lookup from log2MaskBits enum.. */
6654 unsigned antmask_length = 2;
6655 if (log2maskbits >= 4) {
6656 antmask_length = (1 << log2maskbits) / 8;
6657 }
6658 proto_item *ant_mask_ti = proto_tree_add_item(command_tree, hf_oran_antMask_trx_control, tvb, offset, antmask_length, ENC_NA0x00000000);
6659 /* show count */
6660 unsigned antenna_count = 0;
6661 for (unsigned b=0; b < antmask_length; b++) {
6662 uint8_t byte = tvb_get_uint8(tvb, offset+b);
6663 for (unsigned bit=0; bit < 8; bit++) {
6664 if ((1 << bit) & byte) {
6665 antenna_count++;
6666 }
6667 }
6668 }
6669 proto_item_append_text(ant_mask_ti, " (%u antennas)", antenna_count);
6670 offset += antmask_length;
6671
6672 /* Pad to next 4-byte boundary */
6673 offset = WS_ROUNDUP_4(offset)(((offset) + ((unsigned)(4U-1U))) & (~((unsigned)(4U-1U))
))
;
6674 break;
6675 }
6676
6677 case 4: /* ASM (advanced sleep mode) */
6678 /* reserved (2+4=6 bits) */
6679 add_reserved_field(command_tree, hf_oran_reserved_6bits, tvb, offset, 1);
6680 /* sleepMode (2 bits) */
6681 uint32_t sleep_mode;
6682 proto_tree_add_item_ret_uint(command_tree, hf_oran_sleepmode_asm, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &sleep_mode);
6683 offset += 1;
6684
6685 /* reserved (4 bits) */
6686 add_reserved_field(command_tree, hf_oran_reserved_4bits, tvb, offset, 1);
6687 /* numSlotsExt (20 bits) */
6688 proto_tree_add_item(command_tree, hf_oran_num_slots_ext, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6689 offset += 3;
6690
6691 /* reserved (2 bits) */
6692 add_reserved_field(command_tree, hf_oran_reserved_2bits, tvb, offset, 1);
6693 /* symbolMask (14 bits) */
6694 uint32_t symbol_mask;
6695 proto_item *sm_ti;
6696 offset = dissect_symbolmask(tvb, command_tree, offset, &symbol_mask, &sm_ti);
6697 if (symbol_mask == 0x0) {
6698 proto_item_append_text(sm_ti, " (wake)");
6699 col_append_str(pinfo->cinfo, COL_INFO, " (wake)");
6700 }
6701 else if (symbol_mask == 0x3fff) {
6702 proto_item_append_text(sm_ti, " (sleep)");
6703 col_append_str(pinfo->cinfo, COL_INFO, " (sleep)");
6704 }
6705 else {
6706 expert_add_info_format(pinfo, sm_ti, &ei_oran_bad_symbolmask,
6707 "For non-zero sleepMode (%u), symbolMask should be 0x0 or 0x3fff - found 0x%05x",
6708 sleep_mode, symbol_mask);
6709 }
6710 offset += 2;
6711
6712 /* reserved (2 bytes) */
6713 add_reserved_field(command_tree, hf_oran_reserved_16bits, tvb, offset, 2);
6714 offset += 2;
6715 break;
6716
6717 default:
6718 /* Error! */
6719 expert_add_info_format(pinfo, len_ti, &ei_oran_st4_unknown_cmd,
6720 "Dissected ST4 command (%u) not recognised",
6721 st4_cmd_type);
6722 break;
6723 }
6724
6725 /* Check apparent size of padding (0-3 bytes ok) */
6726 long padding_remaining = command_start_offset + (st4_cmd_len * 4) - offset;
6727 if (padding_remaining > 3) {
6728 expert_add_info_format(pinfo, len_ti, &ei_oran_st4_wrong_len_cmd,
6729 "Dissected ST4 command does not match signalled st4CmdLen - set to %u (%u bytes) but dissected %u bytes",
6730 st4_cmd_len, st4_cmd_len*4, offset-command_start_offset);
6731 }
6732
6733 /* Advance by signalled length (needs to be aligned on 4-byte boundary) */
6734 offset = command_start_offset + (st4_cmd_len * 4);
6735
6736 /* Set end of command tree */
6737 proto_item_set_end(command_ti, tvb, offset);
6738
6739 if (ack_nack_req_id != 0 && state && state->ack_nack_requests) {
6740 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
6741 /* Add this request into conversation state on first pass */
6742 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)))
;
6743 request_details->request_frame_number = pinfo->num;
6744 request_details->request_frame_time = pinfo->abs_ts;
6745 request_details->requestType = ST4Cmd1+st4_cmd_type-1;
6746
6747 wmem_tree_insert32(state->ack_nack_requests,
6748 ack_nack_req_id,
6749 request_details);
6750 }
6751 else {
6752 /* On later passes, try to link forward to ST8 response */
6753 ack_nack_request_t *response = wmem_tree_lookup32(state->ack_nack_requests,
6754 ack_nack_req_id);
6755 if (response) {
6756 show_link_to_acknack_response(section_tree, tvb, pinfo, response);
6757 }
6758 }
6759 }
6760 }
6761 }
6762 /* LAA doesn't have sections either.. */
6763 else if (sectionType == SEC_C_LAA) { /* Section Type 7 */
6764 /* 7.2.5 Table 6.4-6 */
6765 unsigned mcot;
6766 proto_item *mcot_ti;
6767
6768 /* laaMsgType */
6769 uint32_t laa_msg_type;
6770 proto_item *laa_msg_type_ti;
6771 laa_msg_type_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_laaMsgType, tvb, offset, 1, ENC_NA0x00000000, &laa_msg_type);
6772 /* laaMsgLen */
6773 uint32_t laa_msg_len;
6774 proto_item *len_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_laaMsgLen, tvb, offset, 1, ENC_NA0x00000000, &laa_msg_len);
6775 proto_item_append_text(len_ti, " (%u bytes)", 4*laa_msg_len);
6776 if (laa_msg_len == 0) {
6777 proto_item_append_text(len_ti, " (reserved)");
6778 }
6779 offset += 1;
6780
6781 int payload_offset = offset;
6782
6783 /* Payload */
6784 switch (laa_msg_type) {
6785 case 0:
6786 /* LBT_PDSCH_REQ */
6787 /* lbtHandle (16 bits) */
6788 proto_tree_add_item(section_tree, hf_oran_lbtHandle, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6789 offset += 2;
6790 /* lbtOffset (10 bits) */
6791 proto_tree_add_item(section_tree, hf_oran_lbtOffset, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6792 offset += 1;
6793 /* lbtMode (2 bits) */
6794 proto_tree_add_bits_item(section_tree, hf_oran_lbtMode, tvb, offset*8+2, 2, ENC_BIG_ENDIAN0x00000000);
6795 /* reserved (1 bit) */
6796 add_reserved_field(section_tree, hf_oran_reserved_bit4, tvb, offset, 1);
6797 /* lbtDeferFactor (3 bits) */
6798 proto_tree_add_item(section_tree, hf_oran_lbtDeferFactor, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6799 offset += 1;
6800 /* lbtBackoffCounter (10 bits) */
6801 proto_tree_add_item(section_tree, hf_oran_lbtBackoffCounter, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6802 offset += 1;
6803 /* MCOT (4 bits) */
6804 mcot_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_MCOT, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &mcot);
6805 if (mcot<1 || mcot>10) {
6806 proto_item_append_text(mcot_ti, " (should be in range 1-10!)");
6807 expert_add_info_format(pinfo, mcot_ti, &ei_oran_mcot_out_of_range,
6808 "MCOT seen with value %u (must be 1-10)", mcot);
6809
6810 }
6811 /* reserved (10 bits) */
6812 proto_tree_add_bits_item(section_tree, hf_oran_reserved, tvb, (offset*8)+6, 10, ENC_BIG_ENDIAN0x00000000);
6813 break;
6814 case 1:
6815 /* LBT_DRS_REQ */
6816 /* lbtHandle (16 bits) */
6817 proto_tree_add_item(section_tree, hf_oran_lbtHandle, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6818 offset += 2;
6819 /* lbtOffset (10 bits) */
6820 proto_tree_add_item(section_tree, hf_oran_lbtOffset, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6821 offset += 1;
6822 /* lbtMode (2 bits) */
6823 proto_tree_add_bits_item(section_tree, hf_oran_lbtMode, tvb, offset*8+2, 2, ENC_BIG_ENDIAN0x00000000);
6824 /* reserved (28 bits) */
6825 proto_tree_add_bits_item(section_tree, hf_oran_reserved, tvb, (offset*8)+4, 28, ENC_BIG_ENDIAN0x00000000);
6826 break;
6827 case 2:
6828 /* LBT_PDSCH_RSP */
6829 /* lbtHandle (16 bits) */
6830 proto_tree_add_item(section_tree, hf_oran_lbtHandle, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6831 offset += 2;
6832 /* lbtPdschRes (2 bits) */
6833 proto_tree_add_item(section_tree, hf_oran_lbtPdschRes, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6834 /* inParSF (1 bit) */
6835 proto_tree_add_item(section_tree, hf_oran_initialPartialSF, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6836 /* sfStatus (1 bit) */
6837 proto_tree_add_item(section_tree, hf_oran_sfStatus, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6838 /* sfnSf (12 bits) */
6839 proto_tree_add_item(section_tree, hf_oran_sfnSfEnd, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6840 offset += 2;
6841 /* reserved (24 bits) */
6842 proto_tree_add_bits_item(section_tree, hf_oran_reserved, tvb, (offset*8), 24, ENC_BIG_ENDIAN0x00000000);
6843 break;
6844 case 3:
6845 /* LBT_DRS_RSP */
6846 /* lbtHandle (16 bits) */
6847 proto_tree_add_item(section_tree, hf_oran_lbtHandle, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6848 offset += 2;
6849 /* lbtDrsRes (1 bit) */
6850 proto_tree_add_item(section_tree, hf_oran_lbtDrsRes, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6851 /* reserved (7 bits) */
6852 add_reserved_field(section_tree, hf_oran_reserved_last_7bits, tvb, offset, 1);
6853 break;
6854 case 4:
6855 /* LBT_Buffer_Error */
6856 /* lbtHandle (16 bits) */
6857 proto_tree_add_item(section_tree, hf_oran_lbtHandle, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6858 offset += 2;
6859 /* lbtBufErr (1 bit) */
6860 proto_tree_add_item(section_tree, hf_oran_lbtBufErr, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6861 /* reserved (7 bits) */
6862 add_reserved_field(section_tree, hf_oran_reserved_last_7bits, tvb, offset, 1);
6863 break;
6864 case 5:
6865 /* LBT_CWCONFIG_REQ */
6866 /* lbtHandle (16 bits) */
6867 proto_tree_add_item(section_tree, hf_oran_lbtHandle, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6868 offset += 2;
6869 /* lbtCWConfig_H (8 bits) */
6870 proto_tree_add_item(section_tree, hf_oran_lbtCWConfig_H, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6871 offset += 1;
6872 /* lbtCWConfig_T (8 bits) */
6873 proto_tree_add_item(section_tree, hf_oran_lbtCWConfig_T, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6874 offset += 1;
6875 /* lbtMode (2 bits) */
6876 proto_tree_add_bits_item(section_tree, hf_oran_lbtMode, tvb, offset*8, 2, ENC_BIG_ENDIAN0x00000000);
6877 /* lbtTrafficClass (3 bits) */
6878 proto_tree_add_item(section_tree, hf_oran_lbtTrafficClass, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6879 /* reserved (19 bits) */
6880 proto_tree_add_bits_item(section_tree, hf_oran_reserved, tvb, (offset*8)+5, 19, ENC_BIG_ENDIAN0x00000000);
6881 break;
6882 case 6:
6883 /* LBT_CWCONFIG_RSP */
6884 /* lbtHandle (16 bits) */
6885 proto_tree_add_item(section_tree, hf_oran_lbtHandle, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6886 offset += 2;
6887 /* lbtCWR_Rst (1 bit) */
6888 proto_tree_add_item(section_tree, hf_oran_lbtCWR_Rst, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6889 /* reserved (7 bits) */
6890 add_reserved_field(section_tree, hf_oran_reserved_last_7bits, tvb, offset, 1);
6891 break;
6892
6893 default:
6894 /* Unhandled! */
6895 expert_add_info_format(pinfo, laa_msg_type_ti, &ei_oran_laa_msg_type_unsupported,
6896 "laaMsgType %u not supported by dissector",
6897 laa_msg_type);
6898
6899 break;
6900 }
6901 /* For now just skip indicated length of bytes */
6902 offset = payload_offset + 4*(laa_msg_len+1);
6903 }
6904
6905
6906 /* Dissect each C section */
6907 for (uint32_t i = 0; i < nSections; ++i) {
6908 tvbuff_t *section_tvb = tvb_new_subset_remaining(tvb, offset);
6909 offset += dissect_oran_c_section(section_tvb, oran_tree, pinfo, state, sectionType, tap_info,
6910 protocol_item,
6911 subframeId, frameId, slotId, startSymbolId,
6912 bit_width, ci_comp_method, ci_comp_opt,
6913 num_sinr_per_prb);
6914 }
6915
6916 /* Expert error if we are short of tvb by > 3 bytes */
6917 if (tvb_reported_length_remaining(tvb, offset) > 3) {
6918 expert_add_info_format(pinfo, protocol_item, &ei_oran_frame_length,
6919 "%u bytes remain at end of frame - should be 0-3",
6920 tvb_reported_length_remaining(tvb, offset));
6921 }
6922
6923 return tvb_captured_length(tvb);
6924}
6925
6926static int dissect_oran_u_re(tvbuff_t *tvb, proto_tree *tree,
6927 unsigned sample_number, int samples_offset,
6928 oran_tap_info *tap_info,
6929 unsigned sample_bit_width,
6930 int comp_meth,
6931 uint32_t exponent,
6932 section_mod_compr_config_t *mod_compr_params,
6933 uint8_t re)
6934{
6935 /* I */
6936 unsigned i_bits = tvb_get_bits32(tvb, samples_offset, sample_bit_width, ENC_BIG_ENDIAN0x00000000);
6937 float i_value = decompress_value(i_bits, comp_meth, sample_bit_width, exponent, mod_compr_params, re);
6938 unsigned sample_len_in_bytes = ((samples_offset%8)+sample_bit_width+7)/8;
6939 proto_item *i_ti = proto_tree_add_float(tree, hf_oran_iSample, tvb, samples_offset/8, sample_len_in_bytes, i_value);
6940 proto_item_set_text(i_ti, "iSample: % 0.7f 0x%04x (RE-%2u in the PRB)", i_value, i_bits, sample_number);
6941 samples_offset += sample_bit_width;
6942 /* Q */
6943 unsigned q_bits = tvb_get_bits32(tvb, samples_offset, sample_bit_width, ENC_BIG_ENDIAN0x00000000);
6944 float q_value = decompress_value(q_bits, comp_meth, sample_bit_width, exponent, mod_compr_params, re);
6945 sample_len_in_bytes = ((samples_offset%8)+sample_bit_width+7)/8;
6946 proto_item *q_ti = proto_tree_add_float(tree, hf_oran_qSample, tvb, samples_offset/8, sample_len_in_bytes, q_value);
6947 proto_item_set_text(q_ti, "qSample: % 0.7f 0x%04x (RE-%2u in the PRB)", q_value, q_bits, sample_number);
6948 samples_offset += sample_bit_width;
6949
6950 /* Update RE stats */
6951 tap_info->num_res++;
6952 /* if (i_value == 0.0 && q_value == 0.0) { */
6953 /* TODO: is just checking bits from frame good enough - assuming this always corresponds to a zero value? */
6954 if (i_bits == 0 && q_bits == 0) {
6955 tap_info->num_res_zero++;
6956 }
6957 else {
6958 tap_info->non_zero_re_in_current_prb = true1;
6959 }
6960 return samples_offset;
6961}
6962
6963
6964static bool_Bool udcomplen_appears_present(bool_Bool udcomphdr_present, tvbuff_t *tvb, int offset)
6965{
6966 if (!udcomplen_heuristic_result_set) {
6967 /* All sections will start the same way */
6968 unsigned int section_bytes_before_field = (udcomphdr_present) ? 6 : 4;
6969
6970 /* Move offset back to the start of the section */
6971 offset -= section_bytes_before_field;
6972
6973 do {
6974 /* This field appears several bytes into the U-plane section */
6975 uint32_t length_remaining = tvb_reported_length_remaining(tvb, offset);
6976 /* Are there enough bytes to still read the length field? */
6977 if (section_bytes_before_field+2 > length_remaining) {
6978 udcomplen_heuristic_result = false0;
6979 udcomplen_heuristic_result_set = true1;
6980 break;
6981 }
6982
6983 /* Read the length field */
6984 uint16_t udcomplen = tvb_get_ntohs(tvb, offset+section_bytes_before_field);
6985
6986 /* Is this less than a valid section? Realistic minimal section will be bigger than this..
6987 * Could take into account numPrbU, etc */
6988 if (udcomplen < section_bytes_before_field+2) {
6989 udcomplen_heuristic_result = false0;
6990 udcomplen_heuristic_result_set = true1;
6991 break;
6992 }
6993
6994 /* Does this section fit into the frame? */
6995 if (udcomplen > length_remaining) {
6996 udcomplen_heuristic_result = false0;
6997 udcomplen_heuristic_result_set = true1;
6998 break;
6999 }
7000
7001 /* Move past this section */
7002 offset += udcomplen;
7003
7004 /* Are we at the end of the frame? */
7005 /* TODO: if frame is less than 60 bytes, there may be > 4 bytes, likely zeros.. */
7006 if (tvb_reported_length_remaining(tvb, offset) < 4) {
7007 udcomplen_heuristic_result = true1;
7008 udcomplen_heuristic_result_set = true1;
7009 }
7010 } while (!udcomplen_heuristic_result_set);
7011 }
7012 return udcomplen_heuristic_result;
7013}
7014
7015static bool_Bool at_udcomphdr(tvbuff_t *tvb, int offset)
7016{
7017 if (tvb_captured_length_remaining(tvb, offset) < 2) {
7018 return false0;
7019 }
7020 uint8_t first_byte = tvb_get_uint8(tvb, offset);
7021 uint8_t reserved_byte = tvb_get_uint8(tvb, offset+1);
7022
7023 /* - iq width could be anything, though unlikely to be signalled as (say) < 1-3? */
7024 /* - meth should be 0-8 */
7025 /* - reserved byte should be 0 */
7026 return (((first_byte & 0x0f) <= MOD_COMPR_AND_SELECTIVE_RE_WITH_MASKS8) && (reserved_byte == 0));
7027}
7028
7029static bool_Bool udcomphdr_appears_present(flow_state_t *flow, uint32_t direction, tvbuff_t *tvb, int offset)
7030{
7031 /* Should really not happen, but guard against this anyway. */
7032 if (flow == NULL((void*)0)) {
7033 /* No state to update. */
7034 return false0;
7035 }
7036
7037 if (direction == DIR_UPLINK0) {
7038 if (flow->udcomphdrUplink_heuristic_result_set) {
7039 /* Return cached value */
7040 return flow->udcomphdrUplink_heuristic_result;
7041 }
7042 else {
7043 /* Work it out, and save answer for next time */
7044 flow->udcomphdrUplink_heuristic_result_set = true1;
7045 flow->udcomphdrUplink_heuristic_result = at_udcomphdr(tvb, offset);
7046 return flow->udcomphdrUplink_heuristic_result;
7047 }
7048 }
7049 else {
7050 /* Downlink */
7051 if (flow->udcomphdrDownlink_heuristic_result_set) {
7052 /* Return cached value */
7053 return flow->udcomphdrDownlink_heuristic_result;
7054 }
7055 else {
7056 /* Work it out, and save answer for next time */
7057 flow->udcomphdrDownlink_heuristic_result_set = true1;
7058 flow->udcomphdrDownlink_heuristic_result = at_udcomphdr(tvb, offset);
7059 return flow->udcomphdrDownlink_heuristic_result;
7060 }
7061 }
7062}
7063
7064static bool_Bool copy_section_entry(const void *key, void* value, void *userdata)
7065{
7066 /* Cast parameters to their types */
7067 uint32_t sectionId = GPOINTER_TO_UINT(key)((guint) (gulong) (key));
7068 expected_section_data_t *result_value = (expected_section_data_t *)value;
7069 wmem_tree_t *result_tree = (wmem_tree_t*)userdata;
7070
7071 /* Deep copy of section data */
7072 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)))
;
7073 *copy = *result_value;
7074
7075 /* Add into result tree */
7076 wmem_tree_insert32(result_tree, sectionId, copy);
7077
7078 return false0;
7079}
7080
7081/* User plane dissector (section 8) */
7082static int
7083dissect_oran_u(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
7084 oran_tap_info *tap_info, void *data _U___attribute__((unused)))
7085{
7086 /* Hidden filter for plane */
7087 proto_item *plane_ti = proto_tree_add_item(tree, hf_oran_uplane, tvb, 0, 0, ENC_NA0x00000000);
7088 PROTO_ITEM_SET_HIDDEN(plane_ti)proto_item_set_hidden((plane_ti));
7089
7090 /* Set up structures needed to add the protocol subtree and manage it */
7091 unsigned offset = 0;
7092
7093 col_set_str(pinfo->cinfo, COL_PROTOCOL, "O-RAN-FH-U");
7094 col_set_str(pinfo->cinfo, COL_INFO, "U-Plane");
7095
7096 tap_info->userplane = true1;
7097
7098 /* Create display subtree for the protocol */
7099 proto_item *protocol_item = proto_tree_add_item(tree, proto_oran, tvb, 0, -1, ENC_NA0x00000000);
7100 proto_item_append_text(protocol_item, "-U");
7101 proto_tree *oran_tree = proto_item_add_subtree(protocol_item, ett_oran);
7102
7103 /* Transport header */
7104 /* Real-time control data / IQ data transfer message series identifier */
7105 uint16_t eAxC;
7106 addPcOrRtcid(tvb, oran_tree, &offset, hf_oran_ecpri_pcid, &eAxC, tap_info);
7107 tap_info->eaxc = eAxC;
7108
7109 /* Update/report status of conversation */
7110 uint32_t key = make_flow_key(pinfo, eAxC, ORAN_U_PLANE1, false0);
7111 flow_state_t* state = (flow_state_t*)wmem_tree_lookup32(flow_states_table, key);
7112
7113 flow_result_t *result = NULL((void*)0);
7114
7115 /* Message identifier */
7116 proto_item *seqIdItem;
7117 uint32_t seqId, subSeqId, e;
7118 offset = addSeqid(tvb, oran_tree, offset, ORAN_U_PLANE1, &seqId, &seqIdItem, pinfo, &subSeqId, &e);
7119
7120 /* Common header for time reference */
7121 proto_item *timingHeader = proto_tree_add_string_format(oran_tree, hf_oran_timing_header,
7122 tvb, offset, 4, "", "Timing Header (");
7123 proto_tree *timing_header_tree = proto_item_add_subtree(timingHeader, ett_oran_u_timing);
7124
7125 /* dataDirection */
7126 uint32_t direction;
7127 proto_tree_add_item_ret_uint(timing_header_tree, hf_oran_data_direction, tvb, offset, 1, ENC_NA0x00000000, &direction);
7128 tap_info->uplink = (direction==0);
1
Assuming 'direction' is not equal to 0
7129 /* payloadVersion */
7130 dissect_payload_version(timing_header_tree, tvb, pinfo, offset);
7131 /* filterIndex */
7132 proto_tree_add_item(timing_header_tree, hf_oran_filter_index, tvb, offset, 1, ENC_NA0x00000000);
7133 offset += 1;
7134
7135 int ref_a_offset = offset;
7136
7137 /* frameId */
7138 uint32_t frameId = 0;
7139 proto_tree_add_item_ret_uint(timing_header_tree, hf_oran_frame_id, tvb, offset, 1, ENC_NA0x00000000, &frameId);
7140 tap_info->frame = frameId;
7141 offset += 1;
7142
7143 /* subframeId */
7144 uint32_t subframeId = 0;
7145 proto_tree_add_item_ret_uint(timing_header_tree, hf_oran_subframe_id, tvb, offset, 1, ENC_NA0x00000000, &subframeId);
7146 /* slotId */
7147 uint32_t slotId = 0;
7148 proto_tree_add_item_ret_uint(timing_header_tree, hf_oran_slot_id, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &slotId);
7149 tap_info->slot = slotId;
7150 offset++;
7151 /* symbolId */
7152 uint32_t symbolId = 0;
7153 proto_tree_add_item_ret_uint(timing_header_tree, hf_oran_symbolId, tvb, offset, 1, ENC_NA0x00000000, &symbolId);
7154 offset++;
7155
7156 char id[16];
7157 snprintf(id, 16, "%u-%u-%u-%u", frameId, subframeId, slotId, symbolId);
7158 proto_item *pi = proto_tree_add_string(timing_header_tree, hf_oran_refa, tvb, ref_a_offset, 3, id);
7159 proto_item_set_generated(pi);
7160
7161 proto_item_append_text(timingHeader, "%s, frameId: %d, subframeId: %d, slotId: %d, symbolId: %d)",
7162 val_to_str_const(direction, data_direction_vals, "Unknown"), frameId, subframeId, slotId, symbolId);
7163
7164 unsigned sample_bit_width;
7165 unsigned compression;
7166 int includeUdCompHeader;
7167
7168 /* Also look up C-PLANE state (sent in opposite direction) so may check current compression settings */
7169 uint32_t cplane_key = make_flow_key(pinfo, eAxC, ORAN_C_PLANE0, true1);
7170 flow_state_t* cplane_state = (flow_state_t*)wmem_tree_lookup32(flow_states_table, cplane_key);
7171 uint32_t cplane_samedir_key = make_flow_key(pinfo, eAxC, ORAN_C_PLANE0, false0);
7172 flow_state_t* cplane_samedir_state = (flow_state_t*)wmem_tree_lookup32(flow_states_table, cplane_samedir_key);
7173
7174
7175 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
2
Assuming field 'visited' is 0
3
Taking true branch
7176 /* Create state/conversation if doesn't exist yet */
7177 if (!state) {
4
Assuming 'state' is non-null
5
Taking false branch
7178 /* Allocate new state */
7179 state = wmem_new0(wmem_file_scope(), flow_state_t)((flow_state_t*)wmem_alloc0((wmem_file_scope()), sizeof(flow_state_t
)))
;
7180 state->ack_nack_requests = wmem_tree_new(wmem_file_scope());
7181 wmem_tree_insert32(flow_states_table, key, state);
7182 }
7183
7184 result = wmem_new0(wmem_file_scope(), flow_result_t)((flow_result_t*)wmem_alloc0((wmem_file_scope()), sizeof(flow_result_t
)))
;
7185 result->expected_dl_sections = wmem_tree_new(wmem_file_scope());
7186 wmem_tree_insert32(flow_results_table, pinfo->num, result);
7187
7188 /* Check sequence analysis status (but not if later part of radio layer fragmentation) */
7189 if (state->last_frame_seen[direction] && (subSeqId==0) && (seqId != state->next_expected_sequence_number[direction])) {
6
Assuming the condition is true
7
Assuming 'subSeqId' is not equal to 0
7190 /* Store this result */
7191 result->unexpected_seq_number = true1;
7192 result->expected_sequence_number = state->next_expected_sequence_number[direction];
7193 result->previous_frame = state->last_frame[direction];
7194 }
7195 /* Update sequence analysis state */
7196 state->last_frame[direction] = pinfo->num;
7197 state->last_frame_seen[direction] = true1;
7198 state->next_expected_sequence_number[direction] = (seqId+1) % 256;
7199 }
7200
7201 /* Show any issues associated with this frame number */
7202 result = wmem_tree_lookup32(flow_results_table, pinfo->num);
8
Value assigned to 'result'
7203 if (result) {
9
Assuming 'result' is null
7204 if (result->unexpected_seq_number) {
7205 expert_add_info_format(pinfo, seqIdItem,
7206 (direction == DIR_UPLINK0) ?
7207 &ei_oran_uplane_unexpected_sequence_number_ul :
7208 &ei_oran_uplane_unexpected_sequence_number_dl,
7209 "Sequence number %u expected, but got %u",
7210 result->expected_sequence_number, seqId);
7211 tap_info->missing_sns = (256 + seqId - result->expected_sequence_number) % 256;
7212 /* TODO: could add previous/next frame (in seqId tree?) ? */
7213 }
7214 }
7215
7216 /* Checking UL timing within current slot. Disabled if limit set to 0. */
7217 /* N.B., timing is relative to first seen frame,
7218 not some notion of the beginning of the slot from sync, offset by some timing.. */
7219 if (direction
9.1
'direction' is not equal to DIR_UPLINK
== DIR_UPLINK0 && us_allowed_for_ul_in_symbol > 0) {
7220 uint32_t timing_key = get_timing_key(frameId, subframeId, slotId, symbolId);
7221 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
7222 /* Set state on first pass */
7223 ul_timing_for_slot* timing = (ul_timing_for_slot*)wmem_tree_lookup32(ul_symbol_timing, timing_key);
7224 if (!timing) {
7225 /* Allocate new state */
7226 timing = wmem_new0(wmem_file_scope(), ul_timing_for_slot)((ul_timing_for_slot*)wmem_alloc0((wmem_file_scope()), sizeof
(ul_timing_for_slot)))
;
7227 timing->first_frame = pinfo->num;
7228 timing->first_frame_time = pinfo->abs_ts;
7229 timing->frames_seen_in_symbol = 1;
7230 timing->last_frame_in_symbol = pinfo->num;
7231 wmem_tree_insert32(ul_symbol_timing, timing_key, timing);
7232 }
7233 else {
7234 /* Update existing state */
7235 timing->frames_seen_in_symbol++;
7236 timing->last_frame_in_symbol = pinfo->num;
7237 }
7238 }
7239 else {
7240 /* Subsequent passes - look up result */
7241 ul_timing_for_slot* timing = (ul_timing_for_slot*)wmem_tree_lookup32(ul_symbol_timing, timing_key);
7242 if (timing) { /* Really shouldn't fail! */
7243 if (timing->frames_seen_in_symbol > 1) {
7244 /* Work out gap between frames (in microseconds) back to frame carrying first seen symbol */
7245 int seconds_between_packets = (int)
7246 (pinfo->abs_ts.secs - timing->first_frame_time.secs);
7247 int nseconds_between_packets =
7248 pinfo->abs_ts.nsecs - timing->first_frame_time.nsecs;
7249
7250
7251 /* Round to nearest microsecond. */
7252 uint32_t total_gap = (seconds_between_packets*1000000) +
7253 ((nseconds_between_packets+500) / 1000);
7254
7255 /* Show how long it has been */
7256 proto_item *ti = NULL((void*)0);
7257 if (pinfo->num != timing->first_frame) {
7258 ti = proto_tree_add_uint(timingHeader, hf_oran_u_section_ul_symbol_time, tvb, 0, 0, total_gap);
7259 proto_item_set_generated(ti);
7260 }
7261
7262 if (total_gap > us_allowed_for_ul_in_symbol) {
7263 expert_add_info_format(pinfo, ti, &ei_oran_ul_uplane_symbol_too_long,
7264 "UL U-Plane Tx took longer (%u us) than limit set in preferences (%u us)",
7265 total_gap, us_allowed_for_ul_in_symbol);
7266 proto_item_append_text(timingHeader, " (%uus since first frame seen for symbol)", total_gap);
7267 }
7268
7269 /* Show how many frames were received */
7270 ti = proto_tree_add_uint(timingHeader, hf_oran_u_section_ul_symbol_frames, tvb, 0, 0, timing->frames_seen_in_symbol);
7271 proto_item_set_generated(ti);
7272
7273 /* Link to first frame for this symbol */
7274 if (pinfo->num != timing->first_frame) {
7275 ti = proto_tree_add_uint(timingHeader, hf_oran_u_section_ul_symbol_first_frame, tvb, 0, 0, timing->first_frame);
7276 proto_item_set_generated(ti);
7277 }
7278
7279 /* And also last frame */
7280 if (pinfo->num != timing->last_frame_in_symbol) {
7281 ti = proto_tree_add_uint(timingHeader, hf_oran_u_section_ul_symbol_last_frame, tvb, 0, 0, timing->last_frame_in_symbol);
7282 proto_item_set_generated(ti);
7283 }
7284
7285 tap_info->ul_delay_in_us = total_gap;
7286 }
7287 }
7288 }
7289 }
7290
7291
7292 /* Look up preferences for samples */
7293 if (direction
9.2
'direction' is not equal to DIR_UPLINK
== DIR_UPLINK0) {
10
Taking false branch
7294 sample_bit_width = pref_sample_bit_width_uplink;
7295 compression = pref_iqCompressionUplink;
7296 includeUdCompHeader = pref_includeUdCompHeaderUplink;
7297 } else {
7298 sample_bit_width = pref_sample_bit_width_downlink;
7299 compression = pref_iqCompressionDownlink;
7300 includeUdCompHeader = pref_includeUdCompHeaderDownlink;
7301 }
7302
7303 /* If uplink, load any udCompHdr settings written by C-Plane */
7304 bool_Bool ud_cmp_hdr_cplane = false0;
7305 if (cplane_state && direction == 0) {
11
Assuming 'cplane_state' is null
7306 /* Initialise settings from udpCompHdr from C-Plane */
7307 if (cplane_state->ul_ud_comp_hdr_set && !pref_override_ul_compression) {
7308 sample_bit_width = cplane_state->ul_ud_comp_hdr_bit_width;
7309 compression = cplane_state->ul_ud_comp_hdr_compression;
7310 ud_cmp_hdr_cplane = true1;
7311 }
7312 }
7313
7314 /* Need a valid value (e.g. 9, 14). 0 definitely won't work, as won't progress around loop! */
7315 /* N.B. may yet be overwritten by udCompHdr settings in sections below! */
7316 if (sample_bit_width == 0) {
12
Assuming 'sample_bit_width' is not equal to 0
13
Taking false branch
7317 expert_add_info_format(pinfo, protocol_item, &ei_oran_invalid_sample_bit_width,
7318 "%cL Sample bit width from %s (%u) not valid, so can't decode sections",
7319 (direction == DIR_UPLINK0) ? 'U' : 'D',
7320 !ud_cmp_hdr_cplane ? "preference" : "C-Plane",
7321 sample_bit_width);
7322 return offset;
7323 }
7324
7325 unsigned bytesLeft;
7326 unsigned number_of_sections = 0;
7327 unsigned nBytesPerPrb =0;
7328
7329
7330 if (link_planes_together && !PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited) && cplane_samedir_state) {
14
Assuming 'link_planes_together' is true
15
Assuming 'cplane_samedir_state' is non-null
16
Taking true branch
7331 /* Take a deep-copy of this state on first pass */
7332 wmem_tree_foreach(cplane_samedir_state->expected_dl_sections, copy_section_entry, result->expected_dl_sections);
17
Access to field 'expected_dl_sections' results in a dereference of a null pointer (loaded from variable 'result')
7333 }
7334
7335 /* Add each section (not from count, just keep parsing until payload used) */
7336 do {
7337 /* Section subtree */
7338 unsigned section_start_offset = offset;
7339 proto_item *sectionHeading = proto_tree_add_string_format(oran_tree, hf_oran_u_section,
7340 tvb, offset, 0, "", "Section");
7341 proto_tree *section_tree = proto_item_add_subtree(sectionHeading, ett_oran_u_section);
7342
7343 /* Section Header fields (darker green part) */
7344
7345 /* sectionId */
7346 uint32_t sectionId = 0;
7347 proto_item *ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_section_id, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &sectionId);
7348 if (sectionId == 4095) {
7349 proto_item_append_text(ti, " (not default coupling C/U planes using sectionId)");
7350 }
7351 offset++;
7352
7353 if (tap_info->num_section_ids < MAX_SECTION_IDs32) {
7354 tap_info->section_ids[tap_info->num_section_ids++] = sectionId;
7355 }
7356
7357 section_details_t *section_details = NULL((void*)0);
7358
7359 /* For DL, lookup corresponding C-plane frame/info */
7360 if (link_planes_together && direction == 1) {
7361 if (cplane_samedir_state != NULL((void*)0)) {
7362
7363 expected_section_data_t *section_data = NULL((void*)0);
7364 section_data = wmem_tree_lookup32(result->expected_dl_sections, sectionId);
7365
7366 if (section_data) {
7367 /* Need to work out which of 2 entries is in use for this data frame */
7368 unsigned index_to_use = 0;
7369
7370 /* Does the first entry match the timing for this frame? */
7371 if (section_data->details[0].frame == frameId &&
7372 section_data->details[0].subframe == subframeId &&
7373 section_data->details[0].slot == slotId &&
7374 /* Check that symbolId is in range */
7375 section_data->details[0].startSymbol <= symbolId &&
7376 (unsigned)(section_data->details[0].startSymbol + section_data->details[0].numSymbols) <= (unsigned)symbolId) {
7377
7378 index_to_use = 0;
7379 }
7380 else if (section_data->details[1].frame == frameId &&
7381 section_data->details[1].subframe == subframeId &&
7382 section_data->details[1].slot == slotId &&
7383 /* Check that symbolId is in range */
7384 section_data->details[1].startSymbol <= symbolId &&
7385 (unsigned)(section_data->details[1].startSymbol + section_data->details[1].numSymbols) <= (unsigned)symbolId) {
7386
7387 index_to_use = 1;
7388 }
7389 else {
7390 /* TODO: expert info warning? */
7391 }
7392
7393 section_details = &section_data->details[index_to_use];
7394
7395 /* Cplane frame number */
7396 proto_item *cplane_frame_ti = proto_tree_add_uint(section_tree, hf_oran_corresponding_cplane_frame, tvb, 0, 0,
7397 section_details->frame_number);
7398 proto_item_set_generated(cplane_frame_ti);
7399
7400 /* usecs since cplane frame */
7401 time_t total_gap = 0;
7402
7403 if ((pinfo->abs_ts.secs == section_details->frame_time.secs) || (pinfo->abs_ts.secs == section_details->frame_time.secs+1)) {
7404 total_gap = ((pinfo->abs_ts.secs - section_details->frame_time.secs) * 1000000) +
7405 ((pinfo->abs_ts.nsecs - section_details->frame_time.nsecs)/1000);
7406 }
7407
7408 if (total_gap > 0) {
7409 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);
7410 proto_item_set_generated(cplane_delta_ti);
7411 }
7412 }
7413 }
7414
7415 }
7416
7417 /* rb */
7418 uint32_t rb;
7419 proto_tree_add_item_ret_uint(section_tree, hf_oran_rb, tvb, offset, 1, ENC_NA0x00000000, &rb);
7420 /* symInc. "use of symInc=1 shall be prohibited in the U-plane" */
7421 uint8_t syminc;
7422 proto_item *syminc_ti = proto_tree_add_item_ret_uint8(section_tree, hf_oran_symInc, tvb, offset, 1, ENC_NA0x00000000, &syminc);
7423 if (syminc) {
7424 expert_add_info(NULL((void*)0), syminc_ti, &ei_oran_syminc_set_for_uplane);
7425 }
7426 /* startPrbu */
7427 uint32_t startPrbu = 0;
7428 proto_tree_add_item_ret_uint(section_tree, hf_oran_startPrbu, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &startPrbu);
7429 offset += 2;
7430
7431 /* numPrbu */
7432 uint32_t numPrbu = 0;
7433 proto_tree_add_item_ret_uint(section_tree, hf_oran_numPrbu, tvb, offset, 1, ENC_NA0x00000000, &numPrbu);
7434 offset += 1;
7435
7436 proto_item *ud_comp_meth_item, *ud_comp_len_ti=NULL((void*)0);
7437 uint32_t ud_comp_len = 0;
7438
7439 /* udCompHdr (if preferences indicate will be present) */
7440 bool_Bool included = (includeUdCompHeader==1) || /* 1 means present.. */
7441 (includeUdCompHeader==2 && udcomphdr_appears_present(state, direction, tvb, offset));
7442 if (included) {
7443 /* 7.5.2.10 */
7444 /* Extract these values to inform how wide IQ samples in each PRB will be. */
7445 offset = dissect_udcomphdr(tvb, pinfo, section_tree, offset, false0, direction == 0, &sample_bit_width,
7446 &compression, &ud_comp_meth_item, tap_info);
7447
7448 /* Not part of udCompHdr */
7449 uint32_t reserved;
7450 proto_item *res_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_reserved_8bits, tvb, offset, 1, ENC_NA0x00000000, &reserved);
7451 offset += 1;
7452 if (reserved != 0) {
7453 expert_add_info_format(pinfo, res_ti, &ei_oran_reserved_not_zero,
7454 "reserved field (0x%x) not zero - perhaps udCompHdr is not really present?",
7455 reserved);
7456 }
7457 }
7458 else {
7459 /* No fields to dissect - just showing comp values from prefs */
7460 /* iqWidth */
7461 proto_item *iq_width_item = proto_tree_add_uint(section_tree, hf_oran_udCompHdrIqWidth_pref, tvb, 0, 0, sample_bit_width);
7462 proto_item_append_text(iq_width_item, (ud_cmp_hdr_cplane) ? " (from c-plane)" : " (from preferences)");
7463 proto_item_set_generated(iq_width_item);
7464
7465 /* udCompMethod */
7466 ud_comp_meth_item = proto_tree_add_uint(section_tree, hf_oran_udCompHdrMeth_pref, tvb, 0, 0, compression);
7467 proto_item_append_text(ud_comp_meth_item, (ud_cmp_hdr_cplane) ? " (from c-plane)" : " (from preferences)");
7468 proto_item_set_generated(ud_comp_meth_item);
7469
7470 /* Point back to C-Plane, if used */
7471 /* TODO: doesn't work with multiple port mappings using SE10.. */
7472 if (ud_cmp_hdr_cplane) {
7473 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);
7474 proto_item_set_generated(cplane_ti);
7475 }
7476
7477 tap_info->compression_methods |= (1 << compression);
7478 tap_info->compression_width = sample_bit_width;
7479 }
7480
7481 /* Consider fragmentation after first section header */
7482 if (do_radio_transport_layer_reassembly && (number_of_sections == 0) && (e !=1 || subSeqId!= 0)) {
7483
7484 /* Set fragmented flag. */
7485 bool_Bool save_fragmented = pinfo->fragmented;
7486 pinfo->fragmented = true1;
7487 fragment_head *fh;
7488 unsigned frag_data_len = tvb_reported_length_remaining(tvb, offset);
7489
7490 /* Add this fragment into reassembly table */
7491 uint32_t reassembly_id = make_reassembly_id(seqId, direction, eAxC,
7492 frameId, subframeId, slotId, symbolId);
7493 fh = fragment_add_seq(&oran_reassembly_table, tvb, offset, pinfo,
7494 reassembly_id, /* id */
7495 GUINT_TO_POINTER(reassembly_id)((gpointer) (gulong) (reassembly_id)), /* data */
7496 subSeqId, /* frag_number */
7497 frag_data_len, /* frag_data_len */
7498 !e, /* more_frags */
7499 0);
7500
7501 bool_Bool update_col_info = true1;
7502
7503 /* See if this completes an SDU */
7504 tvbuff_t *original_tvb = tvb;
7505 tvbuff_t *next_tvb = process_reassembled_data(tvb, offset, pinfo, "Reassembled O-RAN FH CUS Payload",
7506 fh, &oran_frag_items,
7507 &update_col_info, oran_tree);
7508 if (next_tvb) {
7509 /* Have reassembled data */
7510 proto_tree_add_item(oran_tree, hf_oran_payload, next_tvb, 0, -1, ENC_NA0x00000000);
7511 col_append_fstr(pinfo->cinfo, COL_INFO, " Reassembled Data (%u bytes)", tvb_reported_length(next_tvb));
7512 /* Dissection should resume at start of reassembled tvb */
7513 offset = 0;
7514 }
7515 /* Will continue with either reassembled tvb or NULL */
7516 tvb = next_tvb;
7517
7518 /* Restore fragmented flag */
7519 pinfo->fragmented = save_fragmented;
7520
7521 /* Don't dissect any more if not complete yet.. */
7522 if (tvb == NULL((void*)0)) {
7523 return tvb_captured_length(original_tvb);
7524 }
7525 }
7526
7527
7528 /* Not supported! TODO: other places where comp method is looked up (e.g., bfw?) */
7529 switch (compression) {
7530 case COMP_NONE0:
7531 case COMP_BLOCK_FP1:
7532 case BFP_AND_SELECTIVE_RE5:
7533 case COMP_MODULATION4:
7534 case MOD_COMPR_AND_SELECTIVE_RE6:
7535 break;
7536 default:
7537 expert_add_info_format(pinfo, ud_comp_meth_item, &ei_oran_unsupported_compression_method,
7538 "Compression method %u (%s) not supported by dissector",
7539 compression,
7540 rval_to_str_const(compression, ud_comp_header_meth, "reserved"));
7541 }
7542
7543 /* udCompLen (when supported, methods 5,6,7,8) */
7544 if (compression >= BFP_AND_SELECTIVE_RE5) {
7545 bool_Bool supported = (pref_support_udcompLen==1) || /* supported */
7546 (pref_support_udcompLen==2 && udcomplen_appears_present(includeUdCompHeader, tvb, offset));
7547
7548 if (supported) {
7549 ud_comp_len_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_udCompLen, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &ud_comp_len);
7550 if (ud_comp_len <= 1) {
7551 proto_item_append_text(ud_comp_len_ti, " (reserved)");
7552 }
7553 /* TODO: report if less than a viable section in frame? */
7554 /* Check that there is this much length left in the frame */
7555 if (ud_comp_len > tvb_reported_length_remaining(tvb, section_start_offset)) {
7556 expert_add_info_format(pinfo, ud_comp_len_ti, &ei_oran_ud_comp_len_wrong_size,
7557 "udCompLen indicates %u bytes in section, but only %u are left in frame",
7558 ud_comp_len, tvb_reported_length_remaining(tvb, section_start_offset));
7559 }
7560 /* Actual length of section will be checked below, at the end of the section */
7561 offset += 2;
7562 }
7563 }
7564
7565 /* sReSMask1 + sReSMask2 (depends upon compression method) */
7566 uint64_t sresmask1=0, sresmask2=0;
7567 if (compression == BFP_AND_SELECTIVE_RE_WITH_MASKS7 ||
7568 compression == MOD_COMPR_AND_SELECTIVE_RE_WITH_MASKS8)
7569 {
7570 static int * const sres_mask1_2_flags[] = {
7571 &hf_oran_sReSMask1_2_re12,
7572 &hf_oran_sReSMask1_2_re11,
7573 &hf_oran_sReSMask1_2_re10,
7574 &hf_oran_sReSMask1_2_re9,
7575 &hf_oran_sReSMask_re8,
7576 &hf_oran_sReSMask_re7,
7577 &hf_oran_sReSMask_re6,
7578 &hf_oran_sReSMask_re5,
7579 &hf_oran_sReSMask_re4,
7580 &hf_oran_sReSMask_re3,
7581 &hf_oran_sReSMask_re2,
7582 &hf_oran_sReSMask_re1,
7583 NULL((void*)0)
7584 };
7585
7586 /* reserved (4 bits) */
7587 add_reserved_field(section_tree, hf_oran_reserved_4bits, tvb, offset, 1);
7588 /* sReSMask1 (12 bits) */
7589 proto_item *sresmask_ti;
7590 sresmask_ti = proto_tree_add_bitmask_ret_uint64(section_tree, tvb, offset,
7591 hf_oran_sReSMask1,
7592 ett_oran_sresmask,
7593 sres_mask1_2_flags,
7594 ENC_NA0x00000000,
7595 &sresmask1);
7596 offset += 2;
7597 /* Count REs present */
7598 unsigned res = 0;
7599 for (unsigned n=0; n < 12; n++) {
7600 if ((sresmask1 >> n) & 0x1) {
7601 res++;
7602 }
7603 }
7604 proto_item_append_text(sresmask_ti, " (%u REs)", res);
7605
7606
7607 /* reserved (4 bits) */
7608 add_reserved_field(section_tree, hf_oran_reserved_4bits, tvb, offset, 1);
7609 /* sReSMask2 (12 bits) */
7610 sresmask_ti = proto_tree_add_bitmask_ret_uint64(section_tree, tvb, offset,
7611 hf_oran_sReSMask2,
7612 ett_oran_sresmask,
7613 sres_mask1_2_flags,
7614 ENC_NA0x00000000,
7615 &sresmask2);
7616 offset += 2;
7617
7618 if (rb == 1) {
7619 proto_item_append_text(sresmask_ti, " (ignored)");
7620 if (sresmask2 != 0) {
7621 expert_add_info(pinfo, ud_comp_len_ti, &ei_oran_sresmask2_not_zero_with_rb);
7622 }
7623 }
7624 else {
7625 /* Count REs present */
7626 res = 0;
7627 for (unsigned n=0; n < 12; n++) {
7628 if ((sresmask2 >> n) & 0x1) {
7629 res++;
7630 }
7631 }
7632 proto_item_append_text(sresmask_ti, " (%u REs)", res);
7633 }
7634 }
7635
7636 write_section_info(sectionHeading, pinfo, protocol_item, sectionId, startPrbu, numPrbu, rb);
7637
7638 /* TODO: should this use the same pref as c-plane? */
7639 if (numPrbu == 0) {
7640 /* Special case for all PRBs (NR: the total number of PRBs may be > 255) */
7641 numPrbu = pref_data_plane_section_total_rbs;
7642 startPrbu = 0; /* may already be 0... */
7643 }
7644
7645 section_mod_compr_config_t* mod_compr_config = get_mod_compr_section_to_read(cplane_samedir_state, sectionId);
7646
7647 /* Add each PRB */
7648 for (unsigned i = 0; i < numPrbu; i++) {
7649 /* Create subtree */
7650 proto_item *prbHeading = proto_tree_add_string_format(section_tree, hf_oran_samples_prb,
7651 tvb, offset, 0,
7652 "", "PRB");
7653 proto_tree *rb_tree = proto_item_add_subtree(prbHeading, ett_oran_u_prb);
7654 uint32_t exponent = 0;
7655 uint16_t sresmask = 0;
7656
7657 /* udCompParam (depends upon compression method) */
7658 int before = offset;
7659 offset = dissect_udcompparam(tvb, pinfo, rb_tree, offset, compression, &exponent, &sresmask, false0);
7660 int udcompparam_len = offset-before;
7661
7662 /* Show PRB number in root */
7663 proto_item_append_text(prbHeading, " %3u", startPrbu + i*(1+rb));
7664
7665 /* Work out how many REs / PRB */
7666 unsigned res_per_prb = 12;
7667 uint16_t sresmask_to_use = 0x0fff;
7668
7669 if (compression >= BFP_AND_SELECTIVE_RE5) {
7670 /* Work out which mask should be used */
7671 if (compression==BFP_AND_SELECTIVE_RE5 || compression==MOD_COMPR_AND_SELECTIVE_RE6) {
7672 /* Selective RE cases, use value from compModParam */
7673 sresmask_to_use = (uint16_t)sresmask;
7674 }
7675 else {
7676 /* With masks (in section). Choose between sresmask1 and sresmask2 */
7677 if (rb==1 || (i%2)==0) {
7678 /* Even values */
7679 sresmask_to_use = (uint16_t)sresmask1;
7680 }
7681 else {
7682 /* Odd values */
7683 sresmask_to_use = (uint16_t)sresmask2;
7684 }
7685 }
7686
7687 /* Count REs present using sresmask */
7688 res_per_prb = 0;
7689 /* Use sresmask to pick out which REs are present */
7690 for (unsigned n=0; n<12; n++) {
7691 if (sresmask_to_use & (1<<n)) {
7692 res_per_prb++;
7693 }
7694 }
7695 }
7696
7697 /* N.B. bytes for samples need to be padded out to next byte
7698 (certainly where there aren't 12 REs in PRB..) */
7699 unsigned nBytesForSamples = (sample_bit_width * res_per_prb * 2 + 7) / 8;
7700 nBytesPerPrb = nBytesForSamples + udcompparam_len;
7701
7702 proto_tree_add_item(rb_tree, hf_oran_iq_user_data, tvb, offset, nBytesForSamples, ENC_NA0x00000000);
7703
7704 if (section_details) {
7705 if ((startPrbu + i*(1+rb)) < 273) {
7706 proto_item *beamid_ti = proto_tree_add_uint(rb_tree, hf_oran_beamId, tvb, 0, 0,
7707 section_details->beamIds[startPrbu + i*(1+rb)]);
7708 proto_item_set_generated(beamid_ti);
7709 }
7710 }
7711
7712
7713 tap_info->non_zero_re_in_current_prb = false0;
7714
7715 /* Optionally trying to show I/Q RE values */
7716 if (pref_showIQSampleValues) {
7717 /* Individual values */
7718 unsigned samples_offset = offset*8;
7719 unsigned samples_start = offset;
7720 unsigned samples = 0;
7721
7722 if (compression >= BFP_AND_SELECTIVE_RE5) {
7723 /* Use sresmask to pick out which REs are present */
7724 for (unsigned n=1; n<=12; n++) {
7725 if (sresmask_to_use & (1<<(n-1))) {
7726 samples_offset = dissect_oran_u_re(tvb, rb_tree,
7727 n, samples_offset, tap_info, sample_bit_width, compression, exponent, mod_compr_config, n);
7728 samples++;
7729 }
7730 }
7731 }
7732 else {
7733 /* All 12 REs are present */
7734 for (unsigned n=1; n<=12; n++) {
7735 samples_offset = dissect_oran_u_re(tvb, rb_tree,
7736 n, samples_offset, tap_info, sample_bit_width, compression, exponent, mod_compr_config, n);
7737 samples++;
7738 }
7739 }
7740 proto_item_append_text(prbHeading, " (%u REs)", samples);
7741 if (section_details) {
7742 if ((startPrbu + i*(1+rb)) < 273) {
7743 proto_item_append_text(prbHeading, " [BeamId:%u]", section_details->beamIds[startPrbu + i*(1+rb)]);
7744 }
7745 }
7746
7747 /* Was this PRB all zeros? */
7748 if (!tap_info->non_zero_re_in_current_prb) {
7749 tap_info->num_prbs_zero++;
7750 /* Add a filter to make zero-valued PRBs more findable */
7751 proto_item *zero_ti = proto_tree_add_item(rb_tree, hf_oran_zero_prb, tvb,
7752 samples_start, nBytesForSamples, ENC_NA0x00000000);
7753 proto_item_set_hidden(zero_ti);
7754 proto_item_append_text(prbHeading, " (all zeros)");
7755 }
7756 else {
7757 proto_item *nonzero_ti = proto_tree_add_item(rb_tree, hf_oran_nonzero_prb, tvb, samples_start, nBytesForSamples, ENC_NA0x00000000);
7758 proto_item_set_hidden(nonzero_ti);
7759 }
7760 }
7761
7762 tap_info->num_prbs++;
7763
7764
7765 /* Advance past samples */
7766 offset += nBytesForSamples;
7767
7768 /* Set end of prb subtree */
7769 proto_item_set_end(prbHeading, tvb, offset);
7770 }
7771
7772 /* Set extent of section */
7773 proto_item_set_len(sectionHeading, offset-section_start_offset);
7774 if (ud_comp_len_ti != NULL((void*)0) && ((offset-section_start_offset != ud_comp_len))) {
7775 expert_add_info_format(pinfo, ud_comp_len_ti, &ei_oran_ud_comp_len_wrong_size,
7776 "udCompLen indicates %u bytes in section, but dissected %u instead",
7777 ud_comp_len, offset-section_start_offset);
7778 }
7779
7780 bytesLeft = tvb_captured_length(tvb) - offset;
7781 number_of_sections++;
7782 } while (bytesLeft >= (4 + nBytesPerPrb)); /* FIXME: bad heuristic */
7783
7784 /* Show number of sections found */
7785 proto_item *ti = proto_tree_add_uint(oran_tree, hf_oran_numberOfSections, tvb, 0, 0, number_of_sections);
7786 proto_item_set_generated(ti);
7787
7788 /* Expert error if we are short of tvb by > 3 bytes */
7789 if (tvb_reported_length_remaining(tvb, offset) > 3) {
7790 expert_add_info_format(pinfo, protocol_item, &ei_oran_frame_length,
7791 "%u bytes remain at end of frame - should be 0-3",
7792 tvb_reported_length_remaining(tvb, offset));
7793 }
7794
7795 return tvb_captured_length(tvb);
7796}
7797
7798
7799/**********************************************************************/
7800/* Main dissection function. */
7801/* N.B. ecpri message type passed in as 'data' arg by eCPRI dissector */
7802static int
7803dissect_oran(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
7804{
7805 uint32_t ecpri_message_type = *(uint32_t *)data;
7806 unsigned offset = 0;
7807
7808 /* Allocate and zero tap struct */
7809 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
)))
;
7810 tap_info->pdu_size = pinfo->fd->pkt_len;
7811 tap_info->ul_delay_configured_max = us_allowed_for_ul_in_symbol;
7812
7813 switch (ecpri_message_type) {
7814 case ECPRI_MT_IQ_DATA0:
7815 offset = dissect_oran_u(tvb, pinfo, tree, tap_info, data);
7816 break;
7817 case ECPRI_MT_RT_CTRL_DATA2:
7818 offset = dissect_oran_c(tvb, pinfo, tree, tap_info, data);
7819 break;
7820 default:
7821 /* Not dissecting other types - assume these are handled by eCPRI dissector */
7822 return 0;
7823 }
7824
7825 tap_queue_packet(oran_tap, pinfo, tap_info);
7826
7827 return offset;
7828}
7829
7830static void oran_init_protocol(void)
7831{
7832 udcomplen_heuristic_result_set = false0;
7833 udcomplen_heuristic_result = false0;
7834}
7835
7836
7837/* Register the protocol with Wireshark. */
7838void
7839proto_register_oran(void)
7840{
7841 static hf_register_info hf[] = {
7842
7843 /* Section 5.1.3.2.7 */
7844 { &hf_oran_du_port_id,
7845 { "DU Port ID", "oran_fh_cus.du_port_id",
7846 FT_UINT16, BASE_DEC,
7847 NULL((void*)0), 0x0,
7848 "Processing unit at O-RU - width set in dissector preference", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
7849 },
7850
7851 /* Section 5.1.3.2.7 */
7852 { &hf_oran_bandsector_id,
7853 { "BandSector ID", "oran_fh_cus.bandsector_id",
7854 FT_UINT16, BASE_DEC,
7855 NULL((void*)0), 0x0,
7856 "Aggregated cell identified - width set in dissector preference", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
7857 },
7858
7859 /* Section 5.1.3.2.7 */
7860 { &hf_oran_cc_id,
7861 { "CC ID", "oran_fh_cus.cc_id",
7862 FT_UINT16, BASE_DEC,
7863 NULL((void*)0), 0x0,
7864 "Component Carrier - width set in dissector preference", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
7865 },
7866
7867 /* Section 5.1.3.2.7 */
7868 { &hf_oran_ru_port_id,
7869 { "RU Port ID", "oran_fh_cus.ru_port_id",
7870 FT_UINT16, BASE_DEC,
7871 NULL((void*)0), 0x0,
7872 "Logical flow - width set in dissector preference", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
7873 },
7874
7875 /* Section 5.1.3.2.8 */
7876 { &hf_oran_sequence_id,
7877 { "Sequence ID", "oran_fh_cus.sequence_id",
7878 FT_UINT8, BASE_DEC,
7879 NULL((void*)0), 0x0,
7880 "The Sequence ID wraps around individually per eAxC", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
7881 },
7882
7883 /* Section 5.1.3.2.8 */
7884 { &hf_oran_e_bit,
7885 { "E Bit", "oran_fh_cus.e_bit",
7886 FT_UINT8, BASE_DEC,
7887 VALS(e_bit)((0 ? (const struct _value_string*)0 : ((e_bit)))), 0x80,
7888 "Indicate the last message of a subsequence (U-Plane only)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
7889 },
7890
7891 /* Section 5.1.3.2.8 */
7892 { &hf_oran_subsequence_id,
7893 { "Subsequence ID", "oran_fh_cus.subsequence_id",
7894 FT_UINT8, BASE_DEC,
7895 NULL((void*)0), 0x7f,
7896 "The subsequence ID (for eCPRI layer fragmentation)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
7897 },
7898
7899 { &hf_oran_previous_frame,
7900 { "Previous frame in stream", "oran_fh_cus.previous-frame",
7901 FT_FRAMENUM, BASE_NONE,
7902 FRAMENUM_TYPE(FT_FRAMENUM_NONE)((gpointer) (glong) (FT_FRAMENUM_NONE)), 0x0,
7903 "Previous frame in sequence", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
7904 },
7905
7906 /* Section 7.5.2.1 */
7907 { &hf_oran_data_direction,
7908 { "Data Direction", "oran_fh_cus.data_direction",
7909 FT_UINT8, BASE_DEC,
7910 VALS(data_direction_vals)((0 ? (const struct _value_string*)0 : ((data_direction_vals)
)))
, 0x80,
7911 "gNB data direction", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
7912 },
7913
7914 /* Section 7.5.2.2 */
7915 { &hf_oran_payload_version,
7916 { "Payload Version", "oran_fh_cus.payloadVersion",
7917 FT_UINT8, BASE_DEC,
7918 NULL((void*)0), 0x70,
7919 "Payload protocol version the following IEs", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7920 },
7921
7922 /* Section 7.5.2.3 */
7923 { &hf_oran_filter_index,
7924 { "Filter Index", "oran_fh_cus.filterIndex",
7925 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
7926 RVALS(filter_indices)((0 ? (const struct _range_string*)0 : ((filter_indices)))), 0x0f,
7927 "used between IQ data and air interface, both in DL and UL", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7928 },
7929
7930 /* Section 7.5.2.4 */
7931 { &hf_oran_frame_id,
7932 { "Frame ID", "oran_fh_cus.frameId",
7933 FT_UINT8, BASE_DEC,
7934 NULL((void*)0), 0x0,
7935 "A counter for 10 ms frames (wrapping period 2.56 seconds)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7936 },
7937
7938 /* Section 7.5.2.5 */
7939 { &hf_oran_subframe_id,
7940 { "Subframe ID", "oran_fh_cus.subframe_id",
7941 FT_UINT8, BASE_DEC,
7942 NULL((void*)0), 0xf0,
7943 "A counter for 1 ms sub-frames within 10ms frame", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7944 },
7945
7946 /* Section 7.5.2.6 */
7947 { &hf_oran_slot_id,
7948 { "Slot ID", "oran_fh_cus.slotId",
7949 FT_UINT16, BASE_DEC,
7950 NULL((void*)0), 0x0fc0,
7951 "Slot number within a 1ms sub-frame", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7952 },
7953
7954 /* Generated for convenience */
7955 { &hf_oran_slot_within_frame,
7956 { "Slot within frame", "oran_fh_cus.slot-within-frame",
7957 FT_UINT16, BASE_DEC,
7958 NULL((void*)0), 0x0,
7959 "Slot within frame, to match DCT logs", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7960 },
7961
7962 /* Section 7.5.2.7 */
7963 { &hf_oran_start_symbol_id,
7964 { "Start Symbol ID", "oran_fh_cus.startSymbolId",
7965 FT_UINT8, BASE_DEC,
7966 NULL((void*)0), 0x3f,
7967 "The first symbol number within slot affected", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7968 },
7969
7970 /* Section 7.5.2.8 */
7971 { &hf_oran_numberOfSections,
7972 { "Number of Sections", "oran_fh_cus.numberOfSections",
7973 FT_UINT8, BASE_DEC,
7974 NULL((void*)0), 0x0,
7975 "The number of section IDs included in this message", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7976 },
7977
7978 /* Section 7.5.2.9 */
7979 { &hf_oran_sectionType,
7980 { "Section Type", "oran_fh_cus.sectionType",
7981 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
7982 RVALS(section_types)((0 ? (const struct _range_string*)0 : ((section_types)))), 0x0,
7983 "Determines the characteristics of U-plane data", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7984 },
7985
7986 /* Section 7.5.2.10 */
7987 { &hf_oran_udCompHdr,
7988 { "udCompHdr", "oran_fh_cus.udCompHdr",
7989 FT_STRING, BASE_NONE,
7990 NULL((void*)0), 0x0,
7991 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7992 },
7993
7994 /* Section 7.5.2.11 */
7995 { &hf_oran_numberOfUEs,
7996 { "Number Of UEs", "oran_fh_cus.numberOfUEs",
7997 FT_UINT8, BASE_DEC,
7998 NULL((void*)0), 0x0,
7999 "Indicates number of UEs for which channel info is provided", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8000 },
8001
8002 /* Section 7.5.2.12 */
8003 { &hf_oran_timeOffset,
8004 { "Time Offset", "oran_fh_cus.timeOffset",
8005 FT_UINT16, BASE_DEC,
8006 NULL((void*)0), 0x0,
8007 "from start of the slot to start of CP in samples", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8008 },
8009
8010 /* Section 7.5.2.13 */
8011 { &hf_oran_frameStructure_fft,
8012 { "FFT Size", "oran_fh_cus.frameStructure.fft",
8013 FT_UINT8, BASE_HEX | BASE_RANGE_STRING0x00000100,
8014 RVALS(frame_structure_fft)((0 ? (const struct _range_string*)0 : ((frame_structure_fft)
)))
, 0xf0,
8015 "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) }
8016 },
8017
8018 /* Section 7.5.2.13 */
8019 { &hf_oran_frameStructure_subcarrier_spacing,
8020 { "Subcarrier Spacing", "oran_fh_cus.frameStructure.spacing",
8021 FT_UINT8, BASE_HEX | BASE_RANGE_STRING0x00000100,
8022 RVALS(subcarrier_spacings)((0 ? (const struct _range_string*)0 : ((subcarrier_spacings)
)))
, 0x0f,
8023 "The sub carrier spacing as well as the number of slots per 1ms sub-frame",
8024 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
8025 },
8026
8027 /* Section 7.5.2.14 */
8028 { &hf_oran_cpLength,
8029 { "cpLength", "oran_fh_cus.cpLength",
8030 FT_UINT16, BASE_DEC,
8031 NULL((void*)0), 0x0,
8032 "cyclic prefix length", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8033 },
8034
8035 { &hf_oran_timing_header,
8036 { "Timing Header", "oran_fh_cus.timingHeader",
8037 FT_STRING, BASE_NONE,
8038 NULL((void*)0), 0x0,
8039 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8040 },
8041
8042 /* Section 7.5.3.1 */
8043 { &hf_oran_section_id,
8044 { "sectionId", "oran_fh_cus.sectionId",
8045 FT_UINT16, BASE_DEC,
8046 NULL((void*)0), 0xfff0,
8047 "section identifier of data", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8048 },
8049
8050 /* Section 7.5.3.2 */
8051 { &hf_oran_rb,
8052 { "rb", "oran_fh_cus.rb",
8053 FT_UINT8, BASE_DEC,
8054 VALS(rb_vals)((0 ? (const struct _value_string*)0 : ((rb_vals)))), 0x08,
8055 "resource block indicator", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8056 },
8057
8058 /* Section 7.5.5.3 */
8059 { &hf_oran_symInc,
8060 { "symInc", "oran_fh_cus.symInc",
8061 FT_UINT8, BASE_DEC,
8062 VALS(sym_inc_vals)((0 ? (const struct _value_string*)0 : ((sym_inc_vals)))), 0x04,
8063 "Symbol Number Increment Command", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8064 },
8065
8066 /* Section 7.5.3.4 */
8067 { &hf_oran_startPrbc,
8068 { "startPrbc", "oran_fh_cus.startPrbc",
8069 FT_UINT16, BASE_DEC,
8070 NULL((void*)0), 0x03ff,
8071 "Starting PRB of Control Plane Section", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8072 },
8073
8074 /* Section 7.5.3.5 */
8075 { &hf_oran_reMask_re1,
8076 { "RE 1", "oran_fh_cus.reMask-RE1",
8077 FT_BOOLEAN, 16,
8078 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x8000,
8079 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8080 },
8081 { &hf_oran_reMask_re2,
8082 { "RE 2", "oran_fh_cus.reMask-RE2",
8083 FT_BOOLEAN, 16,
8084 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x4000,
8085 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8086 },
8087 { &hf_oran_reMask_re3,
8088 { "RE 3", "oran_fh_cus.reMask-RE3",
8089 FT_BOOLEAN, 16,
8090 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x2000,
8091 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8092 },
8093 { &hf_oran_reMask_re4,
8094 { "RE 4", "oran_fh_cus.reMask-RE4",
8095 FT_BOOLEAN, 16,
8096 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x1000,
8097 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8098 },
8099 { &hf_oran_reMask_re5,
8100 { "RE 5", "oran_fh_cus.reMask-RE5",
8101 FT_BOOLEAN, 16,
8102 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0800,
8103 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8104 },
8105 { &hf_oran_reMask_re6,
8106 { "RE 6", "oran_fh_cus.reMask-RE6",
8107 FT_BOOLEAN, 16,
8108 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0400,
8109 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8110 },
8111 { &hf_oran_reMask_re7,
8112 { "RE 7", "oran_fh_cus.reMask-RE7",
8113 FT_BOOLEAN, 16,
8114 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0200,
8115 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8116 },
8117 { &hf_oran_reMask_re8,
8118 { "RE 8", "oran_fh_cus.reMask-RE8",
8119 FT_BOOLEAN, 16,
8120 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0100,
8121 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8122 },
8123 { &hf_oran_reMask_re9,
8124 { "RE 9", "oran_fh_cus.reMask-RE9",
8125 FT_BOOLEAN, 16,
8126 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0080,
8127 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8128 },
8129 { &hf_oran_reMask_re10,
8130 { "RE 10", "oran_fh_cus.reMask-RE10",
8131 FT_BOOLEAN, 16,
8132 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0040,
8133 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8134 },
8135 { &hf_oran_reMask_re11,
8136 { "RE 11", "oran_fh_cus.reMask-RE11",
8137 FT_BOOLEAN, 16,
8138 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0020,
8139 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8140 },
8141 { &hf_oran_reMask_re12,
8142 { "RE 12", "oran_fh_cus.reMask-RE12",
8143 FT_BOOLEAN, 16,
8144 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0010,
8145 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8146 },
8147 { &hf_oran_reMask,
8148 { "RE Mask", "oran_fh_cus.reMask",
8149 FT_UINT16, BASE_HEX,
8150 NULL((void*)0), 0xfff0,
8151 "The Resource Element (RE) mask within a PRB", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8152 },
8153
8154 /* Section 7.5.3.6 */
8155 { &hf_oran_numPrbc,
8156 { "numPrbc", "oran_fh_cus.numPrbc",
8157 FT_UINT8, BASE_DEC,
8158 NULL((void*)0), 0x0,
8159 "Number of contiguous PRBs per data section description", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8160 },
8161 /* Section 7.5.3.7 */
8162 { &hf_oran_numSymbol,
8163 { "Number of Symbols", "oran_fh_cus.numSymbol",
8164 FT_UINT8, BASE_DEC,
8165 NULL((void*)0), 0x0f,
8166 "Defines number of symbols to which the section control is applicable", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8167 },
8168 /* Section 7.5.3.8 */
8169 { &hf_oran_ef,
8170 { "Extension Flag", "oran_fh_cus.ef",
8171 FT_BOOLEAN, 8,
8172 NULL((void*)0), 0x80,
8173 "Indicates if more section extensions follow", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8174 },
8175 /* Section 7.5.3.9 */
8176 { &hf_oran_beamId,
8177 { "Beam ID", "oran_fh_cus.beamId",
8178 FT_UINT16, BASE_DEC,
8179 NULL((void*)0), 0x7fff,
8180 "Defines the beam pattern to be applied to the U-Plane data", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8181 },
8182
8183 { &hf_oran_extension,
8184 { "Extension", "oran_fh_cus.extension",
8185 FT_STRING, BASE_NONE,
8186 NULL((void*)0), 0x0,
8187 "Section extension", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8188 },
8189
8190 /* Section 7.6.2.1 */
8191 { &hf_oran_exttype,
8192 { "extType", "oran_fh_cus.extType",
8193 FT_UINT8, BASE_DEC|BASE_EXT_STRING0x00000200,
8194 &exttype_vals_ext, 0x7f,
8195 "The extension type, which provides additional parameters specific to subject data extension", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8196 },
8197
8198 /* Section 7.6.2.3 */
8199 { &hf_oran_extlen,
8200 { "extLen", "oran_fh_cus.extLen",
8201 FT_UINT16, BASE_DEC,
8202 NULL((void*)0), 0x0,
8203 "Extension length in 32-bit words", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8204 },
8205
8206 /* Section 7.7.1 */
8207 { &hf_oran_bfw,
8208 { "bfw", "oran_fh_cus.bfw",
8209 FT_STRING, BASE_NONE,
8210 NULL((void*)0), 0x0,
8211 "Set of weights for a particular antenna", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8212 },
8213 { &hf_oran_bfw_bundle,
8214 { "Bundle", "oran_fh_cus.bfw.bundle",
8215 FT_STRING, BASE_NONE,
8216 NULL((void*)0), 0x0,
8217 "Bundle of BFWs", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8218 },
8219 { &hf_oran_bfw_bundle_id,
8220 { "Bundle Id", "oran_fh_cus.bfw.bundleId",
8221 FT_UINT32, BASE_DEC,
8222 NULL((void*)0), 0x0,
8223 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8224 },
8225 /* Section 7.7.1.4 */
8226 { &hf_oran_bfw_i,
8227 { "bfwI", "oran_fh_cus.bfwI",
8228 FT_FLOAT, BASE_NONE,
8229 NULL((void*)0), 0x0,
8230 "In-phase", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8231 },
8232 /* Section 7.7.1.5 */
8233 { &hf_oran_bfw_q,
8234 { "bfwQ", "oran_fh_cus.bfwQ",
8235 FT_FLOAT, BASE_NONE,
8236 NULL((void*)0), 0x0,
8237 "Quadrature", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8238 },
8239
8240 /* Section 7.5.3.10 */
8241 { &hf_oran_ueId,
8242 { "UE ID", "oran_fh_cus.ueId",
8243 FT_UINT16, BASE_DEC,
8244 NULL((void*)0), 0x7fff,
8245 "logical identifier for set of channel info", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8246 },
8247 /* Section 7.5.3.11 */
8248 { &hf_oran_freqOffset,
8249 { "Frequency Offset", "oran_fh_cus.freqOffset",
8250 FT_UINT24, BASE_DEC,
8251 NULL((void*)0), 0x0,
8252 "with respect to the carrier center frequency before additional filtering", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8253 },
8254
8255 /* Section 7.5.3.12 */
8256 { &hf_oran_regularizationFactor,
8257 { "Regularization Factor", "oran_fh_cus.regularizationFactor",
8258 FT_INT16, BASE_DEC,
8259 NULL((void*)0), 0x0,
8260 "Signed value to support MMSE operation within O-RU", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8261 },
8262 /* Section 7.5.3.14 */
8263 { &hf_oran_laaMsgType,
8264 { "LAA Message Type", "oran_fh_cus.laaMsgType",
8265 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
8266 RVALS(laaMsgTypes)((0 ? (const struct _range_string*)0 : ((laaMsgTypes)))), 0xf0,
8267 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8268 },
8269 /* Section 7.5.3.15 */
8270 { &hf_oran_laaMsgLen,
8271 { "LAA Message Length", "oran_fh_cus.laaMsgLen",
8272 FT_UINT8, BASE_DEC,
8273 NULL((void*)0), 0x0f,
8274 "number of 32-bit words in the LAA section", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8275 },
8276 /* Section 7.5.3.16 */
8277 { &hf_oran_lbtHandle,
8278 { "LBT Handle", "oran_fh_cus.lbtHandle",
8279 FT_UINT16, BASE_HEX,
8280 NULL((void*)0), 0x0,
8281 "label to identify transaction", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8282 },
8283 /* Section 7.5.3.17 */
8284 { &hf_oran_lbtDeferFactor,
8285 { "Defer Factor", "oran_fh_cus.lbtDeferFactor",
8286 FT_UINT8, BASE_DEC,
8287 NULL((void*)0), 0x07,
8288 "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)}
8289 },
8290 /* Section 7.5.3.18 */
8291 { &hf_oran_lbtBackoffCounter,
8292 { "Backoff Counter", "oran_fh_cus.lbtBackoffCounter",
8293 FT_UINT16, BASE_DEC,
8294 NULL((void*)0), 0xffc0,
8295 "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)}
8296 },
8297 /* Section 7.5.3.19 */
8298 { &hf_oran_lbtOffset,
8299 { "LBT Offset", "oran_fh_cus.lbtOffset",
8300 FT_UINT16, BASE_DEC,
8301 NULL((void*)0), 0xffc0,
8302 "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)}
8303 },
8304 /* Section 7.5.3.20 */
8305 { &hf_oran_MCOT,
8306 { "Maximum Channel Occupancy Time", "oran_fh_cus.MCOT",
8307 FT_UINT8, BASE_DEC,
8308 NULL((void*)0), 0x3c,
8309 "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)}
8310 },
8311 /* Section 7.5.3.21 */
8312 { &hf_oran_lbtMode,
8313 { "LBT Mode", "oran_fh_cus.lbtMode",
8314 FT_UINT8, BASE_DEC,
8315 VALS(lbtMode_vals)((0 ? (const struct _value_string*)0 : ((lbtMode_vals)))), 0x0,
8316 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8317 },
8318 /* Section 7.5.3.22 */
8319 { &hf_oran_lbtPdschRes,
8320 { "lbtPdschRes", "oran_fh_cus.lbtPdschRes",
8321 FT_UINT8, BASE_DEC,
8322 VALS(lbtPdschRes_vals)((0 ? (const struct _value_string*)0 : ((lbtPdschRes_vals)))), 0xc0,
8323 "LBT result of SFN/SF", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8324 },
8325 /* Section 7.5.3.23 */
8326 { &hf_oran_sfStatus,
8327 { "sfStatus", "oran_fh_cus.sfStatus",
8328 FT_BOOLEAN, 8,
8329 TFS(&tfs_sfStatus)((0 ? (const struct true_false_string*)0 : ((&tfs_sfStatus
))))
, 0x10,
8330 "Indicates whether the subframe was dropped or transmitted", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8331 },
8332 /* Section 7.5.3.24 */
8333 { &hf_oran_lbtDrsRes,
8334 { "lbtDrsRes", "oran_fh_cus.lbtDrsRes",
8335 FT_BOOLEAN, 8,
8336 TFS(&tfs_fail_success)((0 ? (const struct true_false_string*)0 : ((&tfs_fail_success
))))
, 0x80,
8337 "Indicates whether the subframe was dropped or transmitted", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8338 },
8339 /* Section 7.5.3.25 */
8340 { &hf_oran_initialPartialSF,
8341 { "Initial partial SF", "oran_fh_cus.initialPartialSF",
8342 FT_BOOLEAN, 8,
8343 TFS(&tfs_partial_full_sf)((0 ? (const struct true_false_string*)0 : ((&tfs_partial_full_sf
))))
, 0x40,
8344 "Indicates whether the initial SF in the LBT process is full or partial", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8345 },
8346 /* Section 7.5.3.26. */
8347 { &hf_oran_lbtBufErr,
8348 { "lbtBufErr", "oran_fh_cus.lbtBufErr",
8349 FT_BOOLEAN, 8,
8350 TFS(&tfs_lbtBufErr)((0 ? (const struct true_false_string*)0 : ((&tfs_lbtBufErr
))))
, 0x80,
8351 "LBT buffer error", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8352 },
8353 /* Section 7.5.3.27 */
8354 { &hf_oran_sfnSfEnd,
8355 { "SFN/SF End", "oran_fh_cus.sfnSfEnd",
8356 FT_UINT16, BASE_DEC,
8357 NULL((void*)0), 0x0fff,
8358 "SFN/SF by which the DRS window must end", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8359 },
8360 /* Section 7.5.3.28 */
8361 { &hf_oran_lbtCWConfig_H,
8362 { "lbtCWConfig_H", "oran_fh_cus.lbtCWConfig_H",
8363 FT_UINT8, BASE_DEC,
8364 NULL((void*)0), 0x0,
8365 "HARQ parameters for congestion window management", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8366 },
8367 /* Section 7.5.3.29 */
8368 { &hf_oran_lbtCWConfig_T,
8369 { "lbtCWConfig_T", "oran_fh_cus.lbtCWConfig_T",
8370 FT_UINT8, BASE_DEC,
8371 NULL((void*)0), 0x0,
8372 "TB parameters for congestion window management", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8373 },
8374 /* Section 7.5.3.30 */
8375 { &hf_oran_lbtTrafficClass,
8376 { "lbtTrafficClass", "oran_fh_cus.lbtTrafficClass",
8377 FT_UINT8, BASE_DEC,
8378 VALS(lbtTrafficClass_vals)((0 ? (const struct _value_string*)0 : ((lbtTrafficClass_vals
))))
, 0x38,
8379 "Traffic class priority for congestion window management", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8380 },
8381 /* Section 7.5.3.31 */
8382 { &hf_oran_lbtCWR_Rst,
8383 { "lbtCWR_Rst", "oran_fh_cus.lbtCWR_Rst",
8384 FT_BOOLEAN, 8,
8385 TFS(&tfs_fail_success)((0 ? (const struct true_false_string*)0 : ((&tfs_fail_success
))))
, 0x80,
8386 "notification about packet reception successful or not", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8387 },
8388
8389 /* Reserved fields */
8390 { &hf_oran_reserved,
8391 { "reserved", "oran_fh_cus.reserved",
8392 FT_UINT64, BASE_HEX,
8393 NULL((void*)0), 0x0,
8394 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8395 },
8396 { &hf_oran_reserved_1bit,
8397 { "reserved", "oran_fh_cus.reserved",
8398 FT_UINT8, BASE_HEX,
8399 NULL((void*)0), 0x80,
8400 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8401 },
8402 { &hf_oran_reserved_2bits,
8403 { "reserved", "oran_fh_cus.reserved",
8404 FT_UINT8, BASE_HEX,
8405 NULL((void*)0), 0xc0,
8406 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8407 },
8408 { &hf_oran_reserved_3bits,
8409 { "reserved", "oran_fh_cus.reserved",
8410 FT_UINT8, BASE_HEX,
8411 NULL((void*)0), 0xe0,
8412 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8413 },
8414 { &hf_oran_reserved_4bits,
8415 { "reserved", "oran_fh_cus.reserved",
8416 FT_UINT8, BASE_HEX,
8417 NULL((void*)0), 0xf0,
8418 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8419 },
8420 { &hf_oran_reserved_last_4bits,
8421 { "reserved", "oran_fh_cus.reserved",
8422 FT_UINT8, BASE_HEX,
8423 NULL((void*)0), 0x0f,
8424 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8425 },
8426 { &hf_oran_reserved_last_5bits,
8427 { "reserved", "oran_fh_cus.reserved",
8428 FT_UINT8, BASE_HEX,
8429 NULL((void*)0), 0x1f,
8430 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8431 },
8432 { &hf_oran_reserved_6bits,
8433 { "reserved", "oran_fh_cus.reserved",
8434 FT_UINT8, BASE_HEX,
8435 NULL((void*)0), 0xfc,
8436 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8437 },
8438 { &hf_oran_reserved_last_6bits,
8439 { "reserved", "oran_fh_cus.reserved",
8440 FT_UINT8, BASE_HEX,
8441 NULL((void*)0), 0x3f,
8442 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8443 },
8444 { &hf_oran_reserved_7bits,
8445 { "reserved", "oran_fh_cus.reserved",
8446 FT_UINT8, BASE_HEX,
8447 NULL((void*)0), 0xfe,
8448 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8449 },
8450 { &hf_oran_reserved_last_7bits,
8451 { "reserved", "oran_fh_cus.reserved",
8452 FT_UINT8, BASE_HEX,
8453 NULL((void*)0), 0x7f,
8454 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8455 },
8456 { &hf_oran_reserved_8bits,
8457 { "reserved", "oran_fh_cus.reserved",
8458 FT_UINT8, BASE_HEX,
8459 NULL((void*)0), 0x0,
8460 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8461 },
8462 { &hf_oran_reserved_16bits,
8463 { "reserved", "oran_fh_cus.reserved",
8464 FT_UINT16, BASE_HEX,
8465 NULL((void*)0), 0x0,
8466 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8467 },
8468 { &hf_oran_reserved_15bits,
8469 { "reserved", "oran_fh_cus.reserved",
8470 FT_UINT16, BASE_HEX,
8471 NULL((void*)0), 0x7fff,
8472 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8473 },
8474 { &hf_oran_reserved_bit1,
8475 { "reserved", "oran_fh_cus.reserved",
8476 FT_UINT8, BASE_HEX,
8477 NULL((void*)0), 0x40,
8478 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8479 },
8480 { &hf_oran_reserved_bit2,
8481 { "reserved", "oran_fh_cus.reserved",
8482 FT_UINT8, BASE_HEX,
8483 NULL((void*)0), 0x20,
8484 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8485 },
8486 { &hf_oran_reserved_bit4,
8487 { "reserved", "oran_fh_cus.reserved",
8488 FT_UINT8, BASE_HEX,
8489 NULL((void*)0), 0x08,
8490 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8491 },
8492 { &hf_oran_reserved_bit5,
8493 { "reserved", "oran_fh_cus.reserved",
8494 FT_UINT8, BASE_HEX,
8495 NULL((void*)0), 0x04,
8496 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8497 },
8498 { &hf_oran_reserved_bits123,
8499 { "reserved", "oran_fh_cus.reserved",
8500 FT_UINT8, BASE_HEX,
8501 NULL((void*)0), 0x70,
8502 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8503 },
8504 { &hf_oran_reserved_bits456,
8505 { "reserved", "oran_fh_cus.reserved",
8506 FT_UINT8, BASE_HEX,
8507 NULL((void*)0), 0x0e,
8508 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8509 },
8510
8511 /* 7.7.11.9 */
8512 { &hf_oran_cont_ind,
8513 { "contInd", "oran_fh_cus.contInd",
8514 FT_BOOLEAN, 8,
8515 TFS(&continuity_indication_tfs)((0 ? (const struct true_false_string*)0 : ((&continuity_indication_tfs
))))
, 0x80,
8516 "PRB region continuity flag", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8517 },
8518 /* 7.7.11.10 */
8519 { &hf_oran_bundle_offset,
8520 { "BundleOffset", "oran_fh_cus.bundleOffset",
8521 FT_UINT8, BASE_DEC,
8522 NULL((void*)0), 0x3f,
8523 "offset between start of first PRB bundle and startPrbc", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8524 },
8525
8526 /* 7.7.1.2 bfwCompHdr (beamforming weight compression header) */
8527 { &hf_oran_bfwCompHdr,
8528 { "bfwCompHdr", "oran_fh_cus.bfwCompHdr",
8529 FT_STRING, BASE_NONE,
8530 NULL((void*)0), 0x0,
8531 "Compression method and IQ bit width for beamforming weights", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8532 },
8533 { &hf_oran_bfwCompHdr_iqWidth,
8534 { "IQ Bit Width", "oran_fh_cus.bfwCompHdr_iqWidth",
8535 FT_UINT8, BASE_HEX,
8536 VALS(bfw_comp_headers_iq_width)((0 ? (const struct _value_string*)0 : ((bfw_comp_headers_iq_width
))))
, 0xf0,
8537 "IQ bit width for the beamforming weights", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8538 },
8539 { &hf_oran_bfwCompHdr_compMeth,
8540 { "Compression Method", "oran_fh_cus.bfwCompHdr_compMeth",
8541 FT_UINT8, BASE_HEX,
8542 VALS(bfw_comp_headers_comp_meth)((0 ? (const struct _value_string*)0 : ((bfw_comp_headers_comp_meth
))))
, 0x0f,
8543 "compression method for the beamforming weights", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8544 },
8545
8546 /* 7.5.3.32 */
8547 { &hf_oran_ciCompParam,
8548 { "ciCompParam", "oran_fh_cus.ciCompParam",
8549 FT_STRING, BASE_NONE,
8550 NULL((void*)0), 0x0,
8551 "channel information compression parameter", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8552 },
8553
8554 /* Table 7.5.3.32-1 */
8555 { &hf_oran_blockScaler,
8556 { "blockScaler", "oran_fh_cus.blockScaler",
8557 FT_UINT8, BASE_HEX,
8558 NULL((void*)0), 0x0,
8559 "unsigned, 1 integer bit, 7 fractional bits", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8560 },
8561 { &hf_oran_compBitWidth,
8562 { "compBitWidth", "oran_fh_cus.compBitWidth",
8563 FT_UINT8, BASE_DEC,
8564 NULL((void*)0), 0xf0,
8565 "Length of I bits and length of Q bits after compression over entire PRB", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8566 },
8567 { &hf_oran_compShift,
8568 { "compShift", "oran_fh_cus.compShift",
8569 FT_UINT8, BASE_DEC,
8570 NULL((void*)0), 0x0f,
8571 "The shift applied to the entire PRB", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8572 },
8573
8574 { &hf_oran_active_beamspace_coefficient_n1,
8575 { "N1", "oran_fh_cus.activeBeamspace_Coefficient_n1",
8576 FT_BOOLEAN, 8,
8577 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x80,
8578 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8579 },
8580 { &hf_oran_active_beamspace_coefficient_n2,
8581 { "N2", "oran_fh_cus.activeBeamspace_Coefficient_n2",
8582 FT_BOOLEAN, 8,
8583 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x40,
8584 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8585 },
8586 { &hf_oran_active_beamspace_coefficient_n3,
8587 { "N3", "oran_fh_cus.activeBeamspace_Coefficient_n3",
8588 FT_BOOLEAN, 8,
8589 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x20,
8590 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8591 },
8592 { &hf_oran_active_beamspace_coefficient_n4,
8593 { "N4", "oran_fh_cus.activeBeamspace_Coefficient_n4",
8594 FT_BOOLEAN, 8,
8595 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x10,
8596 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8597 },
8598 { &hf_oran_active_beamspace_coefficient_n5,
8599 { "N5", "oran_fh_cus.activeBeamspace_Coefficient_n5",
8600 FT_BOOLEAN, 8,
8601 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x08,
8602 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8603 },
8604 { &hf_oran_active_beamspace_coefficient_n6,
8605 { "N6", "oran_fh_cus.activeBeamspace_Coefficient_n6",
8606 FT_BOOLEAN, 8,
8607 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x04,
8608 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8609 },
8610 { &hf_oran_active_beamspace_coefficient_n7,
8611 { "N7", "oran_fh_cus.activeBeamspace_Coefficient_n7",
8612 FT_BOOLEAN, 8,
8613 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x02,
8614 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8615 },
8616 { &hf_oran_active_beamspace_coefficient_n8,
8617 { "N8", "oran_fh_cus.activeBeamspace_Coefficient_n8",
8618 FT_BOOLEAN, 8,
8619 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x01,
8620 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8621 },
8622
8623 { &hf_oran_activeBeamspaceCoefficientMask,
8624 { "activeBeamspaceCoefficientMask", "oran_fh_cus.activeBeamspaceCoefficientMask",
8625 FT_UINT8, BASE_HEX,
8626 NULL((void*)0), 0xff,
8627 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8628 },
8629 { &hf_oran_activeBeamspaceCoefficientMask_bits_set,
8630 { "Array elements set", "oran_fh_cus.activeBeamspaceCoefficientMask.bits-set",
8631 FT_UINT32, BASE_DEC,
8632 NULL((void*)0), 0x0,
8633 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8634 },
8635
8636 /* Section 7.7.6.6 */
8637 { &hf_oran_se6_repetition,
8638 { "repetition", "oran_fh_cus.repetition",
8639 FT_BOOLEAN, BASE_NONE,
8640 TFS(&repetition_se6_tfs)((0 ? (const struct true_false_string*)0 : ((&repetition_se6_tfs
))))
, 0x0,
8641 "Repetition of a highest priority data section for C-Plane", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8642 },
8643 /* 7.7.20.9 */
8644 { &hf_oran_rbgSize,
8645 { "rbgSize", "oran_fh_cus.rbgSize",
8646 FT_UINT8, BASE_HEX,
8647 VALS(rbg_size_vals)((0 ? (const struct _value_string*)0 : ((rbg_size_vals)))), 0x70,
8648 "Number of PRBs of the resource block groups allocated by the bit mask", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8649 },
8650 /* 7.7.20.10 */
8651 { &hf_oran_rbgMask,
8652 { "rbgMask", "oran_fh_cus.rbgMask",
8653 FT_UINT32, BASE_HEX,
8654 NULL((void*)0), 0x0fffffff,
8655 "Each bit indicates whether a corresponding resource block group is present", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8656 },
8657 /* 7.7.6.5. Also 7.7.12.3 and 7.7.19.5 */
8658 { &hf_oran_noncontig_priority,
8659 { "priority", "oran_fh_cus.priority",
8660 FT_UINT8, BASE_HEX,
8661 VALS(priority_vals)((0 ? (const struct _value_string*)0 : ((priority_vals)))), 0xc0,
8662 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8663 },
8664
8665 /* 7.7.6.4 */
8666 { &hf_oran_symbol_mask,
8667 { "symbolMask", "oran_fh_cus.symbolMask",
8668 FT_UINT16, BASE_HEX,
8669 NULL((void*)0), 0x3fff,
8670 "Each bit indicates whether the rbgMask applies to a given symbol in the slot", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8671 },
8672 { &hf_oran_symbol_mask_s13,
8673 { "symbol 13", "oran_fh_cus.symbolMask.symbol-13",
8674 FT_BOOLEAN, 16,
8675 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x2000,
8676 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8677 },
8678 { &hf_oran_symbol_mask_s12,
8679 { "symbol 12", "oran_fh_cus.symbolMask.symbol-12",
8680 FT_BOOLEAN, 16,
8681 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x1000,
8682 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8683 },
8684 { &hf_oran_symbol_mask_s11,
8685 { "symbol 11", "oran_fh_cus.symbolMask.symbol-11",
8686 FT_BOOLEAN, 16,
8687 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0800,
8688 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8689 },
8690 { &hf_oran_symbol_mask_s10,
8691 { "symbol 10", "oran_fh_cus.symbolMask.symbol-10",
8692 FT_BOOLEAN, 16,
8693 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0400,
8694 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8695 },
8696 { &hf_oran_symbol_mask_s9,
8697 { "symbol 9", "oran_fh_cus.symbolMask.symbol-9",
8698 FT_BOOLEAN, 16,
8699 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0200,
8700 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8701 },
8702 { &hf_oran_symbol_mask_s8,
8703 { "symbol 8", "oran_fh_cus.symbolMask.symbol-8",
8704 FT_BOOLEAN, 16,
8705 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0100,
8706 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8707 },
8708 { &hf_oran_symbol_mask_s7,
8709 { "symbol 7", "oran_fh_cus.symbolMask.symbol-7",
8710 FT_BOOLEAN, 16,
8711 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0080,
8712 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8713 },
8714 { &hf_oran_symbol_mask_s6,
8715 { "symbol 6", "oran_fh_cus.symbolMask.symbol-6",
8716 FT_BOOLEAN, 16,
8717 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0040,
8718 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8719 },
8720 { &hf_oran_symbol_mask_s5,
8721 { "symbol 5", "oran_fh_cus.symbolMask.symbol-5",
8722 FT_BOOLEAN, 16,
8723 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0020,
8724 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8725 },
8726 { &hf_oran_symbol_mask_s4,
8727 { "symbol 4", "oran_fh_cus.symbolMask.symbol-4",
8728 FT_BOOLEAN, 16,
8729 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0010,
8730 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8731 },
8732 { &hf_oran_symbol_mask_s3,
8733 { "symbol 3", "oran_fh_cus.symbolMask.symbol-3",
8734 FT_BOOLEAN, 16,
8735 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0008,
8736 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8737 },
8738 { &hf_oran_symbol_mask_s2,
8739 { "symbol 2", "oran_fh_cus.symbolMask.symbol-2",
8740 FT_BOOLEAN, 16,
8741 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0004,
8742 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8743 },
8744 { &hf_oran_symbol_mask_s1,
8745 { "symbol 1", "oran_fh_cus.symbolMask.symbol-1",
8746 FT_BOOLEAN, 16,
8747 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0002,
8748 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8749 },
8750 { &hf_oran_symbol_mask_s0,
8751 { "symbol 0", "oran_fh_cus.symbolMask.symbol-0",
8752 FT_BOOLEAN, 16,
8753 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0001,
8754 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8755 },
8756
8757
8758 /* 7.7.22.2 */
8759 { &hf_oran_ack_nack_req_id,
8760 { "ackNackReqId", "oran_fh_cus.ackNackReqId",
8761 FT_UINT16, BASE_HEX,
8762 NULL((void*)0), 0x0,
8763 "Indicates the ACK/NACK request ID of a section description", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8764 },
8765
8766 /* Subtree for next 2 items */
8767 { &hf_oran_frequency_range,
8768 { "Frequency Range", "oran_fh_cus.frequencyRange",
8769 FT_STRING, BASE_NONE,
8770 NULL((void*)0), 0x0,
8771 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8772 },
8773
8774 /* 7.7.12.4 */
8775 { &hf_oran_off_start_prb,
8776 { "offStartPrb", "oran_fh_cus.offStartPrb",
8777 FT_UINT8, BASE_DEC,
8778 NULL((void*)0), 0x0,
8779 "Offset of PRB range start", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8780 },
8781 /* 7.7.12.5 */
8782 { &hf_oran_num_prb,
8783 { "numPrb", "oran_fh_cus.numPrb",
8784 FT_UINT8, BASE_DEC,
8785 NULL((void*)0), 0x0,
8786 "Number of PRBs in PRB range", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8787 },
8788
8789 /* symbolId 8.3.3.7 */
8790 { &hf_oran_symbolId,
8791 { "Symbol Identifier", "oran_fh_cus.symbolId",
8792 FT_UINT8, BASE_DEC,
8793 NULL((void*)0), 0x3f,
8794 "Identifies a symbol number within a slot", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8795 },
8796
8797 /* startPrbu 8.3.3.11 */
8798 { &hf_oran_startPrbu,
8799 { "startPrbu", "oran_fh_cus.startPrbu",
8800 FT_UINT16, BASE_DEC,
8801 NULL((void*)0), 0x03ff,
8802 "starting PRB of user plane section", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8803 },
8804
8805 /* numPrbu 8.3.3.12 */
8806 { &hf_oran_numPrbu,
8807 { "numPrbu", "oran_fh_cus.numPrbu",
8808 FT_UINT8, BASE_DEC,
8809 NULL((void*)0), 0x0,
8810 "number of PRBs per user plane section", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8811 },
8812
8813 /* 7.7.1.3 */
8814 { &hf_oran_bfwCompParam,
8815 { "bfwCompParam", "oran_fh_cus.bfwCompParam",
8816 FT_STRING, BASE_NONE,
8817 NULL((void*)0), 0x0,
8818 "Beamforming weight compression parameter", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8819 },
8820
8821 /* 6.3.3.13 */
8822 { &hf_oran_udCompHdrMeth,
8823 { "User Data Compression Method", "oran_fh_cus.udCompHdrMeth",
8824 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
8825 RVALS(ud_comp_header_meth)((0 ? (const struct _range_string*)0 : ((ud_comp_header_meth)
)))
, 0x0f,
8826 "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)}
8827 },
8828 { &hf_oran_udCompHdrMeth_pref,
8829 { "User Data Compression Method", "oran_fh_cus.udCompHdrMeth",
8830 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
8831 RVALS(ud_comp_header_meth)((0 ? (const struct _range_string*)0 : ((ud_comp_header_meth)
)))
, 0x0,
8832 "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)}
8833 },
8834 /* 8.3.3.18 */
8835 { &hf_oran_udCompLen,
8836 { "udCompLen", "oran_fh_cus.udCompLen",
8837 FT_UINT16, BASE_DEC,
8838 NULL((void*)0), 0x0,
8839 "PRB field length in octets", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8840 },
8841
8842 /* 7.5.2.10 */
8843 { &hf_oran_udCompHdrIqWidth,
8844 { "User Data IQ width", "oran_fh_cus.udCompHdrWidth",
8845 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
8846 RVALS(ud_comp_header_width)((0 ? (const struct _range_string*)0 : ((ud_comp_header_width
))))
, 0xf0,
8847 "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)}
8848 },
8849 { &hf_oran_udCompHdrIqWidth_pref,
8850 { "User Data IQ width", "oran_fh_cus.udCompHdrWidth.pref",
8851 FT_UINT8, BASE_DEC,
8852 NULL((void*)0), 0x0,
8853 "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)}
8854 },
8855
8856 { &hf_oran_sinrCompHdrIqWidth_pref,
8857 { "SINR IQ width", "oran_fh_cus.sinrCompHdrWidth",
8858 FT_UINT8, BASE_DEC,
8859 NULL((void*)0), 0x0,
8860 "Defines the IQ bit width for SINR data in section type 9", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8861 },
8862 { &hf_oran_sinrCompHdrMeth_pref,
8863 { "SINR Compression Method", "oran_fh_cus.sinrCompHdrMeth",
8864 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
8865 RVALS(ud_comp_header_meth)((0 ? (const struct _range_string*)0 : ((ud_comp_header_meth)
)))
, 0x0,
8866 "Defines the compression method for SINR data in section type 9", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8867 },
8868
8869 /* Section 8.3.3.15 (not always present - depends upon meth) */
8870 { &hf_oran_udCompParam,
8871 { "User Data Compression Parameter", "oran_fh_cus.udCompParam",
8872 FT_STRING, BASE_NONE,
8873 NULL((void*)0), 0x0,
8874 "Applies to whatever compression method is specified by the associated sectionID's compMeth value", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8875 },
8876 /* 8.3.3.18 */
8877 { &hf_oran_sReSMask,
8878 { "sReSMask", "oran_fh_cus.sReSMask",
8879 FT_UINT16, BASE_HEX,
8880 NULL((void*)0), 0xf0ff,
8881 "selective RE sending mask", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8882 },
8883
8884 { &hf_oran_sReSMask_re12,
8885 { "RE-12", "oran_fh_cus.sReSMask-re12",
8886 FT_BOOLEAN, 16,
8887 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x8000,
8888 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8889 },
8890 { &hf_oran_sReSMask_re11,
8891 { "RE-11", "oran_fh_cus.sReSMask-re11",
8892 FT_BOOLEAN, 16,
8893 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x4000,
8894 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8895 },
8896 { &hf_oran_sReSMask_re10,
8897 { "RE-10", "oran_fh_cus.sReSMask-re10",
8898 FT_BOOLEAN, 16,
8899 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x2000,
8900 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8901 },
8902 { &hf_oran_sReSMask_re9,
8903 { "RE-9", "oran_fh_cus.sReSMask-re9",
8904 FT_BOOLEAN, 16,
8905 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x1000,
8906 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8907 },
8908 { &hf_oran_sReSMask_re8,
8909 { "RE-8", "oran_fh_cus.sReSMask-re8",
8910 FT_BOOLEAN, 16,
8911 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0080,
8912 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8913 },
8914 { &hf_oran_sReSMask_re7,
8915 { "RE-7", "oran_fh_cus.sReSMask-re7",
8916 FT_BOOLEAN, 16,
8917 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0040,
8918 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8919 },
8920 { &hf_oran_sReSMask_re6,
8921 { "RE-6", "oran_fh_cus.sReSMask-re6",
8922 FT_BOOLEAN, 16,
8923 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0020,
8924 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8925 },
8926 { &hf_oran_sReSMask_re5,
8927 { "RE-5", "oran_fh_cus.sReSMask-re5",
8928 FT_BOOLEAN, 16,
8929 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0010,
8930 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8931 },
8932 { &hf_oran_sReSMask_re4,
8933 { "RE-4", "oran_fh_cus.sReSMask-re4",
8934 FT_BOOLEAN, 16,
8935 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0008,
8936 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8937 },
8938 { &hf_oran_sReSMask_re3,
8939 { "RE-3", "oran_fh_cus.sReSMask-re3",
8940 FT_BOOLEAN, 16,
8941 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0004,
8942 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8943 },
8944 { &hf_oran_sReSMask_re2,
8945 { "RE-2", "oran_fh_cus.sReSMask-re2",
8946 FT_BOOLEAN, 16,
8947 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0002,
8948 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8949 },
8950 { &hf_oran_sReSMask_re1,
8951 { "RE-1", "oran_fh_cus.sReSMask-re1",
8952 FT_BOOLEAN, 16,
8953 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0001,
8954 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8955 },
8956
8957 /* 8.3.3.20 */
8958 { &hf_oran_sReSMask1,
8959 { "sReSMask1", "oran_fh_cus.sReSMask1",
8960 FT_UINT16, BASE_HEX,
8961 NULL((void*)0), 0x0fff,
8962 "selective RE sending mask 1", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8963 },
8964 /* 8.3.3.21 */
8965 { &hf_oran_sReSMask2,
8966 { "sReSMask2", "oran_fh_cus.sReSMask2",
8967 FT_UINT16, BASE_HEX,
8968 NULL((void*)0), 0x0fff,
8969 "selective RE sending mask 2", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8970 },
8971
8972 { &hf_oran_sReSMask1_2_re12,
8973 { "RE-12", "oran_fh_cus.sReSMask-re12",
8974 FT_BOOLEAN, 16,
8975 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0800,
8976 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8977 },
8978 { &hf_oran_sReSMask1_2_re11,
8979 { "RE-11", "oran_fh_cus.sReSMask-re11",
8980 FT_BOOLEAN, 16,
8981 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0400,
8982 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8983 },
8984 { &hf_oran_sReSMask1_2_re10,
8985 { "RE-10", "oran_fh_cus.sReSMask-re10",
8986 FT_BOOLEAN, 16,
8987 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0200,
8988 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8989 },
8990 { &hf_oran_sReSMask1_2_re9,
8991 { "RE-9", "oran_fh_cus.sReSMask-re9",
8992 FT_BOOLEAN, 16,
8993 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0100,
8994 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8995 },
8996
8997 /* Section 6.3.3.15 */
8998 { &hf_oran_iSample,
8999 { "iSample", "oran_fh_cus.iSample",
9000 FT_FLOAT, BASE_NONE,
9001 NULL((void*)0), 0x0,
9002 "In-phase Sample value", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9003 },
9004
9005 /* Section 6.3.3.16 */
9006 { &hf_oran_qSample,
9007 { "qSample", "oran_fh_cus.qSample",
9008 FT_FLOAT, BASE_NONE,
9009 NULL((void*)0), 0x0,
9010 "Quadrature Sample value", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9011 },
9012
9013 { &hf_oran_exponent,
9014 { "Exponent", "oran_fh_cus.exponent",
9015 FT_UINT8, BASE_DEC,
9016 NULL((void*)0), 0x0f,
9017 "Exponent applicable to the I & Q mantissas", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9018 },
9019
9020 { &hf_oran_iq_user_data,
9021 { "IQ User Data", "oran_fh_cus.iq_user_data",
9022 FT_BYTES, BASE_NONE,
9023 NULL((void*)0), 0x0,
9024 "Used for the In-phase and Quadrature sample mantissa", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9025 },
9026
9027
9028 { &hf_oran_u_section_ul_symbol_time,
9029 { "Microseconds since first UL U-plane frame for this symbol", "oran_fh_cus.us-since-first-ul-frame",
9030 FT_UINT32, BASE_DEC,
9031 NULL((void*)0), 0x0,
9032 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9033 },
9034 { &hf_oran_u_section_ul_symbol_frames,
9035 { "Number of UL frames sent for this symbol", "oran_fh_cus.number-ul-frames-in-symbol",
9036 FT_UINT32, BASE_DEC,
9037 NULL((void*)0), 0x0,
9038 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9039 },
9040 { &hf_oran_u_section_ul_symbol_first_frame,
9041 { "First UL frame for this symbol", "oran_fh_cus.first-ul-frame-in-symbol",
9042 FT_FRAMENUM, BASE_NONE,
9043 FRAMENUM_TYPE(FT_FRAMENUM_NONE)((gpointer) (glong) (FT_FRAMENUM_NONE)), 0x0,
9044 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9045 },
9046 { &hf_oran_u_section_ul_symbol_last_frame,
9047 { "Last UL frame for this symbol", "oran_fh_cus.last-ul-frame-in-symbol",
9048 FT_FRAMENUM, BASE_NONE,
9049 FRAMENUM_TYPE(FT_FRAMENUM_NONE)((gpointer) (glong) (FT_FRAMENUM_NONE)), 0x0,
9050 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9051 },
9052
9053 { &hf_oran_c_eAxC_ID,
9054 { "c_eAxC_ID", "oran_fh_cus.c_eaxc_id",
9055 FT_STRING, BASE_NONE,
9056 NULL((void*)0), 0x0,
9057 "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) }
9058 },
9059
9060 { &hf_oran_refa,
9061 { "RefA", "oran_fh_cus.refa",
9062 FT_STRING, BASE_NONE,
9063 NULL((void*)0), 0x0,
9064 "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) }
9065 },
9066
9067
9068 /* Section 7.5.2.15 */
9069 { &hf_oran_ciCompHdr,
9070 { "ciCompHdr", "oran_fh_cus.ciCompHdr",
9071 FT_STRING, BASE_NONE,
9072 NULL((void*)0), 0x0,
9073 "Channel Information Compression Header", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9074 },
9075 { &hf_oran_ciCompHdrMeth,
9076 { "User Data Compression Method", "oran_fh_cus.ciCompHdrMeth",
9077 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
9078 RVALS(ud_comp_header_meth)((0 ? (const struct _range_string*)0 : ((ud_comp_header_meth)
)))
, 0x0e,
9079 "Compression method for Channel Information", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9080 },
9081 { &hf_oran_ciCompHdrIqWidth,
9082 { "User Data IQ width", "oran_fh_cus.ciCompHdrWidth",
9083 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
9084 RVALS(ud_comp_header_width)((0 ? (const struct _range_string*)0 : ((ud_comp_header_width
))))
, 0xf0,
9085 "IQ bit width for Channel Information", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9086 },
9087 { &hf_oran_ciCompOpt,
9088 { "ciCompOpt", "oran_fh_cus.ciCompOpt",
9089 FT_UINT8, BASE_DEC,
9090 VALS(ci_comp_opt_vals)((0 ? (const struct _value_string*)0 : ((ci_comp_opt_vals)))), 0x01,
9091 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9092 },
9093
9094 /* 7.7.11.7 */
9095 { &hf_oran_disable_bfws,
9096 { "disableBFWs", "oran_fh_cus.disableBFWs",
9097 FT_BOOLEAN, 8,
9098 NULL((void*)0), 0x80,
9099 "Indicate if BFWs under section extension are disabled", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9100 },
9101 /* 7.7.11.8 */
9102 { &hf_oran_rad,
9103 { "RAD", "oran_fh_cus.rad",
9104 FT_BOOLEAN, 8,
9105 NULL((void*)0), 0x40,
9106 "Reset After PRB Discontinuity", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9107 },
9108 /* 7.7.11.4 */
9109 { &hf_oran_num_bund_prbs,
9110 { "numBundPrb", "oran_fh_cus.numBundPrb",
9111 FT_UINT8, BASE_DEC,
9112 NULL((void*)0), 0x0,
9113 "Number of bundled PRBs per BFWs", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9114 },
9115 { &hf_oran_beam_id,
9116 { "beamId", "oran_fh_cus.beamId",
9117 FT_UINT16, BASE_DEC,
9118 NULL((void*)0), 0x7fff,
9119 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9120 },
9121 { &hf_oran_num_weights_per_bundle,
9122 { "Num weights per bundle", "oran_fh_cus.num_weights_per_bundle",
9123 FT_UINT16, BASE_DEC,
9124 NULL((void*)0), 0x0,
9125 "From dissector preference", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9126 },
9127
9128 { &hf_oran_samples_prb,
9129 {"PRB", "oran_fh_cus.prb",
9130 FT_STRING, BASE_NONE,
9131 NULL((void*)0), 0x0,
9132 "Grouping of samples for a particular Physical Resource Block", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9133 },
9134
9135 /* 7.5.3.13 */
9136 { &hf_oran_ciSample,
9137 { "ciSample", "oran_fh_cus.ciSample",
9138 FT_STRING, BASE_NONE,
9139 NULL((void*)0), 0x0,
9140 "Sample (I and Q values)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9141 },
9142 { &hf_oran_ciIsample,
9143 { "ciIsample", "oran_fh_cus.ciISample",
9144 FT_FLOAT, BASE_NONE,
9145 NULL((void*)0), 0x0,
9146 "Channel information complex value - I part", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9147 },
9148 { &hf_oran_ciQsample,
9149 { "ciQsample", "oran_fh_cus.ciQSample",
9150 FT_FLOAT, BASE_NONE,
9151 NULL((void*)0), 0x0,
9152 "Channel information complex value - Q part", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9153 },
9154
9155 /* 7.7.10.2 */
9156 { &hf_oran_beamGroupType,
9157 { "beamGroupType", "oran_fh_cus.beamGroupType",
9158 FT_UINT8, BASE_DEC,
9159 VALS(beam_group_type_vals)((0 ? (const struct _value_string*)0 : ((beam_group_type_vals
))))
, 0xc0,
9160 "The type of beam grouping", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9161 },
9162 /* 7.7.10.3 */
9163 { &hf_oran_numPortc,
9164 { "numPortc", "oran_fh_cus.numPortc",
9165 FT_UINT8, BASE_DEC,
9166 NULL((void*)0), 0x3f,
9167 "The number of eAxC ports", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9168 },
9169
9170 /* 7.7.4.2 (1 bit) */
9171 { &hf_oran_csf,
9172 { "csf", "oran_fh_cus.csf",
9173 FT_BOOLEAN, BASE_NONE,
9174 NULL((void*)0), 0x0,
9175 "constellation shift flag", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9176 },
9177 /* 7.7.4.3 */
9178 { &hf_oran_modcompscaler,
9179 { "modCompScaler", "oran_fh_cus.modcompscaler",
9180 FT_UINT16, BASE_DEC,
9181 NULL((void*)0), 0x7fff,
9182 "modulation compression scaler value", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9183 },
9184
9185 /* 7.7.5.1 */
9186 { &hf_oran_modcomp_param_set,
9187 { "Set", "oran_fh_cus.modcomp-param-set",
9188 FT_STRING, BASE_NONE,
9189 NULL((void*)0), 0x0,
9190 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9191 },
9192
9193
9194
9195 /* mcScaleReMask 7.7.5.2 (12 bits) */
9196
9197 /* First entry (starts with msb within byte) */
9198 { &hf_oran_mc_scale_re_mask_re1,
9199 { "RE 1", "oran_fh_cus.mcscalermask-RE1",
9200 FT_BOOLEAN, 16,
9201 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x8000,
9202 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9203 },
9204 { &hf_oran_mc_scale_re_mask_re2,
9205 { "RE 2", "oran_fh_cus.mcscalermask-RE2",
9206 FT_BOOLEAN, 16,
9207 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x4000,
9208 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9209 },
9210 { &hf_oran_mc_scale_re_mask_re3,
9211 { "RE 3", "oran_fh_cus.mcscalermask-RE3",
9212 FT_BOOLEAN, 16,
9213 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x2000,
9214 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9215 },
9216 { &hf_oran_mc_scale_re_mask_re4,
9217 { "RE 4", "oran_fh_cus.mcscalermask-RE4",
9218 FT_BOOLEAN, 16,
9219 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x1000,
9220 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9221 },
9222 { &hf_oran_mc_scale_re_mask_re5,
9223 { "RE 5", "oran_fh_cus.mcscalermask-RE5",
9224 FT_BOOLEAN, 16,
9225 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0800,
9226 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9227 },
9228 { &hf_oran_mc_scale_re_mask_re6,
9229 { "RE 6", "oran_fh_cus.mcscalermask-RE6",
9230 FT_BOOLEAN, 16,
9231 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0400,
9232 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9233 },
9234 { &hf_oran_mc_scale_re_mask_re7,
9235 { "RE 7", "oran_fh_cus.mcscalermask-RE7",
9236 FT_BOOLEAN, 16,
9237 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0200,
9238 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9239 },
9240 { &hf_oran_mc_scale_re_mask_re8,
9241 { "RE 8", "oran_fh_cus.mcscalermask-RE8",
9242 FT_BOOLEAN, 16,
9243 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0100,
9244 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9245 },
9246 { &hf_oran_mc_scale_re_mask_re9,
9247 { "RE 9", "oran_fh_cus.mcscalermask-RE9",
9248 FT_BOOLEAN, 16,
9249 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0080,
9250 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9251 },
9252 { &hf_oran_mc_scale_re_mask_re10,
9253 { "RE 10", "oran_fh_cus.mcscalermask-RE10",
9254 FT_BOOLEAN, 16,
9255 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0040,
9256 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9257 },
9258 { &hf_oran_mc_scale_re_mask_re11,
9259 { "RE 11", "oran_fh_cus.mcscalermask-RE11",
9260 FT_BOOLEAN, 16,
9261 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0020,
9262 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9263 },
9264 { &hf_oran_mc_scale_re_mask_re12,
9265 { "RE 12", "oran_fh_cus.mcscalermask-RE12",
9266 FT_BOOLEAN, 16,
9267 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0010,
9268 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9269 },
9270
9271 /* Even tries entry (starts with 5th bit within byte) */
9272 { &hf_oran_mc_scale_re_mask_re1_even,
9273 { "RE 1", "oran_fh_cus.mcscalermask-RE1",
9274 FT_BOOLEAN, 16,
9275 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0800,
9276 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9277 },
9278 { &hf_oran_mc_scale_re_mask_re2_even,
9279 { "RE 2", "oran_fh_cus.mcscalermask-RE2",
9280 FT_BOOLEAN, 16,
9281 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0400,
9282 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9283 },
9284 { &hf_oran_mc_scale_re_mask_re3_even,
9285 { "RE 3", "oran_fh_cus.mcscalermask-RE3",
9286 FT_BOOLEAN, 16,
9287 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0200,
9288 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9289 },
9290 { &hf_oran_mc_scale_re_mask_re4_even,
9291 { "RE 4", "oran_fh_cus.mcscalermask-RE4",
9292 FT_BOOLEAN, 16,
9293 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0100,
9294 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9295 },
9296 { &hf_oran_mc_scale_re_mask_re5_even,
9297 { "RE 5", "oran_fh_cus.mcscalermask-RE5",
9298 FT_BOOLEAN, 16,
9299 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0080,
9300 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9301 },
9302 { &hf_oran_mc_scale_re_mask_re6_even,
9303 { "RE 6", "oran_fh_cus.mcscalermask-RE6",
9304 FT_BOOLEAN, 16,
9305 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0040,
9306 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9307 },
9308 { &hf_oran_mc_scale_re_mask_re7_even,
9309 { "RE 7", "oran_fh_cus.mcscalermask-RE7",
9310 FT_BOOLEAN, 16,
9311 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0020,
9312 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9313 },
9314 { &hf_oran_mc_scale_re_mask_re8_even,
9315 { "RE 8", "oran_fh_cus.mcscalermask-RE8",
9316 FT_BOOLEAN, 16,
9317 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0010,
9318 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9319 },
9320 { &hf_oran_mc_scale_re_mask_re9_even,
9321 { "RE 9", "oran_fh_cus.mcscalermask-RE9",
9322 FT_BOOLEAN, 16,
9323 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0008,
9324 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9325 },
9326 { &hf_oran_mc_scale_re_mask_re10_even,
9327 { "RE 10", "oran_fh_cus.mcscalermask-RE10",
9328 FT_BOOLEAN, 16,
9329 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0004,
9330 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9331 },
9332 { &hf_oran_mc_scale_re_mask_re11_even,
9333 { "RE 11", "oran_fh_cus.mcscalermask-RE11",
9334 FT_BOOLEAN, 16,
9335 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0002,
9336 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9337 },
9338 { &hf_oran_mc_scale_re_mask_re12_even,
9339 { "RE 12", "oran_fh_cus.mcscalermask-RE12",
9340 FT_BOOLEAN, 16,
9341 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0001,
9342 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9343 },
9344
9345 { &hf_oran_mc_scale_re_mask,
9346 { "mcScaleReMask", "oran_fh_cus.mcscaleremask",
9347 FT_UINT16, BASE_HEX,
9348 NULL((void*)0), 0xfff0,
9349 "modulation compression power scale RE mask", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9350 },
9351 { &hf_oran_mc_scale_re_mask_even,
9352 { "mcScaleReMask", "oran_fh_cus.mcscaleremask",
9353 FT_UINT16, BASE_HEX,
9354 NULL((void*)0), 0x0fff,
9355 "modulation compression power scale RE mask", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9356 },
9357
9358 /* mcScaleOffset 7.7.5.4 (15 bits) */
9359 { &hf_oran_mc_scale_offset,
9360 { "mcScaleOffset", "oran_fh_cus.mcscaleoffset",
9361 FT_UINT24, BASE_DEC,
9362 NULL((void*)0), 0x0,
9363 "scaling value for modulation compression", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9364 },
9365 /* eAxCmask (7.7.7.2) */
9366 { &hf_oran_eAxC_mask,
9367 { "eAxC Mask", "oran_fh_cus.eaxcmask",
9368 FT_UINT16, BASE_HEX,
9369 NULL((void*)0), 0xffff,
9370 "Which eAxC_ID values the C-Plane message applies to", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9371 },
9372 /* technology (interface name) 7.7.9.2 */
9373 { &hf_oran_technology,
9374 { "Technology", "oran_fh_cus.technology",
9375 FT_UINT8, BASE_DEC,
9376 VALS(interface_name_vals)((0 ? (const struct _value_string*)0 : ((interface_name_vals)
)))
, 0x0,
9377 "Interface name (that C-PLane section applies to)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9378 },
9379 /* Exttype 14 (7.7.14.2) */
9380 { &hf_oran_nullLayerInd,
9381 { "nullLayerInd", "oran_fh_cus.nulllayerind",
9382 FT_BOOLEAN, BASE_NONE,
9383 NULL((void*)0), 0x0,
9384 "Whether corresponding layer is nulling-layer or not", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9385 },
9386
9387 /* Exttype 19 */
9388 /* 7.7.19.3 */
9389 { &hf_oran_se19_repetition,
9390 { "repetition", "oran_fh_cus.repetition",
9391 FT_BOOLEAN, BASE_NONE,
9392 TFS(&repetition_se19_tfs)((0 ? (const struct true_false_string*)0 : ((&repetition_se19_tfs
))))
, 0x0,
9393 "repeat port info flag", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9394 },
9395 /* 7.7.19.8 */
9396 /* TODO: break down into each RE as done for 7.5.3.5 ? */
9397 { &hf_oran_portReMask,
9398 { "portReMask", "oran_fh_cus.portReMask",
9399 FT_BOOLEAN, 16,
9400 TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, 0x0fff,
9401 "RE bitmask per port", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9402 },
9403 /* 7.7.19.9 */
9404 { &hf_oran_portSymbolMask,
9405 { "portSymbolMask", "oran_fh_cus.portSymbolMask",
9406 FT_BOOLEAN, 16,
9407 TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, 0x3fff,
9408 "Symbol bitmask port port", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9409 },
9410
9411 { &hf_oran_ext19_port,
9412 {"Port", "oran_fh_cus.ext19.port",
9413 FT_STRING, BASE_NONE,
9414 NULL((void*)0), 0x0,
9415 "Entry for a given port in ext19", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9416 },
9417
9418 /* Ext 13 */
9419 { &hf_oran_prb_allocation,
9420 {"PRB allocation", "oran_fh_cus.prb-allocation",
9421 FT_STRING, BASE_NONE,
9422 NULL((void*)0), 0x0,
9423 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9424 },
9425 /* 7.7.13.2 */
9426 { &hf_oran_nextSymbolId,
9427 { "nextSymbolId", "oran_fh_cus.nextSymbolId",
9428 FT_UINT8, BASE_DEC,
9429 NULL((void*)0), 0x3c,
9430 "offset of PRB range start", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9431 },
9432 /* 7.7.13.3 */
9433 { &hf_oran_nextStartPrbc,
9434 { "nextStartPrbc", "oran_fh_cus.nextStartPrbc",
9435 FT_UINT16, BASE_DEC,
9436 NULL((void*)0), 0x03ff,
9437 "number of PRBs in PRB range", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9438 },
9439
9440 /* Puncturing patters as appears in SE 20 */
9441 { &hf_oran_puncPattern,
9442 { "puncPattern", "oran_fh_cus.puncPattern",
9443 FT_STRING, BASE_NONE,
9444 NULL((void*)0), 0x0,
9445 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9446 },
9447
9448 /* 7.7.20.2 numPuncPatterns */
9449 { &hf_oran_numPuncPatterns,
9450 { "numPuncPatterns", "oran_fh_cus.numPuncPatterns",
9451 FT_UINT8, BASE_DEC,
9452 NULL((void*)0), 0x0,
9453 "number of puncturing patterns", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9454 },
9455 /* 7.7.20.3 symbolMask */
9456 { &hf_oran_symbolMask_ext20,
9457 { "symbolMask", "oran_fh_cus.symbolMask",
9458 FT_UINT16, BASE_HEX,
9459 NULL((void*)0), 0xfffc,
9460 "Bitmask where each bit indicates the symbols associated with the puncturing pattern", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9461 },
9462 /* 7.7.20.4 startPuncPrb */
9463 { &hf_oran_startPuncPrb,
9464 { "startPuncPrb", "oran_fh_cus.startPuncPrb",
9465 FT_UINT16, BASE_DEC,
9466 NULL((void*)0), 0x03ff,
9467 "starting PRB to which one puncturing pattern applies", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9468 },
9469 /* 7.7.20.5 numPuncPrb */
9470 { &hf_oran_numPuncPrb,
9471 { "numPuncPrb", "oran_fh_cus.numPuncPrb",
9472 FT_UINT8, BASE_DEC,
9473 NULL((void*)0), 0x0,
9474 "the number of PRBs of the puncturing pattern", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9475 },
9476 /* 7.7.20.6 puncReMask */
9477 { &hf_oran_puncReMask,
9478 { "puncReMask", "oran_fh_cus.puncReMask",
9479 FT_UINT16, BASE_DEC,
9480 NULL((void*)0), 0xffc0,
9481 "puncturing pattern RE mask", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9482 },
9483 /* 7.7.20.12 multiSDScope */
9484 { &hf_oran_multiSDScope,
9485 { "multiSDScope", "oran_fh_cus.multiSDScope",
9486 FT_BOOLEAN, 8,
9487 TFS(&multi_sd_scope_tfs)((0 ? (const struct true_false_string*)0 : ((&multi_sd_scope_tfs
))))
, 0x02,
9488 "multiple section description scope flag", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9489 },
9490 /* 7.7.20.4 rbgIncl */
9491 { &hf_oran_RbgIncl,
9492 { "rbgIncl", "oran_fh_cus.rbgIncl",
9493 FT_BOOLEAN, 8,
9494 NULL((void*)0), 0x01,
9495 "rbg included flag", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9496 },
9497
9498 /* 7.7.21.2 ciPrbGroupSize */
9499 { &hf_oran_ci_prb_group_size,
9500 { "ciPrbGroupSize", "oran_fh_cus.ciPrbGroupSize",
9501 FT_UINT8, BASE_DEC,
9502 NULL((void*)0), 0x0,
9503 "channel information PRB group size", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9504 },
9505 /* 7.21.3 */
9506 { &hf_oran_prg_size_st5,
9507 { "prgSize", "oran_fh_cus.prgSize",
9508 FT_UINT8, BASE_DEC,
9509 VALS(prg_size_st5_vals)((0 ? (const struct _value_string*)0 : ((prg_size_st5_vals)))
)
, 0x03,
9510 "precoding resource block group size", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9511 },
9512 { &hf_oran_prg_size_st6,
9513 { "prgSize", "oran_fh_cus.prgSize",
9514 FT_UINT8, BASE_DEC,
9515 VALS(prg_size_st6_vals)((0 ? (const struct _value_string*)0 : ((prg_size_st6_vals)))
)
, 0x03,
9516 "precoding resource block group size", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9517 },
9518
9519 /* 7.7.17.2 numUeID */
9520 { &hf_oran_num_ueid,
9521 { "numUeID", "oran_fh_cus.numUeID",
9522 FT_UINT8, BASE_DEC,
9523 NULL((void*)0), 0x0,
9524 "number of ueIDs per user", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9525 },
9526
9527 /* 7.7.16.2 antMask */
9528 { &hf_oran_antMask,
9529 { "antMask", "oran_fh_cus.antMask",
9530 FT_UINT64, BASE_HEX,
9531 NULL((void*)0), 0xffffffffffffffff,
9532 "indices of antennas to be pre-combined per RX endpoint", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9533 },
9534
9535 /* 7.7.18.2 transmissionWindowOffset */
9536 { &hf_oran_transmissionWindowOffset,
9537 { "transmissionWindowOffset", "oran_fh_cus.transmissionWindowOffset",
9538 FT_UINT16, BASE_DEC,
9539 NULL((void*)0), 0x0,
9540 "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)}
9541 },
9542 /* 7.7.18.3 transmissionWindowSize */
9543 { &hf_oran_transmissionWindowSize,
9544 { "transmissionWindowSize", "oran_fh_cus.transmissionWindowSize",
9545 FT_UINT16, BASE_DEC,
9546 NULL((void*)0), 0x3fff,
9547 "size of the transmission window in resolution µs", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9548 },
9549 /* 7.7.18.4 toT */
9550 { &hf_oran_toT,
9551 { "toT", "oran_fh_cus.toT",
9552 FT_UINT8, BASE_DEC,
9553 VALS(type_of_transmission_vals)((0 ? (const struct _value_string*)0 : ((type_of_transmission_vals
))))
, 0x03,
9554 "type of transmission", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9555 },
9556
9557 /* 7.7.2.2 bfaCompHdr */
9558 { &hf_oran_bfaCompHdr,
9559 { "bfaCompHdr", "oran_fh_cus.bfaCompHdr",
9560 FT_STRING, BASE_NONE,
9561 NULL((void*)0), 0x0,
9562 "beamforming attributes compression header", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9563 },
9564 /* 7.7.2.2-2: bfAzPtWidth */
9565 { &hf_oran_bfAzPtWidth,
9566 { "bfAzPtWidth", "oran_fh_cus.bfAzPtWidth",
9567 FT_UINT8, BASE_DEC,
9568 VALS(bfa_bw_vals)((0 ? (const struct _value_string*)0 : ((bfa_bw_vals)))), 0x38,
9569 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9570 },
9571 /* 7.7.2.2-3: bfZePtWidth */
9572 { &hf_oran_bfZePtWidth,
9573 { "bfZePtWidth", "oran_fh_cus.bfZePtWidth",
9574 FT_UINT8, BASE_DEC,
9575 VALS(bfa_bw_vals)((0 ? (const struct _value_string*)0 : ((bfa_bw_vals)))), 0x07,
9576 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9577 },
9578 /* 7.7.2.2-4: bfAz3ddWidth */
9579 { &hf_oran_bfAz3ddWidth,
9580 { "bfAz3ddWidth", "oran_fh_cus.bfAz3ddWidth",
9581 FT_UINT8, BASE_DEC,
9582 VALS(bfa_bw_vals)((0 ? (const struct _value_string*)0 : ((bfa_bw_vals)))), 0x38,
9583 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9584 },
9585 /* 7.7.2.2-5: bfZe3ddWidth */
9586 { &hf_oran_bfZe3ddWidth,
9587 { "bfZe3ddWidth", "oran_fh_cus.bfZe3ddWidth",
9588 FT_UINT8, BASE_DEC,
9589 VALS(bfa_bw_vals)((0 ? (const struct _value_string*)0 : ((bfa_bw_vals)))), 0x07,
9590 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9591 },
9592
9593 /* 7.7.2.3 bfAzPt */
9594 { &hf_oran_bfAzPt,
9595 { "bfAzPt", "oran_fh_cus.bfAzPt",
9596 FT_UINT8, BASE_DEC,
9597 NULL((void*)0), 0x0,
9598 "beamforming azimuth pointing parameter", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9599 },
9600 /* 7.7.2.4 bfZePt */
9601 { &hf_oran_bfZePt,
9602 { "bfZePt", "oran_fh_cus.bfZePt",
9603 FT_UINT8, BASE_DEC,
9604 NULL((void*)0), 0x0,
9605 "beamforming zenith pointing parameter", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9606 },
9607 /* 7.7.2.5 bfAz3dd */
9608 { &hf_oran_bfAz3dd,
9609 { "bfAz3dd", "oran_fh_cus.bfAz3dd",
9610 FT_UINT8, BASE_DEC,
9611 NULL((void*)0), 0x0,
9612 "beamforming azimuth beamwidth parameter", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9613 },
9614 /* 7.7.2.6 bfZe3dd */
9615 { &hf_oran_bfZe3dd,
9616 { "bfZe3dd", "oran_fh_cus.bfZe3dd",
9617 FT_UINT8, BASE_DEC,
9618 NULL((void*)0), 0x0,
9619 "beamforming zenith beamwidth parameter", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9620 },
9621
9622 /* 7.7.2.7 bfAzSl */
9623 { &hf_oran_bfAzSl,
9624 { "bfAzSl", "oran_fh_cus.bfAzSl",
9625 FT_UINT8, BASE_DEC,
9626 VALS(sidelobe_suppression_vals)((0 ? (const struct _value_string*)0 : ((sidelobe_suppression_vals
))))
, 0x38,
9627 "beamforming azimuth sidelobe parameter", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9628 },
9629 /* 7.7.2.8 bfZeSl */
9630 { &hf_oran_bfZeSl,
9631 { "bfZeSl", "oran_fh_cus.bfZeSl",
9632 FT_UINT8, BASE_DEC,
9633 VALS(sidelobe_suppression_vals)((0 ? (const struct _value_string*)0 : ((sidelobe_suppression_vals
))))
, 0x07,
9634 "beamforming zenith sidelobe parameter", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9635 },
9636
9637 /* 7.5.2.17 */
9638 { &hf_oran_cmd_scope,
9639 { "cmdScope", "oran_fh_cus.cmdScope",
9640 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
9641 RVALS(cmd_scope_vals)((0 ? (const struct _range_string*)0 : ((cmd_scope_vals)))), 0x0f,
9642 "command scope", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9643 },
9644 /* 7.5.2.18 */
9645 { &hf_oran_number_of_st4_cmds,
9646 { "numberOfST4Cmds", "oran_fh_cus.numberOfST4Cmds",
9647 FT_UINT8, BASE_DEC,
9648 NULL((void*)0), 0x0,
9649 "Number of Section Type 4 commands", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9650 },
9651
9652 { &hf_oran_st4_cmd_header,
9653 { "Command common header", "oran_fh_cus.st4CmdCommonHeader",
9654 FT_STRING, BASE_NONE,
9655 NULL((void*)0), 0x0,
9656 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9657 },
9658
9659 /* 7.5.3.38 */
9660 { &hf_oran_st4_cmd_type,
9661 { "st4CmdType", "oran_fh_cus.st4CmdType",
9662 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
9663 RVALS(st4_cmd_type_vals)((0 ? (const struct _range_string*)0 : ((st4_cmd_type_vals)))
)
, 0x0,
9664 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9665 },
9666 /* 7.5.3.39 */
9667 { &hf_oran_st4_cmd_len,
9668 { "st4CmdLen", "oran_fh_cus.st4CmdLen",
9669 FT_UINT16, BASE_DEC,
9670 NULL((void*)0), 0x0,
9671 "Length of command in 32-bit words", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9672 },
9673 /* 7.5.3.40 */
9674 { &hf_oran_st4_cmd_num_slots,
9675 { "numSlots", "oran_fh_cus.st4NumSlots",
9676 FT_UINT8, BASE_DEC,
9677 NULL((void*)0), 0x0,
9678 "Contiguous slots for which command is applicable", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9679 },
9680 /* 7.5.3.41 */
9681 { &hf_oran_st4_cmd_ack_nack_req_id,
9682 { "ackNackReqId", "oran_fh_cus.ackNackReqId",
9683 FT_UINT16, BASE_DEC,
9684 NULL((void*)0), 0x0,
9685 "ACK/NACK Request Id", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9686 },
9687
9688 { &hf_oran_st4_cmd,
9689 { "Command", "oran_fh_cus.st4Cmd",
9690 FT_STRING, BASE_NONE,
9691 NULL((void*)0), 0x0,
9692 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9693 },
9694
9695 /* 7.5.3.52 */
9696 { &hf_oran_sleepmode_trx,
9697 { "sleepMode", "oran_fh_cus.sleepMode",
9698 FT_UINT8, BASE_HEX,
9699 VALS(sleep_mode_trx_vals)((0 ? (const struct _value_string*)0 : ((sleep_mode_trx_vals)
)))
, 0x03,
9700 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9701 },
9702 { &hf_oran_sleepmode_asm,
9703 { "sleepMode", "oran_fh_cus.sleepMode",
9704 FT_UINT8, BASE_HEX,
9705 VALS(sleep_mode_asm_vals)((0 ? (const struct _value_string*)0 : ((sleep_mode_asm_vals)
)))
, 0x03,
9706 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9707 },
9708
9709 /* 7.5.3.51 */
9710 { &hf_oran_log2maskbits,
9711 { "log2MaskBits", "oran_fh_cus.log2MaskBits",
9712 FT_UINT8, BASE_HEX,
9713 VALS(log2maskbits_vals)((0 ? (const struct _value_string*)0 : ((log2maskbits_vals)))
)
, 0x3c,
9714 "Number of bits to appear in antMask", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9715 },
9716 /* 7.5.3.53 */
9717 { &hf_oran_num_slots_ext,
9718 { "numSlotsExt", "oran_fh_cus.numSlotsExt",
9719 FT_UINT24, BASE_HEX,
9720 NULL((void*)0), 0x0fffff,
9721 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9722 },
9723 /* 7.5.3.54 */
9724 { &hf_oran_antMask_trx_control,
9725 { "antMask", "oran_fh_cus.trxControl.antMask",
9726 FT_BYTES, BASE_NONE,
9727 NULL((void*)0), 0x0,
9728 "which antennas should sleep or wake-up", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9729 },
9730 /* 7.5.3.55 */
9731 { &hf_oran_ready,
9732 { "ready", "oran_fh_cus.ready",
9733 FT_BOOLEAN, 8,
9734 TFS(&ready_tfs)((0 ? (const struct true_false_string*)0 : ((&ready_tfs))
))
, 0x01,
9735 "wake-up ready indicator", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9736 },
9737 /* 7.5.3.34 */
9738 { &hf_oran_number_of_acks,
9739 { "numberOfAcks", "oran_fh_cus.numberOfAcks",
9740 FT_UINT8, BASE_DEC,
9741 NULL((void*)0), 0x0,
9742 "number of ACKs for one eAxC_ID", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9743 },
9744 /* 7.5.3.35 */
9745 { &hf_oran_number_of_nacks,
9746 { "numberOfNacks", "oran_fh_cus.numberOfNacks",
9747 FT_UINT8, BASE_DEC,
9748 NULL((void*)0), 0x0,
9749 "number of NACKs for one eAxC_ID", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9750 },
9751 /* 7.5.3.36 */
9752 { &hf_oran_ackid,
9753 { "ackId", "oran_fh_cus.ackId",
9754 FT_UINT16, BASE_DEC,
9755 NULL((void*)0), 0x0,
9756 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9757 },
9758 /* 7.5.3.37 */
9759 { &hf_oran_nackid,
9760 { "nackId", "oran_fh_cus.nackId",
9761 FT_UINT16, BASE_DEC,
9762 NULL((void*)0), 0x0,
9763 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9764 },
9765
9766 /* Links between acknack requests & responses */
9767 { &hf_oran_acknack_request_frame,
9768 { "Request Frame", "oran_fh_cus.ackNackId.request-frame",
9769 FT_FRAMENUM, BASE_NONE,
9770 FRAMENUM_TYPE(FT_FRAMENUM_REQUEST)((gpointer) (glong) (FT_FRAMENUM_REQUEST)), 0x0,
9771 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9772 },
9773 { &hf_oran_acknack_request_time,
9774 { "Time since request in ms", "oran_fh_cus.ackNackId.time-since-request",
9775 FT_UINT32, BASE_DEC,
9776 NULL((void*)0), 0x0,
9777 "Time between request and response", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9778 },
9779 { &hf_oran_acknack_request_type,
9780 { "Request Type", "oran_fh_cus.ackNackId.request-type",
9781 FT_UINT32, BASE_DEC,
9782 VALS(acknack_type_vals)((0 ? (const struct _value_string*)0 : ((acknack_type_vals)))
)
, 0x0,
9783 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9784 },
9785 { &hf_oran_acknack_response_frame,
9786 { "Response Frame", "oran_fh_cus.ackNackId.response-frame",
9787 FT_FRAMENUM, BASE_NONE,
9788 FRAMENUM_TYPE(FT_FRAMENUM_RESPONSE)((gpointer) (glong) (FT_FRAMENUM_RESPONSE)), 0x0,
9789 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9790 },
9791 { &hf_oran_acknack_response_time,
9792 { "Time to response in ms", "oran_fh_cus.ackNackId.time-to-response",
9793 FT_UINT32, BASE_DEC,
9794 NULL((void*)0), 0x0,
9795 "Time between request and response", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9796 },
9797
9798 /* 7.5.3.43 */
9799 { &hf_oran_disable_tdbfns,
9800 { "disableTDBFNs", "oran_fh_cus.disableTDBFNs",
9801 FT_BOOLEAN, 8,
9802 TFS(&disable_tdbfns_tfs)((0 ? (const struct true_false_string*)0 : ((&disable_tdbfns_tfs
))))
, 0x80,
9803 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9804 },
9805
9806 /* 7.5.3.44 */
9807 { &hf_oran_td_beam_group,
9808 { "tdBeamGrp", "oran_fh_cus.tdBeamGrp",
9809 FT_UINT16, BASE_HEX,
9810 NULL((void*)0), 0x7fff,
9811 "Applies to symbolMask in command header", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9812 },
9813 /* 7.5.3.43 */
9814 { &hf_oran_disable_tdbfws,
9815 { "disableTDBFWs", "oran_fh_cus.disableTDBFWs",
9816 FT_BOOLEAN, 8,
9817 TFS(&beam_numbers_included_tfs)((0 ? (const struct true_false_string*)0 : ((&beam_numbers_included_tfs
))))
, 0x80,
9818 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9819 },
9820
9821 /* 7.5.3.56 */
9822 { &hf_oran_td_beam_num,
9823 { "tdBeamNum", "oran_fh_cus.tdBeamNum",
9824 FT_UINT16, BASE_HEX,
9825 NULL((void*)0), 0x7fff,
9826 "time-domain beam number", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9827 },
9828
9829 /* 7.5.3.49 */
9830 { &hf_oran_dir_pattern,
9831 { "dirPattern", "oran_fh_cus.dirPattern",
9832 FT_BOOLEAN, 16,
9833 TFS(&symbol_direction_tfs)((0 ? (const struct true_false_string*)0 : ((&symbol_direction_tfs
))))
, 0x3fff,
9834 "symbol data direction (gNB Tx/Rx) pattern", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9835 },
9836 /* 7.5.3.50 */
9837 { &hf_oran_guard_pattern,
9838 { "guardPattern", "oran_fh_cus.guardPattern",
9839 FT_BOOLEAN, 16,
9840 TFS(&symbol_guard_tfs)((0 ? (const struct true_false_string*)0 : ((&symbol_guard_tfs
))))
, 0x3fff,
9841 "guard pattern bitmask", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9842 },
9843
9844 /* For convenient filtering */
9845 { &hf_oran_cplane,
9846 { "C-Plane", "oran_fh_cus.c-plane",
9847 FT_NONE, BASE_NONE,
9848 NULL((void*)0), 0x0,
9849 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9850 },
9851 { &hf_oran_uplane,
9852 { "U-Plane", "oran_fh_cus.u-plane",
9853 FT_NONE, BASE_NONE,
9854 NULL((void*)0), 0x0,
9855 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9856 },
9857 { &hf_oran_bf,
9858 { "BeamForming", "oran_fh_cus.bf",
9859 FT_NONE, BASE_NONE,
9860 NULL((void*)0), 0x0,
9861 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9862 },
9863 { &hf_oran_zero_prb,
9864 { "Zero PRB", "oran_fh_cus.zero-prb",
9865 FT_NONE, BASE_NONE,
9866 NULL((void*)0), 0x0,
9867 "All of the REs in this PRB are zero", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9868 },
9869 { &hf_oran_nonzero_prb,
9870 { "Non-Zero PRB", "oran_fh_cus.nonzero-prb",
9871 FT_NONE, BASE_NONE,
9872 NULL((void*)0), 0x0,
9873 "Not all of the REs in this PRB are zero", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9874 },
9875 { &hf_oran_bundle_weights_all_zero,
9876 { "Bundle Weights all zero", "oran_fh_cus.zero-bundle",
9877 FT_NONE, BASE_NONE,
9878 NULL((void*)0), 0x0,
9879 "All of the weights in a bundle are zero", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9880 },
9881
9882
9883 /* 5.1.3.2.7 */
9884 { &hf_oran_ecpri_pcid,
9885 { "ecpriPcid", "oran_fh_cus.ecpriPcid",
9886 FT_NONE, BASE_NONE,
9887 NULL((void*)0), 0x0,
9888 "IQ data transfer message series identifier", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9889 },
9890 { &hf_oran_ecpri_rtcid,
9891 { "ecpriRtcid", "oran_fh_cus.ecpriRtcid",
9892 FT_NONE, BASE_NONE,
9893 NULL((void*)0), 0x0,
9894 "Real time control data identifier", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9895 },
9896 /* 5.1.3.2.8 */
9897 { &hf_oran_ecpri_seqid,
9898 { "ecpriSeqid", "oran_fh_cus.ecpriSeqid",
9899 FT_NONE, BASE_NONE,
9900 NULL((void*)0), 0x0,
9901 "message identifier", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9902 },
9903
9904 /* 7.7.23.2 */
9905 { &hf_oran_num_sym_prb_pattern,
9906 { "numSymPrbPattern", "oran_fh_cus.numSymPrbPattern",
9907 FT_UINT8, BASE_DEC,
9908 NULL((void*)0), 0xf0,
9909 "number of symbol and resource block patterns", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9910 },
9911 /* 7.7.23.11 */
9912 { &hf_oran_prb_mode,
9913 { "prbMode", "oran_fh_cus.prbMode",
9914 FT_BOOLEAN, 8,
9915 TFS(&prb_mode_tfs)((0 ? (const struct true_false_string*)0 : ((&prb_mode_tfs
))))
, 0x01,
9916 "PRB Mode", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9917 },
9918
9919 { &hf_oran_sym_prb_pattern,
9920 { "symPrbPattern", "oran_fh_cus.symPrbPattern",
9921 FT_STRING, BASE_NONE,
9922 NULL((void*)0), 0x0,
9923 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9924 },
9925
9926 /* 7.7.23.3 */
9927 { &hf_oran_sym_mask,
9928 { "symMask", "oran_fh_cus.symMask",
9929 FT_UINT16, BASE_HEX,
9930 NULL((void*)0), 0x3fff,
9931 "symbol mask part of symPrbPattern", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9932 },
9933 /* 7.7.23.5 */
9934 {&hf_oran_num_mc_scale_offset,
9935 {"numMcScaleOffset", "oran_fh_cus.numMcScaleOffset",
9936 FT_UINT8, BASE_DEC,
9937 NULL((void*)0), 0xf0,
9938 "number of modulation compression scaling value per symPrbPattern",
9939 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9940 },
9941 /* 7.7.23.4 */
9942 { &hf_oran_prb_pattern,
9943 { "prbPattern", "oran_fh_cus.prbPattern",
9944 FT_UINT8, BASE_DEC,
9945 NULL((void*)0), 0x0f,
9946 "resource block pattern part of symPrbPattern", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9947 },
9948
9949 /* 7.7.3.2 */
9950 { &hf_oran_codebook_index,
9951 { "codebookIndex", "oran_fh_cus.codebookIndex",
9952 FT_UINT8, BASE_DEC,
9953 NULL((void*)0), 0x0,
9954 "precoder codebook used for transmission", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9955 },
9956 /* 7.7.3.3 */
9957 { &hf_oran_layerid,
9958 { "layerID", "oran_fh_cus.layerID",
9959 FT_UINT8, BASE_DEC,
9960 NULL((void*)0), 0xf0,
9961 "Layer ID for DL transmission", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9962 },
9963 /* 7.7.3.5 */
9964 { &hf_oran_numlayers,
9965 { "numLayers", "oran_fh_cus.numLayers",
9966 FT_UINT8, BASE_DEC,
9967 NULL((void*)0), 0x0f,
9968 "number of layers for DL transmission", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9969 },
9970 /* 7.7.3.4 */
9971 { &hf_oran_txscheme,
9972 { "txScheme", "oran_fh_cus.txScheme",
9973 FT_UINT8, BASE_DEC,
9974 NULL((void*)0), 0xf0,
9975 "transmission scheme", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9976 },
9977 /* 7.7.3.6 */
9978 { &hf_oran_crs_remask,
9979 { "crsReMask", "oran_fh_cus.crsReMask",
9980 FT_UINT16, BASE_HEX,
9981 NULL((void*)0), 0x0fff,
9982 "CRS resource element mask", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9983 },
9984 /* 7.7.3.8 */
9985 { &hf_oran_crs_shift,
9986 { "crsShift", "oran_fh_cus.crsShift",
9987 FT_UINT8, BASE_HEX,
9988 NULL((void*)0), 0x80,
9989 "CRS resource element mask", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9990 },
9991 /* 7.7.3.7 */
9992 { &hf_oran_crs_symnum,
9993 { "crsSymNum", "oran_fh_cus.crsSymNum",
9994 FT_UINT8, BASE_DEC,
9995 NULL((void*)0), 0x0f,
9996 "CRS symbol number indication", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9997 },
9998 /* 7.7.3.9 */
9999 { &hf_oran_beamid_ap1,
10000 { "beamIdAP1", "oran_fh_cus.beamIdAP1",
10001 FT_UINT16, BASE_DEC,
10002 NULL((void*)0), 0x7f,
10003 "beam id to be used for antenna port 1", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10004 },
10005 /* 7.7.3.10 */
10006 { &hf_oran_beamid_ap2,
10007 { "beamIdAP2", "oran_fh_cus.beamIdAP2",
10008 FT_UINT16, BASE_DEC,
10009 NULL((void*)0), 0x7f,
10010 "beam id to be used for antenna port 2", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10011 },
10012 /* 7.7.3.11 */
10013 { &hf_oran_beamid_ap3,
10014 { "beamIdAP3", "oran_fh_cus.beamIdAP3",
10015 FT_UINT16, BASE_DEC,
10016 NULL((void*)0), 0x7f,
10017 "beam id to be used for antenna port 3", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10018 },
10019
10020 /* 7.7.10.3a */
10021 { &hf_oran_port_list_index,
10022 { "portListIndex", "oran_fh_cus.portListIndex",
10023 FT_UINT8, BASE_DEC,
10024 NULL((void*)0), 0x0,
10025 "the index of an eAxC_ID in the port-list", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10026 },
10027
10028 { &hf_oran_alpn_per_sym,
10029 { "alpnPerSym", "oran_fh_cus.alpnPerSym",
10030 FT_UINT8, BASE_HEX,
10031 VALS(alpn_per_sym_vals)((0 ? (const struct _value_string*)0 : ((alpn_per_sym_vals)))
)
, 0x80,
10032 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10033 },
10034 { &hf_oran_ant_dmrs_snr,
10035 { "antDmrsSnr", "oran_fh_cus.antDmrsSnr",
10036 FT_UINT8, BASE_HEX,
10037 VALS(ant_dmrs_snr_vals)((0 ? (const struct _value_string*)0 : ((ant_dmrs_snr_vals)))
)
, 0x40,
10038 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10039 },
10040
10041 /* 7.7.24.6 */
10042 { &hf_oran_user_group_size,
10043 { "userGroupSize", "oran_fh_cus.userGroupSize",
10044 FT_UINT8, BASE_DEC,
10045 NULL((void*)0), 0x1f,
10046 "number of UE data layers in the user group identified by userGroupId", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10047 },
10048 /* 7.7.24.7 */
10049 { &hf_oran_user_group_id,
10050 { "userGroupId", "oran_fh_cus.userGroupId",
10051 FT_UINT8, BASE_DEC,
10052 NULL((void*)0), 0x0,
10053 "indicates user group described by the section", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10054 },
10055 /* 7.7.24.8 */
10056 { &hf_oran_entry_type,
10057 { "entryType", "oran_fh_cus.entryType",
10058 FT_UINT8, BASE_DEC,
10059 VALS(entry_type_vals)((0 ? (const struct _value_string*)0 : ((entry_type_vals)))), 0xe0,
10060 "indicates format of the entry", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10061 },
10062 /* 7.7.24.9 */
10063 { &hf_oran_dmrs_port_number,
10064 { "dmrsPortNumber", "oran_fh_cus.dmrsPortNumber",
10065 FT_UINT8, BASE_DEC,
10066 NULL((void*)0), 0x1f,
10067 "DMRS antenna port number for the associated ueId", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10068 },
10069 /* 7.7.24.10 */
10070 { &hf_oran_ueid_reset,
10071 { "ueidReset", "oran_fh_cus.ueidReset",
10072 FT_BOOLEAN, 8,
10073 TFS(&tfs_ueid_reset)((0 ? (const struct true_false_string*)0 : ((&tfs_ueid_reset
))))
, 0x80,
10074 "same UEID as the previous slot", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10075 },
10076 /* 7.7.24.11 */
10077 { &hf_oran_dmrs_symbol_mask,
10078 { "dmrsSymbolMask", "oran_fh_cus.dmrsSymbolMask",
10079 FT_UINT16, BASE_HEX,
10080 NULL((void*)0), 0x3fff,
10081 "symbols within the slot containing DMRS", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10082 },
10083 { &hf_oran_dmrs_symbol_mask_s13,
10084 { "symbol 13", "oran_fh_cus.dmrsSymbolMask.symbol-13",
10085 FT_BOOLEAN, 16,
10086 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x2000,
10087 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10088 },
10089 { &hf_oran_dmrs_symbol_mask_s12,
10090 { "symbol 12", "oran_fh_cus.dmrsSymbolMask.symbol-12",
10091 FT_BOOLEAN, 16,
10092 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x1000,
10093 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10094 },
10095 { &hf_oran_dmrs_symbol_mask_s11,
10096 { "symbol 11", "oran_fh_cus.dmrsSymbolMask.symbol-11",
10097 FT_BOOLEAN, 16,
10098 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0800,
10099 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10100 },
10101 { &hf_oran_dmrs_symbol_mask_s10,
10102 { "symbol 10", "oran_fh_cus.dmrsSymbolMask.symbol-10",
10103 FT_BOOLEAN, 16,
10104 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0400,
10105 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10106 },
10107 { &hf_oran_dmrs_symbol_mask_s9,
10108 { "symbol 9", "oran_fh_cus.dmrsSymbolMask.symbol-9",
10109 FT_BOOLEAN, 16,
10110 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0200,
10111 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10112 },
10113 { &hf_oran_dmrs_symbol_mask_s8,
10114 { "symbol 8", "oran_fh_cus.dmrsSymbolMask.symbol-8",
10115 FT_BOOLEAN, 16,
10116 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0100,
10117 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10118 },
10119 { &hf_oran_dmrs_symbol_mask_s7,
10120 { "symbol 7", "oran_fh_cus.dmrsSymbolMask.symbol-7",
10121 FT_BOOLEAN, 16,
10122 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0080,
10123 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10124 },
10125 { &hf_oran_dmrs_symbol_mask_s6,
10126 { "symbol 6", "oran_fh_cus.dmrsSymbolMask.symbol-6",
10127 FT_BOOLEAN, 16,
10128 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0040,
10129 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10130 },
10131 { &hf_oran_dmrs_symbol_mask_s5,
10132 { "symbol 5", "oran_fh_cus.dmrsSymbolMask.symbol-5",
10133 FT_BOOLEAN, 16,
10134 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0020,
10135 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10136 },
10137 { &hf_oran_dmrs_symbol_mask_s4,
10138 { "symbol 4", "oran_fh_cus.dmrsSymbolMask.symbol-4",
10139 FT_BOOLEAN, 16,
10140 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0010,
10141 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10142 },
10143 { &hf_oran_dmrs_symbol_mask_s3,
10144 { "symbol 3", "oran_fh_cus.dmrsSymbolMask.symbol-3",
10145 FT_BOOLEAN, 16,
10146 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0008,
10147 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10148 },
10149 { &hf_oran_dmrs_symbol_mask_s2,
10150 { "symbol 2", "oran_fh_cus.dmrsSymbolMask.symbol-2",
10151 FT_BOOLEAN, 16,
10152 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0004,
10153 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10154 },
10155 { &hf_oran_dmrs_symbol_mask_s1,
10156 { "symbol 1", "oran_fh_cus.dmrsSymbolMask.symbol-1",
10157 FT_BOOLEAN, 16,
10158 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0002,
10159 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10160 },
10161 { &hf_oran_dmrs_symbol_mask_s0,
10162 { "symbol 0", "oran_fh_cus.dmrsSymbolMask.symbol-0",
10163 FT_BOOLEAN, 16,
10164 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0001,
10165 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10166 },
10167
10168 /* 7.7.24.12 */
10169 { &hf_oran_scrambling,
10170 { "scrambling", "oran_fh_cus.scrambling",
10171 FT_UINT16, BASE_HEX,
10172 NULL((void*)0), 0x0,
10173 "used to calculate the seed value required to initialize pseudo-random generator", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10174 },
10175 /* 7.7.24.13 */
10176 { &hf_oran_nscid,
10177 { "nscid", "oran_fh_cus.nscid",
10178 FT_UINT8, BASE_HEX,
10179 NULL((void*)0), 0x80,
10180 "used to calculate the seed value for pseudo-random generator", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10181 },
10182 /* 7.7.24.14 */
10183 { &hf_oran_dtype,
10184 { "dType", "oran_fh_cus.dType",
10185 FT_UINT8, BASE_HEX,
10186 VALS(dtype_vals)((0 ? (const struct _value_string*)0 : ((dtype_vals)))), 0x40,
10187 "PUSCH DMRS configuration type", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10188 },
10189 /* 7.7.24.15 */
10190 { &hf_oran_cmd_without_data,
10191 { "cmdWithoutData", "oran_fh_cus.cmdWithoutData",
10192 FT_UINT8, BASE_HEX,
10193 NULL((void*)0), 0x30,
10194 "number of DMRS CDM groups without data", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10195 },
10196 /* 7.7.24.16 */
10197 { &hf_oran_lambda,
10198 { "lambda", "oran_fh_cus.lambda",
10199 FT_UINT8, BASE_HEX,
10200 NULL((void*)0), 0x0c,
10201 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10202 },
10203 /* 7.7.24.19 */
10204 { &hf_oran_first_prb,
10205 { "firstPrb", "oran_fh_cus.firstPrb",
10206 FT_UINT16, BASE_DEC,
10207 NULL((void*)0), 0x03fe,
10208 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10209 },
10210 /* 7.7.24.20 */
10211 { &hf_oran_last_prb,
10212 { "lastPrb", "oran_fh_cus.lastPrb",
10213 FT_UINT16, BASE_DEC,
10214 NULL((void*)0), 0x01ff,
10215 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10216 },
10217
10218 /* 7.7.24.17 */
10219 /* TODO: add value_string */
10220 { &hf_oran_low_papr_type,
10221 { "lowPaprType", "oran_fh_cus.lowPaprType",
10222 FT_UINT8, BASE_HEX,
10223 VALS(papr_type_vals)((0 ? (const struct _value_string*)0 : ((papr_type_vals)))), 0x30,
10224 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10225 },
10226 /* 7.7.24.18 */
10227 { &hf_oran_hopping_mode,
10228 { "hoppingMode", "oran_fh_cus.hoppingMode",
10229 FT_UINT8, BASE_HEX,
10230 VALS(hopping_mode_vals)((0 ? (const struct _value_string*)0 : ((hopping_mode_vals)))
)
, 0x0c,
10231 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10232 },
10233
10234 { &hf_oran_tx_win_for_on_air_symbol_l,
10235 { "txWinForOnAirSymbol", "oran_fh_cus.txWinForOnAirSymbol",
10236 FT_UINT8, BASE_DEC,
10237 NULL((void*)0), 0xf0,
10238 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10239 },
10240 { &hf_oran_tx_win_for_on_air_symbol_r,
10241 { "txWinForOnAirSymbol", "oran_fh_cus.txWinForOnAirSymbol",
10242 FT_UINT8, BASE_DEC,
10243 NULL((void*)0), 0x0f,
10244 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10245 },
10246 /* 7.7.26.2 */
10247 { &hf_oran_num_fo_fb,
10248 { "numFoFb", "oran_fh_cus.numFoFb",
10249 FT_UINT8, BASE_DEC,
10250 NULL((void*)0), 0x7f,
10251 "number of frequency offset feedback", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10252 },
10253 /* 7.7.26.3 */
10254 { &hf_oran_freq_offset_fb,
10255 { "freqOffsetFb", "oran_fh_cus.freqOffsetFb",
10256 FT_UINT16, BASE_HEX_DEC | BASE_RANGE_STRING0x00000100,
10257 RVALS(freq_offset_fb_values)((0 ? (const struct _range_string*)0 : ((freq_offset_fb_values
))))
, 0x0,
10258 "UE frequency offset feedback", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10259 },
10260
10261 /* 7.7.28.2 */
10262 { &hf_oran_num_ue_sinr_rpt,
10263 { "numUeSinrRpt", "oran_fh_cus.numUeSinrRpt",
10264 FT_UINT8, BASE_DEC,
10265 NULL((void*)0), 0x1f,
10266 "number of sinr reported UEs {1 - 12}", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10267 },
10268
10269 /* 7.5.2.19 */
10270 { &hf_oran_num_sinr_per_prb,
10271 { "numSinrPerPrb", "oran_fh_cus.numSinrPerPrb",
10272 FT_UINT8, BASE_DEC,
10273 VALS(num_sinr_per_prb_vals)((0 ? (const struct _value_string*)0 : ((num_sinr_per_prb_vals
))))
, 0x70,
10274 "number of SINR values per PRB", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10275 },
10276 { &hf_oran_num_sinr_per_prb_right,
10277 { "numSinrPerPrb", "oran_fh_cus.numSinrPerPrb",
10278 FT_UINT8, BASE_DEC,
10279 VALS(num_sinr_per_prb_vals)((0 ? (const struct _value_string*)0 : ((num_sinr_per_prb_vals
))))
, 0x07,
10280 "number of SINR values per PRB", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10281 },
10282
10283 /* 7.5.3.68 */
10284 { &hf_oran_sinr_value,
10285 { "sinrValue", "oran_fh_cus.sinrValue",
10286 FT_FLOAT, BASE_NONE,
10287 NULL((void*)0), 0x0,
10288 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10289 },
10290
10291 { &hf_oran_measurement_report,
10292 { "Measurement Report", "oran_fh_cus.measurement-report",
10293 FT_STRING, BASE_NONE,
10294 NULL((void*)0), 0x0,
10295 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10296 },
10297 /* 7.5.3.57 */
10298 { &hf_oran_mf,
10299 { "mf", "oran_fh_cus.mf",
10300 FT_BOOLEAN, 8,
10301 TFS(&measurement_flag_tfs)((0 ? (const struct true_false_string*)0 : ((&measurement_flag_tfs
))))
, 0x80,
10302 "measurement flag", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10303 },
10304 /* 7.5.3.59 */
10305 { &hf_oran_meas_data_size,
10306 { "measDataSize", "oran_fh_cus.measDataSize",
10307 FT_UINT16, BASE_DEC,
10308 NULL((void*)0), 0x0,
10309 "measurement data size (in words)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10310 },
10311
10312 /* 7.5.3.58 */
10313 { &hf_oran_meas_type_id,
10314 { "measTypeId", "oran_fh_cus.measTypeId",
10315 FT_UINT8, BASE_DEC,
10316 VALS(meas_type_id_vals)((0 ? (const struct _value_string*)0 : ((meas_type_id_vals)))
)
, 0x7F,
10317 "measurement report type identifier", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10318 },
10319 /* 7.5.3.66 */
10320 { &hf_oran_num_elements,
10321 { "numElements", "oran_fh_cus.numElements",
10322 FT_UINT8, BASE_DEC,
10323 NULL((void*)0), 0x0,
10324 "measurement report type identifier", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10325 },
10326 /* 7.5.3.60 */
10327 { &hf_oran_ue_tae,
10328 { "ueTae", "oran_fh_cus.ueTae",
10329 FT_UINT16, BASE_DEC | BASE_RANGE_STRING0x00000100,
10330 RVALS(freq_offset_fb_values)((0 ? (const struct _range_string*)0 : ((freq_offset_fb_values
))))
, 0x0,
10331 "UE Timing Advance Error", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10332 },
10333 /* 7.5.3.61 */
10334 { &hf_oran_ue_layer_power,
10335 { "ueLayerPower", "oran_fh_cus.ueLayerPower",
10336 FT_UINT16, BASE_DEC | BASE_RANGE_STRING0x00000100,
10337 RVALS(freq_offset_fb_values)((0 ? (const struct _range_string*)0 : ((freq_offset_fb_values
))))
, 0x0,
10338 "UE Layer Power", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10339 },
10340
10341 /* 7.5.3.62 */
10342 { &hf_oran_ue_freq_offset,
10343 { "ueFreqOffset", "oran_fh_cus.ueFreqOffset",
10344 FT_UINT16, BASE_DEC | BASE_RANGE_STRING0x00000100,
10345 RVALS(freq_offset_fb_values)((0 ? (const struct _range_string*)0 : ((freq_offset_fb_values
))))
, 0x0,
10346 "UE frequency offset", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10347 },
10348 /* 7.5.3.63 */
10349 { &hf_oran_ipn_power,
10350 { "ipnPower", "oran_fh_cus.ipnPower",
10351 FT_UINT16, BASE_DEC | BASE_RANGE_STRING0x00000100,
10352 RVALS(freq_offset_fb_values)((0 ? (const struct _range_string*)0 : ((freq_offset_fb_values
))))
, 0x0,
10353 "Interference plus Noise power", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10354 },
10355 /* 7.5.3.64 */
10356 { &hf_oran_ant_dmrs_snr_val,
10357 { "antDmrsSnrVal", "oran_fh_cus.antDmrsSnrVal",
10358 FT_UINT16, BASE_DEC | BASE_RANGE_STRING0x00000100,
10359 RVALS(freq_offset_fb_values)((0 ? (const struct _range_string*)0 : ((freq_offset_fb_values
))))
, 0x0,
10360 "antenna DMRS-SNR", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10361 },
10362
10363 { &hf_oran_measurement_command,
10364 { "Measurement Command", "oran_fh_cus.measurement-command",
10365 FT_STRING, BASE_NONE,
10366 NULL((void*)0), 0x0,
10367 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10368 },
10369
10370 /* 7.5.27.2 */
10371 { &hf_oran_beam_type,
10372 {"beamType", "oran_fh_cus.beamType",
10373 FT_UINT16, BASE_DEC,
10374 VALS(beam_type_vals)((0 ? (const struct _value_string*)0 : ((beam_type_vals)))), 0xc0,
10375 NULL((void*)0),
10376 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10377 },
10378 /* 7.5.3.65 */
10379 { &hf_oran_meas_cmd_size,
10380 {"measCmdSize", "oran_fh_cus.measCmdSize",
10381 FT_UINT16, BASE_DEC,
10382 NULL((void*)0), 0x0,
10383 "measurement command size in words",
10384 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10385 },
10386
10387 { &hf_oran_symbol_reordering_layer,
10388 { "Layer", "oran_fh_cus.layer",
10389 FT_STRING, BASE_NONE,
10390 NULL((void*)0), 0x0,
10391 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10392 },
10393 { &hf_oran_dmrs_entry,
10394 { "Entry", "oran_fh_cus.dmrs-entry",
10395 FT_STRING, BASE_NONE,
10396 NULL((void*)0), 0x0,
10397 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10398 },
10399
10400 /* 7.7.29.3 */
10401 { &hf_oran_cd_scg_size,
10402 {"cdScgSize", "oran_fh_cus.cdScgSize",
10403 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
10404 RVALS(cd_scg_size_vals)((0 ? (const struct _range_string*)0 : ((cd_scg_size_vals)))), 0x0f,
10405 "Cyclic delay subcarrier group size",
10406 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10407 },
10408 /* 7.7.29.4 */
10409 { &hf_oran_cd_scg_phase_step,
10410 {"cdScgPhaseStep", "oran_fh_cus.cdScgPhaseStep",
10411 FT_INT8, BASE_DEC,
10412 NULL((void*)0), 0x0,
10413 "Cyclic delay subcarrier group phase step",
10414 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10415 },
10416
10417 { &hf_oran_sinr_prb,
10418 { "PRB", "oran_fh_cus.sinr.prb",
10419 FT_STRING, BASE_NONE,
10420 NULL((void*)0), 0x0,
10421 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10422 },
10423 /* 7.5.2.20 */
10424 { &hf_oran_oru_control_sinr_slot_mask_id,
10425 {"oruControlSinrSlotMaskId", "oran_fh_cus.oruControlSinrSlotMaskId",
10426 FT_UINT8, BASE_DEC,
10427 NULL((void*)0), 0x1f,
10428 "SINR time resolution",
10429 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10430 },
10431 /* 7.7.24.21 */
10432 { &hf_oran_pos_meas,
10433 {"posMeas", "oran_fh_cus.posMeas",
10434 FT_BOOLEAN, 8,
10435 TFS(&tfs_report_no_report_pos_meas)((0 ? (const struct true_false_string*)0 : ((&tfs_report_no_report_pos_meas
))))
, 0x40,
10436 "Positioning measurement report request",
10437 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10438 },
10439
10440 /* 7.5.3.69 */
10441 { &hf_oran_ue_radial_speed,
10442 {"ueRadialSpeed", "oran_fh_cus.ueRadialSpeed",
10443 FT_UINT16, BASE_DEC,
10444 NULL((void*)0), 0x0,
10445 "UE radial speed",
10446 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10447 },
10448 /* 7.5.3.70 */
10449 { &hf_oran_ue_az_aoa,
10450 {"ueAzAoa", "oran_fh_cus.ueAzAoa",
10451 FT_UINT16, BASE_DEC,
10452 NULL((void*)0), 0x0,
10453 "UE azimuth angle of arrival",
10454 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10455 },
10456 /* 7.5.3.71 */
10457 { &hf_oran_ue_ze_aoa,
10458 {"ueZeAoa", "oran_fh_cus.ueZeAoa",
10459 FT_UINT16, BASE_DEC,
10460 NULL((void*)0), 0x0,
10461 "UE zenith angle of arrival",
10462 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10463 },
10464 /* 7.5.3.72 */
10465 { &hf_oran_ue_pos_toa_offset,
10466 {"uePosToaOffset", "oran_fh_cus.uePosToaOffset",
10467 FT_UINT16, BASE_DEC,
10468 NULL((void*)0), 0x0,
10469 "UE positioning time of arrival offset",
10470 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10471 },
10472
10473 /* 7.7.30.2 */
10474 { &hf_oran_num_rep_ue,
10475 {"numRepUe", "oran_fh_cus.numRepUe",
10476 FT_UINT8, BASE_DEC,
10477 NULL((void*)0), 0x0f,
10478 "Number of UEs with PUSCH repetition",
10479 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10480 },
10481 /* 7.7.30.3 */
10482 { &hf_oran_rep_ueid,
10483 {"repUeId", "oran_fh_cus.repUeId",
10484 FT_UINT16, BASE_DEC,
10485 NULL((void*)0), 0x7fff,
10486 "UEId the PUSCH is part of",
10487 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10488 },
10489 /* 7.7.30.4 */
10490 { &hf_oran_is_last_rep,
10491 {"isLastRep", "oran_fh_cus.isLastRep",
10492 FT_BOOLEAN, 8,
10493 NULL((void*)0), 0x40,
10494 "Last transmission in the repetition",
10495 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10496 },
10497 /* 7.7.30.5 */
10498 { &hf_oran_rep_index,
10499 {"repIndex", "oran_fh_cus.repIndex",
10500 FT_UINT8, BASE_DEC,
10501 NULL((void*)0), 0x3f,
10502 "Repetition index of the PUSCH transmission",
10503 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10504 },
10505 /* 7.7.30.6 */
10506 { &hf_oran_num_reps,
10507 {"numReps", "oran_fh_cus.numReps",
10508 FT_UINT8, BASE_DEC,
10509 NULL((void*)0), 0x3f,
10510 "The number of total PUSCH repetitions",
10511 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10512 },
10513
10514 /* 7.7.31.2 */
10515 { &hf_oran_mcs_table,
10516 {"mcsTable", "oran_fh_cus.mcsTable",
10517 FT_UINT8, BASE_DEC,
10518 VALS(mcs_table_vals)((0 ? (const struct _value_string*)0 : ((mcs_table_vals)))), 0x0f,
10519 "MCS index table",
10520 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10521 },
10522 /* 7.7.31.3 */
10523 { &hf_oran_mcs_index,
10524 {"mcsIndex", "oran_fh_cus.mcsIndex",
10525 FT_UINT8, BASE_DEC,
10526 NULL((void*)0), 0x3f,
10527 "MCS index value",
10528 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10529 },
10530
10531 /* 7.7.33.3 */
10532 { &hf_oran_num_meas_req,
10533 {"numMeasReq", "oran_fh_cus.numMeasReq",
10534 FT_UINT8, BASE_DEC,
10535 NULL((void*)0), 0x1f,
10536 "Number of UEs for which meas is requested",
10537 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10538 },
10539 /* 7.7.32.5 */
10540 { &hf_oran_ue_rank,
10541 {"ueRank", "oran_fh_cus.ueRank",
10542 FT_UINT8, BASE_DEC,
10543 VALS(ue_rank_vals)((0 ? (const struct _value_string*)0 : ((ue_rank_vals)))), 0x0f,
10544 "Number of UE layers under evaluation",
10545 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10546 },
10547 /* 7.7.32.6 */
10548 { &hf_oran_num_of_ue_ant_ports,
10549 {"numOfUeAntPorts", "oran_fh_cus.numofUeAntPorts",
10550 FT_UINT8, BASE_DEC,
10551 VALS(num_of_ue_ant_ports_vals)((0 ? (const struct _value_string*)0 : ((num_of_ue_ant_ports_vals
))))
, 0xf0,
10552 "Used for the PUSCH tx under evaluation",
10553 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10554 },
10555 /* 7.7.32.8 */
10556 { &hf_oran_codebook_subset,
10557 {"codebookSubset", "oran_fh_cus.codebookSubset",
10558 FT_UINT8, BASE_DEC,
10559 VALS(codebook_subset_vals)((0 ? (const struct _value_string*)0 : ((codebook_subset_vals
))))
, 0xc0,
10560 "UE capability wrt ULTPMI sets",
10561 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10562 },
10563 /* 7.7.32.9 */
10564 { &hf_oran_full_pwr_mode,
10565 {"fullPwrMode", "oran_fh_cus.fullPwrMode",
10566 FT_UINT8, BASE_DEC,
10567 VALS(full_pwr_mode_vals)((0 ? (const struct _value_string*)0 : ((full_pwr_mode_vals))
))
, 0xc0,
10568 "Transmission mode",
10569 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10570 },
10571 /* 7.7.32.10 */
10572 { &hf_oran_full_pwr_mode_2_tpmi_group,
10573 {"fullPwrMode2TpmiGroup", "oran_fh_cus.fullPwrMode2TpmiGroup",
10574 FT_UINT16, BASE_HEX,
10575 NULL((void*)0), 0x3fff,
10576 "Capabilities",
10577 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10578 },
10579
10580 /* 7.5.3.75 */
10581 { &hf_oran_num_cand_ranks,
10582 {"numCandRanks", "oran_fh_cus.numCandRanks",
10583 FT_UINT8, BASE_DEC,
10584 NULL((void*)0), 0xf0,
10585 NULL((void*)0),
10586 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10587 },
10588 /* 7.5.3.76 */
10589 { &hf_oran_ue_pref_rank,
10590 {"uePrefRank", "oran_fh_cus.uePrefRank",
10591 FT_UINT8, BASE_DEC,
10592 NULL((void*)0), 0x0f,
10593 "Most optimal UL Tx rank for UE",
10594 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10595 },
10596
10597 { &hf_oran_c_section_common,
10598 { "Common Section", "oran_fh_cus.c-plane.section.common",
10599 FT_STRING, BASE_NONE,
10600 NULL((void*)0), 0x0,
10601 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10602 },
10603 { &hf_oran_c_section,
10604 { "Section", "oran_fh_cus.c-plane.section",
10605 FT_STRING, BASE_NONE,
10606 NULL((void*)0), 0x0,
10607 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10608 },
10609 { &hf_oran_u_section,
10610 { "Section", "oran_fh_cus.u-plane.section",
10611 FT_STRING, BASE_NONE,
10612 NULL((void*)0), 0x0,
10613 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10614 },
10615
10616 /* Link back to UL C-plane where udCompHdr was recorded */
10617 { &hf_oran_ul_cplane_ud_comp_hdr_frame,
10618 { "C-Plane UL udCompHdr frame", "oran_fh_cus.ul-cplane.udCompHdr",
10619 FT_FRAMENUM, BASE_NONE,
10620 FRAMENUM_TYPE(FT_FRAMENUM_REQUEST)((gpointer) (glong) (FT_FRAMENUM_REQUEST)), 0x0,
10621 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10622 },
10623
10624 /* For ext11, where was a beamId (last) defined? */
10625 { &hf_oran_bfws_frame_defined,
10626 { "Beam defined in frame", "oran_fh_cus.bfw-defined",
10627 FT_FRAMENUM, BASE_NONE,
10628 FRAMENUM_TYPE(FT_FRAMENUM_RETRANS_PREV)((gpointer) (glong) (FT_FRAMENUM_RETRANS_PREV)), 0x0,
10629 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10630 },
10631 { &hf_oran_bfws_symbols_since_defined,
10632 { "Symbols since BFWs defined", "oran_fh_cus.symbols-since-bfw-defined",
10633 FT_UINT32, BASE_DEC,
10634 NULL((void*)0), 0x0,
10635 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10636 },
10637
10638 /* Corresponding C-plane frame for DL U-plane */
10639 { &hf_oran_corresponding_cplane_frame,
10640 { "C-plane frame", "oran_fh_cus.cplane-frame",
10641 FT_FRAMENUM, BASE_NONE,
10642 FRAMENUM_TYPE(FT_FRAMENUM_REQUEST)((gpointer) (glong) (FT_FRAMENUM_REQUEST)), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10643 },
10644 /* Time since corresponding C-plane frame for DL U-plane */
10645 { &hf_oran_corresponding_cplane_frame_time_delta,
10646 { "Time since C-plane frame", "oran_fh_cus.cplane-frame-time-delta",
10647 FT_UINT32, BASE_DEC, NULL((void*)0), 0x0,
10648 "Microseconds since C-plane frame", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10649 },
10650
10651 /* Reassembly */
10652 { &hf_oran_fragment,
10653 { "Fragment", "oran_fh_cus.fragment", FT_FRAMENUM, BASE_NONE,
10654 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10655 { &hf_oran_fragments,
10656 { "Fragments", "oran_fh_cus.fragments", FT_BYTES, BASE_NONE,
10657 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10658 { &hf_oran_fragment_overlap,
10659 { "Fragment overlap", "oran_fh_cus.fragment.overlap", FT_BOOLEAN, BASE_NONE,
10660 NULL((void*)0), 0x0, "Fragment overlaps with other fragments", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10661 { &hf_oran_fragment_overlap_conflict,
10662 { "Conflicting data in fragment overlap", "oran_fh_cus.fragment.overlap.conflict",
10663 FT_BOOLEAN, BASE_NONE, NULL((void*)0), 0x0,
10664 "Overlapping fragments contained conflicting data", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10665 { &hf_oran_fragment_multiple_tails,
10666 { "Multiple tail fragments found", "oran_fh_cus.fragment.multipletails",
10667 FT_BOOLEAN, BASE_NONE, NULL((void*)0), 0x0,
10668 "Several tails were found when defragmenting the packet", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10669 { &hf_oran_fragment_too_long_fragment,
10670 { "Fragment too long", "oran_fh_cus.fragment.toolongfragment",
10671 FT_BOOLEAN, BASE_NONE, NULL((void*)0), 0x0,
10672 "Fragment contained data past end of packet", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10673 { &hf_oran_fragment_error,
10674 { "Defragmentation error", "oran_fh_cus.fragment.error", FT_FRAMENUM, BASE_NONE,
10675 NULL((void*)0), 0x0, "Defragmentation error due to illegal fragments", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10676 { &hf_oran_fragment_count,
10677 { "Fragment count", "oran_fh_cus.fragment.count", FT_UINT32, BASE_DEC,
10678 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10679 { &hf_oran_reassembled_in,
10680 { "Reassembled payload in frame", "oran_fh_cus.reassembled_in", FT_FRAMENUM, BASE_NONE,
10681 NULL((void*)0), 0x0, "This payload packet is reassembled in this frame", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10682 { &hf_oran_reassembled_length,
10683 { "Reassembled payload length", "oran_fh_cus.reassembled.length", FT_UINT32, BASE_DEC,
10684 NULL((void*)0), 0x0, "The total length of the reassembled payload", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10685 { &hf_oran_reassembled_data,
10686 { "Reassembled data", "oran_fh_cus.reassembled.data", FT_BYTES, BASE_NONE,
10687 NULL((void*)0), 0x0, "The reassembled payload", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10688
10689 { &hf_oran_payload,
10690 { "Payload", "oran_fh_cus.payload", FT_BYTES, BASE_SHOW_ASCII_PRINTABLE0x00010000,
10691 NULL((void*)0), 0x0, "Complete or reassembled payload", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10692 };
10693
10694 /* Setup protocol subtree array */
10695 static int *ett[] = {
10696 &ett_oran,
10697 &ett_oran_ecpri_pcid,
10698 &ett_oran_ecpri_rtcid,
10699 &ett_oran_ecpri_seqid,
10700 &ett_oran_section_type,
10701 &ett_oran_u_timing,
10702 &ett_oran_u_section,
10703 &ett_oran_u_prb,
10704 &ett_oran_section,
10705 &ett_oran_iq,
10706 &ett_oran_bfw_bundle,
10707 &ett_oran_bfw,
10708 &ett_oran_frequency_range,
10709 &ett_oran_prb_cisamples,
10710 &ett_oran_cisample,
10711 &ett_oran_udcomphdr,
10712 &ett_oran_udcompparam,
10713 &ett_oran_cicomphdr,
10714 &ett_oran_cicompparam,
10715 &ett_oran_bfwcomphdr,
10716 &ett_oran_bfwcompparam,
10717 &ett_oran_ext19_port,
10718 &ett_oran_prb_allocation,
10719 &ett_oran_punc_pattern,
10720 &ett_oran_bfacomphdr,
10721 &ett_oran_modcomp_param_set,
10722 &ett_oran_st4_cmd_header,
10723 &ett_oran_st4_cmd,
10724 &ett_oran_sym_prb_pattern,
10725 &ett_oran_measurement_report,
10726 &ett_oran_measurement_command,
10727 &ett_oran_sresmask,
10728 &ett_oran_c_section_common,
10729 &ett_oran_c_section,
10730 &ett_oran_remask,
10731 &ett_oran_mc_scale_remask,
10732 &ett_oran_symbol_reordering_layer,
10733 &ett_oran_dmrs_entry,
10734 &ett_oran_dmrs_symbol_mask,
10735 &ett_oran_symbol_mask,
10736 &ett_oran_active_beamspace_coefficient_mask,
10737 &ett_oran_sinr_prb,
10738
10739 &ett_oran_fragment,
10740 &ett_oran_fragments
10741 };
10742
10743 /* Separate subtree array for extensions. Used with [ext-1] */
10744 static int *ext_ett[HIGHEST_EXTTYPE32];
10745 for (unsigned extno=0; extno<HIGHEST_EXTTYPE32; extno++) {
10746 ext_ett[extno] = &ett_oran_c_section_extension[extno];
10747 }
10748
10749 expert_module_t* expert_oran;
10750
10751 static ei_register_info ei[] = {
10752 { &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)}}
}},
10753 { &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)}}
}},
10754 { &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)}}
}},
10755 { &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)}}
}},
10756 { &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)}}
}},
10757 { &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)}}
}},
10758 { &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)}}
}},
10759 { &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)}}
}},
10760 { &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)}}
}},
10761 { &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)}}
}},
10762 { &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)}}
}},
10763 { &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)}}
}},
10764 { &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)}}
}},
10765 { &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)}}
}},
10766 { &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)}}
}},
10767 { &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)}}
}},
10768 { &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)}}
}},
10769 { &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)}}
}},
10770 { &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)}}
}},
10771 { &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)}}
}},
10772 { &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)}}
}},
10773 { &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)}}
}},
10774 { &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)}}
}},
10775 { &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)}}
}},
10776 { &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)}}
}},
10777 { &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)}}
}},
10778 { &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)}}
}},
10779 { &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)}}
}},
10780 { &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)}}
}},
10781 { &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)}}
}},
10782 { &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)}}
}},
10783 { &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)}}
}},
10784 { &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)}}
}},
10785 { &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)}}
}},
10786 { &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)}}
}},
10787 { &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)}}
}},
10788 { &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)}}
}},
10789 { &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)}}
}},
10790 { &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)}}
}},
10791 { &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)}}
}},
10792 { &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)}}
}},
10793 { &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)}}
}},
10794 { &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)}}
}},
10795 { &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)}}
}},
10796 { &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)}}
}},
10797 { &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)}}
}},
10798 { &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)}}
}},
10799 { &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)}}
}},
10800 { &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)}}
}},
10801 { &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)}}
}},
10802 { &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)}}
}},
10803 { &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)}}
}},
10804 { &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)}}
}},
10805 { &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)}}
}},
10806 { &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)}}
}},
10807 { &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)}}
}}
10808 };
10809
10810 /* Register the protocol name and description */
10811 proto_oran = proto_register_protocol("O-RAN Fronthaul CUS", "O-RAN FH CUS", "oran_fh_cus");
10812
10813 /* Allow dissector to find be found by name. */
10814 register_dissector("oran_fh_cus", dissect_oran, proto_oran);
10815
10816 /* Register the tap name. */
10817 oran_tap = register_tap("oran-fh-cus");
10818
10819 /* Required function calls to register the header fields and subtrees */
10820 proto_register_field_array(proto_oran, hf, array_length(hf)(sizeof (hf) / sizeof (hf)[0]));
10821 proto_register_subtree_array(ett, array_length(ett)(sizeof (ett) / sizeof (ett)[0]));
10822 proto_register_subtree_array(ext_ett, array_length(ext_ett)(sizeof (ext_ett) / sizeof (ext_ett)[0]));
10823
10824 expert_oran = expert_register_protocol(proto_oran);
10825 expert_register_field_array(expert_oran, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
10826
10827
10828 /* Preferences */
10829 module_t * oran_module = prefs_register_protocol(proto_oran, NULL((void*)0));
10830
10831 /* Register bit width/compression preferences separately by direction. */
10832 prefs_register_uint_preference(oran_module, "oran.du_port_id_bits", "DU Port ID bits [a]",
10833 "The bit width of DU Port ID - sum of a,b,c&d (eAxC) must be 16", 10, &pref_du_port_id_bits);
10834 prefs_register_uint_preference(oran_module, "oran.bandsector_id_bits", "BandSector ID bits [b]",
10835 "The bit width of BandSector ID - sum of a,b,c&d (eAxC) must be 16", 10, &pref_bandsector_id_bits);
10836 prefs_register_uint_preference(oran_module, "oran.cc_id_bits", "CC ID bits [c]",
10837 "The bit width of CC ID - sum of a,b,c&d (eAxC) must be 16", 10, &pref_cc_id_bits);
10838 prefs_register_uint_preference(oran_module, "oran.ru_port_id_bits", "RU Port ID bits [d]",
10839 "The bit width of RU Port ID - sum of a,b,c&d (eAxC) must be 16", 10, &pref_ru_port_id_bits);
10840
10841 /* Uplink userplane */
10842 prefs_register_static_text_preference(oran_module, "oran.ul", "", "");
10843 prefs_register_uint_preference(oran_module, "oran.iq_bitwidth_up", "IQ Bitwidth Uplink",
10844 "The bit width of a sample in the Uplink (if no udcompHdr and no C-Plane)", 10, &pref_sample_bit_width_uplink);
10845 prefs_register_enum_preference(oran_module, "oran.ud_comp_up", "Uplink User Data Compression",
10846 "Uplink User Data Compression (if no udcompHdr and no C-Plane)", &pref_iqCompressionUplink, ul_compression_options, false0);
10847 prefs_register_enum_preference(oran_module, "oran.ud_comp_hdr_up", "udCompHdr field is present for uplink",
10848 "The udCompHdr field in U-Plane messages may or may not be present, depending on the "
10849 "configuration of the O-RU. This preference instructs the dissector to expect "
10850 "this field to be present in uplink messages",
10851 &pref_includeUdCompHeaderUplink, udcomphdr_present_options, false0);
10852 prefs_register_bool_preference(oran_module, "oran.ignore_cplane_ul_udcomphdr", "Ignore UL compression settings from C-plane",
10853 "When set, override udCompHdr from UL C-Plane with compression method and width configured here", &pref_override_ul_compression);
10854 prefs_register_uint_preference(oran_module, "oran.ul_slot_us_limit", "Microseconds allowed for UL tx in symbol",
10855 "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",
10856 10, &us_allowed_for_ul_in_symbol);
10857
10858 /* Downlink userplane */
10859 prefs_register_static_text_preference(oran_module, "oran.dl", "", "");
10860 prefs_register_uint_preference(oran_module, "oran.iq_bitwidth_down", "IQ Bitwidth Downlink",
10861 "The bit width of a sample in the Downlink (if no udcompHdr)", 10, &pref_sample_bit_width_downlink);
10862 prefs_register_enum_preference(oran_module, "oran.ud_comp_down", "Downlink User Data Compression",
10863 "Downlink User Data Compression", &pref_iqCompressionDownlink, dl_compression_options, false0);
10864 prefs_register_enum_preference(oran_module, "oran.ud_comp_hdr_down", "udCompHdr field is present for downlink",
10865 "The udCompHdr field in U-Plane messages may or may not be present, depending on the "
10866 "configuration of the O-RU. This preference instructs the dissector to expect "
10867 "this field to be present in downlink messages",
10868 &pref_includeUdCompHeaderDownlink, udcomphdr_present_options, false0);
10869
10870 /* SINR */
10871 prefs_register_static_text_preference(oran_module, "oran.sinr", "", "");
10872 prefs_register_uint_preference(oran_module, "oran.iq_bitwidth_sinr", "IQ Bitwidth SINR",
10873 "The bit width of a sample in SINR", 10, &pref_sample_bit_width_sinr);
10874 prefs_register_enum_preference(oran_module, "oran.ud_comp_sinr", "SINR Compression",
10875 "SINR Compression", &pref_iqCompressionSINR, ul_compression_options, false0);
10876
10877 /* BF-related */
10878 prefs_register_static_text_preference(oran_module, "oran.bf", "", "");
10879 prefs_register_uint_preference(oran_module, "oran.num_bf_antennas", "Number of beam weights",
10880 "Number of array elements that BF weights will be provided for", 10, &pref_num_bf_antennas);
10881 prefs_register_obsolete_preference(oran_module, "oran.num_weights_per_bundle");
10882 prefs_register_obsolete_preference(oran_module, "oran.num_bf_weights");
10883 prefs_register_bool_preference(oran_module, "oran.st6_4byte_alignment_required", "Use 4-byte alignment for ST6 sections",
10884 "Default is 1-byte alignment", &st6_4byte_alignment);
10885
10886 /* Misc (and will seldom need to be accessed) */
10887 prefs_register_static_text_preference(oran_module, "oran.misc", "", "");
10888 prefs_register_bool_preference(oran_module, "oran.show_iq_samples", "Show IQ Sample values",
10889 "When enabled, for U-Plane frames show each I and Q value in PRB", &pref_showIQSampleValues);
10890 prefs_register_enum_preference(oran_module, "oran.support_udcomplen", "udCompLen supported",
10891 "When enabled, U-Plane messages with relevant compression schemes will include udCompLen",
10892 &pref_support_udcompLen, udcomplen_support_options, false0);
10893 prefs_register_uint_preference(oran_module, "oran.rbs_in_uplane_section", "Total RBs in User-Plane data section",
10894 "This is used if numPrbu is signalled as 0", 10, &pref_data_plane_section_total_rbs);
10895 prefs_register_bool_preference(oran_module, "oran.unscaled_iq", "Show unscaled I/Q values",
10896 "", &show_unscaled_values);
10897 prefs_register_bool_preference(oran_module, "oran.attempt_reassembly",
10898 "Attempt Radio Transport layer reassembly", "",
10899 &do_radio_transport_layer_reassembly);
10900 prefs_register_obsolete_preference(oran_module, "oran.k_antenna_ports");
10901
10902 prefs_register_bool_preference(oran_module, "oran.link_planes",
10903 "Link C-plane and U-plane using sectionId", "",
10904 &link_planes_together);
10905
10906
10907 flow_states_table = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
10908 flow_results_table = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
10909 ul_symbol_timing = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
10910
10911 dl_beam_ids_defined = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
10912 dl_beam_ids_results = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
10913
10914 register_init_routine(&oran_init_protocol);
10915
10916 /* Register reassembly table. */
10917 reassembly_table_register(&oran_reassembly_table,
10918 &oran_reassembly_table_functions);
10919}
10920
10921/*
10922* Editor modelines - http://www.wireshark.org/tools/modelines.html
10923*
10924* Local Variables:
10925* c-basic-offset: 4
10926* tab-width: 8
10927* indent-tabs-mode: nil
10928* End:
10929*
10930* ex: set shiftwidth=4 tabstop=8 expandtab:
10931* :indentSize=4:tabSize=8:noTabs=true:
10932*/